Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Berry <bryan@olenepal.org>2009-12-31 09:07:15 (GMT)
committer Bryan Berry <bryan@olenepal.org>2009-12-31 09:07:15 (GMT)
commit8eae94e5b502690ca688bc0231049356d8f1675b (patch)
treeb0e4b28821455b6dc19d9aa518c4b93d5c1c2a5f
parent805445cd24e84ce5a3b342a9ca1f937b4d202973 (diff)
testing more obnoxious commit problems
-rw-r--r--bundles/XO/MANIFEST373
-rwxr-xr-xbundles/XO/README.txt4
-rwxr-xr-xbundles/XO/Throbber-small.gifbin0 -> 825 bytes
-rwxr-xr-xbundles/XO/activity/activity-firefox.svg57
-rwxr-xr-xbundles/XO/activity/activity-karma.svg64
-rwxr-xr-xbundles/XO/activity/activity.info7
-rwxr-xr-xbundles/XO/activity/activity.info~7
-rwxr-xr-xbundles/XO/application.ini58
-rwxr-xr-xbundles/XO/blocklist.xml53
-rwxr-xr-xbundles/XO/browserconfig.properties2
-rwxr-xr-xbundles/XO/chrome/browser.jarbin0 -> 2024404 bytes
-rwxr-xr-xbundles/XO/chrome/browser.manifest8
-rwxr-xr-xbundles/XO/chrome/classic.jarbin0 -> 605954 bytes
-rwxr-xr-xbundles/XO/chrome/classic.manifest7
-rwxr-xr-xbundles/XO/chrome/comm.jarbin0 -> 40073 bytes
-rwxr-xr-xbundles/XO/chrome/comm.manifest2
-rwxr-xr-xbundles/XO/chrome/en-US.jarbin0 -> 477417 bytes
-rwxr-xr-xbundles/XO/chrome/en-US.manifest19
-rwxr-xr-xbundles/XO/chrome/icons/default/default16.pngbin0 -> 972 bytes
-rwxr-xr-xbundles/XO/chrome/icons/default/default32.pngbin0 -> 2912 bytes
-rwxr-xr-xbundles/XO/chrome/icons/default/default48.pngbin0 -> 5640 bytes
-rwxr-xr-xbundles/XO/chrome/pippki.jarbin0 -> 279789 bytes
-rwxr-xr-xbundles/XO/chrome/pippki.manifest1
-rwxr-xr-xbundles/XO/chrome/reporter.jarbin0 -> 39459 bytes
-rwxr-xr-xbundles/XO/chrome/reporter.manifest5
-rwxr-xr-xbundles/XO/chrome/toolkit.jarbin0 -> 2009877 bytes
-rwxr-xr-xbundles/XO/chrome/toolkit.manifest6
-rwxr-xr-xbundles/XO/components/FeedConverter.js774
-rwxr-xr-xbundles/XO/components/FeedProcessor.js1950
-rwxr-xr-xbundles/XO/components/FeedWriter.js1387
-rwxr-xr-xbundles/XO/components/NetworkGeolocationProvider.js279
-rwxr-xr-xbundles/XO/components/WebContentConverter.js989
-rwxr-xr-xbundles/XO/components/aboutCertError.js75
-rwxr-xr-xbundles/XO/components/aboutPrivateBrowsing.js63
-rwxr-xr-xbundles/XO/components/aboutRights.js73
-rwxr-xr-xbundles/XO/components/aboutRobots.js73
-rwxr-xr-xbundles/XO/components/aboutSessionRestore.js63
-rwxr-xr-xbundles/XO/components/browser.xptbin0 -> 361500 bytes
-rwxr-xr-xbundles/XO/components/compreg.dat1943
-rwxr-xr-xbundles/XO/components/fuelApplication.js1454
-rwxr-xr-xbundles/XO/components/jsconsole-clhandler.js38
-rwxr-xr-xbundles/XO/components/libbrowsercomps.sobin0 -> 165548 bytes
-rwxr-xr-xbundles/XO/components/libbrowserdirprovider.sobin0 -> 40880 bytes
-rwxr-xr-xbundles/XO/components/libdbusservice.sobin0 -> 28072 bytes
-rwxr-xr-xbundles/XO/components/libimgicon.sobin0 -> 42736 bytes
-rwxr-xr-xbundles/XO/components/libmozgnome.sobin0 -> 32776 bytes
-rwxr-xr-xbundles/XO/components/libnkgnomevfs.sobin0 -> 36660 bytes
-rwxr-xr-xbundles/XO/components/nsAddonRepository.js349
-rwxr-xr-xbundles/XO/components/nsBadCertHandler.js83
-rwxr-xr-xbundles/XO/components/nsBlocklistService.js1069
-rwxr-xr-xbundles/XO/components/nsBrowserContentHandler.js884
-rwxr-xr-xbundles/XO/components/nsBrowserGlue.js1072
-rwxr-xr-xbundles/XO/components/nsContentDispatchChooser.js128
-rwxr-xr-xbundles/XO/components/nsContentPrefService.js944
-rwxr-xr-xbundles/XO/components/nsDefaultCLH.js201
-rwxr-xr-xbundles/XO/components/nsDownloadManagerUI.js159
-rwxr-xr-xbundles/XO/components/nsExtensionManager.js8801
-rwxr-xr-xbundles/XO/components/nsFilePicker.js350
-rwxr-xr-xbundles/XO/components/nsHandlerService.js1431
-rwxr-xr-xbundles/XO/components/nsHelperAppDlg.js1039
-rwxr-xr-xbundles/XO/components/nsLivemarkService.js1140
-rwxr-xr-xbundles/XO/components/nsLoginInfo.js139
-rwxr-xr-xbundles/XO/components/nsLoginManager.js1382
-rwxr-xr-xbundles/XO/components/nsLoginManagerPrompter.js1229
-rwxr-xr-xbundles/XO/components/nsMicrosummaryService.js2260
-rwxr-xr-xbundles/XO/components/nsPlacesDBFlush.js360
-rwxr-xr-xbundles/XO/components/nsPlacesTransactionsService.js1116
-rwxr-xr-xbundles/XO/components/nsPrivateBrowsingService.js512
-rwxr-xr-xbundles/XO/components/nsProxyAutoConfig.js401
-rwxr-xr-xbundles/XO/components/nsSafebrowsingApplication.js745
-rwxr-xr-xbundles/XO/components/nsSearchService.js3572
-rwxr-xr-xbundles/XO/components/nsSearchSuggestions.js759
-rwxr-xr-xbundles/XO/components/nsSessionStartup.js262
-rwxr-xr-xbundles/XO/components/nsSessionStore.js2918
-rwxr-xr-xbundles/XO/components/nsSetDefaultBrowser.js72
-rwxr-xr-xbundles/XO/components/nsSidebar.js333
-rwxr-xr-xbundles/XO/components/nsTaggingService.js663
-rwxr-xr-xbundles/XO/components/nsTryToClose.js80
-rwxr-xr-xbundles/XO/components/nsURLFormatter.js85
-rwxr-xr-xbundles/XO/components/nsUpdateService.js3118
-rwxr-xr-xbundles/XO/components/nsUrlClassifierLib.js1595
-rwxr-xr-xbundles/XO/components/nsUrlClassifierListManager.js615
-rwxr-xr-xbundles/XO/components/nsWebHandlerApp.js184
-rwxr-xr-xbundles/XO/components/pluginGlue.js78
-rwxr-xr-xbundles/XO/components/storage-Legacy.js1478
-rwxr-xr-xbundles/XO/components/storage-mozStorage.js1588
-rwxr-xr-xbundles/XO/components/txEXSLTRegExFunctions.js188
-rwxr-xr-xbundles/XO/components/xpti.dat1449
-rwxr-xr-xbundles/XO/crashreporterbin0 -> 45760 bytes
-rwxr-xr-xbundles/XO/crashreporter-override.ini5
-rwxr-xr-xbundles/XO/crashreporter.ini56
-rwxr-xr-xbundles/XO/defaults/autoconfig/platform.js2
-rwxr-xr-xbundles/XO/defaults/autoconfig/prefcalls.js240
-rwxr-xr-xbundles/XO/defaults/pref/channel-prefs.js2
-rwxr-xr-xbundles/XO/defaults/pref/firefox-branding.js17
-rwxr-xr-xbundles/XO/defaults/pref/firefox-l10n.js5
-rwxr-xr-xbundles/XO/defaults/pref/firefox.js764
-rwxr-xr-xbundles/XO/defaults/pref/reporter.js3
-rwxr-xr-xbundles/XO/defaults/profile/bookmarks.html26
-rwxr-xr-xbundles/XO/defaults/profile/chrome/userChrome-example.css46
-rwxr-xr-xbundles/XO/defaults/profile/chrome/userContent-example.css35
-rwxr-xr-xbundles/XO/defaults/profile/localstore.rdf5
-rwxr-xr-xbundles/XO/defaults/profile/mimeTypes.rdf13
-rwxr-xr-xbundles/XO/defaults/profile/prefs.js10
-rwxr-xr-xbundles/XO/dictionaries/en-US.aff206
-rwxr-xr-xbundles/XO/dictionaries/en-US.dic56053
-rwxr-xr-xbundles/XO/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf42
-rwxr-xr-xbundles/XO/firefox141
-rwxr-xr-xbundles/XO/firefox-binbin0 -> 58228 bytes
-rw-r--r--bundles/XO/foo (renamed from bundles/foo)0
-rw-r--r--bundles/XO/foo~0
-rwxr-xr-xbundles/XO/greprefs/all.js1497
-rwxr-xr-xbundles/XO/greprefs/security-prefs.js74
-rwxr-xr-xbundles/XO/greprefs/xpinstall.js2
-rwxr-xr-xbundles/XO/icons/document.pngbin0 -> 3727 bytes
-rwxr-xr-xbundles/XO/icons/mozicon128.pngbin0 -> 25121 bytes
-rwxr-xr-xbundles/XO/icons/mozicon16.xpm191
-rwxr-xr-xbundles/XO/icons/mozicon50.xpm299
-rwxr-xr-xbundles/XO/icons/updater.pngbin0 -> 4030 bytes
-rwxr-xr-xbundles/XO/karma/AUTHORS3
-rwxr-xr-xbundles/XO/karma/COPYING25
-rwxr-xr-xbundles/XO/karma/assets/default/images/back.pngbin0 -> 3816 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/back_bw.pngbin0 -> 3368 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/chakra_logo.pngbin0 -> 9433 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/chakra_logo_50x50.pngbin0 -> 4569 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/english.pngbin0 -> 13245 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/exercise.pngbin0 -> 6460 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/exercise_bw.pngbin0 -> 4631 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/favicon.icobin0 -> 15086 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/games.pngbin0 -> 7482 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/games_bw.pngbin0 -> 5461 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/geography.pngbin0 -> 17007 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade1.pngbin0 -> 3959 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade1_bw.pngbin0 -> 3727 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade2.pngbin0 -> 4937 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade2_bw.pngbin0 -> 4302 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade3.pngbin0 -> 5556 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade3_bw.pngbin0 -> 4517 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade4.pngbin0 -> 4545 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade4_bw.pngbin0 -> 4046 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade5.pngbin0 -> 4992 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade5_bw.pngbin0 -> 4388 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade6.pngbin0 -> 5677 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade6_bw.pngbin0 -> 4332 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade7.pngbin0 -> 4464 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade7_bw.pngbin0 -> 3926 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade8.pngbin0 -> 6392 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/grade8_bw.pngbin0 -> 4987 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/health.pngbin0 -> 17690 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/help.pngbin0 -> 4872 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/help_50x50.pngbin0 -> 3231 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/history.pngbin0 -> 11252 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/karma_logo.pngbin0 -> 26448 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/karma_logo_35x32.pngbin0 -> 2394 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/karma_logo_50x46.pngbin0 -> 4084 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/karma_logo_54x50.pngbin0 -> 4667 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/mathematics.pngbin0 -> 6375 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_A.pngbin0 -> 1212 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_B.pngbin0 -> 1223 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_C.pngbin0 -> 1205 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_D.pngbin0 -> 1246 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_E.pngbin0 -> 1218 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_F.pngbin0 -> 1135 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_G.pngbin0 -> 1278 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_H.pngbin0 -> 1201 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_I.pngbin0 -> 1037 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_J.pngbin0 -> 1028 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_K.pngbin0 -> 1267 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/month_L.pngbin0 -> 1065 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/music.pngbin0 -> 9550 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/mystuff.pngbin0 -> 3100 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/nepali.pngbin0 -> 13102 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/olenepal_logo.gifbin0 -> 2759 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/preview1.jpgbin0 -> 29263 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/preview2.jpgbin0 -> 120382 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/preview3.jpgbin0 -> 40900 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/preview4.jpgbin0 -> 33406 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/profile.pngbin0 -> 6685 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/resources.pngbin0 -> 9363 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/resources_bw.pngbin0 -> 6262 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/science.pngbin0 -> 16335 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/tutorial.pngbin0 -> 8004 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/tutorial_bw.pngbin0 -> 6008 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-bg_flat_0_aaaaaa_40x100.pngbin0 -> 180 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-bg_flat_75_ffffff_40x100.pngbin0 -> 178 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-bg_glass_55_fbf9ee_1x400.pngbin0 -> 120 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-bg_glass_65_ffffff_1x400.pngbin0 -> 105 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-bg_glass_75_dadada_1x400.pngbin0 -> 111 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-bg_glass_75_e6e6e6_1x400.pngbin0 -> 110 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-bg_glass_95_fef1ec_1x400.pngbin0 -> 119 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-bg_highlight-soft_75_cccccc_1x100.pngbin0 -> 101 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-icons_222222_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-icons_2e83ff_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-icons_454545_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-icons_888888_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/ui-icons_cd0a0a_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/week1.pngbin0 -> 1111 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/week2.pngbin0 -> 1202 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/week3.pngbin0 -> 1279 bytes
-rwxr-xr-xbundles/XO/karma/assets/default/images/week4.pngbin0 -> 1158 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/adding_up134x100.pngbin0 -> 7655 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/alphabet_identification136x100.pngbin0 -> 20338 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/alphabet_puzzle136x100.pngbin0 -> 20311 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/arrows136x100.pngbin0 -> 10811 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/back.pngbin0 -> 3816 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/back_bw.pngbin0 -> 3368 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/chakra_logo.pngbin0 -> 9433 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/chakra_logo_50x50.pngbin0 -> 4569 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/english.pngbin0 -> 13245 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/english_colors136x100.pngbin0 -> 21087 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/english_matching136x100.pngbin0 -> 4881 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/exercise.pngbin0 -> 6460 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/exercise_bw.pngbin0 -> 4631 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/favicon.icobin0 -> 15086 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/games.pngbin0 -> 7482 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/games_bw.pngbin0 -> 5461 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/geography.pngbin0 -> 17007 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade1.pngbin0 -> 3959 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade1_bw.pngbin0 -> 3727 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade2.pngbin0 -> 4937 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade2_bw.pngbin0 -> 4302 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade3.pngbin0 -> 5556 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade3_bw.pngbin0 -> 4517 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade4.pngbin0 -> 4545 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade4_bw.pngbin0 -> 4046 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade5.pngbin0 -> 4992 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade5_bw.pngbin0 -> 4388 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade6.pngbin0 -> 5677 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade6_bw.pngbin0 -> 4332 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade7.pngbin0 -> 4464 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade7_bw.pngbin0 -> 3926 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade8.pngbin0 -> 6392 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/grade8_bw.pngbin0 -> 4987 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/happyChimp120x125.pngbin0 -> 16261 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/health.pngbin0 -> 17690 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/help.pngbin0 -> 4872 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/help_50x50.pngbin0 -> 3231 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/history.pngbin0 -> 11252 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/karma-logo100x118.pngbin0 -> 7001 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/karma-logo50x59.pngbin0 -> 3141 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/karma-logo80x94.pngbin0 -> 4809 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/karma_logo.pngbin0 -> 27614 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/karma_logo_35x32.pngbin0 -> 2394 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/karma_logo_50x46.pngbin0 -> 4084 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/karma_logo_54x50.pngbin0 -> 4667 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/largest_number136x100.pngbin0 -> 6207 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/mathematics.pngbin0 -> 6375 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/money_identification136x100.pngbin0 -> 5452 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_A.pngbin0 -> 1212 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_B.pngbin0 -> 1223 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_C.pngbin0 -> 1205 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_D.pngbin0 -> 1246 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_E.pngbin0 -> 1218 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_F.pngbin0 -> 1135 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_G.pngbin0 -> 1278 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_H.pngbin0 -> 1201 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_I.pngbin0 -> 1037 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_J.pngbin0 -> 1028 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_K.pngbin0 -> 1267 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/month_L.pngbin0 -> 1065 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/mountains.pngbin0 -> 8812 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/music.pngbin0 -> 9550 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/mystuff.pngbin0 -> 3100 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/nepali.pngbin0 -> 13102 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/numeric_puzzle136x100.pngbin0 -> 22361 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/olenepal_logo.gifbin0 -> 2759 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/preview1.jpgbin0 -> 29263 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/preview2.jpgbin0 -> 120382 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/preview3.jpgbin0 -> 40900 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/preview4.jpgbin0 -> 33406 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/profile.pngbin0 -> 6685 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/quads136x100.pngbin0 -> 21573 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/resources.pngbin0 -> 9363 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/resources_bw.pngbin0 -> 6262 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/science.pngbin0 -> 16335 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/screenConozco136x100.pngbin0 -> 12662 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/screenConozco162x100.pngbin0 -> 13807 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/tutorial.pngbin0 -> 8004 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/tutorial_bw.pngbin0 -> 6008 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-bg_flat_0_aaaaaa_40x100.pngbin0 -> 180 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-bg_flat_75_ffffff_40x100.pngbin0 -> 178 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-bg_glass_55_fbf9ee_1x400.pngbin0 -> 120 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-bg_glass_65_ffffff_1x400.pngbin0 -> 105 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-bg_glass_75_dadada_1x400.pngbin0 -> 111 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-bg_glass_75_e6e6e6_1x400.pngbin0 -> 110 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-bg_glass_95_fef1ec_1x400.pngbin0 -> 119 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-bg_highlight-soft_75_cccccc_1x100.pngbin0 -> 101 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-icons_222222_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-icons_2e83ff_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-icons_454545_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-icons_888888_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/ui-icons_cd0a0a_256x240.pngbin0 -> 4369 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/web-bg.pngbin0 -> 25178 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/web-bg.svg651
-rwxr-xr-xbundles/XO/karma/assets/image/week1.pngbin0 -> 1111 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/week2.pngbin0 -> 1202 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/week3.pngbin0 -> 1279 bytes
-rwxr-xr-xbundles/XO/karma/assets/image/week4.pngbin0 -> 1158 bytes
-rwxr-xr-xbundles/XO/karma/css/chakra.css229
-rwxr-xr-xbundles/XO/karma/css/demos.css451
-rwxr-xr-xbundles/XO/karma/css/intro.css94
-rwxr-xr-xbundles/XO/karma/css/karma.css21
-rwxr-xr-xbundles/XO/karma/css/qunit.css17
-rwxr-xr-xbundles/XO/karma/css/ui.all.css2
-rwxr-xr-xbundles/XO/karma/css/ui.base.css2
-rwxr-xr-xbundles/XO/karma/css/ui.core.css37
-rwxr-xr-xbundles/XO/karma/css/ui.tabs.css11
-rwxr-xr-xbundles/XO/karma/css/ui.theme.css245
-rwxr-xr-xbundles/XO/karma/index.html83
-rwxr-xr-xbundles/XO/karma/js/jquery-1.3.2.min.js19
-rwxr-xr-xbundles/XO/karma/js/jquery.jgrowl_minimized.js4
-rwxr-xr-xbundles/XO/karma/js/jquery.svg.js1325
-rwxr-xr-xbundles/XO/karma/js/jquery.svg.pack.js7
-rwxr-xr-xbundles/XO/karma/js/jquery.svgdom.js356
-rwxr-xr-xbundles/XO/karma/js/jquery.svgdom.pack.js7
-rwxr-xr-xbundles/XO/karma/js/karma.js1650
-rwxr-xr-xbundles/XO/karma/js/knavbar.js13
-rwxr-xr-xbundles/XO/karma/js/qunit.js1027
-rwxr-xr-xbundles/XO/karma/js/raphael-min.js7
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/Uruguay_departments_blank.svg92
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien-sad.svg135
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien1.svg281
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien2.svg272
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien3.svg257
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien4.svg265
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien5.svg271
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/capitals1.svg788
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/capitals2.svg789
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/deptosLineas.pngbin0 -> 41887 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/fondo.pngbin0 -> 40650 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/helpIcon.svg171
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/helpScreen.svg426
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/playAgain.svg884
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/quitIcon.svg369
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship1.svg597
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship2.svg599
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship80x200.svg542
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/css/jquery.svg.css15
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/css/lesson.css76
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/index.html47
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/js/lesson.js337
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/tests.html9
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/tests/index.html9
-rwxr-xr-xbundles/XO/karma/lessons/Conozco-Uruguay/tests/tests.js2
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/1.pngbin0 -> 17754 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/10.pngbin0 -> 21498 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/11.pngbin0 -> 26495 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/12.pngbin0 -> 32890 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/13.pngbin0 -> 21052 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/14.pngbin0 -> 26762 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/15.pngbin0 -> 29831 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/16.pngbin0 -> 24311 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/2.pngbin0 -> 20727 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/3.pngbin0 -> 18559 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/4.pngbin0 -> 22151 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/5.pngbin0 -> 18096 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/6.pngbin0 -> 19159 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/7.pngbin0 -> 21455 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/8.pngbin0 -> 28621 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/9.pngbin0 -> 24762 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/img1.pngbin0 -> 357550 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/1.pngbin0 -> 45701 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/10.pngbin0 -> 44321 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/11.pngbin0 -> 46721 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/12.pngbin0 -> 43808 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/13.pngbin0 -> 39899 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/14.pngbin0 -> 38773 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/15.pngbin0 -> 33499 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/16.pngbin0 -> 30825 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/2.pngbin0 -> 37293 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/3.pngbin0 -> 22713 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/4.pngbin0 -> 28222 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/5.pngbin0 -> 41372 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/6.pngbin0 -> 40929 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/7.pngbin0 -> 37334 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/8.pngbin0 -> 36705 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/9.pngbin0 -> 43462 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/img2.pngbin0 -> 610410 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/1.pngbin0 -> 31071 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/10.pngbin0 -> 42874 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/11.pngbin0 -> 44926 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/12.pngbin0 -> 45983 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/13.pngbin0 -> 47862 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/14.pngbin0 -> 48031 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/15.pngbin0 -> 48882 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/16.pngbin0 -> 41768 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/2.pngbin0 -> 26884 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/3.pngbin0 -> 33016 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/4.pngbin0 -> 33709 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/5.pngbin0 -> 40971 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/6.pngbin0 -> 40097 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/7.pngbin0 -> 41742 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/8.pngbin0 -> 44712 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/9.pngbin0 -> 45028 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/img3.pngbin0 -> 647727 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/css/lesson.css51
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/index.html28
-rwxr-xr-xbundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/js/lesson.js218
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/1.pngbin0 -> 42398 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/2.pngbin0 -> 47797 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/3.pngbin0 -> 46837 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/4.pngbin0 -> 46417 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/5.pngbin0 -> 43845 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/6.pngbin0 -> 54887 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/background.jpgbin0 -> 76111 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/correct.pngbin0 -> 2411 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/1.pngbin0 -> 1221 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/10.pngbin0 -> 974 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/2.pngbin0 -> 1106 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/3.pngbin0 -> 1795 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/4.pngbin0 -> 1341 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/5.pngbin0 -> 1287 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/6.pngbin0 -> 1242 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/7.pngbin0 -> 1672 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/8.pngbin0 -> 1129 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/9.pngbin0 -> 964 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/incorrect.pngbin0 -> 2887 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/main.jpgbin0 -> 89900 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/orginal.jpgbin0 -> 127521 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/assets/image/play_again.jpgbin0 -> 11128 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/css/lesson.css87
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/index.html39
-rwxr-xr-xbundles/XO/karma/lessons/English_Animal_Identification/js/lesson.js198
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/1.pngbin0 -> 6485 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/2.pngbin0 -> 9794 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/3.pngbin0 -> 9134 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/4.pngbin0 -> 9172 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/5.pngbin0 -> 9651 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/6.pngbin0 -> 9967 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/7.pngbin0 -> 9244 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/8.pngbin0 -> 9580 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/Thumbs.dbbin0 -> 43008 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/background.jpgbin0 -> 60287 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/correct.pngbin0 -> 2411 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/1.pngbin0 -> 8310 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/2.pngbin0 -> 7682 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/3.pngbin0 -> 8592 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/4.pngbin0 -> 8227 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/5.pngbin0 -> 8777 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/6.pngbin0 -> 8295 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/7.pngbin0 -> 7444 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/8.pngbin0 -> 8806 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/9.pngbin0 -> 8313 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/incorrect.pngbin0 -> 2887 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/assets/image/play_again.jpgbin0 -> 11128 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/css/lesson.css84
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/index.html39
-rwxr-xr-xbundles/XO/karma/lessons/English_Color_Identification/js/lesson.js197
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/1.pngbin0 -> 1416 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/2.pngbin0 -> 2573 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/3.pngbin0 -> 1332 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/4.pngbin0 -> 2932 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/5.pngbin0 -> 1455 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/6.pngbin0 -> 2549 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/7.pngbin0 -> 1363 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/8.pngbin0 -> 3041 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/background.jpgbin0 -> 34277 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/correct.pngbin0 -> 2411 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/incorrect.pngbin0 -> 2887 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/optionBox.pngbin0 -> 6102 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/play_again.jpgbin0 -> 11128 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/questionBox.pngbin0 -> 4550 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/css/lesson.css88
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/index.html42
-rwxr-xr-xbundles/XO/karma/lessons/English_Direction_of_Arrows/js/lesson.js196
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/1.pngbin0 -> 6883 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/10.pngbin0 -> 2319 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/11.pngbin0 -> 1944 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/12.pngbin0 -> 5852 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/13.pngbin0 -> 9069 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/14.pngbin0 -> 3244 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/15.pngbin0 -> 8086 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/16.pngbin0 -> 2367 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/17.pngbin0 -> 8778 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/18.pngbin0 -> 2255 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/19.pngbin0 -> 8451 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/2.pngbin0 -> 2942 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/20.pngbin0 -> 2701 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/21.pngbin0 -> 8378 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/22.pngbin0 -> 2254 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/23.pngbin0 -> 9795 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/24.pngbin0 -> 3137 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/25.pngbin0 -> 9013 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/26.pngbin0 -> 2780 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/27.pngbin0 -> 6712 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/28.pngbin0 -> 3133 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/29.pngbin0 -> 7723 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/3.pngbin0 -> 11830 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/30.pngbin0 -> 2973 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/4.pngbin0 -> 1938 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/5.pngbin0 -> 7737 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/6.pngbin0 -> 2410 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/7.pngbin0 -> 9833 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/8.pngbin0 -> 2444 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/9.pngbin0 -> 10318 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/default.pngbin0 -> 503 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/home.pngbin0 -> 2677 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/info.pngbin0 -> 2420 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/matched.pngbin0 -> 415 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/pause.pngbin0 -> 2411 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/play.pngbin0 -> 3061 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/play_again.jpgbin0 -> 11128 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/repeat.pngbin0 -> 3620 bytes
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/css/lesson.css124
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/index.html37
-rwxr-xr-xbundles/XO/karma/lessons/English_Matching_Words_and_Objects/js/lesson.js260
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/trigger.oggbin0 -> 10771 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/0.pngbin0 -> 1505 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/1.pngbin0 -> 1429 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/10.pngbin0 -> 1516 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/11.pngbin0 -> 1446 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/12.pngbin0 -> 1599 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/13.pngbin0 -> 1572 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/14.pngbin0 -> 1565 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/15.pngbin0 -> 1507 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/16.pngbin0 -> 1558 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/17.pngbin0 -> 1574 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/18.pngbin0 -> 1562 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/19.pngbin0 -> 1561 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/2.pngbin0 -> 1544 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/20.pngbin0 -> 1661 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/21.pngbin0 -> 1582 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/22.pngbin0 -> 1683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/23.pngbin0 -> 1646 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/24.pngbin0 -> 1678 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/25.pngbin0 -> 1652 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/26.pngbin0 -> 1694 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/27.pngbin0 -> 1689 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/28.pngbin0 -> 1720 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/29.pngbin0 -> 1679 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/3.pngbin0 -> 1501 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/30.pngbin0 -> 1580 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/31.pngbin0 -> 1554 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/32.pngbin0 -> 1647 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/33.pngbin0 -> 1645 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/34.pngbin0 -> 1662 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/35.pngbin0 -> 1592 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/36.pngbin0 -> 1627 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/37.pngbin0 -> 1658 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/38.pngbin0 -> 1621 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/39.pngbin0 -> 1612 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/4.pngbin0 -> 1532 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/40.pngbin0 -> 1639 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/41.pngbin0 -> 1578 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/42.pngbin0 -> 1697 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/43.pngbin0 -> 1637 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/44.pngbin0 -> 1674 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/45.pngbin0 -> 1616 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/46.pngbin0 -> 1651 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/47.pngbin0 -> 1676 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/48.pngbin0 -> 1673 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/49.pngbin0 -> 1661 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/5.pngbin0 -> 1483 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/50.pngbin0 -> 1588 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/51.pngbin0 -> 1516 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/52.pngbin0 -> 1638 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/53.pngbin0 -> 1587 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/54.pngbin0 -> 1628 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/55.pngbin0 -> 1559 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/56.pngbin0 -> 1599 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/57.pngbin0 -> 1620 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/58.pngbin0 -> 1643 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/59.pngbin0 -> 1609 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/6.pngbin0 -> 1522 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/60.pngbin0 -> 1609 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/61.pngbin0 -> 1551 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/62.pngbin0 -> 1682 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/63.pngbin0 -> 1611 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/64.pngbin0 -> 1646 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/65.pngbin0 -> 1583 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/66.pngbin0 -> 1618 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/67.pngbin0 -> 1653 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/68.pngbin0 -> 1664 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/69.pngbin0 -> 1642 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/7.pngbin0 -> 1537 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/70.pngbin0 -> 1639 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/71.pngbin0 -> 1583 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/72.pngbin0 -> 1667 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/73.pngbin0 -> 1653 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/74.pngbin0 -> 1668 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/75.pngbin0 -> 1615 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/76.pngbin0 -> 1641 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/77.pngbin0 -> 1650 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/78.pngbin0 -> 1660 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/79.pngbin0 -> 1643 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/8.pngbin0 -> 1550 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/80.pngbin0 -> 1627 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/81.pngbin0 -> 1561 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/82.pngbin0 -> 1681 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/83.pngbin0 -> 1615 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/84.pngbin0 -> 1681 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/85.pngbin0 -> 1618 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/86.pngbin0 -> 1655 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/87.pngbin0 -> 1648 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/88.pngbin0 -> 1666 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/89.pngbin0 -> 1657 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/9.pngbin0 -> 1534 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/90.pngbin0 -> 1615 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/91.pngbin0 -> 1555 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/92.pngbin0 -> 1678 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/93.pngbin0 -> 1606 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/94.pngbin0 -> 1657 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/95.pngbin0 -> 1611 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/96.pngbin0 -> 1643 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/97.pngbin0 -> 1672 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/98.pngbin0 -> 1671 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/99.pngbin0 -> 1645 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/main.pngbin0 -> 43968 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/Exit.pngbin0 -> 3268 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/Info.pngbin0 -> 3982 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/help.pngbin0 -> 2231 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/refresh.pngbin0 -> 2024 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/volumeDisabled.pngbin0 -> 5032 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/volumeEnabled.pngbin0 -> 5375 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0.gifbin0 -> 741 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/09_9b.gifbin0 -> 1545 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0a.gifbin0 -> 1731 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0b.gifbin0 -> 1608 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1.gifbin0 -> 607 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1a.gifbin0 -> 1477 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1b.gifbin0 -> 1350 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2.gifbin0 -> 709 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2a.gifbin0 -> 1619 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2b.gifbin0 -> 1454 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3.gifbin0 -> 730 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3a.gifbin0 -> 1648 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3b.gifbin0 -> 1492 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4.gifbin0 -> 690 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4a.gifbin0 -> 1624 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4b.gifbin0 -> 1482 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5.gifbin0 -> 707 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5a.gifbin0 -> 1708 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5b.gifbin0 -> 1545 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6.gifbin0 -> 739 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6a.gifbin0 -> 1631 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6b.gifbin0 -> 1500 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7.gifbin0 -> 734 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7a.gifbin0 -> 1641 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7b.gifbin0 -> 1462 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8.gifbin0 -> 1200 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8a.gifbin0 -> 1696 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8b.gifbin0 -> 1576 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/9.gifbin0 -> 700 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/9a.gifbin0 -> 1699 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/0.gifbin0 -> 1450 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/1.gifbin0 -> 1338 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/2.gifbin0 -> 1473 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/3.gifbin0 -> 1451 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/4.gifbin0 -> 1488 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/5.gifbin0 -> 1425 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/6.gifbin0 -> 1422 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/7.gifbin0 -> 1395 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/8.gifbin0 -> 1442 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/9.gifbin0 -> 1442 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/scorebox.pngbin0 -> 5015 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/yellowBox.pngbin0 -> 1851 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/css/lesson.css269
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/index.html73
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/info.txt15
-rwxr-xr-xbundles/XO/karma/lessons/Math_Largest_Number_Identification/js/lesson.js194
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/audio/trigger.oggbin0 -> 10771 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/1.pngbin0 -> 111252 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/10.pngbin0 -> 159139 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/2.pngbin0 -> 116414 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/3.pngbin0 -> 123472 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/4.pngbin0 -> 127884 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/5.pngbin0 -> 120792 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/6.pngbin0 -> 145084 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/7.pngbin0 -> 152345 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/8.pngbin0 -> 152936 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/9.pngbin0 -> 155500 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/correct.pngbin0 -> 2411 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/1.pngbin0 -> 7503 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/10.pngbin0 -> 8862 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/2.pngbin0 -> 7836 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/3.pngbin0 -> 7650 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/4.pngbin0 -> 8124 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/5.pngbin0 -> 8317 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/6.pngbin0 -> 8156 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/7.pngbin0 -> 8325 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/8.pngbin0 -> 8544 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/9.pngbin0 -> 8397 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/incorrect.pngbin0 -> 2887 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/assets/image/play_again.jpgbin0 -> 11128 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/css/lesson.css91
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/index.html43
-rwxr-xr-xbundles/XO/karma/lessons/Math_Money_Identification/js/lesson.js197
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/1.jpgbin0 -> 4313 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/10.jpgbin0 -> 14980 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/11.jpgbin0 -> 15491 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/12.jpgbin0 -> 10947 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/13.jpgbin0 -> 9098 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/14.jpgbin0 -> 10338 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/15.jpgbin0 -> 12904 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/16.jpgbin0 -> 9210 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/2.jpgbin0 -> 8027 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/3.jpgbin0 -> 5756 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/4.jpgbin0 -> 4749 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/5.jpgbin0 -> 5975 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/6.jpgbin0 -> 13698 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/7.jpgbin0 -> 12978 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/8.jpgbin0 -> 5324 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/9.jpgbin0 -> 11378 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/img1.jpgbin0 -> 44924 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/1.jpgbin0 -> 5983 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/10.jpgbin0 -> 15926 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/11.jpgbin0 -> 15781 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/12.jpgbin0 -> 12037 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/13.jpgbin0 -> 13531 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/14.jpgbin0 -> 14354 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/15.jpgbin0 -> 14359 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/16.jpgbin0 -> 13554 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/2.jpgbin0 -> 6156 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/3.jpgbin0 -> 7708 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/4.jpgbin0 -> 10259 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/5.jpgbin0 -> 12465 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/6.jpgbin0 -> 16814 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/7.jpgbin0 -> 16615 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/8.jpgbin0 -> 11131 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/9.jpgbin0 -> 12388 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/img2.jpgbin0 -> 92305 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/1.jpgbin0 -> 7164 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/10.jpgbin0 -> 17696 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/11.jpgbin0 -> 16255 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/12.jpgbin0 -> 14456 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/13.jpgbin0 -> 14623 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/14.jpgbin0 -> 13636 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/15.jpgbin0 -> 11223 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/16.jpgbin0 -> 9808 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/2.jpgbin0 -> 6338 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/3.jpgbin0 -> 5922 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/4.jpgbin0 -> 7934 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/5.jpgbin0 -> 14225 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/6.jpgbin0 -> 11524 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/7.jpgbin0 -> 12721 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/8.jpgbin0 -> 15797 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/9.jpgbin0 -> 16904 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/img3.jpgbin0 -> 91926 bytes
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/css/lesson.css50
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/index.html28
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-1.3.2.js4376
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-1.js4376
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-ui-1.js298
-rwxr-xr-xbundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/lesson.js217
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/trigger.oggbin0 -> 10771 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/en/sounds/en_correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/en/sounds/en_incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/es-MX/sounds/es-MX_correct.oggbin0 -> 14432 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/es-MX/sounds/es-MX_incorrect.oggbin0 -> 13705 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/he/sounds/he_correct.oggbin0 -> 38612 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/he/sounds/he_incorrect.oggbin0 -> 51319 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/ball37px.pngbin0 -> 2745 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/balloon37px.pngbin0 -> 2020 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/banana37px.pngbin0 -> 2063 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/chilli.pngbin0 -> 2692 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/fish64px.pngbin0 -> 2515 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/flower37px.pngbin0 -> 2957 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/happyChimp_120x125.pngbin0 -> 16261 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/happyMonkey.jpgbin0 -> 12348 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/normalChimp_120x125.pngbin0 -> 15326 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/plussign.pngbin0 -> 1080 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/sadChimp_120x125.pngbin0 -> 15698 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/scorebox.pngbin0 -> 5015 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/sidebar.pngbin0 -> 8189 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/yellowBox.pngbin0 -> 1524 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/ne/sounds/ne_correct.oggbin0 -> 11930 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/assets/ne/sounds/ne_incorrect.oggbin0 -> 15827 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/css/knavbar.css134
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/css/lesson.css173
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/exercise.html91
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/index.html83
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/index_knavbar.html39
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/js/lesson.js300
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/js/lesson1.js326
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/po/en.po28
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/po/es-MX.po29
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/po/es.po29
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/po/he-IL.po28
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_canvas/resources.html37
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/trigger.oggbin0 -> 10771 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/en/sounds/en_correct.oggbin0 -> 12811 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/en/sounds/en_incorrect.oggbin0 -> 12683 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/es-MX/sounds/es-MX_correct.oggbin0 -> 14432 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/es-MX/sounds/es-MX_incorrect.oggbin0 -> 13705 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/he/sounds/he_correct.oggbin0 -> 38612 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/he/sounds/he_incorrect.oggbin0 -> 51319 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/ball37px.pngbin0 -> 2745 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/balloon37px.pngbin0 -> 2020 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/banana37px.pngbin0 -> 2063 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/chilli.pngbin0 -> 2692 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/fish64px.pngbin0 -> 2515 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/flower37px.pngbin0 -> 2957 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/happyChimp_120x125.pngbin0 -> 16261 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/happyMonkey.jpgbin0 -> 12348 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/normalChimp_120x125.pngbin0 -> 15326 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/plussign.pngbin0 -> 1080 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/sadChimp_120x125.pngbin0 -> 15698 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/scorebox.pngbin0 -> 5015 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/sidebar.pngbin0 -> 8189 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/yellowBox.pngbin0 -> 1524 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/ne/sounds/ne_correct.oggbin0 -> 11930 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/assets/ne/sounds/ne_incorrect.oggbin0 -> 15827 bytes
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/css/knavbar.css139
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/css/lesson.css171
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/exercise.html95
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/index.html83
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/index_knavbar.html39
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/js/lesson.js363
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/po/en.po28
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/po/es-MX.po29
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/po/es.po29
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/po/he-IL.po28
-rwxr-xr-xbundles/XO/karma/lessons/adding_up_to_10_svg/resources.html37
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/css/activity.css4
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/css/jquery.jgrowl.css119
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/css/lesson.css79
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/images/bg.pngbin0 -> 275387 bytes
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/images/bg_small.pngbin0 -> 71108 bytes
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/images/erase.pngbin0 -> 1708 bytes
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/images/eraseOver.pngbin0 -> 804 bytes
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/images/next.pngbin0 -> 1906 bytes
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/images/previous.pngbin0 -> 1851 bytes
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/index.html60
-rwxr-xr-xbundles/XO/karma/lessons/quadrilaterals/js/lesson.js289
-rwxr-xr-xbundles/XO/libfreebl3.chkbin0 -> 478 bytes
-rwxr-xr-xbundles/XO/libfreebl3.sobin0 -> 317036 bytes
-rwxr-xr-xbundles/XO/libmozjs.sobin0 -> 839304 bytes
-rwxr-xr-xbundles/XO/libnspr4.sobin0 -> 200736 bytes
-rwxr-xr-xbundles/XO/libnss3.sobin0 -> 858792 bytes
-rwxr-xr-xbundles/XO/libnssckbi.sobin0 -> 338140 bytes
-rwxr-xr-xbundles/XO/libnssdbm3.sobin0 -> 122896 bytes
-rwxr-xr-xbundles/XO/libnssutil3.sobin0 -> 77608 bytes
-rwxr-xr-xbundles/XO/libplc4.sobin0 -> 13180 bytes
-rwxr-xr-xbundles/XO/libplds4.sobin0 -> 8748 bytes
-rwxr-xr-xbundles/XO/libsmime3.sobin0 -> 125644 bytes
-rwxr-xr-xbundles/XO/libsoftokn3.chkbin0 -> 478 bytes
-rwxr-xr-xbundles/XO/libsoftokn3.sobin0 -> 190032 bytes
-rwxr-xr-xbundles/XO/libsqlite3.sobin0 -> 442840 bytes
-rwxr-xr-xbundles/XO/libssl3.sobin0 -> 160140 bytes
-rwxr-xr-xbundles/XO/libxpcom.sobin0 -> 12160 bytes
-rwxr-xr-xbundles/XO/libxul.sobin0 -> 14177440 bytes
-rwxr-xr-xbundles/XO/modules/DownloadLastDir.jsm70
-rwxr-xr-xbundles/XO/modules/DownloadUtils.jsm502
-rwxr-xr-xbundles/XO/modules/ISO8601DateUtils.jsm176
-rwxr-xr-xbundles/XO/modules/Microformats.js1837
-rwxr-xr-xbundles/XO/modules/PlacesDBUtils.jsm589
-rwxr-xr-xbundles/XO/modules/PluralForm.jsm207
-rwxr-xr-xbundles/XO/modules/SpatialNavigation.js558
-rwxr-xr-xbundles/XO/modules/WindowDraggingUtils.jsm87
-rwxr-xr-xbundles/XO/modules/XPCOMUtils.jsm267
-rwxr-xr-xbundles/XO/modules/debug.js82
-rwxr-xr-xbundles/XO/modules/distribution.js359
-rwxr-xr-xbundles/XO/modules/utils.js1804
-rwxr-xr-xbundles/XO/mozilla-xremote-clientbin0 -> 10804 bytes
-rwxr-xr-xbundles/XO/old-homepage-default.properties1
-rwxr-xr-xbundles/XO/platform.ini5
-rwxr-xr-xbundles/XO/plugins/libnullplugin.sobin0 -> 15824 bytes
-rwxr-xr-xbundles/XO/removed-files531
-rwxr-xr-xbundles/XO/res/EditorOverride.css363
-rwxr-xr-xbundles/XO/res/arrow.gifbin0 -> 56 bytes
-rwxr-xr-xbundles/XO/res/arrowd.gifbin0 -> 59 bytes
-rwxr-xr-xbundles/XO/res/broken-image.gifbin0 -> 106 bytes
-rwxr-xr-xbundles/XO/res/charsetData.properties223
-rwxr-xr-xbundles/XO/res/charsetalias.properties522
-rwxr-xr-xbundles/XO/res/contenteditable.css376
-rwxr-xr-xbundles/XO/res/designmode.css41
-rwxr-xr-xbundles/XO/res/dtd/mathml.dtd1592
-rwxr-xr-xbundles/XO/res/dtd/xhtml11.dtd300
-rwxr-xr-xbundles/XO/res/entityTables/html40Latin1.properties146
-rwxr-xr-xbundles/XO/res/entityTables/html40Special.properties69
-rwxr-xr-xbundles/XO/res/entityTables/html40Symbols.properties164
-rwxr-xr-xbundles/XO/res/entityTables/htmlEntityVersions.properties50
-rwxr-xr-xbundles/XO/res/entityTables/mathml20.properties1286
-rwxr-xr-xbundles/XO/res/entityTables/transliterate.properties2466
-rwxr-xr-xbundles/XO/res/fonts/mathfont.properties522
-rwxr-xr-xbundles/XO/res/fonts/mathfontSTIXNonUnicode.properties101
-rwxr-xr-xbundles/XO/res/fonts/mathfontSTIXSize1.properties64
-rwxr-xr-xbundles/XO/res/fonts/mathfontStandardSymbolsL.properties77
-rwxr-xr-xbundles/XO/res/fonts/mathfontUnicode.properties123
-rwxr-xr-xbundles/XO/res/forms.css592
-rwxr-xr-xbundles/XO/res/grabber.gifbin0 -> 858 bytes
-rwxr-xr-xbundles/XO/res/hiddenWindow.html1
-rwxr-xr-xbundles/XO/res/html.css526
-rwxr-xr-xbundles/XO/res/html/folder.pngbin0 -> 619 bytes
-rwxr-xr-xbundles/XO/res/langGroups.properties239
-rwxr-xr-xbundles/XO/res/language.properties261
-rwxr-xr-xbundles/XO/res/loading-image.gifbin0 -> 122 bytes
-rwxr-xr-xbundles/XO/res/mathml.css455
-rwxr-xr-xbundles/XO/res/quirk.css274
-rwxr-xr-xbundles/XO/res/svg.css67
-rwxr-xr-xbundles/XO/res/table-add-column-after-active.gifbin0 -> 58 bytes
-rwxr-xr-xbundles/XO/res/table-add-column-after-hover.gifbin0 -> 826 bytes
-rwxr-xr-xbundles/XO/res/table-add-column-after.gifbin0 -> 826 bytes
-rwxr-xr-xbundles/XO/res/table-add-column-before-active.gifbin0 -> 57 bytes
-rwxr-xr-xbundles/XO/res/table-add-column-before-hover.gifbin0 -> 825 bytes
-rwxr-xr-xbundles/XO/res/table-add-column-before.gifbin0 -> 825 bytes
-rwxr-xr-xbundles/XO/res/table-add-row-after-active.gifbin0 -> 57 bytes
-rwxr-xr-xbundles/XO/res/table-add-row-after-hover.gifbin0 -> 826 bytes
-rwxr-xr-xbundles/XO/res/table-add-row-after.gifbin0 -> 826 bytes
-rwxr-xr-xbundles/XO/res/table-add-row-before-active.gifbin0 -> 57 bytes
-rwxr-xr-xbundles/XO/res/table-add-row-before-hover.gifbin0 -> 825 bytes
-rwxr-xr-xbundles/XO/res/table-add-row-before.gifbin0 -> 825 bytes
-rwxr-xr-xbundles/XO/res/table-remove-column-active.gifbin0 -> 835 bytes
-rwxr-xr-xbundles/XO/res/table-remove-column-hover.gifbin0 -> 841 bytes
-rwxr-xr-xbundles/XO/res/table-remove-column.gifbin0 -> 841 bytes
-rwxr-xr-xbundles/XO/res/table-remove-row-active.gifbin0 -> 835 bytes
-rwxr-xr-xbundles/XO/res/table-remove-row-hover.gifbin0 -> 841 bytes
-rwxr-xr-xbundles/XO/res/table-remove-row.gifbin0 -> 841 bytes
-rwxr-xr-xbundles/XO/res/ua.css248
-rwxr-xr-xbundles/XO/res/unixcharset.properties622
-rwxr-xr-xbundles/XO/res/viewsource.css119
-rwxr-xr-xbundles/XO/run-mozilla.sh401
-rwxr-xr-xbundles/XO/searchplugins/amazondotcom.xml13
-rwxr-xr-xbundles/XO/searchplugins/answers.xml13
-rwxr-xr-xbundles/XO/searchplugins/creativecommons.xml11
-rwxr-xr-xbundles/XO/searchplugins/eBay.xml10
-rwxr-xr-xbundles/XO/searchplugins/google.xml17
-rwxr-xr-xbundles/XO/searchplugins/wikipedia.xml15
-rwxr-xr-xbundles/XO/searchplugins/yahoo.xml14
-rwxr-xr-xbundles/XO/setup.py21
-rwxr-xr-xbundles/XO/update.locale1
-rwxr-xr-xbundles/XO/updaterbin0 -> 70472 bytes
-rwxr-xr-xbundles/XO/updater.ini4
m---------bundles/xo0
944 files changed, 162206 insertions, 0 deletions
diff --git a/bundles/XO/MANIFEST b/bundles/XO/MANIFEST
new file mode 100644
index 0000000..10e4068
--- /dev/null
+++ b/bundles/XO/MANIFEST
@@ -0,0 +1,373 @@
+application.ini
+libssl3.so
+crashreporter.ini
+platform.ini
+libfreebl3.chk
+libxul.so
+removed-files
+libsqlite3.so
+firefox
+README.txt
+libnssutil3.so
+updater
+setup.py
+libxpcom.so
+firefox-bin
+libsoftokn3.chk
+libsmime3.so
+updater.ini
+run-mozilla.sh
+blocklist.xml
+libmozjs.so
+libnspr4.so
+libsoftokn3.so
+libnss3.so
+crashreporter-override.ini
+libplds4.so
+libnssckbi.so
+update.locale
+libnssdbm3.so
+libplc4.so
+libfreebl3.so
+crashreporter
+old-homepage-default.properties
+browserconfig.properties
+Throbber-small.gif
+mozilla-xremote-client
+res/charsetData.properties
+res/broken-image.gif
+res/charsetalias.properties
+res/table-remove-column-hover.gif
+res/svg.css
+res/table-add-row-before-active.gif
+res/langGroups.properties
+res/forms.css
+res/grabber.gif
+res/table-add-column-before-hover.gif
+res/arrowd.gif
+res/table-add-column-after-active.gif
+res/contenteditable.css
+res/viewsource.css
+res/table-add-column-after.gif
+res/table-remove-row-hover.gif
+res/table-add-row-before-hover.gif
+res/table-add-row-after.gif
+res/table-add-column-after-hover.gif
+res/html.css
+res/table-remove-column-active.gif
+res/table-remove-column.gif
+res/EditorOverride.css
+res/table-add-row-after-active.gif
+res/quirk.css
+res/language.properties
+res/table-add-column-before-active.gif
+res/table-add-row-after-hover.gif
+res/table-add-row-before.gif
+res/unixcharset.properties
+res/ua.css
+res/arrow.gif
+res/designmode.css
+res/table-add-column-before.gif
+res/table-remove-row-active.gif
+res/hiddenWindow.html
+res/table-remove-row.gif
+res/loading-image.gif
+res/mathml.css
+res/dtd/xhtml11.dtd
+res/dtd/mathml.dtd
+res/html/folder.png
+res/fonts/mathfontStandardSymbolsL.properties
+res/fonts/mathfont.properties
+res/fonts/mathfontSTIXSize1.properties
+res/fonts/mathfontUnicode.properties
+res/fonts/mathfontSTIXNonUnicode.properties
+res/entityTables/html40Special.properties
+res/entityTables/html40Symbols.properties
+res/entityTables/transliterate.properties
+res/entityTables/html40Latin1.properties
+res/entityTables/mathml20.properties
+res/entityTables/htmlEntityVersions.properties
+searchplugins/google.xml
+searchplugins/wikipedia.xml
+searchplugins/answers.xml
+searchplugins/creativecommons.xml
+searchplugins/eBay.xml
+searchplugins/amazondotcom.xml
+searchplugins/yahoo.xml
+icons/document.png
+icons/mozicon16.xpm
+icons/mozicon50.xpm
+icons/updater.png
+icons/mozicon128.png
+karma/copying
+karma/karma
+karma/index_nepal.html
+karma/index.html
+karma/readme
+karma/authors
+karma/js/jquery-1.3.2.min.js
+karma/js/jquery.jgrowl_minimized.js
+karma/js/updateDoc.sh
+karma/js/jquery-ui-1.7.2.core.js
+karma/js/jquery.ui.all.js
+karma/js/karma.Gettext.js
+karma/js/jquery.idTabs.min.js
+karma/js/jquery.karma.js
+karma/js/ui.tabs.js
+karma/po/es-SP_yes_no.po
+karma/po/karma.pot
+karma/po/es.po
+karma/po/ne.po
+karma/po/yes_no.pot
+karma/po/en-US.po
+karma/po/en-US_yes_no.po
+karma/po/ne-NP_yes_no.po
+karma/po/es-SP.po
+karma/po/he-IS_yes_no.po
+karma/css/karma.css
+karma/css/ui.base.css
+karma/css/ui.theme.css
+karma/css/chakra.css
+karma/css/ui.tabs.css
+karma/css/demos.css
+karma/css/ui.all.css
+karma/css/ui.core.css
+karma/examples/adding_up_to_10/exercise.html
+karma/examples/adding_up_to_10/index_knavbar.html
+karma/examples/adding_up_to_10/resources.html
+karma/examples/adding_up_to_10/index.html
+karma/examples/adding_up_to_10/js/lesson.js
+karma/examples/adding_up_to_10/po/he-IL.po
+karma/examples/adding_up_to_10/po/en.po
+karma/examples/adding_up_to_10/po/es.po
+karma/examples/adding_up_to_10/po/es-MX.po
+karma/examples/adding_up_to_10/css/knavbar.css
+karma/examples/adding_up_to_10/css/lesson.css
+karma/examples/adding_up_to_10/assets/en/sounds/en_incorrect.ogg
+karma/examples/adding_up_to_10/assets/en/sounds/en_correct.ogg
+karma/examples/adding_up_to_10/assets/he/sounds/he_incorrect.ogg
+karma/examples/adding_up_to_10/assets/he/sounds/he_correct.ogg
+karma/examples/adding_up_to_10/assets/ne/sounds/ne_incorrect.ogg
+karma/examples/adding_up_to_10/assets/ne/sounds/ne_correct.ogg
+karma/examples/adding_up_to_10/assets/es-MX/sounds/es-MX_incorrect.ogg
+karma/examples/adding_up_to_10/assets/es-MX/sounds/es-MX_correct.ogg
+karma/examples/adding_up_to_10/assets/generic/images/ball37px.png
+karma/examples/adding_up_to_10/assets/generic/images/flower37px.png
+karma/examples/adding_up_to_10/assets/generic/images/sidebar.png
+karma/examples/adding_up_to_10/assets/generic/images/happyMonkey.jpg
+karma/examples/adding_up_to_10/assets/generic/images/scorebox.png
+karma/examples/adding_up_to_10/assets/generic/images/sadChimp_120x125.png
+karma/examples/adding_up_to_10/assets/generic/images/yellowBox.png
+karma/examples/adding_up_to_10/assets/generic/images/chilli.png
+karma/examples/adding_up_to_10/assets/generic/images/fish64px.png
+karma/examples/adding_up_to_10/assets/generic/images/happyChimp_120x125.png
+karma/examples/adding_up_to_10/assets/generic/images/plussign.png
+karma/examples/adding_up_to_10/assets/generic/images/balloon37px.png
+karma/examples/adding_up_to_10/assets/generic/images/banana37px.png
+karma/examples/adding_up_to_10/assets/generic/images/normalChimp_120x125.png
+karma/examples/adding_up_to_10/assets/generic/sounds/incorrect.ogg
+karma/examples/adding_up_to_10/assets/generic/sounds/trigger.ogg
+karma/examples/adding_up_to_10/assets/generic/sounds/correct.ogg
+karma/assets/default/images/karma_logo_54x50.png
+karma/assets/default/images/nepali.png
+karma/assets/default/images/ui-bg_glass_55_fbf9ee_1x400.png
+karma/assets/default/images/karma_logo.png
+karma/assets/default/images/tutorial.png
+karma/assets/default/images/ui-bg_flat_75_ffffff_40x100.png
+karma/assets/default/images/health.png
+karma/assets/default/images/ui-bg_glass_75_e6e6e6_1x400.png
+karma/assets/default/images/ui-icons_2e83ff_256x240.png
+karma/assets/default/images/games_bw.png
+karma/assets/default/images/ui-icons_454545_256x240.png
+karma/assets/default/images/grade5_bw.png
+karma/assets/default/images/exercise.png
+karma/assets/default/images/week1.png
+karma/assets/default/images/week2.png
+karma/assets/default/images/week3.png
+karma/assets/default/images/week4.png
+karma/assets/default/images/chakra_logo_50x50.png
+karma/assets/default/images/resources_bw.png
+karma/assets/default/images/karma_logo_35x32.png
+karma/assets/default/images/profile.png
+karma/assets/default/images/chakra_logo.png
+karma/assets/default/images/science.png
+karma/assets/default/images/english.png
+karma/assets/default/images/help_50x50.png
+karma/assets/default/images/ui-bg_flat_0_aaaaaa_40x100.png
+karma/assets/default/images/back.png
+karma/assets/default/images/mystuff.png
+karma/assets/default/images/grade4_bw.png
+karma/assets/default/images/ui-bg_highlight-soft_75_cccccc_1x100.png
+karma/assets/default/images/exercise_bw.png
+karma/assets/default/images/preview1.jpg
+karma/assets/default/images/preview2.jpg
+karma/assets/default/images/preview3.jpg
+karma/assets/default/images/preview4.jpg
+karma/assets/default/images/ui-bg_glass_65_ffffff_1x400.png
+karma/assets/default/images/ui-bg_glass_95_fef1ec_1x400.png
+karma/assets/default/images/games.png
+karma/assets/default/images/help.png
+karma/assets/default/images/grade1.png
+karma/assets/default/images/grade2.png
+karma/assets/default/images/grade3.png
+karma/assets/default/images/favicon.ico
+karma/assets/default/images/grade4.png
+karma/assets/default/images/grade5.png
+karma/assets/default/images/ui-icons_888888_256x240.png
+karma/assets/default/images/grade6.png
+karma/assets/default/images/grade7.png
+karma/assets/default/images/grade8.png
+karma/assets/default/images/geography.png
+karma/assets/default/images/grade8_bw.png
+karma/assets/default/images/grade3_bw.png
+karma/assets/default/images/month_A.png
+karma/assets/default/images/month_B.png
+karma/assets/default/images/month_C.png
+karma/assets/default/images/month_D.png
+karma/assets/default/images/month_E.png
+karma/assets/default/images/month_F.png
+karma/assets/default/images/month_G.png
+karma/assets/default/images/month_H.png
+karma/assets/default/images/month_I.png
+karma/assets/default/images/month_J.png
+karma/assets/default/images/month_K.png
+karma/assets/default/images/month_L.png
+karma/assets/default/images/history.png
+karma/assets/default/images/ui-icons_cd0a0a_256x240.png
+karma/assets/default/images/ui-icons_222222_256x240.png
+karma/assets/default/images/music.png
+karma/assets/default/images/tutorial_bw.png
+karma/assets/default/images/ui-bg_glass_75_dadada_1x400.png
+karma/assets/default/images/grade7_bw.png
+karma/assets/default/images/olenepal_logo.gif
+karma/assets/default/images/grade2_bw.png
+karma/assets/default/images/resources.png
+karma/assets/default/images/back_bw.png
+karma/assets/default/images/karma_logo_50x46.png
+karma/assets/default/images/grade6_bw.png
+karma/assets/default/images/grade1_bw.png
+karma/assets/default/images/mathematics.png
+karma/chakra/grade1e_OLD.html
+karma/chakra/grade1mathematics.html
+karma/chakra/grade1.html
+karma/chakra/grade1english.html
+karma/chakra/index_OLD.html
+karma/chakra/css/chakra.css
+karma/chakra/css/jquery.jgrowl.css
+karma/chakra/css/chakra_OLD.css
+karma/chakra/templates/index_template.html
+karma/chakra/templates/grade_template.html
+karma/chakra/templates/listview_template.html
+defaults/pref/firefox-branding.js
+defaults/pref/firefox.js
+defaults/pref/firefox-l10n.js
+defaults/pref/channel-prefs.js
+defaults/pref/reporter.js
+defaults/autoconfig/prefcalls.js
+defaults/autoconfig/platform.js
+defaults/profile/mimeTypes.rdf
+defaults/profile/bookmarks.html
+defaults/profile/localstore.rdf
+defaults/profile/prefs.js
+defaults/profile/chrome/userChrome-example.css
+defaults/profile/chrome/userContent-example.css
+extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
+greprefs/security-prefs.js
+greprefs/all.js
+greprefs/xpinstall.js
+dictionaries/en-US.aff
+dictionaries/en-US.dic
+components/nsPrivateBrowsingService.js
+components/nsWebHandlerApp.js
+components/FeedConverter.js
+components/aboutCertError.js
+components/nsFilePicker.js
+components/nsBlocklistService.js
+components/libimgicon.so
+components/nsPlacesTransactionsService.js
+components/fuelApplication.js
+components/nsHelperAppDlg.js
+components/xpti.dat
+components/nsContentDispatchChooser.js
+components/nsSessionStore.js
+components/NetworkGeolocationProvider.js
+components/aboutRights.js
+components/nsLoginManager.js
+components/nsDownloadManagerUI.js
+components/aboutPrivateBrowsing.js
+components/nsMicrosummaryService.js
+components/nsAddonRepository.js
+components/nsLoginManagerPrompter.js
+components/FeedProcessor.js
+components/nsPlacesDBFlush.js
+components/storage-Legacy.js
+components/nsSidebar.js
+components/nsDefaultCLH.js
+components/libnkgnomevfs.so
+components/storage-mozStorage.js
+components/nsHandlerService.js
+components/nsSetDefaultBrowser.js
+components/nsProxyAutoConfig.js
+components/nsTaggingService.js
+components/jsconsole-clhandler.js
+components/nsURLFormatter.js
+components/nsUpdateService.js
+components/nsUrlClassifierListManager.js
+components/nsContentPrefService.js
+components/WebContentConverter.js
+components/aboutRobots.js
+components/libbrowserdirprovider.so
+components/nsTryToClose.js
+components/nsSessionStartup.js
+components/compreg.dat
+components/libdbusservice.so
+components/nsBrowserContentHandler.js
+components/nsSafebrowsingApplication.js
+components/nsLoginInfo.js
+components/txEXSLTRegExFunctions.js
+components/libmozgnome.so
+components/aboutSessionRestore.js
+components/nsBrowserGlue.js
+components/nsUrlClassifierLib.js
+components/libbrowsercomps.so
+components/nsLivemarkService.js
+components/FeedWriter.js
+components/nsExtensionManager.js
+components/pluginGlue.js
+components/nsSearchService.js
+components/nsSearchSuggestions.js
+components/browser.xpt
+components/nsBadCertHandler.js
+chrome/reporter.manifest
+chrome/comm.manifest
+chrome/browser.manifest
+chrome/en-US.manifest
+chrome/comm.jar
+chrome/classic.manifest
+chrome/en-US.jar
+chrome/pippki.jar
+chrome/pippki.manifest
+chrome/toolkit.manifest
+chrome/toolkit.jar
+chrome/classic.jar
+chrome/reporter.jar
+chrome/browser.jar
+chrome/icons/default/default16.png
+chrome/icons/default/default32.png
+chrome/icons/default/default48.png
+modules/distribution.js
+modules/debug.js
+modules/WindowDraggingUtils.jsm
+modules/ISO8601DateUtils.jsm
+modules/SpatialNavigation.js
+modules/DownloadLastDir.jsm
+modules/PlacesDBUtils.jsm
+modules/PluralForm.jsm
+modules/Microformats.js
+modules/DownloadUtils.jsm
+modules/XPCOMUtils.jsm
+modules/utils.js
+activity/activity.info
+activity/activity-firefox.svg
+activity/activity-karma.svg
+plugins/libnullplugin.so
diff --git a/bundles/XO/README.txt b/bundles/XO/README.txt
new file mode 100755
index 0000000..7b8e405
--- /dev/null
+++ b/bundles/XO/README.txt
@@ -0,0 +1,4 @@
+For information about installing, running and configuring Firefox
+including a list of known issues and troubleshooting information,
+refer to: http://getfirefox.com/releases/
+
diff --git a/bundles/XO/Throbber-small.gif b/bundles/XO/Throbber-small.gif
new file mode 100755
index 0000000..cce32f2
--- /dev/null
+++ b/bundles/XO/Throbber-small.gif
Binary files differ
diff --git a/bundles/XO/activity/activity-firefox.svg b/bundles/XO/activity/activity-firefox.svg
new file mode 100755
index 0000000..3fda2f6
--- /dev/null
+++ b/bundles/XO/activity/activity-firefox.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+ <!ENTITY stroke_color "#000">
+ <!ENTITY fill_color "#eee">
+]><svg height="55px" viewBox="0 0 55 55" width="55px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" stroke-linecap="round" stroke-linejoin="round" stroke-width="3.5" stroke="&stroke_color;" fill="&fill_color;">
+ <path d="M 53.9248 27.4056 C 53.9248 41.9873 41.9624 53.9862 27.4251 53.9862 C 20.3996 53.9862 13.6547 51.1838 8.68697 46.2009 C 3.71922 41.218 0.925383 34.4525 0.925383 27.4056 C 0.925383 20.3587 3.71922 13.5932 8.68697 8.61028 C 13.6547 3.62737 20.3996 0.825013 27.4251 0.825013 C 41.9624 0.825013 53.9248 12.8239 53.9248 27.4056 Z " stroke="none" />
+ <path d="M 23.696 40.8676 C 23.6638 40.7261 23.3132 40.3156 23.0448 40.2238 C 22.7773 40.132 22.5142 40.6195 22.3419 39.8102 C 21.7765 40.1352 21.5326 39.7206 21.5326 39.7206 C 21.5326 39.7206 20.923 39.7564 20.8051 40.5045 C 20.5148 40.8488 19.7708 42.1009 20.166 40.7986 C 20.5639 39.4883 19.7462 40.6957 19.6703 41.3537 C 19.5282 41.6461 19.2884 41.6756 19.4394 40.3608 C 18.9155 40.1795 18.648 38.9609 18.9352 38.9376 C 18.6015 38.4716 18.8637 37.7589 19.1415 37.797 C 19.4193 37.8328 19.8963 37.1881 19.8815 37.0386 C 19.8668 36.8895 20.0968 36.9961 20.0825 35.9928 C 20.0677 34.9869 20.4608 34.738 20.4929 35.5792 C 20.5269 36.4172 21.0262 35.3048 20.9748 34.8781 C 20.923 34.4533 21.0248 33.493 21.329 34.0607 C 20.9748 32.6563 21.2544 32.6008 21.467 33.5356 C 21.9998 33.5777 22.0181 33.8624 22.0181 33.8624 C 22.608 33.7169 22.8907 34.1623 22.9363 34.4121 C 23.4829 33.7652 24.0349 34.4627 24.0349 34.4627 C 24.0349 34.4627 24.4159 34.336 24.2337 34.9999 C 24.0506 35.6616 25.0251 35.3034 24.7924 34.828 C 25.2716 34.5849 25.983 35.3213 26.2072 35.8236 C 26.4314 36.3282 25.8231 37.0426 26.2974 37.2154 C 26.7744 37.3874 26.5654 38.2191 26.5654 38.2191 C 26.5654 38.2191 27.5622 38.7733 26.8704 39.2492 L 26.6346 39.8155 C 26.6346 39.8155 27.0857 40.3201 27.2393 40.0197 C 27.393 39.7188 27.4474 40.3254 27.4474 40.3254 C 27.3898 40.218 27.5582 40.9504 28.1799 41.1044 C 28.8042 41.257 29.1995 42.2459 28.5063 42.2585 C 27.8159 42.2697 27.7623 42.2509 27.5752 42.6551 C 27.3889 43.0576 26.5073 43.0719 26.0509 42.5508 C 25.5654 42.7156 24.7017 42.5034 24.9558 42.1139 C 24.5369 42.3588 24.1412 41.7011 24.4686 41.4079 C 24.7959 41.1156 24.2846 40.7368 24.1126 41.1559 C 23.9425 41.5744 23.039 41.7808 23.102 41.0686 C 23.1207 40.8573 23.6022 40.7337 23.6084 40.9101 C 23.6964 41.1138 23.7321 40.894 23.696 40.8676 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 27.807 33.4899 C 27.6565 33.6394 27.8293 34.0911 28.0227 34.0701 C 28.2165 34.0482 28.5184 33.9627 28.5184 33.9627 C 28.5184 33.9627 28.6689 34.2635 28.5184 34.3499 C 28.367 34.4349 27.9293 34.3982 28.4965 34.6073 C 29.0784 34.8222 29.2298 34.7577 29.2732 34.6503 C 29.3156 34.5428 29.5094 34.1775 29.6175 34.1986 C 29.7046 34.0056 29.3156 33.8342 29.5313 33.7052 C 29.747 33.575 29.5755 33.1027 29.5755 33.1027 C 29.5755 33.1027 29.2736 33.1242 29.1441 33.3395 C 29.0146 33.5539 28.8422 33.3176 28.7127 33.3176 C 28.6908 33.4465 28.6055 33.5539 28.6055 33.5539 L 28.5193 33.361 C 28.5188 33.361 27.9146 33.3395 27.807 33.4899 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 54.9208 20.1126 L 54.2839 24.2088 C 54.2839 24.2088 53.3733 16.6252 52.2572 13.7901 C 50.5467 9.44585 49.7857 9.48077 49.7808 9.48703 C 50.9263 12.4054 50.7187 13.9732 50.7187 13.9732 C 50.7187 13.9732 48.6888 8.42784 43.322 6.66356 C 36.9659 4.57517 33.728 5.32994 33.7522 5.35904 C 33.7763 5.38859 40.3213 6.50598 41.482 8.10462 C 41.482 8.10462 38.7019 8.10462 35.9352 8.90372 C 35.8101 8.93953 46.1146 10.1939 48.2212 20.5155 C 48.2212 20.5155 47.0918 18.1531 45.6948 17.752 C 46.6135 20.5535 46.3777 25.8696 45.5028 28.5118 C 45.3902 28.8516 45.275 27.043 43.5516 26.264 C 44.1036 30.2291 43.5185 36.518 40.7741 38.2505 C 40.5602 38.3852 42.4944 32.0421 41.1631 34.4945 C 33.2149 46.7101 23.7652 39.4368 19.9324 36.8443 C 23.0086 37.6 26.2764 37.0556 28.1683 35.7596 C 30.0775 34.4515 31.207 33.4953 32.2212 33.7214 C 33.235 33.9483 33.9098 32.9285 33.1224 32.0238 C 32.3342 31.1172 30.42 29.8714 27.8306 30.5505 C 26.0045 31.0299 23.7415 33.0552 20.287 31.0044 C 17.3399 29.254 17.36 27.8327 17.36 26.927 C 17.36 26.0209 18.1639 24.6439 19.6269 24.87 C 20.9373 25.0728 20.2468 24.3014 21.6568 24.87 C 22.0408 25.0249 21.6184 23.0215 21.0717 21.7381 C 22.1244 19.5359 25.5395 18.8814 25.7946 18.6885 C 26.2563 18.3384 26.0022 18.1638 26.1599 17.6365 C 26.3073 17.1454 26.4015 15.818 22.5794 16.1847 C 20.8207 16.3534 19.702 14.069 19.3353 13.5143 C 19.4541 12.8083 19.6448 12.1632 19.9029 11.5723 C 20.1651 11.0337 20.4514 10.5404 20.7372 10.167 C 20.8265 10.0502 20.9042 9.94769 20.9748 9.85234 C 21.5447 9.1862 22.244 8.61676 23.0837 8.14312 C 23.5218 7.89511 18.1849 8.12745 15.7835 11.2652 C 15.139 11.3494 14.2547 11.1631 13.2664 11.1631 C 12.0275 11.1631 11.0544 11.2988 10.1536 11.5257 C 10.0093 11.562 9.77664 11.5423 9.49215 11.4743 C 8.69943 10.651 6.45658 8.67227 6.35386 5.98847 C 6.35386 5.98847 3.09276 8.50081 3.58089 15.3502 C 3.53802 19.138 2.4224 18.055 1.84851 20.1108 C 1.58145 21.0849 2.25001 21.8186 2.25001 21.8473 C 2.24912 21.8621 3.05211 20.9761 3.05211 20.9761 C 3.05211 20.9761 -2.00479 29.7581 4.52591 40.9692 C 10.1549 50.634 19.601 54.9052 29.4031 54.0735 C 31.1176 53.9615 32.8447 53.7055 34.5677 53.2882 C 57.4039 47.7537 54.9208 20.1126 54.9208 20.1126 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 19.2585 13.1853 C 19.2585 13.1853 20.2455 15.8888 22.4593 15.8798 C 26.6829 15.8628 26.7673 15.9214 26.7945 16.4363 C 26.8785 18.0031 26.1067 18.5166 25.8115 18.7395 C 25.5154 18.962 21.4938 21.2993 21.3459 21.9677 C 21.1981 22.6356 16.7053 15.6116 16.7053 15.6116 L 19.2585 13.1853 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 21.5072 16.0996 C 21.5072 16.0996 22.8791 17.8554 21.8417 18.5578 C 20.5742 19.4155 23.6334 19.6031 24.7419 18.9795 C 25.8504 18.3559 26.531 17.4395 26.5699 17.303 C 26.6087 17.1664 26.9727 15.9358 24.6588 16.3646 C 23.1958 16.6359 22.6598 16.6986 21.5072 16.0996 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 25.812 18.7395 C 26.0362 18.5703 26.5337 18.2305 26.7239 17.3916 C 26.585 17.448 26.5721 17.2886 26.4082 17.3576 C 23.3021 20.6054 23.1833 18.3438 21.4879 18.7991 C 19.9427 19.223 19.5957 19.8046 19.5305 19.8498 C 19.5533 19.8824 19.5769 19.916 19.5997 19.9487 C 20.045 20.1752 20.4719 20.8987 20.7926 21.5442 C 21.1061 21.9185 21.3165 22.1029 21.3468 21.9673 C 21.4942 21.2989 25.5159 18.9616 25.812 18.7395 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 2.60506 21.3204 C 1.97088 22.654 -2.09858 29.5473 4.54288 41.0202 C 11.0419 52.2496 22.2896 55.917 33.7731 53.4252 C 37.0512 52.7143 40.8308 50.1433 43.2394 48.2568 C 41.6919 44.3442 42.6079 44.491 41.7785 45.0058 C 32.5276 50.7464 25.1738 45.0837 19.4822 44.3599 C -1.45591 41.6998 2.67875 21.2787 2.67875 21.2787 L 2.60506 21.3204 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 20.0401 37.0565 C 22.0136 37.6497 26.3193 37.1384 28.1687 35.7596 C 29.4147 34.8311 30.3562 34.131 31.148 33.8382 C 29.7483 32.8851 29.726 34.2362 26.7829 34.9193 C 20.6519 36.3452 17.6753 33.2652 17.6753 33.2652 C 18.1094 35.7023 19.6278 36.8891 20.3111 37.3104 C 20.1298 37.1492 20.0347 37.0547 20.0401 37.0565 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 13.3915 48.1861 C 13.3915 48.1861 8.28766 42.4129 6.86299 35.9476 C 4.76216 33.9586 3.2714 32.2767 2.28127 31.0604 C 2.85293 35.6611 5.19314 42.8037 13.3915 48.1861 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 9.13397 42.943 C 9.13397 42.943 5.6116 37.9165 6.93221 33.6484 C 8.12018 29.8114 6.67988 32.0941 5.84205 32.9142 C 4.99574 33.7428 4.56074 30.4681 4.58218 30.0907 C 4.58352 30.0827 4.58263 30.0791 4.58173 30.0786 C 4.52859 30.0675 2.90518 37.9246 9.13397 42.943 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 3.91585 38.5611 C 3.91585 38.5611 3.11285 28.3596 5.65091 26.9176 C 9.68151 24.6278 5.9872 25.1632 4.81843 25.7989 C 3.63717 26.4404 3.74658 22.2175 3.91361 21.8164 C 4.07752 21.4211 -0.246507 25.8087 3.91585 38.5611 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 21.5505 8.54245 C 21.5505 8.54245 18.3595 11.7912 18.3832 11.8024 C 18.4073 11.814 18.4747 15.9725 18.5788 17.1512 C 18.9611 17.6038 20.1526 20.5481 19.2406 19.8945 C 18.309 19.2275 18.9807 19.2132 19.062 19.5521 C 19.0642 19.5633 19.0642 19.5686 19.062 19.5686 C 19.0004 19.5973 16.7463 14.6787 21.5505 8.54245 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 6.37128 6.03906 C 6.37128 6.03906 2.97976 8.64675 3.62779 15.8006 C 6.25293 13.4382 9.96511 11.6721 9.96511 11.6721 C 9.34209 11.2791 6.48427 8.98743 6.37128 6.03906 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 14.7295 13.8621 L 19.8235 20.2124 C 18.3537 13.9763 19.4836 10.2346 23.1015 8.19371 C 23.637 7.89108 15.5427 8.30249 14.7295 13.8621 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 11.1406 29.5495 C 12.0092 24.0628 19.6269 24.8695 19.6269 24.8695 C 19.2871 25.1225 17.9821 25.2738 17.6083 26.3204 C 16.3748 29.776 17.5511 37.3247 25.2354 40.4906 C 26.046 40.8255 9.85703 37.6577 11.1406 29.5495 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 26.6802 17.5402 C 26.6427 17.5335 26.6096 17.5344 26.5931 17.5568 C 26.4993 17.6826 26.1371 18.1115 25.2756 18.8147 C 23.6754 20.1197 23.001 19.7893 21.8091 20.0566 C 21.2664 20.1779 20.7506 20.5432 20.4031 20.836 C 20.5438 21.0639 20.6751 21.3092 20.7921 21.5442 C 21.1057 21.9185 21.316 22.1029 21.3464 21.9673 C 21.4942 21.2989 25.5159 18.9616 25.812 18.7391 C 26.0219 18.5811 26.4676 18.2672 26.6802 17.5402 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 21.7689 25.8343 C 21.8135 24.6748 21.7327 21.8585 20.53 20.6363 C 19.6113 19.7029 19.3956 18.6334 19.2723 17.4126 C 9.28493 21.152 7.85892 26.0402 8.85753 25.8813 C 16.8455 24.6121 19.091 24.4568 21.7689 25.8343 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 0.475206 32.6863 C 0.475206 32.6863 1.16923 23.6469 5.68306 20.3386 C 9.22687 17.7399 6.47489 18.684 5.10649 18.7915 C 3.66352 18.9061 2.89402 19.7857 3.17225 19.4621 C 3.18431 19.4487 3.18833 19.441 3.1861 19.4375 C 3.13876 19.3815 -0.200953 22.1906 0.475206 32.6863 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 1.87542e-05 25.7416 C 1.87542e-05 25.7416 2.41883 18.0452 7.30736 18.1101 C 10.5493 18.1535 7.97772 15.3641 6.99697 14.9401 C 5.9738 14.501 5.72906 14.518 5.49013 14.7302 C 5.13195 15.048 1.91551 14.9254 1.87542e-05 25.7416 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 32.9764 33.275 C 33.344 32.9138 33.0876 31.5278 30.7773 30.6875 C 28.681 29.9242 25.4087 31.8649 24.4378 32.2481 C 24.4378 32.2481 28.1441 31.5519 29.534 31.7838 C 31.4178 32.0981 32.0796 34.1569 32.9764 33.275 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 3.57062 30.7394 C 3.57062 30.7394 3.16912 23.1728 6.55215 19.9411 C 9.20811 17.4028 7.02957 18.4839 5.90726 18.7216 C 4.72375 18.9732 4.18113 19.7857 4.37719 19.4872 C 4.38568 19.4746 4.38746 19.4679 4.38568 19.4652 C 4.33967 19.4245 1.8762 22.115 3.57062 30.7394 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 0.965131 28.3359 C 0.965131 28.3359 2.39471 20.8951 6.45524 18.5761 C 9.6431 16.7546 7.2694 17.2774 6.12252 17.2371 C 4.91312 17.1955 4.1914 17.8527 4.45311 17.6105 C 4.46428 17.6007 4.46785 17.5939 4.46651 17.5917 C 4.43257 17.5402 1.39476 19.5565 0.965131 28.3359 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 5.78623 31.3899 C 5.78623 31.3899 5.00467 26.88 6.68881 24.66 C 8.03309 22.8886 6.85272 23.7553 6.22881 24.0104 C 5.57766 24.2773 5.33069 24.8033 5.41956 24.6103 C 5.50576 24.4218 2.52199 26.7395 5.78623 31.3899 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 6.67944 27.137 C 6.67944 27.137 5.89788 22.6271 7.58202 20.4071 C 8.9263 18.6357 7.74593 19.5024 7.12202 19.7575 C 6.47087 20.0244 6.2239 20.5504 6.31277 20.3574 C 6.39897 20.169 3.4152 22.4866 6.67944 27.137 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 1.95525 20.9716 C 1.95525 20.9716 3.78053 17.2224 6.20693 16.4842 C 8.14341 15.8955 6.80984 15.904 6.21318 15.758 C 5.58972 15.6067 5.12749 15.8628 5.29586 15.7679 C 5.46021 15.6752 2.02224 15.7898 1.95525 20.9716 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 1.69488 23.9388 C 1.69488 23.9388 3.52016 20.1895 5.94656 19.4513 C 7.88304 18.8626 6.54947 18.8712 5.95281 18.7252 C 5.32935 18.5739 4.86711 18.83 5.03548 18.7351 C 5.19939 18.6419 1.76143 18.757 1.69488 23.9388 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 3.01996 23.1205 C 3.01996 23.1205 6.23953 16.5065 10.5202 15.2038 C 13.9368 14.1652 11.584 14.18 10.531 13.9235 C 9.43141 13.6562 8.61591 14.1088 8.91246 13.9409 C 9.20275 13.7766 3.13786 13.979 3.01996 23.1205 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 5.22083 19.5583 C 5.22083 19.5583 7.2234 15.4447 9.88561 14.6344 C 12.0106 13.9884 10.547 13.9978 9.89231 13.838 C 9.20811 13.6719 8.70121 13.953 8.88566 13.8487 C 9.06609 13.7466 5.29407 13.8724 5.22083 19.5583 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 5.87376 21.0115 C 5.87376 21.0115 7.69903 17.2622 10.1254 16.524 C 12.0619 15.9353 10.7284 15.9438 10.1317 15.7979 C 9.50823 15.6466 9.04599 15.9026 9.21436 15.8077 C 9.37827 15.7146 5.94031 15.8297 5.87376 21.0115 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 26.7949 16.4363 C 26.774 16.0454 26.7163 15.9179 24.8495 15.8861 C 25.0635 15.9832 25.4324 16.178 25.8383 16.5119 C 26.3747 16.9524 26.4618 17.4435 26.5172 17.9521 C 26.6989 17.6056 26.832 17.1279 26.7949 16.4363 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 15.8344 11.2137 L 14.2154 13.825 C 14.2154 13.825 7.74146 12.8074 2.25314 18.1298 C 1.79939 18.5694 5.84295 8.71838 15.8344 11.2137 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 10.0205 15.8874 C 10.0205 15.8874 11.7457 12.6767 13.9828 11.7066 C 12.8265 11.7433 10.2299 12.6494 10.0205 15.8874 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 3.38215 19.0211 C 3.38215 19.0211 5.20743 15.2719 7.63383 14.5337 C 9.57031 13.945 8.23675 13.9535 7.64008 13.8075 C 7.01662 13.6562 6.55439 13.9123 6.72276 13.8174 C 6.88711 13.7247 3.4487 13.8393 3.38215 19.0211 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 7.20598 16.3794 C 7.20598 16.3794 9.08931 13.3572 11.3304 12.5527 C 10.2018 12.5155 7.61329 13.2358 7.20598 16.3794 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 10.4349 11.2173 C 10.4349 11.2173 9.01473 11.8391 6.51062 10.7956 L 8.7432 11.9206 L 10.4349 11.2173 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 9.7485 11.6162 C 9.7485 11.6162 7.85579 12.3512 4.21329 11.2571 L 7.32925 12.4999 C 7.71467 12.1426 9.7485 11.6162 9.7485 11.6162 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 11.1298 11.0136 C 11.1298 11.0136 9.87355 11.3968 7.55299 10.497 L 9.78557 11.622 C 10.0214 11.4129 11.1298 11.0136 11.1298 11.0136 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 7.21224 12.4614 C 7.21224 12.4614 6.27883 13.2381 3.88816 13.2699 L 5.95594 13.3375 L 7.21224 12.4614 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 4.94125 16.4358 C 4.94125 16.4358 8.13581 12.2644 10.7668 11.3198 C 9.44124 11.2764 5.41867 12.7461 4.94125 16.4358 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 54.4197 23.5489 C 54.4197 23.5489 54.764 31.2883 44.0388 42.0396 C 42.8468 43.234 36.3751 49.3116 36.6028 51.1349 C 36.6828 51.7791 53.5832 48.5362 54.4197 23.5489 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 33.6262 5.34472 C 46.5447 6.33945 49.0466 15.6506 49.0475 15.0807 C 49.0801 6.02876 36.7909 5.34158 33.6262 5.34472 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 37.5604 8.88447 C 37.5604 8.88447 46.5161 10.7195 49.0421 20.2348 C 49.3771 21.495 47.9631 12.5048 48.3994 13.3581 C 48.8349 14.2158 44.7949 9.16874 37.5604 8.88447 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 41.1399 8.65168 C 41.1399 8.65168 49.2279 10.3416 49.3083 23.2051 C 49.365 32.3098 50.7111 26.6231 52.0464 24.5767 C 53.1978 22.8093 52.4108 20.6551 52.3832 20.6605 C 52.3787 20.6618 51.8003 18.9849 52.1902 19.6953 C 52.2076 19.7267 51.6472 19.2324 51.6512 19.232 C 51.7409 19.2185 51.3399 9.98664 41.1399 8.65168 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 50.2475 10.3945 C 50.2475 10.3945 53.1527 17.9803 50.0738 21.7524 C 49.0689 22.9835 48.9564 29.2907 50.1841 28.7115 C 51.4149 28.1313 51.1474 32.0605 50.9862 32.5077 C 50.9826 32.5162 50.9817 32.5203 50.9835 32.5216 C 51.0639 32.5713 57.0537 22.825 50.2475 10.3945 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 46.2088 18.3805 C 46.2088 18.3805 48.0377 23.7477 46.1227 27.5847 L 47.5714 30.828 C 48.6339 28.2118 49.9867 22.6791 46.2088 18.3805 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 49.4253 17.7421 C 49.4253 17.7421 50.6901 26.2613 46.1262 33.9515 C 46.1968 35.7301 45.8855 37.3399 45.4581 38.6664 C 45.6568 38.9287 45.923 39.1082 46.2741 39.1395 C 46.1191 39.2828 45.965 39.4171 45.8158 39.5442 C 45.5416 39.6656 45.2607 39.794 44.9887 39.9261 C 44.9307 40.0617 44.8722 40.1934 44.815 40.3196 C 45.1187 40.1061 45.4572 39.8469 45.8154 39.5447 C 46.7475 39.1319 47.5862 38.8114 47.5844 38.8096 C 47.5844 38.8096 47.4133 38.8736 47.0025 39.0236 C 46.726 39.1243 46.4844 39.1583 46.2736 39.1395 C 49.7982 35.9199 54.6278 28.72 49.4253 17.7421 Z M 44.1076 40.3899 C 43.7047 40.6267 43.4118 40.8488 43.3492 41.0202 C 43.3032 41.1451 43.5779 41.073 44.0526 40.8058 C 44.0772 40.663 44.0973 40.5229 44.1076 40.3899 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 43.7963 26.8191 C 43.7963 26.8191 47.3946 37.0852 35.8945 46.7101 C 35.2161 47.2782 40.5624 47.0351 41.0305 46.8221 C 42.4087 46.1944 44.0375 42.0064 43.8454 42.5078 C 43.6547 43.0088 49.1855 35.1051 43.7963 26.8191 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 48.8286 33.3305 C 48.8286 33.3305 46.6581 46.6461 31.6518 47.7174 C 25.7758 48.1373 17.339 46.7589 18.0862 49.0054 C 18.3179 49.7019 19.4224 52.606 21.943 53.2797 C 28.7649 55.104 46.9149 54.5068 48.8286 33.3305 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 36.3134 43.4072 C 36.3134 43.4072 27.1317 45.5099 21.1834 40.4342 C 15.7406 35.7887 18.4408 39.6987 19.179 41.6273 C 19.9373 43.6051 15.6718 42.0937 15.0305 41.7759 C 14.3914 41.4621 25.134 48.2152 36.3134 43.4072 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 30.3964 48.4238 C 30.3964 48.4238 19.4434 46.266 15.9755 38.8266 C 13.0123 32.471 13.7965 37.1349 13.663 39.2573 C 13.5228 41.4406 10.4515 38.4591 10.041 37.9402 C 10.0294 37.9277 10.0214 37.9192 10.0205 37.9214 C 9.9593 37.9617 15.6696 46.9349 30.3964 48.4238 Z " fill="&stroke_color;" stroke="none" />
+ <path d="M 18.4314 47.4618 C 18.4314 47.4618 13.1999 43.4 10.8413 37.8305 C 8.85931 37.1402 6.2239 35.5622 6.17165 35.2922 C 7.00903 39.6199 11.4175 44.6728 18.4314 47.4618 Z " fill="&stroke_color;" stroke="none" />
+</svg> \ No newline at end of file
diff --git a/bundles/XO/activity/activity-karma.svg b/bundles/XO/activity/activity-karma.svg
new file mode 100755
index 0000000..340c4db
--- /dev/null
+++ b/bundles/XO/activity/activity-karma.svg
@@ -0,0 +1,64 @@
+<?xml version="1.0" ?><!-- Created with Inkscape (http://www.inkscape.org/) --><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd' [
+ <!ENTITY stroke_color "none">
+ <!ENTITY fill_color "#fefefe">
+]><svg height="55px" id="svg2" inkscape:version="0.47pre4 r22446" sodipodi:docname="karma-logo-sugar.svg" style="" version="1.1" width="55px" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg">
+ <defs id="defs4" style="">
+ <inkscape:perspective id="perspective10" inkscape:persp3d-origin="372.04724 : 350.78739 : 1" inkscape:vp_x="0 : 526.18109 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="744.09448 : 526.18109 : 1" sodipodi:type="inkscape:persp3d" style=""/>
+ <inkscape:perspective id="perspective2920" inkscape:persp3d-origin="0.5 : 0.33333333 : 1" inkscape:vp_x="0 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="1 : 0.5 : 1" sodipodi:type="inkscape:persp3d" style=""/>
+ <inkscape:perspective id="perspective3012" inkscape:persp3d-origin="0.5 : 0.33333333 : 1" inkscape:vp_x="0 : 0.5 : 1" inkscape:vp_y="0 : 1000 : 0" inkscape:vp_z="1 : 0.5 : 1" sodipodi:type="inkscape:persp3d" style=""/>
+ </defs>
+ <sodipodi:namedview bordercolor="#666666" borderopacity="1.0" id="base" inkscape:current-layer="layer1" inkscape:cx="-55.5" inkscape:cy="37.999997" inkscape:document-units="px" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:window-height="551" inkscape:window-maximized="1" inkscape:window-width="1024" inkscape:window-x="0" inkscape:window-y="25" inkscape:zoom="1" pagecolor="#ffffff" showgrid="false" style=""/>
+ <metadata id="metadata7" style="">
+ <rdf:RDF style="">
+ <cc:Work rdf:about="" style="">
+ <dc:format style="">image/svg+xml</dc:format>
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" style=""/>
+ <dc:title style=""/>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g id="layer1" inkscape:groupmode="layer" inkscape:label="Layer 1" style="" transform="translate(-430.5,-515.36218)">
+ <g id="g3018" style="" transform="matrix(0.69567681,0,0,0.65444403,197.10043,194.47428)">
+ <path d="m 335.5,532.36218 0,-42 39.5,0 39.5,0 0,42 0,42 -39.5,0 -39.5,0 0,-42 z" id="path3098" style="fill:&fill_color;"/>
+ <path d="m 361,570.48234 c -8.62335,-2.27674 -17.68726,-10.03896 -21.4304,-18.35273 -1.05673,-2.34709 -2.47177,-8.16999 -3.14453,-12.93979 -1.07701,-7.63592 -1.03465,-8.86092 0.35444,-10.25 2.29839,-2.2984 3.60164,-1.94235 4.29125,1.17236 2.25254,10.17382 6.14989,18.01065 11.57541,23.27595 9.53897,9.25725 21.85383,6.6021 21.85383,-4.71181 0,-3.87949 -3.13256,-12.31414 -4.57338,-12.31414 -0.293,0 -2.18831,1.125 -4.21181,2.5 -5.48599,3.72783 -7.62637,3.32933 -9.57895,-1.78343 -2.53341,-6.63364 -2.189,-8.00845 2.56589,-10.24245 5.35199,-2.51454 8.69225,-6.8387 7.15314,-9.26016 -1.17784,-1.85306 -7.14608,-2.14757 -14.92782,-0.73661 l -4.07292,0.73849 -1.75355,-4.59159 c -0.96445,-2.52537 -1.60115,-5.38643 -1.41489,-6.35792 0.65759,-3.42987 13.2303,-5.57946 19.24919,-3.29108 2.20035,0.83657 2.5651,0.70277 2.5651,-0.94098 0,-3.09613 1.44909,-3.17584 7.48651,-0.41182 6.66737,3.05243 10.13959,2.82844 17.73717,-1.14423 8.01607,-4.19149 10.37331,-1.50676 4.52632,5.15516 -2.51559,2.86621 -2.75642,3.439 -1.06574,2.5348 3.04737,-1.62979 11.85311,-1.45878 15.24666,0.2961 3.62967,1.87697 4.21911,4.55236 4.7447,21.53572 0.71322,23.04597 -2.30222,29 -14.68714,29 -9.38294,0 -11.55337,-3.366 -12.24532,-18.99063 -0.24592,-5.55298 -1.56527,-7.09205 -4.46944,-5.21376 -0.92915,0.60093 -0.69169,1.87274 0.97999,5.24875 2.95496,5.96764 3.58223,16.39176 1.27851,21.2465 -2.51697,5.30413 -7.95256,8.60616 -15.07717,9.15915 -3.27528,0.25422 -7.30505,0.10578 -8.95505,-0.32985 z m 43.35652,-25.65289 c 7.35624,-6.18986 6.4503,-21.0922 -1.50251,-24.71574 -3.32479,-1.51488 -8.0394,0.88587 -7.49578,3.81696 0.19703,1.06233 0.57845,6.20651 0.8476,11.43151 0.64924,12.60338 2.23485,14.44513 8.15069,9.46727 z M 378.5,521.86218 c 1.375,-0.78602 3.625,-1.47289 5,-1.52637 1.99129,-0.0775 3.04485,-1.19886 5.17761,-5.51106 l 2.67761,-5.41381 -2.42818,1.591 c -2.89741,1.89845 -11.16805,2.1044 -14.42881,0.35929 -2.08126,-1.11385 -2.22216,-1.05313 -1.47249,0.63462 0.45595,1.02648 1.01762,4.00383 1.24815,6.61633 0.46022,5.21555 0.59987,5.32295 4.22611,3.25 z m -6.8,-25.7 c -0.66,-0.66 -1.2,-1.59214 -1.2,-2.07143 0,-1.34299 2.70075,-3.73233 4.17857,-3.69677 2.18969,0.0527 4.5294,2.36846 4.00926,3.9682 -0.97327,2.99334 -4.80697,3.98086 -6.98783,1.8 z m 12.15674,-1.31273 c -0.69285,-1.80555 1.30152,-4.48727 3.33713,-4.48727 2.13184,0 4.58746,2.82449 3.93464,4.5257 -0.75699,1.97268 -6.51171,1.94226 -7.27177,-0.0384 z" id="path3096" style="fill:#fafafa"/>
+ <path d="m 362.5,570.47288 c -5.73157,-1.21874 -10.78615,-4.09436 -15.37069,-8.74458 -6.22925,-6.3185 -9.13305,-12.47295 -10.63412,-22.53848 -1.17877,-7.90428 -1.14157,-8.82412 0.42003,-10.38572 2.2688,-2.2688 3.25593,-1.12467 5.08357,5.89214 3.78259,14.52234 13.10942,24.66594 22.67983,24.66594 6.5102,0 11.456,-6.4169 10.16446,-13.18781 -0.73441,-3.8502 -4.04824,-10.83088 -5.1134,-10.77155 -0.40133,0.0223 -2.28768,1.37235 -4.19191,3 -4.80212,4.10465 -6.741,3.82858 -9.0647,-1.29064 -2.88081,-6.34657 -2.57896,-7.56136 2.41033,-9.70002 4.84312,-2.076 7.6166,-5.2794 7.6166,-8.79724 0,-3.67129 -3.9901,-4.59936 -11.58506,-2.69462 -3.49727,0.87708 -6.75458,1.35 -7.23847,1.05094 -0.4839,-0.29906 -1.66441,-2.5982 -2.62337,-5.10919 -2.06454,-5.40591 -1.29472,-6.92175 4.30514,-8.47717 5.12132,-1.42251 9.61975,-1.26765 13.78984,0.47472 3.44355,1.43881 3.5634,1.41928 3.06176,-0.499 -0.81333,-3.11018 0.97563,-3.38002 6.53968,-0.98642 6.06138,2.60753 11.55589,2.33382 17.72774,-0.88313 4.98997,-2.60092 7.02274,-2.69696 7.02274,-0.33182 0,1.91825 -6.06082,8.2297 -9.68426,10.08472 -3.10667,1.59046 -9.9025,1.38329 -13.3654,-0.40745 -3.42846,-1.77292 -3.40789,-1.81364 -1.45034,2.87144 0.825,1.9745 1.5,5.1886 1.5,7.14245 l 0,3.55244 3.96016,-2.02033 c 2.17809,-1.11117 4.78842,-2.02032 5.80074,-2.02032 1.19144,0 2.61327,-1.59045 4.03152,-4.50964 2.72916,-5.61743 7.19218,-8.4834 13.20758,-8.48136 10.31567,0.004 12.96231,4.98086 12.98494,24.42 0.0193,16.57941 -1.32971,21.47554 -6.97665,25.321 -5.00141,3.40586 -12.26982,3.14231 -15.992,-0.57986 -2.83215,-2.83215 -3.53508,-5.73955 -4.27017,-17.66182 -0.18372,-2.97971 -0.71671,-4.08095 -2.10234,-4.34378 -3.53562,-0.67066 -4.02409,1.42288 -1.51913,6.51081 1.82229,3.70131 2.37535,6.4726 2.37535,11.90249 0,6.25906 -0.33338,7.51493 -2.88182,10.85611 -4.32544,5.67093 -12.65822,8.36933 -20.61818,6.67675 z m 41.88313,-24.74139 c 6.31103,-4.42043 6.98074,-18.50544 1.1568,-24.32938 -2.29028,-2.29028 -6.84346,-2.67911 -9.24997,-0.78993 -1.3655,1.07196 -1.49279,2.83858 -0.89372,12.40342 0.88163,14.07619 2.92234,16.96366 8.98689,12.71589 z m -33.29351,-50.99637 c -0.62828,-1.63725 1.8288,-4.27883 4.03794,-4.34114 1.75078,-0.0494 3.66125,2.77319 3.0157,4.45547 -0.79464,2.07079 -6.24906,1.98239 -7.05364,-0.11433 z M 384.5,495.37533 c -1.16072,-0.73993 -1.24957,-1.35848 -0.39282,-2.73468 1.50093,-2.41093 4.05242,-2.76173 5.99054,-0.82361 2.97338,2.97339 -1.77768,5.99349 -5.59772,3.55829 z" id="path3094" style="fill:#f6f6f6"/>
+ <path d="m 356.86299,568.4397 c -8.90129,-4.04196 -18.17662,-15.47591 -19.44766,-23.97367 -0.37874,-2.53212 -1.0223,-6.71583 -1.43012,-9.29713 -0.58012,-3.67177 -0.39632,-5.03846 0.84444,-6.27923 1.44793,-1.44792 1.70955,-1.38759 3.0063,0.69328 0.7812,1.25358 1.69035,3.74881 2.02035,5.54496 0.97069,5.28342 5.36587,13.6414 9.30821,17.70069 12.46186,12.83157 28.21204,5.72086 22.88081,-10.32996 -2.43787,-7.33974 -3.50438,-7.82897 -8.85121,-4.06017 -2.47077,1.74155 -4.99414,2.85631 -5.6075,2.47724 -1.77412,-1.09647 -5.27804,-8.61228 -4.70784,-10.0982 0.28508,-0.74292 2.00398,-2.10193 3.81978,-3.02002 5.21586,-2.63721 7.80145,-5.49775 7.80145,-8.63106 0,-5.18796 -4.38233,-5.82571 -15.70149,-2.285 -1.77956,0.55666 -2.59831,0.0458 -4.27203,-2.6653 -1.17371,-1.90122 -1.95272,-4.64141 -1.79851,-6.32634 0.2417,-2.64097 0.82952,-3.13018 5.27203,-4.38765 4.85886,-1.37532 10.62444,-0.90065 15.67704,1.29068 1.31752,0.57142 1.56681,0.30585 1.16288,-1.23879 -0.76281,-2.91699 0.72882,-3.24589 5.17894,-1.14194 5.55849,2.62798 11.8981,2.43474 18.32826,-0.55867 5.03972,-2.34612 7.15288,-2.49648 7.15288,-0.50895 0,1.79552 -5.40021,7.18123 -9.08595,9.06156 -4.89447,2.49697 -9.46214,2.48222 -14.17886,-0.0458 -2.05435,-1.10107 -3.73519,-1.87122 -3.73519,-1.71144 0,0.15977 0.9,2.05579 2,4.21338 1.1,2.15759 2,5.62773 2,7.71144 0,2.08371 0.12985,3.78856 0.28856,3.78856 0.15871,0 2.05385,-0.9 4.21144,-2 2.15759,-1.1 4.66695,-2 5.57636,-2 0.95671,0 2.65853,-1.95189 4.03856,-4.63201 5.64155,-10.95634 21.03174,-11.31627 24.57377,-0.57472 1.48729,4.51038 1.366,28.2031 -0.17917,34.99691 -1.49047,6.55331 -11.65572,11.04876 -18.5378,8.1981 -4.29909,-1.78074 -6.13377,-6.03817 -6.73162,-15.62096 -0.53808,-8.6249 -1.18156,-9.68383 -5.01804,-8.25781 l -2.27794,0.84671 2.61437,5.1592 c 5.71483,11.27769 3.70625,22.30097 -4.9924,27.39871 -5.3843,3.15542 -14.93595,3.40921 -21.2031,0.56339 z m 48.33773,-23.32752 c 3.37776,-3.70847 4.29928,-6.33073 4.29928,-12.23392 0,-8.92839 -3.31932,-13.51608 -9.77927,-13.51608 -3.55783,0 -6.53692,2.88567 -5.18545,5.02284 0.51375,0.81244 0.94098,5.16036 0.94941,9.66206 0.0196,10.49651 1.03915,13.3151 4.81624,13.3151 1.68213,0 3.69041,-0.92221 4.89979,-2.25 z m -33.62259,-50.60401 c -0.80107,-1.49682 -0.51318,-2.11038 1.49433,-3.18477 2.1139,-1.13132 2.71246,-1.10488 3.9938,0.17646 0.84698,0.84699 1.22524,2.24209 0.86349,3.18478 -0.86486,2.25379 -5.11417,2.13573 -6.35162,-0.17647 z M 384.5,494.86218 c -0.99319,-1.19672 -0.99319,-1.80328 0,-3 2.50662,-3.02029 7.705,-0.51114 5.84113,2.8194 -1.1669,2.08514 -4.1831,2.1784 -5.84113,0.1806 z" id="path3092" style="fill:#f3f3f3"/>
+ <path d="m 359.26404,569.36647 c -10.87909,-3.27574 -20.07819,-15.27441 -22.66642,-29.56448 -1.48668,-8.20828 -1.38673,-10.11489 0.5696,-10.8656 2.27645,-0.87356 2.7586,-0.1317 5.15999,7.9394 4.04025,13.57934 12.72862,22.48639 21.93431,22.48639 5.40589,0 7.78185,-1.21629 9.72813,-4.97998 2.44637,-4.73077 1.35976,-12.51453 -2.39421,-17.15048 l -1.85474,-2.29051 -3.55363,2.71049 c -5.28333,4.02979 -7.40364,3.60547 -9.87246,-1.97572 l -2.07293,-4.68621 2.23994,-1.81379 c 1.23197,-0.99759 2.80373,-1.8138 3.4928,-1.8138 0.68907,0 2.43922,-1.18636 3.88922,-2.63636 2.80134,-2.80135 3.47851,-7.12149 1.43636,-9.16364 -1.6338,-1.6338 -6.67462,-1.50834 -11.78075,0.29321 -2.32772,0.82126 -4.68021,1.21633 -5.22776,0.87792 -1.32442,-0.81853 -3.79149,-6.81637 -3.79149,-9.21769 0,-3.5299 9.3869,-5.84022 16.47612,-4.05514 8.02435,2.02056 13.52388,9.5972 13.52388,18.63171 l 0,2.99797 4.66948,-2.36399 c 2.56821,-1.30019 5.29117,-2.36399 6.05102,-2.36399 0.75986,0 1.9943,-1.4625 2.74321,-3.25 4.9028,-11.70199 21.32231,-13.14455 25.12874,-2.20771 2.13578,6.13661 1.88401,28.60687 -0.3916,34.95121 -2.30452,6.4249 -7.46926,9.80831 -13.99143,9.16574 -7.64126,-0.75283 -10.07071,-4.51716 -11.07433,-17.15924 -0.61749,-7.77831 -0.70378,-7.99228 -3.11383,-7.72126 -3.81538,0.42905 -4.30079,1.62843 -2.15481,5.32426 2.93455,5.05393 4.39228,11.68599 3.65267,16.61809 -0.76556,5.10508 -5.33707,10.88707 -10.22138,12.92787 -3.52973,1.47481 -12.19712,1.66109 -16.5337,0.35533 z m 46.10866,-24.10032 c 3.10793,-2.89547 4.1273,-6.06209 4.1273,-12.82119 0,-8.01908 -2.94428,-12.46249 -8.53264,-12.87718 -2.30805,-0.17127 -4.78729,0.30572 -5.92779,1.14045 -1.70279,1.24629 -1.80135,1.78398 -0.75,4.09146 0.66574,1.46113 1.21043,6.26501 1.21043,10.67528 0,4.41028 0.46583,8.88911 1.03518,9.95295 1.38597,2.5897 5.97432,2.50571 8.83752,-0.16177 z M 375.5,510.82012 c -6.25849,-2.80427 -11.62066,-9.45794 -7.62212,-9.45794 0.75783,0 2.99337,0.675 4.96788,1.5 5.26786,2.20105 11.37737,1.8421 17.54958,-1.0311 2.96743,-1.38136 5.63871,-2.26818 5.93618,-1.97072 1.30651,1.30651 -1.69074,6.15918 -5.42547,8.78405 -4.97721,3.49811 -10.66278,4.30105 -15.40605,2.17571 z m -3.64326,-15.97067 c -0.66274,-1.72708 1.27073,-4.48727 3.14326,-4.48727 0.69031,0 1.81531,0.675 2.5,1.5 0.99319,1.19672 0.99319,1.80328 0,3 -1.60864,1.9383 -4.89743,1.93087 -5.64326,-0.0127 z m 13.12214,0.12094 c -1.61719,-1.18252 -1.7027,-1.6336 -0.56869,-3 1.65117,-1.98953 3.78367,-2.0572 5.66124,-0.17964 1.23809,1.2381 1.21905,1.6381 -0.14286,3 -1.92655,1.92655 -2.53067,1.94847 -4.94969,0.17964 z" id="path3090" style="fill:#efefef"/>
+ <path d="m 359.19799,568.91825 c -8.24175,-2.93978 -16.23195,-10.75604 -19.99125,-19.55607 -1.53139,-3.58479 -3.70674,-13.97415 -3.70674,-17.70321 0,-2.15827 2.80723,-3.9546 4.03126,-2.57957 0.38325,0.43053 1.24225,3.03278 1.90889,5.78278 1.73977,7.17688 6.79978,16.12155 11.29821,19.97203 6.93323,5.93459 16.21715,6.50901 20.56003,1.2721 3.22837,-3.89295 2.29737,-14.31426 -1.75923,-19.69222 l -1.83756,-2.4361 -3.6356,3.19209 c -4.80188,4.21611 -7.27141,4.14141 -9.11703,-0.27578 -2.31762,-5.54686 -1.88828,-7.03027 2.62363,-9.06486 4.94515,-2.22995 6.9274,-4.85412 6.9274,-9.17071 0,-4.7858 -2.38581,-5.19443 -15.69267,-2.68779 -2.96019,0.55762 -3.30856,0.32405 -4.78409,-3.20739 -0.87528,-2.09484 -1.45808,-4.50121 -1.2951,-5.34747 0.7595,-3.94377 13.68434,-5.70188 19.56428,-2.66125 6.12829,3.16907 11.07726,12.27758 9.93043,18.27683 -0.53869,2.818 -0.30782,2.84566 3.65912,0.43839 1.71491,-1.04067 4.46803,-2.19186 6.11803,-2.5582 2.23114,-0.49538 3.51258,-1.72706 5,-4.80587 2.78603,-5.76677 6.38237,-8.12841 12.37809,-8.12841 10.51291,0 13.12866,4.74115 13.10685,23.75673 -0.021,18.29476 -2.71779,24.65057 -11.27866,26.58136 -9.65231,2.17695 -13.45637,-1.62419 -15.12374,-15.11213 -1.21561,-9.83346 -2.22685,-11.28436 -5.96157,-8.55346 -1.7703,1.29447 -1.74621,1.53344 0.63299,6.2789 4.5483,9.07184 4.40407,16.78435 -0.42875,22.92829 -4.54596,5.77925 -14.81403,8.02624 -23.12722,5.06099 z m 47.84243,-24.90934 c 4.25018,-6.04573 4.15869,-16.474 -0.18987,-21.64198 -1.97578,-2.34807 -3.34133,-3.00475 -6.24831,-3.00475 -2.04599,0 -4.57568,0.6257 -5.62154,1.39045 -1.64352,1.20178 -1.7373,1.75095 -0.69113,4.04706 0.66574,1.46113 1.21043,6.46042 1.21043,11.10954 0,7.06421 0.32224,8.7752 1.96143,10.41438 1.65829,1.65829 2.43345,1.79688 5.01563,0.89672 1.67981,-0.58558 3.73333,-2.03073 4.56336,-3.21142 z M 377.18498,511.34532 C 372.99045,510.0863 367.5,505.53178 367.5,503.31129 c 0,-2.28968 1.53851,-2.42787 5,-0.44911 3.65027,2.08668 12.69268,1.82241 17.8592,-0.52196 2.39757,-1.08792 4.76007,-1.97804 5.25,-1.97804 3.91978,0 -4.82988,9.48591 -10.15955,11.01444 -3.92608,1.12598 -4.41527,1.12413 -8.26467,-0.0313 z m -5.32824,-16.49587 c -0.61075,-1.5916 1.22008,-4.48727 2.83713,-4.48727 2.00542,0 3.60443,2.60903 2.64726,4.3194 -1.17073,2.09198 -4.70453,2.20015 -5.48439,0.16787 z M 384.5,494.44397 c 0,-3.78052 4.16138,-5.70958 5.39301,-2.5 1.08091,2.8168 0.65988,3.41821 -2.39301,3.41821 -1.65,0 -3,-0.4132 -3,-0.91821 z" id="path3088" style="fill:#e9e9e9"/>
+ <path d="m 361,569.48447 c -6.93193,-1.82011 -15.46576,-9.03085 -20.28565,-17.14056 -1.99429,-3.35549 -5.2118,-16.08396 -5.21353,-20.62474 -6.6e-4,-1.73348 1.68406,-3.35699 3.48357,-3.35699 0.17644,0 1.30102,3.2625 2.49906,7.25 2.72396,9.06635 5.78071,14.40077 10.90454,19.02984 7.21409,6.51749 15.86661,7.17738 20.58498,1.56992 3.97556,-4.7247 3.19683,-13.82698 -1.73509,-20.28066 -1.43413,-1.87662 -1.58407,-1.84149 -5.33458,1.25 -4.94385,4.07514 -6.63918,4.00649 -8.71809,-0.35303 -2.58367,-5.41801 -2.16526,-6.71008 3.06534,-9.46607 5.62999,-2.96642 7.75236,-6.54705 6.2394,-10.52643 -0.99577,-2.61907 -1.22502,-2.69122 -6.76033,-2.12754 -3.15129,0.3209 -7.13841,0.86751 -8.86026,1.21469 -2.98626,0.60213 -3.21258,0.41667 -4.90753,-4.02149 -1.66941,-4.37128 -1.67449,-4.75516 -0.0841,-6.34598 2.65056,-2.65128 16.52249,-2.39861 20.23358,0.36854 4.9388,3.68258 6.73138,7.02767 7.1941,13.42477 0.23923,3.30739 0.62381,6.01344 0.85462,6.01344 0.2308,0 2.08922,-0.83615 4.12981,-1.8581 2.04059,-1.02196 4.90269,-2.14424 6.36023,-2.49397 1.77625,-0.4262 3.00417,-1.65162 3.72393,-3.71634 0.59062,-1.69425 2.48318,-4.39697 4.20568,-6.00603 2.69991,-2.52208 3.91404,-2.92556 8.80357,-2.92556 10.85203,0 13.12385,4.05271 13.10169,23.37212 -0.0172,14.96111 -1.16788,19.61515 -5.89402,23.83795 -2.54361,2.27272 -4.05866,2.78993 -8.17244,2.78993 -2.77748,0 -5.95847,-0.48622 -7.06888,-1.08049 -2.95999,-1.58414 -4.8496,-7.02086 -4.8496,-13.95313 0,-8.80639 -2.37926,-11.91086 -6.92401,-9.03451 -1.19203,0.75443 -0.98839,1.87193 1.25,6.85974 5.08462,11.33004 3.10824,21.71454 -5.03821,26.47233 -3.5927,2.09825 -12.23193,3.05458 -16.78778,1.85835 z m 44.40288,-23.45268 c 0.77774,-0.64329 2.23288,-2.96961 3.23364,-5.16961 4.91062,-10.7952 -1.16269,-23.97098 -10.14041,-21.99914 -4.26886,0.93759 -5.43039,2.8146 -4.10122,6.62747 0.60781,1.74357 1.10511,6.78003 1.10511,11.19215 0,6.15835 0.3964,8.46005 1.70625,9.90742 1.80316,1.99247 5.40972,1.74681 8.19663,-0.55829 z m -27.13884,-34.68998 c -4.34077,-1.26791 -9.60278,-4.89618 -10.30372,-7.10464 -0.35361,-1.11414 -0.48158,-2.18707 -0.28436,-2.38428 0.19721,-0.19721 3.1633,0.624 6.5913,1.82491 l 6.23274,2.18348 6.25,-2.30175 c 9.22283,-3.39659 9.75,-3.52585 9.75,-2.39071 0,0.57195 -1.1786,2.4406 -2.61912,4.15255 -4.25565,5.05756 -10.57412,7.49339 -15.61684,6.02044 z M 372.5,494.86218 c -0.99319,-1.19672 -0.99319,-1.80328 0,-3 0.68469,-0.825 1.83447,-1.5 2.55506,-1.5 1.91781,0 2.95317,4.06328 1.30195,5.10953 -1.88611,1.1951 -2.43074,1.10903 -3.85701,-0.60953 z m 12.55577,-0.40976 c -0.95592,-1.54672 0.56402,-4.09024 2.44423,-4.09024 1.88021,0 3.40015,2.54352 2.44423,4.09024 -0.30925,0.50037 -1.40915,0.90976 -2.44423,0.90976 -1.03508,0 -2.13498,-0.40939 -2.44423,-0.90976 z" id="path3086" style="fill:#e6e6e6"/>
+ <path d="m 359.31972,568.84129 c -5.94533,-1.90413 -14.49834,-9.63532 -18.2158,-16.46551 C 338.4754,547.54632 335.5,536.57891 335.5,531.71954 c 0,-2.48913 2.41345,-3.7859 3.81141,-2.04792 0.52671,0.65481 1.29272,2.76556 1.70225,4.69056 4.18475,19.67021 22.96099,32.54365 31.92606,21.88927 1.959,-2.32814 2.55512,-4.14023 2.53832,-7.71599 -0.0218,-4.63851 -2.76373,-12.30476 -4.86555,-13.60376 -0.60267,-0.37246 -2.87664,0.75394 -5.05328,2.50314 -4.60625,3.70168 -6.38703,3.40478 -8.70256,-1.45095 -1.81167,-3.79911 -1.33442,-6.33823 1.37067,-7.29227 6.39717,-2.2562 10.41194,-8.3322 8.21634,-12.43472 -0.96952,-1.81157 -1.79873,-2.00579 -6.77421,-1.58675 -3.1182,0.26261 -6.86718,0.79561 -8.33108,1.18444 -2.13856,0.56803 -2.96047,0.24519 -4.18228,-1.64273 -0.83635,-1.29232 -1.82549,-3.58951 -2.19808,-5.10487 -0.61179,-2.48824 -0.30659,-2.91013 3.15011,-4.35443 2.5432,-1.06262 5.73494,-1.46128 9.51194,-1.18808 9.87102,0.71401 15.87994,7.38925 15.87994,17.64085 l 0,5.04089 4.25,-2.42997 c 2.3375,-1.33649 5.26019,-2.4354 6.49488,-2.44202 1.68375,-0.009 2.78703,-1.16544 4.41388,-4.62641 2.71504,-5.77601 6.78824,-8.37695 13.12642,-8.3819 10.25538,-0.008 12.72137,4.52957 12.69976,23.36838 -0.0194,16.90512 -1.60474,21.82855 -8.11245,25.19382 -3.63899,1.88179 -10.86053,1.83117 -13.61112,-0.0954 -2.70333,-1.89349 -4.24848,-7.20838 -4.25579,-14.63873 -0.007,-6.90543 -0.66786,-8.83179 -3.03078,-8.83179 -2.71713,0 -4.97532,1.0708 -4.97062,2.35699 0.002,0.62866 1.12731,3.35678 2.5,6.06249 2.98249,5.87874 3.33661,14.00643 0.83953,19.26863 -3.56601,7.51481 -14.52038,10.99489 -24.52399,7.791 z m 45.92752,-22.91988 c 5.38602,-4.53204 6.73235,-14.20975 3.00276,-21.58455 -2.70081,-5.34053 -6.75722,-7.05163 -11.3824,-4.80141 -2.16585,1.05372 -2.80143,1.99855 -2.5972,3.86093 0.14873,1.35619 0.59873,7.0949 1,12.75268 0.74597,10.51774 1.47421,12.16186 5.40287,12.19781 0.92031,0.008 2.97859,-1.08304 4.57397,-2.42546 z M 374,509.50162 c -6.81468,-4.20939 -8.76173,-9.92381 -2.19325,-6.43701 4.67931,2.48397 13.18382,2.2146 18.56223,-0.58793 5.57368,-2.90428 7.25078,-1.59871 3.56823,2.77775 -1.47149,1.74877 -3.94949,3.83842 -5.50667,4.64367 -3.9185,2.02634 -10.81494,1.83686 -14.43054,-0.39648 z m -1.5,-14.63944 c -0.99319,-1.19672 -0.99319,-1.80328 0,-3 0.68469,-0.825 1.83447,-1.5 2.55506,-1.5 1.91781,0 2.95317,4.06328 1.30195,5.10953 -1.88611,1.1951 -2.43074,1.10903 -3.85701,-0.60953 z m 12.55577,-0.40976 c -0.95592,-1.54672 0.56402,-4.09024 2.44423,-4.09024 1.88021,0 3.40015,2.54352 2.44423,4.09024 -0.30925,0.50037 -1.40915,0.90976 -2.44423,0.90976 -1.03508,0 -2.13498,-0.40939 -2.44423,-0.90976 z" id="path3084" style="fill:#e3e3e3"/>
+ <path d="m 362,569.47429 c -8.68757,-2.27039 -17.23308,-9.63339 -21.78671,-18.7719 -3.24957,-6.52144 -5.58506,-20.18339 -3.65431,-21.37666 2.00877,-1.24149 3.60418,0.54071 4.30171,4.80533 0.96834,5.92033 6.12675,15.73592 10.50028,19.98029 3.86812,3.75387 9.4824,6.25083 14.05471,6.25083 6.18334,0 10.54601,-5.58465 10.25068,-13.12186 -0.15073,-3.84658 -3.17421,-11.14693 -5.11278,-12.34503 -0.53625,-0.33142 -2.8602,0.76305 -5.16433,2.43216 -2.30413,1.6691 -4.56144,3.03473 -5.01624,3.03473 -1.16606,0 -3.61479,-4.00036 -4.39687,-7.18296 -0.58552,-2.38272 -0.21203,-2.91113 3.33775,-4.72209 8.07219,-4.11813 10.58488,-11.19724 4.93169,-13.89425 -2.31676,-1.10527 -3.72805,-1.06464 -8.88179,0.25568 -6.95197,1.78102 -7.77712,1.43765 -9.76655,-4.06401 -1.2123,-3.35257 -1.17028,-3.8658 0.41126,-5.02224 2.32017,-1.69655 9.6459,-2.7525 13.73483,-1.97976 8.38613,1.58482 13.75667,8.46045 13.75667,17.61195 l 0,5.08199 4.33786,-2.54216 c 2.38582,-1.39818 5.28273,-2.54215 6.43758,-2.54215 1.47975,0 2.87443,-1.42337 4.72343,-4.82059 1.44303,-2.65133 3.90305,-5.57633 5.46671,-6.5 3.7737,-2.22919 10.76899,-2.13871 14.58548,0.18865 4.25601,2.59538 5.44894,7.50267 5.44894,22.41505 0,10.24475 -0.36024,13.39149 -1.96045,17.12463 -2.45666,5.73115 -6.82483,8.5834 -13.15319,8.58852 -7.83568,0.006 -10.88636,-4.62849 -10.88636,-16.53947 0,-2.91127 -0.27315,-6.00502 -0.60699,-6.875 -0.69041,-1.79919 -3.62651,-2.06238 -6.40699,-0.57431 -1.80529,0.96616 -1.77183,1.22079 0.81574,6.20822 3.63933,7.01465 3.86147,17.65355 0.46793,22.41101 -3.81507,5.34843 -13.52208,8.37948 -20.76969,6.4854 z m 42.98632,-23.28001 c 9.43542,-7.4219 6.14545,-27.8321 -4.48632,-27.8321 -1.40524,0 -3.52033,0.67615 -4.70019,1.50255 -1.95803,1.37147 -2.10443,2.17851 -1.67792,9.25 0.74123,12.28958 1.39061,16.1171 3.00902,17.7355 2.0995,2.0995 4.62,1.88903 7.85541,-0.65595 z M 374,509.50162 c -3.79877,-2.34648 -7.02908,-5.94369 -6.13783,-6.83495 0.37579,-0.37578 2.81053,0.0792 5.41054,1.01108 6.28661,2.2532 9.59406,2.10294 16.5353,-0.75125 l 5.80801,-2.38821 -0.30801,2.1173 c -0.16941,1.16451 -2.25549,3.59988 -4.63575,5.41194 -5.155,3.92443 -11.72561,4.48961 -16.67226,1.43409 z m -2.02707,-15.18324 c -0.78395,-1.26846 1.28307,-3.9562 3.04253,-3.9562 1.46528,0 2.75991,2.74543 1.92877,4.09024 -0.76783,1.24237 -4.17745,1.15044 -4.9713,-0.13404 z m 13.08284,0.13404 c -0.95592,-1.54672 0.56402,-4.09024 2.44423,-4.09024 1.88021,0 3.40015,2.54352 2.44423,4.09024 -0.30925,0.50037 -1.40915,0.90976 -2.44423,0.90976 -1.03508,0 -2.13498,-0.40939 -2.44423,-0.90976 z" id="path3082" style="fill:#dddddd"/>
+ <path d="m 361.45056,569.02244 c -13.00124,-3.57003 -22.27421,-15.2284 -25.04933,-31.49311 -1.04732,-6.13821 -1.02678,-7.47152 0.12606,-8.18402 2.09744,-1.29628 2.60093,-0.56579 4.95746,7.19256 4.29483,14.1398 12.22835,22.70659 21.78983,23.52913 9.37767,0.80673 14.76168,-6.25481 12.16462,-15.95482 -1.28963,-4.81676 -3.9416,-9.75 -5.24133,-9.75 -0.479,0 -2.81976,1.39956 -5.20169,3.11013 -2.38193,1.71057 -4.82481,2.8048 -5.42863,2.43162 -1.07542,-0.66465 -4.06755,-6.99197 -4.06755,-8.60146 0,-0.44851 2.19728,-2.01138 4.88284,-3.47304 7.27665,-3.96045 9.3298,-9.97137 4.48927,-13.143 -2.48547,-1.62854 -2.98301,-1.62872 -9.18025,-0.003 -3.60381,0.9452 -6.89778,1.37216 -7.31995,0.9488 -0.42218,-0.42336 -1.46085,-2.43031 -2.30817,-4.4599 -1.36956,-3.28053 -1.37403,-3.8567 -0.0402,-5.19052 1.88767,-1.88766 9.35433,-3.05242 13.99118,-2.18254 4.30229,0.80711 10.30364,5.8842 12.13425,10.26547 0.74307,1.77843 1.35104,5.27296 1.35104,7.76562 0,4.71248 0.87481,5.59282 3.00596,3.02494 0.68797,-0.82895 3.33057,-2.10708 5.87244,-2.84029 3.70805,-1.06959 4.9564,-2.02959 6.31531,-4.85656 2.71417,-5.64633 7.18252,-8.79597 12.47872,-8.79597 10.75938,0 13.64223,5.53043 13.15529,25.23695 -0.25786,10.43562 -0.72348,14.05912 -2.18418,16.99729 -4.52995,9.11191 -17.46365,10.57595 -21.8029,2.46799 -0.64616,-1.20736 -1.43714,-6.02178 -1.75774,-10.69872 -0.57694,-8.41657 -0.61163,-8.50681 -3.39337,-8.82577 -5.29703,-0.60737 -5.88694,1.2255 -2.61824,8.13488 3.12961,6.61538 3.86883,13.9935 1.80375,18.00312 -4.2486,8.24918 -13.37122,11.96776 -22.92448,9.34452 z m 42.48763,-21.81405 c 4.08353,-1.86058 6.87483,-8.84204 6.36319,-15.91533 -0.47841,-6.61389 -2.89222,-10.85584 -7.0131,-12.32453 -4.91948,-1.75333 -11.68805,1.80988 -9.90268,5.2131 0.48491,0.9243 1.06528,6.02149 1.28972,11.32709 0.52783,12.47772 2.39081,14.83079 9.26287,11.69967 z m -28.93596,-37.42161 c -3.98617,-2.07845 -6.50223,-4.43096 -6.50223,-6.07959 0,-1.66597 -0.16162,-1.67334 5.12427,0.23345 5.12479,1.84868 11.78138,1.38791 17.18659,-1.18965 2.01521,-0.96099 3.93113,-1.48015 4.2576,-1.15368 1.20088,1.20088 -1.72375,4.77156 -5.92471,7.23349 -4.93185,2.89026 -9.80061,3.21939 -14.14152,0.95598 z m -3.0293,-15.4684 c -0.78395,-1.26846 1.28307,-3.9562 3.04253,-3.9562 1.46528,0 2.75991,2.74543 1.92877,4.09024 -0.76783,1.24237 -4.17745,1.15044 -4.9713,-0.13404 z m 13.08284,0.13404 c -0.96111,-1.55511 0.56848,-4.09024 2.46789,-4.09024 1.94445,0 2.96668,1.72514 2.22204,3.75 -0.53113,1.44429 -3.85841,1.68567 -4.68993,0.34024 z" id="path3080" style="fill:#d9d9d9"/>
+ <path d="m 361.45056,569.02244 c -12.2509,-3.36399 -21.36857,-14.009 -24.41881,-28.50931 -1.91584,-9.10759 -1.91603,-10.78951 -10e-4,-11.52425 1.68069,-0.64494 2.31222,0.54912 4.95749,9.3733 3.55466,11.85777 12.07242,20.74526 20.82807,21.73215 8.52372,0.96074 14.68266,-5.40511 13.20032,-13.64381 -0.94648,-5.26043 -4.46172,-12.08834 -6.22349,-12.08834 -0.84083,0 -3.05039,1.33599 -4.91014,2.96887 -1.85974,1.63288 -3.98273,2.73809 -4.71776,2.45604 -1.31068,-0.50296 -4.66491,-6.57304 -4.66491,-8.44199 0,-0.52208 2.16057,-2.04408 4.80128,-3.38222 7.15544,-3.62594 9.44317,-10.08397 4.6782,-13.2061 -2.50168,-1.63917 -6.3097,-1.33833 -14.15373,1.11815 -1.7578,0.55048 -2.48769,0.0748 -3.81068,-2.48361 -2.56735,-4.9647 -1.70236,-7.31167 3.27521,-8.88664 12.02653,-3.80536 23.20972,4.54257 23.20972,17.32538 0,2.49267 0.26803,4.53212 0.59563,4.53212 0.3276,0 1.89832,-0.9276 3.4905,-2.06133 1.59218,-1.13373 4.4578,-2.31496 6.36805,-2.62495 2.80826,-0.45572 3.67601,-1.17818 4.53262,-3.77372 1.80761,-5.4771 6.20269,-8.80824 12.28727,-9.31282 4.59937,-0.38142 5.72696,-0.0972 8.34115,2.1025 4.59209,3.86399 5.60082,8.34633 5.21882,23.18999 -0.27581,10.71765 -0.69147,13.66162 -2.38453,16.8887 -4.68245,8.92508 -17.34081,10.2688 -21.60887,2.29386 -0.64616,-1.20736 -1.43714,-6.02178 -1.75774,-10.69872 -0.57694,-8.41657 -0.61163,-8.50681 -3.39337,-8.82577 -1.54576,-0.17724 -3.44394,0.20348 -4.21818,0.84604 -1.19314,0.99021 -1.03531,1.90319 1.03544,5.98961 4.56428,9.00718 4.50348,17.44409 -0.1657,22.99309 -4.81361,5.72066 -12.44302,7.8361 -20.39053,5.65378 z m 43.49983,-22.21971 c 4.91777,-3.22225 7.11321,-14.76256 4.15524,-21.84198 -1.73792,-4.15943 -5.11633,-6.59857 -9.13958,-6.59857 -3.52362,0 -7.93009,3.47223 -6.73822,5.30961 0.42469,0.65472 1.00121,5.73859 1.28115,11.29751 0.32154,6.38522 1.01106,10.7121 1.87244,11.75 1.71884,2.07108 5.47955,2.10769 8.56897,0.0834 z m -29.94816,-37.01595 c -3.98617,-2.07845 -6.50223,-4.43096 -6.50223,-6.07959 0,-1.66597 -0.16162,-1.67334 5.12427,0.23345 5.12479,1.84868 11.78138,1.38791 17.18659,-1.18965 2.01521,-0.96099 3.92586,-1.48543 4.24587,-1.16541 1.04412,1.04412 -1.81034,4.49417 -5.92664,7.16322 -4.62597,2.99953 -9.65697,3.36916 -14.12786,1.03798 z m -2.8171,-15.80275 c -0.5913,-1.5409 1.07943,-3.62185 2.90788,-3.62185 1.4035,0 2.6614,2.77933 1.85122,4.09024 -0.86626,1.40163 -4.16613,1.07686 -4.7591,-0.46839 z m 12.87064,0.46839 c -0.95592,-1.54672 0.56402,-4.09024 2.44423,-4.09024 0.98231,0 2.024,0.62017 2.31487,1.37815 0.96578,2.51678 -3.35723,4.98036 -4.7591,2.71209 z" id="path3078" style="fill:#d8d8d8"/>
+ <path d="m 362.8264,569.26457 c -5.95602,-1.10172 -10.03098,-3.46392 -15.25761,-8.84467 -5.46425,-5.62536 -8.92932,-12.26405 -10.69624,-20.49278 -1.84645,-8.59917 -1.74962,-10.56494 0.52046,-10.56494 1.86075,0 3.10699,1.82274 3.10699,4.54428 0,3.27572 4.46022,12.85835 8.16843,17.54959 8.96423,11.34059 23.31913,12.04893 26.85824,1.32531 1.46891,-4.45083 0.56169,-9.6493 -2.64895,-15.17879 -2.6727,-4.60303 -3.88279,-4.65474 -7.7939,-0.33301 -3.03722,3.35609 -6.12231,2.71341 -7.85742,-1.63685 -1.88944,-4.73717 -1.50797,-5.61434 3.40511,-7.82983 7.14491,-3.22191 9.29306,-9.80596 4.2726,-13.09548 -2.59749,-1.70195 -6.01594,-1.41887 -14.15618,1.17227 -1.92536,0.61286 -2.47727,0.17787 -3.80442,-2.99846 -2.19405,-5.25109 -1.56727,-6.81581 3.35538,-8.37653 12.01325,-3.8088 23.20111,4.54571 23.20111,17.32538 0,2.49267 0.17907,4.53212 0.39793,4.53212 0.21886,0 2.35636,-1.11958 4.75,-2.48795 2.39364,-1.36838 5.26372,-2.49338 6.37795,-2.5 1.40158,-0.008 2.63423,-1.32175 4,-4.26205 2.81139,-6.05252 7.66373,-9.05027 13.73425,-8.48494 9.2266,0.85925 11.73987,5.78116 11.73987,22.99104 0,14.05459 -1.07694,18.4569 -5.58369,22.82502 -2.54828,2.46988 -4.417,3.30862 -8.17655,3.66986 -8.52238,0.8189 -12.15982,-4.53065 -12.2159,-17.9658 -0.0263,-6.29193 -1.67323,-8.24833 -5.67153,-6.73709 -3.3782,1.27686 -3.52266,2.44819 -0.87599,7.10327 9.29806,16.35386 -1.17394,32.07614 -19.14994,28.75103 z m 41.73607,-21.93583 c 3.23958,-1.73376 5.93753,-8.31169 5.93753,-14.47638 0,-9.01582 -4.05094,-14.49018 -10.72251,-14.49018 -3.69764,0 -7.83208,3.32978 -6.56397,5.28648 0.43257,0.66743 1.01552,5.76172 1.29546,11.32064 0.32154,6.38522 1.01106,10.7121 1.87244,11.75 1.5459,1.86269 5.31474,2.14345 8.18105,0.60944 z m -30.46659,-38.23301 c -6.83553,-3.91061 -7.83021,-7.98289 -1.28154,-5.24668 5.04283,2.10703 10.94368,1.88792 16.78071,-0.6231 2.7312,-1.17494 5.25681,-1.84524 5.61248,-1.48957 0.8609,0.8609 -4.50903,6.43944 -7.90787,8.21508 -3.87982,2.02691 -8.71255,1.71371 -13.20378,-0.85573 z m -1.91075,-15.1117 c -0.5913,-1.5409 1.07943,-3.62185 2.90788,-3.62185 1.4035,0 2.6614,2.77933 1.85122,4.09024 -0.86626,1.40163 -4.16613,1.07686 -4.7591,-0.46839 z m 13.59301,0.2563 c -1.52182,-1.52183 -0.47564,-3.87815 1.72186,-3.87815 2.1975,0 3.24368,2.35632 1.72185,3.87815 -0.61702,0.61702 -1.39185,1.12185 -1.72185,1.12185 -0.33,0 -1.10483,-0.50483 -1.72186,-1.12185 z" id="path3076" style="fill:#d3d3d3"/>
+ <path d="m 356.68947,567.22589 c -9.42179,-4.68335 -17.27962,-15.67586 -19.79311,-27.68909 -1.84837,-8.83424 -1.78448,-10.17462 0.48492,-10.17462 1.41219,0 2.17531,1.18442 3.06042,4.75 3.94084,15.8753 13.54325,26.25 24.29596,26.25 10.55928,0 14.70771,-10.34611 8.79532,-21.93535 -1.10242,-2.16092 -2.47424,-4.21933 -3.04849,-4.57423 -0.57424,-0.35491 -2.62133,0.73956 -4.54908,2.43215 -4.71295,4.13802 -6.86268,3.97707 -8.70901,-0.65204 -1.76431,-4.42346 -1.38448,-5.88855 1.72924,-6.67004 3.96494,-0.99514 8.54436,-6.04937 8.54436,-9.43027 0,-5.93037 -5.30448,-7.73818 -13.85426,-4.72164 -4.83965,1.70753 -6.51464,0.70127 -7.68234,-4.6152 -0.86114,-3.92076 0.8718,-5.46118 7.21358,-6.41219 11.12866,-1.66885 21.41292,8.11728 20.1249,19.15011 -0.22015,1.88578 -0.15314,3.42682 0.14892,3.42452 0.30206,-0.002 2.76297,-1.12731 5.46868,-2.5 2.70571,-1.3727 5.65354,-2.49582 6.55073,-2.49582 0.9433,0 2.55526,-1.90187 3.82221,-4.50964 3.82819,-7.87957 12.05316,-10.71108 18.93135,-6.51727 5.00308,3.0505 6.27623,7.41179 6.27623,21.49981 0,6.72576 -0.51234,13.7583 -1.13852,15.62788 -2.15947,6.44741 -7.95009,10.89922 -14.17696,10.89922 -7.01621,0 -10.68452,-6.28992 -10.68452,-18.32037 0,-6.64339 -1.34262,-8.15336 -5.85196,-6.58139 -1.73142,0.60357 -3.14804,1.34604 -3.14804,1.64991 0,0.30388 1.23542,3.07236 2.74538,6.15218 3.54411,7.22879 3.85357,16.48109 0.69283,20.71455 -4.02255,5.38776 -7.01066,6.83153 -14.73894,7.12143 -5.7274,0.21484 -8.08055,-0.16801 -11.5098,-1.8726 z m 49.87745,-21.93534 c 3.33068,-3.56552 4.35458,-7.83208 3.71896,-15.49685 -0.35596,-4.29244 -1.07063,-6.1193 -3.30708,-8.45365 -3.42677,-3.57677 -8.92636,-4.05555 -12.58206,-1.09534 -2.06568,1.67269 -2.1895,2.17953 -1.11078,4.54705 0.66772,1.46549 1.21404,6.36822 1.21404,10.89497 0,9.72348 1.43354,12.67545 6.15549,12.67545 2.10644,0 3.92461,-0.94474 5.91143,-3.07163 z m -31.84514,-36.04762 c -2.35301,-1.16472 -4.76443,-3.02618 -5.35869,-4.13657 -0.99523,-1.85961 -0.85494,-1.9646 1.77822,-1.33072 7.68898,1.85097 12.88747,1.7635 18.10869,-0.30469 6.05409,-2.3981 7.02597,-1.17721 2.5,3.14052 -5.35128,5.10507 -10.4417,5.89172 -17.02822,2.63146 z m -1.88595,-15.44797 c -0.33077,-0.86197 -0.0884,-2.08018 0.53853,-2.70714 1.40744,-1.40744 4.74172,1.4685 3.68495,3.1784 -0.9981,1.61495 -3.53139,1.33229 -4.22348,-0.47126 z m 12.95481,0.45787 c -1.58449,-1.5845 -0.46664,-3.89065 1.8859,-3.89065 1.44571,0 1.87841,0.57193 1.64301,2.17167 -0.37609,2.5559 -1.93339,3.31449 -3.52891,1.71898 z" id="path3074" style="fill:#cdcdcd"/>
+ <path d="m 357,567.05351 c -6.24004,-2.99176 -13.9095,-11.11664 -16.96583,-17.97327 -2.50978,-5.63049 -5.29817,-18.2874 -4.25797,-19.32759 1.47468,-1.47468 3.69165,0.79885 4.68843,4.80803 2.63027,10.57942 9.71796,20.9994 16.45999,24.19871 5.45843,2.59019 11.98078,2.11037 15.59433,-1.14721 5.20926,-4.69609 4.98355,-14.95166 -0.47986,-21.80343 l -2.29024,-2.87225 -3.65922,3.21284 c -5.34575,4.69363 -7.88466,3.9877 -9.19343,-2.55616 -0.5645,-2.82252 -0.27958,-3.24984 3.42798,-5.1413 4.97754,-2.53936 7.17582,-5.5345 7.17582,-9.77702 0,-5.40279 -3.08871,-6.13244 -15.71454,-3.71227 -2.9327,0.56216 -3.36159,0.30779 -4.89187,-2.90122 -2.27418,-4.76903 -1.41856,-6.25382 4.4095,-7.65195 12.39756,-2.97413 23.74408,6.87582 21.81528,18.9379 -0.3531,2.20817 -0.40204,4.01486 -0.10875,4.01486 0.29329,0 2.21848,-1.11522 4.27818,-2.47827 2.05971,-1.36305 5.20426,-2.77014 6.98789,-3.12687 2.60543,-0.52108 3.61592,-1.49172 5.1401,-4.93738 3.26052,-7.37097 11.16198,-10.32452 18.08421,-6.75984 5.68103,2.92551 6.89984,6.75998 6.93001,21.80236 0.0212,10.55951 -0.32169,13.76568 -1.82634,17.0786 -3.21405,7.07664 -10.43047,10.81246 -16.79084,8.69235 -4.25586,-1.41863 -6.4225,-6.11179 -7.05034,-15.27173 -0.63759,-9.30227 -1.73231,-10.87568 -6.26159,-8.99959 -1.65049,0.68365 -3.0009,1.65338 -3.0009,2.15493 0,0.50156 1.11374,3.10978 2.47497,5.79604 5.14069,10.14466 3.95329,19.33275 -3.20389,24.79181 -5.12048,3.90557 -14.73061,4.32444 -21.77108,0.94892 z m 48.2832,-20.25203 c 3.51156,-2.45959 5.2168,-6.81505 5.2168,-13.32454 0,-6.78232 -1.01337,-10.12813 -3.96007,-13.07483 -2.65224,-2.65224 -8.9612,-2.73402 -12.14319,-0.1574 -2.06568,1.67269 -2.1895,2.17953 -1.11078,4.54705 0.66772,1.46549 1.21404,6.36822 1.21404,10.89497 0,5.83072 0.45388,8.87845 1.5567,10.45294 1.84453,2.63344 5.98736,2.93059 9.2265,0.66181 z M 376,509.95054 c -1.65,-0.73335 -4.125,-2.57737 -5.5,-4.09782 l -2.5,-2.76446 3,0.73868 c 6.96874,1.71591 13.71158,1.72615 18.15921,0.0276 5.33837,-2.03874 6.50827,-1.36398 3.39001,1.95526 -4.79132,5.10013 -10.93311,6.63686 -16.54922,4.14076 z m -3.16417,-16.15558 c -0.33077,-0.86197 -0.11071,-2.0579 0.48901,-2.65762 1.44384,-1.44384 4.27127,0.81081 3.50873,2.79795 -0.73152,1.90632 -3.24624,1.81805 -3.99774,-0.14033 z m 12.87146,0.31699 c -1.48236,-1.78614 0.13711,-4.21533 2.26569,-3.39851 1.79629,0.6893 1.74509,3.74396 -0.0729,4.34918 -0.60495,0.20139 -1.59171,-0.22641 -2.19279,-0.95067 z" id="path3072" style="fill:#c7c7c7"/>
+ <path d="m 360.49353,568.42784 c -7.81921,-2.37849 -16.59625,-10.67911 -20.45808,-19.3476 -2.40747,-5.40395 -5.21672,-18.37012 -4.20029,-19.38655 1.45038,-1.45038 3.4888,0.913 4.6,5.33332 2.51453,10.00271 9.58932,20.47288 16.06484,23.77477 6.41726,3.27219 13.2174,2.39976 17.33475,-2.22397 3.88496,-4.36277 3.03562,-14.80488 -1.6801,-20.65586 l -2.36974,-2.94022 -3.8703,3.19022 c -4.78336,3.94285 -5.95562,3.9785 -7.88893,0.23989 -2.23579,-4.32354 -1.90062,-5.80879 1.72432,-7.64095 5.70478,-2.88338 7.75,-5.40305 7.75,-9.54784 0,-5.89362 -4.53845,-7.09525 -16.21388,-4.29291 -2.38442,0.57231 -2.91758,0.22421 -4.39187,-2.86739 -2.2872,-4.79632 -1.39094,-6.32109 4.45215,-7.57421 6.60171,-1.41581 13.94553,0.64922 17.55225,4.93556 3.14861,3.74191 4.96905,10.16456 4.13746,14.59731 -0.34471,1.83742 -0.3717,3.34077 -0.06,3.34077 0.31171,0 2.2446,-1.08385 4.29531,-2.40856 2.05071,-1.32471 5.16551,-2.70485 6.92178,-3.06698 2.50281,-0.51607 3.64854,-1.59899 5.29911,-5.00861 2.70585,-5.58955 6.24994,-7.89537 12.1397,-7.89822 10.07576,-0.005 12.86797,4.96035 12.86797,22.88237 0,12.99707 -1.13245,17.77098 -5.28072,22.26124 -2.97956,3.22519 -8.95231,4.64699 -13.38114,3.18534 -4.50191,-1.48576 -6.20069,-5.35229 -7.0201,-15.97821 -0.67043,-8.69398 -1.69081,-9.91774 -6.68596,-8.01859 -3.25535,1.23769 -3.25357,1.45832 0.0702,8.67938 3.33996,7.25622 3.61234,14.4098 0.73913,19.41155 -3.6351,6.32805 -14.03725,9.58335 -22.44788,7.02495 z m 45.35885,-21.95433 c 6.86884,-5.9575 6.67812,-23.34872 -0.29699,-27.08169 -3.26924,-1.74964 -9.55036,-1.24517 -11.51412,0.92476 -1.48392,1.63971 -1.58938,2.46883 -0.65499,5.14922 0.61255,1.75716 1.11372,6.47338 1.11372,10.4805 0,4.00713 0.42445,8.40206 0.94321,9.76652 1.43392,3.77148 6.5101,4.14244 10.40917,0.76069 z m -27.94946,-35.79702 c -2.54706,-0.50202 -9.14633,-5.87015 -8.29161,-6.74474 0.33622,-0.34404 1.82802,-0.16294 3.3151,0.40245 4.02624,1.53077 11.99306,1.24407 16.59484,-0.5972 2.23395,-0.89385 4.3403,-1.34661 4.68077,-1.00613 1.04253,1.04253 -2.9777,4.81076 -7.20202,6.75058 -3.98596,1.83036 -5.11871,1.97916 -9.09708,1.19504 z m -5.06709,-16.88153 c -0.91,-2.37144 1.22281,-4.04396 3.13412,-2.45772 1.18442,0.98298 1.28444,1.61596 0.41994,2.65762 -1.49748,1.80435 -2.81336,1.73034 -3.55406,-0.1999 z M 385.5,492.28886 c 0,-1.4311 0.53852,-1.96962 1.73852,-1.73852 2.60673,0.50201 2.89745,3.81184 0.3348,3.81184 -1.4311,0 -2.07332,-0.64223 -2.07332,-2.07332 z" id="path3070" style="fill:#c4c4c4"/>
+ <path d="m 360.26404,568.36647 c -7.4293,-2.237 -15.97331,-10.46552 -20.12337,-19.3803 -2.44223,-5.24619 -5.34497,-18.25302 -4.30551,-19.29248 1.53411,-1.53412 3.44094,1.04585 5.03536,6.81293 2.25507,8.15669 5.37108,13.44088 10.9682,18.60013 4.87003,4.48904 11.0803,6.76158 15.70305,5.74626 1.58092,-0.34723 4.24327,-2.19038 5.91632,-4.09588 2.48075,-2.82541 3.03786,-4.33439 3.01995,-8.17975 -0.0233,-5.00733 -2.58881,-11.82791 -5.28955,-14.06274 -1.40483,-1.16248 -2.14455,-0.92214 -5.38633,1.75 -4.66723,3.84713 -5.85158,3.86955 -7.77648,0.1472 -2.23579,-4.32354 -1.90062,-5.80879 1.72432,-7.64095 5.66198,-2.86175 7.75,-5.41063 7.75,-9.46058 0,-5.21283 -1.77925,-6.33717 -8.75152,-5.53026 -11.12542,1.28757 -10.5026,1.42734 -12.09534,-2.71445 -2.0447,-5.31706 -0.80921,-6.20342 8.64686,-6.20342 6.36376,0 8.2426,0.38704 10.82671,2.23031 4.2816,3.05409 6.76969,8.6285 6.70392,15.01969 -0.0297,2.8875 -0.004,5.2443 0.0577,5.23733 0.0614,-0.007 2.76261,-1.35696 6.00262,-3 3.24001,-1.64303 6.52547,-2.98733 7.30103,-2.98733 0.77556,0 2.08665,-1.6192 2.91353,-3.59822 2.54313,-6.08655 5.87077,-8.40178 12.07573,-8.40178 10.78541,0 13.31879,4.28721 13.31879,22.53922 0,14.02783 -1.63992,19.64407 -6.81121,23.32635 -3.2398,2.30694 -10.83841,2.9275 -14.14935,1.15554 -2.52964,-1.35382 -4.03944,-6.2521 -4.03944,-13.10523 0,-3.18213 -0.45952,-6.99432 -1.02117,-8.47155 -0.90002,-2.36724 -1.40048,-2.61 -4.21875,-2.04635 -5.08359,1.01672 -5.32595,1.9497 -2.27344,8.75161 5.27023,11.74362 3.0674,21.46742 -5.84007,25.77946 -4.41295,2.13627 -10.90015,2.57545 -15.88253,1.07524 z m 46.43687,-23.04334 c 7.00815,-7.47964 5.52229,-23.08952 -2.51758,-26.4488 -3.82612,-1.59865 -7.95486,-0.97458 -10.23721,1.54739 -1.38722,1.53286 -1.48301,2.39588 -0.55984,5.04408 0.61255,1.75716 1.11372,6.86667 1.11372,11.35447 0,8.15265 0.87489,10.74188 4,11.83793 2.48713,0.87229 5.34939,-0.29171 8.20091,-3.33507 z M 376,509.4987 c -3.86823,-1.75962 -7.23588,-4.73398 -6.35607,-5.61378 0.23591,-0.23591 2.82244,0.27271 5.74786,1.13027 5.04878,1.48001 5.65035,1.4504 11.84423,-0.5829 3.58892,-1.17816 6.68116,-1.98626 6.87164,-1.79578 0.95609,0.95608 -3.36249,5.16454 -6.99016,6.81192 -5.10215,2.31697 -6.12436,2.3216 -11.1175,0.0503 z m -3.16417,-15.70374 c -0.83346,-2.17196 1.28244,-4.21451 2.79695,-2.7 1.28004,1.28004 0.48705,4.26722 -1.13278,4.26722 -0.58452,0 -1.3334,-0.70525 -1.66417,-1.56722 z M 385.5,492.28886 c 0,-1.4311 0.53852,-1.96962 1.73852,-1.73852 2.60673,0.50201 2.89745,3.81184 0.3348,3.81184 -1.4311,0 -2.07332,-0.64223 -2.07332,-2.07332 z" id="path3068" style="fill:#c1c1c1"/>
+ <path d="m 359.36025,567.85311 c -9.80494,-3.14272 -19.14207,-15.10002 -22.32047,-28.584 -1.95672,-8.30116 -1.9459,-10.13579 0.0574,-9.73025 1.00496,0.20343 2.45704,3.03906 3.91607,7.64728 3.62587,11.45206 9.12546,18.66848 16.98674,22.28961 4.96556,2.28727 7.73224,2.34459 12.14292,0.25159 6.26407,-2.9725 8.22816,-11.65533 4.4936,-19.86516 -3.02379,-6.64729 -4.43654,-7.22259 -8.83436,-3.59754 -4.66723,3.84713 -5.85158,3.86955 -7.77648,0.1472 -2.24748,-4.34614 -1.89366,-5.86605 1.72432,-7.40736 6.6856,-2.84815 10.04257,-9.02065 7.23573,-13.30442 -1.56178,-2.38358 -2.07831,-2.52516 -7.33293,-2.01 -3.10904,0.30481 -6.89127,0.85838 -8.40495,1.23015 -2.46211,0.60471 -2.90999,0.29816 -4.25,-2.90892 -0.82382,-1.97168 -1.49785,-4.01443 -1.49785,-4.53944 0,-1.69831 7.08267,-3.35048 12.4537,-2.90507 9.50746,0.78844 14.5463,6.74531 14.5463,17.19653 0,3.07938 0.3375,5.59591 0.75,5.59228 0.4125,-0.004 2.1,-0.90793 3.75,-2.00958 1.65,-1.10165 4.72154,-2.47519 6.82564,-3.05232 2.92814,-0.80316 4.15122,-1.82854 5.21342,-4.37074 2.33859,-5.59704 6.78255,-8.56435 12.78766,-8.53853 10.03679,0.0431 12.67328,4.71124 12.67328,22.439 0,10.79271 -0.30456,13.20848 -2.16388,17.16402 -2.6748,5.69038 -6.80181,8.36601 -12.91181,8.371 -7.17847,0.006 -9.19252,-2.8019 -9.88401,-13.77924 -0.30202,-4.79436 -0.91119,-9.27952 -1.35373,-9.96702 -1.53827,-2.38979 -8.69185,-0.71297 -8.68239,2.03518 0.002,0.66815 1.12731,3.42859 2.5,6.1343 3.19298,6.29363 3.44803,15.30684 0.56489,19.96249 -3.99592,6.45254 -13.95686,9.07443 -23.20882,6.10896 z m 47.24636,-22.11196 c 5.11091,-4.85951 6.26749,-14.23026 2.64339,-21.41708 -3.56516,-7.06993 -10.78801,-8.89234 -15.33409,-3.86897 -1.53769,1.69913 -1.62321,2.44489 -0.60369,5.26432 0.65328,1.80661 1.18778,6.96531 1.18778,11.46376 0,6.95889 0.31128,8.49028 2.08666,10.26566 2.55411,2.55411 6.18925,1.93457 10.01995,-1.70769 z m -29.51568,-35.88353 c -3.94969,-1.38336 -8.43382,-4.98588 -7.44136,-5.97834 0.29615,-0.29615 2.46522,0.14135 4.82017,0.97222 5.52511,1.94938 6.95632,1.9057 13.55524,-0.41363 4.4685,-1.57055 5.47502,-1.66508 5.47502,-0.51419 0,1.65257 -6.39209,5.97269 -10,6.75855 -1.375,0.29949 -4.25908,-0.0716 -6.40907,-0.82461 z m -4.2551,-16.06266 c -0.83346,-2.17196 1.28244,-4.21451 2.79695,-2.7 1.28004,1.28004 0.48705,4.26722 -1.13278,4.26722 -0.58452,0 -1.3334,-0.70525 -1.66417,-1.56722 z M 385.5,492.28886 c 0,-1.4311 0.53852,-1.96962 1.73852,-1.73852 2.60673,0.50201 2.89745,3.81184 0.3348,3.81184 -1.4311,0 -2.07332,-0.64223 -2.07332,-2.07332 z" id="path3066" style="fill:#bbbbbb"/>
+ <path d="m 361.18251,568.26333 c -10.82615,-2.54651 -20.71587,-14.46052 -24.17199,-29.11967 -1.94119,-8.23358 -1.91562,-10.00756 0.13845,-9.6048 1.06599,0.20901 2.23813,2.44461 3.31539,6.32332 3.21573,11.57838 8.52979,19.07239 16.25377,22.92141 5.91198,2.94606 9.61958,3.231 13.8146,1.06166 6.3386,-3.27781 7.79099,-12.43065 3.37782,-21.28673 -1.76656,-3.54502 -3.19659,-5.19634 -4.5,-5.19634 -1.0508,0 -1.91363,0.3375 -1.91738,0.75 -0.008,0.83477 -6.19403,5.25 -7.35608,5.25 -0.7663,0 -3.63709,-6.2187 -3.63709,-7.87867 0,-0.51861 1.95839,-1.89096 4.35198,-3.04968 2.75487,-1.3336 5.04523,-3.39404 6.24101,-5.61447 1.71892,-3.19184 1.75341,-3.74933 0.38299,-6.19091 -2.30534,-4.10725 -5.03339,-4.395 -16.16845,-1.70545 -2.40533,0.58098 -2.86146,0.24587 -4.27716,-3.14237 -2.302,-5.50947 -0.58478,-6.91845 8.43201,-6.91845 7.68865,0 10.74295,1.54698 14.78762,7.48983 1.70041,2.49842 2.25,4.73539 2.25,9.15805 0,3.21867 0.22476,5.85212 0.49948,5.85212 0.27471,0 2.63721,-1.11314 5.25,-2.47364 2.61278,-1.3605 5.89201,-2.69498 7.28716,-2.9655 1.78297,-0.34573 2.91105,-1.52729 3.79683,-3.97688 3.92342,-10.85003 18.3869,-11.79365 23.68651,-1.54534 1.07623,2.0812 1.48002,6.28888 1.48002,15.4226 0,10.67724 -0.31505,13.2308 -2.10118,17.03063 -2.6266,5.58785 -7.12041,8.50813 -13.09254,8.50813 -6.95961,0 -9.01696,-2.839 -9.59459,-13.23986 -0.25231,-4.54308 -0.86899,-9.04764 -1.3704,-10.01014 -1.12152,-2.15285 -4.66523,-2.26204 -7.56209,-0.23301 l -2.16581,1.51699 2.69331,5.19123 c 2.20189,4.24406 2.6933,6.51862 2.6933,12.46634 0,7.01383 -0.12875,7.40386 -3.5847,10.85981 -4.93237,4.93237 -10.9602,6.29566 -19.23279,4.34979 z m 43.43444,-20.6293 c 5.68202,-3.35646 8.63717,-14.51201 5.81644,-21.95675 -2.66535,-7.03463 -9.2807,-9.98413 -14.94466,-6.66319 -2.97009,1.74144 -3.10754,2.07891 -2.38192,5.84809 0.76421,3.96965 1.20678,9.546 1.32938,16.75 0.0678,3.98604 2.8165,7.75 5.65952,7.75 0.87764,0 2.9122,-0.77767 4.52124,-1.72815 z M 373.75,508.37314 c -3.76407,-2.295 -4.3875,-4.55623 -1,-3.62706 6.32725,1.73554 9.55519,1.70586 15.01721,-0.13811 3.15303,-1.06446 5.73279,-1.60184 5.73279,-1.19418 0,0.40767 -1.59066,2.13782 -3.5348,3.8448 -2.88703,2.53485 -4.39886,3.10291 -8.25,3.09985 -2.93488,-0.002 -5.9423,-0.75191 -7.9652,-1.9853 z m -0.15408,-13.95168 c -1.51127,-0.93402 -0.81522,-4.05928 0.90408,-4.05928 1.46416,0 2.46592,2.93408 1.37442,4.02558 -0.5015,0.5015 -1.49774,0.51624 -2.2785,0.0337 z m 12.07696,-1.71847 c 0.19498,-1.01244 1.02335,-1.84081 1.84081,-1.84081 2.14351,0 1.83391,2.90567 -0.3545,3.32712 -1.3364,0.25736 -1.74367,-0.14991 -1.48631,-1.48631 z" id="path3064" style="fill:#b5b5b5"/>
+ <path d="m 361.83198,568.45331 c -5.66083,-1.43842 -12.24528,-6.06073 -16.21457,-11.38269 -5.16717,-6.92804 -6.82993,-10.38954 -8.60267,-17.90886 -1.86546,-7.91261 -1.88196,-9.79958 -0.0857,-9.79958 0.87799,0 2.06883,2.20078 3.0882,5.70729 3.51829,12.10249 9.46256,20.65224 16.84243,24.22478 11.72358,5.67528 22.39316,-2.14839 19.64619,-14.40594 -1.23732,-5.52114 -4.73973,-11.52613 -6.72262,-11.52613 -0.83557,0 -3.04082,1.33599 -4.90057,2.96887 -1.85974,1.63288 -3.9719,2.74225 -4.69368,2.46528 -1.22673,-0.47074 -4.28075,-7.26299 -3.53079,-7.85261 0.18799,-0.14779 2.29842,-1.34676 4.68984,-2.66437 6.5054,-3.5843 9.09975,-9.8968 5.40196,-13.1439 -2.91845,-2.56274 -5.55538,-2.84475 -11.68099,-1.24923 -3.21949,0.83857 -5.95736,1.40121 -6.08414,1.25032 -0.12678,-0.1509 -1.00323,-1.7928 -1.94766,-3.64868 -1.58336,-3.11142 -1.59084,-3.50062 -0.096,-4.99541 2.5424,-2.54241 14.5647,-2.25689 18.17017,0.43152 5.10165,3.80404 6.76777,7.02811 7.20846,13.94898 0.42377,6.6552 1.6187,8.07566 4.18859,4.97913 0.6893,-0.83055 3.58128,-2.18687 6.42663,-3.01403 4.4359,-1.28955 5.3505,-1.99381 6.41601,-4.94042 3.90681,-10.80408 18.38259,-11.71952 23.66896,-1.49681 1.07377,2.07643 1.48002,6.2733 1.48002,15.28958 0,14.25621 -1.00088,17.70935 -6.54357,22.57589 -3.22034,2.8275 -4.21845,3.15978 -8.69592,2.895 -7.03074,-0.41577 -8.8915,-3.04767 -9.53256,-13.48307 -0.26408,-4.29882 -0.88923,-8.60354 -1.38923,-9.56604 -1.11902,-2.15413 -4.66305,-2.26177 -7.56417,-0.22975 l -2.17047,1.52026 2.94717,6.22974 c 5.1685,10.92521 3.44079,20.20214 -4.6415,24.92245 -3.66269,2.13913 -10.6622,3.02043 -15.07777,1.89843 z m 42.61527,-20.56385 c 5.89896,-3.05047 8.9019,-15.16587 5.67393,-22.8915 -1.69111,-4.0474 -6.06426,-7.63578 -9.3057,-7.63578 -4.95162,0 -9.19941,3.34597 -8.25191,6.5 0.16522,0.55 0.59181,5.60481 0.94797,11.23292 0.86289,13.63549 3.45181,16.66443 10.93571,12.79436 z M 373.75,508.30705 c -3.75525,-2.47416 -4.33248,-4.49987 -1,-3.50938 5.69221,1.69185 9.78392,1.71398 14.70476,0.0795 2.84614,-0.94534 5.36596,-1.52764 5.59959,-1.29401 0.23363,0.23363 -0.91056,1.70413 -2.54265,3.26777 -4.07003,3.89934 -12.00688,4.58881 -16.7617,1.45608 z m -0.80385,-15.032 c -0.87268,-1.41202 1.0547,-3.3394 2.46672,-2.46672 0.59792,0.36954 1.08713,1.32033 1.08713,2.11287 0,1.68362 -2.57364,1.93987 -3.55385,0.35385 z m 13,0 c -1.03052,-1.66742 1.28721,-3.57951 2.66672,-2.2 1.15392,1.15392 0.43172,3.28713 -1.11287,3.28713 -0.48508,0 -1.18431,-0.48921 -1.55385,-1.08713 z" id="path3062" style="fill:#b1b1b1"/>
+ <path d="m 362.5,568.44712 c -12.1119,-2.51719 -22.91316,-15.72928 -26.05094,-31.86549 -2.12076,-10.90611 1.21086,-9.34677 4.87254,2.28055 3.98957,12.66849 12.5746,21.36509 21.95298,22.23827 12.38913,1.1535 17.78916,-11.98037 10.06842,-24.48827 -2.48871,-4.03182 -4.13826,-4.07595 -8.52086,-0.22799 -3.8126,3.34751 -4.63127,3.21467 -6.87012,-1.11479 -1.85539,-3.58792 -1.45244,-4.35619 3.65002,-6.95928 7.4014,-3.77591 9.0434,-12.40241 2.8491,-14.96818 -2.58232,-1.06963 -4.04498,-1.00355 -9.13985,0.41295 -3.33605,0.92751 -6.21895,1.53297 -6.40645,1.34547 -0.18749,-0.1875 -1.01768,-1.96066 -1.84485,-3.94036 -1.35959,-3.25396 -1.34825,-3.72866 0.1182,-4.9457 1.00656,-0.83538 4.19237,-1.34737 8.39509,-1.34919 5.28299,-0.002 7.38124,0.45064 9.53805,2.05886 5.10166,3.80404 6.76777,7.02811 7.20846,13.94898 0.22726,3.56908 0.85381,6.48923 1.39234,6.48923 0.53852,0 2.28182,-0.9276 3.874,-2.06133 1.59218,-1.13373 4.51846,-2.3248 6.50284,-2.64682 3.07186,-0.4985 3.87559,-1.2098 5.40895,-4.787 2.54107,-5.92808 6.17742,-8.50485 12.00208,-8.50485 3.28275,0 5.5427,0.63905 7.38512,2.0883 4.80372,3.7786 5.61488,6.72599 5.61488,20.40188 0,10.52198 -0.32125,13.2192 -1.95615,16.42387 -2.98834,5.85762 -7.39349,9.08595 -12.39807,9.08595 -7.78542,0 -10.62902,-4.423 -10.6402,-16.55 -0.003,-3.36479 -0.53818,-6.5826 -1.20558,-7.25 -1.57597,-1.57597 -5.96321,-1.53237 -8.16988,0.0812 -1.64261,1.2011 -1.56083,1.68562 1.30808,7.75 5.26607,11.13158 3.60942,20.48145 -4.4416,25.06767 -3.69845,2.1068 -9.85634,2.95044 -14.4966,1.98607 z m 42.12824,-20.65126 c 5.83893,-3.01943 8.73489,-15.03881 5.49294,-22.7979 -1.69111,-4.0474 -6.06426,-7.63578 -9.3057,-7.63578 -4.95162,0 -9.19941,3.34597 -8.25191,6.5 0.16522,0.55 0.59181,5.60481 0.94797,11.23292 0.86943,13.73871 3.43697,16.67211 11.1167,12.70076 z M 376,509.41682 c -1.1,-0.45022 -2.9,-1.848 -4,-3.10618 -2,-2.28759 -2,-2.28759 0,-1.54701 4.49768,1.66544 11.10309,1.75461 15.5,0.20925 5.95872,-2.09428 6.67527,-2.01434 4.40735,0.49168 -3.98388,4.40214 -10.71946,6.07563 -15.90735,3.95226 z m -3.05385,-16.14177 c -0.87268,-1.41202 1.0547,-3.3394 2.46672,-2.46672 0.59792,0.36954 1.08713,1.32033 1.08713,2.11287 0,1.68362 -2.57364,1.93987 -3.55385,0.35385 z m 13,0 c -1.03052,-1.66742 1.28721,-3.57951 2.66672,-2.2 1.15392,1.15392 0.43172,3.28713 -1.11287,3.28713 -0.48508,0 -1.18431,-0.48921 -1.55385,-1.08713 z" id="path3060" style="fill:#adadad"/>
+ <path d="m 362.8264,568.31509 c -5.56546,-1.09684 -9.05776,-3.00574 -13.62252,-7.4461 -6.9567,-6.76711 -11.53354,-16.10147 -13.11945,-26.75681 -1.05438,-7.0841 2.38926,-5.98858 3.92923,1.25 1.32042,6.20655 5.20732,13.74198 9.47845,18.37561 9.74263,10.56951 23.7667,9.83686 27.13867,-1.41779 1.35721,-4.52995 -0.8142,-12.89512 -4.53165,-17.45782 l -2.44425,-3 -3.37505,3.25 c -4.24794,4.09055 -6.28834,4.10111 -8.38666,0.0434 -1.85324,-3.58377 -2.16363,-3.13344 5.59363,-8.11578 6.08678,-3.90943 6.7134,-11.31653 1.15222,-13.62005 -2.97986,-1.2343 -8.96984,-0.65914 -12.57202,1.20717 -1.53244,0.79396 -2.30951,0.53651 -3.75,-1.24241 -0.99935,-1.23415 -1.817,-3.30171 -1.817,-4.59458 0,-5.19072 14.19505,-5.65885 20.13122,-0.66389 4.1005,3.45035 5.86878,7.88327 5.86878,14.71256 l 0,5.54067 5.33086,-3.00855 c 2.93197,-1.6547 6.32296,-3.00855 7.53553,-3.00855 1.65984,0 2.68039,-1.10977 4.1296,-4.49065 4.59779,-10.72621 18.29495,-11.58256 23.52399,-1.47071 1.07676,2.08223 1.48002,6.29226 1.48002,15.45154 0,10.40821 -0.32966,13.23233 -1.90268,16.29966 -2.92292,5.69958 -6.36098,8.37284 -11.51547,8.95382 -8.32919,0.93882 -11.56459,-3.61502 -11.57627,-16.29366 -0.003,-3.36479 -0.53818,-6.5826 -1.20558,-7.25 -1.61914,-1.61914 -5.98415,-1.51705 -8.32511,0.1947 -1.85177,1.35405 -1.82159,1.5508 1.03556,6.75 3.82136,6.95379 4.2355,17.02792 0.88502,21.52842 -4.09937,5.50642 -11.17309,7.83593 -19.06907,6.27979 z m 42.55931,-20.58541 c 5.74136,-4.02141 7.82935,-16.19321 4.09953,-23.89798 -2.16181,-4.46572 -5.28319,-6.46952 -10.07775,-6.46952 -3.5194,0 -8.47739,4.30281 -7.21133,6.25838 0.44211,0.68289 1.03393,5.8125 1.31516,11.39914 0.40674,8.08018 0.89859,10.58545 2.40498,12.25 2.26821,2.50634 6.27027,2.70074 9.46941,0.45998 z m -30.5266,-39.29019 c -3.79428,-2.31362 -5.6673,-4.7966 -2.77315,-3.67624 4.26064,1.64935 11.01939,1.75457 15.37499,0.23936 4.94051,-1.71868 5.9839,-1.48383 4.00438,0.90134 -3.77381,4.54717 -11.39808,5.71129 -16.60622,2.53554 z m -1.91296,-15.16444 c -0.87268,-1.41202 1.0547,-3.3394 2.46672,-2.46672 0.59792,0.36954 1.08713,1.32033 1.08713,2.11287 0,1.68362 -2.57364,1.93987 -3.55385,0.35385 z m 13,0 c -1.03052,-1.66742 1.28721,-3.57951 2.66672,-2.2 1.15392,1.15392 0.43172,3.28713 -1.11287,3.28713 -0.48508,0 -1.18431,-0.48921 -1.55385,-1.08713 z" id="path3058" style="fill:#a9a9a9"/>
+ <path d="m 356.82277,566.29289 c -5.32784,-2.63726 -12.41005,-10.19602 -15.77506,-16.83657 -2.72203,-5.37165 -6.23085,-18.74434 -5.19109,-19.78409 1.19324,-1.19324 3.4093,1.82107 4.01323,5.45883 0.91747,5.52643 4.93213,13.45273 9.21476,18.1931 15.209,16.83454 35.52456,4.85362 25.40499,-14.98236 -3.16782,-6.20945 -4.43817,-6.67097 -8.51336,-3.0929 -4.50217,3.95295 -6.23224,3.92316 -7.93938,-0.13672 -1.42917,-3.39883 -0.60549,-5.75 2.01438,-5.75 2.52861,0 8.44876,-6.61039 8.44876,-9.43382 0,-6.60044 -5.33583,-9.01485 -13.76402,-6.22808 -5.45851,1.80484 -6.79488,1.11742 -7.82321,-4.02424 -0.59838,-2.9919 -0.4273,-3.21616 3.22768,-4.23103 5.68231,-1.5778 8.42941,-1.33841 13.39354,1.16717 6.19509,3.12689 9.17672,8.47068 8.67208,15.54247 -0.41193,5.77269 0.49616,7.21246 3.10694,4.92608 2.58189,-2.26108 7.85275,-4.71855 10.12048,-4.71855 1.43364,0 2.7762,-1.467 4.55486,-4.97701 3.96928,-7.83301 11.34893,-10.24861 18.32183,-5.99735 5.03474,3.06959 6.19232,7.0434 6.17337,21.19224 -0.0146,10.87342 -0.27438,12.73751 -2.26523,16.25255 -2.92039,5.15623 -7.965,8.52957 -12.75542,8.52957 -7.02842,0 -9.88764,-4.94185 -9.93904,-17.17857 -0.016,-3.80305 -0.54287,-6.19758 -1.59529,-7.25 -0.86428,-0.86429 -1.77874,-1.57143 -2.03212,-1.57143 -1.25418,0 -7.39645,2.98899 -7.39645,3.5993 0,0.38575 1.2051,3.1645 2.67801,6.17501 5.17127,10.56969 3.81763,20.01656 -3.57589,24.95576 -4.61271,3.08148 -14.76145,3.17948 -20.77935,0.20064 z m 48.91552,-18.90351 c 7.56672,-5.95198 7.80017,-22.28903 0.40375,-28.25496 -4.84181,-3.90539 -15.75938,-0.33038 -14.09065,4.61405 0.39236,1.16254 1.00078,6.46443 1.35205,11.78199 0.49165,7.4427 1.07234,10.14747 2.5226,11.75 2.37283,2.62195 6.55839,2.66841 9.81225,0.10892 z M 374.75,508.37314 c -1.7875,-1.08986 -3.25,-2.19625 -3.25,-2.45864 0,-0.26239 2.8125,-0.23091 6.25,0.07 4.36091,0.38169 7.55806,0.0732 10.57768,-1.02067 5.20423,-1.88523 5.30291,-0.31088 0.19734,3.14839 -4.12505,2.79493 -9.45345,2.89587 -13.77502,0.26096 z m -1.59934,-15.47894 c -0.70524,-1.83784 1.16969,-3.11167 2.54934,-1.73202 1.06741,1.06741 0.29966,3.2 -1.15203,3.2 -0.4587,0 -1.08748,-0.66059 -1.39731,-1.46798 z m 12.79549,0.38085 c -1.03052,-1.66742 1.28721,-3.57951 2.66672,-2.2 1.15392,1.15392 0.43172,3.28713 -1.11287,3.28713 -0.48508,0 -1.18431,-0.48921 -1.55385,-1.08713 z" id="path3056" style="fill:#a2a2a2"/>
+ <path d="m 356.45637,565.90133 c -5.64557,-2.94195 -12.0149,-9.74774 -15.43024,-16.48758 -2.64994,-5.22942 -6.21331,-18.69773 -5.21188,-19.69915 1.20772,-1.20772 2.63242,0.95232 4.21203,6.38597 2.26954,7.80694 4.90139,12.6854 9.58446,17.76592 4.91807,5.33548 9.3289,7.49569 15.30507,7.49569 3.85981,0 5.22383,-0.55962 8.34887,-3.42531 3.51571,-3.22393 3.73165,-3.76777 3.67295,-9.25 -0.0635,-5.93365 -2.60605,-12.55972 -5.8535,-15.25487 -1.32044,-1.09587 -2.11051,-0.81483 -5.10789,1.8169 -4.31052,3.78469 -6.21749,3.92405 -7.50099,0.54818 -1.53177,-4.02885 -1.19087,-5.10295 2.045,-6.44329 4.42175,-1.83155 7.97975,-6.51846 7.97975,-10.51163 0,-6.02541 -6.14852,-8.10296 -14.87196,-5.02516 l -4.1234,1.45483 -1.50232,-2.90517 c -0.82628,-1.59784 -1.50232,-3.59393 -1.50232,-4.43577 0,-3.40651 12.67651,-4.09008 18.09915,-0.97599 4.86109,2.79162 8.14949,9.57018 7.61014,15.68721 -0.2318,2.62896 -0.0332,5.01992 0.44145,5.31323 0.4746,0.29332 2.25022,-0.45455 3.94583,-1.66193 1.69561,-1.20737 4.95504,-2.74207 7.24318,-3.41043 3.5127,-1.02605 4.51328,-1.94853 6.42835,-5.92659 4.78234,-9.93406 17.90965,-10.1151 22.56193,-0.31114 1.27026,2.67687 1.66997,6.37742 1.66997,15.46078 0,10.56655 -0.26766,12.44906 -2.32448,16.34887 -3.30889,6.27374 -7.96872,9.21622 -13.61471,8.5971 -6.51296,-0.7142 -9.044,-5.4291 -9.05523,-16.86839 -0.004,-3.82296 -0.51908,-6.19208 -1.57701,-7.25 -0.86428,-0.86429 -1.77874,-1.57143 -2.03212,-1.57143 -1.52805,0 -7.39645,3.05992 -7.39645,3.85669 0,0.5273 1.13357,3.14365 2.51906,5.81411 3.73395,7.19702 4.17717,13.76308 1.29978,19.25521 -3.03662,5.79604 -7.40698,8.08855 -15.30324,8.02743 -4.31285,-0.0334 -7.3017,-0.71676 -10.55923,-2.41429 z m 49.52995,-18.70705 c 3.71309,-2.92072 5.51368,-7.62292 5.51368,-14.39885 0,-6.19683 -2.10673,-11.69417 -5.35287,-13.96786 -3.2575,-2.28164 -9.0922,-1.84679 -12.30542,0.91711 -2.50623,2.15576 -2.65428,2.63606 -1.55576,5.04705 0.66773,1.46551 1.21405,6.27297 1.21405,10.68324 0,7.6602 0.99989,11.5195 3.3997,13.1219 2.10597,1.40619 6.34833,0.75135 9.08662,-1.40259 z m -30.11627,-38.27249 c -5.44234,-2.36842 -4.63519,-3.23768 2.92171,-3.14654 3.96453,0.0478 8.50441,-0.31408 10.08862,-0.8042 4.04216,-1.25056 3.09023,1.13318 -1.41807,3.55101 -4.03399,2.16345 -7.28209,2.27545 -11.59226,0.39973 z m -2.71939,-16.02759 c -0.70524,-1.83784 1.16969,-3.11167 2.54934,-1.73202 1.06741,1.06741 0.29966,3.2 -1.15203,3.2 -0.4587,0 -1.08748,-0.66059 -1.39731,-1.46798 z m 12.79549,0.38085 c -0.85813,-1.38848 1.04395,-3.34604 2.42304,-2.49371 1.14846,0.70978 0.41309,3.58084 -0.91716,3.58084 -0.4587,0 -1.13634,-0.48921 -1.50588,-1.08713 z" id="path3054" style="fill:#9c9c9c"/>
+ <path d="m 356.9619,565.99659 c -5.96785,-2.779 -12.78547,-10.07202 -16.10214,-17.22496 -2.7681,-5.96986 -5.94991,-18.15263 -4.99133,-19.11121 1.14931,-1.14931 2.7536,1.29867 3.74616,5.71624 2.30452,10.25668 10.41921,21.61164 17.60329,24.63244 4.20839,1.76958 10.66652,1.72278 14.19693,-0.10287 3.16244,-1.63536 6.08519,-6.95674 6.08519,-11.07916 0,-4.42939 -2.10096,-10.16137 -4.99516,-13.62816 l -2.69973,-3.23384 -3.8804,3.19856 c -4.68788,3.86414 -5.75674,3.96 -7.26419,0.6515 -1.77403,-3.89357 -1.42679,-5.10002 1.85973,-6.46134 7.41895,-3.07303 10.61282,-12.22025 5.44836,-15.60413 -2.47871,-1.62412 -6.65159,-1.56531 -14.56145,0.20521 -2.18857,0.48989 -2.78827,0.10855 -3.84632,-2.4458 -1.59029,-3.83932 -0.936,-4.83415 4.06506,-6.18079 11.16687,-3.00693 22.06607,6.32086 20.52481,17.5656 -0.73905,5.39197 0.41185,6.272 4.44586,3.39953 1.69561,-1.20737 4.95369,-2.7476 7.24017,-3.42272 3.42699,-1.01187 4.57077,-2.03105 6.5114,-5.80205 5.15133,-10.01001 17.87512,-10.13144 22.58054,-0.21551 1.4228,2.99833 1.66974,5.90851 1.39948,16.49312 -0.31809,12.45802 -0.42141,12.98531 -3.36725,17.18416 -3.60424,5.1373 -9.67915,7.85199 -14.07124,6.28801 -4.8117,-1.71341 -6.54052,-5.32667 -7.13908,-14.92078 -0.47651,-7.638 -0.80628,-8.83153 -2.67539,-9.68315 -2.50481,-1.14127 -7.33386,0.35519 -8.16897,2.53145 -0.29838,0.77758 0.62214,3.71211 2.0456,6.52119 3.7834,7.46617 4.28348,12.94466 1.6737,18.33575 -4.15561,8.58433 -15.10256,11.3116 -25.66363,6.39371 z m 48.92322,-18.72271 c 4.10374,-3.228 5.61488,-7.10663 5.61488,-14.4117 0,-10.25756 -3.75009,-15.5 -11.08765,-15.5 -4.85681,0 -9.35707,3.43879 -8.35758,6.38629 0.39421,1.16254 0.9972,6.66191 1.33997,12.22083 0.38356,6.22056 1.14752,10.73887 1.98668,11.75 1.89538,2.28379 7.32689,2.05346 10.5037,-0.44542 z M 375.75,508.71451 c -1.7875,-0.88118 -3.25037,-1.88343 -3.25082,-2.22723 -4.4e-4,-0.34381 3.26206,-0.6251 7.25,-0.6251 3.98795,0 8.31656,-0.38472 9.61913,-0.85494 3.63883,-1.31358 2.22064,1.30168 -1.906,3.51482 -4.18786,2.24597 -7.4383,2.29938 -11.71231,0.19245 z m -2.57987,-15.76957 c -0.61925,-1.61373 1.95396,-3.00001 2.85686,-1.53909 0.68044,1.10098 -0.24777,2.95633 -1.47902,2.95633 -0.4587,0 -1.07872,-0.63776 -1.37784,-1.41724 z m 12.87257,-0.51366 c -0.73954,-1.1966 1.14163,-2.38223 2.47361,-1.55902 1.11836,0.69118 0.38417,2.48992 -1.01631,2.48992 -0.48508,0 -1.14086,-0.41891 -1.4573,-0.9309 z" id="path3052" style="fill:#969696"/>
+ <path d="m 359.24797,566.98908 c -11.11814,-4.12665 -20.66272,-18.07645 -23.25074,-33.9819 -1.08693,-6.68012 1.67076,-3.73259 4.15697,4.44312 4.37951,14.4017 14.00618,24.06243 24.12977,24.21515 9.01877,0.13606 14.02115,-5.85745 12.88631,-15.43946 -0.6116,-5.16399 -4.89036,-13.86381 -6.81853,-13.86381 -0.58517,0 -2.76845,1.35 -4.85175,3 -4.61366,3.65409 -5.35847,3.70341 -6.83949,0.45295 -1.76974,-3.88417 -1.42751,-5.09971 1.81381,-6.44231 5.01653,-2.07792 8.02568,-5.82432 8.02568,-9.99202 0,-5.54494 -2.58056,-7.41934 -9.21846,-6.69588 -2.90485,0.31659 -6.46062,0.86479 -7.90173,1.21821 -2.29487,0.56279 -2.76209,0.23551 -3.76312,-2.63606 -1.35805,-3.89571 -0.70272,-4.75774 4.51105,-5.93388 11.33464,-2.55693 21.82061,7.49679 19.86876,19.04972 -0.40613,2.40387 -0.2818,3.97927 0.31406,3.97927 0.54249,0 3.55274,-1.35 6.68944,-3 3.1367,-1.65 6.48036,-3 7.43036,-3 1.05378,0 2.47636,-1.62793 3.64845,-4.17511 2.64921,-5.75724 6.4537,-8.34909 12.07625,-8.22708 3.79016,0.0822 5.09092,0.68105 8.17608,3.76383 l 3.66886,3.66602 0.32816,12.92033 c 0.27032,10.64292 0.024,13.56128 -1.39737,16.55662 -3.83267,8.07675 -11.29434,12.10778 -17.18556,9.2842 -3.77595,-1.80977 -5.19645,-5.3444 -5.92034,-14.73157 -0.71235,-9.2376 -1.77968,-10.78972 -6.49055,-9.43866 -5.09967,1.46257 -5.51669,3.2874 -2.26845,9.92657 6.76516,13.82749 1.32911,25.38223 -12.30245,26.14982 -3.28548,0.18501 -7.37661,-0.27421 -9.51547,-1.06807 z m 45.8745,-18.81831 c 3.77347,-1.79573 6.75418,-8.55429 6.73818,-15.27836 -0.0239,-10.04852 -4.22235,-15.53023 -11.8946,-15.53023 -5.10667,0 -9.00197,3.12506 -7.93838,6.3687 0.38437,1.17221 0.98539,6.6313 1.33559,12.1313 0.68407,10.74337 1.1725,12.20555 4.48907,13.43868 2.21636,0.82406 3.62339,0.60535 7.27014,-1.13009 z m -28.25242,-39.24898 c -5.25306,-2.28605 -4.50078,-3.05961 2.97544,-3.05961 3.93498,0 8.27598,-0.40241 9.64667,-0.89425 2.31796,-0.83174 2.38786,-0.76849 1,0.90491 -1.56259,1.88406 -7.01226,4.51729 -9.21004,4.4502 -0.70517,-0.0215 -2.6906,-0.65209 -4.41207,-1.40125 z m -3.69992,-15.97685 c -0.29911,-0.77948 0.0588,-1.64848 0.79525,-1.9311 1.73435,-0.66554 2.53802,0.17591 1.85873,1.94611 -0.69188,1.80301 -1.95909,1.79585 -2.65398,-0.015 z m 12.87257,-0.51366 c -0.73954,-1.1966 1.14163,-2.38223 2.47361,-1.55902 1.11836,0.69118 0.38417,2.48992 -1.01631,2.48992 -0.48508,0 -1.14086,-0.41891 -1.4573,-0.9309 z" id="path3050" style="fill:#909090"/>
+ <path d="m 359.79322,566.91355 c -5.47205,-1.71031 -11.37089,-6.44345 -15.16028,-12.16438 -5.00947,-7.56292 -10.80862,-25.38699 -8.25978,-25.38699 0.53008,0 1.96175,3.0375 3.18149,6.75 2.86971,8.7345 4.43452,11.81191 8.6563,17.02377 11.14505,13.75874 29.27271,10.71971 29.28531,-4.90958 0.004,-5.44241 -4.57589,-15.15955 -7.40217,-15.70384 -1.03312,-0.19897 -3.28921,1.08274 -5.27357,2.99596 l -3.46802,3.34369 -1.92625,-2.36078 c -2.82445,-3.46161 -2.42035,-4.65961 2.55536,-7.57557 2.46488,-1.44452 4.97078,-3.54043 5.56866,-4.65758 1.7162,-3.20675 1.42495,-7.72347 -0.64556,-10.01136 -1.63143,-1.80271 -2.67716,-2.02252 -7.40226,-1.55595 -3.02635,0.29883 -6.68153,0.83615 -8.12264,1.19404 -2.29759,0.57061 -2.7609,0.24706 -3.76312,-2.62791 -1.53176,-4.394 -0.47329,-5.23381 7.13609,-5.66196 10.89769,-0.61317 16.73668,5.14338 16.74348,16.50707 0.004,7.02458 1.14349,7.85843 5.76744,4.22123 1.41854,-1.11582 4.55484,-2.52625 6.96956,-3.13428 3.76695,-0.94853 4.6111,-1.65711 5.94464,-4.98995 2.22466,-5.55999 5.56807,-7.847 11.47164,-7.847 4.16082,0 5.4302,0.50404 8.61514,3.42084 l 3.73532,3.42084 0.33898,11.6981 c 0.44593,15.38906 -0.0582,17.61027 -5.21981,22.99719 -3.95015,4.12261 -4.65897,4.46303 -9.29276,4.46303 -7.22429,0 -8.51842,-1.79822 -9.32314,-12.95463 -0.8315,-11.52774 -3.09355,-14.1725 -9.31901,-10.89567 -3.54897,1.86803 -3.60046,2.80761 -0.47795,8.72054 2.62049,4.96228 2.92906,6.42608 2.60254,12.34624 -0.31924,5.7882 -0.77295,7.13661 -3.2828,9.75633 -4.66301,4.86714 -11.9733,6.1601 -20.23283,3.57856 z m 46.3073,-19.0442 c 4.78724,-3.09359 7.49336,-13.52856 5.42458,-20.91753 -2.47919,-8.8548 -10.63203,-12.69811 -17.45422,-8.22804 -2.39213,1.56739 -2.67765,2.24914 -2.0845,4.97727 0.378,1.73862 0.98571,7.58966 1.35045,13.00231 0.59347,8.80691 0.91927,10.04826 3.09994,11.81153 2.59955,2.10198 5.73629,1.89244 9.66375,-0.64554 z M 376.75,508.8833 c -4.38572,-1.92239 -4.09894,-2.84034 0.63738,-2.04015 2.13805,0.36123 5.78348,0.1462 8.10094,-0.47782 4.93927,-1.33001 6.1452,-0.77169 2.84844,1.31879 -3.64434,2.31087 -8.01788,2.76352 -11.58676,1.19918 z m -3.68524,-16.41634 c -0.3043,-0.49236 0.10473,-1.14771 0.90896,-1.45632 1.56267,-0.59966 2.89724,0.64725 1.83243,1.71206 -0.90401,0.90401 -2.09319,0.79308 -2.74139,-0.25574 z m 12.97794,-0.0357 c -0.73954,-1.1966 1.14163,-2.38223 2.47361,-1.55902 1.11836,0.69118 0.38417,2.48992 -1.01631,2.48992 -0.48508,0 -1.14086,-0.41891 -1.4573,-0.9309 z" id="path3048" style="fill:#8a8a8a"/>
+ <path d="m 362,567.4746 c -6.7186,-1.74198 -12.50912,-6.05818 -17.33926,-12.92454 -3.28168,-4.66512 -7.60354,-15.41469 -8.61909,-21.43788 -0.99829,-5.92084 1.19445,-4.47941 3.04244,2 5.71585,20.04073 20.99503,32.07217 32.11736,25.29048 6.80025,-4.14635 8.20726,-12.91349 3.54855,-22.11116 -1.5125,-2.98613 -3.55022,-5.57727 -4.52827,-5.75809 -0.97805,-0.18082 -3.39922,1.09444 -5.38037,2.83392 -3.85513,3.38484 -5.37089,3.02664 -6.7507,-1.59532 -0.50954,-1.70683 0.27503,-2.64902 4.27796,-5.13738 3.49818,-2.17458 5.22976,-4.04051 6.04667,-6.51579 1.49933,-4.54301 0.0553,-8.47496 -3.43415,-9.35075 -2.80933,-0.7051 -10.95387,-0.0768 -13.66355,1.05406 -1.24314,0.51881 -2.11391,-0.13231 -3.3351,-2.49382 -2.17375,-4.20358 -1.03982,-5.2384 6.25262,-5.70614 11.02714,-0.70728 17.26489,5.21361 17.26489,16.38787 0,7.33298 0.78777,7.79311 6.59514,3.85212 2.02617,-1.375 4.48435,-2.5 5.46262,-2.5 3.41719,0 5.07404,-1.28894 6.61845,-5.14879 2.22632,-5.56412 5.56854,-7.85121 11.47333,-7.85121 4.16082,0 5.4302,0.50404 8.61514,3.42084 l 3.73532,3.42084 0.33898,11.6981 c 0.44593,15.38906 -0.0582,17.61027 -5.21981,22.99719 -3.95015,4.12261 -4.65897,4.46303 -9.29276,4.46303 -7.18516,0 -8.42746,-1.7296 -9.21211,-12.82569 -0.81865,-11.57677 -3.16641,-14.32152 -9.43004,-11.02461 -3.54335,1.86507 -3.65852,2.93635 -0.88578,8.23911 5.09959,9.75277 3.80067,20.57314 -3.00074,24.99707 -2.81515,1.8311 -11.23105,2.78093 -15.29774,1.72654 z m 43.20145,-19.07194 c 8.42604,-5.13765 9.72206,-21.42831 2.27256,-28.56538 -3.64126,-3.48855 -9.08777,-3.94103 -13.40313,-1.1135 -2.37747,1.55778 -2.67894,2.26586 -2.11911,4.97727 0.35897,1.73862 0.96668,7.58899 1.35045,13.00081 0.61577,8.68319 0.97525,10.06422 3.05856,11.75 2.97895,2.41053 4.82343,2.40026 8.84067,-0.0492 z m -30.26032,-40.46191 c -1.75678,-1.28644 -1.41878,-1.40516 3.55887,-1.25 3.025,0.0943 7.075,-0.18768 9,-0.62659 l 3.5,-0.79803 -2.36078,2.04803 c -2.8253,2.45099 -10.71388,2.81184 -13.69809,0.62659 z M 373,492.36218 c -0.33992,-0.55 0.33508,-1 1.5,-1 1.16492,0 1.83992,0.45 1.5,1 -0.33992,0.55 -1.01492,1 -1.5,1 -0.48508,0 -1.16008,-0.45 -1.5,-1 z m 13.0427,0.0691 c -0.73954,-1.1966 1.14163,-2.38223 2.47361,-1.55902 1.11836,0.69118 0.38417,2.48992 -1.01631,2.48992 -0.48508,0 -1.14086,-0.41891 -1.4573,-0.9309 z" id="path3046" style="fill:#878787"/>
+ <path d="m 362,567.47754 c -5.19858,-1.35297 -8.91321,-3.78062 -13.83331,-9.0406 -4.57388,-4.88985 -9.63639,-13.86728 -9.65692,-17.12476 -0.005,-0.8525 -0.40116,-1.9775 -0.87953,-2.5 -1.26499,-1.38168 -2.14866,-8.32058 -1.13909,-8.94453 0.4727,-0.29215 1.60799,2.06211 2.52286,5.23168 5.81113,20.13265 21.03433,32.10381 32.18166,25.30685 4.63129,-2.82388 6.50253,-6.24078 6.45951,-11.79512 -0.0418,-5.39075 -1.23445,-9.1471 -4.24818,-13.37949 -2.41951,-3.39788 -4.88717,-3.65377 -7.49082,-0.77677 -3.69138,4.07892 -5.19326,4.23914 -6.99929,0.74666 -1.83398,-3.54653 -1.851,-3.51991 4.49997,-7.03803 1.68664,-0.93431 3.80604,-3.24932 4.70977,-5.14448 4.38279,-9.19081 -4.37181,-13.91288 -16.88896,-9.1096 -1.98429,0.76144 -5.47197,-5.21287 -3.93843,-6.74641 0.53319,-0.53319 3.60899,-1.18465 6.8351,-1.44769 11.03373,-0.89961 17.36566,5.02034 17.36566,16.2358 0,3.4612 0.3674,6.52016 0.81644,6.79769 0.44905,0.27752 2.81155,-0.81899 5.25,-2.4367 2.43846,-1.61772 5.18426,-2.94322 6.10177,-2.94558 3.30779,-0.008 4.97902,-1.33178 6.508,-5.15307 2.23109,-5.57603 5.56601,-7.85121 11.50822,-7.85121 4.28695,0 5.38736,0.4587 8.61514,3.59116 l 3.70043,3.59117 0.33898,11.52777 c 0.44288,15.06118 -0.034,17.14787 -5.183,22.67697 -4.03438,4.33226 -4.60954,4.61293 -9.45281,4.61293 -6.88766,0 -8.40283,-2.25001 -9.15629,-13.59697 -0.66231,-9.9743 -2.02092,-12.00568 -7.35967,-11.00413 -5.73605,1.07609 -6.12884,2.48797 -2.7054,9.72453 6.69139,14.14439 2.07029,24.99868 -11.21458,26.3414 -2.34698,0.23721 -5.61723,0.08 -7.26723,-0.34947 z m 43.30814,-19.13976 c 11.68547,-7.12444 7.94863,-31.9756 -4.80814,-31.9756 -5.06771,0 -10.67491,4.97872 -9.03895,8.02582 0.43531,0.8108 1.01038,5.87942 1.27793,11.2636 0.4209,8.47031 0.79793,10.12097 2.79805,12.25 2.80482,2.98559 5.3996,3.10142 9.77111,0.43618 z m -30.26116,-40.5161 c -1.78685,-1.35123 -1.56349,-1.4235 2.62503,-0.8494 2.67854,0.36713 6.10991,0.12193 8.27002,-0.59097 4.66384,-1.5392 5.71545,-0.66905 1.70056,1.40713 -3.80039,1.96526 -10.01903,1.98167 -12.59561,0.0332 z M 373,492.36218 c -0.33992,-0.55 0.33508,-1 1.5,-1 1.16492,0 1.83992,0.45 1.5,1 -0.33992,0.55 -1.01492,1 -1.5,1 -0.48508,0 -1.16008,-0.45 -1.5,-1 z m 13.0427,0.0691 c -0.73954,-1.1966 1.14163,-2.38223 2.47361,-1.55902 1.11836,0.69118 0.38417,2.48992 -1.01631,2.48992 -0.48508,0 -1.14086,-0.41891 -1.4573,-0.9309 z" id="path3044" style="fill:#838383"/>
+ <path d="m 362.2175,567.29215 c -2.08037,-0.50172 -5.05228,-1.56885 -6.60424,-2.3714 -4.82,-2.49252 -12.64971,-11.96727 -15.06066,-18.22494 -1.23617,-3.2085 -2.61724,-6.73363 -3.06905,-7.83363 -1.37975,-3.35923 -1.96827,-8.39141 -1.04789,-8.96023 0.47858,-0.29578 1.85022,2.72427 3.04809,6.71122 2.76347,9.19786 5.73289,14.31133 11.27974,19.42424 7.75104,7.14466 17.07692,8.247 22.86404,2.70259 6.0165,-5.76417 5.59137,-16.53008 -0.96186,-24.35809 l -2.91351,-3.48026 -4.12896,3.73026 c -2.27093,2.05165 -4.34111,3.73027 -4.6004,3.73027 -0.49528,0 -3.5228,-5.5214 -3.5228,-6.42466 0,-0.28819 1.4625,-1.26317 3.25,-2.16663 5.0126,-2.53353 7.65982,-5.41108 8.34681,-9.07305 1.35418,-7.2184 -4.86966,-10.67258 -14.15616,-7.85655 -4.52415,1.3719 -5.04602,1.35659 -6.19065,-0.18159 -3.46264,-4.65319 0.61603,-7.81066 9.07449,-7.02494 8.82446,0.81971 13.6712,6.81645 13.67396,16.9184 8.5e-4,3.13004 0.37638,5.92264 0.8345,6.20578 0.45812,0.28313 2.46364,-0.59329 4.4567,-1.94762 1.99307,-1.35432 5.33074,-2.80571 7.41706,-3.2253 3.25204,-0.65405 4.11571,-1.43492 6.05292,-5.47267 2.61155,-5.44327 6.25607,-7.75117 12.24028,-7.75117 3.3521,0 4.77366,0.65501 7.79966,3.59382 l 3.70043,3.59381 0,14.18077 c 0,15.23262 0.23904,14.40646 -6.15,21.25504 -2.60367,2.79093 -3.8725,3.37656 -7.31574,3.37656 -2.29116,0 -5.01647,-0.4553 -6.05625,-1.01177 -2.41113,-1.2904 -3.96532,-6.88674 -3.97243,-14.30397 -0.003,-3.19866 -0.47141,-6.68616 -1.04076,-7.75 -1.35202,-2.52627 -6.94573,-2.58005 -10.01305,-0.0963 l -2.2698,1.83797 3.15901,6.32175 c 5.25051,10.5072 3.78185,20.58416 -3.54676,24.33551 -3.8989,1.99576 -10.1039,2.67547 -14.57672,1.59677 z m 44.54776,-19.63723 c 3.18392,-2.82963 5.69082,-9.34608 5.69082,-14.79274 0,-10.58121 -6.24273,-17.60681 -14.3015,-16.09498 -4.47525,0.83956 -8.06074,4.96755 -6.63257,7.63611 0.5379,1.00506 0.9805,5.11947 0.98357,9.14313 0.007,8.57189 1.3873,14.34045 3.78379,15.80789 2.31768,1.41919 8.00493,0.4966 10.47589,-1.69941 z m -30.63679,-39.57514 c -1.51643,-1.10884 -1.22508,-1.23198 2.15265,-0.90986 2.14855,0.20489 5.55174,-0.0817 7.56266,-0.63699 4.18371,-1.15518 4.90971,-0.0629 1.10917,1.66874 -3.3679,1.53451 -8.64041,1.47514 -10.82448,-0.12189 z M 373,492.36218 c -0.33992,-0.55 0.33508,-1 1.5,-1 1.16492,0 1.83992,0.45 1.5,1 -0.33992,0.55 -1.01492,1 -1.5,1 -0.48508,0 -1.16008,-0.45 -1.5,-1 z m 13.0427,0.0691 c -0.73954,-1.1966 1.14163,-2.38223 2.47361,-1.55902 1.11836,0.69118 0.38417,2.48992 -1.01631,2.48992 -0.48508,0 -1.14086,-0.41891 -1.4573,-0.9309 z" id="path3042" style="fill:#7e7e7e"/>
+ <path d="m 362.68424,567.2403 c -5.42848,-1.00158 -9.9613,-3.78207 -14.67957,-9.00463 -3.8228,-4.23138 -9.5025,-15.06233 -9.50388,-18.12349 -4.3e-4,-0.9625 -0.40352,-1.75 -0.89575,-1.75 -1.05173,0 -1.98483,-7.95626 -1.00418,-8.56233 0.36738,-0.22706 1.19716,1.71908 1.84396,4.32475 4.06564,16.37864 15.23931,28.15554 26.77038,28.21562 7.82746,0.0408 14.34907,-8.49143 12.80038,-16.74671 -0.86139,-4.59159 -3.6854,-10.173 -6.38035,-12.61023 -2.04682,-1.85108 -2.13034,-1.83257 -5.6412,1.25 -4.44601,3.90364 -6.01726,3.93533 -7.33754,0.14798 -0.97935,-2.80939 -0.84046,-3.07521 2.4138,-4.61946 14.4854,-6.87377 8.84548,-22.06946 -6.33431,-17.06661 -5.27234,1.73761 -6.21982,1.31325 -6.52578,-2.92281 -0.19677,-2.72432 0.0951,-2.96915 4.56885,-3.83323 3.92063,-0.75723 5.624,-0.57285 9.48305,1.0265 6.43598,2.66732 9.35488,7.71089 9.0173,15.58098 -0.27123,6.32335 0.48794,7.83864 3.01856,6.025 2.69024,-1.92804 9.46404,-5.04765 12.20204,-5.61954 1.82503,-0.38119 3.00285,-1.75503 4.36249,-5.08853 3.67538,-9.01109 14.38573,-10.19176 21.13751,-2.33014 1.798,2.09356 2,3.77168 2,16.61523 0,9.29351 -0.38454,14.53585 -1.1003,15 -0.60516,0.39244 -1.64638,1.75011 -2.31382,3.01704 -2.70679,5.13803 -12.2485,7.99172 -16.44972,4.91971 -2.12681,-1.55516 -3.58029,-7.40517 -3.6123,-14.53896 -0.0131,-2.92366 -0.48969,-6.18616 -1.05904,-7.25 -1.36307,-2.54691 -6.95461,-2.57287 -10.0742,-0.0468 l -2.33095,1.88749 2.79472,5.13482 c 8.92578,16.3996 0.16101,30.16601 -17.17015,26.96832 z m 43.87501,-19.58143 c 4.17564,-3.51357 5.94075,-7.91225 5.94075,-14.80441 0,-6.21055 -2.56333,-12.37259 -6.20912,-14.9262 -3.6697,-2.57036 -9.272,-2.00151 -12.98807,1.3188 -2.95904,2.6439 -3.12742,3.10726 -2.01578,5.54706 0.66713,1.46419 1.21297,5.9867 1.21297,10.05001 0,7.96807 1.13182,12.2904 3.73616,14.26805 2.67744,2.03317 6.88333,1.44106 10.32309,-1.45331 z M 376.5,508.36218 c -1.09245,-0.70599 -0.27734,-0.97724 3,-0.99834 2.475,-0.0159 5.625,-0.28122 7,-0.58953 2.41289,-0.54104 2.43237,-0.50572 0.55887,1.01365 -2.15398,1.74683 -8.23284,2.07742 -10.55887,0.57422 z m -3,-16 c -1.20677,-0.77988 -1.04862,-0.97237 0.80902,-0.98469 1.28756,-0.009 2.03561,0.42706 1.69098,0.98469 -0.74319,1.2025 -0.63926,1.2025 -2.5,0 z m 12.8,-1.2 c 0.93333,-0.93333 1.46667,-0.93333 2.4,0 0.93333,0.93333 0.66667,1.2 -1.2,1.2 -1.86667,0 -2.13333,-0.26667 -1.2,-1.2 z" id="path3040" style="fill:#777777"/>
+ <path d="m 356.35888,564.90553 c -2.55261,-1.35906 -6.31865,-4.39979 -8.36898,-6.75718 -3.88375,-4.4654 -9.48775,-15.06783 -9.48911,-17.95284 -4.3e-4,-0.91666 -0.41066,-1.81666 -0.91162,-2 -0.80559,-0.29482 -1.53983,-5.63518 -1.14575,-8.33333 0.0803,-0.55 1.17507,2.15 2.43275,6 3.16202,9.67957 6.01936,14.89553 10.75297,19.62914 4.84008,4.84008 9.30508,6.87217 15.08874,6.86712 8.66022,-0.008 14.60304,-6.99035 13.40266,-15.74808 -0.68449,-4.99389 -5.09711,-13.83335 -7.33407,-14.69174 -0.80243,-0.30793 -3.09768,0.79091 -5.10056,2.44185 -4.50467,3.71312 -5.77834,3.76175 -6.65867,0.2542 -0.52508,-2.09207 -0.25579,-2.98666 1.12881,-3.75 1.00011,-0.55137 3.51164,-2.63705 5.58117,-4.63484 4.84472,-4.6768 5.22871,-9.56524 1.01278,-12.89342 -2.78259,-2.19667 -6.56127,-2.30241 -14.47086,-0.40494 -2.28188,0.54741 -2.91479,0.22709 -3.92288,-1.98541 -1.54668,-3.39459 -0.51604,-4.39464 5.35893,-5.1999 10.47685,-1.43601 18.73349,6.95812 17.45577,17.74646 -0.7367,6.22022 0.71007,7.04545 6.01232,3.42939 2.0992,-1.43161 5.54786,-2.88273 7.66369,-3.2247 3.34475,-0.54059 4.08228,-1.17072 5.64945,-4.82677 2.28931,-5.34076 6.26842,-8.50836 10.6881,-8.50836 4.32274,0 8.98234,2.37501 9.81661,5.00355 0.35357,1.11402 1.03773,1.78145 1.52034,1.48318 0.48261,-0.29827 1.16525,0.99167 1.51698,2.86654 0.96869,5.16358 0.11901,26.61632 -1.08663,27.43498 -0.5765,0.39146 -2.02732,2.11482 -3.22405,3.82968 -4.21474,6.03953 -12.83564,7.16165 -16.55696,2.1551 -1.55035,-2.0858 -2.13286,-4.74531 -2.47748,-11.31122 -0.40462,-7.70892 -0.69577,-8.74491 -2.85527,-10.15987 -2.20586,-1.44534 -2.73273,-1.42772 -6.37139,0.21309 -2.18167,0.98379 -3.96667,2.37156 -3.96667,3.08393 0,0.71237 1.10059,3.36514 2.44577,5.89507 4.86218,9.1445 4.31371,17.48804 -1.51679,23.07401 -2.6849,2.5723 -3.83408,2.92874 -10.22688,3.17212 -6.06765,0.23101 -7.93315,-0.11503 -11.84322,-2.19681 z m 50.20037,-17.24666 c 4.1744,-3.51252 5.94075,-7.91199 5.94075,-14.79669 0,-10.12228 -4.66081,-16.5 -12.05813,-16.5 -5.00358,0 -10.44037,4.28986 -9.38265,7.4033 0.39177,1.15319 0.9938,6.66758 1.33786,12.25422 0.49048,7.96418 1.03446,10.60935 2.51922,12.25 2.71164,2.99632 7.66493,2.73646 11.64295,-0.61083 z M 377.5,508.41853 c -1.14269,-0.78139 -0.54719,-1.03262 2.5,-1.05469 2.2,-0.0159 5.125,-0.30904 6.5,-0.65136 1.93159,-0.48088 2.24332,-0.34615 1.37108,0.59257 -1.52269,1.63875 -8.50644,2.38856 -10.37108,1.11348 z m -4.25,-16.71863 c 0.6875,-0.27741 1.8125,-0.27741 2.5,0 0.6875,0.27741 0.125,0.50439 -1.25,0.50439 -1.375,0 -1.9375,-0.22698 -1.25,-0.50439 z m 13.05,-0.53772 c 0.93333,-0.93333 1.46667,-0.93333 2.4,0 0.93333,0.93333 0.66667,1.2 -1.2,1.2 -1.86667,0 -2.13333,-0.26667 -1.2,-1.2 z" id="path3038" style="fill:#717171"/>
+ <path d="m 358.54427,565.78481 c -8.4916,-3.68364 -16.63851,-13.6588 -19.14603,-23.44261 -0.70199,-2.73901 -1.59203,-4.98002 -1.97788,-4.98002 -1.01494,0 -1.68509,-7.02737 -0.72665,-7.61972 0.44346,-0.27407 0.80629,0.5296 0.80629,1.78594 0,3.63035 4.8063,14.89873 8.55996,20.06885 4.91702,6.77248 10.33403,10.06799 17.28047,10.5128 4.4343,0.28395 6.37621,-0.0873 8.96975,-1.71462 3.58402,-2.24887 6.18982,-7.2482 6.18982,-11.8754 0,-6.34841 -5.5254,-17.15785 -8.77049,-17.15785 -0.89886,0 -3.14968,1.4625 -5.00182,3.25 -3.26432,3.15039 -3.41136,3.19051 -4.79761,1.30887 -2.14972,-2.91794 -1.75359,-4.34022 1.70731,-6.12992 5.18012,-2.67874 7.86261,-6.26224 7.86261,-10.50354 0,-6.65785 -4.68872,-9.0362 -13.96276,-7.08259 -4.89319,1.03077 -5.68263,0.9692 -6.78724,-0.52932 -2.11001,-2.86246 -1.41934,-4.19081 2.76482,-5.31749 11.27282,-3.03546 21.02579,5.59197 19.52451,17.27128 -0.7846,6.10376 0.95835,6.99267 6.50885,3.31952 2.19926,-1.4554 5.45061,-2.92114 7.22523,-3.25721 1.77463,-0.33606 3.71828,-0.99403 4.31922,-1.46215 1.70146,-1.32539 3.32688,5.50665 3.63487,15.27828 0.31956,10.13875 1.89608,12.85427 7.46267,12.85427 7.55718,0 12.30983,-6.76029 12.30983,-17.50982 0,-7.29474 -1.51291,-11.17527 -5.61488,-14.40188 -3.49596,-2.74993 -9.63429,-2.75913 -13.48075,-0.0202 -2.40366,1.71156 -2.90437,1.80048 -2.90437,0.51578 0,-0.85377 1.31309,-3.02192 2.91797,-4.81809 2.58168,-2.8894 3.51313,-3.26578 8.08203,-3.26578 4.5689,0 5.50035,0.37638 8.08203,3.26578 1.60488,1.79617 2.9496,2.92117 2.98825,2.5 0.0387,-0.42118 0.45703,0.13422 0.92972,1.23422 0.98276,2.28701 1.27792,23.86118 0.37265,27.23875 -0.33001,1.23132 -0.96647,2.01228 -1.41434,1.73548 -0.44788,-0.2768 -1.07689,0.32403 -1.39782,1.33518 -1.07536,3.38816 -6.19284,7.33159 -10.21437,7.87099 -7.10693,0.95324 -10.26858,-4.18498 -10.32226,-16.77541 -0.0324,-7.60132 -2.21448,-9.76367 -8.07947,-8.00648 -2.22757,0.6674 -4.31949,1.91542 -4.64873,2.77338 -0.32923,0.85797 0.62407,4.05291 2.11844,7.09988 5.25185,10.70831 4.10515,19.00333 -3.31198,23.9583 -4.0624,2.71385 -12.63997,3.04282 -18.05785,0.69256 z m 19.51535,-57.32616 c -0.30712,-0.49694 1.70027,-1.05944 4.46087,-1.25 4.21168,-0.29072 4.74397,-0.14535 3.30826,0.90353 -1.98266,1.44846 -6.95112,1.67003 -7.76913,0.34647 z M 373.25,491.6999 c 0.6875,-0.27741 1.8125,-0.27741 2.5,0 0.6875,0.27741 0.125,0.50439 -1.25,0.50439 -1.375,0 -1.9375,-0.22698 -1.25,-0.50439 z m 13.05,-0.53772 c 0.93333,-0.93333 1.46667,-0.93333 2.4,0 0.93333,0.93333 0.66667,1.2 -1.2,1.2 -1.86667,0 -2.13333,-0.26667 -1.2,-1.2 z" id="path3036" style="fill:#6e6e6e"/>
+ <path d="m 359.30816,565.95612 c -8.47283,-3.02546 -17.98093,-14.85988 -20.16115,-25.09394 -0.36885,-1.73137 0.57432,-0.41748 2.23036,3.10701 5.46327,11.62731 14.06817,18.56293 23.20164,18.70071 12.57496,0.18971 18.02391,-13.51951 10.32383,-25.9741 -1.63941,-2.65168 -3.79829,-4.97868 -4.79752,-5.17111 -1.04697,-0.20163 -3.28464,1.06691 -5.28098,2.9938 -3.35505,3.23835 -3.50924,3.28254 -4.89426,1.40256 -2.19735,-2.98258 -1.74138,-4.31731 2.09712,-6.1388 4.79639,-2.27604 7.46652,-5.9432 7.50321,-10.30493 0.0257,-3.05374 0.19651,-3.32941 1.10005,-1.77515 0.62663,1.07793 0.79528,3.66953 0.4072,6.25744 -0.54343,3.62383 -0.35733,4.53454 1.03587,5.06916 0.93407,0.35844 2.42465,0.11888 3.31239,-0.53234 2.31953,-1.70156 9.18022,-4.79267 12.17359,-5.48487 2.2073,-0.51042 2.72333,-0.13882 3.75,2.70038 0.65477,1.81073 1.19049,6.9121 1.19049,11.33638 0,10.05345 1.94386,13.31386 7.93772,13.31386 7.61185,0 12.06462,-6.5179 12.05854,-17.65113 -0.004,-7.00541 -1.9891,-12.09275 -5.87284,-15.04938 -2.67955,-2.0399 -10.48086,-1.59277 -13.48856,0.77309 -3.04411,2.39449 -3.23816,1.99474 -1.06844,-2.20102 3.31415,-6.40886 13.18338,-7.33448 17.93922,-1.68248 1.3719,1.6304 2.52599,2.59234 2.56464,2.13764 0.0387,-0.45469 0.45703,0.0733 0.92972,1.17328 0.47269,1.1 0.85943,7.4 0.85943,14 0,6.6 -0.38674,12.9 -0.85943,14 -0.47269,1.1 -0.89106,1.59595 -0.92972,1.10212 -0.0387,-0.49384 -1.08872,0.63116 -2.33348,2.5 -3.10387,4.66003 -8.90265,7.42594 -13.06829,6.23331 -4.20538,-1.20401 -5.7444,-4.68341 -6.4179,-14.50952 -0.73431,-10.7134 -3.22269,-12.96019 -10.30027,-9.30023 -3.64064,1.88265 -3.67301,3.2979 -0.23605,10.32278 3.42916,7.00896 3.70745,14.74624 0.67891,18.87604 -4.24898,5.79405 -13.28618,7.83278 -21.58504,4.86944 z m -23.00504,-32.15465 c -0.22863,-1.95838 -0.0529,-3.78494 0.39059,-4.05901 0.44346,-0.27407 0.80629,1.32824 0.80629,3.5607 0,5.01039 -0.63906,5.27646 -1.19688,0.49831 z M 367,512.75164 c -2.02306,-1.56476 -10.07148,-1.49557 -15.23218,0.13096 -1.82372,0.57479 -2.42355,0.20019 -3.27798,-2.04714 -1.2574,-3.30723 -1.16953,-3.41518 3.68094,-4.52177 6.45295,-1.47218 13.80815,1.33782 16.45703,6.2873 1.13893,2.12812 0.95127,2.14549 -1.62781,0.15065 z m 12,-4.38946 c -0.37772,-0.61116 1.05746,-0.97267 3.69098,-0.92971 3.32492,0.0542 3.85226,0.26656 2.30902,0.92971 -2.76748,1.18923 -5.26502,1.18923 -6,0 z m -5.22917,-16.60417 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19293 -1.3125,-0.52522 z M 386.3,491.16218 c 0.93333,-0.93333 1.46667,-0.93333 2.4,0 0.93333,0.93333 0.66667,1.2 -1.2,1.2 -1.86667,0 -2.13333,-0.26667 -1.2,-1.2 z" id="path3034" style="fill:#686868"/>
+ <path d="m 361.49353,566.48609 c -9.44843,-3.09365 -18.6827,-13.06424 -21.41624,-23.12391 -0.37363,-1.375 0.77764,0.12133 2.55838,3.32518 1.78074,3.20385 5.37991,7.75121 7.99816,10.10524 8.55158,7.68861 17.89982,8.319 24.3,1.63865 5.07379,-5.2959 4.56533,-16.22164 -1.10849,-23.81907 -3.01721,-4.04014 -4.62646,-4.07081 -9.06609,-0.17276 -3.58292,3.14585 -4.55126,3.02714 -5.67238,-0.69535 -0.50782,-1.68613 -0.041,-2.36534 2.28883,-3.3304 3.48309,-1.44275 6.62707,-4.60682 8.00085,-8.052 0.87931,-2.20515 1.00414,-1.94013 1.06006,2.25051 0.0544,4.07922 0.34885,4.75 2.08483,4.75 1.11179,0 3.69929,-1.1053 5.75,-2.45621 2.05071,-1.35092 5.58037,-2.74873 7.8437,-3.10625 3.96214,-0.62586 4.15733,-0.52899 5.25,2.60544 0.62417,1.79051 1.13486,6.58566 1.13486,10.6559 0,8.56636 1.69512,12.7568 5.55196,13.72481 3.6249,0.90979 9.36858,-2.09809 12.2663,-6.42369 2.0876,-3.11627 2.30832,-4.43192 2.0132,-12 -0.39511,-10.13234 -2.62315,-14.25809 -8.67976,-16.0727 -3.66258,-1.09733 -5.17931,-0.74733 -12.4848,2.881 -1.75847,0.87336 2.45468,-5.803 4.27771,-6.77866 1.05815,-0.5663 3.99894,-1.02964 6.5351,-1.02964 3.56251,0 5.16942,0.55822 7.06574,2.45455 1.35,1.35 2.45455,2.95155 2.45455,3.55901 0,0.60746 0.40285,0.8555 0.89521,0.5512 1.59386,-0.98506 2.10506,2.38041 2.09114,13.76703 -0.0141,11.52493 -0.61551,16.01543 -2.02804,15.14244 -0.44788,-0.2768 -1.09577,0.3835 -1.43976,1.46733 -0.344,1.08383 -1.98592,3.11536 -3.64872,4.51452 -2.33814,1.96741 -4.13318,2.54392 -7.92088,2.54392 -4.33674,0 -5.05792,-0.31492 -6.2977,-2.75 -0.77006,-1.5125 -1.60575,-6.43748 -1.85709,-10.9444 -0.50078,-8.97976 -1.6679,-11.30755 -5.6666,-11.30186 -2.39022,0.003 -9.12756,3.28931 -9.12756,4.45165 0,0.26664 1.35,3.14142 3,6.38841 4.88609,9.61519 3.83164,19.41559 -2.53801,23.58915 -2.99928,1.9652 -11.71949,2.91846 -15.46846,1.69096 z m -24.72117,-33.12391 c 0,-2.475 0.19502,-3.4875 0.43337,-2.25 0.23836,1.2375 0.23836,3.2625 0,4.5 -0.23835,1.2375 -0.43337,0.225 -0.43337,-2.25 z m 11.94867,-22.41423 c -0.99495,-2.18368 -0.88875,-2.69323 0.74335,-3.56671 3.48475,-1.86498 11.4525,-1.21376 15.06064,1.23094 3.96428,2.686 5.54037,5.65814 1.99397,3.76016 -2.21041,-1.18297 -10.5794,-0.94093 -14.57808,0.42162 -1.59797,0.54451 -2.31904,0.13111 -3.21988,-1.84601 z m 25.0498,-19.18994 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19293 -1.3125,-0.52522 z m 12.20218,-0.35216 c 0.32507,-0.52598 1.25163,-0.70283 2.05901,-0.39301 2.06712,0.79323 1.82353,1.34934 -0.59104,1.34934 -1.13246,0 -1.79304,-0.43035 -1.46797,-0.95633 z" id="path3032" style="fill:#656565"/>
+ <path d="m 362,566.47754 c -6.94416,-1.80727 -13.67728,-7.39844 -18.34468,-15.23339 -3.06378,-5.14303 -2.66839,-5.88759 0.68079,-1.28201 9.97255,13.7136 22.27763,17.14163 30.41389,8.4729 3.43108,-3.65562 3.75,-4.48213 3.75,-9.71841 0,-6.30015 -2.45243,-12.55195 -6.3661,-16.22866 l -2.34841,-2.20622 -4.32042,3.60961 -4.32042,3.60961 -1.28689,-2.31939 c -1.78847,-3.22341 -1.72402,-3.42505 1.52476,-4.77074 3.03947,-1.25899 7.49359,-5.51983 8.41377,-8.04866 0.3002,-0.825 0.58134,0.36435 0.62476,2.64301 0.0992,5.20511 1.76157,5.9367 6.37165,2.80406 1.94171,-1.31942 5.66964,-2.87837 8.28429,-3.46432 5.7468,-1.28789 6.39214,-0.63 6.39295,6.51725 5.4e-4,4.70319 -0.0757,4.8516 -1.28477,2.5 -1.08095,-2.10245 -1.96327,-2.48553 -5.54846,-2.40902 -2.88394,0.0616 -4.93048,0.75835 -6.326,2.15387 l -2.06289,2.06288 3.12609,6.25586 c 5.08649,10.17897 3.88981,19.93875 -2.8736,23.43625 -3.66209,1.89374 -10.50284,2.65589 -14.50031,1.61552 z m 32.81256,-11.90103 c -1.87303,-1.19097 -3.32297,-5.96557 -3.19756,-10.52943 l 0.115,-4.1849 0.75815,3.93808 c 1.92866,10.01805 13.26468,9.6291 18.60686,-0.63842 2.20675,-4.24129 1.8639,-17.53477 -0.55453,-21.50111 -3.77244,-6.18701 -12.3627,-8.03188 -17.16451,-3.68631 -1.76484,1.59717 -1.87597,1.59687 -1.87597,-0.005 0,-0.93651 1.19071,-2.80625 2.64602,-4.15499 3.7602,-3.48484 11.41348,-3.48366 14.89943,0.002 1.35,1.35 2.45455,2.95156 2.45455,3.55902 0,0.60746 0.40285,0.8555 0.89521,0.5512 1.59386,-0.98506 2.10506,2.3804 2.09114,13.76702 -0.0148,12.10876 -0.68911,16.74394 -2.10978,14.50275 -0.65599,-1.03487 -0.84938,-0.95757 -0.86126,0.34426 -0.008,0.92334 -1.53094,3.28584 -3.38339,5.25 -2.87385,3.04718 -4.01107,3.56896 -7.75,3.55589 -2.41006,-0.008 -4.91627,-0.35508 -5.56936,-0.77035 z m -58.06038,-20.71433 c -0.0111,-2.2 0.18461,-3.21775 0.4349,-2.26166 0.25029,0.95609 0.25937,2.75609 0.0202,4 -0.23919,1.24391 -0.44398,0.46166 -0.45508,-1.73834 z m 11.92354,-23.01368 c -1.04703,-2.29797 -0.91262,-2.63585 1.39804,-3.51436 5.81926,-2.21248 15.19172,-0.1472 17.31214,3.81484 1.00416,1.8763 0.89223,1.90283 -2.74341,0.65025 -3.5829,-1.23441 -6.71317,-1.00738 -12.72543,0.92293 -1.60717,0.516 -2.34753,0.088 -3.24134,-1.87366 z m 25.09511,-19.09049 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19293 -1.3125,-0.52522 z m 12.20218,-0.35216 c 0.32507,-0.52598 1.25163,-0.70283 2.05901,-0.39301 2.06712,0.79323 1.82353,1.34934 -0.59104,1.34934 -1.13246,0 -1.79304,-0.43035 -1.46797,-0.95633 z" id="path3030" style="fill:#626262"/>
+ <path d="m 361.43879,566.01945 c -6.78281,-1.86213 -12.18171,-6.15612 -16.54285,-13.15727 -1.31539,-2.11166 -0.38678,-1.4961 3.136,2.07882 11.10194,11.26626 24.61946,11.11516 29.68299,-0.3318 1.79764,-4.06386 1.89565,-5.17503 0.86334,-9.78787 -1.30013,-5.80962 -6.31078,-14.45915 -8.37614,-14.45915 -0.73805,0 -2.85401,1.35 -4.70213,3 -3.95005,3.5266 -4.58698,3.64025 -5.96554,1.06439 -0.89152,-1.66582 -0.47429,-2.25125 2.99336,-4.20018 2.2161,-1.24552 4.91797,-3.637 6.00416,-5.31439 l 1.97488,-3.04982 -0.19927,3.02862 c -0.21341,3.24353 0.71206,5.47138 2.27287,5.47138 0.52933,0 2.75408,-1.18566 4.94388,-2.6348 2.1898,-1.44915 5.79519,-2.96647 8.01197,-3.37184 4.73267,-0.86543 5.96369,0.51003 5.96369,6.66341 0,3.71379 -0.0306,3.74456 -1.5567,1.56574 -1.85561,-2.64925 -6.1641,-2.93537 -10.49296,-0.69683 -3.65249,1.88878 -3.68504,3.36632 -0.20484,9.29625 2.24959,3.83307 2.74632,5.88228 2.75,11.3448 0.004,5.73462 -0.34504,7.04074 -2.4955,9.34182 -1.375,1.4713 -3.175,3.03152 -4,3.46714 -3.00118,1.58472 -9.60549,1.90485 -14.06121,0.68158 z m 32.72132,-12.48036 c -0.90743,-1.00269 -1.87538,-4.04019 -2.151,-6.75 -0.44771,-4.40168 -0.39315,-4.58523 0.51186,-1.72172 2.53436,8.01893 11.62814,8.25846 17.47903,0.46041 2.4397,-3.25163 3.42337,-17.52218 1.5239,-22.10791 -2.80344,-6.7681 -11.22473,-10.1218 -16.58956,-6.60663 -3.92339,2.57071 -4.39182,0.79364 -0.66788,-2.53371 5.05877,-4.52 13.42386,-3.66728 16.27439,1.65898 0.69332,1.29548 1.5956,2.14835 2.00508,1.89528 0.40948,-0.25307 1.01665,0.2491 1.34928,1.11592 0.91431,2.38265 0.58768,24.62517 -0.39521,26.91247 -0.57499,1.33808 -0.88439,1.50356 -0.93484,0.5 -0.0415,-0.825 -1.13494,0.25037 -2.42993,2.3897 -1.29498,2.13933 -3.43018,4.48589 -4.74487,5.21457 -3.52084,1.95143 -9.27567,1.73244 -11.23025,-0.42736 z m -57.40793,-19.67691 c -0.0111,-2.2 0.18461,-3.21775 0.4349,-2.26166 0.25029,0.95609 0.25937,2.75609 0.0202,4 -0.23919,1.24391 -0.44398,0.46166 -0.45508,-1.73834 z m 12.1696,-22.95565 c -0.36409,-1.45062 -0.34543,-2.95403 0.0415,-3.34092 0.38688,-0.38689 3.5807,-0.70343 7.09737,-0.70343 5.66087,0 6.71183,0.3188 9.16666,2.78067 l 2.77273,2.78068 -3.22003,-1.11805 c -3.08641,-1.07166 -8.81966,-0.42322 -13.4881,1.52552 -1.29493,0.54054 -1.86826,0.075 -2.37009,-1.92447 z m 24.84905,-19.14852 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19293 -1.3125,-0.52522 z M 386.25,491.6999 c 0.6875,-0.27741 1.8125,-0.27741 2.5,0 0.6875,0.27741 0.125,0.50439 -1.25,0.50439 -1.375,0 -1.9375,-0.22698 -1.25,-0.50439 z" id="path3028" style="fill:#5f5f5f"/>
+ <path d="m 358.5,565.04402 c -5.1321,-2.68069 -7.95289,-4.93209 -10.65757,-8.50629 l -2.78138,-3.67555 4.6603,4.07398 c 9.70742,8.48613 21.78545,8.45005 27.37571,-0.0818 1.83597,-2.80204 2.39368,-10.23207 1.11286,-14.826 -1.37044,-4.91534 1.01956,-1.99675 2.83108,3.45724 2.54353,7.65784 1.57731,13.4636 -2.92778,17.5922 -3.31453,3.03754 -4.0922,3.28389 -10.34854,3.27819 -3.72057,-0.003 -7.88968,-0.59379 -9.26468,-1.312 z m 35.76386,-11.43184 c -0.85037,-0.9625 -1.79657,-3.775 -2.10266,-6.25 -0.3061,-2.475 -0.31017,-3.6 -0.009,-2.5 2.13307,7.79202 11.16603,8.66705 17.09287,1.6558 1.9123,-2.26218 2.24577,-2.37899 2.25,-0.78815 0.003,1.0272 -1.74209,3.6147 -3.87738,5.75 -3.20354,3.20349 -4.5753,3.88235 -7.84506,3.88235 -2.51829,0 -4.52621,-0.63786 -5.50877,-1.75 z m 18.21798,-7.75 c -0.0873,-1.1 -0.0835,-6.62998 0.009,-12.28884 l 0.16725,-10.28884 -3.96116,-3.96116 c -4.46641,-4.46641 -8.88556,-5.20753 -14.31376,-2.4005 -2.92701,1.51362 -2.98557,1.50009 -1.94261,-0.44871 2.99533,-5.59683 10.85561,-6.83763 15.98319,-2.52306 1.6922,1.4239 3.08362,3.33639 3.09204,4.25 0.0119,1.29147 0.20347,1.36429 0.86084,0.32726 0.67448,-1.06401 0.97482,-0.9969 1.48468,0.33179 0.93971,2.44878 0.64281,24.66652 -0.36081,27.00206 -0.85943,2 -0.85943,2 -1.01816,0 z m -75.72966,-12 c -0.0111,-2.2 0.18461,-3.21775 0.4349,-2.26166 0.25029,0.95609 0.25937,2.75609 0.0202,4 -0.23919,1.24391 -0.44398,0.46166 -0.45508,-1.73834 z m 23.41449,1.83333 c -1.61988,-1.61988 -0.38527,-4.03006 2.99759,-5.85186 2.01534,-1.08533 4.43332,-3.23795 5.37329,-4.78361 l 1.70903,-2.81028 -0.10636,4.05621 c -0.0585,2.23092 -0.59229,4.05621 -1.1862,4.05621 -0.59391,0 -2.37322,1.35 -3.95402,3 -2.97896,3.10936 -3.70621,3.46045 -4.83333,2.33333 z m 13.43852,-2.18561 c -1.43983,-2.02205 -1.78923,-3.14772 -0.97704,-3.14772 0.69539,0 2.97451,-1.18514 5.06471,-2.63366 2.09021,-1.44851 5.61693,-2.96583 7.83716,-3.37183 4.75204,-0.86897 5.98871,0.52389 5.93957,6.68975 -0.0244,3.06035 -0.23083,3.47173 -1.04283,2.078 -1.91957,-3.2948 -4.51402,-3.91121 -8.96545,-2.1301 -2.27219,0.90915 -4.46503,2.55531 -4.87299,3.65814 -0.69026,1.86594 -0.89736,1.78662 -2.98313,-1.14258 z m -24.46555,-22.64441 c -1.1272,-2.93745 -0.72413,-3.36809 3.78538,-4.04434 4.67129,-0.7005 10.63597,0.70466 12.4939,2.94333 0.86081,1.03722 0.11895,1.28284 -3.67001,1.21509 -2.6119,-0.0467 -6.37357,0.28358 -8.35927,0.73395 -2.93811,0.66638 -3.72946,0.50847 -4.25,-0.84803 z m 24.63119,-19.10748 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19293 -1.3125,-0.52522 z M 386.25,491.6999 c 0.6875,-0.27741 1.8125,-0.27741 2.5,0 0.6875,0.27741 0.125,0.50439 -1.25,0.50439 -1.375,0 -1.9375,-0.22698 -1.25,-0.50439 z" id="path3026" style="fill:#5d5d5d"/>
+ <path d="m 358,564.45942 c -2.2,-1.02235 -5.8,-3.80429 -8,-6.18208 l -4,-4.32326 4.11929,3.58336 c 5.15743,4.48643 10.21042,6.19165 16.54404,5.58307 10.24986,-0.98488 14.96362,-10.3542 11.2801,-22.42091 -0.3085,-1.01058 0.37336,-0.15562 1.51523,1.89992 4.65516,8.37998 3.28896,17.81223 -3.14848,21.73702 -4.29062,2.61592 -12.82224,2.67317 -18.31018,0.12288 z m 37.27963,-10.16076 c -1.74552,-1.01735 -4.38258,-8.66686 -3.34535,-9.70409 0.31114,-0.31115 0.56572,0.18428 0.56572,1.10094 0,2.9881 3.71777,5.66667 7.86514,5.66667 4.39324,0 8.37536,-2.6306 10.65484,-7.03864 2.03619,-3.93756 2.01197,-19.03201 -0.0369,-22.99409 -2.65039,-5.12529 -9.72879,-7.34514 -15.91797,-4.99202 -3.03563,1.15414 -3.33553,0.0319 -0.64272,-2.40501 2.46931,-2.2347 9.15027,-3.13691 11.98697,-1.61875 1.20872,0.64688 3.07191,2.60993 4.14042,4.36233 1.06852,1.7524 1.95133,2.51118 1.9618,1.68618 0.0169,-1.33333 0.12676,-1.33333 0.98843,0 1.18997,1.84134 1.18997,24.7308 0,27.5 -0.85943,2 -0.85943,2 -0.95249,0 -0.0717,-1.54072 -0.46401,-1.24739 -1.70843,1.27735 -3.35831,6.81348 -10.50815,10.10323 -15.55945,7.15913 z m -58.52745,-20.43648 c -0.0111,-2.2 0.18461,-3.21775 0.4349,-2.26166 0.25029,0.95609 0.25937,2.75609 0.0202,4 -0.23919,1.24391 -0.44398,0.46166 -0.45508,-1.73834 z m 23.35481,0.91821 c -1.00658,-2.62309 -0.73408,-3.12293 2.41326,-4.4266 1.66113,-0.68806 4.05481,-2.48053 5.31927,-3.98326 l 2.29902,-2.73223 -0.0693,3.35899 c -0.0381,1.84745 -0.54758,3.36033 -1.13218,3.36195 -0.5846,0.002 -2.35629,1.35294 -3.93709,3.00294 -3.27603,3.41943 -4.04009,3.64089 -4.89301,1.41821 z m 13.5777,-1.38227 c -1.85555,-2.50977 -1.96784,-3.03594 -0.64791,-3.03594 0.87817,0 3.09981,-1.1465 4.93698,-2.54779 3.99366,-3.04611 9.86335,-4.24725 12.01778,-2.45923 0.82965,0.68855 1.50846,2.77181 1.50846,4.62947 0,3.37755 0,3.37755 -2,1.37755 -1.1,-1.1 -2.68945,-2 -3.53212,-2 -3.03106,0 -8.51501,2.95319 -9.26904,4.99151 -0.7354,1.98798 -0.86927,1.94553 -3.01415,-0.95557 z m -24.54078,-22.52151 c -1.09786,-2.86098 -0.76714,-3.23911 3.41836,-3.9084 4.43162,-0.70864 11.09945,0.67928 12.73662,2.65115 0.79905,0.9624 -0.13359,1.25315 -4.13351,1.28862 -2.84096,0.0252 -6.56312,0.40599 -8.27147,0.84622 -2.46837,0.63608 -3.23829,0.4559 -3.75,-0.87759 z m 24.62692,-19.1186 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19292 -1.3125,-0.52522 z m 12,0 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19292 -1.3125,-0.52522 z" id="path3024" style="fill:#5b5b5b"/>
+ <path d="m 357.8594,564.31101 c -2.27734,-1.12727 -4.95977,-2.95475 -5.96096,-4.06106 -1.5365,-1.69781 -1.12473,-1.61386 2.6406,0.53834 5.69954,3.25775 13.70322,3.51434 18.43336,0.59095 4.55945,-2.8179 6.95056,-8.63997 6.26106,-15.24496 l -0.55036,-5.2721 1.52604,3.5 c 3.67839,8.43643 2.14555,16.28912 -3.89896,19.97436 -4.47746,2.72984 -12.90794,2.71817 -18.45078,-0.0255 z M 394.5,553.36218 c -1.1,-1.1 -2,-2.9 -2,-4 0,-2 0,-2 2,0 3.22845,3.22845 9.14029,2.69373 13.61036,-1.23104 l 3.67995,-3.23104 -1.6937,3.27526 c -3.30874,6.39839 -11.62078,9.16265 -15.59661,5.18682 z m 18.07028,-18.1788 -0.0703,-12.6788 -3.36808,-3.5712 c -2.93325,-3.11015 -3.97455,-3.5712 -8.06574,-3.5712 -2.58371,0 -5.55795,0.46041 -6.60942,1.02314 -1.55412,0.83174 -1.79976,0.73129 -1.31307,-0.53699 0.73651,-1.91933 5.5177,-4.48615 8.35631,-4.48615 3.58222,0 8.08736,2.98318 9.53634,6.31472 1.02368,2.35366 1.39959,2.66312 1.43983,1.18528 0.0452,-1.66105 0.21874,-1.74579 1.02383,-0.5 1.18997,1.84134 1.18997,24.7308 0,27.5 -0.54329,1.2643 -0.88528,-2.66387 -0.92972,-10.6788 z m -75.8181,-1.3212 c -0.0111,-2.2 0.18461,-3.21775 0.4349,-2.26166 0.25029,0.95609 0.25937,2.75609 0.0202,4 -0.23919,1.24391 -0.44398,0.46166 -0.45508,-1.73834 z m 23.35159,0.90983 c -0.95238,-2.48187 -0.71795,-3.40983 0.86143,-3.40983 0.80587,0 3.05587,-1.39662 5,-3.10359 3.33855,-2.93128 3.5348,-2.98322 3.5348,-0.93544 0,1.19616 -1.41102,3.37204 -3.14748,4.85359 -4.66547,3.98059 -5.57258,4.35734 -6.24875,2.59527 z m 13.37617,-1.934 c -0.69572,-0.83829 -1.08832,-1.62579 -0.87244,-1.75 0.21587,-0.12421 1.2925,-0.78362 2.3925,-1.46536 11.49497,-7.12416 16.5,-6.99084 16.5,0.43953 0,3.3 0,3.3 -2,1.3 -1.1,-1.1 -2.66589,-2 -3.47976,-2 -2.3054,0 -9.52024,3.11366 -9.52024,4.10858 0,1.38963 -1.62402,1.04937 -3.02006,-0.63275 z m -24.25001,-22.40057 c -0.63744,-2.43756 -0.33948,-2.68268 4.32455,-3.55766 2.41679,-0.45339 4.95154,-0.0895 7.99238,1.14725 l 4.45314,1.81122 -5.5,0.64093 c -3.025,0.35251 -6.67628,0.95381 -8.11395,1.33623 -2.12213,0.56447 -2.71596,0.3052 -3.15612,-1.37797 z m 24.5409,-18.67943 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19292 -1.3125,-0.52522 z m 12,0 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19292 -1.3125,-0.52522 z" id="path3022" style="fill:#595959"/>
+ <path d="m 358.75,564.38911 c -2.3375,-1.06103 -4.25,-2.11023 -4.25,-2.33155 0,-0.22132 2.30723,0.19608 5.12718,0.92757 11.73409,3.04378 19.81903,-2.98475 19.90323,-14.84083 0.0362,-5.10054 1.55526,-3.37671 2.4797,2.814 1.19714,8.01692 -5.74028,15.42328 -14.40799,15.38192 -2.53117,-0.0121 -6.51462,-0.89008 -8.85212,-1.95111 z m 36.20454,-11.48147 c -2.87826,-2.87827 -3.43909,-5.74644 -0.6258,-3.20045 2.40194,2.17373 9.49128,2.14664 12.84236,-0.0491 2.58493,-1.69371 2.59237,-1.69067 1.22408,0.50029 -1.46178,2.34069 -6.60157,5.20378 -9.34176,5.20378 -0.90438,0 -2.74887,-1.10454 -4.09888,-2.45454 z m 17.39791,-19.04546 c -0.19385,-7.15 -0.16435,-13.8759 0.0656,-14.94645 0.95492,-4.44663 1.94142,2.13188 1.94142,12.94645 0,16.16671 -1.5802,17.74142 -2.00697,2 z m -75.60027,0 c -0.0111,-2.2 0.18461,-3.21775 0.4349,-2.26166 0.25029,0.95609 0.25937,2.75609 0.0202,4 -0.23919,1.24391 -0.44398,0.46166 -0.45508,-1.73834 z m 23.38758,0.004 c -0.39213,-1.02187 0.66682,-2.12953 3.33938,-3.49297 2.15248,-1.09811 4.37406,-2.78723 4.93682,-3.7536 0.8774,-1.50662 1.02756,-1.36511 1.05363,0.99297 0.0181,1.63236 -0.50837,2.75 -1.29528,2.75 -0.72912,0 -2.38257,1.125 -3.67431,2.5 -2.71244,2.88726 -3.56235,3.08288 -4.36024,1.00361 z m 13.92899,-1.18503 c -0.3387,-0.88266 -0.49274,-1.67164 -0.34229,-1.7533 0.15045,-0.0817 2.19658,-1.38061 4.54695,-2.88655 8.03169,-5.14612 13.10622,-4.32206 13.19479,2.1427 0.0298,2.17353 -0.0752,2.21446 -1.64728,0.64235 -2.16134,-2.16134 -8.52264,-1.43009 -12.38213,1.42336 -2.4421,1.80552 -2.82399,1.85441 -3.37004,0.43144 z m 34.03103,-14.98489 c -2.50454,-2.15562 -3.68908,-2.45098 -8.68238,-2.16493 -5.42909,0.31102 -5.68631,0.22559 -4.21249,-1.39919 3.9133,-4.31413 11.15406,-2.96682 14.91662,2.77558 2.26347,3.45449 1.44612,3.77328 -2.02175,0.78854 z m -58.55231,-7.24498 c -0.74643,-1.39472 -0.73374,-2.16456 0.0436,-2.64498 1.97319,-1.2195 10.35239,-0.83378 12.90894,0.59424 2.40483,1.34328 2.26219,1.42392 -3.74688,2.11829 -3.43578,0.39702 -6.67571,0.98689 -7.19983,1.31081 -0.52412,0.32393 -1.42674,-0.29634 -2.00582,-1.37836 z m 24.22336,-18.69287 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19292 -1.3125,-0.52522 z m 12,0 c 0.33229,-0.33229 1.19479,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19292 -1.3125,-0.52522 z" id="path3020" style="fill:#575757"/>
+ </g>
+ </g>
+</svg> \ No newline at end of file
diff --git a/bundles/XO/activity/activity.info b/bundles/XO/activity/activity.info
new file mode 100755
index 0000000..dcd3f68
--- /dev/null
+++ b/bundles/XO/activity/activity.info
@@ -0,0 +1,7 @@
+[Activity]
+name = Karma
+service_name = org.karmaeducation.Karma
+icon = activity-karma
+activity_version = 2
+show_launcher = yes
+exec = ./firefox karma/index.html
diff --git a/bundles/XO/activity/activity.info~ b/bundles/XO/activity/activity.info~
new file mode 100755
index 0000000..80b0fae
--- /dev/null
+++ b/bundles/XO/activity/activity.info~
@@ -0,0 +1,7 @@
+[Activity]
+name = Karma
+service_name = org.karmaeducation.Karma
+icon = activity-karma
+activity_version = 1
+show_launcher = yes
+exec = ./firefox karma/examples/adding_up_to_10/index.html
diff --git a/bundles/XO/application.ini b/bundles/XO/application.ini
new file mode 100755
index 0000000..182bf1f
--- /dev/null
+++ b/bundles/XO/application.ini
@@ -0,0 +1,58 @@
+; ***** BEGIN LICENSE BLOCK *****
+; Version: MPL 1.1/GPL 2.0/LGPL 2.1
+;
+; The contents of this file are subject to the Mozilla Public License Version
+; 1.1 (the "License"); you may not use this file except in compliance with
+; the License. You may obtain a copy of the License at
+; http://www.mozilla.org/MPL/
+;
+; Software distributed under the License is distributed on an "AS IS" basis,
+; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+; for the specific language governing rights and limitations under the
+; License.
+;
+; The Original Code is Mozilla Firefox.
+;
+; The Initial Developer of the Original Code is
+; Benjamin Smedberg <benjamin@smedbergs.us>.
+;
+; Portions created by the Initial Developer are Copyright (C) 2006
+; the Mozilla Foundation <http://www.mozilla.org/>. All Rights Reserved.
+;
+; Contributor(s):
+;
+; Alternatively, the contents of this file may be used under the terms of
+; either the GNU General Public License Version 2 or later (the "GPL"), or
+; the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+; in which case the provisions of the GPL or the LGPL are applicable instead
+; of those above. If you wish to allow use of your version of this file only
+; under the terms of either the GPL or the LGPL, and not to allow others to
+; use your version of this file under the terms of the MPL, indicate your
+; decision by deleting the provisions above and replace them with the notice
+; and other provisions required by the GPL or the LGPL. If you do not delete
+; the provisions above, a recipient may use your version of this file under
+; the terms of any one of the MPL, the GPL or the LGPL.
+;
+; ***** END LICENSE BLOCK *****
+
+[App]
+Vendor=Mozilla
+Name=Firefox
+Version=3.5.3
+BuildID=20090824085743
+SourceRepository=http://hg.mozilla.org/releases/mozilla-1.9.1
+SourceStamp=0da982f65d37
+Copyright=Copyright (c) 1998 - 2009 mozilla.org
+ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
+
+[Gecko]
+MinVersion=1.9.1.3
+MaxVersion=1.9.1.3
+
+[XRE]
+EnableProfileMigrator=1
+EnableExtensionManager=1
+
+[Crash Reporter]
+Enabled=1
+ServerURL=https://crash-reports.mozilla.com/submit
diff --git a/bundles/XO/blocklist.xml b/bundles/XO/blocklist.xml
new file mode 100755
index 0000000..1689e6b
--- /dev/null
+++ b/bundles/XO/blocklist.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
+ <emItems>
+ <emItem id="fdm_ffext@freedownloadmanager.org">
+ <versionRange minVersion="1.0" maxVersion="1.3.1">
+ <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+ <versionRange minVersion="3.0a1" maxVersion="*"/>
+ </targetApplication>
+ </versionRange>
+ </emItem>
+ <emItem id="langpack-vi-VN@firefox.mozilla.org">
+ <versionRange minVersion="2.0" maxVersion="2.0"/>
+ </emItem>
+ <emItem id="mozilla_cc@internetdownloadmanager.com">
+ <versionRange minVersion="2.1" maxVersion="3.3">
+ <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+ <versionRange minVersion="3.0a1" maxVersion="*"/>
+ </targetApplication>
+ </versionRange>
+ </emItem>
+ <emItem id="support@daemon-tools.cc">
+ <versionRange minVersion=" " maxVersion="1.0.0.5"/>
+ </emItem>
+ <emItem id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
+ <versionRange minVersion="1.2" maxVersion="1.2">
+ <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+ <versionRange minVersion="3.0a1" maxVersion="*"/>
+ </targetApplication>
+ </versionRange>
+ </emItem>
+ </emItems>
+<pluginItems>
+ <pluginItem>
+ <match name="name" exp="^Yahoo Application State Plugin$"/>
+ <match name="description" exp="^Yahoo Application State Plugin$"/>
+ <match name="filename" exp="npYState.dll"/>
+ <versionRange>
+ <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+ <versionRange minVersion="3.0a1" maxVersion="3.*"/>
+ </targetApplication>
+ </versionRange>
+ </pluginItem>
+ <pluginItem>
+ <match name="name" exp="QuickTime Plug-in 7[.]1[.]"/>
+ <match name="filename" exp="npqtplugin.?[.]dll"/>
+ <versionRange>
+ <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+ <versionRange minVersion="3.0a1" maxVersion="3.*"/>
+ </targetApplication>
+ </versionRange>
+ </pluginItem>
+</pluginItems>
+</blocklist>
diff --git a/bundles/XO/browserconfig.properties b/bundles/XO/browserconfig.properties
new file mode 100755
index 0000000..e80916e
--- /dev/null
+++ b/bundles/XO/browserconfig.properties
@@ -0,0 +1,2 @@
+browser.startup.homepage=http://en-US.start3.mozilla.com/firefox?client=firefox-a&rls=org.mozilla:en-US:official
+browser.startup.homepage_reset=http://en-US.start3.mozilla.com/firefox?client=firefox-a&rls=org.mozilla:en-US:official
diff --git a/bundles/XO/chrome/browser.jar b/bundles/XO/chrome/browser.jar
new file mode 100755
index 0000000..caecd22
--- /dev/null
+++ b/bundles/XO/chrome/browser.jar
Binary files differ
diff --git a/bundles/XO/chrome/browser.manifest b/bundles/XO/chrome/browser.manifest
new file mode 100755
index 0000000..17d0fc0
--- /dev/null
+++ b/bundles/XO/chrome/browser.manifest
@@ -0,0 +1,8 @@
+overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
+override chrome://global/content/license.html chrome://browser/content/license.html
+overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul
+style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css
+overlay chrome://browser/content/browser.xul chrome://browser/content/safebrowsing/report-phishing-overlay.xul
+content browser jar:browser.jar!/content/browser/ xpcnativewrappers=yes contentaccessible=yes
+style chrome://global/content/customizeToolbar.xul chrome://browser/skin/
+content branding jar:browser.jar!/content/branding/ xpcnativewrappers=yes
diff --git a/bundles/XO/chrome/classic.jar b/bundles/XO/chrome/classic.jar
new file mode 100755
index 0000000..34b4d25
--- /dev/null
+++ b/bundles/XO/chrome/classic.jar
Binary files differ
diff --git a/bundles/XO/chrome/classic.manifest b/bundles/XO/chrome/classic.manifest
new file mode 100755
index 0000000..61059c8
--- /dev/null
+++ b/bundles/XO/chrome/classic.manifest
@@ -0,0 +1,7 @@
+skin global classic/1.0 jar:classic.jar!/skin/classic/global/ os!=WINNT
+skin communicator classic/1.0 jar:classic.jar!/skin/classic/communicator/
+skin global classic/1.0 jar:classic.jar!/skin/classic/global/ os=WINNT osversion<6
+skin browser classic/1.0 jar:classic.jar!/skin/classic/browser/
+override chrome://global/skin/icons/warning-16.png moz-icon://stock/gtk-dialog-warning?size=menu
+skin mozapps classic/1.0 jar:classic.jar!/skin/classic/mozapps/ os!=WINNT
+skin mozapps classic/1.0 jar:classic.jar!/skin/classic/mozapps/ os=WINNT osversion<6
diff --git a/bundles/XO/chrome/comm.jar b/bundles/XO/chrome/comm.jar
new file mode 100755
index 0000000..376adc7
--- /dev/null
+++ b/bundles/XO/chrome/comm.jar
Binary files differ
diff --git a/bundles/XO/chrome/comm.manifest b/bundles/XO/chrome/comm.manifest
new file mode 100755
index 0000000..d72f8df
--- /dev/null
+++ b/bundles/XO/chrome/comm.manifest
@@ -0,0 +1,2 @@
+content cookie jar:comm.jar!/content/cookie/ xpcnativewrappers=yes
+content xbl-marquee jar:comm.jar!/content/xbl-marquee/ xpcnativewrappers=yes
diff --git a/bundles/XO/chrome/en-US.jar b/bundles/XO/chrome/en-US.jar
new file mode 100755
index 0000000..378d6a2
--- /dev/null
+++ b/bundles/XO/chrome/en-US.jar
Binary files differ
diff --git a/bundles/XO/chrome/en-US.manifest b/bundles/XO/chrome/en-US.manifest
new file mode 100755
index 0000000..86239c8
--- /dev/null
+++ b/bundles/XO/chrome/en-US.manifest
@@ -0,0 +1,19 @@
+locale global-region en-US jar:en-US.jar!/locale/en-US/global-region/
+override chrome://global/locale/netError.dtd chrome://browser/locale/netError.dtd
+locale global-platform en-US jar:en-US.jar!/locale/en-US/global-platform/
+override chrome://mozapps/locale/downloads/settingsChange.dtd chrome://browser/locale/downloads/settingsChange.dtd
+override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties
+locale branding en-US jar:en-US.jar!/locale/branding/
+locale mozapps en-US jar:en-US.jar!/locale/en-US/mozapps/
+locale alerts en-US jar:en-US.jar!/locale/en-US/alerts/
+locale autoconfig en-US jar:en-US.jar!/locale/en-US/autoconfig/
+locale cookie en-US jar:en-US.jar!/locale/en-US/cookie/
+locale passwordmgr en-US jar:en-US.jar!/locale/en-US/passwordmgr/
+locale places en-US jar:en-US.jar!/locale/en-US/places/
+locale global en-US jar:en-US.jar!/locale/en-US/global/
+locale browser-region en-US jar:en-US.jar!/locale/browser-region/
+locale reporter en-US jar:en-US.jar!/locale/en-US/reporter/
+locale browser en-US jar:en-US.jar!/locale/browser/
+locale pipnss en-US jar:en-US.jar!/locale/en-US/pipnss/
+locale pippki en-US jar:en-US.jar!/locale/en-US/pippki/
+locale necko en-US jar:en-US.jar!/locale/en-US/necko/
diff --git a/bundles/XO/chrome/icons/default/default16.png b/bundles/XO/chrome/icons/default/default16.png
new file mode 100755
index 0000000..0822f73
--- /dev/null
+++ b/bundles/XO/chrome/icons/default/default16.png
Binary files differ
diff --git a/bundles/XO/chrome/icons/default/default32.png b/bundles/XO/chrome/icons/default/default32.png
new file mode 100755
index 0000000..0c4f681
--- /dev/null
+++ b/bundles/XO/chrome/icons/default/default32.png
Binary files differ
diff --git a/bundles/XO/chrome/icons/default/default48.png b/bundles/XO/chrome/icons/default/default48.png
new file mode 100755
index 0000000..b982cf9
--- /dev/null
+++ b/bundles/XO/chrome/icons/default/default48.png
Binary files differ
diff --git a/bundles/XO/chrome/pippki.jar b/bundles/XO/chrome/pippki.jar
new file mode 100755
index 0000000..bc64444
--- /dev/null
+++ b/bundles/XO/chrome/pippki.jar
Binary files differ
diff --git a/bundles/XO/chrome/pippki.manifest b/bundles/XO/chrome/pippki.manifest
new file mode 100755
index 0000000..db7a425
--- /dev/null
+++ b/bundles/XO/chrome/pippki.manifest
@@ -0,0 +1 @@
+content pippki jar:pippki.jar!/content/pippki/ xpcnativewrappers=yes
diff --git a/bundles/XO/chrome/reporter.jar b/bundles/XO/chrome/reporter.jar
new file mode 100755
index 0000000..c7e2027
--- /dev/null
+++ b/bundles/XO/chrome/reporter.jar
Binary files differ
diff --git a/bundles/XO/chrome/reporter.manifest b/bundles/XO/chrome/reporter.manifest
new file mode 100755
index 0000000..71ac25d
--- /dev/null
+++ b/bundles/XO/chrome/reporter.manifest
@@ -0,0 +1,5 @@
+overlay chrome://navigator/content/navigator.xul chrome://reporter/content/reporterOverlay.xul
+content reporter jar:reporter.jar!/content/reporter/ xpcnativewrappers=yes
+overlay chrome://global/content/customizeToolbar.xul chrome://reporter/content/reporterOverlay.xul
+overlay chrome://browser/content/browser.xul chrome://reporter/content/reporterOverlay.xul
+skin reporter classic/1.0 jar:reporter.jar!/skin/classic/reporter/
diff --git a/bundles/XO/chrome/toolkit.jar b/bundles/XO/chrome/toolkit.jar
new file mode 100755
index 0000000..466b6b8
--- /dev/null
+++ b/bundles/XO/chrome/toolkit.jar
Binary files differ
diff --git a/bundles/XO/chrome/toolkit.manifest b/bundles/XO/chrome/toolkit.manifest
new file mode 100755
index 0000000..0839061
--- /dev/null
+++ b/bundles/XO/chrome/toolkit.manifest
@@ -0,0 +1,6 @@
+content global-region jar:toolkit.jar!/content/global-region/ xpcnativewrappers=yes
+content global jar:toolkit.jar!/content/global/ xpcnativewrappers=yes contentaccessible=yes
+content mozapps jar:toolkit.jar!/content/mozapps/ xpcnativewrappers=yes
+content passwordmgr jar:toolkit.jar!/content/passwordmgr/ xpcnativewrappers=yes
+override chrome://global/content/nsTransferable.js chrome://global/content/nsDragAndDrop.js
+content global-platform jar:toolkit.jar!/content/global-platform/ platform xpcnativewrappers=yes
diff --git a/bundles/XO/components/FeedConverter.js b/bundles/XO/components/FeedConverter.js
new file mode 100755
index 0000000..aeb603d
--- /dev/null
+++ b/bundles/XO/components/FeedConverter.js
@@ -0,0 +1,774 @@
+//@line 39 "/builds/moz2_slave/linux_build/build/browser/components/feeds/src/FeedConverter.js"
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+function LOG(str) {
+ dump("*** " + str + "\n");
+}
+
+const FC_CLASSID = Components.ID("{229fa115-9412-4d32-baf3-2fc407f76fb1}");
+const FC_CLASSNAME = "Feed Stream Converter";
+const FS_CLASSID = Components.ID("{2376201c-bbc6-472f-9b62-7548040a61c6}");
+const FS_CLASSNAME = "Feed Result Service";
+const FS_CONTRACTID = "@mozilla.org/browser/feeds/result-service;1";
+const FPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=feed";
+const FPH_CLASSID = Components.ID("{4f91ef2e-57ba-472e-ab7a-b4999e42d6c0}");
+const FPH_CLASSNAME = "Feed Protocol Handler";
+const PCPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=pcast";
+const PCPH_CLASSID = Components.ID("{1c31ed79-accd-4b94-b517-06e0c81999d5}");
+const PCPH_CLASSNAME = "Podcast Protocol Handler";
+
+const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
+const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
+const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
+const TYPE_ANY = "*/*";
+
+const FEEDHANDLER_URI = "about:feeds";
+
+const PREF_SELECTED_APP = "browser.feeds.handlers.application";
+const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
+const PREF_SELECTED_ACTION = "browser.feeds.handler";
+const PREF_SELECTED_READER = "browser.feeds.handler.default";
+
+const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
+const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
+const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
+const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
+
+const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
+const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
+const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
+const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
+
+function getPrefAppForType(t) {
+ switch (t) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return PREF_VIDEO_SELECTED_APP;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return PREF_AUDIO_SELECTED_APP;
+
+ default:
+ return PREF_SELECTED_APP;
+ }
+}
+
+function getPrefWebForType(t) {
+ switch (t) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return PREF_VIDEO_SELECTED_WEB;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return PREF_AUDIO_SELECTED_WEB;
+
+ default:
+ return PREF_SELECTED_WEB;
+ }
+}
+
+function getPrefActionForType(t) {
+ switch (t) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return PREF_VIDEO_SELECTED_ACTION;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return PREF_AUDIO_SELECTED_ACTION;
+
+ default:
+ return PREF_SELECTED_ACTION;
+ }
+}
+
+function getPrefReaderForType(t) {
+ switch (t) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return PREF_VIDEO_SELECTED_READER;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return PREF_AUDIO_SELECTED_READER;
+
+ default:
+ return PREF_SELECTED_READER;
+ }
+}
+
+function safeGetCharPref(pref, defaultValue) {
+ var prefs =
+ Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ try {
+ return prefs.getCharPref(pref);
+ }
+ catch (e) {
+ }
+ return defaultValue;
+}
+
+function FeedConverter() {
+}
+FeedConverter.prototype = {
+ /**
+ * This is the downloaded text data for the feed.
+ */
+ _data: null,
+
+ /**
+ * This is the object listening to the conversion, which is ultimately the
+ * docshell for the load.
+ */
+ _listener: null,
+
+ /**
+ * Records if the feed was sniffed
+ */
+ _sniffed: false,
+
+ /**
+ * See nsIStreamConverter.idl
+ */
+ canConvert: function FC_canConvert(sourceType, destinationType) {
+ // We only support one conversion.
+ return destinationType == TYPE_ANY && ((sourceType == TYPE_MAYBE_FEED) ||
+ (sourceType == TYPE_MAYBE_VIDEO) ||
+ (sourceType == TYPE_MAYBE_AUDIO));
+ },
+
+ /**
+ * See nsIStreamConverter.idl
+ */
+ convert: function FC_convert(sourceStream, sourceType, destinationType,
+ context) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ /**
+ * See nsIStreamConverter.idl
+ */
+ asyncConvertData: function FC_asyncConvertData(sourceType, destinationType,
+ listener, context) {
+ this._listener = listener;
+ },
+
+ /**
+ * Whether or not the preview page is being forced.
+ */
+ _forcePreviewPage: false,
+
+ /**
+ * Release our references to various things once we're done using them.
+ */
+ _releaseHandles: function FC__releaseHandles() {
+ this._listener = null;
+ this._request = null;
+ this._processor = null;
+ },
+
+ /**
+ * See nsIFeedResultListener.idl
+ */
+ handleResult: function FC_handleResult(result) {
+ // Feeds come in various content types, which our feed sniffer coerces to
+ // the maybe.feed type. However, feeds are used as a transport for
+ // different data types, e.g. news/blogs (traditional feed), video/audio
+ // (podcasts) and photos (photocasts, photostreams). Each of these is
+ // different in that there's a different class of application suitable for
+ // handling feeds of that type, but without a content-type differentiation
+ // it is difficult for us to disambiguate.
+ //
+ // The other problem is that if the user specifies an auto-action handler
+ // for one feed application, the fact that the content type is shared means
+ // that all other applications will auto-load with that handler too,
+ // regardless of the content-type.
+ //
+ // This means that content-type alone is not enough to determine whether
+ // or not a feed should be auto-handled. This means that for feeds we need
+ // to always use this stream converter, even when an auto-action is
+ // specified, not the basic one provided by WebContentConverter. This
+ // converter needs to consume all of the data and parse it, and based on
+ // that determination make a judgement about type.
+ //
+ // Since there are no content types for this content, and I'm not going to
+ // invent any, the upshot is that while a user can set an auto-handler for
+ // generic feed content, the system will prevent them from setting an auto-
+ // handler for other stream types. In those cases, the user will always see
+ // the preview page and have to select a handler. We can guess and show
+ // a client handler, but will not be able to show web handlers for those
+ // types.
+ //
+ // If this is just a feed, not some kind of specialized application, then
+ // auto-handlers can be set and we should obey them.
+ try {
+ var feedService =
+ Cc["@mozilla.org/browser/feeds/result-service;1"].
+ getService(Ci.nsIFeedResultService);
+ if (!this._forcePreviewPage && result.doc) {
+ var feed = result.doc.QueryInterface(Ci.nsIFeed);
+ var handler = safeGetCharPref(getPrefActionForType(feed.type), "ask");
+
+ if (handler != "ask") {
+ if (handler == "reader")
+ handler = safeGetCharPref(getPrefReaderForType(feed.type), "bookmarks");
+ switch (handler) {
+ case "web":
+ var wccr =
+ Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
+ getService(Ci.nsIWebContentConverterService);
+ if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
+ wccr.getAutoHandler(TYPE_MAYBE_FEED)) ||
+ (feed.type == Ci.nsIFeed.TYPE_VIDEO &&
+ wccr.getAutoHandler(TYPE_MAYBE_VIDEO_FEED)) ||
+ (feed.type == Ci.nsIFeed.TYPE_AUDIO &&
+ wccr.getAutoHandler(TYPE_MAYBE_AUDIO_FEED))) {
+ wccr.loadPreferredHandler(this._request);
+ return;
+ }
+ break;
+
+ default:
+ LOG("unexpected handler: " + handler);
+ // fall through -- let feed service handle error
+ case "bookmarks":
+ case "client":
+ try {
+ var title = feed.title ? feed.title.plainText() : "";
+ var desc = feed.subtitle ? feed.subtitle.plainText() : "";
+ feedService.addToClientReader(result.uri.spec, title, desc, feed.type);
+ return;
+ } catch(ex) { /* fallback to preview mode */ }
+ }
+ }
+ }
+
+ var ios =
+ Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var chromeChannel;
+
+ // show the feed page if it wasn't sniffed and we have a document,
+ // or we have a document, title, and link or id
+ if (result.doc && (!this._sniffed ||
+ (result.doc.title && (result.doc.link || result.doc.id)))) {
+
+ // If there was no automatic handler, or this was a podcast,
+ // photostream or some other kind of application, we must always
+ // show the preview page.
+
+ // Store the result in the result service so that the display
+ // page can access it.
+
+ feedService.addFeedResult(result);
+
+ // Now load the actual XUL document.
+ var chromeURI = ios.newURI(FEEDHANDLER_URI, null, null);
+ chromeChannel = ios.newChannelFromURI(chromeURI, null);
+ chromeChannel.originalURI = result.uri;
+ }
+ else
+ chromeChannel = ios.newChannelFromURI(result.uri, null);
+
+ chromeChannel.loadGroup = this._request.loadGroup;
+ chromeChannel.asyncOpen(this._listener, null);
+ }
+ finally {
+ this._releaseHandles();
+ }
+ },
+
+ /**
+ * See nsIStreamListener.idl
+ */
+ onDataAvailable: function FC_onDataAvailable(request, context, inputStream,
+ sourceOffset, count) {
+ if (this._processor)
+ this._processor.onDataAvailable(request, context, inputStream,
+ sourceOffset, count);
+ },
+
+ /**
+ * See nsIRequestObserver.idl
+ */
+ onStartRequest: function FC_onStartRequest(request, context) {
+ var channel = request.QueryInterface(Ci.nsIChannel);
+
+ // Check for a header that tells us there was no sniffing
+ // The value doesn't matter.
+ try {
+ var httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
+ var noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
+ }
+ catch (ex) {
+ this._sniffed = true;
+ }
+
+ this._request = request;
+
+ // Save and reset the forced state bit early, in case there's some kind of
+ // error.
+ var feedService =
+ Cc["@mozilla.org/browser/feeds/result-service;1"].
+ getService(Ci.nsIFeedResultService);
+ this._forcePreviewPage = feedService.forcePreviewPage;
+ feedService.forcePreviewPage = false;
+
+ // Parse feed data as it comes in
+ this._processor =
+ Cc["@mozilla.org/feed-processor;1"].
+ createInstance(Ci.nsIFeedProcessor);
+ this._processor.listener = this;
+ this._processor.parseAsync(null, channel.URI);
+
+ this._processor.onStartRequest(request, context);
+ },
+
+ /**
+ * See nsIRequestObserver.idl
+ */
+ onStopRequest: function FC_onStopReqeust(request, context, status) {
+ if (this._processor)
+ this._processor.onStopRequest(request, context, status);
+ },
+
+ /**
+ * See nsISupports.idl
+ */
+ QueryInterface: function FC_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIFeedResultListener) ||
+ iid.equals(Ci.nsIStreamConverter) ||
+ iid.equals(Ci.nsIStreamListener) ||
+ iid.equals(Ci.nsIRequestObserver)||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+};
+
+var FeedConverterFactory = {
+ createInstance: function FS_createInstance(outer, iid) {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return new FeedConverter().QueryInterface(iid);
+ },
+
+ QueryInterface: function FS_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIFactory) ||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+};
+
+/**
+ * Keeps parsed FeedResults around for use elsewhere in the UI after the stream
+ * converter completes.
+ */
+var FeedResultService = {
+
+ /**
+ * A URI spec -> [nsIFeedResult] hash. We have to keep a list as the
+ * value in case the same URI is requested concurrently.
+ */
+ _results: { },
+
+ /**
+ * See nsIFeedResultService.idl
+ */
+ forcePreviewPage: false,
+
+ /**
+ * See nsIFeedResultService.idl
+ */
+ addToClientReader: function FRS_addToClientReader(spec, title, subtitle, feedType) {
+ var prefs =
+ Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+
+ var handler = safeGetCharPref(getPrefActionForType(feedType), "bookmarks");
+ if (handler == "ask" || handler == "reader")
+ handler = safeGetCharPref(getPrefReaderForType(feedType), "bookmarks");
+
+ switch (handler) {
+ case "client":
+ var clientApp = prefs.getComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile);
+
+ // For the benefit of applications that might know how to deal with more
+ // URLs than just feeds, send feed: URLs in the following format:
+ //
+ // http urls: replace scheme with feed, e.g.
+ // http://foo.com/index.rdf -> feed://foo.com/index.rdf
+ // other urls: prepend feed: scheme, e.g.
+ // https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
+ var ios =
+ Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var feedURI = ios.newURI(spec, null, null);
+ if (feedURI.schemeIs("http")) {
+ feedURI.scheme = "feed";
+ spec = feedURI.spec;
+ }
+ else
+ spec = "feed:" + spec;
+
+ // Retrieving the shell service might fail on some systems, most
+ // notably systems where GNOME is not installed.
+ try {
+ var ss =
+ Cc["@mozilla.org/browser/shell-service;1"].
+ getService(Ci.nsIShellService);
+ ss.openApplicationWithURI(clientApp, spec);
+ } catch(e) {
+ // If we couldn't use the shell service, fallback to using a
+ // nsIProcess instance
+ var p =
+ Cc["@mozilla.org/process/util;1"].
+ createInstance(Ci.nsIProcess);
+ p.init(clientApp);
+ p.run(false, [spec], 1);
+ }
+ break;
+
+ default:
+ // "web" should have been handled elsewhere
+ LOG("unexpected handler: " + handler);
+ // fall through
+ case "bookmarks":
+ var wm =
+ Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ var topWindow = wm.getMostRecentWindow("navigator:browser");
+ topWindow.PlacesCommandHook.addLiveBookmark(spec, title, subtitle);
+ break;
+ }
+ },
+
+ /**
+ * See nsIFeedResultService.idl
+ */
+ addFeedResult: function FRS_addFeedResult(feedResult) {
+ NS_ASSERT(feedResult.uri != null, "null URI!");
+ NS_ASSERT(feedResult.uri != null, "null feedResult!");
+ var spec = feedResult.uri.spec;
+ if(!this._results[spec])
+ this._results[spec] = [];
+ this._results[spec].push(feedResult);
+ },
+
+ /**
+ * See nsIFeedResultService.idl
+ */
+ getFeedResult: function RFS_getFeedResult(uri) {
+ NS_ASSERT(uri != null, "null URI!");
+ var resultList = this._results[uri.spec];
+ for (var i in resultList) {
+ if (resultList[i].uri == uri)
+ return resultList[i];
+ }
+ return null;
+ },
+
+ /**
+ * See nsIFeedResultService.idl
+ */
+ removeFeedResult: function FRS_removeFeedResult(uri) {
+ NS_ASSERT(uri != null, "null URI!");
+ var resultList = this._results[uri.spec];
+ if (!resultList)
+ return;
+ var deletions = 0;
+ for (var i = 0; i < resultList.length; ++i) {
+ if (resultList[i].uri == uri) {
+ delete resultList[i];
+ ++deletions;
+ }
+ }
+
+ // send the holes to the end
+ resultList.sort();
+ // and trim the list
+ resultList.splice(resultList.length - deletions, deletions);
+ if (resultList.length == 0)
+ delete this._results[uri.spec];
+ },
+
+ createInstance: function FRS_createInstance(outer, iid) {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return this.QueryInterface(iid);
+ },
+
+ QueryInterface: function FRS_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIFeedResultService) ||
+ iid.equals(Ci.nsIFactory) ||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+};
+
+/**
+ * A protocol handler that attempts to deal with the variant forms of feed:
+ * URIs that are actually either http or https.
+ */
+function FeedProtocolHandler(scheme) {
+ this._scheme = scheme;
+ var ios =
+ Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ this._http = ios.getProtocolHandler("http");
+}
+FeedProtocolHandler.prototype = {
+ _scheme: "",
+ get scheme() {
+ return this._scheme;
+ },
+
+ get protocolFlags() {
+ return this._http.protocolFlags;
+ },
+
+ get defaultPort() {
+ return this._http.defaultPort;
+ },
+
+ allowPort: function FPH_allowPort(port, scheme) {
+ return this._http.allowPort(port, scheme);
+ },
+
+ newURI: function FPH_newURI(spec, originalCharset, baseURI) {
+ // See bug 408599 - feed URIs can be either standard URLs of the form
+ // feed://example.com, in which case the real protocol is http, or nested
+ // URIs of the form feed:realscheme:. When realscheme is either http or
+ // https, we deal with the way that creates a standard URL with the
+ // realscheme as the host by unmangling in newChannel; for others, we fail
+ // rather than let it wind up loading something like www.realscheme.com//foo
+
+ const feedSlashes = "feed://";
+ const feedHttpSlashes = "feed:http://";
+ const feedHttpsSlashes = "feed:https://";
+ const NS_ERROR_MALFORMED_URI = 0x804B000A;
+
+ if (spec.substr(0, feedSlashes.length) != feedSlashes &&
+ spec.substr(0, feedHttpSlashes.length) != feedHttpSlashes &&
+ spec.substr(0, feedHttpsSlashes.length) != feedHttpsSlashes)
+ throw NS_ERROR_MALFORMED_URI;
+
+ var uri =
+ Cc["@mozilla.org/network/standard-url;1"].
+ createInstance(Ci.nsIStandardURL);
+ uri.init(Ci.nsIStandardURL.URLTYPE_STANDARD, 80, spec, originalCharset,
+ baseURI);
+ return uri;
+ },
+
+ newChannel: function FPH_newChannel(aUri) {
+ var ios =
+ Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ // feed: URIs either start feed://, in which case the real scheme is http:
+ // or feed:http(s)://, (which by now we've changed to feed://realscheme//)
+ var feedSpec = aUri.spec;
+ const httpsChunk = "feed://https//";
+ const httpChunk = "feed://http//";
+ if (feedSpec.substr(0, httpsChunk.length) == httpsChunk)
+ feedSpec = "https://" + feedSpec.substr(httpsChunk.length);
+ else if (feedSpec.substr(0, httpChunk.length) == httpChunk)
+ feedSpec = "http://" + feedSpec.substr(httpChunk.length);
+ else
+ feedSpec = feedSpec.replace(/^feed/, "http");
+
+ var uri = ios.newURI(feedSpec, aUri.originCharset, null);
+ var channel =
+ ios.newChannelFromURI(uri, null).QueryInterface(Ci.nsIHttpChannel);
+ // Set this so we know this is supposed to be a feed
+ channel.setRequestHeader("X-Moz-Is-Feed", "1", false);
+ channel.originalURI = aUri;
+ return channel;
+ },
+
+ QueryInterface: function FPH_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIProtocolHandler) ||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+};
+
+var Module = {
+ QueryInterface: function M_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIModule) ||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ getClassObject: function M_getClassObject(cm, cid, iid) {
+ if (!iid.equals(Ci.nsIFactory))
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+
+ if (cid.equals(FS_CLASSID))
+ return FeedResultService;
+ if (cid.equals(FPH_CLASSID))
+ return new GenericComponentFactory(FeedProtocolHandler, "feed");
+ if (cid.equals(PCPH_CLASSID))
+ return new GenericComponentFactory(FeedProtocolHandler, "pcast");
+ if (cid.equals(FC_CLASSID))
+ return new GenericComponentFactory(FeedConverter);
+
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ registerSelf: function M_registerSelf(cm, file, location, type) {
+ var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
+
+ cr.registerFactoryLocation(FS_CLASSID, FS_CLASSNAME, FS_CONTRACTID,
+ file, location, type);
+ cr.registerFactoryLocation(FPH_CLASSID, FPH_CLASSNAME, FPH_CONTRACTID,
+ file, location, type);
+ cr.registerFactoryLocation(PCPH_CLASSID, PCPH_CLASSNAME, PCPH_CONTRACTID,
+ file, location, type);
+
+ // The feed converter is always attached, since parsing must be done to
+ // determine whether or not auto-handling can occur.
+ const converterPrefix = "@mozilla.org/streamconv;1?from=";
+ var converterContractID =
+ converterPrefix + TYPE_MAYBE_FEED + "&to=" + TYPE_ANY;
+ cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
+ file, location, type);
+
+ converterContractID =
+ converterPrefix + TYPE_MAYBE_VIDEO_FEED + "&to=" + TYPE_ANY;
+ cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
+ file, location, type);
+
+ converterContractID =
+ converterPrefix + TYPE_MAYBE_AUDIO_FEED + "&to=" + TYPE_ANY;
+ cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
+ file, location, type);
+ },
+
+ unregisterSelf: function M_unregisterSelf(cm, location, type) {
+ var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
+ cr.unregisterFactoryLocation(FPH_CLASSID, location);
+ cr.unregisterFactoryLocation(PCPH_CLASSID, location);
+ },
+
+ canUnload: function M_canUnload(cm) {
+ return true;
+ }
+};
+
+function NSGetModule(cm, file) {
+ return Module;
+}
+
+//@line 44 "/builds/moz2_slave/linux_build/build/toolkit/content/debug.js"
+
+var EXPORTED_SYMBOLS = ["NS_ASSERT"];
+
+var gTraceOnAssert = true;
+
+/**
+ * This function provides a simple assertion function for JavaScript.
+ * If the condition is true, this function will do nothing. If the
+ * condition is false, then the message will be printed to the console
+ * and an alert will appear showing a stack trace, so that the (alpha
+ * or nightly) user can file a bug containing it. For future enhancements,
+ * see bugs 330077 and 330078.
+ *
+ * To suppress the dialogs, you can run with the environment variable
+ * XUL_ASSERT_PROMPT set to 0 (if unset, this defaults to 1).
+ *
+ * @param condition represents the condition that we're asserting to be
+ * true when we call this function--should be
+ * something that can be evaluated as a boolean.
+ * @param message a string to be displayed upon failure of the assertion
+ */
+
+function NS_ASSERT(condition, message) {
+ if (condition)
+ return;
+
+ var releaseBuild = true;
+ var defB = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService)
+ .getDefaultBranch(null);
+ try {
+ switch (defB.getCharPref("app.update.channel")) {
+ case "nightly":
+ case "beta":
+ case "default":
+ releaseBuild = false;
+ }
+ } catch(ex) {}
+
+ var caller = arguments.callee.caller;
+ var assertionText = "ASSERT: " + message + "\n";
+
+ if (releaseBuild) {
+ // Just report the error to the console
+ Components.utils.reportError(assertionText);
+ return;
+ }
+
+ // Otherwise, dump to stdout and launch an assertion failure dialog
+ dump(assertionText);
+
+ var stackText = "";
+ if (gTraceOnAssert) {
+ stackText = "Stack Trace: \n";
+ var count = 0;
+ while (caller) {
+ stackText += count++ + ":" + caller.name + "(";
+ for (var i = 0; i < caller.arguments.length; ++i) {
+ var arg = caller.arguments[i];
+ stackText += arg;
+ if (i < caller.arguments.length - 1)
+ stackText += ",";
+ }
+ stackText += ")\n";
+ caller = caller.arguments.callee.caller;
+ }
+ }
+
+ var environment = Components.classes["@mozilla.org/process/environment;1"].
+ getService(Components.interfaces.nsIEnvironment);
+ if (environment.exists("XUL_ASSERT_PROMPT") &&
+ !parseInt(environment.get("XUL_ASSERT_PROMPT")))
+ return;
+
+ var source = null;
+ if (this.window)
+ source = this.window;
+ var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Components.interfaces.nsIPromptService);
+ ps.alert(source, "Assertion Failed", assertionText + stackText);
+}
+//@line 37 "/builds/moz2_slave/linux_build/build/browser/components/feeds/src/GenericFactory.js"
+
+/**
+ * An object implementing nsIFactory that can construct other objects upon
+ * createInstance, passing a set of parameters to that object's constructor.
+ */
+function GenericComponentFactory(ctor, params) {
+ this._ctor = ctor;
+ this._params = params;
+}
+GenericComponentFactory.prototype = {
+ _ctor: null,
+ _params: null,
+
+ createInstance: function GCF_createInstance(outer, iid) {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return (new this._ctor(this._params)).QueryInterface(iid);
+ },
+
+ QueryInterface: function GCF_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIFactory) ||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+};
+
diff --git a/bundles/XO/components/FeedProcessor.js b/bundles/XO/components/FeedProcessor.js
new file mode 100755
index 0000000..64298ee
--- /dev/null
+++ b/bundles/XO/components/FeedProcessor.js
@@ -0,0 +1,1950 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Robert Sayre.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ben Goodger <beng@google.com>
+ * Myk Melez <myk@mozilla.org>
+ * Michael Ventnor <m.ventnor@gmail.com>
+ * Will Guaraldi <will.guaraldi@pculture.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+function LOG(str) {
+ dump("*** " + str + "\n");
+}
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/ISO8601DateUtils.jsm");
+
+const FP_CONTRACTID = "@mozilla.org/feed-processor;1";
+const FP_CLASSID = Components.ID("{26acb1f0-28fc-43bc-867a-a46aabc85dd4}");
+const FP_CLASSNAME = "Feed Processor";
+const FR_CONTRACTID = "@mozilla.org/feed-result;1";
+const FR_CLASSID = Components.ID("{072a5c3d-30c6-4f07-b87f-9f63d51403f2}");
+const FR_CLASSNAME = "Feed Result";
+const FEED_CONTRACTID = "@mozilla.org/feed;1";
+const FEED_CLASSID = Components.ID("{5d0cfa97-69dd-4e5e-ac84-f253162e8f9a}");
+const FEED_CLASSNAME = "Feed";
+const ENTRY_CONTRACTID = "@mozilla.org/feed-entry;1";
+const ENTRY_CLASSID = Components.ID("{8e4444ff-8e99-4bdd-aa7f-fb3c1c77319f}");
+const ENTRY_CLASSNAME = "Feed Entry";
+const TEXTCONSTRUCT_CONTRACTID = "@mozilla.org/feed-textconstruct;1";
+const TEXTCONSTRUCT_CLASSID =
+ Components.ID("{b992ddcd-3899-4320-9909-924b3e72c922}");
+const TEXTCONSTRUCT_CLASSNAME = "Feed Text Construct";
+const GENERATOR_CONTRACTID = "@mozilla.org/feed-generator;1";
+const GENERATOR_CLASSID =
+ Components.ID("{414af362-9ad8-4296-898e-62247f25a20e}");
+const GENERATOR_CLASSNAME = "Feed Generator";
+const PERSON_CONTRACTID = "@mozilla.org/feed-person;1";
+const PERSON_CLASSID = Components.ID("{95c963b7-20b2-11db-92f6-001422106990}");
+const PERSON_CLASSNAME = "Feed Person";
+
+const IO_CONTRACTID = "@mozilla.org/network/io-service;1"
+const BAG_CONTRACTID = "@mozilla.org/hash-property-bag;1"
+const ARRAY_CONTRACTID = "@mozilla.org/array;1";
+const SAX_CONTRACTID = "@mozilla.org/saxparser/xmlreader;1";
+const UNESCAPE_CONTRACTID = "@mozilla.org/feed-unescapehtml;1";
+
+
+var gIoService = null;
+
+const XMLNS = "http://www.w3.org/XML/1998/namespace";
+const RSS090NS = "http://my.netscape.com/rdf/simple/0.9/";
+const WAIROLE_NS = "http://www.w3.org/2005/01/wai-rdf/GUIRoleTaxonomy#";
+
+/***** Some general utils *****/
+function strToURI(link, base) {
+ var base = base || null;
+ if (!gIoService)
+ gIoService = Cc[IO_CONTRACTID].getService(Ci.nsIIOService);
+ try {
+ return gIoService.newURI(link, null, base);
+ }
+ catch(e) {
+ return null;
+ }
+}
+
+function isArray(a) {
+ return isObject(a) && a.constructor == Array;
+}
+
+function isObject(a) {
+ return (a && typeof a == "object") || isFunction(a);
+}
+
+function isFunction(a) {
+ return typeof a == "function";
+}
+
+function isIID(a, iid) {
+ var rv = false;
+ try {
+ a.QueryInterface(iid);
+ rv = true;
+ }
+ catch(e) {
+ }
+ return rv;
+}
+
+function isIArray(a) {
+ return isIID(a, Ci.nsIArray);
+}
+
+function isIFeedContainer(a) {
+ return isIID(a, Ci.nsIFeedContainer);
+}
+
+function stripTags(someHTML) {
+ return someHTML.replace(/<[^>]+>/g,"");
+}
+
+/**
+ * Searches through an array of links and returns a JS array
+ * of matching property bags.
+ */
+const IANA_URI = "http://www.iana.org/assignments/relation/";
+function findAtomLinks(rel, links) {
+ var rvLinks = [];
+ for (var i = 0; i < links.length; ++i) {
+ var linkElement = links.queryElementAt(i, Ci.nsIPropertyBag2);
+ // atom:link MUST have @href
+ if (bagHasKey(linkElement, "href")) {
+ var relAttribute = null;
+ if (bagHasKey(linkElement, "rel"))
+ relAttribute = linkElement.getPropertyAsAString("rel")
+ if ((!relAttribute && rel == "alternate") || relAttribute == rel) {
+ rvLinks.push(linkElement);
+ continue;
+ }
+ // catch relations specified by IANA URI
+ if (relAttribute == IANA_URI + rel) {
+ rvLinks.push(linkElement);
+ }
+ }
+ }
+ return rvLinks;
+}
+
+function xmlEscape(s) {
+ s = s.replace(/&/g, "&amp;");
+ s = s.replace(/>/g, "&gt;");
+ s = s.replace(/</g, "&lt;");
+ s = s.replace(/"/g, "&quot;");
+ s = s.replace(/'/g, "&apos;");
+ return s;
+}
+
+function arrayContains(array, element) {
+ for (var i = 0; i < array.length; ++i) {
+ if (array[i] == element) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// XXX add hasKey to nsIPropertyBag
+function bagHasKey(bag, key) {
+ try {
+ bag.getProperty(key);
+ return true;
+ }
+ catch (e) {
+ return false;
+ }
+}
+
+function makePropGetter(key) {
+ return function FeedPropGetter(bag) {
+ try {
+ return value = bag.getProperty(key);
+ }
+ catch(e) {
+ }
+ return null;
+ }
+}
+
+function W3CToIETFDate(dateString) {
+ var date = ISO8601DateUtils.parse(dateString);
+ return date.toUTCString();
+}
+
+const RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+// namespace map
+var gNamespaces = {
+ "http://webns.net/mvcb/":"admin",
+ "http://backend.userland.com/rss":"",
+ "http://blogs.law.harvard.edu/tech/rss":"",
+ "http://www.w3.org/2005/Atom":"atom",
+ "http://purl.org/atom/ns#":"atom03",
+ "http://purl.org/rss/1.0/modules/content/":"content",
+ "http://purl.org/dc/elements/1.1/":"dc",
+ "http://purl.org/dc/terms/":"dcterms",
+ "http://www.w3.org/1999/02/22-rdf-syntax-ns#":"rdf",
+ "http://purl.org/rss/1.0/":"rss1",
+ "http://my.netscape.com/rdf/simple/0.9/":"rss1",
+ "http://wellformedweb.org/CommentAPI/":"wfw",
+ "http://purl.org/rss/1.0/modules/wiki/":"wiki",
+ "http://www.w3.org/XML/1998/namespace":"xml",
+ "http://search.yahoo.com/mrss/":"media",
+ "http://search.yahoo.com/mrss":"media"
+}
+
+// We allow a very small set of namespaces in XHTML content,
+// for attributes only
+var gAllowedXHTMLNamespaces = {
+ "http://www.w3.org/XML/1998/namespace":"xml",
+ "http://www.w3.org/TR/xhtml2":"xhtml2",
+ "http://www.w3.org/2005/07/aaa":"aaa",
+ // if someone ns qualifies XHTML, we have to prefix it to avoid an
+ // attribute collision.
+ "http://www.w3.org/1999/xhtml":"xhtml"
+}
+
+function FeedResult() {}
+FeedResult.prototype = {
+ bozo: false,
+ doc: null,
+ version: null,
+ headers: null,
+ uri: null,
+ stylesheet: null,
+
+ registerExtensionPrefix: function FR_registerExtensionPrefix(ns, prefix) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ // XPCOM stuff
+ classDescription: FR_CLASSNAME,
+ classID: FR_CLASSID,
+ contractID: FR_CONTRACTID,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFeedResult])
+}
+
+function Feed() {
+ this.subtitle = null;
+ this.title = null;
+ this.items = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
+ this.link = null;
+ this.id = null;
+ this.generator = null;
+ this.authors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
+ this.contributors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
+ this.baseURI = null;
+ this.enclosureCount = 0;
+ this.type = Ci.nsIFeed.TYPE_FEED;
+}
+
+Feed.prototype = {
+ searchLists: {
+ title: ["title", "rss1:title", "atom03:title", "atom:title"],
+ subtitle: ["description","dc:description","rss1:description",
+ "atom03:tagline","atom:subtitle"],
+ items: ["items","atom03_entries","entries"],
+ id: ["atom:id","rdf:about"],
+ generator: ["generator"],
+ authors : ["authors"],
+ contributors: ["contributors"],
+ title: ["title","rss1:title", "atom03:title","atom:title"],
+ link: [["link",strToURI],["rss1:link",strToURI]],
+ categories: ["categories", "dc:subject"],
+ rights: ["atom03:rights","atom:rights"],
+ cloud: ["cloud"],
+ image: ["image", "rss1:image", "atom:logo"],
+ textInput: ["textInput", "rss1:textinput"],
+ skipDays: ["skipDays"],
+ skipHours: ["skipHours"],
+ updated: ["pubDate", "lastBuildDate", "atom03:modified", "dc:date",
+ "dcterms:modified", "atom:updated"]
+ },
+
+ normalize: function Feed_normalize() {
+ fieldsToObj(this, this.searchLists);
+ if (this.skipDays)
+ this.skipDays = this.skipDays.getProperty("days");
+ if (this.skipHours)
+ this.skipHours = this.skipHours.getProperty("hours");
+
+ if (this.updated)
+ this.updated = dateParse(this.updated);
+
+ // Assign Atom link if needed
+ if (bagHasKey(this.fields, "links"))
+ this._atomLinksToURI();
+
+ this._calcEnclosureCountAndFeedType();
+
+ // Resolve relative image links
+ if (this.image && bagHasKey(this.image, "url"))
+ this._resolveImageLink();
+
+ this._resetBagMembersToRawText([this.searchLists.subtitle,
+ this.searchLists.title]);
+ },
+
+ _calcEnclosureCountAndFeedType: function Feed_calcEnclosureCountAndFeedType() {
+ var entries_with_enclosures = 0;
+ var audio_count = 0;
+ var image_count = 0;
+ var video_count = 0;
+ var other_count = 0;
+
+ for (var i = 0; i < this.items.length; ++i) {
+ var entry = this.items.queryElementAt(i, Ci.nsIFeedEntry);
+ entry.QueryInterface(Ci.nsIFeedContainer);
+
+ if (entry.enclosures && entry.enclosures.length > 0) {
+ ++entries_with_enclosures;
+
+ for (var e = 0; e < entry.enclosures.length; ++e) {
+ var enc = entry.enclosures.queryElementAt(e, Ci.nsIWritablePropertyBag2);
+ if (enc.hasKey("type")) {
+ var enctype = enc.get("type");
+
+ if (/^audio/.test(enctype)) {
+ ++audio_count;
+ } else if (/^image/.test(enctype)) {
+ ++image_count;
+ } else if (/^video/.test(enctype)) {
+ ++video_count;
+ } else {
+ ++other_count;
+ }
+ } else {
+ ++other_count;
+ }
+ }
+ }
+ }
+
+ var feedtype = Ci.nsIFeed.TYPE_FEED;
+
+ // For a feed to be marked as TYPE_VIDEO, TYPE_AUDIO and TYPE_IMAGE,
+ // we enforce two things:
+ //
+ // 1. all entries must have at least one enclosure
+ // 2. all enclosures must be video for TYPE_VIDEO, audio for TYPE_AUDIO or image
+ // for TYPE_IMAGE
+ //
+ // Otherwise it's a TYPE_FEED.
+ if (entries_with_enclosures == this.items.length && other_count == 0) {
+ if (audio_count > 0 && !video_count && !image_count) {
+ feedtype = Ci.nsIFeed.TYPE_AUDIO;
+
+ } else if (image_count > 0 && !audio_count && !video_count) {
+ feedtype = Ci.nsIFeed.TYPE_IMAGE;
+
+ } else if (video_count > 0 && !audio_count && !image_count) {
+ feedtype = Ci.nsIFeed.TYPE_VIDEO;
+ }
+ }
+
+ this.type = feedtype;
+ this.enclosureCount = other_count + video_count + audio_count + image_count;
+ },
+
+ _atomLinksToURI: function Feed_linkToURI() {
+ var links = this.fields.getPropertyAsInterface("links", Ci.nsIArray);
+ var alternates = findAtomLinks("alternate", links);
+ if (alternates.length > 0) {
+ var href = alternates[0].getPropertyAsAString("href");
+ var base;
+ if (bagHasKey(alternates[0], "xml:base"))
+ base = alternates[0].getPropertyAsAString("xml:base");
+ this.link = this._resolveURI(href, base);
+ }
+ },
+
+ _resolveImageLink: function Feed_resolveImageLink() {
+ var base;
+ if (bagHasKey(this.image, "xml:base"))
+ base = this.image.getPropertyAsAString("xml:base");
+ var url = this._resolveURI(this.image.getPropertyAsAString("url"), base);
+ if (url)
+ this.image.setPropertyAsAString("url", url.spec);
+ },
+
+ _resolveURI: function Feed_resolveURI(linkSpec, baseSpec) {
+ var uri = null;
+ try {
+ var base = baseSpec ? strToURI(baseSpec, this.baseURI) : this.baseURI;
+ uri = strToURI(linkSpec, base);
+ }
+ catch(e) {
+ LOG(e);
+ }
+
+ return uri;
+ },
+
+ // reset the bag to raw contents, not text constructs
+ _resetBagMembersToRawText: function Feed_resetBagMembers(fieldLists) {
+ for (var i=0; i<fieldLists.length; i++) {
+ for (var j=0; j<fieldLists[i].length; j++) {
+ if (bagHasKey(this.fields, fieldLists[i][j])) {
+ var textConstruct = this.fields.getProperty(fieldLists[i][j]);
+ this.fields.setPropertyAsAString(fieldLists[i][j],
+ textConstruct.text);
+ }
+ }
+ }
+ },
+
+ // XPCOM stuff
+ classDescription: FEED_CLASSNAME,
+ classID: FEED_CLASSID,
+ contractID: FEED_CONTRACTID,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFeed, Ci.nsIFeedContainer])
+}
+
+function Entry() {
+ this.summary = null;
+ this.content = null;
+ this.title = null;
+ this.fields = Cc["@mozilla.org/hash-property-bag;1"].
+ createInstance(Ci.nsIWritablePropertyBag2);
+ this.link = null;
+ this.id = null;
+ this.baseURI = null;
+ this.updated = null;
+ this.published = null;
+ this.authors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
+ this.contributors = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
+}
+
+Entry.prototype = {
+ fields: null,
+ enclosures: null,
+ mediaContent: null,
+
+ searchLists: {
+ title: ["title", "rss1:title", "atom03:title", "atom:title"],
+ link: [["link",strToURI],["rss1:link",strToURI]],
+ id: [["guid", makePropGetter("guid")], "rdf:about",
+ "atom03:id", "atom:id"],
+ authors : ["authors"],
+ contributors: ["contributors"],
+ summary: ["description", "rss1:description", "dc:description",
+ "atom03:summary", "atom:summary"],
+ content: ["content:encoded","atom03:content","atom:content"],
+ rights: ["atom03:rights","atom:rights"],
+ published: ["pubDate", "atom03:issued", "dcterms:issued", "atom:published"],
+ updated: ["pubDate", "atom03:modified", "dc:date", "dcterms:modified",
+ "atom:updated"]
+ },
+
+ normalize: function Entry_normalize() {
+ fieldsToObj(this, this.searchLists);
+
+ // Assign Atom link if needed
+ if (bagHasKey(this.fields, "links"))
+ this._atomLinksToURI();
+
+ // Populate enclosures array
+ this._populateEnclosures();
+
+ // The link might be a guid w/ permalink=true
+ if (!this.link && bagHasKey(this.fields, "guid")) {
+ var guid = this.fields.getProperty("guid");
+ var isPermaLink = true;
+
+ if (bagHasKey(guid, "isPermaLink"))
+ isPermaLink = guid.getProperty("isPermaLink").toLowerCase() != "false";
+
+ if (guid && isPermaLink)
+ this.link = strToURI(guid.getProperty("guid"));
+ }
+
+ if (this.updated)
+ this.updated = dateParse(this.updated);
+ if (this.published)
+ this.published = dateParse(this.published);
+
+ this._resetBagMembersToRawText([this.searchLists.content,
+ this.searchLists.summary,
+ this.searchLists.title]);
+ },
+
+ _populateEnclosures: function Entry_populateEnclosures() {
+ if (bagHasKey(this.fields, "links"))
+ this._atomLinksToEnclosures();
+
+ // Add RSS2 enclosure to enclosures
+ if (bagHasKey(this.fields, "enclosure"))
+ this._enclosureToEnclosures();
+
+ // Add media:content to enclosures
+ if (bagHasKey(this.fields, "mediacontent"))
+ this._mediacontentToEnclosures();
+
+ // Add media:content in media:group to enclosures
+ if (bagHasKey(this.fields, "mediagroup"))
+ this._mediagroupToEnclosures();
+ },
+
+ __enclosure_map: null,
+
+ _addToEnclosures: function Entry_addToEnclosures(new_enc) {
+ // items we add to the enclosures array get displayed in the FeedWriter and
+ // they must have non-empty urls.
+ if (!bagHasKey(new_enc, "url") || new_enc.getPropertyAsAString("url") == "")
+ return;
+
+ if (this.__enclosure_map == null)
+ this.__enclosure_map = {};
+
+ var previous_enc = this.__enclosure_map[new_enc.getPropertyAsAString("url")];
+
+ if (previous_enc != undefined) {
+ previous_enc.QueryInterface(Ci.nsIWritablePropertyBag2);
+
+ if (!bagHasKey(previous_enc, "type") && bagHasKey(new_enc, "type"))
+ previous_enc.setPropertyAsAString("type", new_enc.getPropertyAsAString("type"));
+
+ if (!bagHasKey(previous_enc, "length") && bagHasKey(new_enc, "length"))
+ previous_enc.setPropertyAsAString("length", new_enc.getPropertyAsAString("length"));
+
+ return;
+ }
+
+ if (this.enclosures == null) {
+ this.enclosures = Cc[ARRAY_CONTRACTID].createInstance(Ci.nsIMutableArray);
+ this.enclosures.QueryInterface(Ci.nsIMutableArray);
+ }
+
+ this.enclosures.appendElement(new_enc, false);
+ this.__enclosure_map[new_enc.getPropertyAsAString("url")] = new_enc;
+ },
+
+ _atomLinksToEnclosures: function Entry_linkToEnclosure() {
+ var links = this.fields.getPropertyAsInterface("links", Ci.nsIArray);
+ var enc_links = findAtomLinks("enclosure", links);
+ if (enc_links.length == 0)
+ return;
+
+ for (var i = 0; i < enc_links.length; ++i) {
+ var link = enc_links[i];
+
+ // an enclosure must have an href
+ if (!(link.getProperty("href")))
+ return;
+
+ var enc = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+
+ // copy Atom bits over to equivalent enclosure bits
+ enc.setPropertyAsAString("url", link.getPropertyAsAString("href"));
+ if (bagHasKey(link, "type"))
+ enc.setPropertyAsAString("type", link.getPropertyAsAString("type"));
+ if (bagHasKey(link, "length"))
+ enc.setPropertyAsAString("length", link.getPropertyAsAString("length"));
+
+ this._addToEnclosures(enc);
+ }
+ },
+
+ _enclosureToEnclosures: function Entry_enclosureToEnclosures() {
+ var enc = this.fields.getPropertyAsInterface("enclosure", Ci.nsIPropertyBag2);
+
+ if (!(enc.getProperty("url")))
+ return;
+
+ this._addToEnclosures(enc);
+ },
+
+ _mediacontentToEnclosures: function Entry_mediacontentToEnclosures() {
+ var mediacontent = this.fields.getPropertyAsInterface("mediacontent", Ci.nsIArray);
+
+ for (var i = 0; i < mediacontent.length; ++i) {
+ var contentElement = mediacontent.queryElementAt(i, Ci.nsIWritablePropertyBag2);
+
+ // media:content don't require url, but if it's not there, we should
+ // skip it.
+ if (!bagHasKey(contentElement, "url"))
+ continue;
+
+ var enc = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+
+ // copy media:content bits over to equivalent enclosure bits
+ enc.setPropertyAsAString("url", contentElement.getPropertyAsAString("url"));
+ if (bagHasKey(contentElement, "type")) {
+ enc.setPropertyAsAString("type", contentElement.getPropertyAsAString("type"));
+ }
+ if (bagHasKey(contentElement, "fileSize")) {
+ enc.setPropertyAsAString("length", contentElement.getPropertyAsAString("fileSize"));
+ }
+
+ this._addToEnclosures(enc);
+ }
+ },
+
+ _mediagroupToEnclosures: function Entry_mediagroupToEnclosures() {
+ var group = this.fields.getPropertyAsInterface("mediagroup", Ci.nsIPropertyBag2);
+
+ var content = group.getPropertyAsInterface("mediacontent", Ci.nsIArray);
+ for (var i = 0; i < content.length; ++i) {
+ var contentElement = content.queryElementAt(i, Ci.nsIWritablePropertyBag2);
+ // media:content don't require url, but if it's not there, we should
+ // skip it.
+ if (!bagHasKey(contentElement, "url"))
+ continue;
+
+ var enc = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+
+ // copy media:content bits over to equivalent enclosure bits
+ enc.setPropertyAsAString("url", contentElement.getPropertyAsAString("url"));
+ if (bagHasKey(contentElement, "type")) {
+ enc.setPropertyAsAString("type", contentElement.getPropertyAsAString("type"));
+ }
+ if (bagHasKey(contentElement, "fileSize")) {
+ enc.setPropertyAsAString("length", contentElement.getPropertyAsAString("fileSize"));
+ }
+
+ this._addToEnclosures(enc);
+ }
+ },
+
+ // XPCOM stuff
+ classDescription: ENTRY_CLASSNAME,
+ classID: ENTRY_CLASSID,
+ contractID: ENTRY_CONTRACTID,
+ QueryInterface: XPCOMUtils.generateQI(
+ [Ci.nsIFeedEntry, Ci.nsIFeedContainer]
+ )
+}
+
+Entry.prototype._atomLinksToURI = Feed.prototype._atomLinksToURI;
+Entry.prototype._resolveURI = Feed.prototype._resolveURI;
+Entry.prototype._resetBagMembersToRawText =
+ Feed.prototype._resetBagMembersToRawText;
+
+// TextConstruct represents and element that could contain (X)HTML
+function TextConstruct() {
+ this.lang = null;
+ this.base = null;
+ this.type = "text";
+ this.text = null;
+ this.unescapeHTML = Cc[UNESCAPE_CONTRACTID].
+ getService(Ci.nsIScriptableUnescapeHTML);
+}
+
+TextConstruct.prototype = {
+ plainText: function TC_plainText() {
+ if (this.type != "text") {
+ return this.unescapeHTML.unescape(stripTags(this.text));
+ }
+ return this.text;
+ },
+
+ createDocumentFragment: function TC_createDocumentFragment(element) {
+ if (this.type == "text") {
+ var doc = element.ownerDocument;
+ var docFragment = doc.createDocumentFragment();
+ var node = doc.createTextNode(this.text);
+ docFragment.appendChild(node);
+ return docFragment;
+ }
+ var isXML;
+ if (this.type == "xhtml")
+ isXML = true
+ else if (this.type == "html")
+ isXML = false;
+ else
+ return null;
+
+ return this.unescapeHTML.parseFragment(this.text, isXML,
+ this.base, element);
+ },
+
+ // XPCOM stuff
+ classDescription: TEXTCONSTRUCT_CLASSNAME,
+ classID: TEXTCONSTRUCT_CLASSID,
+ contractID: TEXTCONSTRUCT_CONTRACTID,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFeedTextConstruct])
+}
+
+// Generator represents the software that produced the feed
+function Generator() {
+ this.lang = null;
+ this.agent = null;
+ this.version = null;
+ this.uri = null;
+
+ // nsIFeedElementBase
+ this._attributes = null;
+ this.baseURI = null;
+}
+
+Generator.prototype = {
+
+ get attributes() {
+ return this._attributes;
+ },
+
+ set attributes(value) {
+ this._attributes = value;
+ this.version = this._attributes.getValueFromName("","version");
+ var uriAttribute = this._attributes.getValueFromName("","uri") ||
+ this._attributes.getValueFromName("","url");
+ this.uri = strToURI(uriAttribute, this.baseURI);
+
+ // RSS1
+ uriAttribute = this._attributes.getValueFromName(RDF_NS,"resource");
+ if (uriAttribute) {
+ this.agent = uriAttribute;
+ this.uri = strToURI(uriAttribute, this.baseURI);
+ }
+ },
+
+ // XPCOM stuff
+ classDescription: GENERATOR_CLASSNAME,
+ classID: GENERATOR_CLASSID,
+ contractID: GENERATOR_CONTRACTID,
+ QueryInterface: XPCOMUtils.generateQI(
+ [Ci.nsIFeedGenerator, Ci.nsIFeedElementBase]
+ )
+}
+
+function Person() {
+ this.name = null;
+ this.uri = null;
+ this.email = null;
+
+ // nsIFeedElementBase
+ this.attributes = null;
+ this.baseURI = null;
+}
+
+Person.prototype = {
+ // XPCOM stuff
+ classDescription: PERSON_CLASSNAME,
+ classID: PERSON_CLASSID,
+ contractID: PERSON_CONTRACTID,
+ QueryInterface: XPCOMUtils.generateQI(
+ [Ci.nsIFeedPerson, Ci.nsIFeedElementBase]
+ )
+}
+
+/**
+ * Map a list of fields into properties on a container.
+ *
+ * @param container An nsIFeedContainer
+ * @param fields A list of fields to search for. List members can
+ * be a list, in which case the second member is
+ * transformation function (like parseInt).
+ */
+function fieldsToObj(container, fields) {
+ var props,prop,field,searchList;
+ for (var key in fields) {
+ searchList = fields[key];
+ for (var i=0; i < searchList.length; ++i) {
+ props = searchList[i];
+ prop = null;
+ field = isArray(props) ? props[0] : props;
+ try {
+ prop = container.fields.getProperty(field);
+ }
+ catch(e) {
+ }
+ if (prop) {
+ prop = isArray(props) ? props[1](prop) : prop;
+ container[key] = prop;
+ }
+ }
+ }
+}
+
+/**
+ * Lower cases an element's localName property
+ * @param element A DOM element.
+ *
+ * @returns The lower case localName property of the specified element
+ */
+function LC(element) {
+ return element.localName.toLowerCase();
+}
+
+// TODO move these post-processor functions
+// create a generator element
+function atomGenerator(s, generator) {
+ generator.QueryInterface(Ci.nsIFeedGenerator);
+ generator.agent = trimString(s);
+ return generator;
+}
+
+// post-process atom:logo to create an RSS2-like structure
+function atomLogo(s, logo) {
+ logo.setPropertyAsAString("url", trimString(s));
+}
+
+// post-process an RSS category, map it to the Atom fields.
+function rssCatTerm(s, cat) {
+ // add slash handling?
+ cat.setPropertyAsAString("term", trimString(s));
+ return cat;
+}
+
+// post-process a GUID
+function rssGuid(s, guid) {
+ guid.setPropertyAsAString("guid", trimString(s));
+ return guid;
+}
+
+// post-process an RSS author element
+//
+// It can contain a field like this:
+//
+// <author>lawyer@boyer.net (Lawyer Boyer)</author>
+//
+// or, delightfully, a field like this:
+//
+// <dc:creator>Simon St.Laurent (mailto:simonstl@simonstl.com)</dc:creator>
+//
+// We want to split this up and assign it to corresponding Atom
+// fields.
+//
+function rssAuthor(s,author) {
+ author.QueryInterface(Ci.nsIFeedPerson);
+ // check for RSS2 string format
+ var chars = trimString(s);
+ var matches = chars.match(/(.*)\((.*)\)/);
+ var emailCheck =
+ /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
+ if (matches) {
+ var match1 = trimString(matches[1]);
+ var match2 = trimString(matches[2]);
+ if (match2.indexOf("mailto:") == 0)
+ match2 = match2.substring(7);
+ if (emailCheck.test(match1)) {
+ author.email = match1;
+ author.name = match2;
+ }
+ else if (emailCheck.test(match2)) {
+ author.email = match2;
+ author.name = match1;
+ }
+ else {
+ // put it back together
+ author.name = match1 + " (" + match2 + ")";
+ }
+ }
+ else {
+ author.name = chars;
+ if (chars.indexOf('@'))
+ author.email = chars;
+ }
+ return author;
+}
+
+//
+// skipHours and skipDays map to arrays, so we need to change the
+// string to an nsISupports in order to stick it in there.
+//
+function rssArrayElement(s) {
+ var str = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ str.data = s;
+ str.QueryInterface(Ci.nsISupportsString);
+ return str;
+}
+
+/***** Some feed utils from TBird *****/
+
+/**
+ * Tests a RFC822 date against a regex.
+ * @param aDateStr A string to test as an RFC822 date.
+ *
+ * @returns A boolean indicating whether the string is a valid RFC822 date.
+ */
+function isValidRFC822Date(aDateStr) {
+ var regex = new RegExp(RFC822_RE);
+ return regex.test(aDateStr);
+}
+
+/**
+ * Removes leading and trailing whitespace from a string.
+ * @param s The string to trim.
+ *
+ * @returns A new string with whitespace stripped.
+ */
+function trimString(s) {
+ return(s.replace(/^\s+/, "").replace(/\s+$/, ""));
+}
+
+// Regular expression matching RFC822 dates
+const RFC822_RE = "^((Mon|Tue|Wed|Thu|Fri|Sat|Sun)([a-z]+)?,? *)?\\d\\d?"
++ " +(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)([a-z]+)?"
++ " +\\d\\d(\\d\\d)? +\\d?\\d:\\d\\d(:\\d\\d)?"
++ " +([+-]?\\d\\d\\d\\d|GMT|UT[C]?|(E|C|M|P)(ST|DT)|[A-IK-Z])$";
+
+/**
+ * XXX -- need to decide what this should return.
+ * XXX -- Is there a Date class usable from C++?
+ *
+ * Tries tries parsing various date formats.
+ * @param dateString
+ * A string that is supposedly an RFC822 or RFC3339 date.
+ * @returns A Date.toString XXX--fixme
+ */
+function dateParse(dateString) {
+ var date = trimString(dateString);
+
+ if (date.search(/^\d\d\d\d/) != -1) //Could be a ISO8601/W3C date
+ return W3CToIETFDate(dateString);
+
+ if (isValidRFC822Date(date))
+ return date;
+
+ if (!isNaN(parseInt(date, 10))) {
+ //It's an integer, so maybe it's a timestamp
+ var d = new Date(parseInt(date, 10) * 1000);
+ var now = new Date();
+ var yeardiff = now.getFullYear() - d.getFullYear();
+ if ((yeardiff >= 0) && (yeardiff < 3)) {
+ // it's quite likely the correct date. 3 years is an arbitrary cutoff,
+ // but this is an invalid date format, and there's no way to verify
+ // its correctness.
+ return d.toString();
+ }
+ }
+ // Can't help.
+ return null;
+}
+
+
+const XHTML_NS = "http://www.w3.org/1999/xhtml";
+
+// The XHTMLHandler handles inline XHTML found in things like atom:summary
+function XHTMLHandler(processor, isAtom, waiPrefixes) {
+ this._buf = "";
+ this._processor = processor;
+ this._depth = 0;
+ this._isAtom = isAtom;
+ // a stack of lists tracking in-scope namespaces
+ this._inScopeNS = [];
+ this._waiPrefixes = waiPrefixes;
+}
+
+// The fidelity can be improved here, to allow handling of stuff like
+// SVG and MathML. XXX
+XHTMLHandler.prototype = {
+
+ // look back up at the declared namespaces
+ // we always use the same prefixes for our safe stuff
+ _isInScope: function XH__isInScope(ns) {
+ for (var i in this._inScopeNS) {
+ for (var uri in this._inScopeNS[i]) {
+ if (this._inScopeNS[i][uri] == ns)
+ return true;
+ }
+ }
+ return false;
+ },
+
+ startDocument: function XH_startDocument() {
+ },
+ endDocument: function XH_endDocument() {
+ },
+ startElement: function XH_startElement(uri, localName, qName, attributes) {
+ ++this._depth;
+ this._inScopeNS.push([]);
+
+ // RFC4287 requires XHTML to be wrapped in a div that is *not* part of
+ // the content. This prevents people from screwing up namespaces, but
+ // we need to skip it here.
+ if (this._isAtom && this._depth == 1 && localName == "div")
+ return;
+
+ // If it's an XHTML element, record it. Otherwise, it's ignored.
+ if (uri == XHTML_NS) {
+ this._buf += "<" + localName;
+ var uri;
+ for (var i=0; i < attributes.length; ++i) {
+ uri = attributes.getURI(i);
+ // XHTML attributes aren't in a namespace
+ if (uri == "") {
+ this._buf += (" " + attributes.getLocalName(i) + "='" +
+ xmlEscape(attributes.getValue(i)) + "'");
+ } else {
+ // write a small set of allowed attribute namespaces
+ var prefix = gAllowedXHTMLNamespaces[uri];
+ if (prefix != null) {
+ // The attribute value we'll attempt to write
+ var attributeValue = xmlEscape(attributes.getValue(i));
+
+ // More QName abuse from W3C
+ var rolePrefix = "";
+ if (attributes.getLocalName(i) == "role") {
+ for (var aPrefix in this._waiPrefixes) {
+ if (attributeValue.indexOf(aPrefix + ":") == 0) {
+ // Now, due to the terrible layer mismatch
+ // that is QNames in content, we have to see
+ // if the attribute value clashes with our
+ // namespace declarations.
+ var isCollision = false;
+ for (var uriKey in gAllowedXHTMLNamespaces) {
+ if (gAllowedXHTMLNamespaces[uriKey] == aPrefix)
+ isCollision = true;
+ }
+
+ if (isCollision) {
+ rolePrefix = aPrefix + i;
+ attributeValue =
+ rolePrefix + ":" +
+ attributeValue.substring(aPrefix.length + 1);
+ } else {
+ rolePrefix = aPrefix;
+ }
+
+ break;
+ }
+ }
+
+ if (rolePrefix)
+ this._buf += (" xmlns:" + rolePrefix +
+ "='" + WAIROLE_NS + "'");
+ }
+
+ // it's an allowed attribute NS.
+ // write the attribute
+ this._buf += (" " + prefix + ":" +
+ attributes.getLocalName(i) +
+ "='" + attributeValue + "'");
+
+ // write an xmlns declaration if necessary
+ if (prefix != "xml" && !this._isInScope(uri)) {
+ this._inScopeNS[this._inScopeNS.length - 1].push(uri);
+ this._buf += " xmlns:" + prefix + "='" + uri + "'";
+ }
+ }
+ }
+ }
+ this._buf += ">";
+ }
+ },
+ endElement: function XH_endElement(uri, localName, qName) {
+ --this._depth;
+ this._inScopeNS.pop();
+
+ // We need to skip outer divs in Atom. See comment in startElement.
+ if (this._isAtom && this._depth == 0 && localName == "div")
+ return;
+
+ // When we peek too far, go back to the main processor
+ if (this._depth < 0) {
+ this._processor.returnFromXHTMLHandler(trimString(this._buf),
+ uri, localName, qName);
+ return;
+ }
+ // If it's an XHTML element, record it. Otherwise, it's ignored.
+ if (uri == XHTML_NS) {
+ this._buf += "</" + localName + ">";
+ }
+ },
+ characters: function XH_characters(data) {
+ this._buf += xmlEscape(data);
+ },
+ startPrefixMapping: function XH_startPrefixMapping(prefix, uri) {
+ if (prefix && uri == WAIROLE_NS)
+ this._waiPrefixes[prefix] = WAIROLE_NS;
+ },
+ endPrefixMapping: function FP_endPrefixMapping(prefix) {
+ if (prefix)
+ delete this._waiPrefixes[prefix];
+ },
+ processingInstruction: function XH_processingInstruction() {
+ },
+}
+
+/**
+ * The ExtensionHandler deals with elements we haven't explicitly
+ * added to our transition table in the FeedProcessor.
+ */
+function ExtensionHandler(processor) {
+ this._buf = "";
+ this._depth = 0;
+ this._hasChildElements = false;
+
+ // The FeedProcessor
+ this._processor = processor;
+
+ // Fields of the outermost extension element.
+ this._localName = null;
+ this._uri = null;
+ this._qName = null;
+ this._attrs = null;
+}
+
+ExtensionHandler.prototype = {
+ startDocument: function EH_startDocument() {
+ },
+ endDocument: function EH_endDocument() {
+ },
+ startElement: function EH_startElement(uri, localName, qName, attrs) {
+ ++this._depth;
+ var prefix = gNamespaces[uri] ? gNamespaces[uri] + ":" : "";
+ var key = prefix + localName;
+
+ if (this._depth == 1) {
+ this._uri = uri;
+ this._localName = localName;
+ this._qName = qName;
+ this._attrs = attrs;
+ }
+
+ // if we descend into another element, we won't send text
+ this._hasChildElements = (this._depth > 1);
+
+ },
+ endElement: function EH_endElement(uri, localName, qName) {
+ --this._depth;
+ if (this._depth == 0) {
+ var text = this._hasChildElements ? null : trimString(this._buf);
+ this._processor.returnFromExtHandler(this._uri, this._localName,
+ text, this._attrs);
+ }
+ },
+ characters: function EH_characters(data) {
+ if (!this._hasChildElements)
+ this._buf += data;
+ },
+ startPrefixMapping: function EH_startPrefixMapping() {
+ },
+ endPrefixMapping: function EH_endPrefixMapping() {
+ },
+ processingInstruction: function EH_processingInstruction() {
+ },
+};
+
+
+/**
+ * ElementInfo is a simple container object that describes
+ * some characteristics of a feed element. For example, it
+ * says whether an element can be expected to appear more
+ * than once inside a given entry or feed.
+ */
+function ElementInfo(fieldName, containerClass, closeFunc, isArray) {
+ this.fieldName = fieldName;
+ this.containerClass = containerClass;
+ this.closeFunc = closeFunc;
+ this.isArray = isArray;
+ this.isWrapper = false;
+}
+
+/**
+ * FeedElementInfo represents a feed element, usually the root.
+ */
+function FeedElementInfo(fieldName, feedVersion) {
+ this.isWrapper = false;
+ this.fieldName = fieldName;
+ this.feedVersion = feedVersion;
+}
+
+/**
+ * Some feed formats include vestigial wrapper elements that we don't
+ * want to include in our object model, but we do need to keep track
+ * of during parsing.
+ */
+function WrapperElementInfo(fieldName) {
+ this.isWrapper = true;
+ this.fieldName = fieldName;
+}
+
+/***** The Processor *****/
+function FeedProcessor() {
+ this._reader = Cc[SAX_CONTRACTID].createInstance(Ci.nsISAXXMLReader);
+ this._buf = "";
+ this._feed = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+ this._handlerStack = [];
+ this._xmlBaseStack = []; // sparse array keyed to nesting depth
+ this._depth = 0;
+ this._state = "START";
+ this._result = null;
+ this._extensionHandler = null;
+ this._xhtmlHandler = null;
+ this._haveSentResult = false;
+
+ // http://www.w3.org/WAI/PF/GUI/ uses QNames in content :(
+ this._waiPrefixes = {};
+
+ // The nsIFeedResultListener waiting for the parse results
+ this.listener = null;
+
+ // These elements can contain (X)HTML or plain text.
+ // We keep a table here that contains their default treatment
+ this._textConstructs = {"atom:title":"text",
+ "atom:summary":"text",
+ "atom:rights":"text",
+ "atom:content":"text",
+ "atom:subtitle":"text",
+ "description":"html",
+ "rss1:description":"html",
+ "dc:description":"html",
+ "content:encoded":"html",
+ "title":"text",
+ "rss1:title":"text",
+ "atom03:title":"text",
+ "atom03:tagline":"text",
+ "atom03:summary":"text",
+ "atom03:content":"text"};
+ this._stack = [];
+
+ this._trans = {
+ "START": {
+ //If we hit a root RSS element, treat as RSS2.
+ "rss": new FeedElementInfo("RSS2", "rss2"),
+
+ // If we hit an RDF element, if could be RSS1, but we can't
+ // verify that until we hit a rss1:channel element.
+ "rdf:RDF": new WrapperElementInfo("RDF"),
+
+ // If we hit a Atom 1.0 element, treat as Atom 1.0.
+ "atom:feed": new FeedElementInfo("Atom", "atom"),
+
+ // Treat as Atom 0.3
+ "atom03:feed": new FeedElementInfo("Atom03", "atom03"),
+ },
+
+ /********* RSS2 **********/
+ "IN_RSS2": {
+ "channel": new WrapperElementInfo("channel")
+ },
+
+ "IN_CHANNEL": {
+ "item": new ElementInfo("items", Cc[ENTRY_CONTRACTID], null, true),
+ "managingEditor": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "category": new ElementInfo("categories", null, rssCatTerm, true),
+ "cloud": new ElementInfo("cloud", null, null, false),
+ "image": new ElementInfo("image", null, null, false),
+ "textInput": new ElementInfo("textInput", null, null, false),
+ "skipDays": new ElementInfo("skipDays", null, null, false),
+ "skipHours": new ElementInfo("skipHours", null, null, false),
+ "generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
+ atomGenerator, false),
+ },
+
+ "IN_ITEMS": {
+ "author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "category": new ElementInfo("categories", null, rssCatTerm, true),
+ "enclosure": new ElementInfo("enclosure", null, null, false),
+ "media:content": new ElementInfo("mediacontent", null, null, true),
+ "media:group": new ElementInfo("mediagroup", null, null, false),
+ "guid": new ElementInfo("guid", null, rssGuid, false)
+ },
+
+ "IN_SKIPDAYS": {
+ "day": new ElementInfo("days", null, rssArrayElement, true)
+ },
+
+ "IN_SKIPHOURS":{
+ "hour": new ElementInfo("hours", null, rssArrayElement, true)
+ },
+
+ "IN_MEDIAGROUP": {
+ "media:content": new ElementInfo("mediacontent", null, null, true)
+ },
+
+ /********* RSS1 **********/
+ "IN_RDF": {
+ // If we hit a rss1:channel, we can verify that we have RSS1
+ "rss1:channel": new FeedElementInfo("rdf_channel", "rss1"),
+ "rss1:image": new ElementInfo("image", null, null, false),
+ "rss1:textinput": new ElementInfo("textInput", null, null, false),
+ "rss1:item": new ElementInfo("items", Cc[ENTRY_CONTRACTID], null, true),
+ },
+
+ "IN_RDF_CHANNEL": {
+ "admin:generatorAgent": new ElementInfo("generator",
+ Cc[GENERATOR_CONTRACTID],
+ null, false),
+ "dc:creator": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "dc:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ "dc:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+ rssAuthor, true),
+ },
+
+ /********* ATOM 1.0 **********/
+ "IN_ATOM": {
+ "atom:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ null, true),
+ "atom:generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
+ atomGenerator, false),
+ "atom:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+ null, true),
+ "atom:link": new ElementInfo("links", null, null, true),
+ "atom:logo": new ElementInfo("atom:logo", null, atomLogo, false),
+ "atom:entry": new ElementInfo("entries", Cc[ENTRY_CONTRACTID],
+ null, true)
+ },
+
+ "IN_ENTRIES": {
+ "atom:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ null, true),
+ "atom:contributor": new ElementInfo("contributors", Cc[PERSON_CONTRACTID],
+ null, true),
+ "atom:link": new ElementInfo("links", null, null, true),
+ },
+
+ /********* ATOM 0.3 **********/
+ "IN_ATOM03": {
+ "atom03:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ null, true),
+ "atom03:contributor": new ElementInfo("contributors",
+ Cc[PERSON_CONTRACTID],
+ null, true),
+ "atom03:link": new ElementInfo("links", null, null, true),
+ "atom03:entry": new ElementInfo("atom03_entries", Cc[ENTRY_CONTRACTID],
+ null, true),
+ "atom03:generator": new ElementInfo("generator", Cc[GENERATOR_CONTRACTID],
+ atomGenerator, false),
+ },
+
+ "IN_ATOM03_ENTRIES": {
+ "atom03:author": new ElementInfo("authors", Cc[PERSON_CONTRACTID],
+ null, true),
+ "atom03:contributor": new ElementInfo("contributors",
+ Cc[PERSON_CONTRACTID],
+ null, true),
+ "atom03:link": new ElementInfo("links", null, null, true),
+ "atom03:entry": new ElementInfo("atom03_entries", Cc[ENTRY_CONTRACTID],
+ null, true)
+ }
+ }
+}
+
+// See startElement for a long description of how feeds are processed.
+FeedProcessor.prototype = {
+
+ // Set ourselves as the SAX handler, and set the base URI
+ _init: function FP_init(uri) {
+ this._reader.contentHandler = this;
+ this._reader.errorHandler = this;
+ this._result = Cc[FR_CONTRACTID].createInstance(Ci.nsIFeedResult);
+ if (uri) {
+ this._result.uri = uri;
+ this._reader.baseURI = uri;
+ this._xmlBaseStack[0] = uri;
+ }
+ },
+
+ // This function is called once we figure out what type of feed
+ // we're dealing with. Some feed types require digging a bit further
+ // than the root.
+ _docVerified: function FP_docVerified(version) {
+ this._result.doc = Cc[FEED_CONTRACTID].createInstance(Ci.nsIFeed);
+ this._result.doc.baseURI =
+ this._xmlBaseStack[this._xmlBaseStack.length - 1];
+ this._result.doc.fields = this._feed;
+ this._result.version = version;
+ },
+
+ // When we're done with the feed, let the listener know what
+ // happened.
+ _sendResult: function FP_sendResult() {
+ this._haveSentResult = true;
+ try {
+ // Can be null when a non-feed is fed to us
+ if (this._result.doc)
+ this._result.doc.normalize();
+ }
+ catch (e) {
+ LOG("FIXME: " + e);
+ }
+
+ try {
+ if (this.listener != null)
+ this.listener.handleResult(this._result);
+ }
+ finally {
+ this._result = null;
+ }
+ },
+
+ // Parsing functions
+ parseFromStream: function FP_parseFromStream(stream, uri) {
+ this._init(uri);
+ this._reader.parseFromStream(stream, null, stream.available(),
+ "application/xml");
+ this._reader = null;
+ },
+
+ parseFromString: function FP_parseFromString(inputString, uri) {
+ this._init(uri);
+ this._reader.parseFromString(inputString, "application/xml");
+ this._reader = null;
+ },
+
+ parseAsync: function FP_parseAsync(requestObserver, uri) {
+ this._init(uri);
+ this._reader.parseAsync(requestObserver);
+ },
+
+ // nsIStreamListener
+
+ // The XMLReader will throw sensible exceptions if these get called
+ // out of order.
+ onStartRequest: function FP_onStartRequest(request, context) {
+ // this will throw if the request is not a channel, but so will nsParser.
+ var channel = request.QueryInterface(Ci.nsIChannel);
+ channel.contentType = "application/vnd.mozilla.maybe.feed";
+ this._reader.onStartRequest(request, context);
+ },
+
+ onStopRequest: function FP_onStopRequest(request, context, statusCode) {
+ try {
+ this._reader.onStopRequest(request, context, statusCode);
+ }
+ finally {
+ this._reader = null;
+ }
+ },
+
+ onDataAvailable:
+ function FP_onDataAvailable(request, context, inputStream, offset, count) {
+ this._reader.onDataAvailable(request, context, inputStream, offset, count);
+ },
+
+ // nsISAXErrorHandler
+
+ // We only care about fatal errors. When this happens, we may have
+ // parsed through the feed metadata and some number of entries. The
+ // listener can still show some of that data if it wants, and we'll
+ // set the bozo bit to indicate we were unable to parse all the way
+ // through.
+ fatalError: function FP_reportError() {
+ this._result.bozo = true;
+ //XXX need to QI to FeedProgressListener
+ if (!this._haveSentResult)
+ this._sendResult();
+ },
+
+ // nsISAXContentHandler
+
+ startDocument: function FP_startDocument() {
+ //LOG("----------");
+ },
+
+ endDocument: function FP_endDocument() {
+ if (!this._haveSentResult)
+ this._sendResult();
+ },
+
+ // The transitions defined above identify elements that contain more
+ // than just text. For example RSS items contain many fields, and so
+ // do Atom authors. The only commonly used elements that contain
+ // mixed content are Atom Text Constructs of type="xhtml", which we
+ // delegate to another handler for cleaning. That leaves a couple
+ // different types of elements to deal with: those that should occur
+ // only once, such as title elements, and those that can occur
+ // multiple times, such as the RSS category element and the Atom
+ // link element. Most of the RSS1/DC elements can occur multiple
+ // times in theory, but in practice, the only ones that do have
+ // analogues in Atom.
+ //
+ // Some elements are also groups of attributes or sub-elements,
+ // while others are simple text fields. For the most part, we don't
+ // have to pay explicit attention to the simple text elements,
+ // unless we want to post-process the resulting string to transform
+ // it into some richer object like a Date or URI.
+ //
+ // Elements that have more sophisticated content models still end up
+ // being dictionaries, whether they are based on attributes like RSS
+ // cloud, sub-elements like Atom author, or even items and
+ // entries. These elements are treated as "containers". It's
+ // theoretically possible for a container to have an attribute with
+ // the same universal name as a sub-element, but none of the feed
+ // formats allow this by default, and I don't of any extension that
+ // works this way.
+ //
+ startElement: function FP_startElement(uri, localName, qName, attributes) {
+ this._buf = "";
+ ++this._depth;
+ var elementInfo;
+
+ //LOG("<" + localName + ">");
+
+ // Check for xml:base
+ var base = attributes.getValueFromName(XMLNS, "base");
+ if (base) {
+ this._xmlBaseStack[this._depth] =
+ strToURI(base, this._xmlBaseStack[this._xmlBaseStack.length - 1]);
+ }
+
+ // To identify the element we're dealing with, we look up the
+ // namespace URI in our gNamespaces dictionary, which will give us
+ // a "canonical" prefix for a namespace URI. For example, this
+ // allows Dublin Core "creator" elements to be consistently mapped
+ // to "dc:creator", for easy field access by consumer code. This
+ // strategy also happens to shorten up our state table.
+ var key = this._prefixForNS(uri) + localName;
+
+ // Check to see if we need to hand this off to our XHTML handler.
+ // The elements we're dealing with will look like this:
+ //
+ // <title type="xhtml">
+ // <div xmlns="http://www.w3.org/1999/xhtml">
+ // A title with <b>bold</b> and <i>italics</i>.
+ // </div>
+ // </title>
+ //
+ // When it returns in returnFromXHTMLHandler, the handler should
+ // give us back a string like this:
+ //
+ // "A title with <b>bold</b> and <i>italics</i>."
+ //
+ // The Atom spec explicitly says the div is not part of the content,
+ // and explicitly allows whitespace collapsing.
+ //
+ if ((this._result.version == "atom" || this._result.version == "atom03") &&
+ this._textConstructs[key] != null) {
+ var type = attributes.getValueFromName("","type");
+ if (type != null && type.indexOf("xhtml") >= 0) {
+ this._xhtmlHandler =
+ new XHTMLHandler(this, (this._result.version == "atom"),
+ this._waiPrefixes);
+ this._reader.contentHandler = this._xhtmlHandler;
+ return;
+ }
+ }
+
+ // Check our current state, and see if that state has a defined
+ // transition. For example, this._trans["atom:entry"]["atom:author"]
+ // will have one, and it tells us to add an item to our authors array.
+ if (this._trans[this._state] && this._trans[this._state][key]) {
+ elementInfo = this._trans[this._state][key];
+ }
+ else {
+ // If we don't have a transition, hand off to extension handler
+ this._extensionHandler = new ExtensionHandler(this);
+ this._reader.contentHandler = this._extensionHandler;
+ this._extensionHandler.startElement(uri, localName, qName, attributes);
+ return;
+ }
+
+ // This distinguishes wrappers like 'channel' from elements
+ // we'd actually like to do something with (which will test true).
+ this._handlerStack[this._depth] = elementInfo;
+ if (elementInfo.isWrapper) {
+ this._state = "IN_" + elementInfo.fieldName.toUpperCase();
+ this._stack.push([this._feed, this._state]);
+ }
+ else if (elementInfo.feedVersion) {
+ this._state = "IN_" + elementInfo.fieldName.toUpperCase();
+
+ // Check for the older RSS2 variants
+ if (elementInfo.feedVersion == "rss2")
+ elementInfo.feedVersion = this._findRSSVersion(attributes);
+ else if (uri == RSS090NS)
+ elementInfo.feedVersion = "rss090";
+
+ this._docVerified(elementInfo.feedVersion);
+ this._stack.push([this._feed, this._state]);
+ this._mapAttributes(this._feed, attributes);
+ }
+ else {
+ this._state = this._processComplexElement(elementInfo, attributes);
+ }
+ },
+
+ // In the endElement handler, we decrement the stack and look
+ // for cleanup/transition functions to execute. The second part
+ // of the state transition works as above in startElement, but
+ // the state we're looking for is prefixed with an underscore
+ // to distinguish endElement events from startElement events.
+ endElement: function FP_endElement(uri, localName, qName) {
+ var elementInfo = this._handlerStack[this._depth];
+ //LOG("</" + localName + ">");
+ if (elementInfo && !elementInfo.isWrapper)
+ this._closeComplexElement(elementInfo);
+
+ // cut down xml:base context
+ if (this._xmlBaseStack.length == this._depth + 1)
+ this._xmlBaseStack = this._xmlBaseStack.slice(0, this._depth);
+
+ // our new state is whatever is at the top of the stack now
+ if (this._stack.length > 0)
+ this._state = this._stack[this._stack.length - 1][1];
+ this._handlerStack = this._handlerStack.slice(0, this._depth);
+ --this._depth;
+ },
+
+ // Buffer up character data. The buffer is cleared with every
+ // opening element.
+ characters: function FP_characters(data) {
+ this._buf += data;
+ },
+ // TODO: It would be nice to check new prefixes here, and if they
+ // don't conflict with the ones we've defined, throw them in a
+ // dictionary to check.
+ startPrefixMapping: function FP_startPrefixMapping(prefix, uri) {
+ // Thanks for QNames in content, W3C
+ // This will even be a perf hit for every single feed
+ // http://www.w3.org/WAI/PF/GUI/
+ if (prefix && uri == WAIROLE_NS)
+ this._waiPrefixes[prefix] = WAIROLE_NS;
+ },
+
+ endPrefixMapping: function FP_endPrefixMapping(prefix) {
+ if (prefix)
+ delete this._waiPrefixes[prefix];
+ },
+
+ processingInstruction: function FP_processingInstruction(target, data) {
+ if (target == "xml-stylesheet") {
+ var hrefAttribute = data.match(/href=[\"\'](.*?)[\"\']/);
+ if (hrefAttribute && hrefAttribute.length == 2)
+ this._result.stylesheet = strToURI(hrefAttribute[1], this._result.uri);
+ }
+ },
+
+ // end of nsISAXContentHandler
+
+ // Handle our more complicated elements--those that contain
+ // attributes and child elements.
+ _processComplexElement:
+ function FP__processComplexElement(elementInfo, attributes) {
+ var obj, key, prefix;
+
+ // If the container is an entry/item, it'll need to have its
+ // more esoteric properties put in the 'fields' property bag.
+ if (elementInfo.containerClass == Cc[ENTRY_CONTRACTID]) {
+ obj = elementInfo.containerClass.createInstance(Ci.nsIFeedEntry);
+ obj.baseURI = this._xmlBaseStack[this._xmlBaseStack.length - 1];
+ this._mapAttributes(obj.fields, attributes);
+ }
+ else if (elementInfo.containerClass) {
+ obj = elementInfo.containerClass.createInstance(Ci.nsIFeedElementBase);
+ obj.baseURI = this._xmlBaseStack[this._xmlBaseStack.length - 1];
+ obj.attributes = attributes; // just set the SAX attributes
+ }
+ else {
+ obj = Cc[BAG_CONTRACTID].createInstance(Ci.nsIWritablePropertyBag2);
+ this._mapAttributes(obj, attributes);
+ }
+
+ // We should have a container/propertyBag that's had its
+ // attributes processed. Now we need to attach it to its
+ // container.
+ var newProp;
+
+ // First we'll see what's on top of the stack.
+ var container = this._stack[this._stack.length - 1][0];
+
+ // Check to see if it has the property
+ var prop;
+ try {
+ prop = container.getProperty(elementInfo.fieldName);
+ }
+ catch(e) {
+ }
+
+ if (elementInfo.isArray) {
+ if (!prop) {
+ container.setPropertyAsInterface(elementInfo.fieldName,
+ Cc[ARRAY_CONTRACTID].
+ createInstance(Ci.nsIMutableArray));
+ }
+
+ newProp = container.getProperty(elementInfo.fieldName);
+ // XXX This QI should not be necessary, but XPConnect seems to fly
+ // off the handle in the browser, and loses track of the interface
+ // on large files. Bug 335638.
+ newProp.QueryInterface(Ci.nsIMutableArray);
+ newProp.appendElement(obj,false);
+
+ // If new object is an nsIFeedContainer, we want to deal with
+ // its member nsIPropertyBag instead.
+ if (isIFeedContainer(obj))
+ newProp = obj.fields;
+
+ }
+ else {
+ // If it doesn't, set it.
+ if (!prop) {
+ container.setPropertyAsInterface(elementInfo.fieldName,obj);
+ }
+ newProp = container.getProperty(elementInfo.fieldName);
+ }
+
+ // make our new state name, and push the property onto the stack
+ var newState = "IN_" + elementInfo.fieldName.toUpperCase();
+ this._stack.push([newProp, newState, obj]);
+ return newState;
+ },
+
+ // Sometimes we need reconcile the element content with the object
+ // model for a given feed. We use helper functions to do the
+ // munging, but we need to identify array types here, so the munging
+ // happens only to the last element of an array.
+ _closeComplexElement: function FP__closeComplexElement(elementInfo) {
+ var stateTuple = this._stack.pop();
+ var container = stateTuple[0];
+ var containerParent = stateTuple[2];
+ var element = null;
+ var isArray = isIArray(container);
+
+ // If it's an array and we have to post-process,
+ // grab the last element
+ if (isArray)
+ element = container.queryElementAt(container.length - 1, Ci.nsISupports);
+ else
+ element = container;
+
+ // Run the post-processing function if there is one.
+ if (elementInfo.closeFunc)
+ element = elementInfo.closeFunc(this._buf, element);
+
+ // If an nsIFeedContainer was on top of the stack,
+ // we need to normalize it
+ if (elementInfo.containerClass == Cc[ENTRY_CONTRACTID])
+ containerParent.normalize();
+
+ // If it's an array, re-set the last element
+ if (isArray)
+ container.replaceElementAt(element, container.length - 1, false);
+ },
+
+ _prefixForNS: function FP_prefixForNS(uri) {
+ if (!uri)
+ return "";
+ var prefix = gNamespaces[uri];
+ if (prefix)
+ return prefix + ":";
+ if (uri.toLowerCase().indexOf("http://backend.userland.com") == 0)
+ return "";
+ else
+ return null;
+ },
+
+ _mapAttributes: function FP__mapAttributes(bag, attributes) {
+ // Cycle through the attributes, and set our properties using the
+ // prefix:localNames we find in our namespace dictionary.
+ for (var i = 0; i < attributes.length; ++i) {
+ var key = this._prefixForNS(attributes.getURI(i)) + attributes.getLocalName(i);
+ var val = attributes.getValue(i);
+ bag.setPropertyAsAString(key, val);
+ }
+ },
+
+ // Only for RSS2esque formats
+ _findRSSVersion: function FP__findRSSVersion(attributes) {
+ var versionAttr = trimString(attributes.getValueFromName("", "version"));
+ var versions = { "0.91":"rss091",
+ "0.92":"rss092",
+ "0.93":"rss093",
+ "0.94":"rss094" }
+ if (versions[versionAttr])
+ return versions[versionAttr];
+ if (versionAttr.substr(0,2) != "2.")
+ return "rssUnknown";
+ return "rss2";
+ },
+
+ // unknown element values are returned here. See startElement above
+ // for how this works.
+ returnFromExtHandler:
+ function FP_returnExt(uri, localName, chars, attributes) {
+ --this._depth;
+
+ // take control of the SAX events
+ this._reader.contentHandler = this;
+ if (localName == null && chars == null)
+ return;
+
+ // we don't take random elements inside rdf:RDF
+ if (this._state == "IN_RDF")
+ return;
+
+ // Grab the top of the stack
+ var top = this._stack[this._stack.length - 1];
+ if (!top)
+ return;
+
+ var container = top[0];
+ // Grab the last element if it's an array
+ if (isIArray(container)) {
+ var contract = this._handlerStack[this._depth].containerClass;
+ // check if it's something specific, but not an entry
+ if (contract && contract != Cc[ENTRY_CONTRACTID]) {
+ var el = container.queryElementAt(container.length - 1,
+ Ci.nsIFeedElementBase);
+ // XXX there must be a way to flatten these interfaces
+ if (contract == Cc[PERSON_CONTRACTID])
+ el.QueryInterface(Ci.nsIFeedPerson);
+ else
+ return; // don't know about this interface
+
+ var propName = localName;
+ var prefix = gNamespaces[uri];
+
+ // synonyms
+ if ((uri == "" ||
+ prefix &&
+ ((prefix.indexOf("atom") > -1) ||
+ (prefix.indexOf("rss") > -1))) &&
+ (propName == "url" || propName == "href"))
+ propName = "uri";
+
+ try {
+ if (el[propName] !== "undefined") {
+ var propValue = chars;
+ // convert URI-bearing values to an nsIURI
+ if (propName == "uri") {
+ var base = this._xmlBaseStack[this._xmlBaseStack.length - 1];
+ propValue = strToURI(chars, base);
+ }
+ el[propName] = propValue;
+ }
+ }
+ catch(e) {
+ // ignore XPConnect errors
+ }
+ // the rest of the function deals with entry- and feed-level stuff
+ return;
+ }
+ else {
+ container = container.queryElementAt(container.length - 1,
+ Ci.nsIWritablePropertyBag2);
+ }
+ }
+
+ // Make the buffer our new property
+ var propName = this._prefixForNS(uri) + localName;
+
+ // But, it could be something containing HTML. If so,
+ // we need to know about that.
+ if (this._textConstructs[propName] != null &&
+ this._handlerStack[this._depth].containerClass !== null) {
+ var newProp = Cc[TEXTCONSTRUCT_CONTRACTID].
+ createInstance(Ci.nsIFeedTextConstruct);
+ newProp.text = chars;
+ // Look up the default type in our table
+ var type = this._textConstructs[propName];
+ var typeAttribute = attributes.getValueFromName("","type");
+ if (this._result.version == "atom" && typeAttribute != null) {
+ type = typeAttribute;
+ }
+ else if (this._result.version == "atom03" && typeAttribute != null) {
+ if (typeAttribute.toLowerCase().indexOf("xhtml") >= 0) {
+ type = "xhtml";
+ }
+ else if (typeAttribute.toLowerCase().indexOf("html") >= 0) {
+ type = "html";
+ }
+ else if (typeAttribute.toLowerCase().indexOf("text") >= 0) {
+ type = "text";
+ }
+ }
+
+ // If it's rss feed-level description, it's not supposed to have html
+ if (this._result.version.indexOf("rss") >= 0 &&
+ this._handlerStack[this._depth].containerClass != ENTRY_CONTRACTID) {
+ type = "text";
+ }
+ newProp.type = type;
+ newProp.base = this._xmlBaseStack[this._xmlBaseStack.length - 1];
+ container.setPropertyAsInterface(propName, newProp);
+ }
+ else {
+ container.setPropertyAsAString(propName, chars);
+ }
+ },
+
+ // Sometimes, we'll hand off SAX handling duties to an XHTMLHandler
+ // (see above) that will scrape out non-XHTML stuff, normalize
+ // namespaces, and remove the wrapper div from Atom 1.0. When the
+ // XHTMLHandler is done, it'll callback here.
+ returnFromXHTMLHandler:
+ function FP_returnFromXHTMLHandler(chars, uri, localName, qName) {
+ // retake control of the SAX content events
+ this._reader.contentHandler = this;
+
+ // Grab the top of the stack
+ var top = this._stack[this._stack.length - 1];
+ if (!top)
+ return;
+ var container = top[0];
+
+ // Assign the property
+ var newProp = newProp = Cc[TEXTCONSTRUCT_CONTRACTID].
+ createInstance(Ci.nsIFeedTextConstruct);
+ newProp.text = chars;
+ newProp.type = "xhtml";
+ newProp.base = this._xmlBaseStack[this._xmlBaseStack.length - 1];
+ container.setPropertyAsInterface(this._prefixForNS(uri) + localName,
+ newProp);
+
+ // XHTML will cause us to peek too far. The XHTML handler will
+ // send us an end element to call. RFC4287-valid feeds allow a
+ // more graceful way to handle this. Unfortunately, we can't count
+ // on compliance at this point.
+ this.endElement(uri, localName, qName);
+ },
+
+ // XPCOM stuff
+ classDescription: FP_CLASSNAME,
+ classID: FP_CLASSID,
+ contractID: FP_CONTRACTID,
+ QueryInterface: XPCOMUtils.generateQI(
+ [Ci.nsIFeedProcessor, Ci.nsISAXContentHandler, Ci.nsISAXErrorHandler,
+ Ci.nsIStreamListener, Ci.nsIRequestObserver]
+ )
+}
+
+var components = [FeedProcessor, FeedResult, Feed, Entry,
+ TextConstruct, Generator, Person];
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(components);
+
+}
diff --git a/bundles/XO/components/FeedWriter.js b/bundles/XO/components/FeedWriter.js
new file mode 100755
index 0000000..ae10bef
--- /dev/null
+++ b/bundles/XO/components/FeedWriter.js
@@ -0,0 +1,1387 @@
+//@line 42 "/builds/moz2_slave/linux_build/build/browser/components/feeds/src/FeedWriter.js"
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function LOG(str) {
+ var prefB = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+
+ var shouldLog = false;
+ try {
+ shouldLog = prefB.getBoolPref("feeds.log");
+ }
+ catch (ex) {
+ }
+
+ if (shouldLog)
+ dump("*** Feeds: " + str + "\n");
+}
+
+/**
+ * Wrapper function for nsIIOService::newURI.
+ * @param aURLSpec
+ * The URL string from which to create an nsIURI.
+ * @returns an nsIURI object, or null if the creation of the URI failed.
+ */
+function makeURI(aURLSpec, aCharset) {
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ try {
+ return ios.newURI(aURLSpec, aCharset, null);
+ } catch (ex) { }
+
+ return null;
+}
+
+const XML_NS = "http://www.w3.org/XML/1998/namespace"
+const HTML_NS = "http://www.w3.org/1999/xhtml";
+const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
+const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
+const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
+const URI_BUNDLE = "chrome://browser/locale/feeds/subscribe.properties";
+const SUBSCRIBE_PAGE_URI = "chrome://browser/content/feeds/subscribe.xhtml";
+
+const PREF_SELECTED_APP = "browser.feeds.handlers.application";
+const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
+const PREF_SELECTED_ACTION = "browser.feeds.handler";
+const PREF_SELECTED_READER = "browser.feeds.handler.default";
+
+const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
+const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
+const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
+const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
+
+const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
+const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
+const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
+const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
+
+const PREF_SHOW_FIRST_RUN_UI = "browser.feeds.showFirstRunUI";
+
+const TITLE_ID = "feedTitleText";
+const SUBTITLE_ID = "feedSubtitleText";
+
+function getPrefAppForType(t) {
+ switch (t) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return PREF_VIDEO_SELECTED_APP;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return PREF_AUDIO_SELECTED_APP;
+
+ default:
+ return PREF_SELECTED_APP;
+ }
+}
+
+function getPrefWebForType(t) {
+ switch (t) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return PREF_VIDEO_SELECTED_WEB;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return PREF_AUDIO_SELECTED_WEB;
+
+ default:
+ return PREF_SELECTED_WEB;
+ }
+}
+
+function getPrefActionForType(t) {
+ switch (t) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return PREF_VIDEO_SELECTED_ACTION;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return PREF_AUDIO_SELECTED_ACTION;
+
+ default:
+ return PREF_SELECTED_ACTION;
+ }
+}
+
+function getPrefReaderForType(t) {
+ switch (t) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return PREF_VIDEO_SELECTED_READER;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return PREF_AUDIO_SELECTED_READER;
+
+ default:
+ return PREF_SELECTED_READER;
+ }
+}
+
+/**
+ * Converts a number of bytes to the appropriate unit that results in a
+ * number that needs fewer than 4 digits
+ *
+ * @return a pair: [new value with 3 sig. figs., its unit]
+ */
+function convertByteUnits(aBytes) {
+ var units = ["bytes", "kilobyte", "megabyte", "gigabyte"];
+ let unitIndex = 0;
+
+ // convert to next unit if it needs 4 digits (after rounding), but only if
+ // we know the name of the next unit
+ while ((aBytes >= 999.5) && (unitIndex < units.length - 1)) {
+ aBytes /= 1024;
+ unitIndex++;
+ }
+
+ // Get rid of insignificant bits by truncating to 1 or 0 decimal points
+ // 0 -> 0; 1.2 -> 1.2; 12.3 -> 12.3; 123.4 -> 123; 234.5 -> 235
+ aBytes = aBytes.toFixed((aBytes > 0) && (aBytes < 100) ? 1 : 0);
+
+ return [aBytes, units[unitIndex]];
+}
+
+function FeedWriter() {}
+FeedWriter.prototype = {
+ _mimeSvc : Cc["@mozilla.org/mime;1"].
+ getService(Ci.nsIMIMEService),
+
+ _getPropertyAsBag: function FW__getPropertyAsBag(container, property) {
+ return container.fields.getProperty(property).
+ QueryInterface(Ci.nsIPropertyBag2);
+ },
+
+ _getPropertyAsString: function FW__getPropertyAsString(container, property) {
+ try {
+ return container.fields.getPropertyAsAString(property);
+ }
+ catch (e) {
+ }
+ return "";
+ },
+
+ _setContentText: function FW__setContentText(id, text) {
+ this._contentSandbox.element = this._document.getElementById(id);
+ this._contentSandbox.textNode = this._document.createTextNode(text);
+ var codeStr =
+ "while (element.hasChildNodes()) " +
+ " element.removeChild(element.firstChild);" +
+ "element.appendChild(textNode);";
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ this._contentSandbox.element = null;
+ this._contentSandbox.textNode = null;
+ },
+
+ /**
+ * Safely sets the href attribute on an anchor tag, providing the URI
+ * specified can be loaded according to rules.
+ * @param element
+ * The element to set a URI attribute on
+ * @param attribute
+ * The attribute of the element to set the URI to, e.g. href or src
+ * @param uri
+ * The URI spec to set as the href
+ */
+ _safeSetURIAttribute:
+ function FW__safeSetURIAttribute(element, attribute, uri) {
+ var secman = Cc["@mozilla.org/scriptsecuritymanager;1"].
+ getService(Ci.nsIScriptSecurityManager);
+ const flags = Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL;
+ try {
+ secman.checkLoadURIStrWithPrincipal(this._feedPrincipal, uri, flags);
+ // checkLoadURIStrWithPrincipal will throw if the link URI should not be
+ // loaded, either because our feedURI isn't allowed to load it or per
+ // the rules specified in |flags|, so we'll never "linkify" the link...
+ }
+ catch (e) {
+ // Not allowed to load this link because secman.checkLoadURIStr threw
+ return;
+ }
+
+ this._contentSandbox.element = element;
+ this._contentSandbox.uri = uri;
+ var codeStr = "element.setAttribute('" + attribute + "', uri);";
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ },
+
+ /**
+ * Use this sandbox to run any dom manipulation code on nodes which
+ * are already inserted into the content document.
+ */
+ __contentSandbox: null,
+ get _contentSandbox() {
+ if (!this.__contentSandbox)
+ this.__contentSandbox = new Cu.Sandbox(this._window);
+
+ return this.__contentSandbox;
+ },
+
+ /**
+ * Calls doCommand for a the given XUL element within the context of the
+ * content document.
+ *
+ * @param aElement
+ * the XUL element to call doCommand() on.
+ */
+ _safeDoCommand: function FW___safeDoCommand(aElement) {
+ this._contentSandbox.element = aElement;
+ Cu.evalInSandbox("element.doCommand();", this._contentSandbox);
+ this._contentSandbox.element = null;
+ },
+
+ __faviconService: null,
+ get _faviconService() {
+ if (!this.__faviconService)
+ this.__faviconService = Cc["@mozilla.org/browser/favicon-service;1"].
+ getService(Ci.nsIFaviconService);
+
+ return this.__faviconService;
+ },
+
+ __bundle: null,
+ get _bundle() {
+ if (!this.__bundle) {
+ this.__bundle = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).
+ createBundle(URI_BUNDLE);
+ }
+ return this.__bundle;
+ },
+
+ _getFormattedString: function FW__getFormattedString(key, params) {
+ return this._bundle.formatStringFromName(key, params, params.length);
+ },
+
+ _getString: function FW__getString(key) {
+ return this._bundle.GetStringFromName(key);
+ },
+
+ /* Magic helper methods to be used instead of xbl properties */
+ _getSelectedItemFromMenulist: function FW__getSelectedItemFromList(aList) {
+ var node = aList.firstChild.firstChild;
+ while (node) {
+ if (node.localName == "menuitem" && node.getAttribute("selected") == "true")
+ return node;
+
+ node = node.nextSibling;
+ }
+
+ return null;
+ },
+
+ _setCheckboxCheckedState: function FW__setCheckboxCheckedState(aCheckbox, aValue) {
+ // see checkbox.xml, xbl bindings are not applied within the sandbox!
+ this._contentSandbox.checkbox = aCheckbox;
+ var codeStr;
+ var change = (aValue != (aCheckbox.getAttribute('checked') == 'true'));
+ if (aValue)
+ codeStr = "checkbox.setAttribute('checked', 'true'); ";
+ else
+ codeStr = "checkbox.removeAttribute('checked'); ";
+
+ if (change) {
+ this._contentSandbox.document = this._document;
+ codeStr += "var event = document.createEvent('Events'); " +
+ "event.initEvent('CheckboxStateChange', true, true);" +
+ "checkbox.dispatchEvent(event);"
+ }
+
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ },
+
+ /**
+ * Returns a date suitable for displaying in the feed preview.
+ * If the date cannot be parsed, the return value is "false".
+ * @param dateString
+ * A date as extracted from a feed entry. (entry.updated)
+ */
+ _parseDate: function FW__parseDate(dateString) {
+ // Convert the date into the user's local time zone
+ dateObj = new Date(dateString);
+
+ // Make sure the date we're given is valid.
+ if (!dateObj.getTime())
+ return false;
+
+ var dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
+ getService(Ci.nsIScriptableDateFormat);
+ return dateService.FormatDateTime("", dateService.dateFormatLong, dateService.timeFormatNoSeconds,
+ dateObj.getFullYear(), dateObj.getMonth()+1, dateObj.getDate(),
+ dateObj.getHours(), dateObj.getMinutes(), dateObj.getSeconds());
+ },
+
+ /**
+ * Returns the feed type.
+ */
+ __feedType: null,
+ _getFeedType: function FW__getFeedType() {
+ if (this.__feedType != null)
+ return this.__feedType;
+
+ try {
+ // grab the feed because it's got the feed.type in it.
+ var container = this._getContainer();
+ var feed = container.QueryInterface(Ci.nsIFeed);
+ this.__feedType = feed.type;
+ return feed.type;
+ } catch (ex) { }
+
+ return Ci.nsIFeed.TYPE_FEED;
+ },
+
+ /**
+ * Maps a feed type to a maybe-feed mimetype.
+ */
+ _getMimeTypeForFeedType: function FW__getMimeTypeForFeedType() {
+ switch (this._getFeedType()) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ return TYPE_MAYBE_VIDEO_FEED;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ return TYPE_MAYBE_AUDIO_FEED;
+
+ default:
+ return TYPE_MAYBE_FEED;
+ }
+ },
+
+ /**
+ * Writes the feed title into the preview document.
+ * @param container
+ * The feed container
+ */
+ _setTitleText: function FW__setTitleText(container) {
+ if (container.title) {
+ var title = container.title.plainText();
+ this._setContentText(TITLE_ID, title);
+ this._contentSandbox.document = this._document;
+ this._contentSandbox.title = title;
+ var codeStr = "document.title = title;"
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ }
+
+ var feed = container.QueryInterface(Ci.nsIFeed);
+ if (feed && feed.subtitle)
+ this._setContentText(SUBTITLE_ID, container.subtitle.plainText());
+ },
+
+ /**
+ * Writes the title image into the preview document if one is present.
+ * @param container
+ * The feed container
+ */
+ _setTitleImage: function FW__setTitleImage(container) {
+ try {
+ var parts = container.image;
+
+ // Set up the title image (supplied by the feed)
+ var feedTitleImage = this._document.getElementById("feedTitleImage");
+ this._safeSetURIAttribute(feedTitleImage, "src",
+ parts.getPropertyAsAString("url"));
+
+ // Set up the title image link
+ var feedTitleLink = this._document.getElementById("feedTitleLink");
+
+ var titleText = this._getFormattedString("linkTitleTextFormat",
+ [parts.getPropertyAsAString("title")]);
+ this._contentSandbox.feedTitleLink = feedTitleLink;
+ this._contentSandbox.titleText = titleText;
+ this._contentSandbox.feedTitleText = this._document.getElementById("feedTitleText");
+ this._contentSandbox.titleImageWidth = parseInt(parts.getPropertyAsAString("width")) + 15;
+
+ // Fix the margin on the main title, so that the image doesn't run over
+ // the underline
+ var codeStr = "feedTitleLink.setAttribute('title', titleText); " +
+ "feedTitleText.style.marginRight = titleImageWidth + 'px';";
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ this._contentSandbox.feedTitleLink = null;
+ this._contentSandbox.titleText = null;
+ this._contentSandbox.feedTitleText = null;
+ this._contentSandbox.titleImageWidth = null;
+
+ this._safeSetURIAttribute(feedTitleLink, "href",
+ parts.getPropertyAsAString("link"));
+ }
+ catch (e) {
+ LOG("Failed to set Title Image (this is benign): " + e);
+ }
+ },
+
+ /**
+ * Writes all entries contained in the feed.
+ * @param container
+ * The container of entries in the feed
+ */
+ _writeFeedContent: function FW__writeFeedContent(container) {
+ // Build the actual feed content
+ var feed = container.QueryInterface(Ci.nsIFeed);
+ if (feed.items.length == 0)
+ return;
+
+ this._contentSandbox.feedContent =
+ this._document.getElementById("feedContent");
+
+ for (var i = 0; i < feed.items.length; ++i) {
+ var entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
+ entry.QueryInterface(Ci.nsIFeedContainer);
+
+ var entryContainer = this._document.createElementNS(HTML_NS, "div");
+ entryContainer.className = "entry";
+
+ // If the entry has a title, make it a link
+ if (entry.title) {
+ var a = this._document.createElementNS(HTML_NS, "a");
+ a.appendChild(this._document.createTextNode(entry.title.plainText()));
+
+ // Entries are not required to have links, so entry.link can be null.
+ if (entry.link)
+ this._safeSetURIAttribute(a, "href", entry.link.spec);
+
+ var title = this._document.createElementNS(HTML_NS, "h3");
+ title.appendChild(a);
+
+ var lastUpdated = this._parseDate(entry.updated);
+ if (lastUpdated) {
+ var dateDiv = this._document.createElementNS(HTML_NS, "div");
+ dateDiv.className = "lastUpdated";
+ dateDiv.textContent = lastUpdated;
+ title.appendChild(dateDiv);
+ }
+
+ entryContainer.appendChild(title);
+ }
+
+ var body = this._document.createElementNS(HTML_NS, "div");
+ var summary = entry.summary || entry.content;
+ var docFragment = null;
+ if (summary) {
+ if (summary.base)
+ body.setAttributeNS(XML_NS, "base", summary.base.spec);
+ else
+ LOG("no base?");
+ docFragment = summary.createDocumentFragment(body);
+ if (docFragment)
+ body.appendChild(docFragment);
+
+ // If the entry doesn't have a title, append a # permalink
+ // See http://scripting.com/rss.xml for an example
+ if (!entry.title && entry.link) {
+ var a = this._document.createElementNS(HTML_NS, "a");
+ a.appendChild(this._document.createTextNode("#"));
+ this._safeSetURIAttribute(a, "href", entry.link.spec);
+ body.appendChild(this._document.createTextNode(" "));
+ body.appendChild(a);
+ }
+
+ }
+ body.className = "feedEntryContent";
+ entryContainer.appendChild(body);
+
+ if (entry.enclosures && entry.enclosures.length > 0) {
+ var enclosuresDiv = this._buildEnclosureDiv(entry);
+ entryContainer.appendChild(enclosuresDiv);
+ }
+
+ this._contentSandbox.entryContainer = entryContainer;
+ this._contentSandbox.clearDiv =
+ this._document.createElementNS(HTML_NS, "div");
+ this._contentSandbox.clearDiv.style.clear = "both";
+
+ var codeStr = "feedContent.appendChild(entryContainer); " +
+ "feedContent.appendChild(clearDiv);"
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ }
+
+ this._contentSandbox.feedContent = null;
+ this._contentSandbox.entryContainer = null;
+ this._contentSandbox.clearDiv = null;
+ },
+
+ /**
+ * Takes a url to a media item and returns the best name it can come up with.
+ * Frequently this is the filename portion (e.g. passing in
+ * http://example.com/foo.mpeg would return "foo.mpeg"), but in more complex
+ * cases, this will return the entire url (e.g. passing in
+ * http://example.com/somedirectory/ would return
+ * http://example.com/somedirectory/).
+ * @param aURL
+ * The URL string from which to create a display name
+ * @returns a string
+ */
+ _getURLDisplayName: function FW__getURLDisplayName(aURL) {
+ var url = makeURI(aURL);
+ url.QueryInterface(Ci.nsIURL);
+ if (url == null || url.fileName.length == 0)
+ return aURL;
+
+ return decodeURI(url.fileName);
+ },
+
+ /**
+ * Takes a FeedEntry with enclosures, generates the HTML code to represent
+ * them, and returns that.
+ * @param entry
+ * FeedEntry with enclosures
+ * @returns element
+ */
+ _buildEnclosureDiv: function FW__buildEnclosureDiv(entry) {
+ var enclosuresDiv = this._document.createElementNS(HTML_NS, "div");
+ enclosuresDiv.className = "enclosures";
+
+ enclosuresDiv.appendChild(this._document.createTextNode(this._getString("mediaLabel")));
+
+ var roundme = function(n) {
+ return (Math.round(n * 100) / 100).toLocaleString();
+ }
+
+ for (var i_enc = 0; i_enc < entry.enclosures.length; ++i_enc) {
+ var enc = entry.enclosures.queryElementAt(i_enc, Ci.nsIWritablePropertyBag2);
+
+ if (!(enc.hasKey("url")))
+ continue;
+
+ var enclosureDiv = this._document.createElementNS(HTML_NS, "div");
+ enclosureDiv.setAttribute("class", "enclosure");
+
+ var mozicon = "moz-icon://.txt?size=16";
+ var type_text = null;
+ var size_text = null;
+
+ if (enc.hasKey("type")) {
+ type_text = enc.get("type");
+ try {
+ var handlerInfoWrapper = this._mimeSvc.getFromTypeAndExtension(enc.get("type"), null);
+
+ if (handlerInfoWrapper)
+ type_text = handlerInfoWrapper.description;
+
+ if (type_text && type_text.length > 0)
+ mozicon = "moz-icon://goat?size=16&contentType=" + enc.get("type");
+
+ } catch (ex) { }
+
+ }
+
+ if (enc.hasKey("length") && /^[0-9]+$/.test(enc.get("length"))) {
+ var enc_size = convertByteUnits(parseInt(enc.get("length")));
+
+ var size_text = this._getFormattedString("enclosureSizeText",
+ [enc_size[0], this._getString(enc_size[1])]);
+ }
+
+ var iconimg = this._document.createElementNS(HTML_NS, "img");
+ iconimg.setAttribute("src", mozicon);
+ iconimg.setAttribute("class", "type-icon");
+ enclosureDiv.appendChild(iconimg);
+
+ enclosureDiv.appendChild(this._document.createTextNode( " " ));
+
+ var enc_href = this._document.createElementNS(HTML_NS, "a");
+ enc_href.appendChild(this._document.createTextNode(this._getURLDisplayName(enc.get("url"))));
+ this._safeSetURIAttribute(enc_href, "href", enc.get("url"));
+ enclosureDiv.appendChild(enc_href);
+
+ if (type_text && size_text)
+ enclosureDiv.appendChild(this._document.createTextNode( " (" + type_text + ", " + size_text + ")"));
+
+ else if (type_text)
+ enclosureDiv.appendChild(this._document.createTextNode( " (" + type_text + ")"))
+
+ else if (size_text)
+ enclosureDiv.appendChild(this._document.createTextNode( " (" + size_text + ")"))
+
+ enclosuresDiv.appendChild(enclosureDiv);
+ }
+
+ return enclosuresDiv;
+ },
+
+ /**
+ * Gets a valid nsIFeedContainer object from the parsed nsIFeedResult.
+ * Displays error information if there was one.
+ * @param result
+ * The parsed feed result
+ * @returns A valid nsIFeedContainer object containing the contents of
+ * the feed.
+ */
+ _getContainer: function FW__getContainer(result) {
+ var feedService =
+ Cc["@mozilla.org/browser/feeds/result-service;1"].
+ getService(Ci.nsIFeedResultService);
+
+ try {
+ var result =
+ feedService.getFeedResult(this._getOriginalURI(this._window));
+ }
+ catch (e) {
+ LOG("Subscribe Preview: feed not available?!");
+ }
+
+ if (result.bozo) {
+ LOG("Subscribe Preview: feed result is bozo?!");
+ }
+
+ try {
+ var container = result.doc;
+ }
+ catch (e) {
+ LOG("Subscribe Preview: no result.doc? Why didn't the original reload?");
+ return null;
+ }
+ return container;
+ },
+
+ /**
+ * Get the human-readable display name of a file. This could be the
+ * application name.
+ * @param file
+ * A nsIFile to look up the name of
+ * @returns The display name of the application represented by the file.
+ */
+ _getFileDisplayName: function FW__getFileDisplayName(file) {
+//@line 702 "/builds/moz2_slave/linux_build/build/browser/components/feeds/src/FeedWriter.js"
+ var ios =
+ Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var url = ios.newFileURI(file).QueryInterface(Ci.nsIURL);
+ return url.fileName;
+ },
+
+ /**
+ * Get moz-icon url for a file
+ * @param file
+ * A nsIFile object for which the moz-icon:// is returned
+ * @returns moz-icon url of the given file as a string
+ */
+ _getFileIconURL: function FW__getFileIconURL(file) {
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Components.interfaces.nsIIOService);
+ var fph = ios.getProtocolHandler("file")
+ .QueryInterface(Ci.nsIFileProtocolHandler);
+ var urlSpec = fph.getURLSpecFromFile(file);
+ return "moz-icon://" + urlSpec + "?size=16";
+ },
+
+ /**
+ * Helper method to set the selected application and system default
+ * reader menuitems details from a file object
+ * @param aMenuItem
+ * The menuitem on which the attributes should be set
+ * @param aFile
+ * The menuitem's associated file
+ */
+ _initMenuItemWithFile: function(aMenuItem, aFile) {
+ this._contentSandbox.menuitem = aMenuItem;
+ this._contentSandbox.label = this._getFileDisplayName(aFile);
+ this._contentSandbox.image = this._getFileIconURL(aFile);
+ var codeStr = "menuitem.setAttribute('label', label); " +
+ "menuitem.setAttribute('image', image);"
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ },
+
+ /**
+ * Displays a prompt from which the user may choose a (client) feed reader.
+ * @return - true if a feed reader was selected, false otherwise.
+ */
+ _chooseClientApp: function FW__chooseClientApp() {
+ try {
+ var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+ fp.init(this._window,
+ this._getString("chooseApplicationDialogTitle"),
+ Ci.nsIFilePicker.modeOpen);
+ fp.appendFilters(Ci.nsIFilePicker.filterApps);
+
+ if (fp.show() == Ci.nsIFilePicker.returnOK) {
+ this._selectedApp = fp.file;
+ if (this._selectedApp) {
+ // XXXben - we need to compare this with the running instance executable
+ // just don't know how to do that via script...
+ // XXXmano TBD: can probably add this to nsIShellService
+//@line 765 "/builds/moz2_slave/linux_build/build/browser/components/feeds/src/FeedWriter.js"
+ if (fp.file.leafName != "firefox-bin") {
+//@line 768 "/builds/moz2_slave/linux_build/build/browser/components/feeds/src/FeedWriter.js"
+ this._initMenuItemWithFile(this._contentSandbox.selectedAppMenuItem,
+ this._selectedApp);
+
+ // Show and select the selected application menuitem
+ var codeStr = "selectedAppMenuItem.hidden = false;" +
+ "selectedAppMenuItem.doCommand();"
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ return true;
+ }
+ }
+ }
+ }
+ catch(ex) { }
+
+ return false;
+ },
+
+ _setAlwaysUseCheckedState: function FW__setAlwaysUseCheckedState(feedType) {
+ var checkbox = this._document.getElementById("alwaysUse");
+ if (checkbox) {
+ var alwaysUse = false;
+ try {
+ var prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ if (prefs.getCharPref(getPrefActionForType(feedType)) != "ask")
+ alwaysUse = true;
+ }
+ catch(ex) { }
+ this._setCheckboxCheckedState(checkbox, alwaysUse);
+ }
+ },
+
+ _setSubscribeUsingLabel: function FW__setSubscribeUsingLabel() {
+ var stringLabel = "subscribeFeedUsing";
+ switch (this._getFeedType()) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ stringLabel = "subscribeVideoPodcastUsing";
+ break;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ stringLabel = "subscribeAudioPodcastUsing";
+ break;
+ }
+
+ this._contentSandbox.subscribeUsing =
+ this._document.getElementById("subscribeUsingDescription");
+ this._contentSandbox.label = this._getString(stringLabel);
+ var codeStr = "subscribeUsing.setAttribute('value', label);"
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ },
+
+ _setAlwaysUseLabel: function FW__setAlwaysUseLabel() {
+ var checkbox = this._document.getElementById("alwaysUse");
+ if (checkbox) {
+ var handlersMenuList = this._document.getElementById("handlersMenuList");
+ if (handlersMenuList) {
+ var handlerName = this._getSelectedItemFromMenulist(handlersMenuList)
+ .getAttribute("label");
+ var stringLabel = "alwaysUseForFeeds";
+ switch (this._getFeedType()) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ stringLabel = "alwaysUseForVideoPodcasts";
+ break;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ stringLabel = "alwaysUseForAudioPodcasts";
+ break;
+ }
+
+ this._contentSandbox.checkbox = checkbox;
+ this._contentSandbox.label = this._getFormattedString(stringLabel, [handlerName]);
+
+ var codeStr = "checkbox.setAttribute('label', label);";
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ }
+ }
+ },
+
+ // nsIDomEventListener
+ handleEvent: function(event) {
+ // see comments in init()
+ event = new XPCNativeWrapper(event);
+ if (event.target.ownerDocument != this._document) {
+ LOG("FeedWriter.handleEvent: Someone passed the feed writer as a listener to the events of another document!");
+ return;
+ }
+
+ if (event.type == "command") {
+ switch (event.target.id) {
+ case "subscribeButton":
+ this.subscribe();
+ break;
+ case "chooseApplicationMenuItem":
+ /* Bug 351263: Make sure to not steal focus if the "Choose
+ * Application" item is being selected with the keyboard. We do this
+ * by ignoring command events while the dropdown is closed (user
+ * arrowing through the combobox), but handling them while the
+ * combobox dropdown is open (user pressed enter when an item was
+ * selected). If we don't show the filepicker here, it will be shown
+ * when clicking "Subscribe Now".
+ */
+ var popupbox = this._document.getElementById("handlersMenuList")
+ .firstChild.boxObject;
+ popupbox.QueryInterface(Components.interfaces.nsIPopupBoxObject);
+ if (popupbox.popupState == "hiding" && !this._chooseClientApp()) {
+ // Select the (per-prefs) selected handler if no application was
+ // selected
+ this._setSelectedHandler(this._getFeedType());
+ }
+ break;
+ default:
+ this._setAlwaysUseLabel();
+ }
+ }
+ },
+
+ _setSelectedHandler: function FW__setSelectedHandler(feedType) {
+ var prefs =
+ Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+
+ var handler = "bookmarks";
+ try {
+ handler = prefs.getCharPref(getPrefReaderForType(feedType));
+ }
+ catch (ex) { }
+
+ switch (handler) {
+ case "web": {
+ var handlersMenuList = this._document.getElementById("handlersMenuList");
+ if (handlersMenuList) {
+ var url = prefs.getComplexValue(getPrefWebForType(feedType), Ci.nsISupportsString).data;
+ var handlers =
+ handlersMenuList.getElementsByAttribute("webhandlerurl", url);
+ if (handlers.length == 0) {
+ LOG("FeedWriter._setSelectedHandler: selected web handler isn't in the menulist")
+ return;
+ }
+
+ this._safeDoCommand(handlers[0]);
+ }
+ break;
+ }
+ case "client": {
+ try {
+ this._selectedApp =
+ prefs.getComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile);
+ }
+ catch(ex) {
+ this._selectedApp = null;
+ }
+
+ if (this._selectedApp) {
+ this._initMenuItemWithFile(this._contentSandbox.selectedAppMenuItem,
+ this._selectedApp);
+ var codeStr = "selectedAppMenuItem.hidden = false; " +
+ "selectedAppMenuItem.doCommand(); ";
+
+ // Only show the default reader menuitem if the default reader
+ // isn't the selected application
+ if (this._defaultSystemReader) {
+ var shouldHide =
+ this._defaultSystemReader.path == this._selectedApp.path;
+ codeStr += "defaultHandlerMenuItem.hidden = " + shouldHide + ";"
+ }
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ break;
+ }
+ }
+ case "bookmarks":
+ default: {
+ var liveBookmarksMenuItem = this._document.getElementById("liveBookmarksMenuItem");
+ if (liveBookmarksMenuItem)
+ this._safeDoCommand(liveBookmarksMenuItem);
+ }
+ }
+ },
+
+ _initSubscriptionUI: function FW__initSubscriptionUI() {
+ var handlersMenuPopup = this._document.getElementById("handlersMenuPopup");
+ if (!handlersMenuPopup)
+ return;
+
+ var feedType = this._getFeedType();
+ var codeStr;
+
+ // change the background
+ var header = this._document.getElementById("feedHeader");
+ this._contentSandbox.header = header;
+ switch (feedType) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ codeStr = "header.className = 'videoPodcastBackground'; ";
+ break;
+
+ case Ci.nsIFeed.TYPE_AUDIO:
+ codeStr = "header.className = 'audioPodcastBackground'; ";
+ break;
+
+ default:
+ codeStr = "header.className = 'feedBackground'; ";
+ }
+
+
+ // Last-selected application
+ var menuItem = this._document.createElementNS(XUL_NS, "menuitem");
+ menuItem.id = "selectedAppMenuItem";
+ menuItem.className = "menuitem-iconic";
+ menuItem.setAttribute("handlerType", "client");
+ try {
+ var prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ this._selectedApp = prefs.getComplexValue(getPrefAppForType(feedType),
+ Ci.nsILocalFile);
+
+ if (this._selectedApp.exists())
+ this._initMenuItemWithFile(menuItem, this._selectedApp);
+ else {
+ // Hide the menuitem if the last selected application doesn't exist
+ menuItem.setAttribute("hidden", true);
+ }
+ }
+ catch(ex) {
+ // Hide the menuitem until an application is selected
+ menuItem.setAttribute("hidden", true);
+ }
+ this._contentSandbox.handlersMenuPopup = handlersMenuPopup;
+ this._contentSandbox.selectedAppMenuItem = menuItem;
+
+ codeStr += "handlersMenuPopup.appendChild(selectedAppMenuItem); ";
+
+ // List the default feed reader
+ try {
+ this._defaultSystemReader = Cc["@mozilla.org/browser/shell-service;1"].
+ getService(Ci.nsIShellService).
+ defaultFeedReader;
+ menuItem = this._document.createElementNS(XUL_NS, "menuitem");
+ menuItem.id = "defaultHandlerMenuItem";
+ menuItem.className = "menuitem-iconic";
+ menuItem.setAttribute("handlerType", "client");
+
+ this._initMenuItemWithFile(menuItem, this._defaultSystemReader);
+
+ // Hide the default reader item if it points to the same application
+ // as the last-selected application
+ if (this._selectedApp &&
+ this._selectedApp.path == this._defaultSystemReader.path)
+ menuItem.hidden = true;
+ }
+ catch(ex) { menuItem = null; /* no default reader */ }
+
+ if (menuItem) {
+ this._contentSandbox.defaultHandlerMenuItem = menuItem;
+ codeStr += "handlersMenuPopup.appendChild(defaultHandlerMenuItem); ";
+ }
+
+ // "Choose Application..." menuitem
+ menuItem = this._document.createElementNS(XUL_NS, "menuitem");
+ menuItem.id = "chooseApplicationMenuItem";
+ menuItem.className = "menuitem-iconic";
+ menuItem.setAttribute("label", this._getString("chooseApplicationMenuItem"));
+
+ this._contentSandbox.chooseAppMenuItem = menuItem;
+ codeStr += "handlersMenuPopup.appendChild(chooseAppMenuItem); ";
+
+ // separator
+ this._contentSandbox.chooseAppSep =
+ this._document.createElementNS(XUL_NS, "menuseparator")
+ codeStr += "handlersMenuPopup.appendChild(chooseAppSep); ";
+
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+
+ var historySvc = Cc["@mozilla.org/browser/nav-history-service;1"].
+ getService(Ci.nsINavHistoryService);
+ historySvc.addObserver(this, false);
+
+ // List of web handlers
+ var wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
+ getService(Ci.nsIWebContentConverterService);
+ var handlers = wccr.getContentHandlers(this._getMimeTypeForFeedType(feedType), {});
+ if (handlers.length != 0) {
+ for (var i = 0; i < handlers.length; ++i) {
+ menuItem = this._document.createElementNS(XUL_NS, "menuitem");
+ menuItem.className = "menuitem-iconic";
+ menuItem.setAttribute("label", handlers[i].name);
+ menuItem.setAttribute("handlerType", "web");
+ menuItem.setAttribute("webhandlerurl", handlers[i].uri);
+ this._contentSandbox.menuItem = menuItem;
+ codeStr = "handlersMenuPopup.appendChild(menuItem);";
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+
+ // For privacy reasons we cannot set the image attribute directly
+ // to the icon url, see Bug 358878
+ var uri = makeURI(handlers[i].uri);
+ if (!this._setFaviconForWebReader(uri, menuItem)) {
+ if (uri && /^https?/.test(uri.scheme)) {
+ var iconURL = makeURI(uri.prePath + "/favicon.ico");
+ this._faviconService.setAndLoadFaviconForPage(uri, iconURL, true);
+ }
+ }
+ }
+ this._contentSandbox.menuItem = null;
+ }
+
+ this._setSelectedHandler(feedType);
+
+ // "Subscribe using..."
+ this._setSubscribeUsingLabel();
+
+ // "Always use..." checkbox initial state
+ this._setAlwaysUseCheckedState(feedType);
+ this._setAlwaysUseLabel();
+
+ // We update the "Always use.." checkbox label whenever the selected item
+ // in the list is changed
+ handlersMenuPopup.addEventListener("command", this, false);
+
+ // Set up the "Subscribe Now" button
+ this._document
+ .getElementById("subscribeButton")
+ .addEventListener("command", this, false);
+
+ // first-run ui
+ var showFirstRunUI = true;
+ try {
+ showFirstRunUI = prefs.getBoolPref(PREF_SHOW_FIRST_RUN_UI);
+ }
+ catch (ex) { }
+ if (showFirstRunUI) {
+ var textfeedinfo1, textfeedinfo2;
+ switch (feedType) {
+ case Ci.nsIFeed.TYPE_VIDEO:
+ textfeedinfo1 = "feedSubscriptionVideoPodcast1";
+ textfeedinfo2 = "feedSubscriptionVideoPodcast2";
+ break;
+ case Ci.nsIFeed.TYPE_AUDIO:
+ textfeedinfo1 = "feedSubscriptionAudioPodcast1";
+ textfeedinfo2 = "feedSubscriptionAudioPodcast2";
+ break;
+ default:
+ textfeedinfo1 = "feedSubscriptionFeed1";
+ textfeedinfo2 = "feedSubscriptionFeed2";
+ }
+
+ this._contentSandbox.feedinfo1 =
+ this._document.getElementById("feedSubscriptionInfo1");
+ this._contentSandbox.feedinfo1Str = this._getString(textfeedinfo1);
+ this._contentSandbox.feedinfo2 =
+ this._document.getElementById("feedSubscriptionInfo2");
+ this._contentSandbox.feedinfo2Str = this._getString(textfeedinfo2);
+ this._contentSandbox.header = header;
+ codeStr = "feedinfo1.textContent = feedinfo1Str; " +
+ "feedinfo2.textContent = feedinfo2Str; " +
+ "header.setAttribute('firstrun', 'true');"
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ prefs.setBoolPref(PREF_SHOW_FIRST_RUN_UI, false);
+ }
+ },
+
+ /**
+ * Returns the original URI object of the feed and ensures that this
+ * component is only ever invoked from the preview document.
+ * @param aWindow
+ * The window of the document invoking the BrowserFeedWriter
+ */
+ _getOriginalURI: function FW__getOriginalURI(aWindow) {
+ var chan = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
+ getInterface(Ci.nsIWebNavigation).
+ QueryInterface(Ci.nsIDocShell).currentDocumentChannel;
+
+ var uri = makeURI(SUBSCRIBE_PAGE_URI);
+ var resolvedURI = Cc["@mozilla.org/chrome/chrome-registry;1"].
+ getService(Ci.nsIChromeRegistry).
+ convertChromeURL(uri);
+
+ if (resolvedURI.equals(chan.URI))
+ return chan.originalURI;
+
+ return null;
+ },
+
+ _window: null,
+ _document: null,
+ _feedURI: null,
+ _feedPrincipal: null,
+
+ // nsIFeedWriter
+ init: function FW_init(aWindow) {
+ // Explicitly wrap |window| in an XPCNativeWrapper to make sure
+ // it's a real native object! This will throw an exception if we
+ // get a non-native object.
+ var window = new XPCNativeWrapper(aWindow);
+ this._feedURI = this._getOriginalURI(window);
+ if (!this._feedURI)
+ return;
+
+ this._window = window;
+ this._document = window.document;
+
+ var secman = Cc["@mozilla.org/scriptsecuritymanager;1"].
+ getService(Ci.nsIScriptSecurityManager);
+ this._feedPrincipal = secman.getCodebasePrincipal(this._feedURI);
+
+ LOG("Subscribe Preview: feed uri = " + this._window.location.href);
+
+ // Set up the subscription UI
+ this._initSubscriptionUI();
+ var prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+ prefs.addObserver(PREF_SELECTED_ACTION, this, false);
+ prefs.addObserver(PREF_SELECTED_READER, this, false);
+ prefs.addObserver(PREF_SELECTED_WEB, this, false);
+ prefs.addObserver(PREF_SELECTED_APP, this, false);
+ prefs.addObserver(PREF_VIDEO_SELECTED_ACTION, this, false);
+ prefs.addObserver(PREF_VIDEO_SELECTED_READER, this, false);
+ prefs.addObserver(PREF_VIDEO_SELECTED_WEB, this, false);
+ prefs.addObserver(PREF_VIDEO_SELECTED_APP, this, false);
+
+ prefs.addObserver(PREF_AUDIO_SELECTED_ACTION, this, false);
+ prefs.addObserver(PREF_AUDIO_SELECTED_READER, this, false);
+ prefs.addObserver(PREF_AUDIO_SELECTED_WEB, this, false);
+ prefs.addObserver(PREF_AUDIO_SELECTED_APP, this, false);
+ },
+
+ writeContent: function FW_writeContent() {
+ if (!this._window)
+ return;
+
+ try {
+ // Set up the feed content
+ var container = this._getContainer();
+ if (!container)
+ return;
+
+ this._setTitleText(container);
+ this._setTitleImage(container);
+ this._writeFeedContent(container);
+ }
+ finally {
+ this._removeFeedFromCache();
+ }
+ },
+
+ close: function FW_close() {
+ this._document
+ .getElementById("handlersMenuPopup")
+ .removeEventListener("command", this, false);
+ this._document
+ .getElementById("subscribeButton")
+ .removeEventListener("command", this, false);
+ this._document = null;
+ this._window = null;
+ var prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+ prefs.removeObserver(PREF_SELECTED_ACTION, this);
+ prefs.removeObserver(PREF_SELECTED_READER, this);
+ prefs.removeObserver(PREF_SELECTED_WEB, this);
+ prefs.removeObserver(PREF_SELECTED_APP, this);
+ prefs.removeObserver(PREF_VIDEO_SELECTED_ACTION, this);
+ prefs.removeObserver(PREF_VIDEO_SELECTED_READER, this);
+ prefs.removeObserver(PREF_VIDEO_SELECTED_WEB, this);
+ prefs.removeObserver(PREF_VIDEO_SELECTED_APP, this);
+
+ prefs.removeObserver(PREF_AUDIO_SELECTED_ACTION, this);
+ prefs.removeObserver(PREF_AUDIO_SELECTED_READER, this);
+ prefs.removeObserver(PREF_AUDIO_SELECTED_WEB, this);
+ prefs.removeObserver(PREF_AUDIO_SELECTED_APP, this);
+
+ this._removeFeedFromCache();
+ this.__faviconService = null;
+ this.__bundle = null;
+ this._feedURI = null;
+ this.__contentSandbox = null;
+
+ var historySvc = Cc["@mozilla.org/browser/nav-history-service;1"].
+ getService(Ci.nsINavHistoryService);
+ historySvc.removeObserver(this);
+ },
+
+ _removeFeedFromCache: function FW__removeFeedFromCache() {
+ if (this._feedURI) {
+ var feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
+ getService(Ci.nsIFeedResultService);
+ feedService.removeFeedResult(this._feedURI);
+ this._feedURI = null;
+ }
+ },
+
+ subscribe: function FW_subscribe() {
+ var feedType = this._getFeedType();
+
+ // Subscribe to the feed using the selected handler and save prefs
+ var prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ var defaultHandler = "reader";
+ var useAsDefault = this._document.getElementById("alwaysUse")
+ .getAttribute("checked");
+
+ var handlersMenuList = this._document.getElementById("handlersMenuList");
+ var selectedItem = this._getSelectedItemFromMenulist(handlersMenuList);
+
+ // Show the file picker before subscribing if the
+ // choose application menuitem was choosen using the keyboard
+ if (selectedItem.id == "chooseApplicationMenuItem") {
+ if (!this._chooseClientApp())
+ return;
+
+ selectedItem = this._getSelectedItemFromMenulist(handlersMenuList);
+ }
+
+ if (selectedItem.hasAttribute("webhandlerurl")) {
+ var webURI = selectedItem.getAttribute("webhandlerurl");
+ prefs.setCharPref(getPrefReaderForType(feedType), "web");
+
+ var supportsString = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ supportsString.data = webURI;
+ prefs.setComplexValue(getPrefWebForType(feedType), Ci.nsISupportsString,
+ supportsString);
+
+ var wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
+ getService(Ci.nsIWebContentConverterService);
+ var handler = wccr.getWebContentHandlerByURI(this._getMimeTypeForFeedType(feedType), webURI);
+ if (handler) {
+ if (useAsDefault)
+ wccr.setAutoHandler(this._getMimeTypeForFeedType(feedType), handler);
+
+ this._window.location.href = handler.getHandlerURI(this._window.location.href);
+ }
+ }
+ else {
+ switch (selectedItem.id) {
+ case "selectedAppMenuItem":
+ prefs.setComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile,
+ this._selectedApp);
+ prefs.setCharPref(getPrefReaderForType(feedType), "client");
+ break;
+ case "defaultHandlerMenuItem":
+ prefs.setComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile,
+ this._defaultSystemReader);
+ prefs.setCharPref(getPrefReaderForType(feedType), "client");
+ break;
+ case "liveBookmarksMenuItem":
+ defaultHandler = "bookmarks";
+ prefs.setCharPref(getPrefReaderForType(feedType), "bookmarks");
+ break;
+ }
+ var feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
+ getService(Ci.nsIFeedResultService);
+
+ // Pull the title and subtitle out of the document
+ var feedTitle = this._document.getElementById(TITLE_ID).textContent;
+ var feedSubtitle = this._document.getElementById(SUBTITLE_ID).textContent;
+ feedService.addToClientReader(this._window.location.href, feedTitle, feedSubtitle, feedType);
+ }
+
+ // If "Always use..." is checked, we should set PREF_*SELECTED_ACTION
+ // to either "reader" (If a web reader or if an application is selected),
+ // or to "bookmarks" (if the live bookmarks option is selected).
+ // Otherwise, we should set it to "ask"
+ if (useAsDefault)
+ prefs.setCharPref(getPrefActionForType(feedType), defaultHandler);
+ else
+ prefs.setCharPref(getPrefActionForType(feedType), "ask");
+ },
+
+ // nsIObserver
+ observe: function FW_observe(subject, topic, data) {
+ // see init()
+ subject = new XPCNativeWrapper(subject);
+
+ if (!this._window) {
+ // this._window is null unless this.init was called with a trusted
+ // window object.
+ return;
+ }
+
+ var feedType = this._getFeedType();
+
+ if (topic == "nsPref:changed") {
+ switch (data) {
+ case PREF_SELECTED_READER:
+ case PREF_SELECTED_WEB:
+ case PREF_SELECTED_APP:
+ case PREF_VIDEO_SELECTED_READER:
+ case PREF_VIDEO_SELECTED_WEB:
+ case PREF_VIDEO_SELECTED_APP:
+ case PREF_AUDIO_SELECTED_READER:
+ case PREF_AUDIO_SELECTED_WEB:
+ case PREF_AUDIO_SELECTED_APP:
+ this._setSelectedHandler(feedType);
+ break;
+ case PREF_SELECTED_ACTION:
+ case PREF_VIDEO_SELECTED_ACTION:
+ case PREF_AUDIO_SELECTED_ACTION:
+ this._setAlwaysUseCheckedState(feedType);
+ }
+ }
+ },
+
+ /**
+ * Sets the icon for the given web-reader item in the readers menu
+ * if the favicon-service has the necessary icon stored.
+ * @param aURI
+ * the reader URI.
+ * @param aMenuItem
+ * the reader item in the readers menulist.
+ * @return true if the icon was set, false otherwise.
+ */
+ _setFaviconForWebReader:
+ function FW__setFaviconForWebReader(aURI, aMenuItem) {
+ var faviconsSvc = this._faviconService;
+ var faviconURI = null;
+ try {
+ faviconURI = faviconsSvc.getFaviconForPage(aURI);
+ }
+ catch(ex) { }
+
+ if (faviconURI) {
+ var dataURL = faviconsSvc.getFaviconDataAsDataURL(faviconURI);
+ if (dataURL) {
+ this._contentSandbox.menuItem = aMenuItem;
+ this._contentSandbox.dataURL = dataURL;
+ var codeStr = "menuItem.setAttribute('image', dataURL);";
+ Cu.evalInSandbox(codeStr, this._contentSandbox);
+ this._contentSandbox.menuItem = null;
+ this._contentSandbox.dataURL = null;
+
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ // nsINavHistoryService
+ onPageChanged: function FW_onPageChanged(aURI, aWhat, aValue) {
+ // see init()
+ aURI = new XPCNativeWrapper(aURI);
+
+ if (aWhat == Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) {
+ // Go through the readers menu and look for the corresponding
+ // reader menu-item for the page if any.
+ var spec = aURI.spec;
+ var handlersMenulist = this._document.getElementById("handlersMenuList");
+ var possibleHandlers = handlersMenulist.firstChild.childNodes;
+ for (var i=0; i < possibleHandlers.length ; i++) {
+ if (possibleHandlers[i].getAttribute("webhandlerurl") == spec) {
+ this._setFaviconForWebReader(aURI, possibleHandlers[i]);
+ return;
+ }
+ }
+ }
+ },
+
+ onBeginUpdateBatch: function() { },
+ onEndUpdateBatch: function() { },
+ onVisit: function() { },
+ onTitleChanged: function() { },
+ onDeleteURI: function() { },
+ onClearHistory: function() { },
+ onPageExpired: function() { },
+
+ // nsIClassInfo
+ getInterfaces: function FW_getInterfaces(countRef) {
+ var interfaces = [Ci.nsIFeedWriter, Ci.nsIClassInfo, Ci.nsISupports];
+ countRef.value = interfaces.length;
+ return interfaces;
+ },
+ getHelperForLanguage: function FW_getHelperForLanguage(language) null,
+ contractID: "@mozilla.org/browser/feeds/result-writer;1",
+ classDescription: "Feed Writer",
+ classID: Components.ID("{49bb6593-3aff-4eb3-a068-2712c28bd58e}"),
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ flags: Ci.nsIClassInfo.DOM_OBJECT,
+ _xpcom_categories: [{ category: "JavaScript global constructor",
+ entry: "BrowserFeedWriter"}],
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFeedWriter, Ci.nsIClassInfo,
+ Ci.nsIDOMEventListener, Ci.nsIObserver,
+ Ci.nsINavHistoryObserver])
+};
+
+function NSGetModule(cm, file)
+ XPCOMUtils.generateModule([FeedWriter]);
diff --git a/bundles/XO/components/NetworkGeolocationProvider.js b/bundles/XO/components/NetworkGeolocationProvider.js
new file mode 100755
index 0000000..c56b44d
--- /dev/null
+++ b/bundles/XO/components/NetworkGeolocationProvider.js
@@ -0,0 +1,279 @@
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+
+function nowInSeconds()
+{
+ return Date.now() / 1000;
+}
+
+function LOG(aMsg) {
+ //aMsg = ("*** WIFI GEO: " + aMsg);
+ //Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(aMsg);
+}
+
+function getAccessTokenForURL(url)
+{
+ // check to see if we have an access token:
+ var accessToken = "";
+
+ try {
+ var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+
+ var accessTokenPrefName = "geo.wifi.access_token." + url;
+ accessToken = prefService.getCharPref(accessTokenPrefName);
+
+ // check to see if it has expired
+ var accessTokenDate = prefService.getIntPref(accessTokenPrefName + ".time");
+
+ var accessTokenInterval = 1209600; /* seconds in 2 weeks */
+ try {
+ accessTokenInterval = prefService.getIntPref("geo.wifi.access_token.recycle_interval");
+ } catch (e) {}
+
+ if (nowInSeconds() - accessTokenDate > accessTokenInterval)
+ accessToken = "";
+ }
+ catch (e) {
+ accessToken = "";
+ LOG("Error: "+ e);
+ }
+ return accessToken;
+}
+
+function WifiGeoCoordsObject(lat, lon, acc) {
+ this.latitude = lat;
+ this.longitude = lon;
+ this.accuracy = acc;
+};
+
+WifiGeoCoordsObject.prototype = {
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPositionCoords, Ci.nsIClassInfo]),
+
+ getInterfaces: function(countRef) {
+ var interfaces = [Ci.nsIDOMGeoPositionCoords, Ci.nsIClassInfo, Ci.nsISupports];
+ countRef.value = interfaces.length;
+ return interfaces;
+ },
+
+ getHelperForLanguage: function(language) null,
+ contractID: "",
+ classDescription: "wifi geo position coords object",
+ classID: null,
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ flags: Ci.nsIClassInfo.DOM_OBJECT,
+
+ latitude: 0,
+ longitude: 0,
+ accuracy: 0,
+
+ altitude: 0,
+ altitudeAccuracy: 0,
+ heading: 0,
+ speed: 0,
+};
+
+function WifiGeoPositionObject(lat, lon, acc) {
+ this.coords = new WifiGeoCoordsObject(lat, lon, acc);
+ this.timestamp = Date.now();
+};
+
+WifiGeoPositionObject.prototype = {
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGeoPosition, Ci.nsIClassInfo]),
+
+ // Class Info is required to be able to pass objects back into the DOM.
+ getInterfaces: function(countRef) {
+ var interfaces = [Ci.nsIDOMGeoPosition, Ci.nsIClassInfo, Ci.nsISupports];
+ countRef.value = interfaces.length;
+ return interfaces;
+ },
+
+ getHelperForLanguage: function(language) null,
+ contractID: "",
+ classDescription: "wifi geo location position object",
+ classID: null,
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ flags: Ci.nsIClassInfo.DOM_OBJECT,
+
+ coords: null,
+ timestamp: 0,
+};
+
+function WifiGeoPositionProvider() {};
+WifiGeoPositionProvider.prototype = {
+ classDescription: "A component that returns a geolocation based on WIFI",
+ classID: Components.ID("{77DA64D3-7458-4920-9491-86CC9914F904}"),
+ contractID: "@mozilla.org/geolocation/provider;1",
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationProvider, Ci.nsIWifiListener, Ci.nsITimerCallback]),
+
+ provider_url: null,
+ wifi_service: null,
+ timer: null,
+ hasSeenWiFi: false,
+
+ observe: function (aSubject, aTopic, aData) {
+ if (aTopic == "private-browsing") {
+ if (aData == "enter" || aData == "exit") {
+ let psvc = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
+ try {
+ let branch = psvc.getBranch("geo.wifi.access_token.");
+ branch.deleteBranch("");
+ } catch (e) {}
+ }
+ }
+ },
+
+ startup: function() {
+ LOG("startup called");
+
+ var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+ this.provider_url = prefService.getCharPref("geo.wifi.uri");
+ LOG("provider url = " + this.provider_url);
+
+ // if we don't see anything in 5 seconds, kick of one IP geo lookup.
+ this.hasSeenWiFi = false;
+ this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this.timer.initWithCallback(this, 5000, this.timer.TYPE_ONE_SHOT);
+
+ let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ os.addObserver(this, "private-browsing", false);
+ },
+
+ isReady: function() {
+ LOG("isReady called");
+ return true
+ },
+
+ watch: function(c) {
+ LOG("watch called");
+ if (!this.wifi_service) {
+ this.wifi_service = Cc["@mozilla.org/wifi/monitor;1"].getService(Components.interfaces.nsIWifiMonitor);
+ this.wifi_service.startWatching(this);
+ }
+ },
+
+ shutdown: function() {
+ LOG("shutdown called");
+ if(this.wifi_service)
+ this.wifi_service.stopWatching(this);
+ this.wifi_service = null;
+
+ if (this.timer != null) {
+ this.timer.cancel();
+ this.timer = null;
+ }
+
+ // Although we aren't using cookies, we should err on the side of not
+ // saving any access tokens if the user asked us not to save cookies or
+ // has changed the lifetimePolicy. The access token in these cases is
+ // used and valid for the life of this object (eg. between startup and
+ // shutdown).e
+ let prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+ if (prefBranch.getIntPref("network.cookie.lifetimePolicy") != 0)
+ prefBranch.deleteBranch("geo.wifi.access_token.");
+
+ let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ os.removeObserver(this, "private-browsing");
+ },
+
+ onChange: function(accessPoints) {
+
+ LOG("onChange called");
+ this.hasSeenWiFi = true;
+
+ var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+
+ // send our request to a wifi geolocation network provider:
+ var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
+
+ // This is a background load
+ xhr.mozBackgroundRequest = true;
+
+ xhr.open("POST", this.provider_url, false);
+
+ // set something so that we can strip cookies
+ xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
+
+ xhr.onerror = function(req) {
+ LOG("onerror: " + req);
+ };
+
+ xhr.onload = function (req) {
+
+ LOG("service returned: " + req.target.responseText);
+
+ // if we get a bad response, we will throw and never report a location
+ var response = JSON.parse(req.target.responseText);
+
+ // response looks something like:
+ // {"location":{"latitude":51.5090332,"longitude":-0.1212726,"accuracy":150.0},"access_token":"2:jVhRZJ-j6PiRchH_:RGMrR0W1BiwdZs12"}
+
+ // Check to see if we have a new access token
+ var newAccessToken = response.access_token;
+ if (newAccessToken != undefined)
+ {
+ var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+ var accessToken = "";
+ var accessTokenPrefName = "geo.wifi.access_token." + req.target.channel.URI.spec;
+ try { accessToken = prefService.getCharPref(accessTokenPrefName); } catch (e) {}
+
+ if (accessToken != newAccessToken) {
+ // no match, lets cache
+ LOG("New Access Token: " + newAccessToken + "\n" + accessTokenPrefName);
+
+ prefService.setIntPref(accessTokenPrefName + ".time", nowInSeconds());
+ prefService.setCharPref(accessTokenPrefName, newAccessToken);
+ }
+ }
+
+ var newLocation = new WifiGeoPositionObject(response.location.latitude,
+ response.location.longitude,
+ response.location.accuracy);
+
+ var update = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate);
+ update.update(newLocation);
+ };
+
+ var accessToken = getAccessTokenForURL(this.provider_url);
+
+ var request = {
+ version: "1.1.0",
+// request_address: true,
+ };
+
+ if (accessToken != "")
+ request.access_token = accessToken;
+
+ if (accessPoints != null) {
+ request.wifi_towers = accessPoints.map(function (ap) ({
+ mac_address: ap.mac,
+ ssid: ap.ssid,
+ signal_strength: ap.signal,
+ }));
+ }
+
+ var jsonString = JSON.stringify(request);
+ LOG("client sending: " + jsonString);
+
+ xhr.send(jsonString);
+ },
+
+ onError: function (code) {
+ LOG("wifi error: " + code);
+ },
+
+ notify: function (timer) {
+ if (this.hasSeenWiFi == false)
+ this.onChange(null);
+ this.timer = null;
+ },
+
+};
+
+var components = [WifiGeoPositionProvider];
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(components);
+}
diff --git a/bundles/XO/components/WebContentConverter.js b/bundles/XO/components/WebContentConverter.js
new file mode 100755
index 0000000..42f47e9
--- /dev/null
+++ b/bundles/XO/components/WebContentConverter.js
@@ -0,0 +1,989 @@
+//@line 39 "/builds/moz2_slave/linux_build/build/browser/components/feeds/src/WebContentConverter.js"
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+function LOG(str) {
+ dump("*** " + str + "\n");
+}
+
+const WCCR_CONTRACTID = "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1";
+const WCCR_CLASSID = Components.ID("{792a7e82-06a0-437c-af63-b2d12e808acc}");
+const WCCR_CLASSNAME = "Web Content Handler Registrar";
+
+const WCC_CLASSID = Components.ID("{db7ebf28-cc40-415f-8a51-1b111851df1e}");
+const WCC_CLASSNAME = "Web Service Handler";
+
+const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
+const TYPE_ANY = "*/*";
+
+const PREF_CONTENTHANDLERS_AUTO = "browser.contentHandlers.auto.";
+const PREF_CONTENTHANDLERS_BRANCH = "browser.contentHandlers.types.";
+const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
+const PREF_SELECTED_ACTION = "browser.feeds.handler";
+const PREF_SELECTED_READER = "browser.feeds.handler.default";
+const PREF_HANDLER_EXTERNAL_PREFIX = "network.protocol-handler.external";
+const PREF_ALLOW_DIFFERENT_HOST = "gecko.handlerService.allowRegisterFromDifferentHost";
+
+const STRING_BUNDLE_URI = "chrome://browser/locale/feeds/subscribe.properties";
+
+const NS_ERROR_MODULE_DOM = 2152923136;
+const NS_ERROR_DOM_SYNTAX_ERR = NS_ERROR_MODULE_DOM + 12;
+
+function WebContentConverter() {
+}
+WebContentConverter.prototype = {
+ convert: function WCC_convert() { },
+ asyncConvertData: function WCC_asyncConvertData() { },
+ onDataAvailable: function WCC_onDataAvailable() { },
+ onStopRequest: function WCC_onStopRequest() { },
+
+ onStartRequest: function WCC_onStartRequest(request, context) {
+ var wccr =
+ Cc[WCCR_CONTRACTID].
+ getService(Ci.nsIWebContentConverterService);
+ wccr.loadPreferredHandler(request);
+ },
+
+ QueryInterface: function WCC_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIStreamConverter) ||
+ iid.equals(Ci.nsIStreamListener) ||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+};
+
+var WebContentConverterFactory = {
+ createInstance: function WCCF_createInstance(outer, iid) {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return new WebContentConverter().QueryInterface(iid);
+ },
+
+ QueryInterface: function WCC_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIFactory) ||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+};
+
+function ServiceInfo(contentType, uri, name) {
+ this._contentType = contentType;
+ this._uri = uri;
+ this._name = name;
+}
+ServiceInfo.prototype = {
+ /**
+ * See nsIHandlerApp
+ */
+ get name() {
+ return this._name;
+ },
+
+ /**
+ * See nsIHandlerApp
+ */
+ equals: function SI_equals(aHandlerApp) {
+ if (!aHandlerApp)
+ throw Cr.NS_ERROR_NULL_POINTER;
+
+ if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo &&
+ aHandlerApp.contentType == this.contentType &&
+ aHandlerApp.uri == this.uri)
+ return true;
+
+ return false;
+ },
+
+ /**
+ * See nsIWebContentHandlerInfo
+ */
+ get contentType() {
+ return this._contentType;
+ },
+
+ /**
+ * See nsIWebContentHandlerInfo
+ */
+ get uri() {
+ return this._uri;
+ },
+
+ /**
+ * See nsIWebContentHandlerInfo
+ */
+ getHandlerURI: function SI_getHandlerURI(uri) {
+ return this._uri.replace(/%s/gi, encodeURIComponent(uri));
+ },
+
+ QueryInterface: function SI_QueryInterface(iid) {
+ if (iid.equals(Ci.nsIWebContentHandlerInfo) ||
+ iid.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+};
+
+function WebContentConverterRegistrar() {
+ this._contentTypes = { };
+ this._autoHandleContentTypes = { };
+}
+
+WebContentConverterRegistrar.prototype = {
+ get stringBundle() {
+ var sb = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).
+ createBundle(STRING_BUNDLE_URI);
+ delete WebContentConverterRegistrar.prototype.stringBundle;
+ return WebContentConverterRegistrar.prototype.stringBundle = sb;
+ },
+
+ _getFormattedString: function WCCR__getFormattedString(key, params) {
+ return this.stringBundle.formatStringFromName(key, params, params.length);
+ },
+
+ _getString: function WCCR_getString(key) {
+ return this.stringBundle.GetStringFromName(key);
+ },
+
+ /**
+ * See nsIWebContentConverterService
+ */
+ getAutoHandler:
+ function WCCR_getAutoHandler(contentType) {
+ contentType = this._resolveContentType(contentType);
+ if (contentType in this._autoHandleContentTypes)
+ return this._autoHandleContentTypes[contentType];
+ return null;
+ },
+
+ /**
+ * See nsIWebContentConverterService
+ */
+ setAutoHandler:
+ function WCCR_setAutoHandler(contentType, handler) {
+ if (handler && !this._typeIsRegistered(contentType, handler.uri))
+ throw Cr.NS_ERROR_NOT_AVAILABLE;
+
+ contentType = this._resolveContentType(contentType);
+ this._setAutoHandler(contentType, handler);
+
+ var ps =
+ Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ var autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
+ if (handler)
+ autoBranch.setCharPref(contentType, handler.uri);
+ else if (autoBranch.prefHasUserValue(contentType))
+ autoBranch.clearUserPref(contentType);
+
+ ps.savePrefFile(null);
+ },
+
+ /**
+ * Update the internal data structure (not persistent)
+ */
+ _setAutoHandler:
+ function WCCR__setAutoHandler(contentType, handler) {
+ if (handler)
+ this._autoHandleContentTypes[contentType] = handler;
+ else if (contentType in this._autoHandleContentTypes)
+ delete this._autoHandleContentTypes[contentType];
+ },
+
+ /**
+ * See nsIWebContentConverterService
+ */
+ getWebContentHandlerByURI:
+ function WCCR_getWebContentHandlerByURI(contentType, uri) {
+ var handlers = this.getContentHandlers(contentType, { });
+ for (var i = 0; i < handlers.length; ++i) {
+ if (handlers[i].uri == uri)
+ return handlers[i];
+ }
+ return null;
+ },
+
+ /**
+ * See nsIWebContentConverterService
+ */
+ loadPreferredHandler:
+ function WCCR_loadPreferredHandler(request) {
+ var channel = request.QueryInterface(Ci.nsIChannel);
+ var contentType = this._resolveContentType(channel.contentType);
+ var handler = this.getAutoHandler(contentType);
+ if (handler) {
+ request.cancel(Cr.NS_ERROR_FAILURE);
+
+ var webNavigation =
+ channel.notificationCallbacks.getInterface(Ci.nsIWebNavigation);
+ webNavigation.loadURI(handler.getHandlerURI(channel.URI.spec),
+ Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
+ null, null, null);
+ }
+ },
+
+ /**
+ * See nsIWebContentConverterService
+ */
+ removeProtocolHandler:
+ function WCCR_removeProtocolHandler(aProtocol, aURITemplate) {
+ var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
+ getService(Ci.nsIExternalProtocolService);
+ var handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
+ var handlers = handlerInfo.possibleApplicationHandlers;
+ for (let i = 0; i < handlers.length; i++) {
+ try { // We only want to test web handlers
+ let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
+ if (handler.uriTemplate == aURITemplate) {
+ handlers.removeElementAt(i);
+ var hs = Cc["@mozilla.org/uriloader/handler-service;1"].
+ getService(Ci.nsIHandlerService);
+ hs.store(handlerInfo);
+ return;
+ }
+ } catch (e) { /* it wasn't a web handler */ }
+ }
+ },
+
+ /**
+ * See nsIWebContentConverterService
+ */
+ removeContentHandler:
+ function WCCR_removeContentHandler(contentType, uri) {
+ function notURI(serviceInfo) {
+ return serviceInfo.uri != uri;
+ }
+
+ if (contentType in this._contentTypes) {
+ this._contentTypes[contentType] =
+ this._contentTypes[contentType].filter(notURI);
+ }
+ },
+
+ /**
+ *
+ */
+ _mappings: {
+ "application/rss+xml": TYPE_MAYBE_FEED,
+ "application/atom+xml": TYPE_MAYBE_FEED,
+ },
+
+ /**
+ * These are types for which there is a separate content converter aside
+ * from our built in generic one. We should not automatically register
+ * a factory for creating a converter for these types.
+ */
+ _blockedTypes: {
+ "application/vnd.mozilla.maybe.feed": true,
+ },
+
+ /**
+ * Determines the "internal" content type based on the _mappings.
+ * @param contentType
+ * @returns The resolved contentType value.
+ */
+ _resolveContentType:
+ function WCCR__resolveContentType(contentType) {
+ if (contentType in this._mappings)
+ return this._mappings[contentType];
+ return contentType;
+ },
+
+ _makeURI: function(aURL, aOriginCharset, aBaseURI) {
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+ return ioService.newURI(aURL, aOriginCharset, aBaseURI);
+ },
+
+ _checkAndGetURI:
+ function WCCR_checkAndGetURI(aURIString, aContentWindow)
+ {
+ try {
+ var uri = this._makeURI(aURIString);
+ } catch (ex) {
+ // not supposed to throw according to spec
+ return;
+ }
+
+ // For security reasons we reject non-http(s) urls (see bug 354316),
+ // we may need to revise this once we support more content types
+ // XXX this should be a "security exception" according to spec, but that
+ // isn't defined yet.
+ if (uri.scheme != "http" && uri.scheme != "https")
+ throw("Permission denied to add " + uri.spec + " as a content or protocol handler");
+
+ // We also reject handlers registered from a different host (see bug 402287)
+ // The pref allows us to test the feature
+ var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+ if ((!pb.prefHasUserValue(PREF_ALLOW_DIFFERENT_HOST) ||
+ !pb.getBoolPref(PREF_ALLOW_DIFFERENT_HOST)) &&
+ aContentWindow.location.hostname != uri.host)
+ throw("Permission denied to add " + uri.spec + " as a content or protocol handler");
+
+ // If the uri doesn't contain '%s', it won't be a good handler
+ if (uri.spec.indexOf("%s") < 0)
+ throw NS_ERROR_DOM_SYNTAX_ERR;
+
+ return uri;
+ },
+
+ /**
+ * Determines if a web handler is already registered.
+ *
+ * @param aProtocol
+ * The scheme of the web handler we are checking for.
+ * @param aURITemplate
+ * The URI template that the handler uses to handle the protocol.
+ * @return true if it is already registered, false otherwise.
+ */
+ _protocolHandlerRegistered:
+ function WCCR_protocolHandlerRegistered(aProtocol, aURITemplate) {
+ var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
+ getService(Ci.nsIExternalProtocolService);
+ var handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
+ var handlers = handlerInfo.possibleApplicationHandlers;
+ for (let i = 0; i < handlers.length; i++) {
+ try { // We only want to test web handlers
+ let handler = handlers.queryElementAt(i, Ci.nsIWebHandlerApp);
+ if (handler.uriTemplate == aURITemplate)
+ return true;
+ } catch (e) { /* it wasn't a web handler */ }
+ }
+ return false;
+ },
+
+ /**
+ * See nsIWebContentHandlerRegistrar
+ */
+ registerProtocolHandler:
+ function WCCR_registerProtocolHandler(aProtocol, aURIString, aTitle, aContentWindow) {
+ LOG("registerProtocolHandler(" + aProtocol + "," + aURIString + "," + aTitle + ")");
+
+ // First, check to make sure this isn't already handled internally (we don't
+ // want to let them take over, say "chrome").
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var handler = ios.getProtocolHandler(aProtocol);
+ if (!(handler instanceof Ci.nsIExternalProtocolHandler)) {
+ // This is handled internally, so we don't want them to register
+ // XXX this should be a "security exception" according to spec, but that
+ // isn't defined yet.
+ throw("Permission denied to add " + aURIString + "as a protocol handler");
+ }
+
+ // check if it is in the black list
+ var pb = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+ var allowed;
+ try {
+ allowed = pb.getBoolPref(PREF_HANDLER_EXTERNAL_PREFIX + "." + aProtocol);
+ }
+ catch (e) {
+ allowed = pb.getBoolPref(PREF_HANDLER_EXTERNAL_PREFIX + "-default");
+ }
+ if (!allowed) {
+ // XXX this should be a "security exception" according to spec
+ throw("Not allowed to register a protocol handler for " + aProtocol);
+ }
+
+ var uri = this._checkAndGetURI(aURIString, aContentWindow);
+
+ var buttons, message;
+ if (this._protocolHandlerRegistered(aProtocol, uri.spec))
+ message = this._getFormattedString("protocolHandlerRegistered",
+ [aTitle, aProtocol]);
+ else {
+ // Now Ask the user and provide the proper callback
+ message = this._getFormattedString("addProtocolHandler",
+ [aTitle, uri.host, aProtocol]);
+ var fis = Cc["@mozilla.org/browser/favicon-service;1"].
+ getService(Ci.nsIFaviconService);
+ var notificationIcon = fis.getFaviconLinkForIcon(uri);
+ var notificationValue = "Protocol Registration: " + aProtocol;
+ var addButton = {
+ label: this._getString("addProtocolHandlerAddButton"),
+ accessKey: this._getString("addHandlerAddButtonAccesskey"),
+ protocolInfo: { protocol: aProtocol, uri: uri.spec, name: aTitle },
+
+ callback:
+ function WCCR_addProtocolHandlerButtonCallback(aNotification, aButtonInfo) {
+ var protocol = aButtonInfo.protocolInfo.protocol;
+ var uri = aButtonInfo.protocolInfo.uri;
+ var name = aButtonInfo.protocolInfo.name;
+
+ var handler = Cc["@mozilla.org/uriloader/web-handler-app;1"].
+ createInstance(Ci.nsIWebHandlerApp);
+ handler.name = name;
+ handler.uriTemplate = uri;
+
+ var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
+ getService(Ci.nsIExternalProtocolService);
+ var handlerInfo = eps.getProtocolHandlerInfo(protocol);
+ handlerInfo.possibleApplicationHandlers.appendElement(handler, false);
+
+ // Since the user has agreed to add a new handler, chances are good
+ // that the next time they see a handler of this type, they're going
+ // to want to use it. Reset the handlerInfo to ask before the next
+ // use.
+ handlerInfo.alwaysAskBeforeHandling = true;
+
+ var hs = Cc["@mozilla.org/uriloader/handler-service;1"].
+ getService(Ci.nsIHandlerService);
+ hs.store(handlerInfo);
+ }
+ };
+ buttons = [addButton];
+ }
+
+ var browserWindow = this._getBrowserWindowForContentWindow(aContentWindow);
+ var browserElement = this._getBrowserForContentWindow(browserWindow, aContentWindow);
+ var notificationBox = browserWindow.getBrowser().getNotificationBox(browserElement);
+ notificationBox.appendNotification(message,
+ notificationValue,
+ notificationIcon,
+ notificationBox.PRIORITY_INFO_LOW,
+ buttons);
+ },
+
+ /**
+ * See nsIWebContentHandlerRegistrar
+ * If a DOM window is provided, then the request came from content, so we
+ * prompt the user to confirm the registration.
+ */
+ registerContentHandler:
+ function WCCR_registerContentHandler(aContentType, aURIString, aTitle, aContentWindow) {
+ LOG("registerContentHandler(" + aContentType + "," + aURIString + "," + aTitle + ")");
+
+ // We only support feed types at present.
+ // XXX this should be a "security exception" according to spec, but that
+ // isn't defined yet.
+ var contentType = this._resolveContentType(aContentType);
+ if (contentType != TYPE_MAYBE_FEED)
+ return;
+
+ if (aContentWindow) {
+ var uri = this._checkAndGetURI(aURIString, aContentWindow);
+
+ var browserWindow = this._getBrowserWindowForContentWindow(aContentWindow);
+ var browserElement = this._getBrowserForContentWindow(browserWindow, aContentWindow);
+ var notificationBox = browserWindow.getBrowser().getNotificationBox(browserElement);
+ this._appendFeedReaderNotification(uri, aTitle, notificationBox);
+ }
+ else
+ this._registerContentHandler(contentType, aURIString, aTitle);
+ },
+
+ /**
+ * Returns the browser chrome window in which the content window is in
+ */
+ _getBrowserWindowForContentWindow:
+ function WCCR__getBrowserWindowForContentWindow(aContentWindow) {
+ return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .wrappedJSObject;
+ },
+
+ /**
+ * Returns the <xul:browser> element associated with the given content
+ * window.
+ *
+ * @param aBrowserWindow
+ * The browser window in which the content window is in.
+ * @param aContentWindow
+ * The content window. It's possible to pass a child content window
+ * (i.e. the content window of a frame/iframe).
+ */
+ _getBrowserForContentWindow:
+ function WCCR__getBrowserForContentWindow(aBrowserWindow, aContentWindow) {
+ // This depends on pseudo APIs of browser.js and tabbrowser.xml
+ aContentWindow = aContentWindow.top;
+ var browsers = aBrowserWindow.getBrowser().browsers;
+ for (var i = 0; i < browsers.length; ++i) {
+ if (browsers[i].contentWindow == aContentWindow)
+ return browsers[i];
+ }
+ },
+
+ /**
+ * Appends a notifcation for the given feed reader details.
+ *
+ * The notification could be either a pseudo-dialog which lets
+ * the user to add the feed reader:
+ * [ [icon] Add %feed-reader-name% (%feed-reader-host%) as a Feed Reader? (Add) [x] ]
+ *
+ * or a simple message for the case where the feed reader is already registered:
+ * [ [icon] %feed-reader-name% is already registered as a Feed Reader [x] ]
+ *
+ * A new notification isn't appended if the given notificationbox has a
+ * notification for the same feed reader.
+ *
+ * @param aURI
+ * The url of the feed reader as a nsIURI object
+ * @param aName
+ * The feed reader name as it was passed to registerContentHandler
+ * @param aNotificationBox
+ * The notification box to which a notification might be appended
+ * @return true if a notification has been appended, false otherwise.
+ */
+ _appendFeedReaderNotification:
+ function WCCR__appendFeedReaderNotification(aURI, aName, aNotificationBox) {
+ var uriSpec = aURI.spec;
+ var notificationValue = "feed reader notification: " + uriSpec;
+ var notificationIcon = aURI.prePath + "/favicon.ico";
+
+ // Don't append a new notification if the notificationbox
+ // has a notification for the given feed reader already
+ if (aNotificationBox.getNotificationWithValue(notificationValue))
+ return false;
+
+ var buttons, message;
+ if (this.getWebContentHandlerByURI(TYPE_MAYBE_FEED, uriSpec))
+ message = this._getFormattedString("handlerRegistered", [aName]);
+ else {
+ message = this._getFormattedString("addHandler", [aName, aURI.host]);
+ var self = this;
+ var addButton = {
+ _outer: self,
+ label: self._getString("addHandlerAddButton"),
+ accessKey: self._getString("addHandlerAddButtonAccesskey"),
+ feedReaderInfo: { uri: uriSpec, name: aName },
+
+ /* static */
+ callback:
+ function WCCR__addFeedReaderButtonCallback(aNotification, aButtonInfo) {
+ var uri = aButtonInfo.feedReaderInfo.uri;
+ var name = aButtonInfo.feedReaderInfo.name;
+ var outer = aButtonInfo._outer;
+
+ // The reader could have been added from another window mean while
+ if (!outer.getWebContentHandlerByURI(TYPE_MAYBE_FEED, uri))
+ outer._registerContentHandler(TYPE_MAYBE_FEED, uri, name);
+
+ // avoid reference cycles
+ aButtonInfo._outer = null;
+
+ return false;
+ }
+ };
+ buttons = [addButton];
+ }
+
+ aNotificationBox.appendNotification(message,
+ notificationValue,
+ notificationIcon,
+ aNotificationBox.PRIORITY_INFO_LOW,
+ buttons);
+ return true;
+ },
+
+ /**
+ * Save Web Content Handler metadata to persistent preferences.
+ * @param contentType
+ * The content Type being handled
+ * @param uri
+ * The uri of the web service
+ * @param title
+ * The human readable name of the web service
+ *
+ * This data is stored under:
+ *
+ * browser.contentHandlers.type0 = content/type
+ * browser.contentHandlers.uri0 = http://www.foo.com/q=%s
+ * browser.contentHandlers.title0 = Foo 2.0alphr
+ */
+ _saveContentHandlerToPrefs:
+ function WCCR__saveContentHandlerToPrefs(contentType, uri, title) {
+ var ps =
+ Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ var i = 0;
+ var typeBranch = null;
+ while (true) {
+ typeBranch =
+ ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + i + ".");
+ try {
+ typeBranch.getCharPref("type");
+ ++i;
+ }
+ catch (e) {
+ // No more handlers
+ break;
+ }
+ }
+ if (typeBranch) {
+ typeBranch.setCharPref("type", contentType);
+ var pls =
+ Cc["@mozilla.org/pref-localizedstring;1"].
+ createInstance(Ci.nsIPrefLocalizedString);
+ pls.data = uri;
+ typeBranch.setComplexValue("uri", Ci.nsIPrefLocalizedString, pls);
+ pls.data = title;
+ typeBranch.setComplexValue("title", Ci.nsIPrefLocalizedString, pls);
+
+ ps.savePrefFile(null);
+ }
+ },
+
+ /**
+ * Determines if there is a type with a particular uri registered for the
+ * specified content type already.
+ * @param contentType
+ * The content type that the uri handles
+ * @param uri
+ * The uri of the
+ */
+ _typeIsRegistered: function WCCR__typeIsRegistered(contentType, uri) {
+ if (!(contentType in this._contentTypes))
+ return false;
+
+ var services = this._contentTypes[contentType];
+ for (var i = 0; i < services.length; ++i) {
+ // This uri has already been registered
+ if (services[i].uri == uri)
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Gets a stream converter contract id for the specified content type.
+ * @param contentType
+ * The source content type for the conversion.
+ * @returns A contract id to construct a converter to convert between the
+ * contentType and *\/*.
+ */
+ _getConverterContractID: function WCCR__getConverterContractID(contentType) {
+ const template = "@mozilla.org/streamconv;1?from=%s&to=*/*";
+ return template.replace(/%s/, contentType);
+ },
+
+ /**
+ * Register a web service handler for a content type.
+ *
+ * @param contentType
+ * the content type being handled
+ * @param uri
+ * the URI of the web service
+ * @param title
+ * the human readable name of the web service
+ */
+ _registerContentHandler:
+ function WCCR__registerContentHandler(contentType, uri, title) {
+ this._updateContentTypeHandlerMap(contentType, uri, title);
+ this._saveContentHandlerToPrefs(contentType, uri, title);
+
+ if (contentType == TYPE_MAYBE_FEED) {
+ // Make the new handler the last-selected reader in the preview page
+ // and make sure the preview page is shown the next time a feed is visited
+ var pb = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).getBranch(null);
+ pb.setCharPref(PREF_SELECTED_READER, "web");
+
+ var supportsString =
+ Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ supportsString.data = uri;
+ pb.setComplexValue(PREF_SELECTED_WEB, Ci.nsISupportsString,
+ supportsString);
+ pb.setCharPref(PREF_SELECTED_ACTION, "ask");
+ this._setAutoHandler(TYPE_MAYBE_FEED, null);
+ }
+ },
+
+ /**
+ * Update the content type -> handler map. This mapping is not persisted, use
+ * registerContentHandler or _saveContentHandlerToPrefs for that purpose.
+ * @param contentType
+ * The content Type being handled
+ * @param uri
+ * The uri of the web service
+ * @param title
+ * The human readable name of the web service
+ */
+ _updateContentTypeHandlerMap:
+ function WCCR__updateContentTypeHandlerMap(contentType, uri, title) {
+ if (!(contentType in this._contentTypes))
+ this._contentTypes[contentType] = [];
+
+ // Avoid adding duplicates
+ if (this._typeIsRegistered(contentType, uri))
+ return;
+
+ this._contentTypes[contentType].push(new ServiceInfo(contentType, uri, title));
+
+ if (!(contentType in this._blockedTypes)) {
+ var converterContractID = this._getConverterContractID(contentType);
+ var cr = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ cr.registerFactory(WCC_CLASSID, WCC_CLASSNAME, converterContractID,
+ WebContentConverterFactory);
+ }
+ },
+
+ /**
+ * See nsIWebContentConverterService
+ */
+ getContentHandlers:
+ function WCCR_getContentHandlers(contentType, countRef) {
+ countRef.value = 0;
+ if (!(contentType in this._contentTypes))
+ return [];
+
+ var handlers = this._contentTypes[contentType];
+ countRef.value = handlers.length;
+ return handlers;
+ },
+
+ /**
+ * See nsIWebContentConverterService
+ */
+ resetHandlersForType:
+ function WCCR_resetHandlersForType(contentType) {
+ // currently unused within the tree, so only useful for extensions; previous
+ // impl. was buggy (and even infinite-looped!), so I argue that this is a
+ // definite improvement
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ /**
+ * Registers a handler from the settings on a preferences branch.
+ *
+ * @param branch
+ * an nsIPrefBranch containing "type", "uri", and "title" preferences
+ * corresponding to the content handler to be registered
+ */
+ _registerContentHandlerWithBranch: function(branch) {
+ /**
+ * Since we support up to six predefined readers, we need to handle gaps
+ * better, since the first branch with user-added values will be .6
+ *
+ * How we deal with that is to check to see if there's no prefs in the
+ * branch and stop cycling once that's true. This doesn't fix the case
+ * where a user manually removes a reader, but that's not supported yet!
+ */
+ var vals = branch.getChildList("", {});
+ if (vals.length == 0)
+ return;
+
+ try {
+ var type = branch.getCharPref("type");
+ var uri = branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
+ var title = branch.getComplexValue("title",
+ Ci.nsIPrefLocalizedString).data;
+ this._updateContentTypeHandlerMap(type, uri, title);
+ }
+ catch(ex) {
+ // do nothing, the next branch might have values
+ }
+ },
+
+ /**
+ * Load the auto handler, content handler and protocol tables from
+ * preferences.
+ */
+ _init: function WCCR__init() {
+ var ps =
+ Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+
+ var kids = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH)
+ .getChildList("", {});
+
+ // first get the numbers of the providers by getting all ###.uri prefs
+ var nums = [];
+ for (var i = 0; i < kids.length; i++) {
+ var match = /^(\d+)\.uri$/.exec(kids[i]);
+ if (!match)
+ continue;
+ else
+ nums.push(match[1]);
+ }
+
+ // sort them, to get them back in order
+ nums.sort(function(a, b) {return a - b;});
+
+ // now register them
+ for (var i = 0; i < nums.length; i++) {
+ var branch = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + nums[i] + ".");
+ this._registerContentHandlerWithBranch(branch);
+ }
+
+ // We need to do this _after_ registering all of the available handlers,
+ // so that getWebContentHandlerByURI can return successfully.
+ try {
+ var autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
+ var childPrefs = autoBranch.getChildList("", { });
+ for (var i = 0; i < childPrefs.length; ++i) {
+ var type = childPrefs[i];
+ var uri = autoBranch.getCharPref(type);
+ if (uri) {
+ var handler = this.getWebContentHandlerByURI(type, uri);
+ this._setAutoHandler(type, handler);
+ }
+ }
+ }
+ catch (e) {
+ // No auto branch yet, that's fine
+ //LOG("WCCR.init: There is no auto branch, benign");
+ }
+ },
+
+ /**
+ * See nsIObserver
+ */
+ observe: function WCCR_observe(subject, topic, data) {
+ var os =
+ Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ switch (topic) {
+ case "app-startup":
+ os.addObserver(this, "browser-ui-startup-complete", false);
+ break;
+ case "browser-ui-startup-complete":
+ os.removeObserver(this, "browser-ui-startup-complete");
+ this._init();
+ break;
+ }
+ },
+
+ /**
+ * See nsIFactory
+ */
+ createInstance: function WCCR_createInstance(outer, iid) {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return this.QueryInterface(iid);
+ },
+
+ /**
+ * See nsIClassInfo
+ */
+ getInterfaces: function WCCR_getInterfaces(countRef) {
+ var interfaces =
+ [Ci.nsIWebContentConverterService, Ci.nsIWebContentHandlerRegistrar,
+ Ci.nsIObserver, Ci.nsIClassInfo, Ci.nsIFactory, Ci.nsISupports];
+ countRef.value = interfaces.length;
+ return interfaces;
+ },
+ getHelperForLanguage: function WCCR_getHelperForLanguage(language) {
+ return null;
+ },
+ contractID: WCCR_CONTRACTID,
+ classDescription: WCCR_CLASSNAME,
+ classID: WCCR_CLASSID,
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ flags: Ci.nsIClassInfo.DOM_OBJECT,
+
+ /**
+ * See nsISupports
+ */
+ QueryInterface: XPCOMUtils.generateQI(
+ [Ci.nsIWebContentConverterService,
+ Ci.nsIWebContentHandlerRegistrar,
+ Ci.nsIObserver,
+ Ci.nsIClassInfo,
+ Ci.nsIFactory,
+ Ci.nsISupports]),
+
+ _xpcom_categories: [{
+ category: "app-startup",
+ service: true
+ }]
+};
+
+function NSGetModule(cm, file) {
+ return XPCOMUtils.generateModule([WebContentConverterRegistrar]);
+}
+
+//@line 44 "/builds/moz2_slave/linux_build/build/toolkit/content/debug.js"
+
+var EXPORTED_SYMBOLS = ["NS_ASSERT"];
+
+var gTraceOnAssert = true;
+
+/**
+ * This function provides a simple assertion function for JavaScript.
+ * If the condition is true, this function will do nothing. If the
+ * condition is false, then the message will be printed to the console
+ * and an alert will appear showing a stack trace, so that the (alpha
+ * or nightly) user can file a bug containing it. For future enhancements,
+ * see bugs 330077 and 330078.
+ *
+ * To suppress the dialogs, you can run with the environment variable
+ * XUL_ASSERT_PROMPT set to 0 (if unset, this defaults to 1).
+ *
+ * @param condition represents the condition that we're asserting to be
+ * true when we call this function--should be
+ * something that can be evaluated as a boolean.
+ * @param message a string to be displayed upon failure of the assertion
+ */
+
+function NS_ASSERT(condition, message) {
+ if (condition)
+ return;
+
+ var releaseBuild = true;
+ var defB = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService)
+ .getDefaultBranch(null);
+ try {
+ switch (defB.getCharPref("app.update.channel")) {
+ case "nightly":
+ case "beta":
+ case "default":
+ releaseBuild = false;
+ }
+ } catch(ex) {}
+
+ var caller = arguments.callee.caller;
+ var assertionText = "ASSERT: " + message + "\n";
+
+ if (releaseBuild) {
+ // Just report the error to the console
+ Components.utils.reportError(assertionText);
+ return;
+ }
+
+ // Otherwise, dump to stdout and launch an assertion failure dialog
+ dump(assertionText);
+
+ var stackText = "";
+ if (gTraceOnAssert) {
+ stackText = "Stack Trace: \n";
+ var count = 0;
+ while (caller) {
+ stackText += count++ + ":" + caller.name + "(";
+ for (var i = 0; i < caller.arguments.length; ++i) {
+ var arg = caller.arguments[i];
+ stackText += arg;
+ if (i < caller.arguments.length - 1)
+ stackText += ",";
+ }
+ stackText += ")\n";
+ caller = caller.arguments.callee.caller;
+ }
+ }
+
+ var environment = Components.classes["@mozilla.org/process/environment;1"].
+ getService(Components.interfaces.nsIEnvironment);
+ if (environment.exists("XUL_ASSERT_PROMPT") &&
+ !parseInt(environment.get("XUL_ASSERT_PROMPT")))
+ return;
+
+ var source = null;
+ if (this.window)
+ source = this.window;
+ var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Components.interfaces.nsIPromptService);
+ ps.alert(source, "Assertion Failed", assertionText + stackText);
+}
+//@line 944 "/builds/moz2_slave/linux_build/build/browser/components/feeds/src/WebContentConverter.js"
+
diff --git a/bundles/XO/components/aboutCertError.js b/bundles/XO/components/aboutCertError.js
new file mode 100755
index 0000000..e6b2229
--- /dev/null
+++ b/bundles/XO/components/aboutCertError.js
@@ -0,0 +1,75 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is about:robots
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Flint <rflint@mozilla.com>
+ * Justin Dolske <dolske@mozilla.com>
+ * Johnathan Nightingale <johnath@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function AboutCertError() {}
+AboutCertError.prototype = {
+ classDescription: "About Cert Error",
+ contractID: "@mozilla.org/network/protocol/about;1?what=certerror",
+ classID: Components.ID("{78d2286f-de9d-47ac-9c26-e8675aedf3be}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
+
+ getURIFlags: function(aURI) {
+ return (Ci.nsIAboutModule.ALLOW_SCRIPT |
+ Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT);
+ },
+
+ newChannel: function(aURI) {
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+
+ var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
+ getService(Ci.nsIScriptSecurityManager);
+
+ var channel = ios.newChannel("chrome://browser/content/certerror/aboutCertError.xhtml",
+ null, null);
+ var principal = secMan.getCodebasePrincipal(aURI);
+
+ channel.originalURI = aURI;
+ channel.owner = principal;
+
+ return channel;
+ }
+};
+
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule([AboutCertError]);
+}
diff --git a/bundles/XO/components/aboutPrivateBrowsing.js b/bundles/XO/components/aboutPrivateBrowsing.js
new file mode 100755
index 0000000..237c770
--- /dev/null
+++ b/bundles/XO/components/aboutPrivateBrowsing.js
@@ -0,0 +1,63 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Private Browsing.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function AboutPrivateBrowsing() { }
+AboutPrivateBrowsing.prototype = {
+ classDescription: "about:privatebrowsing",
+ contractID: "@mozilla.org/network/protocol/about;1?what=privatebrowsing",
+ classID: Components.ID("{d92a18c8-234d-49e4-9936-3b7e020c29a2}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
+
+ getURIFlags: function(aURI) {
+ return Ci.nsIAboutModule.ALLOW_SCRIPT;
+ },
+
+ newChannel: function(aURI) {
+ let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ let channel = ios.newChannel("chrome://browser/content/aboutPrivateBrowsing.xhtml",
+ null, null);
+ channel.originalURI = aURI;
+ return channel;
+ }
+};
+
+function NSGetModule(compMgr, fileSpec)
+ XPCOMUtils.generateModule([AboutPrivateBrowsing]);
diff --git a/bundles/XO/components/aboutRights.js b/bundles/XO/components/aboutRights.js
new file mode 100755
index 0000000..05e1c27
--- /dev/null
+++ b/bundles/XO/components/aboutRights.js
@@ -0,0 +1,73 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is about:robots.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Flint <rflint@mozilla.com>
+ * Justin Dolske <dolske@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function AboutRights() {}
+AboutRights.prototype = {
+ classDescription: "about:rights",
+ contractID: "@mozilla.org/network/protocol/about;1?what=rights",
+ classID: Components.ID("{89e9da80-4c03-46a0-a357-cf77bbef98b9}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
+
+ getURIFlags: function(aURI) {
+ return (Ci.nsIAboutModule.ALLOW_SCRIPT |
+ Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT);
+ },
+
+ newChannel: function(aURI) {
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+
+ var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
+ getService(Ci.nsIScriptSecurityManager);
+
+ var channel = ios.newChannel("chrome://browser/content/aboutRights.xhtml",
+ null, null);
+ var principal = secMan.getCodebasePrincipal(aURI);
+
+ channel.originalURI = aURI;
+ channel.owner = principal;
+
+ return channel;
+ }
+};
+
+function NSGetModule(compMgr, fileSpec)
+ XPCOMUtils.generateModule([AboutRights]);
diff --git a/bundles/XO/components/aboutRobots.js b/bundles/XO/components/aboutRobots.js
new file mode 100755
index 0000000..5d75f7b
--- /dev/null
+++ b/bundles/XO/components/aboutRobots.js
@@ -0,0 +1,73 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is About:IceCream.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ryan Flint <rflint@mozilla.com>
+ * Justin Dolske <dolske@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function AboutRobots() {}
+AboutRobots.prototype = {
+ classDescription: "About Robots",
+ contractID: "@mozilla.org/network/protocol/about;1?what=robots",
+ classID: Components.ID("{e18da21c-a4b8-4be5-98aa-942e1e19f35c}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
+
+ getURIFlags: function(aURI) {
+ return (Ci.nsIAboutModule.ALLOW_SCRIPT |
+ Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT);
+ },
+
+ newChannel: function(aURI) {
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+
+ var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
+ getService(Ci.nsIScriptSecurityManager);
+
+ var channel = ios.newChannel("chrome://browser/content/aboutRobots.xhtml",
+ null, null);
+ var principal = secMan.getCodebasePrincipal(aURI);
+
+ channel.originalURI = aURI;
+ channel.owner = principal;
+
+ return channel;
+ }
+};
+
+function NSGetModule(compMgr, fileSpec)
+ XPCOMUtils.generateModule([AboutRobots]);
diff --git a/bundles/XO/components/aboutSessionRestore.js b/bundles/XO/components/aboutSessionRestore.js
new file mode 100755
index 0000000..82d3069
--- /dev/null
+++ b/bundles/XO/components/aboutSessionRestore.js
@@ -0,0 +1,63 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the nsSessionStore component.
+ *
+ * The Initial Developer of the Original Code is
+ * Simon BĂĽnzli <zeniko@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function AboutSessionRestore() { }
+AboutSessionRestore.prototype = {
+ classDescription: "about:sessionrestore",
+ contractID: "@mozilla.org/network/protocol/about;1?what=sessionrestore",
+ classID: Components.ID("{7c65e6f0-7605-11dd-ad8b-0800200c9a66}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
+
+ getURIFlags: function(aURI) {
+ return Ci.nsIAboutModule.ALLOW_SCRIPT;
+ },
+
+ newChannel: function(aURI) {
+ let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ let channel = ios.newChannel("chrome://browser/content/aboutSessionRestore.xhtml",
+ null, null);
+ channel.originalURI = aURI;
+ return channel;
+ }
+};
+
+function NSGetModule(compMgr, fileSpec)
+ XPCOMUtils.generateModule([AboutSessionRestore]);
diff --git a/bundles/XO/components/browser.xpt b/bundles/XO/components/browser.xpt
new file mode 100755
index 0000000..f9e5b57
--- /dev/null
+++ b/bundles/XO/components/browser.xpt
Binary files differ
diff --git a/bundles/XO/components/compreg.dat b/bundles/XO/components/compreg.dat
new file mode 100755
index 0000000..de5d6f9
--- /dev/null
+++ b/bundles/XO/components/compreg.dat
@@ -0,0 +1,1943 @@
+Generated File. Do not edit.
+
+[HEADER]
+Version,0,5
+
+[COMPONENTS]
+rel:libbrowserdirprovider.so,1253014814000
+rel:libimgicon.so,1253014814000
+rel:FeedProcessor.js,1253014816000
+rel:nsSessionStore.js,1253014816000
+rel:WebContentConverter.js,1253014814000
+rel:libnkgnomevfs.so,1253014815000
+rel:libdbusservice.so,1253014816000
+rel:nsProxyAutoConfig.js,1253014815000
+rel:nsSearchService.js,1253014816000
+rel:aboutSessionRestore.js,1253014815000
+rel:nsSetDefaultBrowser.js,1253014816000
+rel:nsHandlerService.js,1253014815000
+rel:libbrowsercomps.so,1253014815000
+rel:nsBlocklistService.js,1253014815000
+rel:nsContentPrefService.js,1253014815000
+rel:nsAddonRepository.js,1253014815000
+rel:nsBadCertHandler.js,1253014814000
+rel:nsPlacesDBFlush.js,1253014816000
+rel:nsUrlClassifierLib.js,1253014815000
+rel:nsURLFormatter.js,1253014816000
+rel:txEXSLTRegExFunctions.js,1253014816000
+rel:fuelApplication.js,1253014816000
+rel:aboutRobots.js,1253014814000
+rel:nsLivemarkService.js,1253014816000
+rel:nsSessionStartup.js,1253014814000
+rel:nsHelperAppDlg.js,1253014814000
+rel:nsDefaultCLH.js,1253014814000
+rel:FeedConverter.js,1253014815000
+rel:nsContentDispatchChooser.js,1253014816000
+rel:nsUrlClassifierListManager.js,1253014815000
+rel:nsExtensionManager.js,1253014815000
+rel:storage-Legacy.js,1253014814000
+rel:nsPlacesTransactionsService.js,1253014815000
+rel:pluginGlue.js,1253014816000
+rel:FeedWriter.js,1253014815000
+rel:nsTaggingService.js,1253014816000
+rel:nsSafebrowsingApplication.js,1253014815000
+rel:NetworkGeolocationProvider.js,1253014814000
+rel:aboutCertError.js,1253014815000
+rel:nsTryToClose.js,1253014814000
+rel:nsDownloadManagerUI.js,1253014814000
+rel:nsFilePicker.js,1253014815000
+rel:nsLoginManagerPrompter.js,1253014816000
+rel:nsPrivateBrowsingService.js,1253014816000
+rel:nsLoginInfo.js,1253014816000
+rel:libmozgnome.so,1253014815000
+rel:aboutPrivateBrowsing.js,1253014814000
+rel:storage-mozStorage.js,1253014815000
+rel:nsBrowserContentHandler.js,1253014815000
+rel:nsMicrosummaryService.js,1253014815000
+rel:nsBrowserGlue.js,1253014816000
+rel:jsconsole-clhandler.js,1253014814000
+rel:nsWebHandlerApp.js,1253014816000
+rel:aboutRights.js,1253014816000
+rel:nsSidebar.js,1253014815000
+rel:nsLoginManager.js,1253014814000
+rel:nsSearchSuggestions.js,1253014816000
+rel:nsUpdateService.js,1253014816000
+
+[CLASSIDS]
+{bfc310d2-38a0-11d3-8cd3-0060b0fc14a3},,application/x-mozilla-static,,nsLayoutModule
+{a7f800e0-4306-11d4-98d0-001083010e9b},@mozilla.org/uriloader/external-helper-app-service;1,application/x-mozilla-static,Netscape External Helper App Service,docshell_provider
+{75656ad9-bd13-4c5d-939a-ec6351eea0cc},,application/x-mozilla-static,,nsComposerModule
+{ba6151ad-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{8df290ae-dcaa-4c11-98a5-2429a4dc97bb},,text/javascript,,rel:nsContentPrefService.js
+{495eca42-0a5c-11d4-a135-005004832142},,application/x-mozilla-static,,nsUConvModule
+{0cd233e0-7a86-11d3-915c-006008a6edf6},,application/x-mozilla-static,,nsI18nModule
+{73bb7c12-dbab-4ae2-aecf-a0331dec916f},,application/x-mozilla-static,,nsUCvMathModule
+{cb6593e0-f9b2-11d2-bdd6-000064657374},@mozilla.org/js/xpc/XPConnect;1,application/x-mozilla-static,,xpconnect
+{e768ebef-70f9-4fe3-8835-4f4f3fd996e2},,application/x-mozilla-static,,nsUCvMathModule
+{229fa115-9412-4d32-baf3-2fc407f76fb1},,text/javascript,,rel:FeedConverter.js
+{4bfaa9f0-1dd2-11b2-afae-a82cbaa0b606},,application/x-mozilla-static,,PKI
+{f1299dc2-1dd1-11b2-a347-ee6b7660e048},,application/x-mozilla-static,,JavaScript_Debugger
+{77da64d3-7458-4920-9491-86cc9914f904},,text/javascript,,rel:NetworkGeolocationProvider.js
+{0de2fbfa-6b7f-11d7-bbba-0003938a9d96},,application/x-mozilla-static,,nsLayoutModule
+{5eb7c3c1-ec1f-4007-87cc-eefb37d68ce6},,application/x-mozilla-static,,nsToolkitCompsModule
+{6394eeae-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{d4f2b600-b5c1-11d6-b483-cc97c63e567c},,application/x-mozilla-static,,nsLayoutModule
+{27f0682c-ff64-4dd2-ae7a-668e59f2fd38},,application/x-mozilla-static,,nsImageLib2Module
+{748a1132-671a-409a-8d1d-f1cdf6b3a6b4},,application/x-mozilla-static,,nsI18nModule
+{fcacef24-2b40-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{a496d0a2-dff7-4e23-bd65-1ca742fa178a},,application/x-mozilla-static,,NSS
+{2d524fd3-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{8323fad0-2102-11d4-8142-000064657374},,application/x-mozilla-static,,nsParserModule
+{16786594-0296-4471-8096-8f84497ca428},,application/x-mozilla-static,,NSS
+{a5570462-1dd1-11b2-9d19-df30a27fbdc4},,application/x-mozilla-static,,nsFileViewModule
+{c0773e90-5799-4eff-ad03-3ebcd85624ac},,application/x-mozilla-static,,RemoteServiceModule
+{ba6151ba-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{f7fa4581-238e-11d5-a73c-ab64fb68f2bc},,application/x-mozilla-static,,embedcomponents
+{8b1ae382-51a9-4972-b930-56977a57919d},,text/javascript,,rel:nsWebHandlerApp.js
+{10f2f5f0-f103-4901-980f-ba11bd70d60d},,application/x-mozilla-static,,nsToolkitCompsModule
+{9416bfb4-1f93-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{e18da21c-a4b8-4be5-98aa-942e1e19f35c},,text/javascript,,rel:aboutRobots.js
+{be9a53ae-c7e9-11d3-8cda-0060b0fc14a3},@mozilla.org/network/file-input-stream;1,application/x-mozilla-static,nsFileInputStream,necko
+{a0f827e1-8ab6-11d5-a14b-005004832142},,application/x-mozilla-static,,nsUConvModule
+{a6cf9124-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsLayoutModule
+{d3f69889-e13a-4321-980c-a39332e21f34},,application/x-mozilla-static,,nsWidgetGtk2Module
+{05bae29d-8aef-486d-84aa-53f48f146811},,application/x-mozilla-static,,xpconnect
+{660d8ca8-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eebb-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{0c4f1ddc-1dd2-11b2-9d95-f2fdf113044b},,application/x-mozilla-static,,NSS
+{7b8556ac-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{a15789aa-8903-462b-81e9-4aa2cff4d5cb},,application/x-mozilla-static,,NSS
+{ffc08380-256c-11d5-9905-001083010e9b},,application/x-mozilla-native,,rel:libimgicon.so
+{bc0017e3-2438-47be-a567-41db58f17627},,application/x-mozilla-static,,docshell_provider
+{ff41913b-546a-4bff-9201-dc9b2c032eba},@mozilla.org/network/url-parser;1?auth=maybe,application/x-mozilla-static,nsStdURLParser,necko
+{7fa5237d-b0eb-438f-9e50-ca0166e63788},,application/x-mozilla-static,,necko
+{3c1c0163-9bd0-11d3-9d09-0050040007b2},,application/x-mozilla-static,,nsUConvModule
+{efc323e1-ec62-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{95c963b7-20b2-11db-92f6-001422106990},,text/javascript,,rel:FeedProcessor.js
+{d25e0511-2bae-11d4-9d10-0050040007b2},,application/x-mozilla-static,,nsChardetModule
+{b69155f4-a8bf-453d-8653-91d1456e1d3d},,text/javascript,,rel:nsTryToClose.js
+{7c657d14-ec5e-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eea6-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{ba61519b-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{5fcaa2c1-7ca4-4f73-a357-93e79d709376},,application/x-mozilla-static,,nsLayoutModule
+{831f8f13-7aa8-485f-b02e-77c881cc5773},,application/x-mozilla-static,,necko
+{660d8ca6-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{7294fe9c-14d8-11d5-9882-00c04fa02f40},,application/x-mozilla-static,,docshell_provider
+{ba6151a3-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{eaca2576-0d4a-11d3-9d7e-0060088f9ff7},,application/x-mozilla-static,,nsLayoutModule
+{b88a4712-eb52-4c10-9b85-bf5894b510f0},,application/x-mozilla-static,,nsLayoutModule
+{6a4d4c1e-a74a-4320-8124-16233a0183d6},,application/x-mozilla-static,,nsSoftwareUpdate
+{ba6151b2-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{0c351177-0159-4500-86b0-a219dfde4258},,application/x-mozilla-static,,nsLayoutModule
+{495eca47-0a5c-11d4-a135-005004832142},,application/x-mozilla-static,,nsUConvModule
+{da5b130a-1dd1-11b2-ad47-f455b1814a78},,application/x-mozilla-static,,nsGfxModule
+{3ff8fb9f-ee63-48df-89f0-dace0242fd82},,application/x-mozilla-static,,necko
+{02bf7a2a-39d8-4a23-a50c-2cbb085ab7a5},,application/x-mozilla-static,,necko
+{98d41c21-ccf3-11d2-b3b1-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{6803cac5-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{a62af1ba-79b3-4896-8aaf-b148bfce4280},,application/x-mozilla-static,,necko
+{18c2f98d-b09f-11d2-bcde-00805f0e1353},,application/x-mozilla-static,,nsSoftwareUpdate
+{fb0bbc5c-452e-4783-b32c-80124693d871},,application/x-mozilla-static,,NSS
+{e3fa9d0a-1dd1-11b2-bdef-8c720b597445},,application/x-mozilla-static,,nsToolkitCompsModule
+{660d8ca0-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eeb3-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{ba6151b7-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{019718e3-cdb5-11d2-8d3c-000000000000},,application/x-mozilla-static,,nsLayoutModule
+{7b8556a4-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{9fe5d975-09bd-44aa-a01a-66402ea28657},,application/x-mozilla-static,,mozSpellCheckerModule
+{ea06d4e2-2b3d-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{2d524fd8-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{c31f4883-839b-45f6-82ad-a6a9bc5ad599},,text/javascript,,rel:nsPrivateBrowsingService.js
+{12bb8f17-2389-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsChardetModule
+{6b8bdffc-3394-417d-be83-a81b7c0f63bf},,application/x-mozilla-static,,docshell_provider
+{ea06d4e6-2b3d-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{de9472d0-8034-11d3-9399-00104ba0fd40},,application/x-mozilla-static,,necko
+{c0844a84-5a12-4808-80a8-809cb002bb4f},,text/javascript,,rel:nsPlacesTransactionsService.js
+{5060b803-340e-11d5-be5b-b3e063ec6a3c},,application/x-mozilla-static,,nsFindComponent
+{a6cf9107-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsParserModule
+{21dd6a02-413c-11d3-b3c3-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{c5de4da2-d667-42d2-b8c2-efdbcf3302ef},,application/x-mozilla-static,,nsUConvModule
+{57cf9383-3405-11d5-be5b-aa20fa2cf37c},,application/x-mozilla-static,,embedcomponents
+{9445791f-fa4c-4669-b174-df5032bb67b3},,application/x-mozilla-static,,necko
+{ccd0e960-7947-4635-b70e-4c661b63d675},,application/x-mozilla-static,,necko
+{9b6dc177-a2e4-49e1-9c98-0a8384de7f6c},,application/x-mozilla-native,,rel:libnkgnomevfs.so
+{a6cf9129-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsWidgetGtk2Module
+{2f977d53-5485-11d4-87e2-0010a4e75ef2},,application/x-mozilla-static,,nsWidgetGtk2Module
+{d4214e92-fb94-11d2-bdd8-00104bde6048},,application/x-mozilla-static,,nsRDFModule
+{c401eb80-f9ea-11d3-bb6f-e732b73ebe7c},,application/x-mozilla-static,,nsWidgetGtk2Module
+{aa892eb4-ffbf-477d-9f9a-06c995ae9f27},,text/javascript,,rel:nsSearchSuggestions.js
+{24f92fae-f793-473b-8061-713408bd11d5},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{ba6151aa-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{ce02d538-0217-47a3-a589-b51790fdd8ce},,application/x-mozilla-static,,docshell_provider
+{2587e382-1324-11d4-a652-eadbb2be3484},,application/x-mozilla-static,,application
+{2b026890-5a2e-4981-ada2-a600358947b4},,application/x-mozilla-static,,nsUConvModule
+{214c48a0-b57f-11d4-959c-0020183bf181},,application/x-mozilla-static,,docshell_provider
+{74b7a390-3b41-11d4-8a80-006008c844c3},,application/x-mozilla-static,,NSS
+{22117140-9c6e-11d3-aaf1-00805f8a4905},,text/javascript,,rel:nsSidebar.js
+{9de95a0c-39a4-4d64-9a53-17940dd7cabb},,application/x-mozilla-static,,nsPlacesModule
+{66856477-6596-40eb-bb87-59ca2dabb6f7},,application/x-mozilla-static,,nsLayoutModule
+{892ffeb0-3f80-11d3-a16c-0050041caf44},,application/x-mozilla-static,,necko
+{929d9320-251e-11d4-8a7c-006008c844c3},,application/x-mozilla-static,,NSS
+{1f4dbcf7-245c-4c8c-943d-8a1da0495e8a},,application/x-mozilla-static,,necko
+{eab9012e-5f74-4cbc-b2b5-a590235513cc},,text/javascript,,rel:nsBrowserGlue.js
+{6394eeab-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{ab1da296-6125-40ba-96d0-47a8282ae3db},,application/x-mozilla-static,,nsParserModule
+{4ca3c946-5408-49f0-9eca-3a97d5c67750},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{f30bc0a2-958b-4287-bf62-ce38ba0c811e},,application/x-mozilla-static,,docshell_provider
+{66634f68-be19-42d0-a4ca-d1c21fa059b8},,application/x-mozilla-static,,nsUConvModule
+{2d524fd0-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{ff8780a5-bbb1-4bc5-8ee7-057e7bc5c925},,application/x-mozilla-static,,nsUConvModule
+{2002f784-3960-11d3-b3c3-00805f8a6670},,application/x-mozilla-static,,nsChardetModule
+{2d96b3d0-c051-11d1-a827-0040959a28c9},,application/x-mozilla-static,,nsWidgetGtk2Module
+{4a68cee9-6f07-4950-b441-a1ce6a082e2f},,application/x-mozilla-static,,nsCJVMManagerModule
+{26acb1f0-28fc-43bc-867a-a46aabc85dd4},,text/javascript,,rel:FeedProcessor.js
+{ff8fe7ec-2f74-4408-b742-6b7a546029a8},,application/x-mozilla-static,,necko
+{62db0002-dbb6-43f4-8fb7-9d2538bc5747},,application/x-mozilla-static,,nsComposerModule
+{5b256c10-22d8-4109-af92-1253035e9fcb},,application/x-mozilla-static,,NSS
+{b57f97c1-0d70-11d3-8aae-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{db340cc2-7f50-4ea3-8427-f529daf6dc87},,application/x-mozilla-static,,satchel
+{7b8556a9-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{78d2286f-de9d-47ac-9c26-e8675aedf3be},,text/javascript,,rel:aboutCertError.js
+{439400d3-6f23-43db-8b06-8aafe1869bd8},,application/x-mozilla-static,,necko
+{a578e0a4-f76b-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{9416bfb1-1f93-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{78804a84-8173-42b6-bb94-789f0816a810},@mozilla.org/network/url-parser;1?auth=no,application/x-mozilla-static,nsNoAuthURLParser,necko
+{bfd1a792-ad9f-11d3-bdc7-0050040a9b44},,application/x-mozilla-static,,docshell_provider
+{6803caca-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{a47e9526-6e48-4574-9d6c-3164e271f74e},,application/x-mozilla-static,,nsLayoutModule
+{948a0023-e3a7-11d2-96cf-0060b0fb9956},,application/x-mozilla-static,,nsWidgetGtk2Module
+{8dbe7246-1dd2-11b2-9b8f-b9a849e4403a},,application/x-mozilla-static,,necko
+{8b5314ba-db01-11d2-96ce-0060b0fb9956},,application/x-mozilla-static,,nsWidgetGtk2Module
+{50e95301-17a8-11d4-9f7e-dd530d5f057c},,application/x-mozilla-static,,nsComposerModule
+{7d7008a0-c49a-11d3-9b22-0080c7cb1080},,application/x-mozilla-static,,necko
+{77cfaaf1-1cf4-11d3-8aaf-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eeb8-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{0099907d-123c-4853-a46a-43098b5fb68c},,application/x-mozilla-static,,appshell
+{cb60980e-18a5-4a77-9110-8146614ca7f0},,application/x-mozilla-static,,nsFileViewModule
+{ba6151a2-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{379c2771-ec77-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{8a115faa-7dcb-4e8f-979b-5f53472f51cf},,text/javascript,,rel:nsExtensionManager.js
+{49b38f14-6193-11d3-b3c5-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{12bb8f1c-2389-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{e6fd9940-899d-11d2-8eae-00805f29f370},,application/x-mozilla-static,,nsLayoutModule
+{9226888e-da08-11d3-8cda-0060b0fc14a3},,application/x-mozilla-static,,necko
+{093c2356-4843-4c65-8709-d7dbcbbe7dfb},,text/javascript,,rel:nsUpdateService.js
+{3a9cd622-264d-11d4-ba06-0060b0fc76dd},,application/x-mozilla-static,,nsLayoutModule
+{3b581fd4-3497-426c-8f61-3658b971cb80},,application/x-mozilla-static,,nsLayoutModule
+{36a1d3b3-d886-4317-96ff-87b0005cfef7},,application/x-mozilla-static,,NSS
+{bf88b48c-fd8e-40b4-ba36-c7c3ad6d8ac9},,application/x-mozilla-static,,embedcomponents
+{aa699204-1dd1-11b2-84a9-a280c268e4fb},,application/x-mozilla-static,,nsGfxModule
+{920307b0-c6e8-11d2-8aa8-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{7c657d11-ec5e-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eea3-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{9416bfbe-1f93-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{2bf64764-997f-450d-af96-3028d1a902b0},,application/x-mozilla-static,,nsI18nModule
+{fcacef23-2b40-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{0885d4f8-f7b8-4cda-902e-94ba38bc256e},,application/x-mozilla-static,,necko
+{7c02eadc-0076-4d03-998d-80d779c48589},,application/x-mozilla-static,,nsSecurityManagerModule
+{895db6c7-dbdf-40ea-9f64-b175033243dc},,application/x-mozilla-static,,satchel
+{e12752f0-ee9a-11d1-a82a-0040959a28c9},,application/x-mozilla-static,,nsGfxModule
+{47049e42-1d87-482a-984d-56ae185e367a},,application/x-mozilla-static,,nsChromeModule
+{c1751cfc-e8f1-4ade-b0bb-f74edfb8ef6a},,text/javascript,,rel:nsPlacesDBFlush.js
+{ba6151af-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{495eca44-0a5c-11d4-a135-005004832142},,application/x-mozilla-static,,nsUConvModule
+{972d8d8f-f0da-11d4-9885-00c04fa0cf4b},,application/x-mozilla-static,,nsLayoutModule
+{56388dad-287b-4240-a785-85c394012503},,application/x-mozilla-static,,necko
+{0f78da56-8321-11d2-8eac-00805f29f370},,application/x-mozilla-static,,nsRDFModule
+{e56f5e01-c7cc-4675-a9d7-b8f1e4127295},,application/x-mozilla-static,,docshell_provider
+{6394eec0-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{0404d02a-01ca-aaab-4762-944b1bf2f7b5},,application/x-mozilla-static,,nsLayoutModule
+{898cdc9b-e43f-422f-9cc4-2f6291b415a3},,text/javascript,,rel:nsUpdateService.js
+{a35d1cd4-c505-4d2d-a0f9-aef00b7ce5a5},,application/x-mozilla-static,,nsLayoutModule
+{0032d852-1dd2-11b2-95f7-e0a1910ed2da},,application/x-mozilla-static,,nsRDFModule
+{87ed1160-e2f2-11d3-b32f-004005a7a7e4},,application/x-mozilla-static,,nsUCvMathModule
+{6394eeb0-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{7b8556a1-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{0cb0d9a0-f503-11d3-b32f-004005a7a7e4},,application/x-mozilla-static,,nsUCvMathModule
+{a59da935-4091-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{3f6fe6a2-ac0a-11d2-b3ae-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{2d524fd5-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{e332db00-e076-11d3-b32f-004005a7a7e4},,application/x-mozilla-static,,nsUCvMathModule
+{3decd6c8-30ef-11d3-8cd0-0060b0fc14a3},,application/x-mozilla-static,,necko
+{e8b8bdb7-c96c-4d82-9c6f-2b3c585ec7ea},,application/x-mozilla-static,,nsPlacesModule
+{ba6151bc-ec62-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{e6a3f533-4ffa-4615-8eb4-d4e72d883fa7},,text/javascript,,rel:nsContentPrefService.js
+{2e9b69dd-9087-438c-8b5d-f77b553abefb},,application/x-mozilla-static,,docshell_provider
+{e64f152a-9f07-11d3-8cda-0060b0fc14a3},@mozilla.org/network/protocol;1?name=resource,application/x-mozilla-static,nsResProtocolHandler,necko
+{26a4a019-2827-4a89-a85c-5931a678823a},,text/javascript,,rel:nsUrlClassifierLib.js
+{4a6212db-accb-11d3-b765-0060b0b6cecb},,application/x-mozilla-static,,nsSecurityManagerModule
+{bbbb1d61-438f-4436-92ed-8308e5830fb0},,application/x-mozilla-static,,mozStorageModule
+{7319788a-fe93-4db3-9f39-818cf08f4256},,text/javascript,,rel:nsSearchService.js
+{841387c8-72e6-484b-9296-bf6eea80d58a},,application/x-mozilla-static,,nsWidgetGtk2Module
+{7fbd2146-5ff4-4674-b069-a7bbce66e773},,application/x-mozilla-static,,nsComposerModule
+{d0f9db12-249c-11d5-9905-001083010e9b},,application/x-mozilla-native,,rel:libimgicon.so
+{6803cacf-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{ed0244e0-c144-11d2-8f4c-006008159b0c},,application/x-mozilla-static,,nsLayoutModule
+{14632191-ac21-4bdf-83e7-2363ad17e838},,application/x-mozilla-static,,nsLayoutModule
+{a6cf9126-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsLayoutModule
+{5f43022c-6194-4b37-b26d-e41024625264},,application/x-mozilla-native,,rel:libmozgnome.so
+{4d977f60-fbe7-4583-8cb7-f5ed882293ef},,application/x-mozilla-static,,nsLayoutModule
+{c2710d40-6f4d-4b7f-9778-76ae5166648c},,application/x-mozilla-static,,nsLayoutModule
+{6394eebd-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{7b8556ae-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{379c2776-ec77-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{ea617873-3b73-4efd-a2c4-fc39bfab809d},,application/x-mozilla-static,,necko
+{f6d5ebbd-34f4-487d-9d10-3d34123e3eb9},,application/x-mozilla-static,,tkAutoCompleteModule
+{6987230e-0098-4e78-bc5f-1493ee7519fa},,application/x-mozilla-static,,nsWidgetGtk2Module
+{f01cb3e7-4ace-414e-a2b7-eaba03e9c86c},,application/x-mozilla-static,,nsUCvMathModule
+{af7a9952-aa48-11d2-b3ae-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{8c2023b9-175c-477e-9761-44ae7b549756},,text/javascript,,rel:storage-mozStorage.js
+{4ca6b67b-5cc7-4e71-a98a-97af1c134862},,application/x-mozilla-static,,nsPermissionsModule
+{64f300a1-c88c-11d3-97fb-00400553eef0},,application/x-mozilla-static,,nsLayoutModule
+{a4bd2161-7892-4389-8d5a-3111a6d17ec7},,application/x-mozilla-static,,PKI
+{66230b2b-17fa-4bd3-abf4-07986151022d},,application/x-mozilla-static,,necko
+{1dcc23b0-d4cb-11dc-9ad6-479d56d89593},,text/javascript,,rel:nsTaggingService.js
+{5d0fcdd0-4daa-11d2-b328-00805f8a3859},,application/x-mozilla-static,,nsLayoutModule
+{a431b276-f77d-4b83-9b37-872cf2fbcc2a},,application/x-mozilla-static,,nsUConvModule
+{8f666a11-04a0-11d3-b3b9-00805f8a6670},,application/x-mozilla-static,,nsI18nModule
+{1cd91b88-1dd2-11b2-92e1-ed22ed298000},@mozilla.org/preferences-service;1,application/x-mozilla-static,Preferences Server,nsPrefModule
+{dab3a846-3a59-4fc2-9745-c6ff48776f00},,application/x-mozilla-static,,mozStorageModule
+{6394eea8-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{0958b101-9ada-11d2-8ebc-00805f29f370},,application/x-mozilla-static,,nsRDFModule
+{9158c470-86e4-11d4-9be2-00e09872a416},,application/x-mozilla-static,,necko
+{b9507aec-1dd1-11b2-8cd5-c48ee0c50307},,application/x-mozilla-static,,NSS
+{c64d0bcb-8270-4ca7-a0b3-3380c8ffecb5},,text/javascript,,rel:nsSafebrowsingApplication.js
+{b6ed3030-6183-11d3-a178-0050041caf44},,application/x-mozilla-static,,necko
+{c07e81e0-ef12-11d2-92b6-00105a1b0d64},@mozilla.org/network/socket-transport-service;1,application/x-mozilla-static,nsSocketTransportService,necko
+{64d6174c-1496-4ffd-87f2-da2670f88934},,application/x-mozilla-static,,mozSpellCheckerModule
+{fb5c1775-1bbd-4b9c-abb0-ae7acd29e87e},,application/x-mozilla-static,,nsLayoutModule
+{2002f781-3960-11d3-b3c3-00805f8a6670},,application/x-mozilla-static,,nsChardetModule
+{1f34bc80-1bc7-11d6-a384-d705dd0746fc},,application/x-mozilla-static,,nsLayoutModule
+{ba61519a-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{35b2656c-4102-4bc1-876a-fd6cb830787b},,application/x-mozilla-static,,nsLayoutModule
+{8b042e22-6f87-11d3-b3c8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{4dc30689-929d-425e-a709-082c6294e542},,application/x-mozilla-static,,nsLayoutModule
+{ba6151b4-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{660d8ca5-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{4f6b5e00-0c36-11d5-a535-0010a401eb10},,application/x-mozilla-static,,nsCookieModule
+{495eca49-0a5c-11d4-a135-005004832142},,application/x-mozilla-static,,nsUConvModule
+{a578e0a1-f76b-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{aeb8936f-219c-4d3c-8385-d9382daa551a},,application/x-mozilla-static,,mozSpellCheckerModule
+{63c7b9f4-0cc8-43f8-b666-0a661655cb73},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{bacd8ad0-552f-11d3-a9f7-000064657374},,application/x-mozilla-static,,nsLayoutModule
+{6803cac7-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{0bec75a8-1dd2-11b2-863a-f69f77c31371},,application/x-mozilla-static,,PKI
+{d5eb483c-67c0-4286-a4a6-330e58a82300},,application/x-mozilla-static,,nsUCvMathModule
+{9286e71a-621a-4b91-851e-9984c1a2e81a},,application/x-mozilla-static,,nsLayoutModule
+{0704e7c0-a758-11d2-9119-006008a6edf6},,application/x-mozilla-static,,nsI18nModule
+{4aef38b7-6364-4e23-a5e7-12f837fbbd9c},,application/x-mozilla-static,,nsLayoutModule
+{660d8ca2-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eeb5-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{7b8556a6-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{ba61519f-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{5d5d92cd-6bf8-11d9-bf4a-000a95dc234c},,application/x-mozilla-static,,nsLayoutModule
+{2d524fda-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{7baf62e0-8e61-11d2-8eb1-00805f29f370},,application/x-mozilla-static,,nsRDFModule
+{136e2c4d-c5a4-477c-b131-d93d7d704f64},@mozilla.org/privatebrowsing-wrapper;1,application/x-mozilla-native,PrivateBrowsing Service C++ Wrapper,rel:libbrowsercomps.so
+{0f2f347c-1e4f-40cc-8efd-792dea70a85e},,text/javascript,,rel:nsLoginInfo.js
+{2ee83680-2af0-4bcb-bfa0-c9705f6554f1},,application/x-mozilla-static,,docshell_provider
+{414af362-9ad8-4296-898e-62247f25a20e},,text/javascript,,rel:FeedProcessor.js
+{2d524fdd-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{aaab6710-0f2c-11d5-a53b-0010a401eb10},,application/x-mozilla-static,,necko
+{e9b301c0-e0e4-11d3-a1a8-0050041caf44},,application/x-mozilla-static,,necko
+{77cfaaf2-1cf4-11d3-8aaf-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{d9b1f97e-cfa0-80b6-fb92-9972e48e3dcc},,application/x-mozilla-static,,nsUConvModule
+{929814d6-1dd2-11b2-8e08-82fa0a339b00},,application/x-mozilla-static,,xpconnect
+{ba5bc4c6-1dd1-11b2-bb89-b844c6ec0339},,application/x-mozilla-static,,nsAutoConfigModule
+{e7caf8c0-3570-47fe-aa1b-da47539b5d07},,application/x-mozilla-static,,NSS
+{ea06d4e5-2b3d-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{2f277c00-0eaf-4ddb-b936-41326ba48aae},,application/x-mozilla-static,,necko
+{1423e739-782c-4081-b5d8-fe6fba68c0ef},,application/x-mozilla-static,,necko
+{ecea1b28-ae54-4047-8bbe-c624235106b4},,application/x-mozilla-static,,nsLayoutModule
+{0ae53c0f-8ea2-4916-bedc-717443c3e185},,application/x-mozilla-static,,NSS
+{0ddf4df8-4dbb-4133-8b79-9afb966514f5},,application/x-mozilla-static,,nsLayoutModule
+{dbfd145d-3298-4f3c-902f-2c5e1a1494ce},,application/x-mozilla-static,,nsImageLib2Module
+{ba6151ac-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{cb3ede1a-0fa5-4e27-aafe-0f7801e5a1f1},,application/x-mozilla-static,,nsImageLib2Module
+{c94f4a30-64d7-11d4-9960-00b0d02354a0},,application/x-mozilla-static,,NSS
+{56ad2981-8a87-11d2-918c-0080c8e44db5},,application/x-mozilla-static,,nsLayoutModule
+{822bcd11-6432-48be-9e9d-36f7804b7747},,application/x-mozilla-static,,nsCookieModule
+{b3c290a6-3943-4b89-8bbe-c01eb7b3b311},,text/javascript,,rel:nsUpdateService.js
+{6ddb050c-0d04-11d4-986e-00c04fa0cf4a},,application/x-mozilla-static,,necko
+{1691e1f4-ee41-11d4-9885-00c04fa0cf4b},,application/x-mozilla-static,,nsLayoutModule
+{379c2774-ec77-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{a6cf90f5-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsLayoutModule
+{49bb6593-3aff-4eb3-a068-2712c28bd58e},,text/javascript,,rel:FeedWriter.js
+{e6156350-2be8-11db-a98b-0800200c9a66},,text/javascript,,rel:nsURLFormatter.js
+{6394eead-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{42c52b81-a200-11d3-9d0b-0050040007b2},,application/x-mozilla-static,,nsXPIntlModule
+{5d0cfa97-69dd-4e5e-ac84-f253162e8f9a},,text/javascript,,rel:FeedProcessor.js
+{a59da932-4091-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{bfcb82c2-5611-4318-90d6-baf4a7864252},,application/x-mozilla-static,,nsLayoutModule
+{9d3f70da-86e9-11d4-95ec-00b0d03e37b7},,application/x-mozilla-static,,nsLayoutModule
+{2d524fd2-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{a2112d6a-0e28-421f-b46a-25c0b308cbd0},,application/x-mozilla-static,,embedcomponents
+{2ce606b0-bee6-11d1-aad9-00805f8a3e14},,application/x-mozilla-static,,nsParserModule
+{7526a738-9632-11d3-8cd9-0060b0fc14a3},,application/x-mozilla-static,,nsJarModule
+{ff8c4d10-3194-11d3-9885-006008962422},@mozilla.org/js/xpc/ContextStack;1,application/x-mozilla-static,,xpconnect
+{d2800356-c2d7-4e05-a884-79fe566af1cf},,application/x-mozilla-static,,nsUConvModule
+{9868b4ce-da08-11d3-8cda-0060b0fc14a3},,application/x-mozilla-static,,necko
+{69bb8313-2d4f-45ec-97e0-d39da58ecce9},,text/javascript,,rel:nsExtensionManager.js
+{ba6151b9-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{d9b1f97f-cfa0-80b6-fb92-9972e48e3dcc},,application/x-mozilla-static,,nsUConvModule
+{bc54f001-6eb0-4e32-9f49-7e064d8e70ef},,application/x-mozilla-static,,nsAuthModule
+{26fb965c-9de6-11d3-bccc-0060b0fc76bd},,application/x-mozilla-static,,nsLayoutModule
+{2d78bbf0-e26c-482b-92b3-78a7b2afc8f7},,application/x-mozilla-static,,nsLayoutModule
+{62b778a6-bce3-456b-8c31-2865fbb68c91},@mozilla.org/network/idn-service;1,application/x-mozilla-static,nsIDNService,necko
+{9416bfb3-1f93-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{6030f7ef-32ed-46a7-9a63-6a5d3f90445f},,application/x-mozilla-static,,nsLayoutModule
+{6803cacc-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{9f6d5d40-90e7-11d3-af80-00a024ffc08c},,application/x-mozilla-static,,docshell_provider
+{8b5314bc-db01-11d2-96ce-0060b0fb9956},,application/x-mozilla-static,,nsWidgetGtk2Module
+{660d8ca7-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{7b8556a2-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{bd1326a6-5a14-48de-97cc-95b5195f4fb9},,application/x-mozilla-static,,nsUCvMathModule
+{ba6151a4-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{75c80fd0-accb-432c-af59-ec60668c3990},,application/x-mozilla-static,,nsAuthModule
+{6deb193c-f87d-4078-bc78-5e64655b4d62},,application/x-mozilla-native,,rel:libbrowserdirprovider.so
+{44588c1f-2ce8-4ad8-9b16-dfb9d9d513a7},,application/x-mozilla-static,,necko
+{45c23a20-d71c-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{a6cf9112-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsParserModule
+{f916ebfb-78ef-464b-94d0-a6f2ca3200ae},,application/x-mozilla-static,,nsWidgetGtk2Module
+{cc75499a-1dd1-11b2-8a82-ca410ac907b8},,application/x-mozilla-static,,BOOT
+{c6e8c44d-9f39-4af7-bcc0-76e38a8310f5},,text/javascript,,rel:nsBrowserGlue.js
+{7b8556b2-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{7c657d13-ec5e-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eea5-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{9416bfc0-1f93-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{2e363d60-872e-11d2-b531-000000000000},,application/x-mozilla-static,,nsLayoutModule
+{d930e29b-6909-44e5-ab4b-af10d6923705},,application/x-mozilla-static,,nsWidgetGtk2Module
+{a1b72850-a999-11d2-9119-006008a6edf6},,application/x-mozilla-static,,nsI18nModule
+{3a0a0fc1-8349-11d3-be47-00104bde6048},,application/x-mozilla-static,,nsLayoutModule
+{6049b263-c1e6-11d1-a827-0040959a28c9},,application/x-mozilla-static,,nsGfxModule
+{670ee5da-6ad5-11d7-9950-000393636592},,application/x-mozilla-static,,embedcomponents
+{ec693a6f-0832-49dd-877c-89f6552df5de},,application/x-mozilla-static,,NSS
+{dccbe7e4-7750-466b-a557-5ea36c8ff24e},,application/x-mozilla-static,,necko
+{1f59b001-02c9-11d5-ae76-cc92f7db9e03},,application/x-mozilla-static,,embedcomponents
+{ba6151b1-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{47433d1d-d9a7-4954-994f-f7a05cf87c2e},,application/x-mozilla-static,,nsUConvModule
+{cb9e0de8-3598-4ed7-857b-827f011ad5d8},,text/javascript,,rel:nsLoginManager.js
+{495eca46-0a5c-11d4-a135-005004832142},,application/x-mozilla-static,,nsUConvModule
+{0e6892c1-a9ad-11d2-b3ae-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{d4214e93-fb94-11d2-bdd8-00104bde6048},,application/x-mozilla-static,,nsRDFModule
+{58f089ee-512a-42d2-a935-d0c874128930},,application/x-mozilla-static,,nsLayoutModule
+{6316c6ce-12d3-479e-8f53-e289351412b8},@mozilla.org/intl/stringbundle/text-override;1,application/x-mozilla-static,String Textfile Overrides,nsI18nModule
+{6803cac4-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{34587f4a-be18-43c0-9112-b782b08c0add},,application/x-mozilla-static,,BOOT
+{5ba6d920-d4e9-11d3-a1a5-0050041caf44},,application/x-mozilla-static,,necko
+{822cb9ae-6421-4484-b3c3-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{6803cac9-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{1b117e16-0cad-11d4-986e-00c04fa0cf4a},,application/x-mozilla-static,,nsJarModule
+{4b664e54-72a2-4bbf-a5c2-66d4dc3066a0},,application/x-mozilla-static,,nsLayoutModule
+{8e4444ff-8e99-4bdd-aa7f-fb3c1c77319f},,text/javascript,,rel:FeedProcessor.js
+{6394eeb2-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{6803cacd-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{b992ddcd-3899-4320-9909-924b3e72c922},,text/javascript,,rel:FeedProcessor.js
+{7b8556a3-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{471f4944-1dd2-11b2-87ac-90be0a51d609},,application/x-mozilla-static,,embedcomponents
+{14c13684-1dd2-11b2-9463-bb10ba742554},,application/x-mozilla-static,,nsToolkitCompsModule
+{9c7ec5d1-23f9-11d5-aea8-8fcc0793e97f},,application/x-mozilla-static,,necko
+{2d524fd7-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{b148eed2-236d-11d3-b35c-00a0cc3c1cde},,application/x-mozilla-static,,nsWidgetGtk2Module
+{12bb8f16-2389-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsChardetModule
+{ed394ba0-5472-11d3-bbc8-0000861d1237},,application/x-mozilla-static,,necko
+{e638d761-8687-11d2-b530-000000000000},,application/x-mozilla-static,,nsRDFModule
+{54ae32f8-1dd2-11b2-a209-df7c505370f8},,text/javascript,,rel:nsFilePicker.js
+{a41661d5-1417-11d5-9882-00c04fa02f40},,application/x-mozilla-static,,docshell_provider
+{9e9b565a-8e52-4c1a-8805-b2b91655f874},,application/x-mozilla-static,,nsI18nModule
+{057b04d0-0ccf-11d2-beba-00805f8a66dc},,application/x-mozilla-static,,docshell_provider
+{0a698c44-3bff-11d4-9649-00c0ca135b4e},,application/x-mozilla-static,,nsUConvModule
+{bfd1a791-ad9f-11d3-bdc7-0050040a9b44},,application/x-mozilla-static,,docshell_provider
+{36102b6b-7b62-451a-a1c8-a0d456c92dc5},,application/x-mozilla-static,,nsSecurityManagerModule
+{ec7a6c20-e081-11da-8ad9-0800200c9a66},,text/javascript,,rel:nsSessionStartup.js
+{8aa66d77-1bbb-45a6-991e-b8f47751c291},,text/javascript,,rel:nsLoginManagerPrompter.js
+{9eb760f0-4380-11d2-b328-00805f8a3859},,application/x-mozilla-static,,nsLayoutModule
+{2e41ada0-62b7-4902-b9a6-e4542aa458ba},,application/x-mozilla-static,,embedcomponents
+{320706d2-2e81-42c6-89c3-8d83b17d3fb4},,application/x-mozilla-static,,necko
+{1f5c1721-7dc3-11d3-bf87-00105a1b0627},,application/x-mozilla-static,,nsLayoutModule
+{f1eac761-87e9-11d3-af80-00a024ffc08c},,application/x-mozilla-static,,Browser_Embedding_Module
+{40b22006-5dd5-42f2-bfe7-7dbf0757ab8b},,application/x-mozilla-static,,nsLayoutModule
+{9ef9fa14-1dd1-11b2-9d65-d72d6d1f025e},,application/x-mozilla-static,,necko
+{5632bf70-51ec-11d3-9896-006008962422},@mozilla.org/js/xpc/Exception;1,application/x-mozilla-static,,xpconnect
+{36b63ef3-e0fa-4c49-9fd4-e065e85568f4},,application/x-mozilla-static,,necko
+{6394eebf-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{ba6151a9-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{379c2778-ec77-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{dc8e21a0-03e4-11da-8cd6-0800200c9a66},,application/x-mozilla-static,,nsAuthModule
+{17491ba4-1dd2-11b2-aae3-de6b92dab620},,application/x-mozilla-static,,necko
+{d6008c40-4dad-11d2-b328-00805f8a3859},,application/x-mozilla-static,,nsLayoutModule
+{3a8a3a50-512c-11d4-9a54-000064657374},,application/x-mozilla-static,,nsLayoutModule
+{4f91ef2e-57ba-472e-ab7a-b4999e42d6c0},,text/javascript,,rel:FeedConverter.js
+{7ef2f07f-6e34-410b-8336-88acd1cd16b7},,application/x-mozilla-static,,nsLayoutModule
+{9f6a0d2e-1dd1-11b2-a5b8-951f13c846f7},,application/x-mozilla-static,,nsImageLib2Module
+{94f1de09-d0e5-4ca8-94c2-98b049316b7f},,application/x-mozilla-static,,nsSystemPrefModule
+{a4557478-ae16-11d5-ba4b-00108303b117},,application/x-mozilla-static,,NSS
+{adf42751-1cef-4ad2-aa8e-bcb849d8d31f},,application/x-mozilla-static,,nsI18nModule
+{a39e0e9d-e567-41e3-b12c-5df67f18174d},,application/x-mozilla-static,,NSS
+{fb8cbf4e-4701-4ba1-b1d6-5388e041fb67},,application/x-mozilla-static,,necko
+{feca3c34-205e-4ae5-bd1c-03c686ff012b},,application/x-mozilla-static,,nsLayoutModule
+{7c657d18-ec5e-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eeaa-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{a772eee4-0464-405d-a329-a29dfda3791a},,application/x-mozilla-static,,docshell_provider
+{549abb24-7c9d-4aba-915e-7ce0b716b32f},,application/x-mozilla-static,,nsSystemPrefModule
+{3a449110-66fd-11d4-9528-0020183bf181},,application/x-mozilla-static,,Browser_Embedding_Module
+{6fb0c970-e1b1-11db-8314-0800200c9a66},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{b5e65b52-1dd1-11b2-ae8f-f0928ed88482},@mozilla.org/js/xpc/RuntimeService;1,application/x-mozilla-static,,xpconnect
+{38d1592e-b81e-432b-86f8-471878bbfe07},,application/x-mozilla-static,,nsImageLib2Module
+{a277189c-1dd1-11b2-a8c9-e4e8bfb1338e},,application/x-mozilla-static,,NSS
+{0fa3158c-d5a7-43de-9181-a285e74cf1d4},,application/x-mozilla-static,,nsUnixProxyModule
+{2002f783-3960-11d3-b3c3-00805f8a6670},,application/x-mozilla-static,,nsChardetModule
+{6ebc941a-f2ff-4d56-b3b6-f7d0b9d73344},,text/javascript,,rel:nsDefaultCLH.js
+{1abdcc96-1dd2-11b2-b520-f8f59cdd67bc},,application/x-mozilla-static,,nsLayoutModule
+{e09af32d-2a54-4d76-9ef0-3070e83f8be7},,application/x-mozilla-static,,nsLayoutModule
+{a665e49a-f3e6-4fed-9f31-f7c568a29899},@mozilla.org/intl/unicodenormalizer;1,application/x-mozilla-static,Unicode Normlization,nsI18nModule
+{ba6151b6-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{cf0f71fd-fafd-4e2b-9fdc-134d972e16e2},,application/x-mozilla-static,,necko
+{5fb907e0-1dd2-11b2-a7c0-f14c416a62a1},,application/x-mozilla-static,,NSS
+{f66bc334-1dd1-11b2-bab2-90e04fe15c19},,application/x-mozilla-static,,Browser_Embedding_Module
+{13e50d8d-9cee-4ad1-a3a2-4a442fdf7dfa},,application/x-mozilla-static,,nsComposerModule
+{a1fde867-e802-11d4-9885-00c04fa0cf4b},,application/x-mozilla-static,,nsLayoutModule
+{a578e0a3-f76b-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{f96f5ec9-755b-447e-b1f3-717d1a84bb41},,application/x-mozilla-static,,nsLayoutModule
+{adea1880-1a8e-11d2-a82e-0040959a28c9},,application/x-mozilla-static,,nsPluginModule
+{776588a6-86d5-47e2-b6b3-992810078202},,application/x-mozilla-static,,nsUConvModule
+{f6913e2e-1dd1-11b2-84be-f455dee342af},,application/x-mozilla-static,,necko
+{a6cf9120-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsI18nModule
+{ba61519d-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{d8e716f9-c96e-4e84-ab12-980f5567e2a4},,application/x-mozilla-static,,nsPluginModule
+{660d8ca4-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eeb7-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{67ba681d-5485-4fff-952c-2ee337ffdcd6},,application/x-mozilla-static,,NSS
+{7b8556a8-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{ba6151a1-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{830b5f80-e2f2-11d3-b32f-004005a7a7e4},,application/x-mozilla-static,,nsUCvMathModule
+{d92a18c8-234d-49e4-9936-3b7e020c29a2},,text/javascript,,rel:aboutPrivateBrowsing.js
+{2d524fdc-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{cc10c750-9ec3-11d2-b3ae-00805f8a6670},,application/x-mozilla-static,,nsI18nModule
+{12bb8f1b-2389-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{d9783472-8fe9-11d2-9d3c-0060088f9ff7},,application/x-mozilla-static,,nsLayoutModule
+{09f689e0-b4da-11d2-a68b-00104bde6048},,application/x-mozilla-static,,nsLayoutModule
+{eae599aa-ecef-49c6-a8af-6ddcc6feb484},,application/x-mozilla-static,,NSS
+{fcca6f83-9f7d-44e4-a74b-b59433e6c8c3},,application/x-mozilla-static,,nsLayoutModule
+{218f2ac0-0a48-11d3-b3ba-00805f8a6670},,application/x-mozilla-static,,nsChardetModule
+{6049b261-c1e6-11d1-a827-0040959a28c9},,application/x-mozilla-static,,nsGfxModule
+{663ca4a8-d219-4000-925d-d8f66406b626},,application/x-mozilla-static,,nsAccessibilityModule
+{6394eea2-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{bfd05264-834c-11d2-8eac-00805f29f370},,application/x-mozilla-static,,nsRDFModule
+{ca200860-4696-40d7-88fa-4490d423a8ef},,application/x-mozilla-static,,embedcomponents
+{2bc2ad62-ad5d-4b7b-a9db-f74ae203c527},,application/x-mozilla-static,,nsUConvModule
+{1f1ce501-663a-11d3-b7a0-be426e4e69bc},,application/x-mozilla-static,,appshell
+{3f429a14-dffe-417d-8cb8-fdf09bacd09e},,application/x-mozilla-static,,NSS
+{a2059c0e-5a58-4c55-ab7c-26f0557546ef},,application/x-mozilla-static,,satchel
+{5d0ce354-df01-421a-83fb-7ead0990c24e},,text/javascript,,rel:nsBrowserContentHandler.js
+{a61e6398-2057-40fd-9c81-873b908d24e7},,application/x-mozilla-static,,nsWidgetGtk2Module
+{8d995d4f-adcc-4159-b7f1-e94af72eeb88},,application/x-mozilla-static,,BOOT
+{2ee3039b-2de4-43d9-93b0-649beacff39a},,application/x-mozilla-static,,tkAutoCompleteModule
+{75a500a2-0030-40f7-86f8-63f225b940ae},,application/x-mozilla-native,,rel:libdbusservice.so
+{67671792-8e25-4487-b1b7-5073cfa95fee},,application/x-mozilla-static,,nsUCvMathModule
+{ba6151ae-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{1f13b201-39fa-11d6-a7f2-df501ff820dc},,application/x-mozilla-static,,nsLayoutModule
+{ea06d4e1-2b3d-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{a3254cb0-8e20-11d2-8a98-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{9dcef3a4-a3bc-11d5-ba47-00108303b117},,application/x-mozilla-static,,NSS
+{ac9e3e82-bfbd-4f26-941e-f58c8ee178c1},,application/x-mozilla-static,,nsLayoutModule
+{9e3b6c90-2f75-11d3-8cd0-0060b0fc14a3},,application/x-mozilla-static,,necko
+{7dd4d320-c84b-4624-8d45-7bb9b2356977},,application/x-mozilla-static,,nsToolkitCompsModule
+{374e0cde-f605-4259-8c92-e639c6c2eeef},,application/x-mozilla-static,,nsUniversalCharDetModule
+{2a898043-180f-4c8b-8e54-410c7a540f27},,application/x-mozilla-static,,nsWidgetGtk2Module
+{2376201c-bbc6-472f-9b62-7548040a61c6},,text/javascript,,rel:FeedConverter.js
+{e0da1d70-2f7b-11d3-8cd0-0060b0fc14a3},,application/x-mozilla-static,,necko
+{a181af0d-68b8-4308-94db-d4f859058215},,application/x-mozilla-static,,necko
+{461cd5dd-73c6-47a4-8cc3-603b37d84a61},,application/x-mozilla-static,,ZipWriterModule
+{5534ddc0-dd96-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{84b0f182-c6c7-11d2-b3b0-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{6394eeaf-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{460a9792-b154-4f26-a922-0f653e2c8f91},,text/javascript,,rel:nsMicrosummaryService.js
+{a2027ec6-ba0d-4c72-805d-148233f5f33c},,application/x-mozilla-static,,necko
+{ba615199-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{495eca43-0a5c-11d4-a135-005004832142},,application/x-mozilla-static,,nsUConvModule
+{3f6fe6a1-ac0a-11d2-b3ae-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{296d76aa-275b-4f3c-af8a-30a4026c18fc},,application/x-mozilla-static,,NSS
+{2d524fd4-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{a6cf90e5-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsLayoutModule
+{77c0e42a-1dd2-11b2-8ebf-edc6606f2f4b},,application/x-mozilla-static,,necko
+{7bb40992-77eb-43db-9a4e-39d3bcc383ae},,application/x-mozilla-static,,nsParserModule
+{8a0dce80-e2f2-11d3-b32f-004005a7a7e4},,application/x-mozilla-static,,nsUCvMathModule
+{a4048e94-1dd1-11b2-a676-8a06c086cc7d},,application/x-mozilla-static,,nsRDFModule
+{ce768990-5a4e-11d2-8164-006008119d7a},,application/x-mozilla-static,,nsPluginModule
+{815e42e0-72cc-480f-934b-148e33c228a6},,application/x-mozilla-static,,nsAuthModule
+{ba6151bb-ec62-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{95f46161-d177-11d2-bf86-00105a1b0627},,application/x-mozilla-static,,nsLayoutModule
+{072a5c3d-30c6-4f07-b87f-9f63d51403f2},,text/javascript,,rel:FeedProcessor.js
+{e1c61582-2a84-11d3-8cce-0060b0fc14a3},,application/x-mozilla-static,,necko
+{a0f827e2-8ab6-11d5-a14b-005004832142},,application/x-mozilla-static,,nsUConvModule
+{6803cace-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{32314cc8-22f7-4f7f-a645-1a45453ba6a6},,text/javascript,,rel:nsHandlerService.js
+{1c31ed79-accd-4b94-b517-06e0c81999d5},,text/javascript,,rel:FeedConverter.js
+{2f977d4f-5485-11d4-87e2-0010a4e75ef2},,application/x-mozilla-static,,nsPrefModule
+{fe74cf80-aa2d-11db-abbd-0800200c9a66},,text/javascript,,rel:fuelApplication.js
+{660d8ca9-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eebc-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{7b8556ad-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{379c2775-ec77-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{a4e5888f-4fe4-4632-8e7e-745196ea7c70},,application/x-mozilla-static,,NSS
+{541afcb2-a9a3-11d2-8ec5-00805f29f370},,application/x-mozilla-static,,nsLayoutModule
+{bfd0526d-834c-11d2-8eac-00805f29f370},,application/x-mozilla-static,,nsRDFModule
+{4f47e42e-4d23-4dd3-bfda-eb29255e9ea3},,application/x-mozilla-static,,necko
+{64edb481-0c04-11d5-a73c-e964b968b0bc},,application/x-mozilla-static,,embedcomponents
+{7e677795-c582-4cd1-9e8d-8271b3474d2a},,application/x-mozilla-static,,embedcomponents
+{af7a9951-aa48-11d2-b3ae-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{797bec5a-1dd2-11b2-a7f8-ca397e0179c4},,application/x-mozilla-static,,nsImageLib2Module
+{27aecc62-7777-428e-b34c-5973a47b8298},,application/x-mozilla-static,,nsLayoutModule
+{d96d5985-a13a-4bdc-9386-ef348d7a97a1},,application/x-mozilla-native,,rel:libmozgnome.so
+{efc323e2-ec62-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{fca3766a-434a-4ae7-83cf-0909e18a093a},,application/x-mozilla-static,,necko
+{95d89e3e-a169-41a3-8e56-719978e15b12},@mozilla.org/xre/app-info;1,application/x-mozilla-static,nsXULAppInfo,Apprunner
+{fcacef22-2b40-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{9ac9e770-18bc-11d3-9337-00104ba0fd40},@mozilla.org/network/io-service;1,application/x-mozilla-static,nsIOService,necko
+{7c657d15-ec5e-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{edb0490e-1dd1-11b2-83b8-dbf8d85906a6},,application/x-mozilla-static,,nsToolkitCompsModule
+{6394eea7-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{a21bfa01-f349-4394-a84c-8de5cf0737d0},,application/x-mozilla-static,,embedcomponents
+{63ac8c66-1dd2-11b2-b070-84d00d3eaece},,text/javascript,,rel:nsProxyAutoConfig.js
+{ba615191-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{fe4f7592-c1fc-4662-ac83-538841318803},,application/x-mozilla-static,,xpconnect
+{fc2389b8-c650-4093-9e42-b05e5f0685b7},,application/x-mozilla-static,,nsWidgetGtk2Module
+{58a1c31c-1dd2-11b2-a3f6-d36949d48268},,application/x-mozilla-static,,necko
+{c7e410d4-85f2-11d3-9f63-006008a6efe9},,application/x-mozilla-static,,nsJarModule
+{18a03189-067b-4978-b4f1-bafe35292ed6},,text/javascript,,rel:txEXSLTRegExFunctions.js
+{7b8556b1-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{7ee2a4c0-4b93-17d3-ba18-0060b0f199a2},@mozilla.org/scriptsecuritymanager;1,application/x-mozilla-static,scriptsecuritymanager,nsSecurityManagerModule
+{ba6151b3-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{ca168834-cc00-48f9-b83c-fd018e58cae3},,text/javascript,,rel:nsUrlClassifierListManager.js
+{77221d5a-1dd2-11b2-8c69-c710f15d2ed5},,application/x-mozilla-static,,nsWidgetGtk2Module
+{5280606b-2510-4fe0-97ef-9b5a22eafe6b},,text/javascript,,rel:nsSessionStore.js
+{495eca48-0a5c-11d4-a135-005004832142},,application/x-mozilla-static,,nsUConvModule
+{6049b262-c1e6-11d1-a827-0040959a28c9},,application/x-mozilla-static,,nsGfxModule
+{b00ed78a-04e2-4f74-8e1c-d1af79dfd12f},,application/x-mozilla-static,,necko
+{bfd05264-834c-11d2-8eac-00805f29f371},,application/x-mozilla-static,,nsLayoutModule
+{e746a8b1-c97a-4fc5-baa4-66607521bd08},,application/x-mozilla-static,,necko
+{a6cf9063-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsLayoutModule
+{6803cac6-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{fcacef21-2b40-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{518e071f-1dd2-11b2-937e-c45f14def778},,application/x-mozilla-static,,PKI
+{f24a14f0-4fa1-11d3-9894-006008962422},,application/x-mozilla-static,,xpconnect
+{e35d5067-95bc-4029-8432-e8f1e431148d},,text/javascript,,rel:nsContentDispatchChooser.js
+{82776710-5690-11d3-be36-00104bde6048},,application/x-mozilla-static,,application
+{660d8ca1-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eeb4-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{14c0e880-623e-11d3-a178-0050041caf44},,application/x-mozilla-static,,necko
+{ba61519e-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{4f5e62b8-d659-4156-84fc-2f6099400369},,application/x-mozilla-static,,nsLayoutModule
+{6c84aec9-29a5-4264-8fbc-bee8f922ea67},,application/x-mozilla-static,,necko
+{2d524fd9-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{47cd0651-b1be-4a0f-b5c4-10e5a573ef71},,text/javascript,,rel:nsBrowserContentHandler.js
+{e91f9440-e076-11d3-b32f-004005a7a7e4},,application/x-mozilla-static,,nsUCvMathModule
+{06beec76-a183-4d9f-85dd-085f26da565a},,application/x-mozilla-static,,nsWidgetGtk2Module
+{12ff56ec-58be-402c-b057-01f961de969b},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{6394eeba-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{e7f70966-9a37-48d7-8aeb-35998f31090e},,application/x-mozilla-static,,nsToolkitCompsModule
+{a0ccaaf8-09da-44d8-b250-9ac3e93c8117},,application/x-mozilla-static,,nsToolkitCompsModule
+{21dd6a03-413c-11d3-b3c3-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{dbded6ec-edbf-4054-a834-287b82c260f9},,text/javascript,,rel:nsBadCertHandler.js
+{5551a1e0-5a66-11d3-806a-00600811a9c3},,application/x-mozilla-static,,application
+{27aba825-35b5-4018-9fdd-f99250a0e722},,text/javascript,,rel:nsUpdateService.js
+{6c3c274b-4cbf-4bb5-a635-05ad2cbb6535},,application/x-mozilla-static,,docshell_provider
+{25029490-f132-11d2-9588-00805f369f95},,application/x-mozilla-static,,necko
+{30dcd313-73e1-447d-8339-37744952154e},,application/x-mozilla-static,,nsUConvModule
+{e638d760-8687-11d2-b530-000000000001},,application/x-mozilla-static,,nsRDFModule
+{fc886801-e768-11d4-9885-00c04fa0cf4b},,application/x-mozilla-static,,nsLayoutModule
+{ac2bb8fe-eeeb-4572-b40f-be03932b56e0},,application/x-mozilla-static,,nsImageLib2Module
+{4ea60761-31d6-491d-9e34-4b53a26c416c},,application/x-mozilla-static,,NSS
+{aa40253b-4c42-4056-8132-37bcd07862fd},,application/x-mozilla-static,,nsLayoutModule
+{4e4aae11-8901-46cc-8217-dad7c5415873},,application/x-mozilla-static,,embedcomponents
+{fbc81170-1f69-11d3-9344-00104ba0fd40},@mozilla.org/network/protocol;1?name=file,application/x-mozilla-static,nsFileProtocolHandler,necko
+{a0d6ad32-1dd1-11b2-aa55-a40187b54036},,application/x-mozilla-static,,necko
+{984e3259-9266-49cf-b605-60b022a00756},,application/x-mozilla-static,,nsPlacesModule
+{ba6151ab-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{7584ce90-5b25-11d3-a175-0050041caf44},,application/x-mozilla-static,,necko
+{0a5cd734-eb65-4d14-88a0-9f0bb2aba206},,application/x-mozilla-static,,nsRDFModule
+{749e62f4-60ae-4569-a8a2-de78b649660e},,text/javascript,,rel:nsLoginManagerPrompter.js
+{9a28ffa7-e6ef-4b52-a127-6ad951de8e9b},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{2d96b3df-c051-11d1-a827-0040959a28c9},,application/x-mozilla-static,,nsWidgetGtk2Module
+{a6cf9115-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsGfxModule
+{5c337258-a580-472e-8615-f277ddc5bb06},,application/x-mozilla-static,,nsWidgetGtk2Module
+{0e3afd3d-eb60-4c2b-963b-56d7c439f124},,application/x-mozilla-static,,nsLayoutModule
+{8eaaf524-7d6d-4f7d-ae8b-9277b324008d},,text/javascript,,rel:nsAddonRepository.js
+{6394eeac-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{36fa00c2-1dd2-11b2-be07-d16eeb4c50ed},,application/x-mozilla-static,,nsImageLib2Module
+{275d800e-3f60-4896-adb7-d7f390ce0e42},@mozilla.org/network/url-parser;1?auth=yes,application/x-mozilla-static,nsAuthURLParser,necko
+{a59da931-4091-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{0659cb83-faad-11d2-8e19-b206620a657c},,application/x-mozilla-static,,appshell
+{f3294b1c-89f4-46f8-98a0-44e1eae92518},,text/javascript,,rel:nsExtensionManager.js
+{2d524fd1-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{20557898-1dd2-11b2-8f65-9c462ee2bc95},,application/x-mozilla-static,,nsImageLib2Module
+{2d96b3d1-c051-11d1-a827-0040959a28c9},,application/x-mozilla-static,,nsWidgetGtk2Module
+{13111d00-ce81-11d6-8082-ecf3665af67c},,application/x-mozilla-static,,nsLayoutModule
+{bc26ff01-f2bd-11d4-a73c-e5a4b5a8bdfc},,application/x-mozilla-static,,nsComposerModule
+{7dfdf0d1-aff6-4a34-bad1-d0fe74601642},,text/javascript,,rel:nsDownloadManagerUI.js
+{ba6151b8-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{b57f97c2-0d70-11d3-8aae-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{c87a37fc-8109-4ce2-a322-8cdec925379f},,application/x-mozilla-static,,nsLayoutModule
+{9416bfb2-1f93-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{e7ba1480-1dea-11d3-830f-00104bed045e},,application/x-mozilla-static,,nsLayoutModule
+{6803cacb-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{f68578eb-6ec2-4169-ae19-8c6243f0abe1},,text/javascript,,rel:nsHelperAppDlg.js
+{d92d57c5-ba1d-11d2-af0c-0060089fe59b},,application/x-mozilla-static,,nsI18nModule
+{e036c738-1dd1-11b2-9392-9d94aa74b0c5},,application/x-mozilla-static,,nsAutoConfigModule
+{8b5314bb-db01-11d2-96ce-0060b0fb9956},,application/x-mozilla-static,,nsWidgetGtk2Module
+{e7509b46-2eb2-410a-9d7c-c3ce73284d01},,application/x-mozilla-static,,nsLayoutModule
+{d673255d-1184-400a-b0b5-ee9d1295bd85},,application/x-mozilla-static,,nsUConvModule
+{6394eeb9-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{d0a75e02-b5e7-11d5-a7f2-df109fb8a1fc},,application/x-mozilla-static,,nsLayoutModule
+{a33982d3-1adf-4162-9941-f734bc45e4ed},,application/x-mozilla-static,,nsComposerModule
+{7b8556aa-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{bd6390c8-fbea-11d4-98f6-001083010e9b},,application/x-mozilla-static,,docshell_provider
+{a6cf9059-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,docshell_provider
+{c375fa80-150f-11d6-a618-0010a401eb10},,application/x-mozilla-static,,necko
+{51fa28c7-74c0-4b85-9c46-d03faa7b696b},,application/x-mozilla-static,,necko
+{d750a964-2d14-484c-b3aa-8ed7823b5c7b},,application/x-mozilla-static,,nsLayoutModule
+{f57899d0-4e2c-4ac6-9e29-50c736103b0c},,text/javascript,,rel:nsSetDefaultBrowser.js
+{786e0a0e-e035-4600-8ee0-365a63a80b80},,application/x-mozilla-static,,nsToolkitCompsModule
+{b0ff4572-dae4-4bef-a092-83c1b88f6be9},@mozilla.org/network/dns-service;1,application/x-mozilla-static,nsDNSService,necko
+{bbc23860-2553-479d-8b78-94d9038334f7},,text/javascript,,rel:nsTaggingService.js
+{064d9cee-1dd2-11b2-83e3-d25ab0193c26},,application/x-mozilla-static,,nsPrefModule
+{6394eea4-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{6ee5301a-3981-49bd-85f8-1a2cc228cf3e},,application/x-mozilla-static,,nsUniversalCharDetModule
+{9416bfbf-1f93-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{2bf64765-997f-450d-af96-3028d1a902b0},,application/x-mozilla-static,,nsI18nModule
+{9c8f9601-801a-11d2-98ba-00805f297d89},,application/x-mozilla-static,,nsTransactionManagerModule
+{6c392c62-1ab1-4de7-bfc6-ed4f9fc7749a},,application/x-mozilla-static,,nsLayoutModule
+{2cd0c310-e127-44d0-88fc-4435c9ab4d4b},,text/javascript,,rel:jsconsole-clhandler.js
+{b7b2ccec-7912-4ea6-a548-b038447004bd},,application/x-mozilla-static,,nsToolkitCompsModule
+{06893e69-71d8-4b23-81eb-80314daf3e66},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{d899a152-9412-46b2-b651-2e71c5c2f05f},,application/x-mozilla-static,,nsLayoutModule
+{217d014a-1dd2-11b2-999c-b0c4df79b324},,application/x-mozilla-static,,NSS
+{80d7e247-d4b8-45d7-bb59-6f1dd56f384c},,application/x-mozilla-static,,nsLayoutModule
+{ba6151b0-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{df71c6f0-ec53-11d2-bdca-000064657374},,application/x-mozilla-static,,nsRDFModule
+{c2be6dc0-ef1e-4abd-86a2-4f864ddc57f6},,application/x-mozilla-static,,nsToolkitCompsModule
+{792a7e82-06a0-437c-af63-b2d12e808acc},,text/javascript,,rel:WebContentConverter.js
+{495eca45-0a5c-11d4-a135-005004832142},,application/x-mozilla-static,,nsUConvModule
+{78c61626-4d1f-4843-9364-4652d98ff6e1},,application/x-mozilla-static,,nsImageLib2Module
+{6356aa16-7916-4215-a825-cbc2692ca87a},,application/x-mozilla-static,,application
+{e11a6080-4daa-11d2-b328-00805f8a3859},,application/x-mozilla-static,,nsLayoutModule
+{7e6e57c0-e2f2-11d3-b32f-004005a7a7e4},,application/x-mozilla-static,,nsUCvMathModule
+{ea06d4e3-2b3d-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{5871a422-1dd2-11b2-ab3f-e2e56be5da9c},,application/x-mozilla-static,,nsImageLib2Module
+{0e4e7d00-f71a-439f-9178-1a71ff11b55f},,application/x-mozilla-static,,nsLayoutModule
+{e197cc01-cfe1-11d4-8eb0-87ae406dfd3f},,application/x-mozilla-static,,nsLayoutModule
+{2ea2e7d0-4095-11d3-9144-006008a6edf6},,application/x-mozilla-static,,nsI18nModule
+{dd156d62-d26f-4441-9cdb-e8f09107c273},,application/x-mozilla-static,,nsSecurityManagerModule
+{6394eeb1-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{c272fee0-c7e9-11d3-8cda-0060b0fc14a3},,application/x-mozilla-static,,necko
+{96ec4163-efc8-407a-8735-007fb26be4e8},,application/x-mozilla-static,,nsAuthModule
+{e38e53b9-5bb0-456a-b553-579370cb1567},,application/x-mozilla-static,,xpconnect
+{a6cf90e3-15b3-11d2-932e-00805f8add32},,application/x-mozilla-static,,nsLayoutModule
+{89e9da80-4c03-46a0-a357-cf77bbef98b9},,text/javascript,,rel:aboutRights.js
+{d164e770-4157-11d4-9a42-000064657374},,application/x-mozilla-static,,nsLayoutModule
+{2d524fd6-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{78481e4a-50e4-4489-b68a-ef82670ed63f},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{301dea42-6850-4cda-8945-81f7dbc2186b},,application/x-mozilla-static,,necko
+{b322a5c0-a419-484e-96ba-d7182163899f},,text/javascript,,rel:nsUpdateService.js
+{9c47c121-1c6e-4d8f-b904-3ac968116e88},,application/x-mozilla-static,,docshell_provider
+{8b449142-1eab-4bfa-9830-fab6ebb09774},,application/x-mozilla-static,,nsLayoutModule
+{6bd13476-1dd2-11b2-bbef-f0ccb5fa64b6},@mozilla.org/moz/jsloader;1,application/x-mozilla-static,JS component loader,xpconnect
+{c8e518c1-47ae-11d3-91cd-00105aa3f7dc},,application/x-mozilla-static,,nsI18nModule
+{2fd6b7f6-eb8c-4f32-ad26-113f2c02d0fe},,application/x-mozilla-static,,JavaScript_Debugger
+{ff9fbcd7-9517-4334-b97a-ceed78909974},,application/x-mozilla-static,,NSS
+{510a86bb-6019-4ed1-bb4f-965cffd23ece},,application/x-mozilla-static,,necko
+{b084a2ce-1dd1-11b2-bf10-8324f8e065cc},,application/x-mozilla-static,,NSS
+{3d262d00-8b5a-11d2-8eb0-00805f29f370},,application/x-mozilla-static,,nsLayoutModule
+{dca61eb5-c7cd-4df1-b0fb-d0722baba251},,text/javascript,,rel:nsLivemarkService.js
+{ea06d4e4-2b3d-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUniversalCharDetModule
+{660a3226-915c-4ffb-bb20-8985a632df05},,application/x-mozilla-static,,NSS
+{2ec62893-3b35-48fa-ab1d-5e68a9f45f08},,application/x-mozilla-static,,necko
+{ce002b28-92b7-4701-8621-cc925866fb87},,application/x-mozilla-static,,nsCookieModule
+{7ef52eaf-b7e1-462b-87e2-5d1dbaca9048},,application/x-mozilla-static,,mozSpellCheckerModule
+{c95f1831-c376-11d1-b721-00600891d8c9},,application/x-mozilla-static,,nsLayoutModule
+{cf3a0e06-1dd1-11b2-a904-ac1d6da77a02},,application/x-mozilla-static,,necko
+{e09e4ca6-276b-4bb4-8b71-0635a3a2a007},,text/javascript,,rel:storage-Legacy.js
+{56c778e4-1bee-45f3-a689-886692a97fe7},,application/x-mozilla-static,,mozSpellCheckerModule
+{fd9a9e8a-a77b-496a-b7bb-263df9715149},,application/x-mozilla-static,,nsImageLib2Module
+{7bd05c78-6a26-11d7-b16f-0003938a9d96},,application/x-mozilla-static,,nsLayoutModule
+{6394eebe-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{7b8556af-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{379c2777-ec77-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{de401c37-9a7f-4278-a6f8-3de2833989ef},,application/x-mozilla-static,,nsAccessibilityModule
+{4ec832da-6ae7-4185-807b-daddcb5da37a},,application/x-mozilla-static,,nsLayoutModule
+{f0acde16-1dd1-11b2-9e35-f5786fff5a66},,application/x-mozilla-static,,docshell_provider
+{56e2ada8-4631-11d4-ba11-001083023c1e},,application/x-mozilla-static,,nsLayoutModule
+{f34ff792-722e-4490-b195-47d242edca1c},,application/x-mozilla-native,,rel:libbrowsercomps.so
+{61ba33c0-3031-11d3-8cd0-0060b0fc14a3},,application/x-mozilla-static,,nsChromeModule
+{e042570c-62de-4bb6-a6e0-798e3c07b4df},,application/x-mozilla-static,,embedcomponents
+{bbef8185-c628-4cc1-b53e-e61e74c2451a},,application/x-mozilla-static,,necko
+{9416bfc1-1f93-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{aa13e4a0-a5ac-11d2-9119-006008a6edf6},,application/x-mozilla-static,,nsI18nModule
+{7c657d17-ec5e-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eea9-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{66354bc9-7ed1-4692-ae1d-8da97d6b205e},,text/javascript,,rel:nsBlocklistService.js
+{171e72db-0f8a-412a-8461-e4c927a3a2ac},,application/x-mozilla-static,,nsComposerModule
+{ef565d0a-ab9a-4a13-9160-0644cdfd859a},,application/x-mozilla-static,,nsCookieModule
+{735959a1-af01-447e-b02d-56e968fa52b4},,application/x-mozilla-static,,NSS
+{5e8d4751-1852-434b-a992-2c6d2a25fa46},,application/x-mozilla-static,,nsPlacesModule
+{ecd55a01-2780-11d5-a73c-ca641a6813bc},,application/x-mozilla-static,,embedcomponents
+{2002f782-3960-11d3-b3c3-00805f8a6670},,application/x-mozilla-static,,nsChardetModule
+{8227f019-afc7-461e-b030-9f185d7a0e29},,application/x-mozilla-static,,mozSpellCheckerModule
+{7c65e6f0-7605-11dd-ad8b-0800200c9a66},,text/javascript,,rel:aboutSessionRestore.js
+{1d40026b-4c44-4f6f-b158-26bb5e9c65e9},,application/x-mozilla-static,,nsLayoutModule
+{e28ab250-d66d-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{ba6151b5-1dfa-11d3-b3bf-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{4f76e100-d71c-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{88cecbb7-6c63-4b3b-8cd4-84f3b8228c69},,application/x-mozilla-static,,nsPlacesModule
+{d85a17c1-aa7c-11d2-9b8c-00805f8a16d9},@mozilla.org/intl/stringbundle;1,application/x-mozilla-static,String Bundle,nsI18nModule
+{a578e0a2-f76b-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{f7c9f5f4-4451-41c3-a28a-5ba2447fbace},,application/x-mozilla-static,,necko
+{7b8556b0-ec79-11d2-8aac-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{1147d32c-215b-4014-b180-07fe7aedf915},,application/x-mozilla-static,,nsLayoutModule
+{905f80f1-8a7b-11d2-918c-0080c8e44db5},,application/x-mozilla-static,,nsLayoutModule
+{6803cac8-1e3b-11d5-a145-005004832142},,application/x-mozilla-static,,nsUConvModule
+{758e4f20-e2f2-11d3-b32f-004005a7a7e4},,application/x-mozilla-static,,nsUCvMathModule
+{6394eea1-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{ec06f3fc-70db-4ecd-94e0-a6e91ca44d8a},,application/x-mozilla-static,,docshell_provider
+{660d8ca3-f763-11d2-8aad-00600811a836},,application/x-mozilla-static,,nsUConvModule
+{6394eeb6-fc3d-11d2-b3b8-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{bd57cee8-1dd1-11b2-9fe7-95cf4709aea3},,application/x-mozilla-static,,nsWidgetGtk2Module
+{9c0ff6f4-deda-40e5-806c-b6cc449c21ce},,application/x-mozilla-static,,nsUConvModule
+{49b38f12-6193-11d3-b3c5-00805f8a6670},,application/x-mozilla-static,,nsUConvModule
+{2d524fdb-ae74-11d3-abf7-0004aceefa51},,application/x-mozilla-static,,nsUConvModule
+{7f915b01-98fc-11d4-8eb0-a803f80ff1bc},,application/x-mozilla-static,,nsLayoutModule
+{430d416c-a722-4ad1-be98-d9a445f85e3f},,application/x-mozilla-static,,ZipWriterModule
+{245abae2-b947-4ded-a46d-9829d3cca462},,application/x-mozilla-static,,nsJarModule
+{cb9abbae-66b6-4609-8594-5c4ff300888e},,application/x-mozilla-static,,necko
+{38e7ef10-58df-11d2-8164-006008119d7a},,application/x-mozilla-static,,nsCJVMManagerModule
+{2c3837af-8b85-4a68-b0d8-0aed88985b32},,application/x-mozilla-static,,NSS
+{23bcc750-dc20-460b-b2d4-74d8f58d3615},,application/x-mozilla-static,,CommandLineModule
+{6049b260-c1e6-11d1-a827-0040959a28c9},,application/x-mozilla-static,,nsGfxModule
+{dbfcbe4a-10f7-4d6f-a481-68e6d6b71d21},,application/x-mozilla-static,,NSS
+{c744ca3d-840b-460a-8d70-7ce63c51c958},,application/x-mozilla-static,,nsWindowDataSourceModule
+{be65e2b7-fe46-4e0f-88e0-4b385db4d68a},,application/x-mozilla-static,,NSS
+{dca9d7c3-7b6a-4490-ad6d-2699a8d683cd},,application/x-mozilla-static,,nsLayoutModule
+{dc26e0e0-ca94-11d1-a9a4-00805f8a7ac4},,application/x-mozilla-static,,nsPrefModule
+{b7f44954-11d1-11b2-8c2e-c2feab4186bc},,application/x-mozilla-static,,nsLayoutModule
+{9f1800ab-f428-4207-b40c-e832e77b01fc},,application/x-mozilla-static,,nsWidgetGtk2Module
+{0320e073-79c7-4dae-8055-81bed8b8db96},,application/x-mozilla-static,,nsJarModule
+{93ad72a6-02cd-4716-9626-d47d5ec275ec},,application/x-mozilla-static,,nsLayoutModule
+
+[CONTRACTIDS]
+@mozilla.org/intl/unicode/encoder;1?charset=Big5,{efc323e2-ec62-11d2-8aac-00600811a836}
+@mozilla.org/gfx/region/nsThebes;1,{e12752f0-ee9a-11d1-a82a-0040959a28c9}
+@mozilla.org/image/tools;1,{fd9a9e8a-a77b-496a-b7bb-263df9715149}
+@mozilla.org/network/effective-tld-service;1,{cb9abbae-66b6-4609-8594-5c4ff300888e}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-greek,{7b8556b1-ec79-11d2-8aac-00600811a836}
+@mozilla.org/extensions/addon-repository;1,{8eaaf524-7d6d-4f7d-ae8b-9277b324008d}
+@mozilla.org/oji/jvm-mgr;1,{38e7ef10-58df-11d2-8164-006008119d7a}
+@mozilla.org/inspector/dom-utils;1,{40b22006-5dd5-42f2-bfe7-7dbf0757ab8b}
+@mozilla.org/xtf/xml-contentbuilder;1,{e09af32d-2a54-4d76-9ef0-3070e83f8be7}
+@mozilla.org/intl/unicharcategory;1,{748a1132-671a-409a-8d1d-f1cdf6b3a6b4}
+@mozilla.org/intl/unicode/decoder;1?charset=x-windows-949,{9416bfbf-1f93-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-6,{660d8ca8-f763-11d2-8aad-00600811a836}
+@mozilla.org/intl/unicode/decoder;1?charset=UTF-32,{30dcd313-73e1-447d-8339-37744952154e}
+@mozilla.org/content/post-content-iterator;1,{a6cf90e3-15b3-11d2-932e-00805f8add32}
+@mozilla.org/intl/unicode/encoder;1?charset=x-t1-cmmi,{bd1326a6-5a14-48de-97cc-95b5195f4fb9}
+@mozilla.org/network/mime-hdrparam;1,{1f4dbcf7-245c-4c8c-943d-8a1da0495e8a}
+@mozilla.org/network/protocol/about;1?what=config,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/network/sync-stream-listener;1,{439400d3-6f23-43db-8b06-8aafe1869bd8}
+@mozilla.org/intl/unicode/decoder;1?charset=x-viet-tcvn5712,{6394eead-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/download-manager-ui;1,{7dfdf0d1-aff6-4a34-bad1-d0fe74601642}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-arabic,{6803cac7-1e3b-11d5-a145-005004832142}
+@mozilla.org/url-classifier/streamupdater;1,{c2be6dc0-ef1e-4abd-86a2-4f864ddc57f6}
+@mozilla.org/xmlextras/domparser;1,{3a8a3a50-512c-11d4-9a54-000064657374}
+@mozilla.org/oji/jvm-config-mgr;1,{4a68cee9-6f07-4950-b441-a1ce6a082e2f}
+@mozilla.org/streamconv;1?from=x-compress&to=uncompressed,{66230b2b-17fa-4bd3-abf4-07986151022d}
+@mozilla.org/network/protocol-proxy-service;1,{e9b301c0-e0e4-11d3-a1a8-0050041caf44}
+@mozilla.org/storage/service;1,{bbbb1d61-438f-4436-92ed-8308e5830fb0}
+@mozilla.org/widget/clipboardhelper;1,{77221d5a-1dd2-11b2-8c69-c710f15d2ed5}
+@mozilla.org/network/server-socket;1,{2ec62893-3b35-48fa-ab1d-5e68a9f45f08}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-14,{6394eeb1-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-turkish,{7b8556a4-ec79-11d2-8aac-00600811a836}
+@mozilla.org/uriloader/web-handler-app;1,{8b1ae382-51a9-4972-b930-56977a57919d}
+@mozilla.org/intl/saveascharset;1,{0cd233e0-7a86-11d3-915c-006008a6edf6}
+@mozilla.org/network/http-authenticator;1?scheme=basic,{fca3766a-434a-4ae7-83cf-0909e18a093a}
+@mozilla.org/sidebar;1,{22117140-9c6e-11d3-aaf1-00805f8a4905}
+@mozilla.org/streamconv;1?from=text/plain&to=text/html,{9ef9fa14-1dd1-11b2-9d65-d72d6d1f025e}
+@mozilla.org/webnavigation-info;1,{f30bc0a2-958b-4287-bf62-ce38ba0c811e}
+@mozilla.org/intl/charsetdetect;1?type=ukprob,{2002f782-3960-11d3-b3c3-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1251,{a578e0a1-f76b-11d2-8aad-00600811a836}
+@mozilla.org/storage/statement-wrapper;1,{dab3a846-3a59-4fc2-9745-c6ff48776f00}
+@mozilla.org/layout/contentserializer;1?mimetype=application/xml,{4aef38b7-6364-4e23-a5e7-12f837fbbd9c}
+@mozilla.org/system-proxy-settings;1,{0fa3158c-d5a7-43de-9181-a285e74cf1d4}
+@mozilla.org/gfx/renderingcontext;1,{6049b261-c1e6-11d1-a827-0040959a28c9}
+@mozilla.org/image/decoder;2?type=image/jpg,{5871a422-1dd2-11b2-ab3f-e2e56be5da9c}
+@mozilla.org/security/crlmanager;1,{5b256c10-22d8-4109-af92-1253035e9fcb}
+@mozilla.org/layout/contentserializer;1?mimetype=image/svg+xml,{4aef38b7-6364-4e23-a5e7-12f837fbbd9c}
+@mozilla.org/network/mime-input-stream;1,{58a1c31c-1dd2-11b2-a3f6-d36949d48268}
+@mozilla.org/intl/unicode/decoder;1?charset=UTF-8,{5534ddc0-dd96-11d2-8aac-00600811a836}
+@mozilla.org/dom/storage;1,{8b449142-1eab-4bfa-9830-fab6ebb09774}
+@mozilla.org/embedding/browser/nsCommandHandler;1,{3a449110-66fd-11d4-9528-0020183bf181}
+@mozilla.org/intl/unicode/encoder;1?charset=IBM850,{2d524fd6-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1254,{7b8556ae-ec79-11d2-8aac-00600811a836}
+@mozilla.org/sound;1,{b148eed2-236d-11d3-b35c-00a0cc3c1cde}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-devanagari,{6803cac5-1e3b-11d5-a145-005004832142}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-6,{660d8ca3-f763-11d2-8aad-00600811a836}
+@mozilla.org/xpinstall/install-manager;1,{6a4d4c1e-a74a-4320-8124-16233a0183d6}
+@mozilla.org/passwordmanager/authpromptfactory;1,{749e62f4-60ae-4569-a8a2-de78b649660e}
+@mozilla.org/extensions/blocklist;1,{66354bc9-7ed1-4692-ae1d-8da97d6b205e}
+@mozilla.org/widget/bidikeyboard;1,{9f1800ab-f428-4207-b40c-e832e77b01fc}
+@mozilla.org/permissions/contentblocker;1,{4ca6b67b-5cc7-4e71-a98a-97af1c134862}
+@mozilla.org/appshell/component/browser-status-filter;1,{6356aa16-7916-4215-a825-cbc2692ca87a}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-2022-CN,{ba615199-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/security/nsASN1Tree;1,{4bfaa9f0-1dd2-11b2-afae-a82cbaa0b606}
+@mozilla.org/intl/texttransform;1?type=hankakutozenkaku,{8f666a11-04a0-11d3-b3b9-00805f8a6670}
+@mozilla.org/intl/charsetdetect;1?type=ruprob,{2002f781-3960-11d3-b3c3-00805f8a6670}
+@mozilla.org/uriloader/content-handler;1?type=text/css,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/widget/native-key-bindings;1?type=input,{5c337258-a580-472e-8615-f277ddc5bb06}
+@mozilla.org/streamconv;1?from=text/gopher-dir&to=application/http-index-format,{ea617873-3b73-4efd-a2c4-fc39bfab809d}
+@mozilla.org/editor/editorcontroller;1,{26fb965c-9de6-11d3-bccc-0060b0fc76bd}
+@mozilla.org/layout/documentEncoder;1?type=application/xml,{e7ba1480-1dea-11d3-830f-00104bed045e}
+@mozilla.org/image/decoder;2?type=image/gif,{797bec5a-1dd2-11b2-a7f8-ca397e0179c4}
+@mozilla.org/intl/texttosuburi;1,{8b042e22-6f87-11d3-b3c8-00805f8a6670}
+@mozilla.org/network/protocol/about;1?what=buildconfig,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/widget/htmlformatconverter;1,{948a0023-e3a7-11d2-96cf-0060b0fb9956}
+@mozilla.org/intl/unicode/encoder;1?charset=Shift_JIS,{e28ab250-d66d-11d2-8aac-00600811a836}
+@mozilla.org/nsCertificateDialogs;1,{518e071f-1dd2-11b2-937e-c45f14def778}
+@mozilla.org/streamconv;1?from=application/http-index-format&to=text/html,{cf0f71fd-fafd-4e2b-9fdc-134d972e16e2}
+@mozilla.org/network/stream-transport-service;1,{0885d4f8-f7b8-4cda-902e-94ba38bc256e}
+@mozilla.org/js/xpc/RuntimeService;1,{b5e65b52-1dd1-11b2-ae8f-f0928ed88482}
+@mozilla.org/network/binary-detector;1,{a2027ec6-ba0d-4c72-805d-148233f5f33c}
+@mozilla.org/intl/charsetalias;1,{98d41c21-ccf3-11d2-b3b1-00805f8a6670}
+@mozilla.org/browser/favicon-service;1,{984e3259-9266-49cf-b605-60b022a00756}
+@mozilla.org/globalprefsecuritycheck;1,{7ee2a4c0-4b93-17d3-ba18-0060b0f199a2}
+@mozilla.org/js/xpc/Exception;1,{5632bf70-51ec-11d3-9896-006008962422}
+@mozilla.org/feed-person;1,{95c963b7-20b2-11db-92f6-001422106990}
+@mozilla.org/xul/xul-popup-manager;1,{14632191-ac21-4bdf-83e7-2363ad17e838}
+@mozilla.org/content/plugin/document-loader-factory;1,{0ddf4df8-4dbb-4133-8b79-9afb966514f5}
+@mozilla.org/network/request-observer-proxy;1,{51fa28c7-74c0-4b85-9c46-d03faa7b696b}
+@mozilla.org/browser/clh;1,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/embedcomp/controller-command-group;1,{ecd55a01-2780-11d5-a73c-ca641a6813bc}
+@mozilla.org/uriloader/content-handler;1?type=text/plain,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/network/socket;2?type=starttls,{b9507aec-1dd1-11b2-8cd5-c48ee0c50307}
+@mozilla.org/uriloader/external-helper-app-service;1,{a7f800e0-4306-11d4-98d0-001083010e9b}
+@mozilla.org/scriptsecuritymanager;1,{7ee2a4c0-4b93-17d3-ba18-0060b0f199a2}
+@mozilla.org/browser/browserglue;1,{eab9012e-5f74-4cbc-b2b5-a590235513cc}
+@mozilla.org/network/protocol;1?name=ftp,{25029490-f132-11d2-9588-00805f369f95}
+@mozilla.org/js/xpc/XPConnect;1,{cb6593e0-f9b2-11d2-bdd6-000064657374}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mathematica3,{830b5f80-e2f2-11d3-b32f-004005a7a7e4}
+@mozilla.org/intl/unicode/decoder;1?charset=Big5-HKSCS,{ba6151bb-ec62-11d2-8aac-00600811a836}
+@mozilla.org/security/psmdownload;1,{c94f4a30-64d7-11d4-9960-00b0d02354a0}
+@mozilla.org/embedcomp/find;1,{57cf9383-3405-11d5-be5b-aa20fa2cf37c}
+@mozilla.org/autocomplete/controller;1,{f6d5ebbd-34f4-487d-9d10-3d34123e3eb9}
+@mozilla.org/network/unichar-stream-loader;1,{9445791f-fa4c-4669-b174-df5032bb67b3}
+@mozilla.org/nsTokenDialogs;1,{518e071f-1dd2-11b2-937e-c45f14def778}
+@mozilla.org/intl/scriptabledateformat;1,{2ea2e7d0-4095-11d3-9144-006008a6edf6}
+@mozilla.org/network/application-cache-service;1,{02bf7a2a-39d8-4a23-a50c-2cbb085ab7a5}
+@mozilla.org/network/http-authenticator;1?scheme=ntlm,{bbef8185-c628-4cc1-b53e-e61e74c2451a}
+@mozilla.org/intl/unicode/encoder;1?charset=gb18030,{a59da932-4091-11d5-a145-005004832142}
+@mozilla.org/geolocation/provider;1,{77da64d3-7458-4920-9491-86cc9914f904}
+@mozilla.org/intl/charsetdetect;1?type=ko_parallel_state_machine,{ea06d4e1-2b3d-11d3-b3bf-00805f8a6670}
+@mozilla.org/inspector/search;1?type=cssvalue,{4d977f60-fbe7-4583-8cb7-f5ed882293ef}
+@mozilla.org/network/socket;2?type=socks,{8dbe7246-1dd2-11b2-9b8f-b9a849e4403a}
+@mozilla.org/intl/platformcharset;1,{84b0f182-c6c7-11d2-b3b0-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-arabic,{6803cac6-1e3b-11d5-a145-005004832142}
+@mozilla.org/intl/charsetdetect;1?type=cjk_parallel_state_machine,{fcacef24-2b40-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=KOI8-U,{6394eea6-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=x-t1-cmr,{d5eb483c-67c0-4286-a4a6-330e58a82300}
+@mozilla.org/browser/sessionstore;1,{5280606b-2510-4fe0-97ef-9b5a22eafe6b}
+@mozilla.org/pref-localizedstring;1,{064d9cee-1dd2-11b2-83e3-d25ab0193c26}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-6-E,{495eca45-0a5c-11d4-a135-005004832142}
+@mozilla.org/security/nsscertcache;1,{3f429a14-dffe-417d-8cb8-fdf09bacd09e}
+@mozilla.org/libjar/zip-reader-cache;1,{1b117e16-0cad-11d4-986e-00c04fa0cf4a}
+@mozilla.org/url-classifier/utils;1,{b7b2ccec-7912-4ea6-a548-b038447004bd}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-936,{9416bfc1-1f93-11d3-b3bf-00805f8a6670}
+@mozilla.org/editor/txtsrvfilter;1,{171e72db-0f8a-412a-8461-e4c927a3a2ac}
+@mozilla.org/nsDOMCryptoDialogs;1,{518e071f-1dd2-11b2-937e-c45f14def778}
+@mozilla.org/intl/unicode/decoder;1?charset=armscii-8,{6394eeac-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/image/decoder;2?type=image/icon,{ffc08380-256c-11d5-9905-001083010e9b}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-874,{6394eeb4-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/network/protocol;1?name=resource,{e64f152a-9f07-11d3-8cda-0060b0fc14a3}
+@mozilla.org/updates/update-manager;1,{093c2356-4843-4c65-8709-d7dbcbbe7dfb}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-3,{660d8ca5-f763-11d2-8aad-00600811a836}
+@mozilla.org/network/url-parser;1?auth=yes,{275d800e-3f60-4896-adb7-d7f390ce0e42}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-8-I,{495eca48-0a5c-11d4-a135-005004832142}
+@mozilla.org/embedcomp/cookieprompt-service;1,{ce002b28-92b7-4701-8621-cc925866fb87}
+@mozilla.org/intl/unicode/encoder;1?charset=x-zapf-dingbats,{21dd6a03-413c-11d3-b3c3-00805f8a6670}
+@mozilla.org/network/idn-service;1,{62b778a6-bce3-456b-8c31-2865fbb68c91}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-ukrainian,{6394eeaa-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/gfx/image/frame;2,{aa699204-1dd1-11b2-84a9-a280c268e4fb}
+@mozilla.org/network/input-stream-channel;1,{6ddb050c-0d04-11d4-986e-00c04fa0cf4a}
+@mozilla.org/microsummary/service;1,{460a9792-b154-4f26-a922-0f653e2c8f91}
+@mozilla.org/toolkit/app-startup;1,{7dd4d320-c84b-4624-8d45-7bb9b2356977}
+@mozilla.org/url-classifier/listmanager;1,{ca168834-cc00-48f9-b83c-fd018e58cae3}
+@mozilla.org/network/auth-module;1?name=ntlm,{a4e5888f-4fe4-4632-8e7e-745196ea7c70}
+@mozilla.org/intl/xmlencoding;1,{12bb8f16-2389-11d3-b3bf-00805f8a6670}
+@mozilla.org/network/socket;2?type=udp,{320706d2-2e81-42c6-89c3-8d83b17d3fb4}
+@mozilla.org/intl/unicode/encoder;1?charset=x-johab,{d9b1f97e-cfa0-80b6-fb92-9972e48e3dcc}
+@mozilla.org/spellchecker/personaldictionary;1,{7ef52eaf-b7e1-462b-87e2-5d1dbaca9048}
+@mozilla.org/browser/global-history;1,{a772eee4-0464-405d-a329-a29dfda3791a}
+@mozilla.org/widget/idleservice;1,{6987230e-0098-4e78-bc5f-1493ee7519fa}
+@mozilla.org/xpinstall/installtrigger;1,{18c2f98d-b09f-11d2-bcde-00805f0e1353}
+@mozilla.org/layout/documentEncoder;1?type=application/xhtml+xml,{e7ba1480-1dea-11d3-830f-00104bed045e}
+@mozilla.org/network/protocol;1?name=http,{4f47e42e-4d23-4dd3-bfda-eb29255e9ea3}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1252,{7c657d15-ec5e-11d2-8aac-00600811a836}
+@mozilla.org/intl/unicode/encoder;1?charset=UTF-32,{49b38f14-6193-11d3-b3c5-00805f8a6670}
+@mozilla.org/intl/semanticunitscanner;1,{adf42751-1cef-4ad2-aa8e-bcb849d8d31f}
+@mozilla.org/rdf/datasource;1?name=in-memory-datasource,{bfd0526d-834c-11d2-8eac-00805f29f370}
+@mozilla.org/intl/unicode/decoder;1?charset=UTF-16LE,{ba6151b7-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/streamconv;1?from=compress&to=uncompressed,{66230b2b-17fa-4bd3-abf4-07986151022d}
+@mozilla.org/intl/unicode/decoder;1?charset=us-ascii,{ba6151b9-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/network/stream-loader;1,{5ba6d920-d4e9-11d3-a1a5-0050041caf44}
+@mozilla.org/content/canvas-rendering-context;1?id=2d,{a35d1cd4-c505-4d2d-a0f9-aef00b7ce5a5}
+@mozilla.org/layout/contentserializer;1?mimetype=text/html,{9d3f70da-86e9-11d4-95ec-00b0d03e37b7}
+@mozilla.org/network/socket;2?type=ssl,{217d014a-1dd2-11b2-999c-b0c4df79b324}
+@mozilla.org/intl/unicode/encoder;1?charset=x-windows-949,{9416bfbe-1f93-11d3-b3bf-00805f8a6670}
+@mozilla.org/security/hash;1,{36a1d3b3-d886-4317-96ff-87b0005cfef7}
+@mozilla.org/network/auth-module;1?name=sasl-gssapi,{815e42e0-72cc-480f-934b-148e33c228a6}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1251,{a578e0a3-f76b-11d2-8aac-00600811a836}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-15,{6394eea2-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-3,{660d8ca0-f763-11d2-8aad-00600811a836}
+@mozilla.org/intl/unicode/encoder;1?charset=UTF-32LE,{ba6151b6-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/dom/storagemanager;1,{b88a4712-eb52-4c10-9b85-bf5894b510f0}
+@mozilla.org/psm;1,{a277189c-1dd1-11b2-a8c9-e4e8bfb1338e}
+@mozilla.org/docloaderservice;1,{057b04d0-0ccf-11d2-beba-00805f8a66dc}
+@mozilla.org/streamconv;1?from=application/mac-binhex40&to=*/*,{301dea42-6850-4cda-8945-81f7dbc2186b}
+@mozilla.org/network/protocol/about;1?what=cache,{9158c470-86e4-11d4-9be2-00e09872a416}
+@mozilla.org/gfx/printsettings-service;1,{841387c8-72e6-484b-9296-bf6eea80d58a}
+@mozilla.org/intl/unicode/decoder;1?charset=IBM866,{ba6151a9-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/content/syncload-dom-service;1,{0e4e7d00-f71a-439f-9178-1a71ff11b55f}
+@mozilla.org/intl/unicode/encoder;1?charset=us-ascii,{ba6151ba-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=TIS-620,{c5de4da2-d667-42d2-b8c2-efdbcf3302ef}
+@mozilla.org/uriloader/content-handler;1?type=text/html,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/security/nsCertTree;1,{4ea60761-31d6-491d-9e34-4b53a26c416c}
+@mozilla.org/xul/xul-template-builder;1,{3d262d00-8b5a-11d2-8eb0-00805f29f370}
+@mozilla.org/inspector/flasher;1,{9286e71a-621a-4b91-851e-9984c1a2e81a}
+@mozilla.org/security/crypto;1,{929d9320-251e-11d4-8a7c-006008c844c3}
+@mozilla.org/fuel/application;1,{fe74cf80-aa2d-11db-abbd-0800200c9a66}
+@mozilla.org/url-classifier/hashcompleter;1,{786e0a0e-e035-4600-8ee0-365a63a80b80}
+@mozilla.org/intl/converter-output-stream;1,{ff8780a5-bbb1-4bc5-8ee7-057e7bc5c925}
+@mozilla.org/embeddor.implemented/bookmark-charset-resolver;1,{88cecbb7-6c63-4b3b-8cd4-84f3b8228c69}
+@mozilla.org/intl/stringcharsetdetect;1?type=zhcn_parallel_state_machine,{ea06d4e5-2b3d-11d3-b3bf-00805f8a6670}
+@mozilla.org/find/find_service;1,{5060b803-340e-11d5-be5b-b3e063ec6a3c}
+@mozilla.org/editor/editingsession;1,{bc26ff01-f2bd-11d4-a73c-e5a4b5a8bdfc}
+@mozilla.org/xbl;1,{64f300a1-c88c-11d3-97fb-00400553eef0}
+@mozilla.org/uriloader/dbus-handler-app;1,{6c3c274b-4cbf-4bb5-a635-05ad2cbb6535}
+@mozilla.org/intl/unicode/encoder;1?charset=GEOSTD8,{6394eebe-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/content-pref/hostname-grouper;1,{8df290ae-dcaa-4c11-98a5-2429a4dc97bb}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-romanian,{6394eeb8-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/network/util;1,{9ac9e770-18bc-11d3-9337-00104ba0fd40}
+@mozilla.org/intl/unicode/encoder;1?charset=x-ttf-cmex,{e91f9440-e076-11d3-b32f-004005a7a7e4}
+@mozilla.org/intl/converter-input-stream;1,{2bc2ad62-ad5d-4b7b-a9db-f74ae203c527}
+@mozilla.org/network/url-parser;1?auth=maybe,{ff41913b-546a-4bff-9201-dc9b2c032eba}
+@mozilla.org/netwerk/global-channel-event-sink;1,{7ee2a4c0-4b93-17d3-ba18-0060b0f199a2}
+@mozilla.org/layout/documentEncoder;1?type=image/svg+xml,{e7ba1480-1dea-11d3-830f-00104bed045e}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-ce,{7b8556b0-ec79-11d2-8aac-00600811a836}
+@mozilla.org/permissionmanager;1,{4f6b5e00-0c36-11d5-a535-0010a401eb10}
+@mozilla.org/toolkit/crash-reporter;1,{95d89e3e-a169-41a3-8e56-719978e15b12}
+@mozilla.org/DOM/Level2/CSS/computedStyleDeclaration;1,{ecea1b28-ae54-4047-8bbe-c624235106b4}
+@mozilla.org/safebrowsing/application;1,{c64d0bcb-8270-4ca7-a0b3-3380c8ffecb5}
+@mozilla.org/network/application-cache-namespace;1,{b00ed78a-04e2-4f74-8e1c-d1af79dfd12f}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-8,{660d8ca9-f763-11d2-8aad-00600811a836}
+@mozilla.org/uriloader/content-handler;1?type=image/x-icon,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/accessibleRetrieval;1,{663ca4a8-d219-4000-925d-d8f66406b626}
+@mozilla.org/intl/stringcharsetdetect;1?type=cjk_parallel_state_machine,{fcacef22-2b40-11d3-b3bf-00805f8a6670}
+@mozilla.org/js/jsd/debugger-service;1,{f1299dc2-1dd1-11b2-a347-ee6b7660e048}
+@mozilla.org/image/encoder;2?type=image/png,{38d1592e-b81e-432b-86f8-471878bbfe07}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-cyrillic,{6394eeb9-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/gfx/devicecontextspec;1,{d3f69889-e13a-4321-980c-a39332e21f34}
+@mozilla.org/nsGeneratingKeypairInfoDialogs;1,{518e071f-1dd2-11b2-937e-c45f14def778}
+@mozilla.org/cookie/permission;1,{ef565d0a-ab9a-4a13-9160-0644cdfd859a}
+@mozilla.org/uriloader/content-handler;1?type=image/bmp,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mathematica4,{87ed1160-e2f2-11d3-b32f-004005a7a7e4}
+@mozilla.org/gnome-gconf-service;1,{d96d5985-a13a-4bdc-9386-ef348d7a97a1}
+@mozilla.org/widget/appshell/gtk;1,{2d96b3df-c051-11d1-a827-0040959a28c9}
+@mozilla.org/xhtmlparanoidfragmentsink;1,{2d78bbf0-e26c-482b-92b3-78a7b2afc8f7}
+@mozilla.org/intl/unicode/decoder;1?charset=GB2312,{379c2774-ec77-11d2-8aac-00600811a836}
+@mozilla.org/image/loader;1,{9f6a0d2e-1dd1-11b2-a5b8-951f13c846f7}
+@mozilla.org/profile/migrator;1?app=browser&type=seamonkey,{9a28ffa7-e6ef-4b52-a127-6ad951de8e9b}
+@mozilla.org/uriloader/psm-external-content-listener;1,{c94f4a30-64d7-11d4-9960-00b0d02354a0}
+@mozilla.org/uriloader/content-handler;1?type=image/vnd.microsoft.icon,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/intl/unicode/encoder;1?charset=x-koreanjamo-0,{47433d1d-d9a7-4954-994f-f7a05cf87c2e}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1257,{a578e0a2-f76b-11d2-8aad-00600811a836}
+@mozilla.org/widget/window/gtk;1,{2d96b3d0-c051-11d1-a827-0040959a28c9}
+@mozilla.org/widget/printdialog-service;1,{06beec76-a183-4d9f-85dd-085f26da565a}
+@mozilla.org/login-manager/prompter;1,{8aa66d77-1bbb-45a6-991e-b8f47751c291}
+@mozilla.org/network/protocol;1?name=gopher,{44588c1f-2ce8-4ad8-9b16-dfb9d9d513a7}
+@mozilla.org/intl/unicode/decoder;1?charset=KOI8-R,{6394eea5-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-romanian,{6394eea8-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/network/standard-url;1,{de9472d0-8034-11d3-9399-00104ba0fd40}
+@mozilla.org/updates/item;1,{f3294b1c-89f4-46f8-98a0-44e1eae92518}
+@mozilla.org/intl/charsetdetect;1?type=zhcn_parallel_state_machine,{ea06d4e2-2b3d-11d3-b3bf-00805f8a6670}
+@mozilla.org/feed-processor;1,{26acb1f0-28fc-43bc-867a-a46aabc85dd4}
+@mozilla.org/security/cipherinfo;1,{ec693a6f-0832-49dd-877c-89f6552df5de}
+@mozilla.org/network/protocol;1?name=moz-anno,{e8b8bdb7-c96c-4d82-9c6f-2b3c585ec7ea}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-gujarati,{6803cacb-1e3b-11d5-a145-005004832142}
+@mozilla.org/xmlextras/xmlserializer;1,{a6cf9124-15b3-11d2-932e-00805f8add32}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-8,{660d8ca4-f763-11d2-8aad-00600811a836}
+@mozilla.org/layout/xul-boxobject-container;1,{dca9d7c3-7b6a-4490-ad6d-2699a8d683cd}
+@mozilla.org/streamconv;1?from=multipart/mixed&to=*/*,{7584ce90-5b25-11d3-a175-0050041caf44}
+@mozilla.org/network/auth-module;1?name=kerb-gss,{dc8e21a0-03e4-11da-8cd6-0800200c9a66}
+@mozilla.org/layout/contentserializer;1?mimetype=application/xhtml+xml,{4aef38b7-6364-4e23-a5e7-12f837fbbd9c}
+@mozilla.org/appshell/appShellService;1,{0099907d-123c-4853-a46a-43098b5fb68c}
+@mozilla.org/network/protocol/about;1?what=mozilla,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/js/jsd/app-start-observer;2,{2fd6b7f6-eb8c-4f32-ad26-113f2c02d0fe}
+@mozilla.org/network/protocol/about;1?what=plugins,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/intl/unicharutil;1,{cc10c750-9ec3-11d2-b3ae-00805f8a6670}
+@mozilla.org/browser/search-service;1,{7319788a-fe93-4db3-9f39-818cf08f4256}
+@mozilla.org/intl/unicode/decoder;1?charset=gb18030,{a59da935-4091-11d5-a145-005004832142}
+@mozilla.org/browser/feeds/sniffer;1,{06893e69-71d8-4b23-81eb-80314daf3e66}
+@mozilla.org/image/decoder;2?type=image/xbm,{dbfd145d-3298-4f3c-902f-2c5e1a1494ce}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-greek,{7b8556a3-ec79-11d2-8aac-00600811a836}
+@mozilla.org/network/protocol/about;1?what=logo,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/intl/unicode/encoder;1?charset=T.61-8bit,{ba6151af-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=T.61-8bit,{ba6151b4-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/plugin/manager;1,{ce768990-5a4e-11d2-8164-006008119d7a}
+@mozilla.org/intl/unicode/encoder;1?charset=IBM855,{2d524fd8-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-ce,{7b8556a2-ec79-11d2-8aac-00600811a836}
+@mozilla.org/rdf/datasource;1?name=composite-datasource,{e638d761-8687-11d2-b530-000000000000}
+@mozilla.org/satchel/form-history;1,{a2059c0e-5a58-4c55-ab7c-26f0557546ef}
+@mozilla.org/nsClientAuthDialogs;1,{518e071f-1dd2-11b2-937e-c45f14def778}
+@mozilla.org/intl/datetimeformat;1,{0704e7c0-a758-11d2-9119-006008a6edf6}
+@mozilla.org/nullprincipal;1,{dd156d62-d26f-4441-9cdb-e8f09107c273}
+@mozilla.org/dom/window-controller;1,{7bd05c78-6a26-11d7-b16f-0003938a9d96}
+@mozilla.org/inspector/deep-tree-walker;1,{bfcb82c2-5611-4318-90d6-baf4a7864252}
+@mozilla.org/intl/charsetdetect;1?type=zh_parallel_state_machine,{fcacef23-2b40-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/collation-factory;1,{a1b72850-a999-11d2-9119-006008a6edf6}
+@mozilla.org/layout/contentserializer;1?mimetype=text/plain,{6030f7ef-32ed-46a7-9a63-6a5d3f90445f}
+@mozilla.org/inspector/dom-view;1,{fb5c1775-1bbd-4b9c-abb0-ae7acd29e87e}
+@mozilla.org/embeddor.implemented/web-content-handler-registrar;1,{792a7e82-06a0-437c-af63-b2d12e808acc}
+@mozilla.org/network/protocol/about;1?what=blocked,{c64d0bcb-8270-4ca7-a0b3-3380c8ffecb5}
+@mozilla.org/offlinecacheupdate;1,{e56f5e01-c7cc-4675-a9d7-b8f1e4127295}
+@mozilla.org/embedcomp/controller-command-table;1,{670ee5da-6ad5-11d7-9950-000393636592}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-roman,{7b8556a1-ec79-11d2-8aac-00600811a836}
+@mozilla.org/image/request;1,{20557898-1dd2-11b2-8f65-9c462ee2bc95}
+@mozilla.org/autoconfiguration;1,{e036c738-1dd1-11b2-9392-9d94aa74b0c5}
+@mozilla.org/network/protocol;1?name=wyciwyg,{e7509b46-2eb2-410a-9d7c-c3ce73284d01}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-turkish,{7b8556b2-ec79-11d2-8aac-00600811a836}
+@mozilla.org/streamconv;1?from=uncompressed&to=deflate,{461cd5dd-73c6-47a4-8cc3-603b37d84a61}
+@mozilla.org/svg/svg-document;1,{b7f44954-11d1-11b2-8c2e-c2feab4186bc}
+@mozilla.org/rdf/serializer;1?format=ntriples,{0a5cd734-eb65-4d14-88a0-9f0bb2aba206}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1252,{7b8556ac-ec79-11d2-8aac-00600811a836}
+@mozilla.org/network/protocol;1?name=moz-gnomevfs,{9b6dc177-a2e4-49e1-9c98-0a8384de7f6c}
+@mozilla.org/intl/charsetdetect;1?type=zhtw_parallel_state_machine,{ea06d4e3-2b3d-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-10,{ba6151b0-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/uriloader/content-handler;1?type=application/http-index-format,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/network/simple-stream-listener;1,{fb8cbf4e-4701-4ba1-b1d6-5388e041fb67}
+@mozilla.org/browser/directory-provider;1,{6deb193c-f87d-4078-bc78-5e64655b4d62}
+@mozilla.org/layout/xmlfragmentsink;1,{4b664e54-72a2-4bbf-a5c2-66d4dc3066a0}
+@mozilla.org/intl/unicode/decoder;1?charset=VISCII,{6394eeae-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/layout/xul-boxobject-scrollbox;1,{56e2ada8-4631-11d4-ba11-001083023c1e}
+@mozilla.org/network/load-group;1,{e1c61582-2a84-11d3-8cce-0060b0fc14a3}
+@mozilla.org/layout/xul-boxobject-tree;1,{3b581fd4-3497-426c-8f61-3658b971cb80}
+@mozilla.org/alerts-service;1,{a0ccaaf8-09da-44d8-b250-9ac3e93c8117}
+@mozilla.org/intl/unicode/encoder;1?charset=x-euc-tw,{379c2776-ec77-11d2-8aac-00600811a836}
+@mozilla.org/browser/shell-service;1,{63c7b9f4-0cc8-43f8-b666-0a661655cb73}
+@mozilla.org/intl/unicode/encoder;1?charset=x-adobe-euro,{822cb9ae-6421-4484-b3c3-00805f8a6670}
+@mozilla.org/widget/lookandfeel;1,{a61e6398-2057-40fd-9c81-873b908d24e7}
+@mozilla.org/browser/placesTransactionsService;1,{c0844a84-5a12-4808-80a8-809cb002bb4f}
+@mozilla.org/intl/unicode/encoder;1?charset=IBM862,{2d524fda-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/network/file-output-stream;1,{c272fee0-c7e9-11d3-8cda-0060b0fc14a3}
+@mozilla.org/network/protocol/about;1?what=credits,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1258,{6394eea3-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/network/protocol;1?name=about,{9e3b6c90-2f75-11d3-8cd0-0060b0fc14a3}
+@mozilla.org/content/style-sheet-service;1,{fcca6f83-9f7d-44e4-a74b-b59433e6c8c3}
+@mozilla.org/uriloader/content-handler;1?type=image/png,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/chrome/chrome-registry;1,{47049e42-1d87-482a-984d-56ae185e367a}
+@mozilla.org/appshell/trytoclose;1,{b69155f4-a8bf-453d-8653-91d1456e1d3d}
+@mozilla.org/image/decoder;2?type=image/x-png,{36fa00c2-1dd2-11b2-be07-d16eeb4c50ed}
+@mozilla.org/cookieService;1,{c375fa80-150f-11d6-a618-0010a401eb10}
+@mozilla.org/principal;1,{36102b6b-7b62-451a-a1c8-a0d456c92dc5}
+@mozilla.org/nsCMSDecoder;1,{9dcef3a4-a3bc-11d5-ba47-00108303b117}
+@mozilla.org/intl/unicode/encoder;1?charset=EUC-JP,{45c23a20-d71c-11d2-8aac-00600811a836}
+@mozilla.org/crypto/fips-info-service;1,{ff9fbcd7-9517-4334-b97a-ceed78909974}
+@mozilla.org/intl/charsetdetect;1?type=ja_parallel_state_machine,{12bb8f1b-2389-11d3-b3bf-00805f8a6670}
+@mozilla.org/content/element/html;1?name=audio,{1d40026b-4c44-4f6f-b158-26bb5e9c65e9}
+@mozilla.org/security/script/nameset;1,{7c02eadc-0076-4d03-998d-80d779c48589}
+@mozilla.org/network/protocol;1?name=moz-icon,{d0f9db12-249c-11d5-9905-001083010e9b}
+@mozilla.org/uriloader/handler-service;1,{32314cc8-22f7-4f7f-a645-1a45453ba6a6}
+@mozilla.org/security/pkcs11moduledb;1,{ff9fbcd7-9517-4334-b97a-ceed78909974}
+@mozilla.org/widgets/child_window/gtk;1,{2d96b3d1-c051-11d1-a827-0040959a28c9}
+@mozilla.org/autocomplete/search;1?name=form-history,{895db6c7-dbdf-40ea-9f64-b175033243dc}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-5,{660d8ca7-f763-11d2-8aad-00600811a836}
+@mozilla.org/browser/places/import-export-service;1,{6fb0c970-e1b1-11db-8314-0800200c9a66}
+@mozilla.org/toolkit/URLFormatterService;1,{e6156350-2be8-11db-a98b-0800200c9a66}
+@mozilla.org/xml/xml-document;1,{a6cf9063-15b3-11d2-932e-00805f8add32}
+@mozilla.org/image/decoder;2?type=image/pjpeg,{5871a422-1dd2-11b2-ab3f-e2e56be5da9c}
+@mozilla.org/network/buffered-input-stream;1,{9226888e-da08-11d3-8cda-0060b0fc14a3}
+@mozilla.org/intl/nslanguageatomservice;1,{a6cf9120-15b3-11d2-932e-00805f8add32}
+@mozilla.org/feed-textconstruct;1,{b992ddcd-3899-4320-9909-924b3e72c922}
+@mozilla.org/intl/unicode/encoder;1?charset=Adobe-Symbol-Encoding,{21dd6a02-413c-11d3-b3c3-00805f8a6670}
+@mozilla.org/image/decoder;2?type=image/x-icon,{cb3ede1a-0fa5-4e27-aafe-0f7801e5a1f1}
+@mozilla.org/uriloader/content-handler;1?type=application/xhtml+xml,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/security/keyobjectfactory;1,{a39e0e9d-e567-41e3-b12c-5df67f18174d}
+@mozilla.org/intl/unicode/encoder;1?charset=UTF-16LE,{ba6151b5-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/widget/native-key-bindings;1?type=textarea,{2a898043-180f-4c8b-8e54-410c7a540f27}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-15,{6394eeb2-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/spellchecker-inline;1,{9fe5d975-09bd-44aa-a01a-66402ea28657}
+@mozilla.org/network/safe-file-output-stream;1,{a181af0d-68b8-4308-94db-d4f859058215}
+@mozilla.org/streamconv;1?from=uncompressed&to=gzip,{461cd5dd-73c6-47a4-8cc3-603b37d84a61}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-6-E,{495eca47-0a5c-11d4-a135-005004832142}
+@mozilla.org/content/css-parser;1,{2e363d60-872e-11d2-b531-000000000000}
+@mozilla.org/rdf/datasource;1?name=window-mediator,{c744ca3d-840b-460a-8d70-7ce63c51c958}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1250,{7c657d14-ec5e-11d2-8aac-00600811a836}
+@mozilla.org/toolkit/console-clh;1,{2cd0c310-e127-44d0-88fc-4435c9ab4d4b}
+@mozilla.org/transformiix-nodeset;1,{5d5d92cd-6bf8-11d9-bf4a-000a95dc234c}
+@mozilla.org/uriloader/content-handler;1?type=image/svg+xml,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/updates/update-prompt;1,{27aba825-35b5-4018-9fdd-f99250a0e722}
+@mozilla.org/uriloader/content-handler;1?type=image/x-xbitmap,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/intl/unicode/decoder;1?charset=UTF-32BE,{ba6151b3-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/nslocaleservice;1,{c8e518c1-47ae-11d3-91cd-00105aa3f7dc}
+@mozilla.org/rdf/content-sink;1,{0958b101-9ada-11d2-8ebc-00805f29f370}
+@mozilla.org/network/urichecker;1,{cf3a0e06-1dd1-11b2-a904-ac1d6da77a02}
+@mozilla.org/dom/storage;2,{27aecc62-7777-428e-b34c-5973a47b8298}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mtextra,{0cb0d9a0-f503-11d3-b32f-004005a7a7e4}
+@mozilla.org/uriloader/content-handler;1?type=application/vnd.mozilla.xul+xml,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/browser/livemark-service;2,{dca61eb5-c7cd-4df1-b0fb-d0722baba251}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-5,{660d8ca2-f763-11d2-8aad-00600811a836}
+@mozilla.org/intl/unicode/decoder;1?charset=x-user-defined,{9416bfb2-1f93-11d3-b3bf-00805f8a6670}
+@mozilla.org/preferences;1,{dc26e0e0-ca94-11d1-a9a4-00805f8a7ac4}
+@mozilla.org/uriloader/content-handler;1?type=image/jpg,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/network/protocol;1?name=data,{b6ed3030-6183-11d3-a178-0050041caf44}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-8-E,{495eca42-0a5c-11d4-a135-005004832142}
+@mozilla.org/parser/parser-service;1,{a6cf9112-15b3-11d2-932e-00805f8add32}
+@mozilla.org/intl/unicode/encoder;1?charset=x-viet-tcvn5712,{6394eebd-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/browser/httpindex-service;1,{2587e382-1324-11d4-a652-eadbb2be3484}
+@mozilla.org/gfx/fontmetrics;1,{6049b263-c1e6-11d1-a827-0040959a28c9}
+@mozilla.org/intl/stringcharsetdetect;1?type=ukprob,{2002f784-3960-11d3-b3c3-00805f8a6670}
+@mozilla.org/focus-event-suppressor-service;1,{35b2656c-4102-4bc1-876a-fd6cb830787b}
+@mozilla.org/widget/native-key-bindings;1?type=editor,{f916ebfb-78ef-464b-94d0-a6f2ca3200ae}
+@mozilla.org/js/xpc/ContextStackIterator;1,{05bae29d-8aef-486d-84aa-53f48f146811}
+@mozilla.org/browser/session-history-entry;1,{bfd1a791-ad9f-11d3-bdc7-0050040a9b44}
+@mozilla.org/feed-result;1,{072a5c3d-30c6-4f07-b87f-9f63d51403f2}
+@mozilla.org/userinfo;1,{14c13684-1dd2-11b2-9463-bb10ba742554}
+@mozilla.org/xpfe/http-index-format-factory-constructor,{82776710-5690-11d3-be36-00104bde6048}
+@mozilla.org/intl/unicode/encoder;1?charset=IBM852,{2d524fd7-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/browser/nav-history-service;1,{88cecbb7-6c63-4b3b-8cd4-84f3b8228c69}
+@mozilla.org/gnome-vfs-service;1,{5f43022c-6194-4b37-b26d-e41024625264}
+@mozilla.org/nsFormSigningDialog;1,{a4bd2161-7892-4389-8d5a-3111a6d17ec7}
+@mozilla.org/security/hmac;1,{a496d0a2-dff7-4e23-bd65-1ca742fa178a}
+@mozilla.org/js/xpc/ID;1,{f24a14f0-4fa1-11d3-9894-006008962422}
+@mozilla.org/geolocation/service;1,{0404d02a-01ca-aaab-4762-944b1bf2f7b5}
+@mozilla.org/intl/stringcharsetdetect;1?type=zhtw_parallel_state_machine,{ea06d4e6-2b3d-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-roman,{7b8556af-ec79-11d2-8aac-00600811a836}
+@mozilla.org/nsCMSSecureMessage;1,{5fb907e0-1dd2-11b2-a7c0-f14c416a62a1}
+@mozilla.org/embedding/browser/nsWebBrowserPersist;1,{7e677795-c582-4cd1-9e8d-8271b3474d2a}
+@mozilla.org/toolkit/remote-service;1,{c0773e90-5799-4eff-ad03-3ebcd85624ac}
+@mozilla.org/uriloader/content-handler;1?type=image/gif,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/intl/stringbundle;1,{d85a17c1-aa7c-11d2-9b8c-00805f8a16d9}
+@mozilla.org/user_cert_picker;1,{735959a1-af01-447e-b02d-56e968fa52b4}
+@mozilla.org/browser/shistory;1,{7294fe9c-14d8-11d5-9882-00c04fa02f40}
+@mozilla.org/intl/unicode/encoder;1?charset=UTF-7,{77cfaaf2-1cf4-11d3-8aaf-00600811a836}
+@mozilla.org/gfx/devicecontext;1,{6049b262-c1e6-11d1-a827-0040959a28c9}
+@mozilla.org/browser/final-clh;1,{47cd0651-b1be-4a0f-b5c4-10e5a573ef71}
+@mozilla.org/network/input-stream-pump;1,{ccd0e960-7947-4635-b70e-4c661b63d675}
+@mozilla.org/embedcomp/prompt-service;1,{a2112d6a-0e28-421f-b46a-25c0b308cbd0}
+@mozilla.org/intl/entityconverter;1,{9e9b565a-8e52-4c1a-8805-b2b91655f874}
+@mozilla.org/intl/unicode/decoder;1?charset=x-imap4-modified-utf7,{b57f97c1-0d70-11d3-8aae-00600811a836}
+@mozilla.org/intl/unicode/encoder;1?charset=x-user-defined,{9416bfb4-1f93-11d3-b3bf-00805f8a6670}
+@mozilla.org/typeaheadfind;1,{e7f70966-9a37-48d7-8aeb-35998f31090e}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-13,{ba6151b1-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mathematica2,{7e6e57c0-e2f2-11d3-b32f-004005a7a7e4}
+@mozilla.org/intl/unicode/decoder;1?charset=x-johab,{d9b1f97f-cfa0-80b6-fb92-9972e48e3dcc}
+@mozilla.org/prefetch-service;1,{6b8bdffc-3394-417d-be83-a81b7c0f63bf}
+@mozilla.org/embedcomp/nbalert-service;1,{a2112d6a-0e28-421f-b46a-25c0b308cbd0}
+@mozilla.org/network/socket-provider-service;1,{ed394ba0-5472-11d3-bbc8-0000861d1237}
+@mozilla.org/zipwriter;1,{430d416c-a722-4ad1-be98-d9a445f85e3f}
+@mozilla.org/rdf/datasource;1?name=local-store,{df71c6f0-ec53-11d2-bdca-000064657374}
+@mozilla.org/preferences-service;1,{1cd91b88-1dd2-11b2-92e1-ed22ed298000}
+@mozilla.org/nsSSLCertErrorDialog;1,{518e071f-1dd2-11b2-937e-c45f14def778}
+@mozilla.org/streamconv;1?from=gzip&to=uncompressed,{66230b2b-17fa-4bd3-abf4-07986151022d}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1255,{ba6151a1-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/scriptableunicodeconverter,{0a698c44-3bff-11d4-9649-00c0ca135b4e}
+@mozilla.org/nsCertPickDialogs;1,{518e071f-1dd2-11b2-937e-c45f14def778}
+@mozilla.org/content/range-utils;1,{a6cf9126-15b3-11d2-932e-00805f8add32}
+@mozilla.org/editor/txtsrvfiltermail;1,{7fbd2146-5ff4-4674-b069-a7bbce66e773}
+@mozilla.org/network/protocol;1?name=jar,{c7e410d4-85f2-11d3-9f63-006008a6efe9}
+@mozilla.org/pref-relativefile;1,{2f977d4f-5485-11d4-87e2-0010a4e75ef2}
+@mozilla.org/gfx/printsession;1,{2f977d53-5485-11d4-87e2-0010a4e75ef2}
+@mozilla.org/mime;1,{a7f800e0-4306-11d4-98d0-001083010e9b}
+@mozilla.org/image/decoder;2?type=image/x-xbitmap,{dbfd145d-3298-4f3c-902f-2c5e1a1494ce}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1258,{6394eeb3-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/webshell;1,{a6cf9059-15b3-11d2-932e-00805f8add32}
+@mozilla.org/intl/charsetdetectionadaptor;1,{12bb8f17-2389-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=VISCII,{6394eebf-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/profile/migrator;1?app=browser&type=phoenix,{78481e4a-50e4-4489-b68a-ef82670ed63f}
+@mozilla.org/intl/unicode/encoder;1?charset=Big5-HKSCS,{ba6151bc-ec62-11d2-8aac-00600811a836}
+@mozilla.org/streamconv;1?from=deflate&to=uncompressed,{66230b2b-17fa-4bd3-abf4-07986151022d}
+@mozilla.org/oji/jvm-auth-tools;1,{d8e716f9-c96e-4e84-ab12-980f5567e2a4}
+@mozilla.org/layout/htmlsanitizer;1,{feca3c34-205e-4ae5-bd1c-03c686ff012b}
+@mozilla.org/cookiemanager;1,{aaab6710-0f2c-11d5-a53b-0010a401eb10}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-2,{7b8556a6-ec79-11d2-8aac-00600811a836}
+@mozilla.org/autocomplete/search;1?name=search-autocomplete,{aa892eb4-ffbf-477d-9f9a-06c995ae9f27}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mathematica1,{758e4f20-e2f2-11d3-b32f-004005a7a7e4}
+@mozilla.org/network/url-parser;1?auth=no,{78804a84-8173-42b6-bb94-789f0816a810}
+@mozilla.org/embedcomp/printingprompt-service;1,{e042570c-62de-4bb6-a6e0-798e3c07b4df}
+@mozilla.org/image/encoder;2?type=image/jpeg,{ac2bb8fe-eeeb-4572-b40f-be03932b56e0}
+@mozilla.org/network/network-link-service;1,{75a500a2-0030-40f7-86f8-63f225b940ae}
+@mozilla.org/intl/wbrk;1,{2bf64765-997f-450d-af96-3028d1a902b0}
+@mozilla.org/charset-converter-manager;1,{3c1c0163-9bd0-11d3-9d09-0050040007b2}
+@mozilla.org/security/streamcipher;1,{dbfcbe4a-10f7-4d6f-a481-68e6d6b71d21}
+@mozilla.org/login-manager/loginInfo;1,{0f2f347c-1e4f-40cc-8efd-792dea70a85e}
+@mozilla.org:/content/content-area-dragdrop;1,{1f34bc80-1bc7-11d6-a384-d705dd0746fc}
+@mozilla.org/layout/documentEncoder;1?type=text/html,{e7ba1480-1dea-11d3-830f-00104bed045e}
+@mozilla.org/rdf/rdf-service;1,{bfd05264-834c-11d2-8eac-00805f29f370}
+@mozilla.org/security/certoverride;1,{67ba681d-5485-4fff-952c-2ee337ffdcd6}
+@mozilla.org/layout/content-policy;1,{0e3afd3d-eb60-4c2b-963b-56d7c439f124}
+@mozilla.org/secure_browser_ui;1,{cc75499a-1dd1-11b2-8a82-ca410ac907b8}
+@mozilla.org/browser/history-entry;1,{a41661d5-1417-11d5-9882-00c04fa02f40}
+@mozilla.org/htmlparanoidfragmentsink;1,{a47e9526-6e48-4574-9d6c-3164e271f74e}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-10,{ba6151ab-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/widget/dragservice;1,{8b5314bb-db01-11d2-96ce-0060b0fb9956}
+@mozilla.org/channelclassifier,{ce02d538-0217-47a3-a589-b51790fdd8ce}
+@mozilla.org/layout/xul-boxobject-menu;1,{aa40253b-4c42-4056-8132-37bcd07862fd}
+@mozilla.org/embedcomp/base-command-controller;1,{bf88b48c-fd8e-40b4-ba36-c7c3ad6d8ac9}
+@mozilla.org/intl/unicode/decoder;1?charset=IBM864i,{2d524fdc-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/wifi/monitor;1,{3ff8fb9f-ee63-48df-89f0-dace0242fd82}
+@mozilla.org/plugin/host;1,{adea1880-1a8e-11d2-a82e-0040959a28c9}
+@mozilla.org/embedcomp/command-params;1,{f7fa4581-238e-11d5-a73c-ab64fb68f2bc}
+@mozilla.org/uriloader/content-handler;1?type=text/xml,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/intl/unicode/encoder;1?charset=IBM857,{2d524fd9-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/layout/xul-boxobject-listbox;1,{c2710d40-6f4d-4b7f-9778-76ae5166648c}
+@mozilla.org/uriloader;1,{9f6d5d40-90e7-11d3-af80-00a024ffc08c}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1255,{ba6151a3-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=x-tamilttf-0,{a431b276-f77d-4b83-9b37-872cf2fbcc2a}
+@mozilla.org/feed-generator;1,{414af362-9ad8-4296-898e-62247f25a20e}
+@mozilla.org/intl/lbrk;1,{2bf64764-997f-450d-af96-3028d1a902b0}
+@mozilla.org/uriloader/local-handler-app;1,{bc0017e3-2438-47be-a567-41db58f17627}
+@mozilla.org/intl/unicode/encoder;1?charset=EUC-KR,{379c2778-ec77-11d2-8aac-00600811a836}
+@mozilla.org/xmlextras/xmlhttprequest;1,{d164e770-4157-11d4-9a42-000064657374}
+@mozilla.org/layout/documentEncoder;1?type=text/plain,{e7ba1480-1dea-11d3-830f-00104bed045e}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-hebrew,{6803cacd-1e3b-11d5-a145-005004832142}
+@mozilla.org/filepicker;1,{bd57cee8-1dd1-11b2-9fe7-95cf4709aea3}
+@mozilla.org/accessibilityService;1,{de401c37-9a7f-4278-a6f8-3de2833989ef}
+@mozilla.org/xml/xpointer;1?scheme=xpath1,{0c351177-0159-4500-86b0-a219dfde4258}
+@mozilla.org/network/protocol/about;1?what=sessionrestore,{7c65e6f0-7605-11dd-ad8b-0800200c9a66}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-gurmukhi,{6803cace-1e3b-11d5-a145-005004832142}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1250,{7b8556aa-ec79-11d2-8aac-00600811a836}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-16,{a0f827e1-8ab6-11d5-a14b-005004832142}
+@mozilla.org/content/xmlhttprequest-bad-cert-handler;1,{dbded6ec-edbf-4054-a834-287b82c260f9}
+@mozilla.org/layout/htmlfragmentsink;2,{13111d00-ce81-11d6-8082-ecf3665af67c}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-2,{7c657d11-ec5e-11d2-8aac-00600811a836}
+@mozilla.org/image/decoder;2?type=image/bmp,{78c61626-4d1f-4843-9364-4652d98ff6e1}
+@mozilla.org/image/decoder;2?type=image/jpeg,{5871a422-1dd2-11b2-ab3f-e2e56be5da9c}
+@mozilla.org/feed-entry;1,{8e4444ff-8e99-4bdd-aa7f-fb3c1c77319f}
+@mozilla.org/streamconv;1?from=x-gzip&to=uncompressed,{66230b2b-17fa-4bd3-abf4-07986151022d}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-IR-111,{9416bfb3-1f93-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=IBM864,{2d524fdb-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/content/namespacemanager;1,{d9783472-8fe9-11d2-9d3c-0060088f9ff7}
+@mozilla.org/rdf/datasource;1?name=xml-datasource,{7baf62e0-8e61-11d2-8eb1-00805f29f370}
+@mozilla.org/uriloader/content-handler;1?type=image/jpeg,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/network/proxy-auto-config;1,{63ac8c66-1dd2-11b2-b070-84d00d3eaece}
+@mozilla.org/system-preferences;1,{549abb24-7c9d-4aba-915e-7ce0b716b32f}
+@mozilla.org/systemprincipal;1,{4a6212db-accb-11d3-b765-0060b0b6cecb}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-ukrainian,{6394eeba-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/login-manager/storage/legacy;1,{e09e4ca6-276b-4bb4-8b71-0635a3a2a007}
+@mozilla.org/streamconv;1?from=uncompressed&to=x-gzip,{461cd5dd-73c6-47a4-8cc3-603b37d84a61}
+@mozilla.org/network/incremental-download;1,{a62af1ba-79b3-4896-8aaf-b148bfce4280}
+@mozilla.org/xtf/xtf-service;1,{4ec832da-6ae7-4185-807b-daddcb5da37a}
+@mozilla.org/embedcomp/command-manager;1,{64edb481-0c04-11d5-a73c-e964b968b0bc}
+@mozilla.org/intl/unicode/decoder;1?charset=IBM850,{2d524fd0-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/intl/stringcharsetdetect;1?type=ruprob,{2002f783-3960-11d3-b3c3-00805f8a6670}
+@mozilla.org/network/file-input-stream;1,{be9a53ae-c7e9-11d3-8cda-0060b0fc14a3}
+@mozilla.org/no-data-protocol-content-policy;1,{ac9e3e82-bfbd-4f26-941e-f58c8ee178c1}
+@mozilla.org/libjar/zip-reader;1,{7526a738-9632-11d3-8cd9-0060b0fc14a3}
+@mozilla.org/document-charset-info;1,{d25e0511-2bae-11d4-9d10-0050040007b2}
+@mozilla.org/network/protocol/about;1?what=privatebrowsing,{d92a18c8-234d-49e4-9936-3b7e020c29a2}
+@mozilla.org/download-manager;1,{edb0490e-1dd1-11b2-83b8-dbf8d85906a6}
+@mozilla.org/xre/runtime;1,{95d89e3e-a169-41a3-8e56-719978e15b12}
+@mozilla.org/readconfig;1,{ba5bc4c6-1dd1-11b2-bb89-b844c6ec0339}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-7,{7b8556a8-ec79-11d2-8aac-00600811a836}
+@mozilla.org/content/subtree-content-iterator;1,{a6cf90e5-15b3-11d2-932e-00805f8add32}
+@mozilla.org/intl/unicode/decoder;1?charset=UTF-16BE,{ba6151b2-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/network/protocol;1?name=file,{fbc81170-1f69-11d3-9344-00104ba0fd40}
+@mozilla.org/offlinecacheupdate-service;1,{ec06f3fc-70db-4ecd-94e0-a6e91ca44d8a}
+@mozilla.org/browser/nav-bookmarks-service;1,{9de95a0c-39a4-4d64-9a53-17940dd7cabb}
+@mozilla.org/widget/image-to-gdk-pixbuf;1,{fc2389b8-c650-4093-9e42-b05e5f0685b7}
+@mozilla.org/txttohtmlconv;1,{77c0e42a-1dd2-11b2-8ebf-edc6606f2f4b}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-devanagari,{6803cac4-1e3b-11d5-a145-005004832142}
+@mozilla.org/embedding/browser/nsWebBrowser;1,{f1eac761-87e9-11d3-af80-00a024ffc08c}
+@mozilla.org/network/protocol;1?name=https,{dccbe7e4-7750-466b-a557-5ea36c8ff24e}
+@mozilla.org/intl/unicode/decoder;1?charset=Shift_JIS,{0e6892c1-a9ad-11d2-b3ae-00805f8a6670}
+@mozilla.org/network/http-authenticator;1?scheme=negotiate,{75c80fd0-accb-432c-af59-ec60668c3990}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-cyrillic,{6394eea9-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-hebrew,{6803cacc-1e3b-11d5-a145-005004832142}
+@mozilla.org/streamconv;1?from=application/x-unknown-content-type&to=*/*,{7d7008a0-c49a-11d3-9b22-0080c7cb1080}
+@mozilla.org/rdf/resource-factory;1,{0f78da56-8321-11d2-8eac-00805f29f370}
+@mozilla.org/intl/unicode/encoder;1?charset=UTF-32BE,{ba6151ae-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/rdf/datasource;1?name=charset-menu,{42c52b81-a200-11d3-9d0b-0050040007b2}
+@mozilla.org/embedcomp/appstartup-notifier;1,{1f59b001-02c9-11d5-ae76-cc92f7db9e03}
+@mozilla.org/intl/metacharset;1,{218f2ac0-0a48-11d3-b3ba-00805f8a6670}
+@mozilla.org/feed;1,{5d0cfa97-69dd-4e5e-ac84-f253162e8f9a}
+@mozilla.org/content/pre-content-iterator;1,{80d7e247-d4b8-45d7-bb59-6f1dd56f384c}
+@mozilla.org/security/x509certdb;1,{fb0bbc5c-452e-4783-b32c-80124693d871}
+@mozilla.org/view-manager;1,{c95f1831-c376-11d1-b721-00600891d8c9}
+@mozilla.org/image/decoder;2?type=image/png,{36fa00c2-1dd2-11b2-be07-d16eeb4c50ed}
+@mozilla.org/moz/jssubscript-loader;1,{929814d6-1dd2-11b2-8e08-82fa0a339b00}
+@mozilla.org/security/sdr;1,{0c4f1ddc-1dd2-11b2-9d95-f2fdf113044b}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1256,{ba6151a2-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/extensions/manager;1,{8a115faa-7dcb-4e8f-979b-5f53472f51cf}
+@mozilla.org/spellchecker/i18nmanager;1,{aeb8936f-219c-4d3c-8385-d9382daa551a}
+@mozilla.org/intl/unicode/decoder;1?charset=x-gbk,{ba61519e-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-6-I,{495eca44-0a5c-11d4-a135-005004832142}
+@mozilla.org/dirIndex;1,{f6913e2e-1dd1-11b2-84be-f455dee342af}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-croatian,{6394eea7-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/appshell/window-mediator;1,{0659cb83-faad-11d2-8e19-b206620a657c}
+@mozilla.org/network/protocol/about;1?what=rights,{89e9da80-4c03-46a0-a357-cf77bbef98b9}
+@mozilla.org/network/simple-uri;1,{e0da1d70-2f7b-11d3-8cd0-0060b0fc14a3}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-gujarati,{6803caca-1e3b-11d5-a145-005004832142}
+@mozilla.org/intl/unicode/decoder;1?charset=GEOSTD8,{6394eeaf-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-7,{af7a9951-aa48-11d2-b3ae-00805f8a6670}
+@mozilla.org/security/datasignatureverifier;1,{296d76aa-275b-4f3c-af8a-30a4026c18fc}
+@mozilla.org/content/range;1,{56ad2981-8a87-11d2-918c-0080c8e44db5}
+@mozilla.org/network/default-auth-prompt;1,{ca200860-4696-40d7-88fa-4490d423a8ef}
+@mozilla.org/places/sync;1,{c1751cfc-e8f1-4ade-b0bb-f74edfb8ef6a}
+@mozilla.org/gfx/image;1,{6049b260-c1e6-11d1-a827-0040959a28c9}
+@mozilla.org/network/protocol/about;1?what=robots,{e18da21c-a4b8-4be5-98aa-942e1e19f35c}
+@mozilla.org/embedcomp/window-watcher;1,{a21bfa01-f349-4394-a84c-8de5cf0737d0}
+@mozilla.org/network/protocol/about;1?what=licence,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/browser/default-browser-clh;1,{f57899d0-4e2c-4ac6-9e29-50c736103b0c}
+@mozilla.org/layout/documentEncoder;1?type=text/xml,{e7ba1480-1dea-11d3-830f-00104bed045e}
+@mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.feed&to=*/*,{229fa115-9412-4d32-baf3-2fc407f76fb1}
+@mozilla.org/intl/stringcharsetdetect;1?type=ko_parallel_state_machine,{ea06d4e4-2b3d-11d3-b3bf-00805f8a6670}
+@mozilla.org/appshell/component/browser/instance;1,{5551a1e0-5a66-11d3-806a-00600811a9c3}
+@mozilla.org/updates/timer-manager;1,{b322a5c0-a419-484e-96ba-d7182163899f}
+@mozilla.org/uriloader/content-handler;1?type=text/rdf,{5d0ce354-df01-421a-83fb-7ead0990c24e}
+@mozilla.org/widget/clipboard;1,{8b5314ba-db01-11d2-96ce-0060b0fb9956}
+@mozilla.org/scripterror;1,{e38e53b9-5bb0-456a-b553-579370cb1567}
+@mozilla.org/nsCMSEncoder;1,{a15789aa-8903-462b-81e9-4aa2cff4d5cb}
+@mozilla.org/content/element/html;1?name=option,{a6cf90f5-15b3-11d2-932e-00805f8add32}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-13,{ba6151ac-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/spellchecker;1,{8227f019-afc7-461e-b030-9f185d7a0e29}
+@mozilla.org/network/async-stream-copier;1,{e746a8b1-c97a-4fc5-baa4-66607521bd08}
+@mozilla.org/image/cache;1,{9f6a0d2e-1dd1-11b2-a5b8-951f13c846f7}
+@mozilla.org/intl/unicodenormalizer;1,{a665e49a-f3e6-4fed-9f31-f7c568a29899}
+@mozilla.org/editor/editordocstatecontroller;1,{50e95301-17a8-11d4-9f7e-dd530d5f057c}
+@mozilla.org/intl/unicode/decoder;1?charset=UTF-16,{d673255d-1184-400a-b0b5-ee9d1295bd85}
+@mozilla.org/uriclassifierservice,{5eb7c3c1-ec1f-4007-87cc-eefb37d68ce6}
+@mozilla.org/textservices/textservicesdocument;1,{019718e3-cdb5-11d2-8d3c-000000000000}
+@mozilla.org/spellcheck/dir-provider;1,{64d6174c-1496-4ffd-87f2-da2670f88934}
+@mozilla.org/embedcomp/rangefind;1,{471f4944-1dd2-11b2-87ac-90be0a51d609}
+@mozilla.org/login-manager;1,{cb9e0de8-3598-4ed7-857b-827f011ad5d8}
+@mozilla.org/streamconv;1?from=multipart/byteranges&to=*/*,{7584ce90-5b25-11d3-a175-0050041caf44}
+@mozilla.org/network/protocol;1?name=javascript,{bfc310d2-38a0-11d3-8cd3-0060b0fc14a3}
+@mozilla.org/geolocation/prompt;1,{c6e8c44d-9f39-4af7-bcc0-76e38a8310f5}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-8-E,{495eca49-0a5c-11d4-a135-005004832142}
+@mozilla.org/network/protocol;1?name=chrome,{61ba33c0-3031-11d3-8cd0-0060b0fc14a3}
+@mozilla.org/toolkit/command-line;1,{23bcc750-dc20-460b-b2d4-74d8f58d3615}
+@mozilla.org/intl/unicode/encoder;1?charset=x-tscii,{d2800356-c2d7-4e05-a884-79fe566af1cf}
+@mozilla.org/uriloader/external-protocol-service;1,{a7f800e0-4306-11d4-98d0-001083010e9b}
+@mozilla.org/rdf/datasource;1?name=extensions,{69bb8313-2d4f-45ec-97e0-d39da58ecce9}
+@mozilla.org/intl/unicode/decoder;1?charset=UTF-7,{77cfaaf1-1cf4-11d3-8aaf-00600811a836}
+@mozilla.org/browser/annotation-service;1,{5e8d4751-1852-434b-a992-2c6d2a25fa46}
+@mozilla.org/system-preference-service;1,{94f1de09-d0e5-4ca8-94c2-98b049316b7f}
+@mozilla.org/intl/unicode/encoder;1?charset=x-ttf-cmsy,{e332db00-e076-11d3-b32f-004005a7a7e4}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-11,{776588a6-86d5-47e2-b6b3-992810078202}
+@mozilla.org/intl/unicode/encoder;1?charset=x-imap4-modified-utf7,{b57f97c2-0d70-11d3-8aae-00600811a836}
+@mozilla.org/intl/unicode/decoder;1?charset=x-viet-vps,{6394eeb0-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/layout/htmlfragmentsink;1,{d4f2b600-b5c1-11d6-b483-cc97c63e567c}
+@mozilla.org/security/pkcs11;1,{74b7a390-3b41-11d4-8a80-006008c844c3}
+@mozilla.org/layout/xmlfragmentsink;2,{4dc30689-929d-425e-a709-082c6294e542}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-croatian,{6394eeb7-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/content-pref/service;1,{e6a3f533-4ffa-4615-8eb4-d4e72d883fa7}
+@mozilla.org/url-classifier/dbservice;1,{5eb7c3c1-ec1f-4007-87cc-eefb37d68ce6}
+@mozilla.org/intl/unicode/decoder;1?charset=IBM862,{2d524fd4-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/exslt/regexp;1,{18a03189-067b-4978-b4f1-bafe35292ed6}
+@mozilla.org/document-transformer;1?type=xslt,{bacd8ad0-552f-11d3-a9f7-000064657374}
+@mozilla.org/image/decoder;2?type=image/vnd.microsoft.icon,{cb3ede1a-0fa5-4e27-aafe-0f7801e5a1f1}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-IR-111,{9416bfb1-1f93-11d3-b3bf-00805f8a6670}
+@mozilla.org/editor/htmleditor;1,{ed0244e0-c144-11d2-8f4c-006008159b0c}
+@mozilla.org/network/http-auth-manager;1,{36b63ef3-e0fa-4c49-9fd4-e065e85568f4}
+@mozilla.org/xul/xul-document;1,{541afcb2-a9a3-11d2-8ec5-00805f29f370}
+@mozilla.org/url-classifier/jslib;1,{26a4a019-2827-4a89-a85c-5931a678823a}
+@mozilla.org/saxparser/attributes;1,{7bb40992-77eb-43db-9a4e-39d3bcc383ae}
+@mozilla.org/intl/unicode/encoder;1?charset=KOI8-U,{6394eeb6-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-gurmukhi,{6803cacf-1e3b-11d5-a145-005004832142}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-936,{9416bfc0-1f93-11d3-b3bf-00805f8a6670}
+@mozilla.org/transfer;1,{e3fa9d0a-1dd1-11b2-bdef-8c720b597445}
+@mozilla.org/rdf/container-utils;1,{d4214e92-fb94-11d2-bdd8-00104bde6048}
+@mozilla.org/rdf/datasource;1?name=httpindex,{2587e382-1324-11d4-a652-eadbb2be3484}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-874,{6394eea4-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/browser/session-history-transaction;1,{bfd1a792-ad9f-11d3-bdc7-0050040a9b44}
+@mozilla.org/autocomplete/simple-result;1,{2ee3039b-2de4-43d9-93b0-649beacff39a}
+@mozilla.org/scriptableinterfaces;1,{fe4f7592-c1fc-4662-ac83-538841318803}
+@mozilla.org/security/random-generator;1,{be65e2b7-fe46-4e0f-88e0-4b385db4d68a}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-4,{660d8ca6-f763-11d2-8aad-00600811a836}
+@mozilla.org/profile/migrator;1?app=browser&type=dogbert,{24f92fae-f793-473b-8061-713408bd11d5}
+@mozilla.org/network/content-sniffer;1,{7d7008a0-c49a-11d3-9b22-0080c7cb1080}
+@mozilla.org/intl/unicode/decoder;1?charset=HZ-GB-2312,{ba61519a-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/rdf/xml-parser;1,{a4048e94-1dd1-11b2-a676-8a06c086cc7d}
+@mozilla.org/nsTokenPasswordDialogs;1,{518e071f-1dd2-11b2-937e-c45f14def778}
+@mozilla.org/intl/unicode/encoder;1?charset=x-t1-cmsy,{e768ebef-70f9-4fe3-8835-4f4f3fd996e2}
+@mozilla.org/intl/unicode/decoder;1?charset=TIS-620,{66634f68-be19-42d0-a4ca-d1c21fa059b8}
+@mozilla.org/network/protocol;1?name=default,{bd6390c8-fbea-11d4-98f6-001083010e9b}
+@mozilla.org/image/container;1,{27f0682c-ff64-4dd2-ae7a-668e59f2fd38}
+@mozilla.org/toolkit/default-clh;1,{6ebc941a-f2ff-4d56-b3b6-f7d0b9d73344}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-icelandic,{6394eebb-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-2022-JP,{4f76e100-d71c-11d2-8aac-00600811a836}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-16,{a0f827e2-8ab6-11d5-a14b-005004832142}
+@mozilla.org/gfx/fontenumerator;1,{a6cf9115-15b3-11d2-932e-00805f8add32}
+@mozilla.org/network/socket-transport-service;1,{c07e81e0-ef12-11d2-92b6-00105a1b0d64}
+@mozilla.org/content/element/html;1?name=img,{d6008c40-4dad-11d2-b328-00805f8a3859}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1257,{a578e0a4-f76b-11d2-8aac-00600811a836}
+@mozilla.org/browser/download-history;1,{88cecbb7-6c63-4b3b-8cd4-84f3b8228c69}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mac-farsi,{6803cac9-1e3b-11d5-a145-005004832142}
+@mozilla.org/security/keyobject;1,{eae599aa-ecef-49c6-a8af-6ddcc6feb484}
+@mozilla.org/network/stream-listener-tee;1,{831f8f13-7aa8-485f-b02e-77c881cc5773}
+@mozilla.org/gfx/printerenumerator;1,{a6cf9129-15b3-11d2-932e-00805f8add32}
+@mozilla.org/browser/feeds/result-service;1,{2376201c-bbc6-472f-9b62-7548040a61c6}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1253,{af7a9952-aa48-11d2-b3ae-00805f8a6670}
+@mozilla.org/network/protocol/about;1?what=,{1f1ce501-663a-11d3-b7a0-be426e4e69bc}
+@mozilla.org/layout/xul-boxobject-popup;1,{6c392c62-1ab1-4de7-bfc6-ed4f9fc7749a}
+@mozilla.org/nsSecurityWarningDialogs;1,{8d995d4f-adcc-4159-b7f1-e94af72eeb88}
+@mozilla.org/data-document-content-policy;1,{1147d32c-215b-4014-b180-07fe7aedf915}
+@mozilla.org/filepicker/fileview;1,{a5570462-1dd1-11b2-9d19-df30a27fbdc4}
+@mozilla.org/xul/xul-controllers;1,{1f5c1721-7dc3-11d3-bf87-00105a1b0627}
+@mozilla.org/embedcomp/dialogparam;1,{4e4aae11-8901-46cc-8217-dad7c5415873}
+@mozilla.org/layout/xul-boxobject;1,{d750a964-2d14-484c-b3aa-8ed7823b5c7b}
+@mozilla.org/layout/form-processor;1,{0ae53c0f-8ea2-4916-bedc-717443c3e185}
+@mozilla.org/intl/unicode/encoder;1?charset=UTF-8,{7c657d18-ec5e-11d2-8aac-00600811a836}
+@mozilla.org/gfx/screenmanager;1,{c401eb80-f9ea-11d3-bb6f-e732b73ebe7c}
+@mozilla.org/rdf/container;1,{d4214e93-fb94-11d2-bdd8-00104bde6048}
+@mozilla.org/moz/jsloader;1,{6bd13476-1dd2-11b2-bbef-f0ccb5fa64b6}
+@mozilla.org/network/protocol/about;1?what=feeds,{12ff56ec-58be-402c-b057-01f961de969b}
+@mozilla.org/rdf/xml-serializer;1,{0032d852-1dd2-11b2-95f7-e0a1910ed2da}
+@mozilla.org/network/dns-service;1,{b0ff4572-dae4-4bef-a092-83c1b88f6be9}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1256,{ba6151a4-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/content/document-loader-factory;1,{fc886801-e768-11d4-9885-00c04fa0cf4b}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-14,{6394eea1-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=Big5,{efc323e1-ec62-11d2-8aac-00600811a836}
+@mozilla.org/helperapplauncherdialog;1,{f68578eb-6ec2-4169-ae19-8c6243f0abe1}
+@mozilla.org/streamConverters;1,{892ffeb0-3f80-11d3-a16c-0050041caf44}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-4,{660d8ca1-f763-11d2-8aad-00600811a836}
+@mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.video.feed&to=*/*,{229fa115-9412-4d32-baf3-2fc407f76fb1}
+@mozilla.org/intl/unicode/decoder;1?charset=EUC-JP,{3f6fe6a1-ac0a-11d2-b3ae-00805f8a6670}
+@mozilla.org/intl/stringbundle/text-override;1,{6316c6ce-12d3-479e-8f53-e289351412b8}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-2022-JP,{3f6fe6a2-ac0a-11d2-b3ae-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=HZ-GB-2312,{ba61519d-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/browser/shistory-internal;1,{9c47c121-1c6e-4d8f-b904-3ac968116e88}
+@mozilla.org/network/socket;2?type=socks4,{f7c9f5f4-4451-41c3-a28a-5ba2447fbace}
+@mozilla.org/network/buffered-output-stream;1,{9868b4ce-da08-11d3-8cda-0060b0fc14a3}
+@mozilla.org/intl/unicode/encoder;1?charset=IBM866,{ba6151aa-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=x-ttf-cmmi,{73bb7c12-dbab-4ae2-aecf-a0331dec916f}
+@mozilla.org/editor/editorspellchecker;1,{75656ad9-bd13-4c5d-939a-ec6351eea0cc}
+@mozilla.org/intl/collation;1,{aa13e4a0-a5ac-11d2-9119-006008a6edf6}
+@mozilla.org/widget/transferable;1,{8b5314bc-db01-11d2-96ce-0060b0fb9956}
+@mozilla.org/intl/unicode/encoder;1?charset=UTF-16BE,{ba6151ad-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/login-manager/storage/mozStorage;1,{8c2023b9-175c-477e-9761-44ae7b549756}
+@mozilla.org/image/decoder;2?type=image/x-xbm,{dbfd145d-3298-4f3c-902f-2c5e1a1494ce}
+@mozilla.org/network/auth-module;1?name=sys-ntlm,{bc54f001-6eb0-4e32-9f49-7e064d8e70ef}
+@mozilla.org/intl/unicode/encoder;1?charset=hkscs-1,{a59da931-4091-11d5-a145-005004832142}
+@mozilla.org/intl/unicode/encoder;1?charset=x-t1-cmex,{f01cb3e7-4ace-414e-a2b7-eaba03e9c86c}
+@mozilla.org/intl/unicode/decoder;1?charset=IBM852,{2d524fd1-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/network/protocol;1?name=feed,{4f91ef2e-57ba-472e-ab7a-b4999e42d6c0}
+@mozilla.org/layout/contentserializer;1?mimetype=application/vnd.mozilla.xul+xml,{4aef38b7-6364-4e23-a5e7-12f837fbbd9c}
+@mozilla.org/intl/unicode/encoder;1?charset=x-gbk,{ba61519b-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=IBM855,{2d524fd2-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/satchel/form-fill-controller;1,{895db6c7-dbdf-40ea-9f64-b175033243dc}
+@mozilla.org/editor/texteditor;1,{e197cc01-cfe1-11d4-8eb0-87ae406dfd3f}
+@mozilla.org/privatebrowsing-wrapper;1,{136e2c4d-c5a4-477c-b131-d93d7d704f64}
+@mozilla.org/chrome/chrome-native-theme;1,{d930e29b-6909-44e5-ab4b-af10d6923705}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-9,{7b8556a9-ec79-11d2-8aac-00600811a836}
+@mozilla.org/intl/unicode/encoder;1?charset=x-ttf-cmr,{67671792-8e25-4487-b1b7-5073cfa95fee}
+@mozilla.org/nsCMSMessage;1,{a4557478-ae16-11d5-ba4b-00108303b117}
+@mozilla.org/content/dom-selection;1,{c87a37fc-8109-4ce2-a322-8cdec925379f}
+@mozilla.org/network/protocol/about;1?what=crashes,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-2022-KR,{ba61519f-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/editor/htmleditorcontroller;1,{62db0002-dbb6-43f4-8fb7-9d2538bc5747}
+@mozilla.org/profile/migrator;1?app=browser&type=opera,{f34ff792-722e-4490-b195-47d242edca1c}
+@mozilla.org/streamconv;1?from=multipart/x-mixed-replace&to=*/*,{7584ce90-5b25-11d3-a175-0050041caf44}
+@mozilla.org/streamconv;1?from=text/ftp-dir&to=application/http-index-format,{14c0e880-623e-11d3-a178-0050041caf44}
+@mozilla.org/intl/unicode/encoder;1?charset=x-mathematica5,{8a0dce80-e2f2-11d3-b32f-004005a7a7e4}
+@mozilla.org/network/protocol/about;1?what=neterror,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/updates/update-checker;1,{898cdc9b-e43f-422f-9cc4-2f6291b415a3}
+@mozilla.org/intl/unicode/encoder;1?charset=IBM864i,{2d524fdd-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/xul/xul-prototype-cache;1,{3a0a0fc1-8349-11d3-be47-00104bde6048}
+@mozilla.org/intl/unicode/encoder;1?charset=UTF-16,{49b38f12-6193-11d3-b3c5-00805f8a6670}
+@mozilla.org/network/default-prompt;1,{2e41ada0-62b7-4902-b9a6-e4542aa458ba}
+@mozilla.org/intl/unicode/encoder;1?charset=GB2312,{379c2777-ec77-11d2-8aac-00600811a836}
+@mozilla.org/security/pkiparamblock;1,{0bec75a8-1dd2-11b2-863a-f69f77c31371}
+@mozilla.org/toolkit/profile-migrator;1,{4ca3c946-5408-49f0-9eca-3a97d5c67750}
+@mozilla.org/network/auth-module;1?name=negotiate-gss,{96ec4163-efc8-407a-8735-007fb26be4e8}
+@mozilla.org/embedding/browser/content-policy;1,{f66bc334-1dd1-11b2-bab2-90e04fe15c19}
+@mozilla.org/browser/tagging-service;1,{bbc23860-2553-479d-8b78-94d9038334f7}
+@mozilla.org/network/protocol/about;1?what=certerror,{78d2286f-de9d-47ac-9c26-e8675aedf3be}
+@mozilla.org/js/xpc/ContextStack;1,{ff8c4d10-3194-11d3-9885-006008962422}
+@mozilla.org/intl/unicode/encoder;1?charset=jis_0201,{ba615191-1dfa-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=windows-1254,{7c657d17-ec5e-11d2-8aac-00600811a836}
+@mozilla.org/streamconv;1?from=uncompressed&to=rawdeflate,{461cd5dd-73c6-47a4-8cc3-603b37d84a61}
+@mozilla.org/xre/app-info;1,{95d89e3e-a169-41a3-8e56-719978e15b12}
+@mozilla.org/xptinfo/loader;1&type=zip,{0320e073-79c7-4dae-8055-81bed8b8db96}
+@mozilla.org/browser/global-history;2,{88cecbb7-6c63-4b3b-8cd4-84f3b8228c69}
+@mozilla.org/intl/unicode/encoder;1?charset=KOI8-R,{6394eeb5-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/network/protocol/about;1?what=license,{f0acde16-1dd1-11b2-9e35-f5786fff5a66}
+@mozilla.org/intl/utf8converterservice;1,{2b026890-5a2e-4981-ada2-a600358947b4}
+@mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.audio.feed&to=*/*,{229fa115-9412-4d32-baf3-2fc407f76fb1}
+@mozilla.org/transactionmanager;1,{9c8f9601-801a-11d2-98ba-00805f297d89}
+@mozilla.org/nss_errors_service;1,{a277189c-1dd1-11b2-a8c9-e4e8bfb1338e}
+@mozilla.org/saxparser/xmlreader;1,{ab1da296-6125-40ba-96d0-47a8282ae3db}
+@mozilla.org/locale/posix-locale;1,{d92d57c5-ba1d-11d2-af0c-0060089fe59b}
+@mozilla.org/content-dispatch-chooser;1,{e35d5067-95bc-4029-8432-e8f1e431148d}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-9,{7c657d13-ec5e-11d2-8aac-00600811a836}
+@mozilla.org/network/authprompt-adapter-factory;1,{a21bfa01-f349-4394-a84c-8de5cf0737d0}
+@mozilla.org/layout/plaintextsink;1,{6030f7ef-32ed-46a7-9a63-6a5d3f90445f}
+@mozilla.org/gfx/region;1,{da5b130a-1dd1-11b2-ad47-f455b1814a78}
+@mozilla.org/network/http-authenticator;1?scheme=digest,{17491ba4-1dd2-11b2-aae3-de6b92dab620}
+@mozilla.org/network/cache-service;1,{6c84aec9-29a5-4264-8fbc-bee8f922ea67}
+@mozilla.org/security/entropy;1,{34587f4a-be18-43c0-9112-b782b08c0add}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-1,{920307b0-c6e8-11d2-8aa8-00600811a836}
+@mozilla.org/satchel/form-history-importer;1,{db340cc2-7f50-4ea3-8427-f529daf6dc87}
+@mozilla.org/spellchecker/engine;1,{56c778e4-1bee-45f3-a689-886692a97fe7}
+@mozilla.org/intl/unicode/decoder;1?charset=x-euc-tw,{379c2771-ec77-11d2-8aac-00600811a836}
+@mozilla.org/network/protocol/about;1?what=blank,{3decd6c8-30ef-11d3-8cd0-0060b0fc14a3}
+@mozilla.org/autocomplete/search;1?name=file,{cb60980e-18a5-4a77-9110-8146614ca7f0}
+@mozilla.org/autocomplete/search;1?name=places-tag-autocomplete,{1dcc23b0-d4cb-11dc-9ad6-479d56d89593}
+@mozilla.org/network/protocol/about;1?what=cache-entry,{7fa5237d-b0eb-438f-9e50-ca0166e63788}
+@mozilla.org/security/pk11tokendb;1,{b084a2ce-1dd1-11b2-bf10-8324f8e065cc}
+@mozilla.org/network/protocol;1?name=view-source,{9c7ec5d1-23f9-11d5-aea8-8fcc0793e97f}
+@mozilla.org/intl/stringcharsetdetect;1?type=ja_parallel_state_machine,{12bb8f1c-2389-11d3-b3bf-00805f8a6670}
+@mozilla.org/rdf/datasource;1?name=files,{e638d760-8687-11d2-b530-000000000001}
+@mozilla.org/intl/unicode/encoder;1?charset=armscii-8,{6394eebc-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-11,{9c0ff6f4-deda-40e5-806c-b6cc449c21ce}
+@mozilla.org/intl/stringcharsetdetect;1?type=universal_charset_detector,{6ee5301a-3981-49bd-85f8-1a2cc228cf3e}
+@mozilla.org/feed-unescapehtml;1,{10f2f5f0-f103-4901-980f-ba11bd70d60d}
+@mozilla.org/updates/update-service;1,{b3c290a6-3943-4b89-8bbe-c01eb7b3b311}
+@mozilla.org/dom/xpath-evaluator;1,{d0a75e02-b5e7-11d5-a7f2-df109fb8a1fc}
+@mozilla.org/layout/contentserializer;1?mimetype=text/xml,{4aef38b7-6364-4e23-a5e7-12f837fbbd9c}
+@mozilla.org/intl/unicode/decoder;1?charset=IBM857,{2d524fd3-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/browser/sessionstartup;1,{ec7a6c20-e081-11da-8ad9-0800200c9a66}
+@mozilla.org/intl/unicode/encoder;1?charset=ISO-8859-6-I,{495eca46-0a5c-11d4-a135-005004832142}
+@mozilla.org/intl/charsetdetect;1?type=universal_charset_detector,{374e0cde-f605-4259-8c92-e639c6c2eeef}
+@mozilla.org/dirIndexParser;1,{a0d6ad32-1dd1-11b2-aa55-a40187b54036}
+@mozilla.org/autocomplete/search;1?name=history,{88cecbb7-6c63-4b3b-8cd4-84f3b8228c69}
+@mozilla.org/network/downloader;1,{510a86bb-6019-4ed1-bb4f-965cffd23ece}
+@mozilla.org/intl/unicode/decoder;1?charset=EUC-KR,{379c2775-ec77-11d2-8aac-00600811a836}
+@mozilla.org/PopupWindowManager;1,{822bcd11-6432-48be-9e9d-36f7804b7747}
+@mozilla.org/security/recentbadcerts;1,{e7caf8c0-3570-47fe-aa1b-da47539b5d07}
+@mozilla.org/dom/json;1,{93ad72a6-02cd-4716-9626-d47d5ec275ec}
+@mozilla.org/browser/feeds/result-writer;1,{49bb6593-3aff-4eb3-a068-2712c28bd58e}
+@mozilla.org/intl/unicode/encoder;1?charset=x-viet-vps,{6394eec0-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/intl/unicode/encoder;1?charset=windows-1253,{7b8556ad-ec79-11d2-8aac-00600811a836}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-8-I,{495eca43-0a5c-11d4-a135-005004832142}
+@mozilla.org/network/protocol;1?name=pcast,{1c31ed79-accd-4b94-b517-06e0c81999d5}
+@mozilla.org/network/io-service;1,{9ac9e770-18bc-11d3-9337-00104ba0fd40}
+@mozilla.org/uriloader/content-handler;1?type=application/x-xpinstall,{18c2f98d-b09f-11d2-bcde-00805f0e1353}
+@mozilla.org/intl/unicode/decoder;1?charset=ISO-8859-1,{a3254cb0-8e20-11d2-8a98-00600811a836}
+@mozilla.org/intl/unicode/decoder;1?charset=IBM864,{2d524fd5-ae74-11d3-abf7-0004aceefa51}
+@mozilla.org/xul/xul-tree-builder;1,{1abdcc96-1dd2-11b2-b520-f8f59cdd67bc}
+@mozilla.org/privatebrowsing;1,{c31f4883-839b-45f6-82ad-a6a9bc5ad599}
+@mozilla.org/docshell/urifixup;1,{214c48a0-b57f-11d4-959c-0020183bf181}
+@mozilla.org/intl/stringcharsetdetect;1?type=zh_parallel_state_machine,{fcacef21-2b40-11d3-b3bf-00805f8a6670}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-icelandic,{6394eeab-fc3d-11d2-b3b8-00805f8a6670}
+@mozilla.org/network/protocol;1?name=moz-safe-about,{1423e739-782c-4081-b5d8-fe6fba68c0ef}
+@mozilla.org/xul/xul-sort-service;1,{bfd05264-834c-11d2-8eac-00805f29f371}
+@mozilla.org/intl/unicode/decoder;1?charset=x-mac-farsi,{6803cac8-1e3b-11d5-a145-005004832142}
+@mozilla.org/image/decoder;2?type=image/x-ms-bmp,{78c61626-4d1f-4843-9364-4652d98ff6e1}
+@mozilla.org/layout/htmlCopyEncoder;1,{7f915b01-98fc-11d4-8eb0-a803f80ff1bc}
+@mozilla.org/intl/unicode/decoder;1?charset=UTF-32LE,{ba6151b8-1dfa-11d3-b3bf-00805f8a6670}
+
+[CATEGORIES]
+content-sniffing-services,@mozilla.org/image/loader;1,@mozilla.org/image/loader;1
+Charset Encoders,UTF-16,
+Charset Encoders,ISO-8859-8-E,
+Charset Encoders,ISO-8859-4,
+Charset Encoders,ISO-8859-16,
+Charset Encoders,x-mac-gurmukhi,
+Charset Encoders,x-ttf-cmex,
+Charset Encoders,TIS-620,
+Charset Encoders,ISO-IR-111,
+Charset Encoders,EUC-JP,
+Charset Encoders,windows-1251,
+Charset Encoders,x-mac-ukrainian,
+Charset Encoders,x-t1-cmex,
+Charset Encoders,x-mac-roman,
+Charset Encoders,ISO-8859-7,
+Charset Encoders,x-mac-hebrew,
+Charset Encoders,ISO-8859-15,
+Charset Encoders,Adobe-Symbol-Encoding,
+Charset Encoders,gb18030,
+Charset Encoders,IBM857,
+Charset Encoders,x-ttf-cmsy,
+Charset Encoders,x-mathematica5,
+Charset Encoders,hkscs-1,
+Charset Encoders,x-mac-ce,
+Charset Encoders,windows-1252,
+Charset Encoders,KOI8-U,
+Charset Encoders,ISO-8859-10,
+Charset Encoders,GB2312,
+Charset Encoders,UTF-8,
+Charset Encoders,x-viet-tcvn5712,
+Charset Encoders,HZ-GB-2312,
+Charset Encoders,ISO-8859-2,
+Charset Encoders,windows-1257,
+Charset Encoders,x-mathematica1,
+Charset Encoders,x-windows-949,
+Charset Encoders,x-tamilttf-0,
+Charset Encoders,ISO-8859-6-I,
+Charset Encoders,ISO-8859-5,
+Charset Encoders,KOI8-R,
+Charset Encoders,x-imap4-modified-utf7,
+Charset Encoders,VISCII,
+Charset Encoders,windows-1258,
+Charset Encoders,ISO-8859-8,
+Charset Encoders,IBM855,
+Charset Encoders,EUC-KR,
+Charset Encoders,x-ttf-cmmi,
+Charset Encoders,x-mathematica3,
+Charset Encoders,UTF-32LE,
+Charset Encoders,windows-1250,
+Charset Encoders,armscii-8,
+Charset Encoders,IBM864i,
+Charset Encoders,IBM852,
+Charset Encoders,x-euc-tw,
+Charset Encoders,ISO-8859-8-I,
+Charset Encoders,x-johab,
+Charset Encoders,UTF-16LE,
+Charset Encoders,x-user-defined,
+Charset Encoders,x-mac-icelandic,
+Charset Encoders,windows-874,
+Charset Encoders,windows-1255,
+Charset Encoders,x-mac-romanian,
+Charset Encoders,x-ttf-cmr,
+Charset Encoders,x-mathematica4,
+Charset Encoders,ISO-8859-3,
+Charset Encoders,ISO-8859-11,
+Charset Encoders,Big5,
+Charset Encoders,UTF-7,
+Charset Encoders,Shift_JIS,
+Charset Encoders,IBM866,
+Charset Encoders,x-mac-devanagari,
+Charset Encoders,x-mtextra,
+Charset Encoders,x-mac-turkish,
+Charset Encoders,x-gbk,
+Charset Encoders,UTF-32BE,
+Charset Encoders,x-t1-cmr,
+Charset Encoders,windows-1256,
+Charset Encoders,x-mac-farsi,
+Charset Encoders,GEOSTD8,
+Charset Encoders,UTF-32,
+Charset Encoders,x-koreanjamo-0,
+Charset Encoders,x-t1-cmsy,
+Charset Encoders,x-mac-croatian,
+Charset Encoders,UTF-16BE,
+Charset Encoders,ISO-8859-6,
+Charset Encoders,us-ascii,
+Charset Encoders,x-mac-greek,
+Charset Encoders,T.61-8bit,
+Charset Encoders,ISO-8859-9,
+Charset Encoders,jis_0201,
+Charset Encoders,x-mac-gujarati,
+Charset Encoders,ISO-8859-6-E,
+Charset Encoders,x-mathematica2,
+Charset Encoders,Big5-HKSCS,
+Charset Encoders,windows-1253,
+Charset Encoders,ISO-8859-1,
+Charset Encoders,IBM864,
+Charset Encoders,ISO-8859-13,
+Charset Encoders,IBM850,
+Charset Encoders,x-zapf-dingbats,
+Charset Encoders,ISO-8859-14,
+Charset Encoders,x-mac-arabic,
+Charset Encoders,IBM862,
+Charset Encoders,windows-936,
+Charset Encoders,windows-1254,
+Charset Encoders,x-t1-cmmi,
+Charset Encoders,x-tscii,
+Charset Encoders,ISO-2022-JP,
+Charset Encoders,x-viet-vps,
+Charset Encoders,x-mac-cyrillic,
+net-content-sniffers,Feed Sniffer,@mozilla.org/browser/feeds/sniffer;1
+net-content-sniffers,Binary Detector,@mozilla.org/network/binary-detector;1
+JavaScript global static nameset,PrivilegeManager,@mozilla.org/security/script/nameset;1
+parser-service-category,Meta Charset Service,@mozilla.org/intl/metacharset;1
+JavaScript global constructor,BrowserFeedWriter,@mozilla.org/browser/feeds/result-writer;1
+JavaScript global constructor,Image,@mozilla.org/content/element/html;1?name=img
+JavaScript global constructor,Audio,@mozilla.org/content/element/html;1?name=audio
+JavaScript global constructor,Option,@mozilla.org/content/element/html;1?name=option
+agent-style-sheets,pluginfinder xbl binding,chrome://mozapps/content/plugins/missingPluginBinding.css
+xpcom-directory-providers,spellcheck-directory-provider,@mozilla.org/spellcheck/dir-provider;1
+xpcom-directory-providers,browser-directory-provider,@mozilla.org/browser/directory-provider;1
+external-uricontentlisteners,application/x-x509-user-cert,@mozilla.org/uriloader/psm-external-content-listener;1
+external-uricontentlisteners,application/x-x509-email-cert,@mozilla.org/uriloader/psm-external-content-listener;1
+external-uricontentlisteners,application/x-x509-crl,@mozilla.org/uriloader/psm-external-content-listener;1
+external-uricontentlisteners,application/pkix-crl,@mozilla.org/uriloader/psm-external-content-listener;1
+external-uricontentlisteners,application/x-pkcs7-crl,@mozilla.org/uriloader/psm-external-content-listener;1
+external-uricontentlisteners,application/x-x509-ca-cert,@mozilla.org/uriloader/psm-external-content-listener;1
+external-uricontentlisteners,application/x-x509-server-cert,@mozilla.org/uriloader/psm-external-content-listener;1
+uconv-charset-titles,chrome://global/locale/charsetTitles.properties,
+uconv-charset-data,resource://gre/res/charsetData.properties,
+command-line-handler,x-default,@mozilla.org/browser/final-clh;1
+command-line-handler,b-jsconsole,@mozilla.org/toolkit/console-clh;1
+command-line-handler,m-setdefaultbrowser,@mozilla.org/browser/default-browser-clh;1
+command-line-handler,m-browser,@mozilla.org/browser/clh;1
+command-line-handler,y-default,@mozilla.org/toolkit/default-clh;1
+content-policy,@mozilla.org/data-document-content-policy;1,@mozilla.org/data-document-content-policy;1
+content-policy,@mozilla.org/no-data-protocol-content-policy;1,@mozilla.org/no-data-protocol-content-policy;1
+content-policy,@mozilla.org/permissions/contentblocker;1,@mozilla.org/permissions/contentblocker;1
+content-policy,@mozilla.org/embedding/browser/content-policy;1,@mozilla.org/embedding/browser/content-policy;1
+@mozilla.org/streamconv;1,?from=multipart/x-mixed-replace&to=*/*,
+@mozilla.org/streamconv;1,?from=multipart/mixed&to=*/*,
+@mozilla.org/streamconv;1,?from=deflate&to=uncompressed,
+@mozilla.org/streamconv;1,?from=application/http-index-format&to=text/html,
+@mozilla.org/streamconv;1,?from=gzip&to=uncompressed,
+@mozilla.org/streamconv;1,?from=text/gopher-dir&to=application/http-index-format,
+@mozilla.org/streamconv;1,?from=application/x-unknown-content-type&to=*/*,
+@mozilla.org/streamconv;1,?from=text/plain&to=text/html,
+@mozilla.org/streamconv;1,?from=x-compress&to=uncompressed,
+@mozilla.org/streamconv;1,?from=compress&to=uncompressed,
+@mozilla.org/streamconv;1,?from=application/mac-binhex40&to=*/*,
+@mozilla.org/streamconv;1,?from=text/ftp-dir&to=application/http-index-format,
+@mozilla.org/streamconv;1,?from=x-gzip&to=uncompressed,
+@mozilla.org/streamconv;1,?from=multipart/byteranges&to=*/*,
+pref-config-startup,ReadConfig Module,@mozilla.org/readconfig;1
+charset-detectors,cjk_parallel_state_machine,@mozilla.org/intl/charsetdetect;1?type=cjk_parallel_state_machine
+charset-detectors,ko_parallel_state_machine,@mozilla.org/intl/charsetdetect;1?type=ko_parallel_state_machine
+charset-detectors,ruprob,@mozilla.org/intl/charsetdetect;1?type=ruprob
+charset-detectors,off,off
+charset-detectors,universal_charset_detector,@mozilla.org/intl/charsetdetect;1?type=universal_charset_detector
+charset-detectors,zhcn_parallel_state_machine,@mozilla.org/intl/charsetdetect;1?type=zhcn_parallel_state_machine
+charset-detectors,zhtw_parallel_state_machine,@mozilla.org/intl/charsetdetect;1?type=zhtw_parallel_state_machine
+charset-detectors,zh_parallel_state_machine,@mozilla.org/intl/charsetdetect;1?type=zh_parallel_state_machine
+charset-detectors,ja_parallel_state_machine,@mozilla.org/intl/charsetdetect;1?type=ja_parallel_state_machine
+charset-detectors,ukprob,@mozilla.org/intl/charsetdetect;1?type=ukprob
+JavaScript global property,InstallTrigger,@mozilla.org/xpinstall/installtrigger;1
+JavaScript global property,external,@mozilla.org/sidebar;1
+JavaScript global property,sidebar,@mozilla.org/sidebar;1
+command-line-validator,b-browser,@mozilla.org/browser/clh;1
+Gecko-Content-Viewers,application/xml,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,application/javascript,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,text/rdf,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,text/plain,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/jpg,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/gif,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/bmp,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,application/x-view-source,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/icon,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/jpeg,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/pjpeg,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,application/ecmascript,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,mozilla.application/cached-xul,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/x-png,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,application/http-index-format,@mozilla.org/xpfe/http-index-format-factory-constructor
+Gecko-Content-Viewers,image/x-xbitmap,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,application/x-javascript,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/x-xbm,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/png,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,text/css,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,text/html,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,application/rdf+xml,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/x-icon,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,text/ecmascript,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,text/javascript,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,application/xhtml+xml,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,application/vnd.mozilla.xul+xml,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,text/xml,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/vnd.microsoft.icon,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/xbm,@mozilla.org/content/document-loader-factory;1
+Gecko-Content-Viewers,image/x-ms-bmp,@mozilla.org/content/document-loader-factory;1
+profile-after-change,Extension Manager,@mozilla.org/extensions/manager;1
+profile-after-change,Blocklist Service,@mozilla.org/extensions/blocklist;1
+Charset Decoders,UTF-16,
+Charset Decoders,ISO-8859-8-E,
+Charset Decoders,ISO-8859-4,
+Charset Decoders,ISO-8859-16,
+Charset Decoders,UTF-32LE,
+Charset Decoders,TIS-620,
+Charset Decoders,ISO-IR-111,
+Charset Decoders,windows-1252,
+Charset Decoders,windows-1251,
+Charset Decoders,UTF-16BE,
+Charset Decoders,x-mac-ukrainian,
+Charset Decoders,IBM852,
+Charset Decoders,x-mac-roman,
+Charset Decoders,ISO-8859-7,
+Charset Decoders,x-mac-ce,
+Charset Decoders,ISO-8859-15,
+Charset Decoders,IBM857,
+Charset Decoders,gb18030,
+Charset Decoders,x-viet-tcvn5712,
+Charset Decoders,IBM862,
+Charset Decoders,KOI8-U,
+Charset Decoders,ISO-8859-2,
+Charset Decoders,armscii-8,
+Charset Decoders,ISO-8859-10,
+Charset Decoders,UTF-8,
+Charset Decoders,us-ascii,
+Charset Decoders,HZ-GB-2312,
+Charset Decoders,ISO-2022-JP,
+Charset Decoders,x-gbk,
+Charset Decoders,windows-1257,
+Charset Decoders,ISO-8859-14,
+Charset Decoders,x-mac-hebrew,
+Charset Decoders,ISO-8859-6-I,
+Charset Decoders,x-johab,
+Charset Decoders,ISO-8859-5,
+Charset Decoders,KOI8-R,
+Charset Decoders,x-imap4-modified-utf7,
+Charset Decoders,VISCII,
+Charset Decoders,windows-1258,
+Charset Decoders,ISO-8859-8,
+Charset Decoders,EUC-KR,
+Charset Decoders,x-mac-gurmukhi,
+Charset Decoders,Big5,
+Charset Decoders,IBM864,
+Charset Decoders,windows-1250,
+Charset Decoders,EUC-JP,
+Charset Decoders,IBM864i,
+Charset Decoders,x-euc-tw,
+Charset Decoders,ISO-8859-8-I,
+Charset Decoders,UTF-16LE,
+Charset Decoders,x-mac-icelandic,
+Charset Decoders,GB2312,
+Charset Decoders,windows-1255,
+Charset Decoders,x-windows-949,
+Charset Decoders,ISO-2022-KR,
+Charset Decoders,x-mac-romanian,
+Charset Decoders,T.61-8bit,
+Charset Decoders,ISO-8859-3,
+Charset Decoders,ISO-8859-11,
+Charset Decoders,UTF-7,
+Charset Decoders,Shift_JIS,
+Charset Decoders,x-mac-devanagari,
+Charset Decoders,ISO-2022-CN,
+Charset Decoders,UTF-32BE,
+Charset Decoders,x-mac-turkish,
+Charset Decoders,IBM866,
+Charset Decoders,windows-1256,
+Charset Decoders,x-mac-farsi,
+Charset Decoders,GEOSTD8,
+Charset Decoders,UTF-32,
+Charset Decoders,x-mac-croatian,
+Charset Decoders,ISO-8859-6,
+Charset Decoders,x-mac-greek,
+Charset Decoders,ISO-8859-9,
+Charset Decoders,x-mac-cyrillic,
+Charset Decoders,x-mac-gujarati,
+Charset Decoders,ISO-8859-6-E,
+Charset Decoders,Big5-HKSCS,
+Charset Decoders,windows-1253,
+Charset Decoders,ISO-8859-1,
+Charset Decoders,ISO-8859-13,
+Charset Decoders,IBM850,
+Charset Decoders,x-user-defined,
+Charset Decoders,x-mac-arabic,
+Charset Decoders,windows-874,
+Charset Decoders,windows-936,
+Charset Decoders,windows-1254,
+Charset Decoders,IBM855,
+Charset Decoders,x-viet-vps,
+JavaScript global constructor prototype alias,Image,HTMLImageElement
+JavaScript global constructor prototype alias,Audio,HTMLAudioElement
+JavaScript global constructor prototype alias,Option,HTMLOptionElement
+module-loader,text/javascript,@mozilla.org/moz/jsloader;1
+app-startup,tryToClose Service,service,@mozilla.org/appshell/trytoclose;1
+app-startup,Update Service,service,@mozilla.org/updates/update-service;1
+app-startup,Firefox Browser Glue Service,service,@mozilla.org/browser/browserglue;1
+app-startup,Web Content Handler Registrar,service,@mozilla.org/embeddor.implemented/web-content-handler-registrar;1
+app-startup,PrivateBrowsing Service,service,@mozilla.org/privatebrowsing;1
+app-startup,Window Data Source,service,@mozilla.org/rdf/datasource;1?name=window-mediator
+app-startup,Application,service,@mozilla.org/fuel/application;1
+app-startup,Browser Session Startup Service,service,@mozilla.org/browser/sessionstartup;1
+app-startup,SystemPref Module,@mozilla.org/system-preferences;1
+app-startup,Script Security Manager,service,@mozilla.org/scriptsecuritymanager;1
+bookmark-observers,Used to synchronize the temporary and permanent tables of Places,@mozilla.org/places/sync;1
+JavaScript global privileged property,Application,@mozilla.org/fuel/application;1
+XSLT extension functions,http://exslt.org/regular-expressions,@mozilla.org/exslt/regexp;1
+history-observers,Used to synchronize the temporary and permanent tables of Places,@mozilla.org/places/sync;1
diff --git a/bundles/XO/components/fuelApplication.js b/bundles/XO/components/fuelApplication.js
new file mode 100755
index 0000000..1584b6e
--- /dev/null
+++ b/bundles/XO/components/fuelApplication.js
@@ -0,0 +1,1454 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FUEL.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Finkle <mfinkle@mozilla.com> (Original Author)
+ * John Resig <jresig@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+//=================================================
+// Singleton that holds services and utilities
+var Utilities = {
+ _bookmarks : null,
+ get bookmarks() {
+ if (!this._bookmarks) {
+ this._bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+ getService(Ci.nsINavBookmarksService);
+ }
+ return this._bookmarks;
+ },
+
+ _livemarks : null,
+ get livemarks() {
+ if (!this._livemarks) {
+ this._livemarks = Cc["@mozilla.org/browser/livemark-service;2"].
+ getService(Ci.nsILivemarkService);
+ }
+ return this._livemarks;
+ },
+
+ _annotations : null,
+ get annotations() {
+ if (!this._annotations) {
+ this._annotations = Cc["@mozilla.org/browser/annotation-service;1"].
+ getService(Ci.nsIAnnotationService);
+ }
+ return this._annotations;
+ },
+
+ _history : null,
+ get history() {
+ if (!this._history) {
+ this._history = Cc["@mozilla.org/browser/nav-history-service;1"].
+ getService(Ci.nsINavHistoryService);
+ }
+ return this._history;
+ },
+
+ _windowMediator : null,
+ get windowMediator() {
+ if (!this._windowMediator) {
+ this._windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ }
+ return this._windowMediator;
+ },
+
+ makeURI : function(aSpec) {
+ if (!aSpec)
+ return null;
+ var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ return ios.newURI(aSpec, null, null);
+ },
+
+ free : function() {
+ this._bookmarks = null;
+ this._livemarks = null;
+ this._annotations = null;
+ this._history = null;
+ this._windowMediator = null;
+ }
+};
+
+
+//=================================================
+// Window implementation
+function Window(aWindow) {
+ this._window = aWindow;
+ this._tabbrowser = aWindow.getBrowser();
+ this._events = new Events();
+ this._cleanup = {};
+
+ this._watch("TabOpen");
+ this._watch("TabMove");
+ this._watch("TabClose");
+ this._watch("TabSelect");
+
+ var self = this;
+ gShutdown.push(function() { self._shutdown(); });
+}
+
+Window.prototype = {
+ get events() {
+ return this._events;
+ },
+
+ /*
+ * Helper used to setup event handlers on the XBL element. Note that the events
+ * are actually dispatched to tabs, so we capture them.
+ */
+ _watch : function win_watch(aType) {
+ var self = this;
+ this._tabbrowser.addEventListener(aType,
+ this._cleanup[aType] = function(e){ self._event(e); },
+ true);
+ },
+
+ /*
+ * Helper event callback used to redirect events made on the XBL element
+ */
+ _event : function win_event(aEvent) {
+ this._events.dispatch(aEvent.type, new BrowserTab(this, aEvent.originalTarget.linkedBrowser));
+ },
+
+ get tabs() {
+ var tabs = [];
+ var browsers = this._tabbrowser.browsers;
+
+ for (var i=0; i<browsers.length; i++)
+ tabs.push(new BrowserTab(this, browsers[i]));
+ return tabs;
+ },
+
+ get activeTab() {
+ return new BrowserTab(this, this._tabbrowser.selectedBrowser);
+ },
+
+ open : function win_open(aURI) {
+ return new BrowserTab(this, this._tabbrowser.addTab(aURI.spec).linkedBrowser);
+ },
+
+ _shutdown : function win_shutdown() {
+ for (var type in this._cleanup)
+ this._tabbrowser.removeEventListener(type, this._cleanup[type], true);
+ this._cleanup = null;
+
+ this._window = null;
+ this._tabbrowser = null;
+ this._events = null;
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.fuelIWindow])
+};
+
+
+//=================================================
+// BrowserTab implementation
+function BrowserTab(aFUELWindow, aBrowser) {
+ this._window = aFUELWindow;
+ this._tabbrowser = aFUELWindow._tabbrowser;
+ this._browser = aBrowser;
+ this._events = new Events();
+ this._cleanup = {};
+
+ this._watch("load");
+
+ var self = this;
+ gShutdown.push(function() { self._shutdown(); });
+}
+
+BrowserTab.prototype = {
+ get uri() {
+ return this._browser.currentURI;
+ },
+
+ get index() {
+ var tabs = this._tabbrowser.mTabs;
+ for (var i=0; i<tabs.length; i++) {
+ if (tabs[i].linkedBrowser == this._browser)
+ return i;
+ }
+ return -1;
+ },
+
+ get events() {
+ return this._events;
+ },
+
+ get window() {
+ return this._window;
+ },
+
+ get document() {
+ return this._browser.contentDocument;
+ },
+
+ /*
+ * Helper used to setup event handlers on the XBL element
+ */
+ _watch : function bt_watch(aType) {
+ var self = this;
+ this._browser.addEventListener(aType,
+ this._cleanup[aType] = function(e){ self._event(e); },
+ true);
+ },
+
+ /*
+ * Helper event callback used to redirect events made on the XBL element
+ */
+ _event : function bt_event(aEvent) {
+ if (aEvent.type == "load") {
+ if (!(aEvent.originalTarget instanceof Ci.nsIDOMHTMLDocument))
+ return;
+
+ if (aEvent.originalTarget.defaultView instanceof Ci.nsIDOMWindowInternal &&
+ aEvent.originalTarget.defaultView.frameElement)
+ return;
+ }
+
+ this._events.dispatch(aEvent.type, this);
+ },
+
+ /*
+ * Helper used to determine the index offset of the browsertab
+ */
+ _getTab : function bt_gettab() {
+ var tabs = this._tabbrowser.mTabs;
+ return tabs[this.index] || null;
+ },
+
+ load : function bt_load(aURI) {
+ this._browser.loadURI(aURI.spec, null, null);
+ },
+
+ focus : function bt_focus() {
+ this._tabbrowser.selectedTab = this._getTab();
+ this._tabbrowser.focus();
+ },
+
+ close : function bt_close() {
+ this._tabbrowser.removeTab(this._getTab());
+ },
+
+ moveBefore : function bt_movebefore(aBefore) {
+ this._tabbrowser.moveTabTo(this._getTab(), aBefore.index);
+ },
+
+ moveToEnd : function bt_moveend() {
+ this._tabbrowser.moveTabTo(this._getTab(), this._tabbrowser.browsers.length);
+ },
+
+ _shutdown : function bt_shutdown() {
+ for (var type in this._cleanup)
+ this._browser.removeEventListener(type, this._cleanup[type], true);
+ this._cleanup = null;
+
+ this._window = null;
+ this._tabbrowser = null;
+ this._browser = null;
+ this._events = null;
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.fuelIBrowserTab])
+};
+
+
+//=================================================
+// Annotations implementation
+function Annotations(aId) {
+ this._id = aId;
+}
+
+Annotations.prototype = {
+ get names() {
+ return Utilities.annotations.getItemAnnotationNames(this._id, {});
+ },
+
+ has : function ann_has(aName) {
+ return Utilities.annotations.itemHasAnnotation(this._id, aName);
+ },
+
+ get : function(aName) {
+ if (this.has(aName))
+ return Utilities.annotations.getItemAnnotation(this._id, aName);
+ return null;
+ },
+
+ set : function(aName, aValue, aExpiration) {
+ Utilities.annotations.setItemAnnotation(this._id, aName, aValue, 0, aExpiration);
+ },
+
+ remove : function ann_remove(aName) {
+ if (aName)
+ Utilities.annotations.removeItemAnnotation(this._id, aName);
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.fuelIAnnotations])
+};
+
+
+//=================================================
+// Bookmark implementation
+function Bookmark(aId, aParent, aType) {
+ this._id = aId;
+ this._parent = aParent;
+ this._type = aType || "bookmark";
+ this._annotations = new Annotations(this._id);
+ this._events = new Events();
+
+ Utilities.bookmarks.addObserver(this, false);
+
+ var self = this;
+ gShutdown.push(function() { self._shutdown(); });
+}
+
+Bookmark.prototype = {
+ _shutdown : function bm_shutdown() {
+ this._annotations = null;
+ this._events = null;
+
+ Utilities.bookmarks.removeObserver(this);
+ },
+
+ get id() {
+ return this._id;
+ },
+
+ get title() {
+ return Utilities.bookmarks.getItemTitle(this._id);
+ },
+
+ set title(aTitle) {
+ Utilities.bookmarks.setItemTitle(this._id, aTitle);
+ },
+
+ get uri() {
+ return Utilities.bookmarks.getBookmarkURI(this._id);
+ },
+
+ set uri(aURI) {
+ return Utilities.bookmarks.changeBookmarkURI(this._id, aURI);
+ },
+
+ get description() {
+ return this._annotations.get("bookmarkProperties/description");
+ },
+
+ set description(aDesc) {
+ this._annotations.set("bookmarkProperties/description", aDesc, Ci.nsIAnnotationService.EXPIRE_NEVER);
+ },
+
+ get keyword() {
+ return Utilities.bookmarks.getKeywordForBookmark(this._id);
+ },
+
+ set keyword(aKeyword) {
+ Utilities.bookmarks.setKeywordForBookmark(this._id, aKeyword);
+ },
+
+ get type() {
+ return this._type;
+ },
+
+ get parent() {
+ return this._parent;
+ },
+
+ set parent(aFolder) {
+ Utilities.bookmarks.moveItem(this._id, aFolder.id, Utilities.bookmarks.DEFAULT_INDEX);
+ // this._parent is updated in onItemMoved
+ },
+
+ get annotations() {
+ return this._annotations;
+ },
+
+ get events() {
+ return this._events;
+ },
+
+ remove : function bm_remove() {
+ Utilities.bookmarks.removeItem(this._id);
+ },
+
+ // observer
+ onBeginUpdateBatch : function bm_obub() {
+ },
+
+ onEndUpdateBatch : function bm_oeub() {
+ },
+
+ onItemAdded : function bm_oia(aId, aFolder, aIndex) {
+ // bookmark object doesn't exist at this point
+ },
+
+ onItemRemoved : function bm_oir(aId, aFolder, aIndex) {
+ if (this._id == aId)
+ this._events.dispatch("remove", aId);
+ },
+
+ onItemChanged : function bm_oic(aId, aProperty, aIsAnnotationProperty, aValue) {
+ if (this._id == aId)
+ this._events.dispatch("change", aProperty);
+ },
+
+ onItemVisited: function bm_oiv(aId, aVisitID, aTime) {
+ },
+
+ onItemMoved: function bm_oim(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
+ if (this._id == aId) {
+ this._parent = new BookmarkFolder(aNewParent, Utilities.bookmarks.getFolderIdForItem(aNewParent));
+ this._events.dispatch("move", aId);
+ }
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.fuelIBookmark, Ci.nsINavBookmarkObserver])
+};
+
+
+//=================================================
+// BookmarkFolder implementation
+function BookmarkFolder(aId, aParent) {
+ this._id = aId;
+ this._parent = aParent;
+ this._annotations = new Annotations(this._id);
+ this._events = new Events();
+
+ Utilities.bookmarks.addObserver(this, false);
+
+ var self = this;
+ gShutdown.push(function() { self._shutdown(); });
+}
+
+BookmarkFolder.prototype = {
+ _shutdown : function bmf_shutdown() {
+ this._annotations = null;
+ this._events = null;
+
+ Utilities.bookmarks.removeObserver(this);
+ },
+
+ get id() {
+ return this._id;
+ },
+
+ get title() {
+ return Utilities.bookmarks.getItemTitle(this._id);
+ },
+
+ set title(aTitle) {
+ Utilities.bookmarks.setItemTitle(this._id, aTitle);
+ },
+
+ get description() {
+ return this._annotations.get("bookmarkProperties/description");
+ },
+
+ set description(aDesc) {
+ this._annotations.set("bookmarkProperties/description", aDesc, Ci.nsIAnnotationService.EXPIRE_NEVER);
+ },
+
+ get type() {
+ return "folder";
+ },
+
+ get parent() {
+ return this._parent;
+ },
+
+ set parent(aFolder) {
+ Utilities.bookmarks.moveItem(this._id, aFolder.id, Utilities.bookmarks.DEFAULT_INDEX);
+ // this._parent is updated in onItemMoved
+ },
+
+ get annotations() {
+ return this._annotations;
+ },
+
+ get events() {
+ return this._events;
+ },
+
+ get children() {
+ var items = [];
+
+ var options = Utilities.history.getNewQueryOptions();
+ var query = Utilities.history.getNewQuery();
+ query.setFolders([this._id], 1);
+ var result = Utilities.history.executeQuery(query, options);
+ var rootNode = result.root;
+ rootNode.containerOpen = true;
+ var cc = rootNode.childCount;
+ for (var i=0; i<cc; ++i) {
+ var node = rootNode.getChild(i);
+ if (node.type == node.RESULT_TYPE_FOLDER) {
+ var folder = new BookmarkFolder(node.itemId, this._id);
+ items.push(folder);
+ }
+ else if (node.type == node.RESULT_TYPE_SEPARATOR) {
+ var separator = new Bookmark(node.itemId, this._id, "separator");
+ items.push(separator);
+ }
+ else {
+ var bookmark = new Bookmark(node.itemId, this._id, "bookmark");
+ items.push(bookmark);
+ }
+ }
+ rootNode.containerOpen = false;
+
+ return items;
+ },
+
+ addBookmark : function bmf_addbm(aTitle, aUri) {
+ var newBookmarkID = Utilities.bookmarks.insertBookmark(this._id, aUri, Utilities.bookmarks.DEFAULT_INDEX, aTitle);
+ var newBookmark = new Bookmark(newBookmarkID, this, "bookmark");
+ return newBookmark;
+ },
+
+ addSeparator : function bmf_addsep() {
+ var newBookmarkID = Utilities.bookmarks.insertSeparator(this._id, Utilities.bookmarks.DEFAULT_INDEX);
+ var newBookmark = new Bookmark(newBookmarkID, this, "separator");
+ return newBookmark;
+ },
+
+ addFolder : function bmf_addfolder(aTitle) {
+ var newFolderID = Utilities.bookmarks.createFolder(this._id, aTitle, Utilities.bookmarks.DEFAULT_INDEX);
+ var newFolder = new BookmarkFolder(newFolderID, this);
+ return newFolder;
+ },
+
+ remove : function bmf_remove() {
+ Utilities.bookmarks.removeFolder(this._id);
+ },
+
+ // observer
+ onBeginUpdateBatch : function bmf_obub() {
+ },
+
+ onEndUpdateBatch : function bmf_oeub() {
+ },
+
+ onItemAdded : function bmf_oia(aId, aFolder, aIndex) {
+ // handle root folder events
+ if (!this._parent)
+ this._events.dispatch("add", aId);
+
+ // handle this folder events
+ if (this._id == aFolder)
+ this._events.dispatch("addchild", aId);
+ },
+
+ onItemRemoved : function bmf_oir(aId, aFolder, aIndex) {
+ // handle root folder events
+ if (!this._parent || this._id == aId)
+ this._events.dispatch("remove", aId);
+
+ // handle this folder events
+ if (this._id == aFolder)
+ this._events.dispatch("removechild", aId);
+ },
+
+ onItemChanged : function bmf_oic(aId, aProperty, aIsAnnotationProperty, aValue) {
+ // handle root folder and this folder events
+ if (!this._parent || this._id == aId)
+ this._events.dispatch("change", aProperty);
+ },
+
+ onItemVisited: function bmf_oiv(aId, aVisitID, aTime) {
+ },
+
+ onItemMoved: function bmf_oim(aId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
+ // handle this folder event, root folder cannot be moved
+ if (this._id == aId) {
+ this._parent = new BookmarkFolder(aNewParent, Utilities.bookmarks.getFolderIdForItem(aNewParent));
+ this._events.dispatch("move", aId);
+ }
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.fuelIBookmarkFolder, Ci.nsINavBookmarkObserver])
+};
+
+//=================================================
+// BookmarkRoots implementation
+function BookmarkRoots() {
+ var self = this;
+ gShutdown.push(function() { self._shutdown(); });
+}
+
+BookmarkRoots.prototype = {
+ _shutdown : function bmr_shutdown() {
+ this._menu = null;
+ this._toolbar = null;
+ this._tags = null;
+ this._unfiled = null;
+ },
+
+ get menu() {
+ if (!this._menu)
+ this._menu = new BookmarkFolder(Utilities.bookmarks.bookmarksMenuFolder, null);
+
+ return this._menu;
+ },
+
+ get toolbar() {
+ if (!this._toolbar)
+ this._toolbar = new BookmarkFolder(Utilities.bookmarks.toolbarFolder, null);
+
+ return this._toolbar;
+ },
+
+ get tags() {
+ if (!this._tags)
+ this._tags = new BookmarkFolder(Utilities.bookmarks.tagsFolder, null);
+
+ return this._tags;
+ },
+
+ get unfiled() {
+ if (!this._unfiled)
+ this._unfiled = new BookmarkFolder(Utilities.bookmarks.unfiledBookmarksFolder, null);
+
+ return this._unfiled;
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.fuelIBookmarkRoots])
+};
+
+
+//=================================================
+// Factory - Treat Application as a singleton
+// XXX This is required, because we're registered for the 'JavaScript global
+// privileged property' category, whose handler always calls createInstance.
+// See bug 386535.
+var gSingleton = null;
+var ApplicationFactory = {
+ createInstance: function af_ci(aOuter, aIID) {
+ if (aOuter != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ if (gSingleton == null) {
+ gSingleton = new Application();
+ }
+
+ return gSingleton.QueryInterface(aIID);
+ }
+};
+
+
+
+//=================================================
+// Application constructor
+function Application() {
+ this.initToolkitHelpers();
+ this._bookmarks = null;
+}
+
+//=================================================
+// Application implementation
+Application.prototype = {
+ // for nsIClassInfo + XPCOMUtils
+ classDescription: "Application",
+ classID: Components.ID("fe74cf80-aa2d-11db-abbd-0800200c9a66"),
+ contractID: "@mozilla.org/fuel/application;1",
+
+ // redefine the default factory for XPCOMUtils
+ _xpcom_factory: ApplicationFactory,
+
+ // for nsISupports
+ QueryInterface : XPCOMUtils.generateQI([Ci.fuelIApplication, Ci.extIApplication, Ci.nsIObserver, Ci.nsIClassInfo]),
+
+ getInterfaces : function app_gi(aCount) {
+ var interfaces = [Ci.fuelIApplication, Ci.extIApplication, Ci.nsIObserver, Ci.nsIClassInfo];
+ aCount.value = interfaces.length;
+ return interfaces;
+ },
+
+ // for nsIObserver
+ observe: function app_observe(aSubject, aTopic, aData) {
+ // Call the extApplication version of this function first
+ this.__proto__.__proto__.observe.call(this, aSubject, aTopic, aData);
+ if (aTopic == "xpcom-shutdown") {
+ this._bookmarks = null;
+ Utilities.free();
+ }
+ },
+
+ get bookmarks() {
+ if (this._bookmarks == null)
+ this._bookmarks = new BookmarkRoots();
+
+ return this._bookmarks;
+ },
+
+ get windows() {
+ var win = [];
+ var enum = Utilities.windowMediator.getEnumerator("navigator:browser");
+
+ while (enum.hasMoreElements())
+ win.push(new Window(enum.getNext()));
+
+ return win;
+ },
+
+ get activeWindow() {
+ return new Window(Utilities.windowMediator.getMostRecentWindow("navigator:browser"));
+ }
+};
+
+//module initialization
+function NSGetModule(aCompMgr, aFileSpec) {
+ // set the proto, defined in extApplication.js
+ Application.prototype.__proto__ = extApplication.prototype;
+ return XPCOMUtils.generateModule([Application]);
+}
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FUEL.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Finkle <mfinkle@mozilla.com> (Original Author)
+ * John Resig <jresig@mozilla.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+//=================================================
+// Shutdown - used to store cleanup functions which will
+// be called on Application shutdown
+var gShutdown = [];
+
+//=================================================
+// Console constructor
+function Console() {
+ this._console = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Ci.nsIConsoleService);
+}
+
+//=================================================
+// Console implementation
+Console.prototype = {
+ log : function cs_log(aMsg) {
+ this._console.logStringMessage(aMsg);
+ },
+
+ open : function cs_open() {
+ var wMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Ci.nsIWindowMediator);
+ var console = wMediator.getMostRecentWindow("global:console");
+ if (!console) {
+ var wWatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
+ .getService(Ci.nsIWindowWatcher);
+ wWatch.openWindow(null, "chrome://global/content/console.xul", "_blank",
+ "chrome,dialog=no,all", null);
+ } else {
+ // console was already open
+ console.focus();
+ }
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extIConsole])
+};
+
+
+//=================================================
+// EventItem constructor
+function EventItem(aType, aData) {
+ this._type = aType;
+ this._data = aData;
+}
+
+//=================================================
+// EventItem implementation
+EventItem.prototype = {
+ _cancel : false,
+
+ get type() {
+ return this._type;
+ },
+
+ get data() {
+ return this._data;
+ },
+
+ preventDefault : function ei_pd() {
+ this._cancel = true;
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extIEventItem])
+};
+
+
+//=================================================
+// Events constructor
+function Events() {
+ this._listeners = [];
+}
+
+//=================================================
+// Events implementation
+Events.prototype = {
+ addListener : function evts_al(aEvent, aListener) {
+ if (this._listeners.some(hasFilter))
+ return;
+
+ this._listeners.push({
+ event: aEvent,
+ listener: aListener
+ });
+
+ function hasFilter(element) {
+ return element.event == aEvent && element.listener == aListener;
+ }
+ },
+
+ removeListener : function evts_rl(aEvent, aListener) {
+ this._listeners = this._listeners.filter(hasFilter);
+
+ function hasFilter(element) {
+ return element.event != aEvent && element.listener != aListener;
+ }
+ },
+
+ dispatch : function evts_dispatch(aEvent, aEventItem) {
+ eventItem = new EventItem(aEvent, aEventItem);
+
+ this._listeners.forEach(function(key){
+ if (key.event == aEvent) {
+ key.listener.handleEvent ?
+ key.listener.handleEvent(eventItem) :
+ key.listener(eventItem);
+ }
+ });
+
+ return !eventItem._cancel;
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extIEvents])
+};
+
+
+//=================================================
+// PreferenceBranch constructor
+function PreferenceBranch(aBranch) {
+ if (!aBranch)
+ aBranch = "";
+
+ this._root = aBranch;
+ this._prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefService);
+
+ if (aBranch)
+ this._prefs = this._prefs.getBranch(aBranch);
+
+ this._prefs.QueryInterface(Ci.nsIPrefBranch);
+ this._prefs.QueryInterface(Ci.nsIPrefBranch2);
+
+ // we want to listen to "all" changes for this branch, so pass in a blank domain
+ this._prefs.addObserver("", this, true);
+ this._events = new Events();
+
+ var self = this;
+ gShutdown.push(function() { self._shutdown(); });
+}
+
+//=================================================
+// PreferenceBranch implementation
+PreferenceBranch.prototype = {
+ // cleanup observer so we don't leak
+ _shutdown: function prefs_shutdown() {
+ this._prefs.removeObserver(this._root, this);
+
+ this._prefs = null;
+ this._events = null;
+ },
+
+ // for nsIObserver
+ observe: function prefs_observe(aSubject, aTopic, aData) {
+ if (aTopic == "nsPref:changed")
+ this._events.dispatch("change", aData);
+ },
+
+ get root() {
+ return this._root;
+ },
+
+ get all() {
+ return this.find({});
+ },
+
+ get events() {
+ return this._events;
+ },
+
+ // XXX: Disabled until we can figure out the wrapped object issues
+ // name: "name" or /name/
+ // path: "foo.bar." or "" or /fo+\.bar/
+ // type: Boolean, Number, String (getPrefType)
+ // locked: true, false (prefIsLocked)
+ // modified: true, false (prefHasUserValue)
+ find : function prefs_find(aOptions) {
+ var retVal = [];
+ var items = this._prefs.getChildList("", []);
+
+ for (var i = 0; i < items.length; i++) {
+ retVal.push(new Preference(items[i], this));
+ }
+
+ return retVal;
+ },
+
+ has : function prefs_has(aName) {
+ return (this._prefs.getPrefType(aName) != Ci.nsIPrefBranch.PREF_INVALID);
+ },
+
+ get : function prefs_get(aName) {
+ return this.has(aName) ? new Preference(aName, this) : null;
+ },
+
+ getValue : function prefs_gv(aName, aValue) {
+ var type = this._prefs.getPrefType(aName);
+
+ switch (type) {
+ case Ci.nsIPrefBranch2.PREF_STRING:
+ aValue = this._prefs.getComplexValue(aName, Ci.nsISupportsString).data;
+ break;
+ case Ci.nsIPrefBranch2.PREF_BOOL:
+ aValue = this._prefs.getBoolPref(aName);
+ break;
+ case Ci.nsIPrefBranch2.PREF_INT:
+ aValue = this._prefs.getIntPref(aName);
+ break;
+ }
+
+ return aValue;
+ },
+
+ setValue : function prefs_sv(aName, aValue) {
+ var type = aValue != null ? aValue.constructor.name : "";
+
+ switch (type) {
+ case "String":
+ var str = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(Ci.nsISupportsString);
+ str.data = aValue;
+ this._prefs.setComplexValue(aName, Ci.nsISupportsString, str);
+ break;
+ case "Boolean":
+ this._prefs.setBoolPref(aName, aValue);
+ break;
+ case "Number":
+ this._prefs.setIntPref(aName, aValue);
+ break;
+ default:
+ throw("Unknown preference value specified.");
+ }
+ },
+
+ reset : function prefs_reset() {
+ this._prefs.resetBranch("");
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extIPreferenceBranch, Ci.nsISupportsWeakReference])
+};
+
+
+//=================================================
+// Preference constructor
+function Preference(aName, aBranch) {
+ this._name = aName;
+ this._branch = aBranch;
+ this._events = new Events();
+
+ var self = this;
+
+ this.branch.events.addListener("change", function(aEvent){
+ if (aEvent.data == self.name)
+ self.events.dispatch(aEvent.type, aEvent.data);
+ });
+}
+
+//=================================================
+// Preference implementation
+Preference.prototype = {
+ get name() {
+ return this._name;
+ },
+
+ get type() {
+ var value = "";
+ var type = this.branch._prefs.getPrefType(this._name);
+
+ switch (type) {
+ case Ci.nsIPrefBranch2.PREF_STRING:
+ value = "String";
+ break;
+ case Ci.nsIPrefBranch2.PREF_BOOL:
+ value = "Boolean";
+ break;
+ case Ci.nsIPrefBranch2.PREF_INT:
+ value = "Number";
+ break;
+ }
+
+ return value;
+ },
+
+ get value() {
+ return this.branch.getValue(this._name, null);
+ },
+
+ set value(aValue) {
+ return this.branch.setValue(this._name, aValue);
+ },
+
+ get locked() {
+ return this.branch._prefs.prefIsLocked(this.name);
+ },
+
+ set locked(aValue) {
+ this.branch._prefs[ aValue ? "lockPref" : "unlockPref" ](this.name);
+ },
+
+ get modified() {
+ return this.branch._prefs.prefHasUserValue(this.name);
+ },
+
+ get branch() {
+ return this._branch;
+ },
+
+ get events() {
+ return this._events;
+ },
+
+ reset : function pref_reset() {
+ this.branch._prefs.clearUserPref(this.name);
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extIPreference])
+};
+
+
+//=================================================
+// SessionStorage constructor
+function SessionStorage() {
+ this._storage = {};
+ this._events = new Events();
+}
+
+//=================================================
+// SessionStorage implementation
+SessionStorage.prototype = {
+ get events() {
+ return this._events;
+ },
+
+ has : function ss_has(aName) {
+ return this._storage.hasOwnProperty(aName);
+ },
+
+ set : function ss_set(aName, aValue) {
+ this._storage[aName] = aValue;
+ this._events.dispatch("change", aName);
+ },
+
+ get : function ss_get(aName, aDefaultValue) {
+ return this.has(aName) ? this._storage[aName] : aDefaultValue;
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extISessionStorage])
+};
+
+
+//=================================================
+// Extension constructor
+function Extension(aItem) {
+ this._item = aItem;
+ this._firstRun = false;
+ this._prefs = new PreferenceBranch("extensions." + this._item.id + ".");
+ this._storage = new SessionStorage();
+ this._events = new Events();
+
+ var installPref = "install-event-fired";
+ if (!this._prefs.has(installPref)) {
+ this._prefs.setValue(installPref, true);
+ this._firstRun = true;
+ }
+
+ this._enabled = false;
+ const PREFIX_ITEM_URI = "urn:mozilla:item:";
+ const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
+ var rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
+ var itemResource = rdf.GetResource(PREFIX_ITEM_URI + this._item.id);
+ if (itemResource) {
+ var extmgr = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
+ var ds = extmgr.datasource;
+ var target = ds.GetTarget(itemResource, rdf.GetResource(PREFIX_NS_EM + "isDisabled"), true);
+ if (target && target instanceof Ci.nsIRDFLiteral)
+ this._enabled = (target.Value != "true");
+ }
+
+ var os = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Ci.nsIObserverService);
+ os.addObserver(this, "em-action-requested", false);
+
+ var self = this;
+ gShutdown.push(function(){ self._shutdown(); });
+}
+
+//=================================================
+// Extension implementation
+Extension.prototype = {
+ // cleanup observer so we don't leak
+ _shutdown: function ext_shutdown() {
+ var os = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Ci.nsIObserverService);
+ os.removeObserver(this, "em-action-requested");
+
+ this._prefs = null;
+ this._storage = null;
+ this._events = null;
+ },
+
+ // for nsIObserver
+ observe: function ext_observe(aSubject, aTopic, aData)
+ {
+ if ((aSubject instanceof Ci.nsIUpdateItem) && (aSubject.id == this._item.id))
+ {
+ if (aData == "item-uninstalled")
+ this._events.dispatch("uninstall", this._item.id);
+ else if (aData == "item-disabled")
+ this._events.dispatch("disable", this._item.id);
+ else if (aData == "item-enabled")
+ this._events.dispatch("enable", this._item.id);
+ else if (aData == "item-cancel-action")
+ this._events.dispatch("cancel", this._item.id);
+ else if (aData == "item-upgraded")
+ this._events.dispatch("upgrade", this._item.id);
+ }
+ },
+
+ get id() {
+ return this._item.id;
+ },
+
+ get name() {
+ return this._item.name;
+ },
+
+ get enabled() {
+ return this._enabled;
+ },
+
+ get version() {
+ return this._item.version;
+ },
+
+ get firstRun() {
+ return this._firstRun;
+ },
+
+ get storage() {
+ return this._storage;
+ },
+
+ get prefs() {
+ return this._prefs;
+ },
+
+ get events() {
+ return this._events;
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extIExtension])
+};
+
+
+//=================================================
+// Extensions constructor
+function Extensions() {
+ this._extmgr = Components.classes["@mozilla.org/extensions/manager;1"]
+ .getService(Ci.nsIExtensionManager);
+
+ this._cache = {};
+
+ var self = this;
+ gShutdown.push(function() { self._shutdown(); });
+}
+
+//=================================================
+// Extensions implementation
+Extensions.prototype = {
+ _shutdown : function exts_shutdown() {
+ this._extmgr = null;
+ this._cache = null;
+ },
+
+ /*
+ * Helper method to check cache before creating a new extension
+ */
+ _get : function exts_get(aId) {
+ if (this._cache.hasOwnProperty(aId))
+ return this._cache[aId];
+
+ var newExt = new Extension(this._extmgr.getItemForID(aId));
+ this._cache[aId] = newExt;
+ return newExt;
+ },
+
+ get all() {
+ return this.find({});
+ },
+
+ // XXX: Disabled until we can figure out the wrapped object issues
+ // id: "some@id" or /id/
+ // name: "name" or /name/
+ // version: "1.0.1"
+ // minVersion: "1.0"
+ // maxVersion: "2.0"
+ find : function exts_find(aOptions) {
+ var retVal = [];
+ var items = this._extmgr.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION, {});
+
+ for (var i = 0; i < items.length; i++) {
+ retVal.push(this._get(items[i].id));
+ }
+
+ return retVal;
+ },
+
+ has : function exts_has(aId) {
+ return this._extmgr.getItemForID(aId) != null;
+ },
+
+ get : function exts_get(aId) {
+ return this.has(aId) ? this._get(aId) : null;
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extIExtensions])
+};
+
+//=================================================
+// extApplication constructor
+function extApplication() {
+}
+
+//=================================================
+// extApplication implementation
+extApplication.prototype = {
+ initToolkitHelpers: function extApp_initToolkitHelpers() {
+ this._console = null;
+ this._storage = null;
+ this._prefs = null;
+ this._extensions = null;
+ this._events = null;
+
+ this._info = Components.classes["@mozilla.org/xre/app-info;1"]
+ .getService(Ci.nsIXULAppInfo);
+
+ var os = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Ci.nsIObserverService);
+
+ os.addObserver(this, "final-ui-startup", false);
+ os.addObserver(this, "quit-application-requested", false);
+ os.addObserver(this, "xpcom-shutdown", false);
+ },
+
+ // get this contractID registered for certain categories via XPCOMUtils
+ _xpcom_categories: [
+ // make Application a startup observer
+ { category: "app-startup", service: true },
+
+ // add Application as a global property for easy access
+ { category: "JavaScript global privileged property" }
+ ],
+
+ // for nsIClassInfo
+ flags : Ci.nsIClassInfo.SINGLETON,
+ implementationLanguage : Ci.nsIProgrammingLanguage.JAVASCRIPT,
+
+ getInterfaces : function app_gi(aCount) {
+ var interfaces = [Ci.extIApplication, Ci.nsIObserver, Ci.nsIClassInfo];
+ aCount.value = interfaces.length;
+ return interfaces;
+ },
+
+ getHelperForLanguage : function app_ghfl(aCount) {
+ return null;
+ },
+
+ // extIApplication
+ get id() {
+ return this._info.ID;
+ },
+
+ get name() {
+ return this._info.name;
+ },
+
+ get version() {
+ return this._info.version;
+ },
+
+ // for nsIObserver
+ observe: function app_observe(aSubject, aTopic, aData) {
+ if (aTopic == "app-startup") {
+ this.events.dispatch("load", "application");
+ }
+ else if (aTopic == "final-ui-startup") {
+ this.events.dispatch("ready", "application");
+ }
+ else if (aTopic == "quit-application-requested") {
+ // we can stop the quit by checking the return value
+ if (this.events.dispatch("quit", "application") == false)
+ aSubject.data = true;
+ }
+ else if (aTopic == "xpcom-shutdown") {
+
+ this.events.dispatch("unload", "application");
+
+ // call the cleanup functions and empty the array
+ while (gShutdown.length) {
+ gShutdown.shift()();
+ }
+
+ // release our observers
+ var os = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Ci.nsIObserverService);
+
+ os.removeObserver(this, "final-ui-startup");
+ os.removeObserver(this, "quit-application-requested");
+ os.removeObserver(this, "xpcom-shutdown");
+
+ this._info = null;
+ this._console = null;
+ this._prefs = null;
+ this._storage = null;
+ this._events = null;
+ this._extensions = null;
+ }
+ },
+
+ get console() {
+ if (this._console == null)
+ this._console = new Console();
+
+ return this._console;
+ },
+
+ get storage() {
+ if (this._storage == null)
+ this._storage = new SessionStorage();
+
+ return this._storage;
+ },
+
+ get prefs() {
+ if (this._prefs == null)
+ this._prefs = new PreferenceBranch("");
+
+ return this._prefs;
+ },
+
+ get extensions() {
+ if (this._extensions == null)
+ this._extensions = new Extensions();
+
+ return this._extensions;
+ },
+
+ get events() {
+ if (this._events == null)
+ this._events = new Events();
+
+ return this._events;
+ },
+
+ // helper method for correct quitting/restarting
+ _quitWithFlags: function app__quitWithFlags(aFlags) {
+ let os = Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService);
+ let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
+ .createInstance(Components.interfaces.nsISupportsPRBool);
+ os.notifyObservers(cancelQuit, "quit-application-requested", null);
+ if (cancelQuit.data)
+ return false; // somebody canceled our quit request
+
+ let appStartup = Components.classes['@mozilla.org/toolkit/app-startup;1']
+ .getService(Components.interfaces.nsIAppStartup);
+ appStartup.quit(aFlags);
+ return true;
+ },
+
+ quit: function app_quit() {
+ return this._quitWithFlags(Components.interfaces.nsIAppStartup.eAttemptQuit);
+ },
+
+ restart: function app_restart() {
+ return this._quitWithFlags(Components.interfaces.nsIAppStartup.eAttemptQuit |
+ Components.interfaces.nsIAppStartup.eRestart);
+ },
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.extIApplication, Ci.nsISupportsWeakReference])
+};
diff --git a/bundles/XO/components/jsconsole-clhandler.js b/bundles/XO/components/jsconsole-clhandler.js
new file mode 100755
index 0000000..e0dffe8
--- /dev/null
+++ b/bundles/XO/components/jsconsole-clhandler.js
@@ -0,0 +1,38 @@
+//@line 41 "/builds/moz2_slave/linux_build/build/toolkit/components/console/jsconsole-clhandler.js"
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function jsConsoleHandler() {}
+jsConsoleHandler.prototype = {
+ handle: function clh_handle(cmdLine) {
+ if (!cmdLine.handleFlag("jsconsole", false))
+ return;
+
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ var console = wm.getMostRecentWindow("global:console");
+ if (!console) {
+ var wwatch = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ wwatch.openWindow(null, "chrome://global/content/console.xul", "_blank",
+ "chrome,dialog=no,all", cmdLine);
+ } else {
+ console.focus(); // the Error console was already open
+ }
+
+ if (cmdLine.state == Ci.nsICommandLine.STATE_REMOTE_AUTO)
+ cmdLine.preventDefault = true;
+ },
+
+ helpInfo : " -jsconsole Open the Error console.\n",
+
+ classDescription: "jsConsoleHandler",
+ classID: Components.ID("{2cd0c310-e127-44d0-88fc-4435c9ab4d4b}"),
+ contractID: "@mozilla.org/toolkit/console-clh;1",
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
+ _xpcom_categories: [{category: "command-line-handler", entry: "b-jsconsole"}]
+};
+
+function NSGetModule(compMgr, fileSpec)
+ XPCOMUtils.generateModule([jsConsoleHandler]);
diff --git a/bundles/XO/components/libbrowsercomps.so b/bundles/XO/components/libbrowsercomps.so
new file mode 100755
index 0000000..0dbc493
--- /dev/null
+++ b/bundles/XO/components/libbrowsercomps.so
Binary files differ
diff --git a/bundles/XO/components/libbrowserdirprovider.so b/bundles/XO/components/libbrowserdirprovider.so
new file mode 100755
index 0000000..b17f6b9
--- /dev/null
+++ b/bundles/XO/components/libbrowserdirprovider.so
Binary files differ
diff --git a/bundles/XO/components/libdbusservice.so b/bundles/XO/components/libdbusservice.so
new file mode 100755
index 0000000..ac88c21
--- /dev/null
+++ b/bundles/XO/components/libdbusservice.so
Binary files differ
diff --git a/bundles/XO/components/libimgicon.so b/bundles/XO/components/libimgicon.so
new file mode 100755
index 0000000..84f9cf7
--- /dev/null
+++ b/bundles/XO/components/libimgicon.so
Binary files differ
diff --git a/bundles/XO/components/libmozgnome.so b/bundles/XO/components/libmozgnome.so
new file mode 100755
index 0000000..33a99e8
--- /dev/null
+++ b/bundles/XO/components/libmozgnome.so
Binary files differ
diff --git a/bundles/XO/components/libnkgnomevfs.so b/bundles/XO/components/libnkgnomevfs.so
new file mode 100755
index 0000000..53928bd
--- /dev/null
+++ b/bundles/XO/components/libnkgnomevfs.so
Binary files differ
diff --git a/bundles/XO/components/nsAddonRepository.js b/bundles/XO/components/nsAddonRepository.js
new file mode 100755
index 0000000..93f9a17
--- /dev/null
+++ b/bundles/XO/components/nsAddonRepository.js
@@ -0,0 +1,349 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+//@line 38 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsAddonRepository.js"
+*/
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const PREF_GETADDONS_BROWSEADDONS = "extensions.getAddons.browseAddons";
+const PREF_GETADDONS_BROWSERECOMMENDED = "extensions.getAddons.recommended.browseURL";
+const PREF_GETADDONS_GETRECOMMENDED = "extensions.getAddons.recommended.url";
+const PREF_GETADDONS_BROWSESEARCHRESULTS = "extensions.getAddons.search.browseURL";
+const PREF_GETADDONS_GETSEARCHRESULTS = "extensions.getAddons.search.url";
+
+const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
+
+const API_VERSION = "1.2";
+
+function AddonSearchResult() {
+}
+
+AddonSearchResult.prototype = {
+ id: null,
+ name: null,
+ version: null,
+ summary: null,
+ description: null,
+ rating: null,
+ iconURL: null,
+ thumbnailURL: null,
+ homepageURL: null,
+ eula: null,
+ type: null,
+ xpiURL: null,
+ xpiHash: null,
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonSearchResult])
+}
+
+function AddonRepository() {
+}
+
+AddonRepository.prototype = {
+ // The current set of results
+ _addons: null,
+
+ // Whether we are currently searching or not
+ _searching: false,
+
+ // Is this a search for recommended add-ons
+ _recommended: false,
+
+ // XHR associated with the current request
+ _request: null,
+
+ // Callback object to notify on completion
+ _callback: null,
+
+ // Maximum number of results to return
+ _maxResults: null,
+
+ get homepageURL() {
+ return Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+ .getService(Components.interfaces.nsIURLFormatter)
+ .formatURLPref(PREF_GETADDONS_BROWSEADDONS);
+ },
+
+ get isSearching() {
+ return this._searching;
+ },
+
+ getRecommendedURL: function() {
+ var urlf = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+ .getService(Components.interfaces.nsIURLFormatter);
+
+ return urlf.formatURLPref(PREF_GETADDONS_BROWSERECOMMENDED);
+ },
+
+ getSearchURL: function(aSearchTerms) {
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+ var urlf = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+ .getService(Components.interfaces.nsIURLFormatter);
+
+ var url = prefs.getCharPref(PREF_GETADDONS_BROWSESEARCHRESULTS);
+ url = url.replace(/%TERMS%/g, encodeURIComponent(aSearchTerms));
+ return urlf.formatURL(url);
+ },
+
+ cancelSearch: function() {
+ this._searching = false;
+ if (this._request) {
+ this._request.abort();
+ this._request = null;
+ }
+ this._callback = null;
+ this._addons = null;
+ },
+
+ retrieveRecommendedAddons: function(aMaxResults, aCallback) {
+ if (this._searching)
+ return;
+
+ this._searching = true;
+ this._addons = [];
+ this._callback = aCallback;
+ this._recommended = true;
+ this._maxResults = aMaxResults;
+
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+ var urlf = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+ .getService(Components.interfaces.nsIURLFormatter);
+
+ var uri = prefs.getCharPref(PREF_GETADDONS_GETRECOMMENDED);
+ uri = uri.replace(/%API_VERSION%/g, API_VERSION);
+ uri = urlf.formatURL(uri);
+ this._loadList(uri);
+ },
+
+ searchAddons: function(aSearchTerms, aMaxResults, aCallback) {
+ if (this._searching)
+ return;
+
+ this._searching = true;
+ this._addons = [];
+ this._callback = aCallback;
+ this._recommended = false;
+ this._maxResults = aMaxResults;
+
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+ var urlf = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+ .getService(Components.interfaces.nsIURLFormatter);
+
+ var uri = prefs.getCharPref(PREF_GETADDONS_GETSEARCHRESULTS);
+ uri = uri.replace(/%API_VERSION%/g, API_VERSION);
+ // We double encode due to bug 427155
+ uri = uri.replace(/%TERMS%/g, encodeURIComponent(encodeURIComponent(aSearchTerms)));
+ uri = urlf.formatURL(uri);
+ this._loadList(uri);
+ },
+
+ // Posts results to the callback
+ _reportSuccess: function(aCount) {
+ this._searching = false;
+ this._request = null;
+ // The callback may want to trigger a new search so clear references early
+ var addons = this._addons;
+ var callback = this._callback;
+ this._callback = null;
+ this._addons = null;
+ callback.searchSucceeded(addons, addons.length, this._recommended ? -1 : aCount);
+ },
+
+ // Notifies the callback of a failure
+ _reportFailure: function(aEvent) {
+ this._searching = false;
+ this._request = null;
+ // The callback may want to trigger a new search so clear references early
+ var callback = this._callback;
+ this._callback = null;
+ this._addons = null;
+ callback.searchFailed();
+ },
+
+ // Parses an add-on entry from an <addon> element
+ _parseAddon: function(element) {
+ var em = Cc["@mozilla.org/extensions/manager;1"].
+ getService(Ci.nsIExtensionManager);
+ var app = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo).
+ QueryInterface(Ci.nsIXULRuntime);
+
+ var guid = element.getElementsByTagName("guid");
+ if (guid.length != 1)
+ return;
+
+ // Ignore add-ons already seen in the results
+ for (var i = 0; i < this._addons.length; i++)
+ if (this._addons[i].id == guid[0].textContent)
+ return;
+
+ // Ignore installed add-ons
+ if (em.getItemForID(guid[0].textContent) != null)
+ return;
+
+ // Ignore sandboxed add-ons
+ var status = element.getElementsByTagName("status");
+ // The status element has a unique id for each status type. 4 is Public.
+ if (status.length != 1 || status[0].getAttribute("id") != 4)
+ return;
+
+ // Ignore add-ons not compatible with this OS
+ var os = element.getElementsByTagName("compatible_os");
+ // Only the version 0 schema included compatible_os if it isn't there then
+ // we will see os compatibility on the install elements.
+ if (os.length > 0) {
+ var compatible = false;
+ var i = 0;
+ while (i < os.length && !compatible) {
+ if (os[i].textContent == "ALL" || os[i].textContent == app.OS) {
+ compatible = true;
+ break;
+ }
+ i++;
+ }
+ if (!compatible)
+ return;
+ }
+
+ // Ignore add-ons not compatible with this Application
+ compatible = false;
+ var tags = element.getElementsByTagName("compatible_applications");
+ if (tags.length != 1)
+ return;
+ var vc = Cc["@mozilla.org/xpcom/version-comparator;1"].
+ getService(Ci.nsIVersionComparator);
+ var apps = tags[0].getElementsByTagName("appID");
+ var i = 0;
+ while (i < apps.length) {
+ if (apps[i].textContent == app.ID) {
+ var minversion = apps[i].parentNode.getElementsByTagName("min_version")[0].textContent;
+ var maxversion = apps[i].parentNode.getElementsByTagName("max_version")[0].textContent;
+ if ((vc.compare(minversion, app.version) > 0) ||
+ (vc.compare(app.version, maxversion) > 0))
+ return;
+ compatible = true;
+ break;
+ }
+ i++;
+ }
+ if (!compatible)
+ return;
+
+ var addon = new AddonSearchResult();
+ addon.id = guid[0].textContent;
+ addon.rating = -1;
+ var node = element.firstChild;
+ while (node) {
+ if (node instanceof Ci.nsIDOMElement) {
+ switch (node.localName) {
+ case "name":
+ case "version":
+ case "summary":
+ case "description":
+ case "eula":
+ addon[node.localName] = node.textContent;
+ break;
+ case "rating":
+ if (node.textContent.length > 0) {
+ var rating = parseInt(node.textContent);
+ if (rating >= 0)
+ addon.rating = Math.min(5, rating);
+ }
+ break;
+ case "thumbnail":
+ addon.thumbnailURL = node.textContent;
+ break;
+ case "icon":
+ addon.iconURL = node.textContent;
+ break;
+ case "learnmore":
+ addon.homepageURL = node.textContent;
+ break;
+ case "type":
+ // The type element has an id attribute that is the id from AMO's
+ // database. This doesn't match our type values to perform a mapping
+ if (node.getAttribute("id") == 2)
+ addon.type = Ci.nsIUpdateItem.TYPE_THEME;
+ else
+ addon.type = Ci.nsIUpdateItem.TYPE_EXTENSION;
+ break;
+ case "install":
+ // No os attribute means the xpi is compatible with any os
+ if (node.hasAttribute("os")) {
+ var os = node.getAttribute("os").toLowerCase();
+ // If the os is not ALL and not the current OS then ignore this xpi
+ if (os != "all" && os != app.OS.toLowerCase())
+ break;
+ }
+ addon.xpiURL = node.textContent;
+ if (node.hasAttribute("hash"))
+ addon.xpiHash = node.getAttribute("hash");
+ break;
+ }
+ }
+ node = node.nextSibling;
+ }
+
+ // Add only if there was an xpi compatible with this os
+ if (addon.xpiURL)
+ this._addons.push(addon);
+ },
+
+ // Called when a single request has completed, parses out any add-ons and
+ // either notifies the callback or does a new request for more results
+ _listLoaded: function(aEvent) {
+ var request = aEvent.target;
+ var responseXML = request.responseXML;
+
+ if (!responseXML || responseXML.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
+ (request.status != 200 && request.status != 0)) {
+ this._reportFailure();
+ return;
+ }
+ var elements = responseXML.documentElement.getElementsByTagName("addon");
+ for (var i = 0; i < elements.length; i++) {
+ this._parseAddon(elements[i]);
+
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+ if (this._addons.length == this._maxResults) {
+ this._reportSuccess(elements.length);
+ return;
+ }
+ }
+
+ if (responseXML.documentElement.hasAttribute("total_results"))
+ this._reportSuccess(responseXML.documentElement.getAttribute("total_results"));
+ else
+ this._reportSuccess(elements.length);
+ },
+
+ // Performs a new request for results
+ _loadList: function(aURI) {
+ this._request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ this._request.open("GET", aURI, true);
+ this._request.overrideMimeType("text/xml");
+
+ var self = this;
+ this._request.onerror = function(event) { self._reportFailure(event); };
+ this._request.onload = function(event) { self._listLoaded(event); };
+ this._request.send(null);
+ },
+
+ classDescription: "Addon Repository",
+ contractID: "@mozilla.org/extensions/addon-repository;1",
+ classID: Components.ID("{8eaaf524-7d6d-4f7d-ae8b-9277b324008d}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonRepository])
+}
+
+function NSGetModule(aCompMgr, aFileSpec) {
+ return XPCOMUtils.generateModule([AddonRepository]);
+}
diff --git a/bundles/XO/components/nsBadCertHandler.js b/bundles/XO/components/nsBadCertHandler.js
new file mode 100755
index 0000000..b475bce
--- /dev/null
+++ b/bundles/XO/components/nsBadCertHandler.js
@@ -0,0 +1,83 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Update Service.
+ *
+ * The Initial Developer of the Original Code is Ben Goodger.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ * Daniel Veditz <dveditz@mozilla.com>
+ * Manish Singh <manish@flock.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+/**
+ * This component's job is to prevent "bad cert" security dialogs from
+ * being shown to the user when in XHR backgroundRequest mode. This
+ * causes the request to simply fail if the certificate is bad.
+ */
+function BadCertHandler() {
+}
+
+BadCertHandler.prototype = {
+
+ // Suppress any certificate errors
+ notifyCertProblem: function(socketInfo, status, targetSite) {
+ return true;
+ },
+
+ // Suppress any ssl errors
+ notifySSLError: function(socketInfo, error, targetSite) {
+ return true;
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIBadCertListener2,
+ Ci.nsISSLErrorListener,
+ Ci.nsIInterfaceRequestor]),
+
+ classDescription: "XMLHttpRequest Bad Cert Handler",
+ classID: Components.ID("{dbded6ec-edbf-4054-a834-287b82c260f9}"),
+ contractID: "@mozilla.org/content/xmlhttprequest-bad-cert-handler;1"
+};
+
+function NSGetModule(aCompMgr, aFileSpec) {
+ return XPCOMUtils.generateModule([BadCertHandler]);
+}
diff --git a/bundles/XO/components/nsBlocklistService.js b/bundles/XO/components/nsBlocklistService.js
new file mode 100755
index 0000000..327221f
--- /dev/null
+++ b/bundles/XO/components/nsBlocklistService.js
@@ -0,0 +1,1069 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+//@line 41 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsBlocklistService.js"
+*/
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const TOOLKIT_ID = "toolkit@mozilla.org"
+const KEY_PROFILEDIR = "ProfD";
+const KEY_APPDIR = "XCurProcD";
+const FILE_BLOCKLIST = "blocklist.xml";
+const PREF_BLOCKLIST_URL = "extensions.blocklist.url";
+const PREF_BLOCKLIST_ENABLED = "extensions.blocklist.enabled";
+const PREF_BLOCKLIST_INTERVAL = "extensions.blocklist.interval";
+const PREF_BLOCKLIST_LEVEL = "extensions.blocklist.level";
+const PREF_GENERAL_USERAGENT_LOCALE = "general.useragent.locale";
+const PREF_PARTNER_BRANCH = "app.partner.";
+const PREF_APP_DISTRIBUTION = "distribution.id";
+const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
+const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
+const PREF_EM_LOGGING_ENABLED = "extensions.logging.enabled";
+const XMLURI_BLOCKLIST = "http://www.mozilla.org/2006/addons-blocklist";
+const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"
+const UNKNOWN_XPCOM_ABI = "unknownABI";
+const URI_BLOCKLIST_DIALOG = "chrome://mozapps/content/extensions/blocklist.xul"
+const DEFAULT_SEVERITY = 3;
+const DEFAULT_LEVEL = 2;
+const MAX_BLOCK_LEVEL = 3;
+
+const MODE_RDONLY = 0x01;
+const MODE_WRONLY = 0x02;
+const MODE_CREATE = 0x08;
+const MODE_APPEND = 0x10;
+const MODE_TRUNCATE = 0x20;
+
+const PERMS_FILE = 0644;
+const PERMS_DIRECTORY = 0755;
+
+var gApp = null;
+var gPref = null;
+var gOS = null;
+var gConsole = null;
+var gVersionChecker = null;
+var gLoggingEnabled = null;
+var gABI = null;
+var gOSVersion = null;
+var gBlocklistEnabled = true;
+var gBlocklistLevel = DEFAULT_LEVEL;
+
+// shared code for suppressing bad cert dialogs
+//@line 41 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/shared/src/badCertHandler.js"
+
+/**
+ * Only allow built-in certs for HTTPS connections. See bug 340198.
+ */
+function checkCert(channel) {
+ if (!channel.originalURI.schemeIs("https")) // bypass
+ return;
+
+ const Ci = Components.interfaces;
+ var cert =
+ channel.securityInfo.QueryInterface(Ci.nsISSLStatusProvider).
+ SSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
+
+ var issuer = cert.issuer;
+ while (issuer && !cert.equals(issuer)) {
+ cert = issuer;
+ issuer = cert.issuer;
+ }
+
+ var errorstring = "cert issuer is not built-in";
+ if (!issuer)
+ throw errorstring;
+
+ issuer = issuer.QueryInterface(Ci.nsIX509Cert3);
+ var tokenNames = issuer.getAllTokenNames({});
+
+ if (!tokenNames.some(isBuiltinToken))
+ throw errorstring;
+}
+
+function isBuiltinToken(tokenName) {
+ return tokenName == "Builtin Object Token";
+}
+
+/**
+ * This class implements nsIBadCertListener. Its job is to prevent "bad cert"
+ * security dialogs from being shown to the user. It is better to simply fail
+ * if the certificate is bad. See bug 304286.
+ */
+function BadCertHandler() {
+}
+BadCertHandler.prototype = {
+
+ // nsIChannelEventSink
+ onChannelRedirect: function(oldChannel, newChannel, flags) {
+ // make sure the certificate of the old channel checks out before we follow
+ // a redirect from it. See bug 340198.
+ checkCert(oldChannel);
+ },
+
+ // Suppress any certificate errors
+ notifyCertProblem: function(socketInfo, status, targetSite) {
+ return true;
+ },
+
+ // Suppress any ssl errors
+ notifySSLError: function(socketInfo, error, targetSite) {
+ return true;
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ // nsISupports
+ QueryInterface: function(iid) {
+ if (!iid.equals(Components.interfaces.nsIChannelEventSink) &&
+ !iid.equals(Components.interfaces.nsIBadCertListener2) &&
+ !iid.equals(Components.interfaces.nsISSLErrorListener) &&
+ !iid.equals(Components.interfaces.nsIInterfaceRequestor) &&
+ !iid.equals(Components.interfaces.nsISupports))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ return this;
+ }
+};
+//@line 93 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsBlocklistService.js"
+
+/**
+ * Logs a string to the error console.
+ * @param string
+ * The string to write to the error console..
+ */
+function LOG(string) {
+ if (gLoggingEnabled) {
+ dump("*** " + string + "\n");
+ if (gConsole)
+ gConsole.logStringMessage(string);
+ }
+}
+
+/**
+ * Gets a preference value, handling the case where there is no default.
+ * @param func
+ * The name of the preference function to call, on nsIPrefBranch
+ * @param preference
+ * The name of the preference
+ * @param defaultValue
+ * The default value to return in the event the preference has
+ * no setting
+ * @returns The value of the preference, or undefined if there was no
+ * user or default value.
+ */
+function getPref(func, preference, defaultValue) {
+ try {
+ return gPref[func](preference);
+ }
+ catch (e) {
+ }
+ return defaultValue;
+}
+
+/**
+ * Gets the file at the specified hierarchy under a Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|. The last item in this array must be the
+ * leaf name of a file.
+ * @return nsIFile object for the file specified. The file is NOT created
+ * if it does not exist, however all required directories along
+ * the way are.
+ */
+function getFile(key, pathArray) {
+ var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ var file = fileLocator.get(key, Ci.nsILocalFile);
+ for (var i = 0; i < pathArray.length - 1; ++i) {
+ file.append(pathArray[i]);
+ if (!file.exists())
+ file.create(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ }
+ file.followLinks = false;
+ file.append(pathArray[pathArray.length - 1]);
+ return file;
+}
+
+/**
+ * Opens a safe file output stream for writing.
+ * @param file
+ * The file to write to.
+ * @param modeFlags
+ * (optional) File open flags. Can be undefined.
+ * @returns nsIFileOutputStream to write to.
+ */
+function openSafeFileOutputStream(file, modeFlags) {
+ var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ if (modeFlags === undefined)
+ modeFlags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
+ if (!file.exists())
+ file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ fos.init(file, modeFlags, PERMS_FILE, 0);
+ return fos;
+}
+
+/**
+ * Closes a safe file output stream.
+ * @param stream
+ * The stream to close.
+ */
+function closeSafeFileOutputStream(stream) {
+ if (stream instanceof Ci.nsISafeOutputStream)
+ stream.finish();
+ else
+ stream.close();
+}
+
+/**
+ * Constructs a URI to a spec.
+ * @param spec
+ * The spec to construct a URI to
+ * @returns The nsIURI constructed.
+ */
+function newURI(spec) {
+ var ioServ = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return ioServ.newURI(spec, null, null);
+}
+
+// Restarts the application checking in with observers first
+function restartApp() {
+ // Notify all windows that an application quit has been requested.
+ var os = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].
+ createInstance(Ci.nsISupportsPRBool);
+ os.notifyObservers(cancelQuit, "quit-application-requested", null);
+
+ // Something aborted the quit process.
+ if (cancelQuit.data)
+ return;
+
+ var as = Cc["@mozilla.org/toolkit/app-startup;1"].
+ getService(Ci.nsIAppStartup);
+ as.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
+}
+
+/**
+ * Checks whether this blocklist element is valid for the current OS and ABI.
+ * If the element has an "os" attribute then the current OS must appear in
+ * its comma separated list for the element to be valid. Similarly for the
+ * xpcomabi attribute.
+ */
+function matchesOSABI(blocklistElement) {
+ if (blocklistElement.hasAttribute("os")) {
+ var choices = blocklistElement.getAttribute("os").split(",");
+ if (choices.length > 0 && choices.indexOf(gApp.OS) < 0)
+ return false;
+ }
+
+ if (blocklistElement.hasAttribute("xpcomabi")) {
+ choices = blocklistElement.getAttribute("xpcomabi").split(",");
+ if (choices.length > 0 && choices.indexOf(gApp.XPCOMABI) < 0)
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Gets the current value of the locale. It's possible for this preference to
+ * be localized, so we have to do a little extra work here. Similar code
+ * exists in nsHttpHandler.cpp when building the UA string.
+ */
+function getLocale() {
+ try {
+ // Get the default branch
+ var defaultPrefs = gPref.getDefaultBranch(null);
+ return defaultPrefs.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
+ } catch (e) {}
+
+ return gPref.getCharPref(PREF_GENERAL_USERAGENT_LOCALE);
+}
+
+/**
+ * Read the update channel from defaults only. We do this to ensure that
+ * the channel is tightly coupled with the application and does not apply
+ * to other installations of the application that may use the same profile.
+ */
+function getUpdateChannel() {
+ var channel = "default";
+ var prefName;
+ var prefValue;
+
+ var defaults = gPref.getDefaultBranch(null);
+ try {
+ channel = defaults.getCharPref(PREF_APP_UPDATE_CHANNEL);
+ } catch (e) {
+ // use default when pref not found
+ }
+
+ try {
+ var partners = gPref.getChildList(PREF_PARTNER_BRANCH, { });
+ if (partners.length) {
+ channel += "-cck";
+ partners.sort();
+
+ for each (prefName in partners) {
+ prefValue = gPref.getCharPref(prefName);
+ channel += "-" + prefValue;
+ }
+ }
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ return channel;
+}
+
+/* Get the distribution pref values, from defaults only */
+function getDistributionPrefValue(aPrefName) {
+ var prefValue = "default";
+
+ var defaults = gPref.getDefaultBranch(null);
+ try {
+ prefValue = defaults.getCharPref(aPrefName);
+ } catch (e) {
+ // use default when pref not found
+ }
+
+ return prefValue;
+}
+
+/**
+ * Manages the Blocklist. The Blocklist is a representation of the contents of
+ * blocklist.xml and allows us to remotely disable / re-enable blocklisted
+ * items managed by the Extension Manager with an item's appDisabled property.
+ * It also blocklists plugins with data from blocklist.xml.
+ */
+
+function Blocklist() {
+ gApp = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
+ gApp.QueryInterface(Ci.nsIXULRuntime);
+ gPref = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).
+ QueryInterface(Ci.nsIPrefBranch2);
+ gVersionChecker = Cc["@mozilla.org/xpcom/version-comparator;1"].
+ getService(Ci.nsIVersionComparator);
+ gConsole = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+
+ gOS = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ gOS.addObserver(this, "xpcom-shutdown", false);
+
+ // Not all builds have a known ABI
+ try {
+ gABI = gApp.XPCOMABI;
+ }
+ catch (e) {
+ LOG("Blocklist: XPCOM ABI unknown.");
+ gABI = UNKNOWN_XPCOM_ABI;
+ }
+
+ var osVersion;
+ var sysInfo = Components.classes["@mozilla.org/system-info;1"]
+ .getService(Components.interfaces.nsIPropertyBag2);
+ try {
+ osVersion = sysInfo.getProperty("name") + " " + sysInfo.getProperty("version");
+ }
+ catch (e) {
+ LOG("Blocklist: OS Version unknown.");
+ }
+
+ if (osVersion) {
+ try {
+ osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
+ }
+ catch (e) {
+ // Not all platforms have a secondary widget library, so an error is nothing to worry about.
+ }
+ gOSVersion = encodeURIComponent(osVersion);
+ }
+
+//@line 362 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsBlocklistService.js"
+}
+
+Blocklist.prototype = {
+ /**
+ * Extension ID -> array of Version Ranges
+ * Each value in the version range array is a JS Object that has the
+ * following properties:
+ * "minVersion" The minimum version in a version range (default = 0)
+ * "maxVersion" The maximum version in a version range (default = *)
+ * "targetApps" Application ID -> array of Version Ranges
+ * (default = current application ID)
+ * Each value in the version range array is a JS Object that
+ * has the following properties:
+ * "minVersion" The minimum version in a version range
+ * (default = 0)
+ * "maxVersion" The maximum version in a version range
+ * (default = *)
+ */
+ _addonEntries: null,
+ _pluginEntries: null,
+
+ observe: function (aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "profile-after-change":
+ gLoggingEnabled = getPref("getBoolPref", PREF_EM_LOGGING_ENABLED, false);
+ gBlocklistEnabled = getPref("getBoolPref", PREF_BLOCKLIST_ENABLED, true);
+ gBlocklistLevel = Math.min(getPref("getIntPref", PREF_BLOCKLIST_LEVEL, DEFAULT_LEVEL),
+ MAX_BLOCK_LEVEL);
+ gPref.addObserver("extensions.blocklist.", this, false);
+ var tm = Cc["@mozilla.org/updates/timer-manager;1"].
+ getService(Ci.nsIUpdateTimerManager);
+ var interval = getPref("getIntPref", PREF_BLOCKLIST_INTERVAL, 86400);
+ tm.registerTimer("blocklist-background-update-timer", this, interval);
+ break;
+ case "xpcom-shutdown":
+ gOS.removeObserver(this, "xpcom-shutdown");
+ gOS = null;
+ gPref.removeObserver("extensions.blocklist.", this);
+ gPref = null;
+ gConsole = null;
+ gVersionChecker = null;
+ gApp = null;
+ break;
+ case "nsPref:changed":
+ switch (aData) {
+ case PREF_BLOCKLIST_ENABLED:
+ gBlocklistEnabled = getPref("getBoolPref", PREF_BLOCKLIST_ENABLED, true);
+ this._loadBlocklist();
+ this._blocklistUpdated(null, null);
+ break;
+ case PREF_BLOCKLIST_LEVEL:
+ gBlocklistLevel = Math.min(getPref("getIntPref", PREF_BLOCKLIST_LEVEL, DEFAULT_LEVEL),
+ MAX_BLOCK_LEVEL);
+ this._blocklistUpdated(null, null);
+ break;
+ }
+ break;
+ }
+ },
+
+ /* See nsIBlocklistService */
+ isAddonBlocklisted: function(id, version, appVersion, toolkitVersion) {
+ return this.getAddonBlocklistState(id, version, appVersion, toolkitVersion) ==
+ Ci.nsIBlocklistService.STATE_BLOCKED;
+ },
+
+ /* See nsIBlocklistService */
+ getAddonBlocklistState: function(id, version, appVersion, toolkitVersion) {
+ if (!this._addonEntries)
+ this._loadBlocklist();
+ return this._getAddonBlocklistState(id, version, this._addonEntries,
+ appVersion, toolkitVersion);
+ },
+
+ /**
+ * Private version of getAddonBlocklistState that allows the caller to pass in
+ * the add-on blocklist entries to compare against.
+ *
+ * @param id
+ * The ID of the item to get the blocklist state for.
+ * @param version
+ * The version of the item to get the blocklist state for.
+ * @param addonEntries
+ * The add-on blocklist entries to compare against.
+ * @param appVersion
+ * The application version to compare to, will use the current
+ * version if null.
+ * @param toolkitVersion
+ * The toolkit version to compare to, will use the current version if
+ * null.
+ * @returns The blocklist state for the item, one of the STATE constants as
+ * defined in nsIBlocklistService.
+ */
+ _getAddonBlocklistState: function(id, version, addonEntries, appVersion, toolkitVersion) {
+ if (!gBlocklistEnabled)
+ return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
+
+ if (!appVersion)
+ appVersion = gApp.version;
+ if (!toolkitVersion)
+ toolkitVersion = gApp.platformVersion;
+
+ var blItem = addonEntries[id];
+ if (!blItem)
+ return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
+
+ for (var i = 0; i < blItem.length; ++i) {
+ if (blItem[i].includesItem(version, appVersion, toolkitVersion))
+ return blItem[i].severity >= gBlocklistLevel ? Ci.nsIBlocklistService.STATE_BLOCKED :
+ Ci.nsIBlocklistService.STATE_SOFTBLOCKED;
+ }
+ return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
+ },
+
+ notify: function(aTimer) {
+ if (!gBlocklistEnabled)
+ return;
+
+ try {
+ var dsURI = gPref.getCharPref(PREF_BLOCKLIST_URL);
+ }
+ catch (e) {
+ LOG("Blocklist::notify: The " + PREF_BLOCKLIST_URL + " preference" +
+ " is missing!");
+ return;
+ }
+
+ dsURI = dsURI.replace(/%APP_ID%/g, gApp.ID);
+ dsURI = dsURI.replace(/%APP_VERSION%/g, gApp.version);
+ dsURI = dsURI.replace(/%PRODUCT%/g, gApp.name);
+ dsURI = dsURI.replace(/%VERSION%/g, gApp.version);
+ dsURI = dsURI.replace(/%BUILD_ID%/g, gApp.appBuildID);
+ dsURI = dsURI.replace(/%BUILD_TARGET%/g, gApp.OS + "_" + gABI);
+ dsURI = dsURI.replace(/%OS_VERSION%/g, gOSVersion);
+ dsURI = dsURI.replace(/%LOCALE%/g, getLocale());
+ dsURI = dsURI.replace(/%CHANNEL%/g, getUpdateChannel());
+ dsURI = dsURI.replace(/%PLATFORM_VERSION%/g, gApp.platformVersion);
+ dsURI = dsURI.replace(/%DISTRIBUTION%/g,
+ getDistributionPrefValue(PREF_APP_DISTRIBUTION));
+ dsURI = dsURI.replace(/%DISTRIBUTION_VERSION%/g,
+ getDistributionPrefValue(PREF_APP_DISTRIBUTION_VERSION));
+ dsURI = dsURI.replace(/\+/g, "%2B");
+
+ // Verify that the URI is valid
+ try {
+ var uri = newURI(dsURI);
+ }
+ catch (e) {
+ LOG("Blocklist::notify: There was an error creating the blocklist URI\r\n" +
+ "for: " + dsURI + ", error: " + e);
+ return;
+ }
+
+ var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ request.open("GET", uri.spec, true);
+ request.channel.notificationCallbacks = new BadCertHandler();
+ request.overrideMimeType("text/xml");
+ request.setRequestHeader("Cache-Control", "no-cache");
+ request.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
+
+ var self = this;
+ request.onerror = function(event) { self.onXMLError(event); };
+ request.onload = function(event) { self.onXMLLoad(event); };
+ request.send(null);
+
+ // When the blocklist loads we need to compare it to the current copy so
+ // make sure we have loaded it.
+ if (!this._addonEntries)
+ this._loadBlocklist();
+ },
+
+ onXMLLoad: function(aEvent) {
+ var request = aEvent.target;
+ try {
+ checkCert(request.channel);
+ }
+ catch (e) {
+ LOG("Blocklist::onXMLLoad: " + e);
+ return;
+ }
+ var responseXML = request.responseXML;
+ if (!responseXML || responseXML.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
+ (request.status != 200 && request.status != 0)) {
+ LOG("Blocklist::onXMLLoad: there was an error during load");
+ return;
+ }
+ var blocklistFile = getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]);
+ if (blocklistFile.exists())
+ blocklistFile.remove(false);
+ var fos = openSafeFileOutputStream(blocklistFile);
+ fos.write(request.responseText, request.responseText.length);
+ closeSafeFileOutputStream(fos);
+
+ var oldAddonEntries = this._addonEntries;
+ var oldPluginEntries = this._pluginEntries;
+ this._addonEntries = { };
+ this._pluginEntries = { };
+ this._loadBlocklistFromFile(getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]));
+
+ this._blocklistUpdated(oldAddonEntries, oldPluginEntries);
+ },
+
+ onXMLError: function(aEvent) {
+ try {
+ var request = aEvent.target;
+ // the following may throw (e.g. a local file or timeout)
+ var status = request.status;
+ }
+ catch (e) {
+ request = aEvent.target.channel.QueryInterface(Ci.nsIRequest);
+ status = request.status;
+ }
+ var statusText = request.statusText;
+ // When status is 0 we don't have a valid channel.
+ if (status == 0)
+ statusText = "nsIXMLHttpRequest channel unavailable";
+ LOG("Blocklist:onError: There was an error loading the blocklist file\r\n" +
+ statusText);
+ },
+
+ /**
+ * Finds the newest blocklist file from the application and the profile and
+ * load it or does nothing if neither exist.
+ */
+ _loadBlocklist: function() {
+ this._addonEntries = { };
+ this._pluginEntries = { };
+ var profFile = getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]);
+ if (profFile.exists()) {
+ this._loadBlocklistFromFile(profFile);
+ return;
+ }
+ var appFile = getFile(KEY_APPDIR, [FILE_BLOCKLIST]);
+ if (appFile.exists()) {
+ this._loadBlocklistFromFile(appFile);
+ return;
+ }
+ LOG("Blocklist::_loadBlocklist: no XML File found");
+ },
+
+ /**
+//@line 653 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsBlocklistService.js"
+ */
+
+ _loadBlocklistFromFile: function(file) {
+ if (!gBlocklistEnabled) {
+ LOG("Blocklist::_loadBlocklistFromFile: blocklist is disabled");
+ return;
+ }
+
+ if (!file.exists()) {
+ LOG("Blocklist::_loadBlocklistFromFile: XML File does not exist");
+ return;
+ }
+
+ var fileStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ fileStream.init(file, MODE_RDONLY, PERMS_FILE, 0);
+ try {
+ var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
+ createInstance(Ci.nsIDOMParser);
+ var doc = parser.parseFromStream(fileStream, "UTF-8", file.fileSize, "text/xml");
+ if (doc.documentElement.namespaceURI != XMLURI_BLOCKLIST) {
+ LOG("Blocklist::_loadBlocklistFromFile: aborting due to incorrect " +
+ "XML Namespace.\r\nExpected: " + XMLURI_BLOCKLIST + "\r\n" +
+ "Received: " + doc.documentElement.namespaceURI);
+ return;
+ }
+
+ var childNodes = doc.documentElement.childNodes;
+ this._addonEntries = this._processItemNodes(childNodes, "em",
+ this._handleEmItemNode);
+ this._pluginEntries = this._processItemNodes(childNodes, "plugin",
+ this._handlePluginItemNode);
+ }
+ catch (e) {
+ LOG("Blocklist::_loadBlocklistFromFile: Error constructing blocklist " + e);
+ return;
+ }
+ fileStream.close();
+ },
+
+ _processItemNodes: function(deChildNodes, prefix, handler) {
+ var result = [];
+ var itemNodes;
+ var containerName = prefix + "Items";
+ for (var i = 0; i < deChildNodes.length; ++i) {
+ var emItemsElement = deChildNodes.item(i);
+ if (emItemsElement instanceof Ci.nsIDOMElement &&
+ emItemsElement.localName == containerName) {
+ itemNodes = emItemsElement.childNodes;
+ break;
+ }
+ }
+ if (!itemNodes)
+ return result;
+
+ var itemName = prefix + "Item";
+ for (var i = 0; i < itemNodes.length; ++i) {
+ var blocklistElement = itemNodes.item(i);
+ if (!(blocklistElement instanceof Ci.nsIDOMElement) ||
+ blocklistElement.localName != itemName)
+ continue;
+
+ handler(blocklistElement, result);
+ }
+ return result;
+ },
+
+ _handleEmItemNode: function(blocklistElement, result) {
+ if (!matchesOSABI(blocklistElement))
+ return;
+
+ var versionNodes = blocklistElement.childNodes;
+ var id = blocklistElement.getAttribute("id");
+ result[id] = [];
+ for (var x = 0; x < versionNodes.length; ++x) {
+ var versionRangeElement = versionNodes.item(x);
+ if (!(versionRangeElement instanceof Ci.nsIDOMElement) ||
+ versionRangeElement.localName != "versionRange")
+ continue;
+
+ result[id].push(new BlocklistItemData(versionRangeElement));
+ }
+ // if only the extension ID is specified block all versions of the
+ // extension for the current application.
+ if (result[id].length == 0)
+ result[id].push(new BlocklistItemData(null));
+ },
+
+ _handlePluginItemNode: function(blocklistElement, result) {
+ if (!matchesOSABI(blocklistElement))
+ return;
+
+ var matchNodes = blocklistElement.childNodes;
+ var blockEntry = {
+ matches: {},
+ versions: []
+ };
+ for (var x = 0; x < matchNodes.length; ++x) {
+ var matchElement = matchNodes.item(x);
+ if (!(matchElement instanceof Ci.nsIDOMElement))
+ continue;
+ if (matchElement.localName == "match") {
+ var name = matchElement.getAttribute("name");
+ var exp = matchElement.getAttribute("exp");
+ blockEntry.matches[name] = new RegExp(exp, "m");
+ }
+ if (matchElement.localName == "versionRange")
+ blockEntry.versions.push(new BlocklistItemData(matchElement));
+ }
+ // Add a default versionRange if there wasn't one specified
+ if (blockEntry.versions.length == 0)
+ blockEntry.versions.push(new BlocklistItemData(null));
+ result.push(blockEntry);
+ },
+
+ /* See nsIBlocklistService */
+ getPluginBlocklistState: function(plugin, appVersion, toolkitVersion) {
+ if (!this._pluginEntries)
+ this._loadBlocklist();
+ return this._getPluginBlocklistState(plugin, this._pluginEntries,
+ appVersion, toolkitVersion);
+ },
+
+ /**
+ * Private version of getPluginBlocklistState that allows the caller to pass in
+ * the plugin blocklist entries.
+ *
+ * @param plugin
+ * The nsIPluginTag to get the blocklist state for.
+ * @param pluginEntries
+ * The plugin blocklist entries to compare against.
+ * @param appVersion
+ * The application version to compare to, will use the current
+ * version if null.
+ * @param toolkitVersion
+ * The toolkit version to compare to, will use the current version if
+ * null.
+ * @returns The blocklist state for the item, one of the STATE constants as
+ * defined in nsIBlocklistService.
+ */
+ _getPluginBlocklistState: function(plugin, pluginEntries, appVersion, toolkitVersion) {
+ if (!gBlocklistEnabled)
+ return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
+
+ if (!appVersion)
+ appVersion = gApp.version;
+ if (!toolkitVersion)
+ toolkitVersion = gApp.platformVersion;
+
+ for each (var blockEntry in pluginEntries) {
+ var matchFailed = false;
+ for (var name in blockEntry.matches) {
+ if (!(name in plugin) ||
+ typeof(plugin[name]) != "string" ||
+ !blockEntry.matches[name].test(plugin[name])) {
+ matchFailed = true;
+ break;
+ }
+ }
+
+ if (matchFailed)
+ continue;
+
+ for (var i = 0; i < blockEntry.versions.length; i++) {
+ if (blockEntry.versions[i].includesItem(plugin.version, appVersion,
+ toolkitVersion))
+ return blockEntry.versions[i].severity >= gBlocklistLevel ?
+ Ci.nsIBlocklistService.STATE_BLOCKED :
+ Ci.nsIBlocklistService.STATE_SOFTBLOCKED;
+ }
+ }
+
+ return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
+ },
+
+ _blocklistUpdated: function(oldAddonEntries, oldPluginEntries) {
+ var addonList = [];
+
+ var em = Cc["@mozilla.org/extensions/manager;1"].
+ getService(Ci.nsIExtensionManager);
+ var addons = em.updateAndGetNewBlocklistedItems({});
+
+ for (let i = 0; i < addons.length; i++) {
+ let oldState = -1;
+ if (oldAddonEntries)
+ oldState = this._getAddonBlocklistState(addons[i].id, addons[i].version,
+ oldAddonEntries);
+ let state = this.getAddonBlocklistState(addons[i].id, addons[i].version);
+ // We don't want to re-warn about items
+ if (state == oldState)
+ continue;
+
+ addonList.push({
+ name: addons[i].name,
+ version: addons[i].version,
+ icon: addons[i].iconURL,
+ disable: false,
+ blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
+ item: addons[i]
+ });
+ }
+
+ var phs = Cc["@mozilla.org/plugin/host;1"].
+ getService(Ci.nsIPluginHost);
+ var plugins = phs.getPluginTags({});
+
+ for (let i = 0; i < plugins.length; i++) {
+ let oldState = -1;
+ if (oldPluginEntries)
+ oldState = this._getPluginBlocklistState(plugins[i], oldPluginEntries);
+ let state = this.getPluginBlocklistState(plugins[i]);
+ // We don't want to re-warn about items
+ if (state == oldState)
+ continue;
+
+ if (plugins[i].blocklisted) {
+ if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
+ plugins[i].disabled = true;
+ }
+ else if (!plugins[i].disabled && state != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
+ addonList.push({
+ name: plugins[i].name,
+ version: plugins[i].version,
+ icon: "chrome://mozapps/skin/plugins/pluginGeneric.png",
+ disable: false,
+ blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
+ item: plugins[i]
+ });
+ }
+ plugins[i].blocklisted = state == Ci.nsIBlocklistService.STATE_BLOCKED;
+ }
+
+ if (addonList.length == 0)
+ return;
+
+ var args = {
+ restart: false,
+ list: addonList
+ };
+ // This lets the dialog get the raw js object
+ args.wrappedJSObject = args;
+
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(null, URI_BLOCKLIST_DIALOG, "",
+ "chrome,centerscreen,dialog,modal,titlebar", args);
+
+ for (let i = 0; i < addonList.length; i++) {
+ if (!addonList[i].disable)
+ continue;
+
+ if (addonList[i].item instanceof Ci.nsIUpdateItem)
+ em.disableItem(addonList[i].item.id);
+ else if (addonList[i].item instanceof Ci.nsIPluginTag)
+ addonList[i].item.disabled = true;
+ else
+ LOG("Unknown add-on type: " + addonList[i].item);
+ }
+
+ if (args.restart)
+ restartApp();
+ },
+
+ classDescription: "Blocklist Service",
+ contractID: "@mozilla.org/extensions/blocklist;1",
+ classID: Components.ID("{66354bc9-7ed1-4692-ae1d-8da97d6b205e}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsIBlocklistService,
+ Ci.nsITimerCallback]),
+ _xpcom_categories: [{ category: "profile-after-change" }]
+};
+
+/**
+ * Helper for constructing a blocklist.
+ */
+function BlocklistItemData(versionRangeElement) {
+ var versionRange = this.getBlocklistVersionRange(versionRangeElement);
+ this.minVersion = versionRange.minVersion;
+ this.maxVersion = versionRange.maxVersion;
+ if (versionRangeElement && versionRangeElement.hasAttribute("severity"))
+ this.severity = versionRangeElement.getAttribute("severity");
+ else
+ this.severity = DEFAULT_SEVERITY;
+ this.targetApps = { };
+ var found = false;
+
+ if (versionRangeElement) {
+ for (var i = 0; i < versionRangeElement.childNodes.length; ++i) {
+ var targetAppElement = versionRangeElement.childNodes.item(i);
+ if (!(targetAppElement instanceof Ci.nsIDOMElement) ||
+ targetAppElement.localName != "targetApplication")
+ continue;
+ found = true;
+ // default to the current application if id is not provided.
+ var appID = targetAppElement.hasAttribute("id") ? targetAppElement.getAttribute("id") : gApp.ID;
+ this.targetApps[appID] = this.getBlocklistAppVersions(targetAppElement);
+ }
+ }
+ // Default to all versions of the current application when no targetApplication
+ // elements were found
+ if (!found)
+ this.targetApps[gApp.ID] = this.getBlocklistAppVersions(null);
+}
+
+BlocklistItemData.prototype = {
+ /**
+ * Tests if a version of an item is included in the version range and target
+ * application information represented by this BlocklistItemData using the
+ * provided application and toolkit versions.
+ * @param version
+ * The version of the item being tested.
+ * @param appVersion
+ * The application version to test with.
+ * @param toolkitVersion
+ * The toolkit version to test with.
+ * @returns True if the version range covers the item version and application
+ * or toolkit version.
+ */
+ includesItem: function(version, appVersion, toolkitVersion) {
+ // Some platforms have no version for plugins, these don't match if there
+ // was a min/maxVersion provided
+ if (!version && (this.minVersion || this.maxVersion))
+ return false;
+
+ // Check if the item version matches
+ if (!this.matchesRange(version, this.minVersion, this.maxVersion))
+ return false;
+
+ // Check if the application version matches
+ if (this.matchesTargetRange(gApp.ID, appVersion))
+ return true;
+
+ // Check if the toolkit version matches
+ return this.matchesTargetRange(TOOLKIT_ID, toolkitVersion);
+ },
+
+ /**
+ * Checks if a version is higher than or equal to the minVersion (if provided)
+ * and lower than or equal to the maxVersion (if provided).
+ * @param version
+ * The version to test.
+ * @param minVersion
+ * The minimum version. If null it is assumed that version is always
+ * larger.
+ * @param maxVersion
+ * The maximum version. If null it is assumed that version is always
+ * smaller.
+ */
+ matchesRange: function(version, minVersion, maxVersion) {
+ if (minVersion && gVersionChecker.compare(version, minVersion) < 0)
+ return false;
+ if (maxVersion && gVersionChecker.compare(version, maxVersion) > 0)
+ return false;
+ return true;
+ },
+
+ /**
+ * Tests if there is a matching range for the given target application id and
+ * version.
+ * @param appID
+ * The application ID to test for, may be for an application or toolkit
+ * @param appVersion
+ * The version of the application to test for.
+ * @returns True if this version range covers the application version given.
+ */
+ matchesTargetRange: function(appID, appVersion) {
+ var blTargetApp = this.targetApps[appID];
+ if (!blTargetApp)
+ return false;
+
+ for (var x = 0; x < blTargetApp.length; ++x) {
+ if (this.matchesRange(appVersion, blTargetApp[x].minVersion, blTargetApp[x].maxVersion))
+ return true;
+ }
+
+ return false;
+ },
+
+ /**
+ * Retrieves a version range (e.g. minVersion and maxVersion) for a
+ * blocklist item's targetApplication element.
+ * @param targetAppElement
+ * A targetApplication blocklist element.
+ * @returns An array of JS objects with the following properties:
+ * "minVersion" The minimum version in a version range (default = null).
+ * "maxVersion" The maximum version in a version range (default = null).
+ */
+ getBlocklistAppVersions: function(targetAppElement) {
+ var appVersions = [ ];
+
+ if (targetAppElement) {
+ for (var i = 0; i < targetAppElement.childNodes.length; ++i) {
+ var versionRangeElement = targetAppElement.childNodes.item(i);
+ if (!(versionRangeElement instanceof Ci.nsIDOMElement) ||
+ versionRangeElement.localName != "versionRange")
+ continue;
+ appVersions.push(this.getBlocklistVersionRange(versionRangeElement));
+ }
+ }
+ // return minVersion = null and maxVersion = null if no specific versionRange
+ // elements were found
+ if (appVersions.length == 0)
+ appVersions.push(this.getBlocklistVersionRange(null));
+ return appVersions;
+ },
+
+ /**
+ * Retrieves a version range (e.g. minVersion and maxVersion) for a blocklist
+ * versionRange element.
+ * @param versionRangeElement
+ * The versionRange blocklist element.
+ * @returns A JS object with the following properties:
+ * "minVersion" The minimum version in a version range (default = null).
+ * "maxVersion" The maximum version in a version range (default = null).
+ */
+ getBlocklistVersionRange: function(versionRangeElement) {
+ var minVersion = null;
+ var maxVersion = null;
+ if (!versionRangeElement)
+ return { minVersion: minVersion, maxVersion: maxVersion };
+
+ if (versionRangeElement.hasAttribute("minVersion"))
+ minVersion = versionRangeElement.getAttribute("minVersion");
+ if (versionRangeElement.hasAttribute("maxVersion"))
+ maxVersion = versionRangeElement.getAttribute("maxVersion");
+
+ return { minVersion: minVersion, maxVersion: maxVersion };
+ }
+};
+
+function NSGetModule(aCompMgr, aFileSpec) {
+ return XPCOMUtils.generateModule([Blocklist]);
+}
diff --git a/bundles/XO/components/nsBrowserContentHandler.js b/bundles/XO/components/nsBrowserContentHandler.js
new file mode 100755
index 0000000..fd5ccb2
--- /dev/null
+++ b/bundles/XO/components/nsBrowserContentHandler.js
@@ -0,0 +1,884 @@
+//@line 37 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserContentHandler.js"
+
+const nsISupports = Components.interfaces.nsISupports;
+
+const nsIBrowserDOMWindow = Components.interfaces.nsIBrowserDOMWindow;
+const nsIBrowserHandler = Components.interfaces.nsIBrowserHandler;
+const nsIBrowserHistory = Components.interfaces.nsIBrowserHistory;
+const nsIChannel = Components.interfaces.nsIChannel;
+const nsICommandLine = Components.interfaces.nsICommandLine;
+const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
+const nsIContentHandler = Components.interfaces.nsIContentHandler;
+const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
+const nsIDOMChromeWindow = Components.interfaces.nsIDOMChromeWindow;
+const nsIDOMWindow = Components.interfaces.nsIDOMWindow;
+const nsIFactory = Components.interfaces.nsIFactory;
+const nsIFileURL = Components.interfaces.nsIFileURL;
+const nsIHttpProtocolHandler = Components.interfaces.nsIHttpProtocolHandler;
+const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
+const nsINetUtil = Components.interfaces.nsINetUtil;
+const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
+const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
+const nsISupportsString = Components.interfaces.nsISupportsString;
+const nsIURIFixup = Components.interfaces.nsIURIFixup;
+const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
+const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
+const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
+const nsICategoryManager = Components.interfaces.nsICategoryManager;
+const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo;
+const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
+const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
+
+const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED;
+const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
+const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
+
+const URI_INHERITS_SECURITY_CONTEXT = nsIHttpProtocolHandler
+ .URI_INHERITS_SECURITY_CONTEXT;
+
+function shouldLoadURI(aURI) {
+ if (aURI && !aURI.schemeIs("chrome"))
+ return true;
+
+ dump("*** Preventing external load of chrome: URI into browser window\n");
+ dump(" Use -chrome <uri> instead\n");
+ return false;
+}
+
+function resolveURIInternal(aCmdLine, aArgument) {
+ var uri = aCmdLine.resolveURI(aArgument);
+
+ if (!(uri instanceof nsIFileURL)) {
+ return uri;
+ }
+
+ try {
+ if (uri.file.exists())
+ return uri;
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ // We have interpreted the argument as a relative file URI, but the file
+ // doesn't exist. Try URI fixup heuristics: see bug 290782.
+
+ try {
+ var urifixup = Components.classes["@mozilla.org/docshell/urifixup;1"]
+ .getService(nsIURIFixup);
+
+ uri = urifixup.createFixupURI(aArgument, 0);
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ return uri;
+}
+
+const OVERRIDE_NONE = 0;
+const OVERRIDE_NEW_PROFILE = 1;
+const OVERRIDE_NEW_MSTONE = 2;
+/**
+ * Determines whether a home page override is needed.
+ * Returns:
+ * OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
+ * OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
+ * Gecko milestone (i.e. right after an upgrade).
+ * OVERRIDE_NONE otherwise.
+ */
+function needHomepageOverride(prefb) {
+ var savedmstone = null;
+ try {
+ savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
+ } catch (e) {}
+
+ if (savedmstone == "ignore")
+ return OVERRIDE_NONE;
+
+ var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
+ .getService(nsIHttpProtocolHandler).misc;
+
+ if (mstone != savedmstone) {
+ // Bug 462254. Previous releases had a default pref to suppress the EULA
+ // agreement if the platform's installer had already shown one. Now with
+ // about:rights we've removed the EULA stuff and default pref, but we need
+ // a way to make existing profiles retain the default that we removed.
+ if (savedmstone)
+ prefb.setBoolPref("browser.rights.3.shown", true);
+
+ prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
+ return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
+ }
+
+ return OVERRIDE_NONE;
+}
+
+// Copies a pref override file into the user's profile pref-override folder,
+// and then tells the pref service to reload its default prefs.
+function copyPrefOverride() {
+ try {
+ var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties);
+ const NS_APP_EXISTING_PREF_OVERRIDE = "ExistingPrefOverride";
+ var prefOverride = fileLocator.get(NS_APP_EXISTING_PREF_OVERRIDE,
+ Components.interfaces.nsIFile);
+ if (!prefOverride.exists())
+ return; // nothing to do
+
+ const NS_APP_PREFS_OVERRIDE_DIR = "PrefDOverride";
+ var prefOverridesDir = fileLocator.get(NS_APP_PREFS_OVERRIDE_DIR,
+ Components.interfaces.nsIFile);
+
+ // Check for any existing pref overrides, and remove them if present
+ var existingPrefOverridesFile = prefOverridesDir.clone();
+ existingPrefOverridesFile.append(prefOverride.leafName);
+ if (existingPrefOverridesFile.exists())
+ existingPrefOverridesFile.remove(false);
+
+ prefOverride.copyTo(prefOverridesDir, null);
+
+ // Now that we've installed the new-profile pref override file,
+ // re-read the default prefs.
+ var prefSvcObs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIObserver);
+ prefSvcObs.observe(null, "reload-default-prefs", null);
+ } catch (ex) {
+ Components.utils.reportError(ex);
+ }
+}
+
+// Flag used to indicate that the arguments to openWindow can be passed directly.
+const NO_EXTERNAL_URIS = 1;
+
+function openWindow(parent, url, target, features, args, noExternalArgs) {
+ var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
+ .getService(nsIWindowWatcher);
+
+ if (noExternalArgs == NO_EXTERNAL_URIS) {
+ // Just pass in the defaultArgs directly
+ var argstring;
+ if (args) {
+ argstring = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(nsISupportsString);
+ argstring.data = args;
+ }
+
+ return wwatch.openWindow(parent, url, target, features, argstring);
+ }
+
+ // Pass an array to avoid the browser "|"-splitting behavior.
+ var argArray = Components.classes["@mozilla.org/supports-array;1"]
+ .createInstance(Components.interfaces.nsISupportsArray);
+
+ // add args to the arguments array
+ var stringArgs = null;
+ if (args instanceof Array) // array
+ stringArgs = args;
+ else if (args) // string
+ stringArgs = [args];
+
+ if (stringArgs) {
+ // put the URIs into argArray
+ var uriArray = Components.classes["@mozilla.org/supports-array;1"]
+ .createInstance(Components.interfaces.nsISupportsArray);
+ stringArgs.forEach(function (uri) {
+ var sstring = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(nsISupportsString);
+ sstring.data = uri;
+ uriArray.AppendElement(sstring);
+ });
+ argArray.AppendElement(uriArray);
+ } else {
+ argArray.AppendElement(null);
+ }
+
+ // Pass these as null to ensure that we always trigger the "single URL"
+ // behavior in browser.js's BrowserStartup (which handles the window
+ // arguments)
+ argArray.AppendElement(null); // charset
+ argArray.AppendElement(null); // referer
+ argArray.AppendElement(null); // postData
+ argArray.AppendElement(null); // allowThirdPartyFixup
+
+ return wwatch.openWindow(parent, url, target, features, argArray);
+}
+
+function openPreferences() {
+ var features = "chrome,titlebar,toolbar,centerscreen,dialog=no";
+ var url = "chrome://browser/content/preferences/preferences.xul";
+
+ var win = getMostRecentWindow("Browser:Preferences");
+ if (win) {
+ win.focus();
+ } else {
+ openWindow(null, url, "_blank", features);
+ }
+}
+
+function getMostRecentWindow(aType) {
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(nsIWindowMediator);
+ return wm.getMostRecentWindow(aType);
+}
+
+// this returns the most recent non-popup browser window
+function getMostRecentBrowserWindow() {
+ var browserGlue = Components.classes["@mozilla.org/browser/browserglue;1"]
+ .getService(Components.interfaces.nsIBrowserGlue);
+ return browserGlue.getMostRecentBrowserWindow();
+}
+
+function doSearch(searchTerm, cmdLine) {
+ var ss = Components.classes["@mozilla.org/browser/search-service;1"]
+ .getService(nsIBrowserSearchService);
+
+ var submission = ss.defaultEngine.getSubmission(searchTerm, null);
+
+ // fill our nsISupportsArray with uri-as-wstring, null, null, postData
+ var sa = Components.classes["@mozilla.org/supports-array;1"]
+ .createInstance(Components.interfaces.nsISupportsArray);
+
+ var wuri = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(Components.interfaces.nsISupportsString);
+ wuri.data = submission.uri.spec;
+
+ sa.AppendElement(wuri);
+ sa.AppendElement(null);
+ sa.AppendElement(null);
+ sa.AppendElement(submission.postData);
+
+ // XXXbsmedberg: use handURIToExistingBrowser to obey tabbed-browsing
+ // preferences, but need nsIBrowserDOMWindow extensions
+
+ var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
+ .getService(nsIWindowWatcher);
+
+ return wwatch.openWindow(null, nsBrowserContentHandler.chromeURL,
+ "_blank",
+ "chrome,dialog=no,all" +
+ nsBrowserContentHandler.getFeatures(cmdLine),
+ sa);
+}
+
+var nsBrowserContentHandler = {
+ /* helper functions */
+
+ mChromeURL : null,
+
+ get chromeURL() {
+ if (this.mChromeURL) {
+ return this.mChromeURL;
+ }
+
+ var prefb = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(nsIPrefBranch);
+ this.mChromeURL = prefb.getCharPref("browser.chromeURL");
+
+ return this.mChromeURL;
+ },
+
+ /* nsISupports */
+ QueryInterface : function bch_QI(iid) {
+ if (!iid.equals(nsISupports) &&
+ !iid.equals(nsICommandLineHandler) &&
+ !iid.equals(nsIBrowserHandler) &&
+ !iid.equals(nsIContentHandler) &&
+ !iid.equals(nsICommandLineValidator) &&
+ !iid.equals(nsIFactory))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+
+ return this;
+ },
+
+ /* nsICommandLineHandler */
+ handle : function bch_handle(cmdLine) {
+ if (cmdLine.handleFlag("browser", false)) {
+ // Passing defaultArgs, so use NO_EXTERNAL_URIS
+ openWindow(null, this.chromeURL, "_blank",
+ "chrome,dialog=no,all" + this.getFeatures(cmdLine),
+ this.defaultArgs, NO_EXTERNAL_URIS);
+ cmdLine.preventDefault = true;
+ }
+
+ try {
+ var remoteCommand = cmdLine.handleFlagWithParam("remote", true);
+ }
+ catch (e) {
+ throw NS_ERROR_ABORT;
+ }
+
+ if (remoteCommand != null) {
+ try {
+ var a = /^\s*(\w+)\(([^\)]*)\)\s*$/.exec(remoteCommand);
+ var remoteVerb;
+ if (a) {
+ remoteVerb = a[1].toLowerCase();
+ var remoteParams = [];
+ var sepIndex = a[2].lastIndexOf(",");
+ if (sepIndex == -1)
+ remoteParams[0] = a[2];
+ else {
+ remoteParams[0] = a[2].substring(0, sepIndex);
+ remoteParams[1] = a[2].substring(sepIndex + 1);
+ }
+ }
+
+ switch (remoteVerb) {
+ case "openurl":
+ case "openfile":
+ // openURL(<url>)
+ // openURL(<url>,new-window)
+ // openURL(<url>,new-tab)
+
+ // First param is the URL, second param (if present) is the "target"
+ // (tab, window)
+ var url = remoteParams[0];
+ var target = nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW;
+ if (remoteParams[1]) {
+ var targetParam = remoteParams[1].toLowerCase()
+ .replace(/^\s*|\s*$/g, "");
+ if (targetParam == "new-tab")
+ target = nsIBrowserDOMWindow.OPEN_NEWTAB;
+ else if (targetParam == "new-window")
+ target = nsIBrowserDOMWindow.OPEN_NEWWINDOW;
+ else {
+ // The "target" param isn't one of our supported values, so
+ // assume it's part of a URL that contains commas.
+ url += "," + remoteParams[1];
+ }
+ }
+
+ var uri = resolveURIInternal(cmdLine, url);
+ handURIToExistingBrowser(uri, target, cmdLine);
+ break;
+
+ case "xfedocommand":
+ // xfeDoCommand(openBrowser)
+ if (remoteParams[0].toLowerCase() != "openbrowser")
+ throw NS_ERROR_ABORT;
+
+ // Passing defaultArgs, so use NO_EXTERNAL_URIS
+ openWindow(null, this.chromeURL, "_blank",
+ "chrome,dialog=no,all" + this.getFeatures(cmdLine),
+ this.defaultArgs, NO_EXTERNAL_URIS);
+ break;
+
+ default:
+ // Somebody sent us a remote command we don't know how to process:
+ // just abort.
+ throw "Unknown remote command.";
+ }
+
+ cmdLine.preventDefault = true;
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ // If we had a -remote flag but failed to process it, throw
+ // NS_ERROR_ABORT so that the xremote code knows to return a failure
+ // back to the handling code.
+ throw NS_ERROR_ABORT;
+ }
+ }
+
+ var uriparam;
+ try {
+ while ((uriparam = cmdLine.handleFlagWithParam("new-window", false))) {
+ var uri = resolveURIInternal(cmdLine, uriparam);
+ if (!shouldLoadURI(uri))
+ continue;
+ openWindow(null, this.chromeURL, "_blank",
+ "chrome,dialog=no,all" + this.getFeatures(cmdLine),
+ uri.spec);
+ cmdLine.preventDefault = true;
+ }
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ try {
+ while ((uriparam = cmdLine.handleFlagWithParam("new-tab", false))) {
+ var uri = resolveURIInternal(cmdLine, uriparam);
+ handURIToExistingBrowser(uri, nsIBrowserDOMWindow.OPEN_NEWTAB, cmdLine);
+ cmdLine.preventDefault = true;
+ }
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ var chromeParam = cmdLine.handleFlagWithParam("chrome", false);
+ if (chromeParam) {
+
+ // Handle the old preference dialog URL separately (bug 285416)
+ if (chromeParam == "chrome://browser/content/pref/pref.xul") {
+ openPreferences();
+ cmdLine.preventDefault = true;
+ } else try {
+ // only load URIs which do not inherit chrome privs
+ var features = "chrome,dialog=no,all" + this.getFeatures(cmdLine);
+ var uri = resolveURIInternal(cmdLine, chromeParam);
+ var netutil = Components.classes["@mozilla.org/network/util;1"]
+ .getService(nsINetUtil);
+ if (!netutil.URIChainHasFlags(uri, URI_INHERITS_SECURITY_CONTEXT)) {
+ openWindow(null, uri.spec, "_blank", features);
+ cmdLine.preventDefault = true;
+ }
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+ }
+ if (cmdLine.handleFlag("preferences", false)) {
+ openPreferences();
+ cmdLine.preventDefault = true;
+ }
+ if (cmdLine.handleFlag("silent", false))
+ cmdLine.preventDefault = true;
+
+ var searchParam = cmdLine.handleFlagWithParam("search", false);
+ if (searchParam) {
+ doSearch(searchParam, cmdLine);
+ cmdLine.preventDefault = true;
+ }
+
+ var fileParam = cmdLine.handleFlagWithParam("file", false);
+ if (fileParam) {
+ var file = cmdLine.resolveFile(fileParam);
+ var ios = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+ var uri = ios.newFileURI(file);
+ openWindow(null, this.chromeURL, "_blank",
+ "chrome,dialog=no,all" + this.getFeatures(cmdLine),
+ uri.spec);
+ cmdLine.preventDefault = true;
+ }
+
+//@line 506 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserContentHandler.js"
+ },
+
+ helpInfo : " -browser Open a browser window.\n",
+
+ /* nsIBrowserHandler */
+
+ get defaultArgs() {
+ var prefb = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(nsIPrefBranch);
+ var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
+ .getService(Components.interfaces.nsIURLFormatter);
+
+ var overridePage = "";
+ var haveUpdateSession = false;
+ try {
+ switch (needHomepageOverride(prefb)) {
+ case OVERRIDE_NEW_PROFILE:
+ // New profile
+ overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
+ break;
+ case OVERRIDE_NEW_MSTONE:
+ // Existing profile, new build
+ copyPrefOverride();
+
+ // Check whether we have a session to restore. If we do, we assume
+ // that this is an "update" session.
+ var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
+ .getService(Components.interfaces.nsISessionStartup);
+ haveUpdateSession = ss.doRestore();
+ overridePage = formatter.formatURLPref("startup.homepage_override_url");
+ break;
+ }
+ } catch (ex) {}
+
+ // formatURLPref might return "about:blank" if getting the pref fails
+ if (overridePage == "about:blank")
+ overridePage = "";
+
+ var startPage = "";
+ try {
+ var choice = prefb.getIntPref("browser.startup.page");
+ if (choice == 1 || choice == 3)
+ startPage = this.startPage;
+
+ if (choice == 2)
+ startPage = Components.classes["@mozilla.org/browser/global-history;2"]
+ .getService(nsIBrowserHistory).lastPageVisited;
+ } catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ if (startPage == "about:blank")
+ startPage = "";
+
+ // Only show the startPage if we're not restoring an update session.
+ if (overridePage && startPage && !haveUpdateSession)
+ return overridePage + "|" + startPage;
+
+ return overridePage || startPage || "about:blank";
+ },
+
+ get startPage() {
+ var prefb = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(nsIPrefBranch);
+
+ var uri = prefb.getComplexValue("browser.startup.homepage",
+ nsIPrefLocalizedString).data;
+
+ if (!uri) {
+ prefb.clearUserPref("browser.startup.homepage");
+ uri = prefb.getComplexValue("browser.startup.homepage",
+ nsIPrefLocalizedString).data;
+ }
+
+ var count;
+ try {
+ count = prefb.getIntPref("browser.startup.homepage.count");
+ }
+ catch (e) {
+ return uri;
+ }
+
+ for (var i = 1; i < count; ++i) {
+ try {
+ var page = prefb.getComplexValue("browser.startup.homepage." + i,
+ nsIPrefLocalizedString).data;
+ uri += "\n" + page;
+ }
+ catch (e) {
+ }
+ }
+
+ return uri;
+ },
+
+ mFeatures : null,
+
+ getFeatures : function bch_features(cmdLine) {
+ if (this.mFeatures === null) {
+ this.mFeatures = "";
+
+ try {
+ var width = cmdLine.handleFlagWithParam("width", false);
+ var height = cmdLine.handleFlagWithParam("height", false);
+
+ if (width)
+ this.mFeatures += ",width=" + width;
+ if (height)
+ this.mFeatures += ",height=" + height;
+ }
+ catch (e) {
+ }
+ }
+
+ return this.mFeatures;
+ },
+
+ /* nsIContentHandler */
+
+ handleContent : function bch_handleContent(contentType, context, request) {
+ try {
+ var webNavInfo = Components.classes["@mozilla.org/webnavigation-info;1"]
+ .getService(nsIWebNavigationInfo);
+ if (!webNavInfo.isTypeSupported(contentType, null)) {
+ throw NS_ERROR_WONT_HANDLE_CONTENT;
+ }
+ } catch (e) {
+ throw NS_ERROR_WONT_HANDLE_CONTENT;
+ }
+
+ request.QueryInterface(nsIChannel);
+ handURIToExistingBrowser(request.URI,
+ nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, null);
+ request.cancel(NS_BINDING_ABORTED);
+ },
+
+ /* nsICommandLineValidator */
+ validate : function bch_validate(cmdLine) {
+ // Other handlers may use osint so only handle the osint flag if the url
+ // flag is also present and the command line is valid.
+ var osintFlagIdx = cmdLine.findFlag("osint", false);
+ var urlFlagIdx = cmdLine.findFlag("url", false);
+ if (urlFlagIdx > -1 && (osintFlagIdx > -1 ||
+ cmdLine.state == nsICommandLine.STATE_REMOTE_EXPLICIT)) {
+ var urlParam = cmdLine.getArgument(urlFlagIdx + 1);
+ if (cmdLine.length != urlFlagIdx + 2 || /firefoxurl:/.test(urlParam))
+ throw NS_ERROR_ABORT;
+ cmdLine.handleFlag("osint", false)
+ }
+ },
+
+ /* nsIFactory */
+ createInstance: function bch_CI(outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ return this.QueryInterface(iid);
+ },
+
+ lockFactory : function bch_lock(lock) {
+ /* no-op */
+ }
+};
+
+const bch_contractID = "@mozilla.org/browser/clh;1";
+const bch_CID = Components.ID("{5d0ce354-df01-421a-83fb-7ead0990c24e}");
+const CONTRACTID_PREFIX = "@mozilla.org/uriloader/content-handler;1?type=";
+
+function handURIToExistingBrowser(uri, location, cmdLine)
+{
+ if (!shouldLoadURI(uri))
+ return;
+
+ var navWin = getMostRecentBrowserWindow();
+ if (!navWin) {
+ // if we couldn't load it in an existing window, open a new one
+ openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
+ "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
+ uri.spec);
+ return;
+ }
+
+ var navNav = navWin.QueryInterface(nsIInterfaceRequestor)
+ .getInterface(nsIWebNavigation);
+ var rootItem = navNav.QueryInterface(nsIDocShellTreeItem).rootTreeItem;
+ var rootWin = rootItem.QueryInterface(nsIInterfaceRequestor)
+ .getInterface(nsIDOMWindow);
+ var bwin = rootWin.QueryInterface(nsIDOMChromeWindow).browserDOMWindow;
+ bwin.openURI(uri, null, location,
+ nsIBrowserDOMWindow.OPEN_EXTERNAL);
+}
+
+
+var nsDefaultCommandLineHandler = {
+ /* nsISupports */
+ QueryInterface : function dch_QI(iid) {
+ if (!iid.equals(nsISupports) &&
+ !iid.equals(nsICommandLineHandler) &&
+ !iid.equals(nsIFactory))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+
+ return this;
+ },
+
+ // List of uri's that were passed via the command line without the app
+ // running and have already been handled. This is compared against uri's
+ // opened using DDE on Win32 so we only open one of the requests.
+ _handledURIs: [ ],
+//@line 717 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserContentHandler.js"
+
+ /* nsICommandLineHandler */
+ handle : function dch_handle(cmdLine) {
+ var urilist = [];
+
+//@line 743 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserContentHandler.js"
+
+ try {
+ var ar;
+ while ((ar = cmdLine.handleFlagWithParam("url", false))) {
+ var found = false;
+ var uri = resolveURIInternal(cmdLine, ar);
+ // count will never be greater than zero except on Win32.
+ var count = this._handledURIs.length;
+ for (var i = 0; i < count; ++i) {
+ if (this._handledURIs[i].spec == uri.spec) {
+ this._handledURIs.splice(i, 1);
+ found = true;
+ cmdLine.preventDefault = true;
+ break;
+ }
+ }
+ if (!found) {
+ urilist.push(uri);
+ // The requestpending command line flag is only used on Win32.
+ if (cmdLine.handleFlag("requestpending", false) &&
+ cmdLine.state == nsICommandLine.STATE_INITIAL_LAUNCH)
+ this._handledURIs.push(uri)
+ }
+ }
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ count = cmdLine.length;
+
+ for (i = 0; i < count; ++i) {
+ var curarg = cmdLine.getArgument(i);
+ if (curarg.match(/^-/)) {
+ Components.utils.reportError("Warning: unrecognized command line flag " + curarg + "\n");
+ // To emulate the pre-nsICommandLine behavior, we ignore
+ // the argument after an unrecognized flag.
+ ++i;
+ } else {
+ try {
+ urilist.push(resolveURIInternal(cmdLine, curarg));
+ }
+ catch (e) {
+ Components.utils.reportError("Error opening URI '" + curarg + "' from the command line: " + e + "\n");
+ }
+ }
+ }
+
+ if (urilist.length) {
+ if (cmdLine.state != nsICommandLine.STATE_INITIAL_LAUNCH &&
+ urilist.length == 1) {
+ // Try to find an existing window and load our URI into the
+ // current tab, new tab, or new window as prefs determine.
+ try {
+ handURIToExistingBrowser(urilist[0], nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, cmdLine);
+ return;
+ }
+ catch (e) {
+ }
+ }
+
+ var URLlist = urilist.filter(shouldLoadURI).map(function (u) u.spec);
+ if (URLlist.length) {
+ openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
+ "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
+ URLlist);
+ }
+
+ }
+ else if (!cmdLine.preventDefault) {
+ // Passing defaultArgs, so use NO_EXTERNAL_URIS
+ openWindow(null, nsBrowserContentHandler.chromeURL, "_blank",
+ "chrome,dialog=no,all" + nsBrowserContentHandler.getFeatures(cmdLine),
+ nsBrowserContentHandler.defaultArgs, NO_EXTERNAL_URIS);
+ }
+ },
+
+ // XXX localize me... how?
+ helpInfo : "Usage: firefox [-flags] [<url>]\n",
+
+ /* nsIFactory */
+ createInstance: function dch_CI(outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ return this.QueryInterface(iid);
+ },
+
+ lockFactory : function dch_lock(lock) {
+ /* no-op */
+ }
+};
+
+const dch_contractID = "@mozilla.org/browser/final-clh;1";
+const dch_CID = Components.ID("{47cd0651-b1be-4a0f-b5c4-10e5a573ef71}");
+
+var Module = {
+ /* nsISupports */
+ QueryInterface: function mod_QI(iid) {
+ if (iid.equals(Components.interfaces.nsIModule) ||
+ iid.equals(Components.interfaces.nsISupports))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ /* nsIModule */
+ getClassObject: function mod_getco(compMgr, cid, iid) {
+ if (cid.equals(bch_CID))
+ return nsBrowserContentHandler.QueryInterface(iid);
+
+ if (cid.equals(dch_CID))
+ return nsDefaultCommandLineHandler.QueryInterface(iid);
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ registerSelf: function mod_regself(compMgr, fileSpec, location, type) {
+ if (Components.classes["@mozilla.org/xre/app-info;1"]) {
+ // Don't register these if Firefox is launching a XULRunner application
+ const FIREFOX_UID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
+ var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
+ .getService(Components.interfaces.nsIXULAppInfo);
+ if (appInfo.ID != FIREFOX_UID)
+ return;
+ }
+
+ var compReg =
+ compMgr.QueryInterface( Components.interfaces.nsIComponentRegistrar );
+
+ compReg.registerFactoryLocation( bch_CID,
+ "nsBrowserContentHandler",
+ bch_contractID,
+ fileSpec,
+ location,
+ type );
+ compReg.registerFactoryLocation( dch_CID,
+ "nsDefaultCommandLineHandler",
+ dch_contractID,
+ fileSpec,
+ location,
+ type );
+
+ function registerType(contentType) {
+ compReg.registerFactoryLocation( bch_CID,
+ "Browser Cmdline Handler",
+ CONTRACTID_PREFIX + contentType,
+ fileSpec,
+ location,
+ type );
+ }
+
+ registerType("text/html");
+ registerType("application/vnd.mozilla.xul+xml");
+//@line 898 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserContentHandler.js"
+ registerType("image/svg+xml");
+//@line 900 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserContentHandler.js"
+ registerType("text/rdf");
+ registerType("text/xml");
+ registerType("application/xhtml+xml");
+ registerType("text/css");
+ registerType("text/plain");
+ registerType("image/gif");
+ registerType("image/jpeg");
+ registerType("image/jpg");
+ registerType("image/png");
+ registerType("image/bmp");
+ registerType("image/x-icon");
+ registerType("image/vnd.microsoft.icon");
+ registerType("image/x-xbitmap");
+ registerType("application/http-index-format");
+
+ var catMan = Components.classes["@mozilla.org/categorymanager;1"]
+ .getService(nsICategoryManager);
+
+ catMan.addCategoryEntry("command-line-handler",
+ "m-browser",
+ bch_contractID, true, true);
+ catMan.addCategoryEntry("command-line-handler",
+ "x-default",
+ dch_contractID, true, true);
+ catMan.addCategoryEntry("command-line-validator",
+ "b-browser",
+ bch_contractID, true, true);
+ },
+
+ unregisterSelf : function mod_unregself(compMgr, location, type) {
+ var compReg = compMgr.QueryInterface(nsIComponentRegistrar);
+ compReg.unregisterFactoryLocation(bch_CID, location);
+ compReg.unregisterFactoryLocation(dch_CID, location);
+
+ var catMan = Components.classes["@mozilla.org/categorymanager;1"]
+ .getService(nsICategoryManager);
+
+ catMan.deleteCategoryEntry("command-line-handler",
+ "m-browser", true);
+ catMan.deleteCategoryEntry("command-line-handler",
+ "x-default", true);
+ catMan.deleteCategoryEntry("command-line-validator",
+ "b-browser", true);
+ },
+
+ canUnload: function(compMgr) {
+ return true;
+ }
+};
+
+// NSGetModule: Return the nsIModule object.
+function NSGetModule(compMgr, fileSpec) {
+ return Module;
+}
diff --git a/bundles/XO/components/nsBrowserGlue.js b/bundles/XO/components/nsBrowserGlue.js
new file mode 100755
index 0000000..d938b13
--- /dev/null
+++ b/bundles/XO/components/nsBrowserGlue.js
@@ -0,0 +1,1072 @@
+//@line 42 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserGlue.js"
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource:///modules/distribution.js");
+
+const PREF_EM_NEW_ADDONS_LIST = "extensions.newAddons";
+
+// Check to see if bookmarks need backing up once per
+// day on 1 hour idle.
+const BOOKMARKS_ARCHIVE_IDLE_TIME = 60 * 60;
+
+// Backup bookmarks once every 24 hours.
+const BOOKMARKS_ARCHIVE_INTERVAL = 86400 * 1000;
+
+// Factory object
+const BrowserGlueServiceFactory = {
+ _instance: null,
+ createInstance: function (outer, iid)
+ {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+ return this._instance == null ?
+ this._instance = new BrowserGlue() : this._instance;
+ }
+};
+
+// Constructor
+
+function BrowserGlue() {
+
+ this.__defineGetter__("_prefs", function() {
+ delete this._prefs;
+ return this._prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ });
+
+ this.__defineGetter__("_bundleService", function() {
+ delete this._bundleService;
+ return this._bundleService = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ });
+
+ this.__defineGetter__("_idleService", function() {
+ delete this._idleService;
+ return this._idleService = Cc["@mozilla.org/widget/idleservice;1"].
+ getService(Ci.nsIIdleService);
+ });
+
+ this.__defineGetter__("_observerService", function() {
+ delete this._observerService;
+ return this._observerService = Cc['@mozilla.org/observer-service;1'].
+ getService(Ci.nsIObserverService);
+ });
+
+ this._init();
+}
+
+BrowserGlue.prototype = {
+
+ _saveSession: false,
+
+ _setPrefToSaveSession: function()
+ {
+ this._prefs.setBoolPref("browser.sessionstore.resume_session_once", true);
+
+ // This method can be called via [NSApplication terminate:] on Mac, which
+ // ends up causing prefs not to be flushed to disk, so we need to do that
+ // explicitly here. See bug 497652.
+ this._prefs.QueryInterface(Ci.nsIPrefService).savePrefFile(null);
+ },
+
+ // nsIObserver implementation
+ observe: function(subject, topic, data)
+ {
+ switch(topic) {
+ case "xpcom-shutdown":
+ this._dispose();
+ break;
+ case "prefservice:after-app-defaults":
+ this._onAppDefaults();
+ break;
+ case "final-ui-startup":
+ this._onProfileStartup();
+ break;
+ case "sessionstore-windows-restored":
+ this._onBrowserStartup();
+ break;
+ case "browser:purge-session-history":
+ // reset the console service's error buffer
+ const cs = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ cs.logStringMessage(null); // clear the console (in case it's open)
+ cs.reset();
+ break;
+ case "quit-application-requested":
+ this._onQuitRequest(subject, data);
+ break;
+ case "quit-application-granted":
+ if (this._saveSession) {
+ this._setPrefToSaveSession();
+ }
+ // Everything that uses Places during shutdown should be here, since
+ // on quit-application Places database connection will be closed
+ // and history synchronization could fail.
+ this._onProfileShutdown();
+ break;
+ case "session-save":
+ this._setPrefToSaveSession();
+ subject.QueryInterface(Ci.nsISupportsPRBool);
+ subject.data = true;
+ break;
+ case "places-init-complete":
+ this._initPlaces();
+ this._observerService.removeObserver(this, "places-init-complete");
+ // no longer needed, since history was initialized completely.
+ this._observerService.removeObserver(this, "places-database-locked");
+ break;
+ case "places-database-locked":
+ this._isPlacesDatabaseLocked = true;
+ // stop observing, so further attempts to load history service
+ // do not show the prompt.
+ this._observerService.removeObserver(this, "places-database-locked");
+ break;
+ case "idle":
+ if (this._idleService.idleTime > BOOKMARKS_ARCHIVE_IDLE_TIME * 1000) {
+ // Back up bookmarks.
+ this._archiveBookmarks();
+ }
+ break;
+ }
+ },
+
+ // initialization (called on application startup)
+ _init: function()
+ {
+ // observer registration
+ const osvr = this._observerService;
+ osvr.addObserver(this, "xpcom-shutdown", false);
+ osvr.addObserver(this, "prefservice:after-app-defaults", false);
+ osvr.addObserver(this, "final-ui-startup", false);
+ osvr.addObserver(this, "sessionstore-windows-restored", false);
+ osvr.addObserver(this, "browser:purge-session-history", false);
+ osvr.addObserver(this, "quit-application-requested", false);
+ osvr.addObserver(this, "quit-application-granted", false);
+ osvr.addObserver(this, "session-save", false);
+ osvr.addObserver(this, "places-init-complete", false);
+ osvr.addObserver(this, "places-database-locked", false);
+ },
+
+ // cleanup (called on application shutdown)
+ _dispose: function()
+ {
+ // observer removal
+ const osvr = this._observerService;
+ osvr.removeObserver(this, "xpcom-shutdown");
+ osvr.removeObserver(this, "prefservice:after-app-defaults");
+ osvr.removeObserver(this, "final-ui-startup");
+ osvr.removeObserver(this, "sessionstore-windows-restored");
+ osvr.removeObserver(this, "browser:purge-session-history");
+ osvr.removeObserver(this, "quit-application-requested");
+ osvr.removeObserver(this, "quit-application-granted");
+ osvr.removeObserver(this, "session-save");
+ },
+
+ _onAppDefaults: function()
+ {
+ // apply distribution customizations (prefs)
+ // other customizations are applied in _onProfileStartup()
+ var distro = new DistributionCustomizer();
+ distro.applyPrefDefaults();
+ },
+
+ // profile startup handler (contains profile initialization routines)
+ _onProfileStartup: function()
+ {
+ this.Sanitizer.onStartup();
+ // check if we're in safe mode
+ var app = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).
+ QueryInterface(Ci.nsIXULRuntime);
+ if (app.inSafeMode) {
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(null, "chrome://browser/content/safeMode.xul",
+ "_blank", "chrome,centerscreen,modal,resizable=no", null);
+ }
+
+ // apply distribution customizations
+ // prefs are applied in _onAppDefaults()
+ var distro = new DistributionCustomizer();
+ distro.applyCustomizations();
+
+ // handle any UI migration
+ this._migrateUI();
+
+ this._observerService.notifyObservers(null, "browser-ui-startup-complete", "");
+ },
+
+ // profile shutdown handler (contains profile cleanup routines)
+ _onProfileShutdown: function()
+ {
+ this._shutdownPlaces();
+ this._idleService.removeIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME);
+ this.Sanitizer.onShutdown();
+ },
+
+ // Browser startup complete. All initial windows have opened.
+ _onBrowserStartup: function()
+ {
+ // Show about:rights notification, if needed.
+ if (this._shouldShowRights())
+ this._showRightsNotification();
+
+ // If new add-ons were installed during startup open the add-ons manager.
+ if (this._prefs.prefHasUserValue(PREF_EM_NEW_ADDONS_LIST)) {
+ var args = Cc["@mozilla.org/supports-array;1"].
+ createInstance(Ci.nsISupportsArray);
+ var str = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ str.data = "";
+ args.AppendElement(str);
+ var str = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ str.data = this._prefs.getCharPref(PREF_EM_NEW_ADDONS_LIST);
+ args.AppendElement(str);
+ const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
+ const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(null, EMURL, "_blank", EMFEATURES, args);
+ this._prefs.clearUserPref(PREF_EM_NEW_ADDONS_LIST);
+ }
+
+ // Load the "more info" page for a locked places.sqlite
+ // This property is set earlier in the startup process:
+ // nsPlacesDBFlush loads after profile-after-change and initializes
+ // the history service, which sends out places-database-locked
+ // which sets this property.
+ if (this._isPlacesDatabaseLocked) {
+ this._showPlacesLockedNotificationBox();
+ }
+ },
+
+ _onQuitRequest: function(aCancelQuit, aQuitType)
+ {
+ // If user has already dismissed quit request, then do nothing
+ if ((aCancelQuit instanceof Ci.nsISupportsPRBool) && aCancelQuit.data)
+ return;
+
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+
+ var windowcount = 0;
+ var pagecount = 0;
+ var browserEnum = wm.getEnumerator("navigator:browser");
+ while (browserEnum.hasMoreElements()) {
+ windowcount++;
+
+ var browser = browserEnum.getNext();
+ var tabbrowser = browser.document.getElementById("content");
+ if (tabbrowser)
+ pagecount += tabbrowser.browsers.length;
+ }
+
+ this._saveSession = false;
+ if (pagecount < 2)
+ return;
+
+ if (aQuitType != "restart")
+ aQuitType = "quit";
+
+ var showPrompt = true;
+ try {
+ // browser.warnOnQuit is a hidden global boolean to override all quit prompts
+ // browser.warnOnRestart specifically covers app-initiated restarts where we restart the app
+ // browser.tabs.warnOnClose is the global "warn when closing multiple tabs" pref
+
+ var sessionWillBeSaved = this._prefs.getIntPref("browser.startup.page") == 3 ||
+ this._prefs.getBoolPref("browser.sessionstore.resume_session_once");
+ if (sessionWillBeSaved || !this._prefs.getBoolPref("browser.warnOnQuit"))
+ showPrompt = false;
+ else if (aQuitType == "restart")
+ showPrompt = this._prefs.getBoolPref("browser.warnOnRestart");
+ else
+ showPrompt = this._prefs.getBoolPref("browser.tabs.warnOnClose");
+ } catch (ex) {}
+
+ // Never show a prompt inside the private browsing mode
+ var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
+ getService(Ci.nsIPrivateBrowsingService).
+ privateBrowsingEnabled;
+ if (!showPrompt || inPrivateBrowsing)
+ return false;
+
+ var buttonChoice = 0;
+ var quitBundle = this._bundleService.createBundle("chrome://browser/locale/quitDialog.properties");
+ var brandBundle = this._bundleService.createBundle("chrome://branding/locale/brand.properties");
+
+ var appName = brandBundle.GetStringFromName("brandShortName");
+ var quitDialogTitle = quitBundle.formatStringFromName(aQuitType + "DialogTitle",
+ [appName], 1);
+
+ var message;
+ if (aQuitType == "restart")
+ message = quitBundle.formatStringFromName("messageRestart",
+ [appName], 1);
+ else if (windowcount == 1)
+ message = quitBundle.formatStringFromName("messageNoWindows",
+ [appName], 1);
+ else
+ message = quitBundle.formatStringFromName("message",
+ [appName], 1);
+
+ var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Ci.nsIPromptService);
+
+ var flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
+ promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1 +
+ promptService.BUTTON_POS_0_DEFAULT;
+
+ var neverAsk = {value:false};
+ var button0Title, button2Title;
+ var button1Title = quitBundle.GetStringFromName("cancelTitle");
+ var neverAskText = quitBundle.GetStringFromName("neverAsk");
+
+ if (aQuitType == "restart")
+ button0Title = quitBundle.GetStringFromName("restartTitle");
+ else {
+ flags += promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
+ button0Title = quitBundle.GetStringFromName("saveTitle");
+ button2Title = quitBundle.GetStringFromName("quitTitle");
+ }
+
+ buttonChoice = promptService.confirmEx(null, quitDialogTitle, message,
+ flags, button0Title, button1Title, button2Title,
+ neverAskText, neverAsk);
+
+ switch (buttonChoice) {
+ case 2: // Quit
+ if (neverAsk.value)
+ this._prefs.setBoolPref("browser.tabs.warnOnClose", false);
+ break;
+ case 1: // Cancel
+ aCancelQuit.QueryInterface(Ci.nsISupportsPRBool);
+ aCancelQuit.data = true;
+ break;
+ case 0: // Save & Quit
+ this._saveSession = true;
+ if (neverAsk.value) {
+ if (aQuitType == "restart")
+ this._prefs.setBoolPref("browser.warnOnRestart", false);
+ else {
+ // always save state when shutting down
+ this._prefs.setIntPref("browser.startup.page", 3);
+ }
+ }
+ break;
+ }
+ },
+
+ /*
+ * _shouldShowRights - Determines if the user should be shown the
+ * about:rights notification. The notification should *not* be shown if
+ * we've already shown the current version, or if the override pref says to
+ * never show it. The notification *should* be shown if it's never been seen
+ * before, if a newer version is available, or if the override pref says to
+ * always show it.
+ */
+ _shouldShowRights : function () {
+ // Look for an unconditional override pref. If set, do what it says.
+ // (true --> never show, false --> always show)
+ try {
+ return !this._prefs.getBoolPref("browser.rights.override");
+ } catch (e) { }
+ // Ditto, for the legacy EULA pref.
+ try {
+ return !this._prefs.getBoolPref("browser.EULA.override");
+ } catch (e) { }
+
+//@line 430 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserGlue.js"
+
+ // Look to see if the user has seen the current version or not.
+ var currentVersion = this._prefs.getIntPref("browser.rights.version");
+ try {
+ return !this._prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
+ } catch (e) { }
+
+ // Legacy: If the user accepted a EULA, we won't annoy them with the
+ // equivalent about:rights page until the version changes.
+ try {
+ return !this._prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
+ } catch (e) { }
+
+ // We haven't shown the notification before, so do so now.
+ return true;
+ },
+
+ _showRightsNotification : function () {
+ // Stick the notification onto the selected tab of the active browser window.
+ var win = this.getMostRecentBrowserWindow();
+ var browser = win.gBrowser; // for closure in notification bar callback
+ var notifyBox = browser.getNotificationBox();
+
+ var brandBundle = this._bundleService.createBundle("chrome://branding/locale/brand.properties");
+ var rightsBundle = this._bundleService.createBundle("chrome://browser/locale/aboutRights.properties");
+
+ var buttonLabel = rightsBundle.GetStringFromName("buttonLabel");
+ var buttonAccessKey = rightsBundle.GetStringFromName("buttonAccessKey");
+ var productName = brandBundle.GetStringFromName("brandFullName");
+ var notifyRightsText = rightsBundle.formatStringFromName("notifyRightsText", [productName], 1);
+
+ var buttons = [
+ {
+ label: buttonLabel,
+ accessKey: buttonAccessKey,
+ popup: null,
+ callback: function(aNotificationBar, aButton) {
+ browser.selectedTab = browser.addTab("about:rights");
+ }
+ }
+ ];
+
+ // Set pref to indicate we've shown the notification.
+ var currentVersion = this._prefs.getIntPref("browser.rights.version");
+ this._prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
+
+ var box = notifyBox.appendNotification(notifyRightsText, "about-rights", null, notifyBox.PRIORITY_INFO_LOW, buttons);
+ box.persistence = 3; // arbitrary number, just so bar sticks around for a bit
+ },
+
+ // returns the (cached) Sanitizer constructor
+ get Sanitizer()
+ {
+ if(typeof(Sanitizer) != "function") { // we should dynamically load the script
+ Cc["@mozilla.org/moz/jssubscript-loader;1"].
+ getService(Ci.mozIJSSubScriptLoader).
+ loadSubScript("chrome://browser/content/sanitize.js", null);
+ }
+ return Sanitizer;
+ },
+
+ /**
+ * Initialize Places
+ * - imports the bookmarks html file if bookmarks database is empty, try to
+ * restore bookmarks from a JSON backup if the backend indicates that the
+ * database was corrupt.
+ *
+ * These prefs can be set up by the frontend:
+ *
+ * WARNING: setting these preferences to true will overwite existing bookmarks
+ *
+ * - browser.places.importBookmarksHTML
+ * Set to true will import the bookmarks.html file from the profile folder.
+ * - browser.places.smartBookmarksVersion
+ * Set during HTML import to indicate that Smart Bookmarks were created.
+ * Set to -1 to disable Smart Bookmarks creation.
+ * Set to 0 to restore current Smart Bookmarks.
+ * - browser.bookmarks.restore_default_bookmarks
+ * Set to true by safe-mode dialog to indicate we must restore default
+ * bookmarks.
+ */
+ _initPlaces: function bg__initPlaces() {
+ // We must instantiate the history service since it will tell us if we
+ // need to import or restore bookmarks due to first-run, corruption or
+ // forced migration (due to a major schema change).
+ var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
+ getService(Ci.nsINavHistoryService);
+
+ // If the database is corrupt or has been newly created we should
+ // import bookmarks.
+ var databaseStatus = histsvc.databaseStatus;
+ var importBookmarks = databaseStatus == histsvc.DATABASE_STATUS_CREATE ||
+ databaseStatus == histsvc.DATABASE_STATUS_CORRUPT;
+
+ if (databaseStatus == histsvc.DATABASE_STATUS_CREATE) {
+ // If the database has just been created, but we already have any
+ // bookmark, this is not the initial import. This can happen after a
+ // migration from a different browser since migrators run before us.
+ // In such a case we should not import, unless some pref has been set.
+ var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+ getService(Ci.nsINavBookmarksService);
+ if (bmsvc.getIdForItemAt(bmsvc.bookmarksMenuFolder, 0) != -1 ||
+ bmsvc.getIdForItemAt(bmsvc.toolbarFolder, 0) != -1)
+ importBookmarks = false;
+ }
+
+ // Check if user or an extension has required to import bookmarks.html
+ var importBookmarksHTML = false;
+ try {
+ importBookmarksHTML =
+ this._prefs.getBoolPref("browser.places.importBookmarksHTML");
+ if (importBookmarksHTML)
+ importBookmarks = true;
+ } catch(ex) {}
+
+ // Check if Safe Mode or the user has required to restore bookmarks from
+ // default profile's bookmarks.html
+ var restoreDefaultBookmarks = false;
+ try {
+ restoreDefaultBookmarks =
+ this._prefs.getBoolPref("browser.bookmarks.restore_default_bookmarks");
+ if (restoreDefaultBookmarks) {
+ // Ensure that we already have a bookmarks backup for today
+ this._archiveBookmarks();
+ importBookmarks = true;
+ }
+ } catch(ex) {}
+
+ // If the user did not require to restore default bookmarks, or import
+ // from bookmarks.html, we will try to restore from JSON
+ if (importBookmarks && !restoreDefaultBookmarks && !importBookmarksHTML) {
+ // get latest JSON backup
+ Cu.import("resource://gre/modules/utils.js");
+ var bookmarksBackupFile = PlacesUtils.getMostRecentBackup();
+ if (bookmarksBackupFile && bookmarksBackupFile.leafName.match("\.json$")) {
+ // restore from JSON backup
+ PlacesUtils.restoreBookmarksFromJSONFile(bookmarksBackupFile);
+ importBookmarks = false;
+ }
+ else {
+ // We have created a new database but we don't have any backup available
+ importBookmarks = true;
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ var bookmarksHTMLFile = dirService.get("BMarks", Ci.nsILocalFile);
+ if (bookmarksHTMLFile.exists()) {
+ // If bookmarks.html is available in current profile import it...
+ importBookmarksHTML = true;
+ }
+ else {
+ // ...otherwise we will restore defaults
+ restoreDefaultBookmarks = true;
+ }
+ }
+ }
+
+ if (!importBookmarks) {
+ // Call it here for Fx3 profiles created before the Places folder
+ // has been added, otherwise it's called during import.
+ this.ensurePlacesDefaultQueriesInitialized();
+ }
+ else {
+ // ensurePlacesDefaultQueriesInitialized() is called by import.
+ // Don't try to recreate smart bookmarks if autoExportHTML is true or
+ // smart bookmarks are disabled.
+ var autoExportHTML = false;
+ try {
+ autoExportHTML = this._prefs.getBoolPref("browser.bookmarks.autoExportHTML");
+ } catch(ex) {}
+ var smartBookmarksVersion = 0;
+ try {
+ smartBookmarksVersion = this._prefs.getIntPref("browser.places.smartBookmarksVersion");
+ } catch(ex) {}
+ if (!autoExportHTML && smartBookmarksVersion != -1)
+ this._prefs.setIntPref("browser.places.smartBookmarksVersion", 0);
+
+ // Get bookmarks.html file location
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+
+ var bookmarksFile = null;
+ if (restoreDefaultBookmarks) {
+ // User wants to restore bookmarks.html file from default profile folder
+ bookmarksFile = dirService.get("profDef", Ci.nsILocalFile);
+ bookmarksFile.append("bookmarks.html");
+ }
+ else
+ bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
+
+ if (bookmarksFile.exists()) {
+ // import the file
+ try {
+ var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
+ getService(Ci.nsIPlacesImportExportService);
+ importer.importHTMLFromFile(bookmarksFile, true /* overwrite existing */);
+ } catch (err) {
+ // Report the error, but ignore it.
+ Cu.reportError("Bookmarks.html file could be corrupt. " + err);
+ }
+ }
+ else
+ Cu.reportError("Unable to find bookmarks.html file.");
+
+ // Reset preferences, so we won't try to import again at next run
+ if (importBookmarksHTML)
+ this._prefs.setBoolPref("browser.places.importBookmarksHTML", false);
+ if (restoreDefaultBookmarks)
+ this._prefs.setBoolPref("browser.bookmarks.restore_default_bookmarks",
+ false);
+ }
+
+ // Initialize bookmark archiving on idle.
+ // Once a day, either on idle or shutdown, bookmarks are backed up.
+ this._idleService.addIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME);
+ },
+
+ /**
+ * Places shut-down tasks
+ * - back up and archive bookmarks
+ * - export bookmarks as HTML, if so configured
+ *
+ * Note: quit-application-granted notification is received twice
+ * so replace this method with a no-op when first called.
+ */
+ _shutdownPlaces: function bg__shutdownPlaces() {
+ // Backup and archive Places bookmarks.
+ this._archiveBookmarks();
+
+ // Backup bookmarks to bookmarks.html to support apps that depend
+ // on the legacy format.
+ var autoExportHTML = false;
+ try {
+ autoExportHTML = this._prefs.getBoolPref("browser.bookmarks.autoExportHTML");
+ } catch(ex) {
+ Components.utils.reportError(ex);
+ }
+
+ if (autoExportHTML) {
+ Cc["@mozilla.org/browser/places/import-export-service;1"].
+ getService(Ci.nsIPlacesImportExportService).
+ backupBookmarksFile();
+ }
+ },
+
+ /**
+ * Back up and archive bookmarks
+ */
+ _archiveBookmarks: function nsBrowserGlue__archiveBookmarks() {
+ Cu.import("resource://gre/modules/utils.js");
+
+ var lastBackup = PlacesUtils.getMostRecentBackup();
+
+ // Backup bookmarks if there aren't any backups or
+ // they haven't been backed up in the last 24 hrs.
+ if (!lastBackup ||
+ Date.now() - lastBackup.lastModifiedTime > BOOKMARKS_ARCHIVE_INTERVAL) {
+ var maxBackups = 5;
+ try {
+ maxBackups = this._prefs.getIntPref("browser.bookmarks.max_backups");
+ } catch(ex) {}
+
+ PlacesUtils.archiveBookmarksFile(maxBackups, false /* don't force */);
+ }
+ },
+
+ /**
+ * Show the notificationBox for a locked places database.
+ */
+ _showPlacesLockedNotificationBox: function nsBrowserGlue__showPlacesLockedNotificationBox() {
+ var brandBundle = this._bundleService.createBundle("chrome://branding/locale/brand.properties");
+ var applicationName = brandBundle.GetStringFromName("brandShortName");
+ var placesBundle = this._bundleService.createBundle("chrome://browser/locale/places/places.properties");
+ var title = placesBundle.GetStringFromName("lockPrompt.title");
+ var text = placesBundle.formatStringFromName("lockPrompt.text", [applicationName], 1);
+ var buttonText = placesBundle.GetStringFromName("lockPromptInfoButton.label");
+ var accessKey = placesBundle.GetStringFromName("lockPromptInfoButton.accessKey");
+
+ var helpTopic = "places-locked";
+ var url = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
+ getService(Components.interfaces.nsIURLFormatter).
+ formatURLPref("app.support.baseURL");
+ url += helpTopic;
+
+ var browser = this.getMostRecentBrowserWindow().gBrowser;
+
+ var buttons = [
+ {
+ label: buttonText,
+ accessKey: accessKey,
+ popup: null,
+ callback: function(aNotificationBar, aButton) {
+ browser.selectedTab = browser.addTab(url);
+ }
+ }
+ ];
+
+ var notifyBox = browser.getNotificationBox();
+ var box = notifyBox.appendNotification(text, title, null,
+ notifyBox.PRIORITY_CRITICAL_MEDIUM,
+ buttons);
+ box.persistence = -1; // Until user closes it
+ },
+
+ _migrateUI: function bg__migrateUI() {
+ var migration = 0;
+ try {
+ migration = this._prefs.getIntPref("browser.migration.version");
+ } catch(ex) {}
+
+ if (migration == 0) {
+ // this code should always migrate pre-FF3 profiles to the current UI state
+
+ // grab the localstore.rdf and make changes needed for new UI
+ this._rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
+ this._dataSource = this._rdf.GetDataSource("rdf:local-store");
+ this._dirty = false;
+
+ let currentsetResource = this._rdf.GetResource("currentset");
+ let toolbars = ["nav-bar", "toolbar-menubar", "PersonalToolbar"];
+ for (let i = 0; i < toolbars.length; i++) {
+ let toolbar = this._rdf.GetResource("chrome://browser/content/browser.xul#" + toolbars[i]);
+ let currentset = this._getPersist(toolbar, currentsetResource);
+ if (!currentset) {
+ // toolbar isn't customized
+ if (i == 0)
+ // new button is in the defaultset, nothing to migrate
+ break;
+ continue;
+ }
+ if (/(?:^|,)unified-back-forward-button(?:$|,)/.test(currentset))
+ // new button is already there, nothing to migrate
+ break;
+ if (/(?:^|,)back-button(?:$|,)/.test(currentset)) {
+ let newset = currentset.replace(/(^|,)back-button($|,)/,
+ "$1unified-back-forward-button,back-button$2")
+ this._setPersist(toolbar, currentsetResource, newset);
+ // done migrating
+ break;
+ }
+ }
+
+ // force the RDF to be saved
+ if (this._dirty)
+ this._dataSource.QueryInterface(Ci.nsIRDFRemoteDataSource).Flush();
+
+ // free up the RDF service
+ this._rdf = null;
+ this._dataSource = null;
+
+ // update the migration version
+ this._prefs.setIntPref("browser.migration.version", 1);
+ }
+ },
+
+ _getPersist: function bg__getPersist(aSource, aProperty) {
+ var target = this._dataSource.GetTarget(aSource, aProperty, true);
+ if (target instanceof Ci.nsIRDFLiteral)
+ return target.Value;
+ return null;
+ },
+
+ _setPersist: function bg__setPersist(aSource, aProperty, aTarget) {
+ this._dirty = true;
+ try {
+ var oldTarget = this._dataSource.GetTarget(aSource, aProperty, true);
+ if (oldTarget) {
+ if (aTarget)
+ this._dataSource.Change(aSource, aProperty, oldTarget, this._rdf.GetLiteral(aTarget));
+ else
+ this._dataSource.Unassert(aSource, aProperty, oldTarget);
+ }
+ else {
+ this._dataSource.Assert(aSource, aProperty, this._rdf.GetLiteral(aTarget), true);
+ }
+ }
+ catch(ex) {}
+ },
+
+ // ------------------------------
+ // public nsIBrowserGlue members
+ // ------------------------------
+
+ sanitize: function(aParentWindow)
+ {
+ this.Sanitizer.sanitize(aParentWindow);
+ },
+
+ ensurePlacesDefaultQueriesInitialized: function() {
+ const SMART_BOOKMARKS_VERSION = 1;
+ const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
+ const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
+
+ // XXX should this be a pref? see bug #399268
+ const MAX_RESULTS = 10;
+
+ // get current smart bookmarks version
+ // By default, if the pref is not set up, we must create Smart Bookmarks
+ var smartBookmarksCurrentVersion = 0;
+ try {
+ smartBookmarksCurrentVersion = this._prefs.getIntPref(SMART_BOOKMARKS_PREF);
+ } catch(ex) {}
+
+ // bail out if we don't have to create or update Smart Bookmarks
+ if (smartBookmarksCurrentVersion == -1 ||
+ smartBookmarksCurrentVersion >= SMART_BOOKMARKS_VERSION)
+ return;
+
+ var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+ getService(Ci.nsINavBookmarksService);
+ var annosvc = Cc["@mozilla.org/browser/annotation-service;1"].
+ getService(Ci.nsIAnnotationService);
+
+ var callback = {
+ _uri: function(aSpec) {
+ return Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService).
+ newURI(aSpec, null, null);
+ },
+
+ runBatched: function() {
+ var smartBookmarks = [];
+ var bookmarksMenuIndex = 0;
+ var bookmarksToolbarIndex = 0;
+
+ var placesBundle = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).
+ createBundle("chrome://browser/locale/places/places.properties");
+
+ // MOST VISITED
+ var smart = {queryId: "MostVisited", // don't change this
+ itemId: null,
+ title: placesBundle.GetStringFromName("mostVisitedTitle"),
+ uri: this._uri("place:queryType=" +
+ Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY +
+ "&sort=" +
+ Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
+ "&maxResults=" + MAX_RESULTS),
+ parent: bmsvc.toolbarFolder,
+ position: bookmarksToolbarIndex++};
+ smartBookmarks.push(smart);
+
+ // RECENTLY BOOKMARKED
+ smart = {queryId: "RecentlyBookmarked", // don't change this
+ itemId: null,
+ title: placesBundle.GetStringFromName("recentlyBookmarkedTitle"),
+ uri: this._uri("place:folder=BOOKMARKS_MENU" +
+ "&folder=UNFILED_BOOKMARKS" +
+ "&folder=TOOLBAR" +
+ "&queryType=" +
+ Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
+ "&sort=" +
+ Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
+ "&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" +
+ "&maxResults=" + MAX_RESULTS +
+ "&excludeQueries=1"),
+ parent: bmsvc.bookmarksMenuFolder,
+ position: bookmarksMenuIndex++};
+ smartBookmarks.push(smart);
+
+ // RECENT TAGS
+ smart = {queryId: "RecentTags", // don't change this
+ itemId: null,
+ title: placesBundle.GetStringFromName("recentTagsTitle"),
+ uri: this._uri("place:"+
+ "type=" +
+ Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
+ "&sort=" +
+ Ci.nsINavHistoryQueryOptions.SORT_BY_LASTMODIFIED_DESCENDING +
+ "&maxResults=" + MAX_RESULTS),
+ parent: bmsvc.bookmarksMenuFolder,
+ position: bookmarksMenuIndex++};
+ smartBookmarks.push(smart);
+
+ var smartBookmarkItemIds = annosvc.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO, {});
+ // set current itemId, parent and position if Smart Bookmark exists
+ for each(var itemId in smartBookmarkItemIds) {
+ var queryId = annosvc.getItemAnnotation(itemId, SMART_BOOKMARKS_ANNO);
+ for (var i = 0; i < smartBookmarks.length; i++){
+ if (smartBookmarks[i].queryId == queryId) {
+ smartBookmarks[i].itemId = itemId;
+ smartBookmarks[i].parent = bmsvc.getFolderIdForItem(itemId);
+ smartBookmarks[i].position = bmsvc.getItemIndex(itemId);
+ // remove current item, since it will be replaced
+ bmsvc.removeItem(itemId);
+ break;
+ }
+ // We don't remove old Smart Bookmarks because user could still
+ // find them useful, or could have personalized them.
+ // Instead we remove the Smart Bookmark annotation.
+ if (i == smartBookmarks.length - 1)
+ annosvc.removeItemAnnotation(itemId, SMART_BOOKMARKS_ANNO);
+ }
+ }
+
+ // create smart bookmarks
+ for each(var smartBookmark in smartBookmarks) {
+ smartBookmark.itemId = bmsvc.insertBookmark(smartBookmark.parent,
+ smartBookmark.uri,
+ smartBookmark.position,
+ smartBookmark.title);
+ annosvc.setItemAnnotation(smartBookmark.itemId,
+ SMART_BOOKMARKS_ANNO, smartBookmark.queryId,
+ 0, annosvc.EXPIRE_NEVER);
+ }
+
+ // If we are creating all Smart Bookmarks from ground up, add a
+ // separator below them in the bookmarks menu.
+ if (smartBookmarkItemIds.length == 0)
+ bmsvc.insertSeparator(bmsvc.bookmarksMenuFolder, bookmarksMenuIndex);
+ }
+ };
+
+ try {
+ bmsvc.runInBatchMode(callback, null);
+ }
+ catch(ex) {
+ Components.utils.reportError(ex);
+ }
+ finally {
+ this._prefs.setIntPref(SMART_BOOKMARKS_PREF, SMART_BOOKMARKS_VERSION);
+ this._prefs.QueryInterface(Ci.nsIPrefService).savePrefFile(null);
+ }
+ },
+
+//@line 957 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserGlue.js"
+
+ // this returns the most recent non-popup browser window
+ getMostRecentBrowserWindow : function ()
+ {
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Components.interfaces.nsIWindowMediator);
+
+//@line 965 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserGlue.js"
+ var win = wm.getMostRecentWindow("navigator:browser", true);
+
+ // if we're lucky, this isn't a popup, and we can just return this
+ if (win && win.document.documentElement.getAttribute("chromehidden")) {
+ win = null;
+ var windowList = wm.getEnumerator("navigator:browser", true);
+ // this is oldest to newest, so this gets a bit ugly
+ while (windowList.hasMoreElements()) {
+ var nextWin = windowList.getNext();
+ if (!nextWin.document.documentElement.getAttribute("chromehidden"))
+ win = nextWin;
+ }
+ }
+//@line 991 "/builds/moz2_slave/linux_build/build/browser/components/nsBrowserGlue.js"
+
+ return win;
+ },
+
+
+ // for XPCOM
+ classDescription: "Firefox Browser Glue Service",
+ classID: Components.ID("{eab9012e-5f74-4cbc-b2b5-a590235513cc}"),
+ contractID: "@mozilla.org/browser/browserglue;1",
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsISupportsWeakReference,
+ Ci.nsIBrowserGlue]),
+
+ // redefine the default factory for XPCOMUtils
+ _xpcom_factory: BrowserGlueServiceFactory,
+
+ // get this contractID registered for certain categories via XPCOMUtils
+ _xpcom_categories: [
+ // make BrowserGlue a startup observer
+ { category: "app-startup", service: true }
+ ]
+}
+
+function GeolocationPrompt() {}
+
+GeolocationPrompt.prototype = {
+ classDescription: "Geolocation Prompting Component",
+ classID: Components.ID("{C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}"),
+ contractID: "@mozilla.org/geolocation/prompt;1",
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationPrompt]),
+
+ prompt: function(request) {
+ var pm = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager);
+
+ var result = pm.testExactPermission(request.requestingURI, "geo");
+
+ if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
+ request.allow();
+ return;
+ }
+
+ if (result == Ci.nsIPermissionManager.DENY_ACTION) {
+ request.cancel();
+ return;
+ }
+
+ function setPagePermission(uri, allow) {
+ if (allow == true)
+ pm.add(uri, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
+ else
+ pm.add(uri, "geo", Ci.nsIPermissionManager.DENY_ACTION);
+ }
+
+ function getChromeWindow(aWindow) {
+ var chromeWin = aWindow
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .QueryInterface(Ci.nsIDOMChromeWindow);
+ return chromeWin;
+ }
+
+ var requestingWindow = request.requestingWindow.top;
+ var chromeWindowObject = getChromeWindow(requestingWindow).wrappedJSObject;
+ var tabbrowser = chromeWindowObject.gBrowser;
+ var browser = tabbrowser.getBrowserForDocument(requestingWindow.document);
+ var notificationBox = tabbrowser.getNotificationBox(browser);
+
+ var notification = notificationBox.getNotificationWithValue("geolocation");
+ if (!notification) {
+ var bundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
+ var browserBundle = bundleService.createBundle("chrome://browser/locale/browser.properties");
+
+ var buttons = [{
+ label: browserBundle.GetStringFromName("geolocation.shareLocation"),
+ accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
+ callback: function(notification) {
+ if (notification.getElementsByClassName("rememberChoice")[0].checked)
+ setPagePermission(request.requestingURI, true);
+ request.allow();
+ },
+ },
+ {
+ label: browserBundle.GetStringFromName("geolocation.dontShareLocation"),
+ accessKey: browserBundle.GetStringFromName("geolocation.dontShareLocation.accesskey"),
+ callback: function(notification) {
+ if (notification.getElementsByClassName("rememberChoice")[0].checked)
+ setPagePermission(request.requestingURI, false);
+ request.cancel();
+ },
+ }];
+
+ var message = browserBundle.formatStringFromName("geolocation.siteWantsToKnow",
+ [request.requestingURI.host], 1);
+
+ var newBar = notificationBox.appendNotification(message,
+ "geolocation",
+ "chrome://browser/skin/Geo.png",
+ notificationBox.PRIORITY_INFO_HIGH,
+ buttons);
+
+ // For whatever reason, if we do this immediately
+ // (eg, without the setTimeout), the "link"
+ // element does not show up in the notification
+ // bar.
+ function geolocation_hacks_to_notification () {
+
+ var checkbox = newBar.ownerDocument.createElementNS(XULNS, "checkbox");
+ checkbox.className = "rememberChoice";
+ checkbox.setAttribute("label", browserBundle.GetStringFromName("geolocation.remember"));
+ newBar.appendChild(checkbox);
+
+ var link = newBar.ownerDocument.createElementNS(XULNS, "label");
+ link.className = "text-link";
+ link.setAttribute("value", browserBundle.GetStringFromName("geolocation.learnMore"));
+
+ var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
+ link.href = formatter.formatURLPref("browser.geolocation.warning.infoURL");
+
+ var description = newBar.ownerDocument.getAnonymousElementByAttribute(newBar, "anonid", "messageText");
+ description.appendChild(link);
+ };
+
+ chromeWindowObject.setTimeout(geolocation_hacks_to_notification, 0);
+
+ }
+ },
+};
+
+
+//module initialization
+function NSGetModule(aCompMgr, aFileSpec) {
+ return XPCOMUtils.generateModule([BrowserGlue, GeolocationPrompt]);
+}
diff --git a/bundles/XO/components/nsContentDispatchChooser.js b/bundles/XO/components/nsContentDispatchChooser.js
new file mode 100755
index 0000000..e01c247
--- /dev/null
+++ b/bundles/XO/components/nsContentDispatchChooser.js
@@ -0,0 +1,128 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is nsContentDispatchChooser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ * Dan Mosedale <dmose@mozilla.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+const CONTENT_HANDLING_URL = "chrome://mozapps/content/handling/dialog.xul";
+const STRINGBUNDLE_URL = "chrome://mozapps/locale/handling/handling.properties";
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsContentDispatchChooser class
+
+function nsContentDispatchChooser()
+{
+}
+
+nsContentDispatchChooser.prototype =
+{
+ classDescription: "Used to handle different types of content",
+ classID: Components.ID("e35d5067-95bc-4029-8432-e8f1e431148d"),
+ contractID: "@mozilla.org/content-dispatch-chooser;1",
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsIContentDispatchChooser
+
+ ask: function ask(aHandler, aWindowContext, aURI, aReason)
+ {
+ var window = null;
+ try {
+ if (aWindowContext)
+ window = aWindowContext.getInterface(Ci.nsIDOMWindow);
+ } catch (e) { /* it's OK to not have a window */ }
+
+ var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ var bundle = sbs.createBundle(STRINGBUNDLE_URL);
+
+ var xai = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo);
+ // TODO when this is hooked up for content, we will need different strings
+ // for most of these
+ var arr = [bundle.GetStringFromName("protocol.title"),
+ "",
+ bundle.GetStringFromName("protocol.description"),
+ bundle.GetStringFromName("protocol.choices.label"),
+ bundle.formatStringFromName("protocol.checkbox.label",
+ [aURI.scheme], 1),
+ bundle.GetStringFromName("protocol.checkbox.accesskey"),
+ bundle.formatStringFromName("protocol.checkbox.extra",
+ [xai.name], 1)];
+
+ var params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+ for each (let text in arr) {
+ let string = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ string.data = text;
+ params.appendElement(string, false);
+ }
+ params.appendElement(aHandler, false);
+ params.appendElement(aURI, false);
+ params.appendElement(aWindowContext, false);
+
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(window,
+ CONTENT_HANDLING_URL,
+ null,
+ "chrome,dialog=yes,resizable,centerscreen",
+ params);
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsISupports
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentDispatchChooser])
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// Module
+
+let components = [nsContentDispatchChooser];
+
+function NSGetModule(compMgr, fileSpec)
+{
+ return XPCOMUtils.generateModule(components);
+}
+
diff --git a/bundles/XO/components/nsContentPrefService.js b/bundles/XO/components/nsContentPrefService.js
new file mode 100755
index 0000000..1a584bc
--- /dev/null
+++ b/bundles/XO/components/nsContentPrefService.js
@@ -0,0 +1,944 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Content Preferences (cpref).
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Myk Melez <myk@mozilla.org>
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function ContentPrefService() {
+ // If this throws an exception, it causes the getService call to fail,
+ // but the next time a consumer tries to retrieve the service, we'll try
+ // to initialize the database again, which might work if the failure
+ // was due to a temporary condition (like being out of disk space).
+ this._dbInit();
+
+ // Observe shutdown so we can shut down the database connection.
+ this._observerSvc.addObserver(this, "xpcom-shutdown", false);
+}
+
+ContentPrefService.prototype = {
+ //**************************************************************************//
+ // XPCOM Plumbing
+
+ classDescription: "Content Pref Service",
+ classID: Components.ID("{e6a3f533-4ffa-4615-8eb4-d4e72d883fa7}"),
+ contractID: "@mozilla.org/content-pref/service;1",
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPrefService]),
+
+
+ //**************************************************************************//
+ // Convenience Getters
+
+ // Observer Service
+ __observerSvc: null,
+ get _observerSvc ContentPrefService_get__observerSvc() {
+ if (!this.__observerSvc)
+ this.__observerSvc = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ return this.__observerSvc;
+ },
+
+ // Console Service
+ __consoleSvc: null,
+ get _consoleSvc ContentPrefService_get__consoleSvc() {
+ if (!this.__consoleSvc)
+ this.__consoleSvc = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ return this.__consoleSvc;
+ },
+
+ // Preferences Service
+ __prefSvc: null,
+ get _prefSvc ContentPrefService_get__prefSvc() {
+ if (!this.__prefSvc)
+ this.__prefSvc = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+ return this.__prefSvc;
+ },
+
+
+ //**************************************************************************//
+ // Destruction
+
+ _destroy: function ContentPrefService__destroy() {
+ this._observerSvc.removeObserver(this, "xpcom-shutdown");
+
+ // Delete references to XPCOM components to make sure we don't leak them
+ // (although we haven't observed leakage in tests). Also delete references
+ // in _observers and _genericObservers to avoid cycles with those that
+ // refer to us and don't remove themselves from those observer pools.
+ for (var i in this) {
+ try { this[i] = null }
+ // Ignore "setting a property that has only a getter" exceptions.
+ catch(ex) {}
+ }
+ },
+
+
+ //**************************************************************************//
+ // nsIObserver
+
+ observe: function ContentPrefService_observe(subject, topic, data) {
+ switch (topic) {
+ case "xpcom-shutdown":
+ this._destroy();
+ break;
+ }
+ },
+
+
+ //**************************************************************************//
+ // nsIContentPrefService
+
+ getPref: function ContentPrefService_getPref(aURI, aName) {
+ if (aURI) {
+ var group = this.grouper.group(aURI);
+ return this._selectPref(group, aName);
+ }
+
+ return this._selectGlobalPref(aName);
+ },
+
+ setPref: function ContentPrefService_setPref(aURI, aName, aValue) {
+ // If the pref is already set to the value, there's nothing more to do.
+ var currentValue = this.getPref(aURI, aName);
+ if (typeof currentValue != "undefined") {
+ if (currentValue == aValue)
+ return;
+ }
+ else {
+ // If we are in private browsing mode, refuse to set new prefs
+ var inPrivateBrowsing = false;
+ try { // The Private Browsing service might not be available.
+ var pbs = Cc["@mozilla.org/privatebrowsing;1"].
+ getService(Ci.nsIPrivateBrowsingService);
+ inPrivateBrowsing = pbs.privateBrowsingEnabled;
+ } catch (e) {}
+ if (inPrivateBrowsing)
+ return;
+ }
+
+ var settingID = this._selectSettingID(aName) || this._insertSetting(aName);
+ var group, groupID, prefID;
+ if (aURI) {
+ group = this.grouper.group(aURI);
+ groupID = this._selectGroupID(group) || this._insertGroup(group);
+ prefID = this._selectPrefID(groupID, settingID);
+ }
+ else {
+ group = null;
+ groupID = null;
+ prefID = this._selectGlobalPrefID(settingID);
+ }
+
+ // Update the existing record, if any, or create a new one.
+ if (prefID)
+ this._updatePref(prefID, aValue);
+ else
+ this._insertPref(groupID, settingID, aValue);
+
+ for each (var observer in this._getObservers(aName)) {
+ try {
+ observer.onContentPrefSet(group, aName, aValue);
+ }
+ catch(ex) {
+ Cu.reportError(ex);
+ }
+ }
+ },
+
+ hasPref: function ContentPrefService_hasPref(aURI, aName) {
+ // XXX If consumers end up calling this method regularly, then we should
+ // optimize this to query the database directly.
+ return (typeof this.getPref(aURI, aName) != "undefined");
+ },
+
+ removePref: function ContentPrefService_removePref(aURI, aName) {
+ // If there's no old value, then there's nothing to remove.
+ if (!this.hasPref(aURI, aName))
+ return;
+
+ var settingID = this._selectSettingID(aName);
+ var group, groupID, prefID;
+ if (aURI) {
+ group = this.grouper.group(aURI);
+ groupID = this._selectGroupID(group);
+ prefID = this._selectPrefID(groupID, settingID);
+ }
+ else {
+ group = null;
+ groupID = null;
+ prefID = this._selectGlobalPrefID(settingID);
+ }
+
+ this._deletePref(prefID);
+
+ // Get rid of extraneous records that are no longer being used.
+ this._deleteSettingIfUnused(settingID);
+ if (groupID)
+ this._deleteGroupIfUnused(groupID);
+
+ for each (var observer in this._getObservers(aName)) {
+ try {
+ observer.onContentPrefRemoved(group, aName);
+ }
+ catch(ex) {
+ Cu.reportError(ex);
+ }
+ }
+ },
+
+ removeGroupedPrefs: function ContentPrefService_removeGroupedPrefs() {
+ this._dbConnection.beginTransaction();
+ try {
+ this._dbConnection.executeSimpleSQL("DELETE FROM prefs WHERE groupID IS NOT NULL");
+ this._dbConnection.executeSimpleSQL("DELETE FROM groups");
+ this._dbConnection.commitTransaction();
+ }
+ catch(ex) {
+ this._dbConnection.rollbackTransaction();
+ throw ex;
+ }
+ },
+
+ getPrefs: function ContentPrefService_getPrefs(aURI) {
+ if (aURI) {
+ var group = this.grouper.group(aURI);
+ return this._selectPrefs(group);
+ }
+
+ return this._selectGlobalPrefs();
+ },
+
+ // A hash of arrays of observers, indexed by setting name.
+ _observers: {},
+
+ // An array of generic observers, which observe all settings.
+ _genericObservers: [],
+
+ addObserver: function ContentPrefService_addObserver(aName, aObserver) {
+ var observers;
+ if (aName) {
+ if (!this._observers[aName])
+ this._observers[aName] = [];
+ observers = this._observers[aName];
+ }
+ else
+ observers = this._genericObservers;
+
+ if (observers.indexOf(aObserver) == -1)
+ observers.push(aObserver);
+ },
+
+ removeObserver: function ContentPrefService_removeObserver(aName, aObserver) {
+ var observers;
+ if (aName) {
+ if (!this._observers[aName])
+ return;
+ observers = this._observers[aName];
+ }
+ else
+ observers = this._genericObservers;
+
+ if (observers.indexOf(aObserver) != -1)
+ observers.splice(observers.indexOf(aObserver), 1);
+ },
+
+ /**
+ * Construct a list of observers to notify about a change to some setting,
+ * putting setting-specific observers before before generic ones, so observers
+ * that initialize individual settings (like the page style controller)
+ * execute before observers that display multiple settings and depend on them
+ * being initialized first (like the content prefs sidebar).
+ */
+ _getObservers: function ContentPrefService__getObservers(aName) {
+ var observers = [];
+
+ if (aName && this._observers[aName])
+ observers = observers.concat(this._observers[aName]);
+ observers = observers.concat(this._genericObservers);
+
+ return observers;
+ },
+
+ _grouper: null,
+ get grouper ContentPrefService_get_grouper() {
+ if (!this._grouper)
+ this._grouper = Cc["@mozilla.org/content-pref/hostname-grouper;1"].
+ getService(Ci.nsIContentURIGrouper);
+ return this._grouper;
+ },
+
+ get DBConnection ContentPrefService_get_DBConnection() {
+ return this._dbConnection;
+ },
+
+
+ //**************************************************************************//
+ // Data Retrieval & Modification
+
+ __stmtSelectPref: null,
+ get _stmtSelectPref ContentPrefService_get__stmtSelectPref() {
+ if (!this.__stmtSelectPref)
+ this.__stmtSelectPref = this._dbCreateStatement(
+ "SELECT prefs.value AS value " +
+ "FROM prefs " +
+ "JOIN groups ON prefs.groupID = groups.id " +
+ "JOIN settings ON prefs.settingID = settings.id " +
+ "WHERE groups.name = :group " +
+ "AND settings.name = :setting"
+ );
+
+ return this.__stmtSelectPref;
+ },
+
+ _selectPref: function ContentPrefService__selectPref(aGroup, aSetting) {
+ var value;
+
+ try {
+ this._stmtSelectPref.params.group = aGroup;
+ this._stmtSelectPref.params.setting = aSetting;
+
+ if (this._stmtSelectPref.step())
+ value = this._stmtSelectPref.row["value"];
+ }
+ finally {
+ this._stmtSelectPref.reset();
+ }
+
+ return value;
+ },
+
+ __stmtSelectGlobalPref: null,
+ get _stmtSelectGlobalPref ContentPrefService_get__stmtSelectGlobalPref() {
+ if (!this.__stmtSelectGlobalPref)
+ this.__stmtSelectGlobalPref = this._dbCreateStatement(
+ "SELECT prefs.value AS value " +
+ "FROM prefs " +
+ "JOIN settings ON prefs.settingID = settings.id " +
+ "WHERE prefs.groupID IS NULL " +
+ "AND settings.name = :name"
+ );
+
+ return this.__stmtSelectGlobalPref;
+ },
+
+ _selectGlobalPref: function ContentPrefService__selectGlobalPref(aName) {
+ var value;
+
+ try {
+ this._stmtSelectGlobalPref.params.name = aName;
+
+ if (this._stmtSelectGlobalPref.step())
+ value = this._stmtSelectGlobalPref.row["value"];
+ }
+ finally {
+ this._stmtSelectGlobalPref.reset();
+ }
+
+ return value;
+ },
+
+ __stmtSelectGroupID: null,
+ get _stmtSelectGroupID ContentPrefService_get__stmtSelectGroupID() {
+ if (!this.__stmtSelectGroupID)
+ this.__stmtSelectGroupID = this._dbCreateStatement(
+ "SELECT groups.id AS id " +
+ "FROM groups " +
+ "WHERE groups.name = :name "
+ );
+
+ return this.__stmtSelectGroupID;
+ },
+
+ _selectGroupID: function ContentPrefService__selectGroupID(aName) {
+ var id;
+
+ try {
+ this._stmtSelectGroupID.params.name = aName;
+
+ if (this._stmtSelectGroupID.step())
+ id = this._stmtSelectGroupID.row["id"];
+ }
+ finally {
+ this._stmtSelectGroupID.reset();
+ }
+
+ return id;
+ },
+
+ __stmtInsertGroup: null,
+ get _stmtInsertGroup ContentPrefService_get__stmtInsertGroup() {
+ if (!this.__stmtInsertGroup)
+ this.__stmtInsertGroup = this._dbCreateStatement(
+ "INSERT INTO groups (name) VALUES (:name)"
+ );
+
+ return this.__stmtInsertGroup;
+ },
+
+ _insertGroup: function ContentPrefService__insertGroup(aName) {
+ this._stmtInsertGroup.params.name = aName;
+ this._stmtInsertGroup.execute();
+ return this._dbConnection.lastInsertRowID;
+ },
+
+ __stmtSelectSettingID: null,
+ get _stmtSelectSettingID ContentPrefService_get__stmtSelectSettingID() {
+ if (!this.__stmtSelectSettingID)
+ this.__stmtSelectSettingID = this._dbCreateStatement(
+ "SELECT id FROM settings WHERE name = :name"
+ );
+
+ return this.__stmtSelectSettingID;
+ },
+
+ _selectSettingID: function ContentPrefService__selectSettingID(aName) {
+ var id;
+
+ try {
+ this._stmtSelectSettingID.params.name = aName;
+
+ if (this._stmtSelectSettingID.step())
+ id = this._stmtSelectSettingID.row["id"];
+ }
+ finally {
+ this._stmtSelectSettingID.reset();
+ }
+
+ return id;
+ },
+
+ __stmtInsertSetting: null,
+ get _stmtInsertSetting ContentPrefService_get__stmtInsertSetting() {
+ if (!this.__stmtInsertSetting)
+ this.__stmtInsertSetting = this._dbCreateStatement(
+ "INSERT INTO settings (name) VALUES (:name)"
+ );
+
+ return this.__stmtInsertSetting;
+ },
+
+ _insertSetting: function ContentPrefService__insertSetting(aName) {
+ this._stmtInsertSetting.params.name = aName;
+ this._stmtInsertSetting.execute();
+ return this._dbConnection.lastInsertRowID;
+ },
+
+ __stmtSelectPrefID: null,
+ get _stmtSelectPrefID ContentPrefService_get__stmtSelectPrefID() {
+ if (!this.__stmtSelectPrefID)
+ this.__stmtSelectPrefID = this._dbCreateStatement(
+ "SELECT id FROM prefs WHERE groupID = :groupID AND settingID = :settingID"
+ );
+
+ return this.__stmtSelectPrefID;
+ },
+
+ _selectPrefID: function ContentPrefService__selectPrefID(aGroupID, aSettingID) {
+ var id;
+
+ try {
+ this._stmtSelectPrefID.params.groupID = aGroupID;
+ this._stmtSelectPrefID.params.settingID = aSettingID;
+
+ if (this._stmtSelectPrefID.step())
+ id = this._stmtSelectPrefID.row["id"];
+ }
+ finally {
+ this._stmtSelectPrefID.reset();
+ }
+
+ return id;
+ },
+
+ __stmtSelectGlobalPrefID: null,
+ get _stmtSelectGlobalPrefID ContentPrefService_get__stmtSelectGlobalPrefID() {
+ if (!this.__stmtSelectGlobalPrefID)
+ this.__stmtSelectGlobalPrefID = this._dbCreateStatement(
+ "SELECT id FROM prefs WHERE groupID IS NULL AND settingID = :settingID"
+ );
+
+ return this.__stmtSelectGlobalPrefID;
+ },
+
+ _selectGlobalPrefID: function ContentPrefService__selectGlobalPrefID(aSettingID) {
+ var id;
+
+ try {
+ this._stmtSelectGlobalPrefID.params.settingID = aSettingID;
+
+ if (this._stmtSelectGlobalPrefID.step())
+ id = this._stmtSelectGlobalPrefID.row["id"];
+ }
+ finally {
+ this._stmtSelectGlobalPrefID.reset();
+ }
+
+ return id;
+ },
+
+ __stmtInsertPref: null,
+ get _stmtInsertPref ContentPrefService_get__stmtInsertPref() {
+ if (!this.__stmtInsertPref)
+ this.__stmtInsertPref = this._dbCreateStatement(
+ "INSERT INTO prefs (groupID, settingID, value) " +
+ "VALUES (:groupID, :settingID, :value)"
+ );
+
+ return this.__stmtInsertPref;
+ },
+
+ _insertPref: function ContentPrefService__insertPref(aGroupID, aSettingID, aValue) {
+ this._stmtInsertPref.params.groupID = aGroupID;
+ this._stmtInsertPref.params.settingID = aSettingID;
+ this._stmtInsertPref.params.value = aValue;
+ this._stmtInsertPref.execute();
+ return this._dbConnection.lastInsertRowID;
+ },
+
+ __stmtUpdatePref: null,
+ get _stmtUpdatePref ContentPrefService_get__stmtUpdatePref() {
+ if (!this.__stmtUpdatePref)
+ this.__stmtUpdatePref = this._dbCreateStatement(
+ "UPDATE prefs SET value = :value WHERE id = :id"
+ );
+
+ return this.__stmtUpdatePref;
+ },
+
+ _updatePref: function ContentPrefService__updatePref(aPrefID, aValue) {
+ this._stmtUpdatePref.params.id = aPrefID;
+ this._stmtUpdatePref.params.value = aValue;
+ this._stmtUpdatePref.execute();
+ },
+
+ __stmtDeletePref: null,
+ get _stmtDeletePref ContentPrefService_get__stmtDeletePref() {
+ if (!this.__stmtDeletePref)
+ this.__stmtDeletePref = this._dbCreateStatement(
+ "DELETE FROM prefs WHERE id = :id"
+ );
+
+ return this.__stmtDeletePref;
+ },
+
+ _deletePref: function ContentPrefService__deletePref(aPrefID) {
+ this._stmtDeletePref.params.id = aPrefID;
+ this._stmtDeletePref.execute();
+ },
+
+ __stmtDeleteSettingIfUnused: null,
+ get _stmtDeleteSettingIfUnused ContentPrefService_get__stmtDeleteSettingIfUnused() {
+ if (!this.__stmtDeleteSettingIfUnused)
+ this.__stmtDeleteSettingIfUnused = this._dbCreateStatement(
+ "DELETE FROM settings WHERE id = :id " +
+ "AND id NOT IN (SELECT DISTINCT settingID FROM prefs)"
+ );
+
+ return this.__stmtDeleteSettingIfUnused;
+ },
+
+ _deleteSettingIfUnused: function ContentPrefService__deleteSettingIfUnused(aSettingID) {
+ this._stmtDeleteSettingIfUnused.params.id = aSettingID;
+ this._stmtDeleteSettingIfUnused.execute();
+ },
+
+ __stmtDeleteGroupIfUnused: null,
+ get _stmtDeleteGroupIfUnused ContentPrefService_get__stmtDeleteGroupIfUnused() {
+ if (!this.__stmtDeleteGroupIfUnused)
+ this.__stmtDeleteGroupIfUnused = this._dbCreateStatement(
+ "DELETE FROM groups WHERE id = :id " +
+ "AND id NOT IN (SELECT DISTINCT groupID FROM prefs)"
+ );
+
+ return this.__stmtDeleteGroupIfUnused;
+ },
+
+ _deleteGroupIfUnused: function ContentPrefService__deleteGroupIfUnused(aGroupID) {
+ this._stmtDeleteGroupIfUnused.params.id = aGroupID;
+ this._stmtDeleteGroupIfUnused.execute();
+ },
+
+ __stmtSelectPrefs: null,
+ get _stmtSelectPrefs ContentPrefService_get__stmtSelectPrefs() {
+ if (!this.__stmtSelectPrefs)
+ this.__stmtSelectPrefs = this._dbCreateStatement(
+ "SELECT settings.name AS name, prefs.value AS value " +
+ "FROM prefs " +
+ "JOIN groups ON prefs.groupID = groups.id " +
+ "JOIN settings ON prefs.settingID = settings.id " +
+ "WHERE groups.name = :group "
+ );
+
+ return this.__stmtSelectPrefs;
+ },
+
+ _selectPrefs: function ContentPrefService__selectPrefs(aGroup) {
+ var prefs = Cc["@mozilla.org/hash-property-bag;1"].
+ createInstance(Ci.nsIWritablePropertyBag);
+
+ try {
+ this._stmtSelectPrefs.params.group = aGroup;
+
+ while (this._stmtSelectPrefs.step())
+ prefs.setProperty(this._stmtSelectPrefs.row["name"],
+ this._stmtSelectPrefs.row["value"]);
+ }
+ finally {
+ this._stmtSelectPrefs.reset();
+ }
+
+ return prefs;
+ },
+
+ __stmtSelectGlobalPrefs: null,
+ get _stmtSelectGlobalPrefs ContentPrefService_get__stmtSelectGlobalPrefs() {
+ if (!this.__stmtSelectGlobalPrefs)
+ this.__stmtSelectGlobalPrefs = this._dbCreateStatement(
+ "SELECT settings.name AS name, prefs.value AS value " +
+ "FROM prefs " +
+ "JOIN settings ON prefs.settingID = settings.id " +
+ "WHERE prefs.groupID IS NULL"
+ );
+
+ return this.__stmtSelectGlobalPrefs;
+ },
+
+ _selectGlobalPrefs: function ContentPrefService__selectGlobalPrefs() {
+ var prefs = Cc["@mozilla.org/hash-property-bag;1"].
+ createInstance(Ci.nsIWritablePropertyBag);
+
+ try {
+ while (this._stmtSelectGlobalPrefs.step())
+ prefs.setProperty(this._stmtSelectGlobalPrefs.row["name"],
+ this._stmtSelectGlobalPrefs.row["value"]);
+ }
+ finally {
+ this._stmtSelectGlobalPrefs.reset();
+ }
+
+ return prefs;
+ },
+
+
+ //**************************************************************************//
+ // Database Creation & Access
+
+ _dbVersion: 3,
+
+ _dbSchema: {
+ tables: {
+ groups: "id INTEGER PRIMARY KEY, \
+ name TEXT NOT NULL",
+
+ settings: "id INTEGER PRIMARY KEY, \
+ name TEXT NOT NULL",
+
+ prefs: "id INTEGER PRIMARY KEY, \
+ groupID INTEGER REFERENCES groups(id), \
+ settingID INTEGER NOT NULL REFERENCES settings(id), \
+ value BLOB"
+ },
+ indices: {
+ groups_idx: {
+ table: "groups",
+ columns: ["name"]
+ },
+ settings_idx: {
+ table: "settings",
+ columns: ["name"]
+ },
+ prefs_idx: {
+ table: "prefs",
+ columns: ["groupID", "settingID"]
+ }
+ }
+ },
+
+ _dbConnection: null,
+
+ _dbCreateStatement: function ContentPrefService__dbCreateStatement(aSQLString) {
+ try {
+ var statement = this._dbConnection.createStatement(aSQLString);
+ }
+ catch(ex) {
+ Cu.reportError("error creating statement " + aSQLString + ": " +
+ this._dbConnection.lastError + " - " +
+ this._dbConnection.lastErrorString);
+ throw ex;
+ }
+
+ var wrappedStatement = Cc["@mozilla.org/storage/statement-wrapper;1"].
+ createInstance(Ci.mozIStorageStatementWrapper);
+ wrappedStatement.initialize(statement);
+ return wrappedStatement;
+ },
+
+ // _dbInit and the methods it calls (_dbCreate, _dbMigrate, and version-
+ // specific migration methods) must be careful not to call any method
+ // of the service that assumes the database connection has already been
+ // initialized, since it won't be initialized until at the end of _dbInit.
+
+ _dbInit: function ContentPrefService__dbInit() {
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ var dbFile = dirService.get("ProfD", Ci.nsIFile);
+ dbFile.append("content-prefs.sqlite");
+
+ var dbService = Cc["@mozilla.org/storage/service;1"].
+ getService(Ci.mozIStorageService);
+
+ var dbConnection;
+
+ if (!dbFile.exists())
+ dbConnection = this._dbCreate(dbService, dbFile);
+ else {
+ try {
+ dbConnection = dbService.openDatabase(dbFile);
+ }
+ // If the connection isn't ready after we open the database, that means
+ // the database has been corrupted, so we back it up and then recreate it.
+ catch (e if e.result == Cr.NS_ERROR_FILE_CORRUPTED) {
+ dbConnection = this._dbBackUpAndRecreate(dbService, dbFile,
+ dbConnection);
+ }
+
+ // Get the version of the schema in the file.
+ var version = dbConnection.schemaVersion;
+
+ // Try to migrate the schema in the database to the current schema used by
+ // the service. If migration fails, back up the database and recreate it.
+ if (version != this._dbVersion) {
+ try {
+ this._dbMigrate(dbConnection, version, this._dbVersion);
+ }
+ catch(ex) {
+ Cu.reportError("error migrating DB: " + ex + "; backing up and recreating");
+ dbConnection = this._dbBackUpAndRecreate(dbService, dbFile, dbConnection);
+ }
+ }
+ }
+
+ // Turn off disk synchronization checking to reduce disk churn and speed up
+ // operations when prefs are changed rapidly (such as when a user repeatedly
+ // changes the value of the browser zoom setting for a site).
+ //
+ // Note: this could cause database corruption if the OS crashes or machine
+ // loses power before the data gets written to disk, but this is considered
+ // a reasonable risk for the not-so-critical data stored in this database.
+ //
+ // If you really don't want to take this risk, however, just set the
+ // toolkit.storage.synchronous pref to 1 (NORMAL synchronization) or 2
+ // (FULL synchronization), in which case mozStorageConnection::Initialize
+ // will use that value, and we won't override it here.
+ if (!this._prefSvc.prefHasUserValue("toolkit.storage.synchronous"))
+ dbConnection.executeSimpleSQL("PRAGMA synchronous = OFF");
+
+ this._dbConnection = dbConnection;
+ },
+
+ _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) {
+ var dbConnection = aDBService.openDatabase(aDBFile);
+
+ try {
+ this._dbCreateSchema(dbConnection);
+ dbConnection.schemaVersion = this._dbVersion;
+ }
+ catch(ex) {
+ // If we failed to create the database (perhaps because the disk ran out
+ // of space), then remove the database file so we don't leave it in some
+ // half-created state from which we won't know how to recover.
+ dbConnection.close();
+ aDBFile.remove(false);
+ throw ex;
+ }
+
+ return dbConnection;
+ },
+
+ _dbCreateSchema: function ContentPrefService__dbCreateSchema(aDBConnection) {
+ this._dbCreateTables(aDBConnection);
+ this._dbCreateIndices(aDBConnection);
+ },
+
+ _dbCreateTables: function ContentPrefService__dbCreateTables(aDBConnection) {
+ for (let name in this._dbSchema.tables)
+ aDBConnection.createTable(name, this._dbSchema.tables[name]);
+ },
+
+ _dbCreateIndices: function ContentPrefService__dbCreateIndices(aDBConnection) {
+ for (let name in this._dbSchema.indices) {
+ let index = this._dbSchema.indices[name];
+ let statement = "CREATE INDEX IF NOT EXISTS " + name + " ON " + index.table +
+ "(" + index.columns.join(", ") + ")";
+ aDBConnection.executeSimpleSQL(statement);
+ }
+ },
+
+ _dbBackUpAndRecreate: function ContentPrefService__dbBackUpAndRecreate(aDBService,
+ aDBFile,
+ aDBConnection) {
+ aDBService.backupDatabaseFile(aDBFile, "content-prefs.sqlite.corrupt");
+
+ // Close the database, ignoring the "already closed" exception, if any.
+ // It'll be open if we're here because of a migration failure but closed
+ // if we're here because of database corruption.
+ try { aDBConnection.close() } catch(ex) {}
+
+ aDBFile.remove(false);
+
+ let dbConnection = this._dbCreate(aDBService, aDBFile);
+
+ return dbConnection;
+ },
+
+ _dbMigrate: function ContentPrefService__dbMigrate(aDBConnection, aOldVersion, aNewVersion) {
+ if (this["_dbMigrate" + aOldVersion + "To" + aNewVersion]) {
+ aDBConnection.beginTransaction();
+ try {
+ this["_dbMigrate" + aOldVersion + "To" + aNewVersion](aDBConnection);
+ aDBConnection.schemaVersion = aNewVersion;
+ aDBConnection.commitTransaction();
+ }
+ catch(ex) {
+ aDBConnection.rollbackTransaction();
+ throw ex;
+ }
+ }
+ else
+ throw("no migrator function from version " + aOldVersion +
+ " to version " + aNewVersion);
+ },
+
+ /**
+ * If the schema version is 0, that means it was never set, which means
+ * the database was somehow created without the schema being applied, perhaps
+ * because the system ran out of disk space (although we check for this
+ * in _createDB) or because some other code created the database file without
+ * applying the schema. In any case, recover by simply reapplying the schema.
+ */
+ _dbMigrate0To3: function ContentPrefService___dbMigrate0To3(aDBConnection) {
+ this._dbCreateSchema(aDBConnection);
+ },
+
+ _dbMigrate1To3: function ContentPrefService___dbMigrate1To3(aDBConnection) {
+ aDBConnection.executeSimpleSQL("ALTER TABLE groups RENAME TO groupsOld");
+ aDBConnection.createTable("groups", this._dbSchema.tables.groups);
+ aDBConnection.executeSimpleSQL(
+ "INSERT INTO groups (id, name) " +
+ "SELECT id, name FROM groupsOld"
+ );
+
+ aDBConnection.executeSimpleSQL("DROP TABLE groupers");
+ aDBConnection.executeSimpleSQL("DROP TABLE groupsOld");
+
+ this._dbCreateIndices(aDBConnection);
+ },
+
+ _dbMigrate2To3: function ContentPrefService__dbMigrate2To3(aDBConnection) {
+ this._dbCreateIndices(aDBConnection);
+ }
+
+};
+
+
+function HostnameGrouper() {}
+
+HostnameGrouper.prototype = {
+ //**************************************************************************//
+ // XPCOM Plumbing
+
+ classDescription: "Hostname Grouper",
+ classID: Components.ID("{8df290ae-dcaa-4c11-98a5-2429a4dc97bb}"),
+ contractID: "@mozilla.org/content-pref/hostname-grouper;1",
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentURIGrouper]),
+
+
+ //**************************************************************************//
+ // nsIContentURIGrouper
+
+ group: function HostnameGrouper_group(aURI) {
+ var group;
+
+ try {
+ // Accessing the host property of the URI will throw an exception
+ // if the URI is of a type that doesn't have a host property.
+ // Otherwise, we manually throw an exception if the host is empty,
+ // since the effect is the same (we can't derive a group from it).
+
+ group = aURI.host;
+ if (!group)
+ throw("can't derive group from host; no host in URI");
+ }
+ catch(ex) {
+ // If we don't have a host, then use the entire URI (minus the query,
+ // reference, and hash, if possible) as the group. This means that URIs
+ // like about:mozilla and about:blank will be considered separate groups,
+ // but at least they'll be grouped somehow.
+
+ // This also means that each individual file: URL will be considered
+ // its own group. This seems suboptimal, but so does treating the entire
+ // file: URL space as a single group (especially if folks start setting
+ // group-specific capabilities prefs).
+
+ // XXX Is there something better we can do here?
+
+ try {
+ var url = aURI.QueryInterface(Ci.nsIURL);
+ group = aURI.prePath + url.filePath;
+ }
+ catch(ex) {
+ group = aURI.spec;
+ }
+ }
+
+ return group;
+ }
+};
+
+
+//****************************************************************************//
+// XPCOM Plumbing
+
+var components = [ContentPrefService, HostnameGrouper];
+var NSGetModule = function ContentPrefService_NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(components);
+}
diff --git a/bundles/XO/components/nsDefaultCLH.js b/bundles/XO/components/nsDefaultCLH.js
new file mode 100755
index 0000000..315c064
--- /dev/null
+++ b/bundles/XO/components/nsDefaultCLH.js
@@ -0,0 +1,201 @@
+//@line 38 "/builds/moz2_slave/linux_build/build/toolkit/components/nsDefaultCLH.js"
+
+const nsISupports = Components.interfaces.nsISupports;
+
+const nsICategoryManager = Components.interfaces.nsICategoryManager;
+const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
+const nsICommandLine = Components.interfaces.nsICommandLine;
+const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
+const nsIFactory = Components.interfaces.nsIFactory;
+const nsIModule = Components.interfaces.nsIModule;
+const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
+const nsISupportsString = Components.interfaces.nsISupportsString;
+const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
+const nsIProperties = Components.interfaces.nsIProperties;
+const nsIFile = Components.interfaces.nsIFile;
+const nsISimpleEnumerator = Components.interfaces.nsISimpleEnumerator;
+
+/**
+ * This file provides a generic default command-line handler.
+ *
+ * It opens the chrome window specified by the pref "toolkit.defaultChromeURI"
+ * with the flags specified by the pref "toolkit.defaultChromeFeatures"
+ * or "chrome,dialog=no,all" is it is not available.
+ * The arguments passed to the window are the nsICommandLine instance.
+ *
+ * It doesn't do anything if the pref "toolkit.defaultChromeURI" is unset.
+ */
+
+function getDirectoryService()
+{
+ return Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(nsIProperties);
+}
+
+var nsDefaultCLH = {
+ /* nsISupports */
+
+ QueryInterface : function clh_QI(iid) {
+ if (iid.equals(nsICommandLineHandler) ||
+ iid.equals(nsIFactory) ||
+ iid.equals(nsISupports))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ /* nsICommandLineHandler */
+
+ handle : function clh_handle(cmdLine) {
+ var printDir;
+ while (printDir = cmdLine.handleFlagWithParam("print-xpcom-dir", false)) {
+ var out = "print-xpcom-dir(\"" + printDir + "\"): ";
+ try {
+ out += getDirectoryService().get(printDir, nsIFile).path;
+ }
+ catch (e) {
+ out += "<Not Provided>";
+ }
+
+ dump(out + "\n");
+ Components.utils.reportError(out);
+ }
+
+ var printDirList;
+ while (printDirList = cmdLine.handleFlagWithParam("print-xpcom-dirlist",
+ false)) {
+ out = "print-xpcom-dirlist(\"" + printDirList + "\"): ";
+ try {
+ var list = getDirectoryService().get(printDirList,
+ nsISimpleEnumerator);
+ while (list.hasMoreElements())
+ out += list.getNext().QueryInterface(nsIFile).path + ";";
+ }
+ catch (e) {
+ out += "<Not Provided>";
+ }
+
+ dump(out + "\n");
+ Components.utils.reportError(out);
+ }
+
+ if (cmdLine.handleFlag("silent", false)) {
+ cmdLine.preventDefault = true;
+ }
+
+ if (cmdLine.preventDefault)
+ return;
+
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(nsIPrefBranch);
+
+ try {
+ var singletonWindowType =
+ prefs.getCharPref("toolkit.singletonWindowType");
+ var windowMediator =
+ Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+
+ var win = windowMediator.getMostRecentWindow(singletonWindowType);
+ if (win) {
+ win.focus();
+ cmdLine.preventDefault = true;
+ return;
+ }
+ }
+ catch (e) { }
+
+ // if the pref is missing, ignore the exception
+ try {
+ var chromeURI = prefs.getCharPref("toolkit.defaultChromeURI");
+
+ var flags = "chrome,dialog=no,all";
+ try {
+ flags = prefs.getCharPref("toolkit.defaultChromeFeatures");
+ }
+ catch (e) { }
+
+ var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
+ .getService(nsIWindowWatcher);
+ wwatch.openWindow(null, chromeURI, "_blank",
+ flags, cmdLine);
+ }
+ catch (e) { }
+ },
+
+ helpInfo : "",
+
+ /* nsIFactory */
+
+ createInstance : function mdh_CI(outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ return this.QueryInterface(iid);
+ },
+
+ lockFactory : function mdh_lock(lock) {
+ /* no-op */
+ }
+};
+
+const clh_contractID = "@mozilla.org/toolkit/default-clh;1";
+const clh_CID = Components.ID("{6ebc941a-f2ff-4d56-b3b6-f7d0b9d73344}");
+
+var Module = {
+ /* nsISupports */
+
+ QueryInterface : function mod_QI(iid) {
+ if (iid.equals(nsIModule) ||
+ iid.equals(nsISupports))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ /* nsIModule */
+
+ getClassObject : function mod_gch(compMgr, cid, iid) {
+ if (cid.equals(clh_CID))
+ return nsDefaultCLH.QueryInterface(iid);
+
+ throw components.results.NS_ERROR_FAILURE;
+ },
+
+ registerSelf : function mod_regself(compMgr, fileSpec, location, type) {
+ var compReg = compMgr.QueryInterface(nsIComponentRegistrar);
+
+ compReg.registerFactoryLocation(clh_CID,
+ "nsDefaultCLH",
+ clh_contractID,
+ fileSpec,
+ location,
+ type);
+
+ var catMan = Components.classes["@mozilla.org/categorymanager;1"]
+ .getService(nsICategoryManager);
+
+ catMan.addCategoryEntry("command-line-handler",
+ "y-default",
+ clh_contractID, true, true);
+ },
+
+ unregisterSelf : function mod_unreg(compMgr, location, type) {
+ var compReg = compMgr.QueryInterface(nsIComponentRegistrar);
+ compReg.unregisterFactoryLocation(clh_CID, location);
+
+ var catMan = Components.classes["@mozilla.org/categorymanager;1"]
+ .getService(nsICategoryManager);
+
+ catMan.deleteCategoryEntry("command-line-handler",
+ "y-default");
+ },
+
+ canUnload : function (compMgr) {
+ return true;
+ }
+};
+
+function NSGetModule(compMgr, fileSpec) {
+ return Module;
+}
diff --git a/bundles/XO/components/nsDownloadManagerUI.js b/bundles/XO/components/nsDownloadManagerUI.js
new file mode 100755
index 0000000..48f85f2
--- /dev/null
+++ b/bundles/XO/components/nsDownloadManagerUI.js
@@ -0,0 +1,159 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Shawn Wilsher <me@shawnwilsher.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const DOWNLOAD_MANAGER_URL = "chrome://mozapps/content/downloads/downloads.xul";
+const PREF_FLASH_COUNT = "browser.download.manager.flashCount";
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsDownloadManagerUI class
+
+function nsDownloadManagerUI() {}
+
+nsDownloadManagerUI.prototype = {
+ classDescription: "Used to show the Download Manager's UI to the user",
+ classID: Components.ID("7dfdf0d1-aff6-4a34-bad1-d0fe74601642"),
+ contractID: "@mozilla.org/download-manager-ui;1",
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsIDownloadManagerUI
+
+ show: function show(aWindowContext, aID, aReason)
+ {
+ if (!aReason)
+ aReason = Ci.nsIDownloadManagerUI.REASON_USER_INTERACTED;
+
+ // First we see if it is already visible
+ let window = this.recentWindow;
+ if (window) {
+ window.focus();
+
+ // If we are being asked to show again, with a user interaction reason,
+ // set the appropriate variable.
+ if (aReason == Ci.nsIDownloadManagerUI.REASON_USER_INTERACTED)
+ window.gUserInteracted = true;
+ return;
+ }
+
+ let parent = null;
+ // We try to get a window to use as the parent here. If we don't have one,
+ // the download manager will close immediately after opening if the pref
+ // browser.download.manager.closeWhenDone is set to true.
+ try {
+ if (aWindowContext)
+ parent = aWindowContext.getInterface(Ci.nsIDOMWindow);
+ } catch (e) { /* it's OK to not have a parent window */ }
+
+ // We pass the download manager and the nsIDownload we want selected (if any)
+ var params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+
+ // Don't fail if our passed in ID is invalid
+ var download = null;
+ try {
+ let dm = Cc["@mozilla.org/download-manager;1"].
+ getService(Ci.nsIDownloadManager);
+ download = dm.getDownload(aID);
+ } catch (ex) {}
+ params.appendElement(download, false);
+
+ // Pass in the reason as well
+ let reason = Cc["@mozilla.org/supports-PRInt16;1"].
+ createInstance(Ci.nsISupportsPRInt16);
+ reason.data = aReason;
+ params.appendElement(reason, false);
+
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(parent,
+ DOWNLOAD_MANAGER_URL,
+ "Download:Manager",
+ "chrome,dialog=no,resizable",
+ params);
+ },
+
+ get visible() {
+ return (null != this.recentWindow);
+ },
+
+ getAttention: function getAttention()
+ {
+ if (!this.visible)
+ throw Cr.NS_ERROR_UNEXPECTED;
+
+ var prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ // This preference may not be set, so defaulting to two.
+ let flashCount = 2;
+ try {
+ flashCount = prefs.getIntPref(PREF_FLASH_COUNT);
+ } catch (e) { }
+
+ var win = this.recentWindow.QueryInterface(Ci.nsIDOMChromeWindow);
+ win.getAttentionWithCycleCount(flashCount);
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsDownloadManagerUI
+
+ get recentWindow() {
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ return wm.getMostRecentWindow("Download:Manager");
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsISupports
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIDownloadManagerUI])
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// Module
+
+let components = [nsDownloadManagerUI];
+
+function NSGetModule(compMgr, fileSpec)
+{
+ return XPCOMUtils.generateModule(components);
+}
+
diff --git a/bundles/XO/components/nsExtensionManager.js b/bundles/XO/components/nsExtensionManager.js
new file mode 100755
index 0000000..637504a
--- /dev/null
+++ b/bundles/XO/components/nsExtensionManager.js
@@ -0,0 +1,8801 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+//@line 44 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+*/
+
+//
+// TODO:
+// - better logging
+//
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const PREF_EM_CHECK_COMPATIBILITY = "extensions.checkCompatibility";
+const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
+const PREF_EM_LAST_APP_VERSION = "extensions.lastAppVersion";
+const PREF_EM_ENABLED_ITEMS = "extensions.enabledItems";
+const PREF_UPDATE_COUNT = "extensions.update.count";
+const PREF_UPDATE_DEFAULT_URL = "extensions.update.url";
+const PREF_EM_NEW_ADDONS_LIST = "extensions.newAddons";
+const PREF_EM_IGNOREMTIMECHANGES = "extensions.ignoreMTimeChanges";
+const PREF_EM_DISABLEDOBSOLETE = "extensions.disabledObsolete";
+const PREF_EM_EXTENSION_FORMAT = "extensions.%UUID%.";
+const PREF_EM_ITEM_UPDATE_ENABLED = "extensions.%UUID%.update.enabled";
+const PREF_EM_UPDATE_ENABLED = "extensions.update.enabled";
+const PREF_EM_ITEM_UPDATE_URL = "extensions.%UUID%.update.url";
+const PREF_EM_DSS_ENABLED = "extensions.dss.enabled";
+const PREF_DSS_SWITCHPENDING = "extensions.dss.switchPending";
+const PREF_DSS_SKIN_TO_SELECT = "extensions.lastSelectedSkin";
+const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
+const PREF_EM_LOGGING_ENABLED = "extensions.logging.enabled";
+const PREF_EM_UPDATE_INTERVAL = "extensions.update.interval";
+const PREF_UPDATE_NOTIFYUSER = "extensions.update.notifyUser";
+const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
+const PREF_SELECTED_LOCALE = "general.useragent.locale";
+
+const DIR_EXTENSIONS = "extensions";
+const DIR_CHROME = "chrome";
+const DIR_STAGE = "staged-xpis";
+const FILE_EXTENSIONS = "extensions.rdf";
+const FILE_EXTENSION_MANIFEST = "extensions.ini";
+const FILE_EXTENSIONS_STARTUP_CACHE = "extensions.cache";
+const FILE_EXTENSIONS_LOG = "extensions.log";
+const FILE_AUTOREG = ".autoreg";
+const FILE_INSTALL_MANIFEST = "install.rdf";
+const FILE_CONTENTS_MANIFEST = "contents.rdf";
+const FILE_CHROME_MANIFEST = "chrome.manifest";
+
+const UNKNOWN_XPCOM_ABI = "unknownABI";
+
+const FILE_DEFAULT_THEME_JAR = "classic.jar";
+const TOOLKIT_ID = "toolkit@mozilla.org"
+
+const KEY_PROFILEDIR = "ProfD";
+const KEY_PROFILEDS = "ProfDS";
+const KEY_APPDIR = "XCurProcD";
+const KEY_TEMPDIR = "TmpD";
+
+const EM_ACTION_REQUESTED_TOPIC = "em-action-requested";
+const EM_ITEM_INSTALLED = "item-installed";
+const EM_ITEM_UPGRADED = "item-upgraded";
+const EM_ITEM_UNINSTALLED = "item-uninstalled";
+const EM_ITEM_ENABLED = "item-enabled";
+const EM_ITEM_DISABLED = "item-disabled";
+const EM_ITEM_CANCEL = "item-cancel-action";
+
+const OP_NONE = "";
+const OP_NEEDS_INSTALL = "needs-install";
+const OP_NEEDS_UPGRADE = "needs-upgrade";
+const OP_NEEDS_UNINSTALL = "needs-uninstall";
+const OP_NEEDS_ENABLE = "needs-enable";
+const OP_NEEDS_DISABLE = "needs-disable";
+
+const KEY_APP_PROFILE = "app-profile";
+const KEY_APP_GLOBAL = "app-global";
+const KEY_APP_SYSTEM_LOCAL = "app-system-local";
+const KEY_APP_SYSTEM_SHARE = "app-system-share";
+const KEY_APP_SYSTEM_USER = "app-system-user";
+
+const CATEGORY_INSTALL_LOCATIONS = "extension-install-locations";
+const CATEGORY_UPDATE_PARAMS = "extension-update-params";
+
+const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
+const PREFIX_NS_CHROME = "http://www.mozilla.org/rdf/chrome#";
+const PREFIX_ITEM_URI = "urn:mozilla:item:";
+const PREFIX_EXTENSION = "urn:mozilla:extension:";
+const PREFIX_THEME = "urn:mozilla:theme:";
+const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";
+const RDFURI_ITEM_ROOT = "urn:mozilla:item:root"
+const RDFURI_DEFAULT_THEME = "urn:mozilla:item:{972ce4c6-7e08-4474-a285-3208198ce6fd}";
+const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"
+
+const URI_GENERIC_ICON_XPINSTALL = "chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png";
+const URI_GENERIC_ICON_THEME = "chrome://mozapps/skin/extensions/themeGeneric.png";
+const URI_XPINSTALL_CONFIRM_DIALOG = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
+const URI_EXTENSIONS_PROPERTIES = "chrome://mozapps/locale/extensions/extensions.properties";
+const URI_BRAND_PROPERTIES = "chrome://branding/locale/brand.properties";
+const URI_DOWNLOADS_PROPERTIES = "chrome://mozapps/locale/downloads/downloads.properties";
+const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
+const URI_EXTENSION_LIST_DIALOG = "chrome://mozapps/content/extensions/list.xul";
+
+const INSTALLERROR_SUCCESS = 0;
+const INSTALLERROR_INVALID_VERSION = -1;
+const INSTALLERROR_INVALID_GUID = -2;
+const INSTALLERROR_INCOMPATIBLE_VERSION = -3;
+const INSTALLERROR_PHONING_HOME = -4;
+const INSTALLERROR_INCOMPATIBLE_PLATFORM = -5;
+const INSTALLERROR_BLOCKLISTED = -6;
+const INSTALLERROR_INSECURE_UPDATE = -7;
+const INSTALLERROR_INVALID_MANIFEST = -8;
+const INSTALLERROR_RESTRICTED = -9;
+const INSTALLERROR_SOFTBLOCKED = -10;
+
+const MODE_RDONLY = 0x01;
+const MODE_WRONLY = 0x02;
+const MODE_CREATE = 0x08;
+const MODE_APPEND = 0x10;
+const MODE_TRUNCATE = 0x20;
+
+const PERMS_FILE = 0644;
+const PERMS_DIRECTORY = 0755;
+
+const REQ_VERSION = 2;
+
+var gApp = null;
+var gPref = null;
+var gRDF = null;
+var gOS = null;
+var gEmSingleton = null;
+var gBlocklist = null;
+var gXPCOMABI = null;
+var gOSTarget = null;
+var gConsole = null;
+var gInstallManifestRoot = null;
+var gVersionChecker = null;
+var gDirService = null;
+var gLoggingEnabled = null;
+var gCheckCompatibility = true;
+var gCheckUpdateSecurity = true;
+var gLocale = "en-US";
+var gFirstRun = false;
+var gAllowFlush = true;
+var gDSNeedsFlush = false;
+var gManifestNeedsFlush = false;
+
+/**
+ * Valid GUIDs fit this pattern.
+ */
+var gIDTest = /^(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)$/i;
+
+// shared code for suppressing bad cert dialogs
+//@line 41 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/shared/src/badCertHandler.js"
+
+/**
+ * Only allow built-in certs for HTTPS connections. See bug 340198.
+ */
+function checkCert(channel) {
+ if (!channel.originalURI.schemeIs("https")) // bypass
+ return;
+
+ const Ci = Components.interfaces;
+ var cert =
+ channel.securityInfo.QueryInterface(Ci.nsISSLStatusProvider).
+ SSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
+
+ var issuer = cert.issuer;
+ while (issuer && !cert.equals(issuer)) {
+ cert = issuer;
+ issuer = cert.issuer;
+ }
+
+ var errorstring = "cert issuer is not built-in";
+ if (!issuer)
+ throw errorstring;
+
+ issuer = issuer.QueryInterface(Ci.nsIX509Cert3);
+ var tokenNames = issuer.getAllTokenNames({});
+
+ if (!tokenNames.some(isBuiltinToken))
+ throw errorstring;
+}
+
+function isBuiltinToken(tokenName) {
+ return tokenName == "Builtin Object Token";
+}
+
+/**
+ * This class implements nsIBadCertListener. Its job is to prevent "bad cert"
+ * security dialogs from being shown to the user. It is better to simply fail
+ * if the certificate is bad. See bug 304286.
+ */
+function BadCertHandler() {
+}
+BadCertHandler.prototype = {
+
+ // nsIChannelEventSink
+ onChannelRedirect: function(oldChannel, newChannel, flags) {
+ // make sure the certificate of the old channel checks out before we follow
+ // a redirect from it. See bug 340198.
+ checkCert(oldChannel);
+ },
+
+ // Suppress any certificate errors
+ notifyCertProblem: function(socketInfo, status, targetSite) {
+ return true;
+ },
+
+ // Suppress any ssl errors
+ notifySSLError: function(socketInfo, error, targetSite) {
+ return true;
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ // nsISupports
+ QueryInterface: function(iid) {
+ if (!iid.equals(Components.interfaces.nsIChannelEventSink) &&
+ !iid.equals(Components.interfaces.nsIBadCertListener2) &&
+ !iid.equals(Components.interfaces.nsISSLErrorListener) &&
+ !iid.equals(Components.interfaces.nsIInterfaceRequestor) &&
+ !iid.equals(Components.interfaces.nsISupports))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ return this;
+ }
+};
+//@line 196 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+
+/**
+ * Creates a Version Checker object.
+ * @returns A handle to the global Version Checker service.
+ */
+function getVersionChecker() {
+ if (!gVersionChecker) {
+ gVersionChecker = Cc["@mozilla.org/xpcom/version-comparator;1"].
+ getService(Ci.nsIVersionComparator);
+ }
+ return gVersionChecker;
+}
+
+var BundleManager = {
+ /**
+ * Creates and returns a String Bundle at the specified URI
+ * @param bundleURI
+ * The URI of the bundle to load
+ * @returns A nsIStringBundle which was retrieved.
+ */
+ getBundle: function BundleManager_getBundle(bundleURI) {
+ var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ return sbs.createBundle(bundleURI);
+ },
+
+ _appName: "",
+
+ /**
+ * The Application's display name.
+ */
+ get appName() {
+ if (!this._appName) {
+ var brandBundle = this.getBundle(URI_BRAND_PROPERTIES)
+ this._appName = brandBundle.GetStringFromName("brandShortName");
+ }
+ return this._appName;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Utility Functions
+//
+function EM_NS(property) {
+ return PREFIX_NS_EM + property;
+}
+
+function CHROME_NS(property) {
+ return PREFIX_NS_CHROME + property;
+}
+
+function EM_R(property) {
+ return gRDF.GetResource(EM_NS(property));
+}
+
+function EM_L(literal) {
+ return gRDF.GetLiteral(literal);
+}
+
+function EM_I(integer) {
+ return gRDF.GetIntLiteral(integer);
+}
+
+function EM_D(integer) {
+ return gRDF.GetDateLiteral(integer);
+}
+
+/**
+ * Gets a preference value, handling the case where there is no default.
+ * @param func
+ * The name of the preference function to call, on nsIPrefBranch
+ * @param preference
+ * The name of the preference
+ * @param defaultValue
+ * The default value to return in the event the preference has
+ * no setting
+ * @returns The value of the preference, or undefined if there was no
+ * user or default value.
+ */
+function getPref(func, preference, defaultValue) {
+ try {
+ return gPref[func](preference);
+ }
+ catch (e) {
+ }
+ return defaultValue;
+}
+
+/**
+ * Initializes a RDF Container at a URI in a datasource.
+ * @param datasource
+ * The datasource the container is in
+ * @param root
+ * The RDF Resource which is the root of the container.
+ * @returns The nsIRDFContainer, initialized at the root.
+ */
+function getContainer(datasource, root) {
+ var ctr = Cc["@mozilla.org/rdf/container;1"].
+ createInstance(Ci.nsIRDFContainer);
+ ctr.Init(datasource, root);
+ return ctr;
+}
+
+/**
+ * Gets a RDF Resource for item with the given ID
+ * @param id
+ * The GUID of the item to construct a RDF resource to the
+ * active item for
+ * @returns The RDF Resource to the Active item.
+ */
+function getResourceForID(id) {
+ return gRDF.GetResource(PREFIX_ITEM_URI + id);
+}
+
+/**
+ * Construct a nsIUpdateItem with the supplied metadata
+ * ...
+ */
+function makeItem(id, version, locationKey, minVersion, maxVersion, name,
+ updateURL, updateHash, iconURL, updateRDF, updateKey, type,
+ targetAppID) {
+ var item = new UpdateItem();
+ item.init(id, version, locationKey, minVersion, maxVersion, name,
+ updateURL, updateHash, iconURL, updateRDF, updateKey, type,
+ targetAppID);
+ return item;
+}
+
+/**
+ * Gets the specified directory at the specified hierarchy under a
+ * Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|
+ * @return nsIFile object for the location specified. If the directory
+ * requested does not exist, it is created, along with any
+ * parent directories that need to be created.
+ */
+function getDir(key, pathArray) {
+ return getDirInternal(key, pathArray, true);
+}
+
+/**
+ * Gets the specified directory at the specified hierarchy under a
+ * Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|
+ * @return nsIFile object for the location specified. If the directory
+ * requested does not exist, it is NOT created.
+ */
+function getDirNoCreate(key, pathArray) {
+ return getDirInternal(key, pathArray, false);
+}
+
+/**
+ * Gets the specified directory at the specified hierarchy under a
+ * Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|
+ * @param shouldCreate
+ * true if the directory hierarchy specified in |pathArray|
+ * should be created if it does not exist,
+ * false otherwise.
+ * @return nsIFile object for the location specified.
+ */
+function getDirInternal(key, pathArray, shouldCreate) {
+ if (!gDirService) {
+ gDirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ }
+
+ var dir = gDirService.get(key, Ci.nsILocalFile);
+ for (var i = 0; i < pathArray.length; ++i) {
+ dir.append(pathArray[i]);
+ if (shouldCreate && !dir.exists())
+ dir.create(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ }
+ dir.followLinks = false;
+ return dir;
+}
+
+/**
+ * Gets the file at the specified hierarchy under a Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|. The last item in this array must be the
+ * leaf name of a file.
+ * @return nsIFile object for the file specified. The file is NOT created
+ * if it does not exist, however all required directories along
+ * the way are.
+ */
+function getFile(key, pathArray) {
+ var file = getDir(key, pathArray.slice(0, -1));
+ file.append(pathArray[pathArray.length - 1]);
+ return file;
+}
+
+/**
+ * Gets the descriptor of a directory as a relative path to common base
+ * directories (profile, user home, app install dir, etc).
+ *
+ * @param itemLocation
+ * The nsILocalFile representing the item's directory.
+ * @param installLocation the nsIInstallLocation for this item
+ */
+function getDescriptorFromFile(itemLocation, installLocation) {
+ var baseDir = installLocation.location;
+
+ if (baseDir && baseDir.contains(itemLocation, true)) {
+ return "rel%" + itemLocation.getRelativeDescriptor(baseDir);
+ }
+
+ return "abs%" + itemLocation.persistentDescriptor;
+}
+
+function getAbsoluteDescriptor(itemLocation) {
+ return itemLocation.persistentDescriptor;
+}
+
+/**
+ * Initializes a Local File object based on a descriptor
+ * provided by "getDescriptorFromFile".
+ *
+ * @param descriptor
+ * The descriptor that locates the directory
+ * @param installLocation
+ * The nsIInstallLocation object for this item.
+ * @returns The nsILocalFile object representing the location of the item
+ */
+function getFileFromDescriptor(descriptor, installLocation) {
+ var location = Cc["@mozilla.org/file/local;1"].
+ createInstance(Ci.nsILocalFile);
+
+ var m = descriptor.match(/^(abs|rel)\%(.*)$/);
+ if (!m)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ if (m[1] == "rel") {
+ location.setRelativeDescriptor(installLocation.location, m[2]);
+ }
+ else {
+ location.persistentDescriptor = m[2];
+ }
+
+ return location;
+}
+
+/**
+ * Determines if a file is an item package - either a XPI or a JAR file.
+ * @param file
+ * The file to check
+ * @returns true if the file is an item package, false otherwise.
+ */
+function fileIsItemPackage(file) {
+ var fileURL = getURIFromFile(file);
+ if (fileURL instanceof Ci.nsIURL)
+ var extension = fileURL.fileExtension.toLowerCase();
+ return extension == "xpi" || extension == "jar";
+}
+
+/**
+ * Opens a safe file output stream for writing.
+ * @param file
+ * The file to write to.
+ * @param modeFlags
+ * (optional) File open flags. Can be undefined.
+ * @returns nsIFileOutputStream to write to.
+ */
+function openSafeFileOutputStream(file, modeFlags) {
+ var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ if (modeFlags === undefined)
+ modeFlags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
+ if (!file.exists())
+ file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ fos.init(file, modeFlags, PERMS_FILE, 0);
+ return fos;
+}
+
+/**
+ * Closes a safe file output stream.
+ * @param stream
+ * The stream to close.
+ */
+function closeSafeFileOutputStream(stream) {
+ if (stream instanceof Ci.nsISafeOutputStream)
+ stream.finish();
+ else
+ stream.close();
+}
+
+/**
+ * Deletes a directory and its children. First it tries nsIFile::Remove(true).
+ * If that fails it will fall back to recursing, setting the appropriate
+ * permissions, and deleting the current entry. This is needed for when we have
+ * rights to delete a directory but there are entries that have a read-only
+ * attribute (e.g. a copy restore from a read-only CD, etc.)
+ * @param dir
+ * A nsIFile for the directory to be deleted
+ */
+function removeDirRecursive(dir) {
+ try {
+ dir.remove(true);
+ return;
+ }
+ catch (e) {
+ }
+
+ var dirEntries = dir.directoryEntries;
+ while (dirEntries.hasMoreElements()) {
+ var entry = dirEntries.getNext().QueryInterface(Ci.nsIFile);
+
+ if (entry.isDirectory()) {
+ removeDirRecursive(entry);
+ }
+ else {
+ entry.permissions = PERMS_FILE;
+ entry.remove(false);
+ }
+ }
+ dir.permissions = PERMS_DIRECTORY;
+ dir.remove(true);
+}
+
+/**
+ * Logs a string to the error console.
+ * @param string
+ * The string to write to the error console.
+ */
+function LOG(string) {
+ if (gLoggingEnabled) {
+ dump("*** " + string + "\n");
+ if (gConsole)
+ gConsole.logStringMessage(string);
+ }
+}
+
+/**
+ * Logs a string to the error console and to a permanent log file.
+ * @param string
+ * The string to write out.
+ */
+function ERROR(string) {
+ LOG(string);
+ try {
+ var tstamp = new Date();
+ var logfile = getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS_LOG]);
+ var stream = Cc["@mozilla.org/network/file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ stream.init(logfile, 0x02 | 0x08 | 0x10, 0666, 0); // write, create, append
+ var writer = Cc["@mozilla.org/intl/converter-output-stream;1"].
+ createInstance(Ci.nsIConverterOutputStream);
+ writer.init(stream, "UTF-8", 0, 0x0000);
+ string = tstamp.toLocaleFormat("%Y-%m-%d %H:%M:%S - ") + string;
+ writer.writeString(string + "\n");
+ writer.close();
+ }
+ catch (e) { }
+}
+
+/**
+ * Randomize the specified file name. Used to force RDF to bypass the cache
+ * when loading certain types of files.
+ * @param fileName
+ * A file name to randomize, e.g. install.rdf
+ * @returns A randomized file name, e.g. install-xyz.rdf
+ */
+function getRandomFileName(fileName) {
+ var extensionDelimiter = fileName.lastIndexOf(".");
+ var prefix = fileName.substr(0, extensionDelimiter);
+ var suffix = fileName.substr(extensionDelimiter);
+
+ var characters = "abcdefghijklmnopqrstuvwxyz0123456789";
+ var nameString = prefix + "-";
+ for (var i = 0; i < 3; ++i) {
+ var index = Math.round((Math.random()) * characters.length);
+ nameString += characters.charAt(index);
+ }
+ return nameString + "." + suffix;
+}
+
+/**
+ * Get the RDF URI prefix of a nsIUpdateItem type. This function should be used
+ * ONLY to support Firefox 1.0 Update RDF files! Item URIs in the datasource
+ * are NOT prefixed.
+ * @param type
+ * The nsIUpdateItem type to find a RDF URI prefix for
+ * @returns The RDF URI prefix.
+ */
+function getItemPrefix(type) {
+ if (type & Ci.nsIUpdateItem.TYPE_EXTENSION)
+ return PREFIX_EXTENSION;
+ else if (type & Ci.nsIUpdateItem.TYPE_THEME)
+ return PREFIX_THEME;
+ return PREFIX_ITEM_URI;
+}
+
+/**
+ * Trims a prefix from a string.
+ * @param string
+ * The source string
+ * @param prefix
+ * The prefix to remove.
+ * @returns The suffix (string - prefix)
+ */
+function stripPrefix(string, prefix) {
+ return string.substr(prefix.length);
+}
+
+/**
+ * Gets a File URL spec for a nsIFile
+ * @param file
+ * The file to get a file URL spec to
+ * @returns The file URL spec to the file
+ */
+function getURLSpecFromFile(file) {
+ var ioServ = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var fph = ioServ.getProtocolHandler("file")
+ .QueryInterface(Ci.nsIFileProtocolHandler);
+ return fph.getURLSpecFromFile(file);
+}
+
+/**
+ * Constructs a URI to a spec.
+ * @param spec
+ * The spec to construct a URI to
+ * @returns The nsIURI constructed.
+ */
+function newURI(spec) {
+ var ioServ = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return ioServ.newURI(spec, null, null);
+}
+
+/**
+ * Constructs a File URI to a nsIFile
+ * @param file
+ * The file to construct a File URI to
+ * @returns The file URI to the file
+ */
+function getURIFromFile(file) {
+ var ioServ = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return ioServ.newFileURI(file);
+}
+
+/**
+ * @returns Whether or not we are currently running in safe mode.
+ */
+function inSafeMode() {
+ return gApp.inSafeMode;
+}
+
+/**
+ * Extract the string value from a RDF Literal or Resource
+ * @param literalOrResource
+ * RDF String Literal or Resource
+ * @returns String value of the literal or resource, or undefined if the object
+ * supplied is not a RDF string literal or resource.
+ */
+function stringData(literalOrResource) {
+ if (literalOrResource instanceof Ci.nsIRDFLiteral)
+ return literalOrResource.Value;
+ if (literalOrResource instanceof Ci.nsIRDFResource)
+ return literalOrResource.Value;
+ return undefined;
+}
+
+/**
+ * Extract the integer value of a RDF Literal
+ * @param literal
+ * nsIRDFInt literal
+ * @return integer value of the literal
+ */
+function intData(literal) {
+ if (literal instanceof Ci.nsIRDFInt)
+ return literal.Value;
+ return undefined;
+}
+
+/**
+ * Gets a property from an install manifest.
+ * @param installManifest
+ * An Install Manifest datasource to read from
+ * @param property
+ * The name of a proprety to read (sans EM_NS)
+ * @returns The literal value of the property, or undefined if the property has
+ * no value.
+ */
+function getManifestProperty(installManifest, property) {
+ var target = installManifest.GetTarget(gInstallManifestRoot,
+ gRDF.GetResource(EM_NS(property)), true);
+ var val = stringData(target);
+ return val === undefined ? intData(target) : val;
+}
+
+/**
+ * Given an Install Manifest Datasource, retrieves the type of item the manifest
+ * describes.
+ * @param installManifest
+ * The Install Manifest Datasource.
+ * @return The nsIUpdateItem type of the item described by the manifest
+ * returns TYPE_EXTENSION if attempts to determine the type fail.
+ */
+function getAddonTypeFromInstallManifest(installManifest) {
+ var target = installManifest.GetTarget(gInstallManifestRoot,
+ gRDF.GetResource(EM_NS("type")), true);
+ if (target) {
+ var type = stringData(target);
+ return type === undefined ? intData(target) : parseInt(type);
+ }
+
+ // Firefox 1.0 and earlier did not support addon-type annotation on the
+ // Install Manifest, so we fall back to a theme-only property to
+ // differentiate.
+ if (getManifestProperty(installManifest, "internalName") !== undefined)
+ return Ci.nsIUpdateItem.TYPE_THEME;
+
+ // If no type is provided, default to "Extension"
+ return Ci.nsIUpdateItem.TYPE_EXTENSION;
+}
+
+/**
+ * Shows a message about an incompatible Extension/Theme.
+ * @param installData
+ * An Install Data object from |getInstallData|
+ */
+function showIncompatibleError(installData) {
+ var extensionStrings = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ var params = [extensionStrings.GetStringFromName("type-" + installData.type)];
+ var title = extensionStrings.formatStringFromName("incompatibleTitle",
+ params, params.length);
+ params = [installData.name, installData.version, BundleManager.appName,
+ gApp.version];
+ var message = extensionStrings.formatStringFromName("incompatibleMessage",
+ params, params.length);
+ var ps = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Ci.nsIPromptService);
+ ps.alert(null, title, message);
+}
+
+/**
+ * Shows a message.
+ * @param titleKey
+ * String key of the title string in the Extensions localization file.
+ * @param messageKey
+ * String key of the message string in the Extensions localization file.
+ * @param messageParams
+ * Array of strings to be substituted into |messageKey|. Can be null.
+ */
+function showMessage(titleKey, titleParams, messageKey, messageParams) {
+ var extensionStrings = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ if (titleParams && titleParams.length > 0) {
+ var title = extensionStrings.formatStringFromName(titleKey, titleParams,
+ titleParams.length);
+ }
+ else
+ title = extensionStrings.GetStringFromName(titleKey);
+
+ if (messageParams && messageParams.length > 0) {
+ var message = extensionStrings.formatStringFromName(messageKey, messageParams,
+ messageParams.length);
+ }
+ else
+ message = extensionStrings.GetStringFromName(messageKey);
+ var ps = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Ci.nsIPromptService);
+ ps.alert(null, title, message);
+}
+
+/**
+ * Shows a dialog for a blocklisted item. For soft blocked items this will
+ * return true if the item should still be installed
+ * @param item
+ * The nsIUpdateItem that is blocklisted
+ * @param softblocked
+ * True if this item is only soft blocked and may still be installed.
+ */
+function showBlocklistMessage(item, softblocked) {
+ var params = Cc["@mozilla.org/embedcomp/dialogparam;1"].
+ createInstance(Ci.nsIDialogParamBlock);
+ params.SetInt(0, softblocked ? 1 : 0);
+ params.SetInt(1, 0);
+ params.SetNumberStrings(1);
+ params.SetString(0, item.name + " " + item.version);
+
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ var win = wm.getMostRecentWindow("Extension:Manager");
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(win, URI_EXTENSION_LIST_DIALOG, "",
+ "chrome,centerscreen,modal,dialog,titlebar", params);
+
+ return params.GetInt(1) == 0 ? false : true;
+}
+
+/**
+ * Gets a zip reader for the file specified.
+ * @param zipFile
+ * A ZIP archive to open with a nsIZipReader.
+ * @return A nsIZipReader for the file specified.
+ */
+function getZipReaderForFile(zipFile) {
+ try {
+ var zipReader = Cc["@mozilla.org/libjar/zip-reader;1"].
+ createInstance(Ci.nsIZipReader);
+ zipReader.open(zipFile);
+ }
+ catch (e) {
+ zipReader.close();
+ throw e;
+ }
+ return zipReader;
+}
+
+/**
+ * Extract a RDF file from a ZIP archive to a random location in the system
+ * temp directory.
+ * @param zipFile
+ * A ZIP archive to read from
+ * @param fileName
+ * The name of the file to read from the zip.
+ * @param suppressErrors
+ * Whether or not to report errors.
+ * @return The file created in the temp directory.
+ */
+function extractRDFFileToTempDir(zipFile, fileName, suppressErrors) {
+ var file = getFile(KEY_TEMPDIR, [getRandomFileName(fileName)]);
+ try {
+ var zipReader = getZipReaderForFile(zipFile);
+ zipReader.extract(fileName, file);
+ zipReader.close();
+ }
+ catch (e) {
+ if (!suppressErrors) {
+ showMessage("missingFileTitle", [], "missingFileMessage",
+ [BundleManager.appName, fileName]);
+ throw e;
+ }
+ }
+ return file;
+}
+
+/**
+ * Gets an Install Manifest datasource from a file.
+ * @param file
+ * The nsIFile that contains the Install Manifest RDF
+ * @returns The Install Manifest datasource
+ */
+function getInstallManifest(file) {
+ var uri = getURIFromFile(file);
+ try {
+ var fis = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ fis.init(file, -1, -1, false);
+ var bis = Cc["@mozilla.org/network/buffered-input-stream;1"].
+ createInstance(Ci.nsIBufferedInputStream);
+ bis.init(fis, 4096);
+
+ var rdfParser = Cc["@mozilla.org/rdf/xml-parser;1"].
+ createInstance(Ci.nsIRDFXMLParser)
+ var ds = Cc["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].
+ createInstance(Ci.nsIRDFDataSource);
+ var listener = rdfParser.parseAsync(ds, uri);
+ var channel = Cc["@mozilla.org/network/input-stream-channel;1"].
+ createInstance(Ci.nsIInputStreamChannel);
+ channel.setURI(uri);
+ channel.contentStream = bis;
+ channel.QueryInterface(Ci.nsIChannel);
+ channel.contentType = "text/xml";
+
+ listener.onStartRequest(channel, null);
+ try {
+ var pos = 0;
+ var count = bis.available();
+ while (count > 0) {
+ listener.onDataAvailable(channel, null, bis, pos, count);
+ pos += count;
+ count = bis.available();
+ }
+ listener.onStopRequest(channel, null, Components.results.NS_OK);
+ bis.close();
+ fis.close();
+
+ var arcs = ds.ArcLabelsOut(gInstallManifestRoot);
+ if (arcs.hasMoreElements())
+ return ds;
+ }
+ catch (e) {
+ listener.onStopRequest(channel, null, e.result);
+ bis.close();
+ fis.close();
+ }
+ }
+ catch (e) { }
+
+ var url = uri.QueryInterface(Ci.nsIURL);
+ showMessage("malformedTitle", [], "malformedMessage",
+ [BundleManager.appName, url.fileName]);
+ return null;
+}
+
+/**
+ * Selects the closest matching localized resource in the given RDF resource
+ * @param aDataSource The datasource to look in
+ * @param aResource The root resource containing the localized sections
+ * @returns The nsIRDFResource of the best em:localized section or null
+ * if no valid match was found
+ */
+function findClosestLocalizedResource(aDataSource, aResource) {
+ var localizedProp = EM_R("localized");
+ var localeProp = EM_R("locale");
+
+ // Holds the best matching localized resource
+ var bestmatch = null;
+ // The number of locale parts it matched with
+ var bestmatchcount = 0;
+ // The number of locale parts in the match
+ var bestpartcount = 0;
+
+ var locales = [gLocale.toLowerCase()];
+ /* If the current locale is English then it will find a match if there is
+ a valid match for en-US so no point searching that locale too. */
+ if (locales[0].substring(0, 3) != "en-")
+ locales.push("en-us");
+
+ for each (var locale in locales) {
+ var lparts = locale.split("-");
+ var localizations = aDataSource.GetTargets(aResource, localizedProp, true);
+ while (localizations.hasMoreElements()) {
+ var localized = localizations.getNext().QueryInterface(Ci.nsIRDFNode);
+ var list = aDataSource.GetTargets(localized, localeProp, true);
+ while (list.hasMoreElements()) {
+ var found = stringData(list.getNext().QueryInterface(Ci.nsIRDFNode));
+ if (!found)
+ continue;
+
+ found = found.toLowerCase();
+
+ // Exact match is returned immediately
+ if (locale == found)
+ return localized;
+
+ var fparts = found.split("-");
+ /* If we have found a possible match and this one isn't any longer
+ then we dont need to check further. */
+ if (bestmatch && fparts.length < bestmatchcount)
+ continue;
+
+ // Count the number of parts that match
+ var maxmatchcount = Math.min(fparts.length, lparts.length);
+ var matchcount = 0;
+ while (matchcount < maxmatchcount &&
+ fparts[matchcount] == lparts[matchcount])
+ matchcount++;
+
+ /* If we matched more than the last best match or matched the same and
+ this locale is less specific than the last best match. */
+ if (matchcount > bestmatchcount ||
+ (matchcount == bestmatchcount && fparts.length < bestpartcount)) {
+ bestmatch = localized;
+ bestmatchcount = matchcount;
+ bestpartcount = fparts.length;
+ }
+ }
+ }
+ // If we found a valid match for this locale return it
+ if (bestmatch)
+ return bestmatch;
+ }
+ return null;
+}
+
+/**
+ * An enumeration of items in a JS array.
+ * @constructor
+ */
+function ArrayEnumerator(aItems) {
+ if (aItems) {
+ for (var i = 0; i < aItems.length; ++i) {
+ if (!aItems[i])
+ aItems.splice(i--, 1);
+ }
+ this._contents = aItems;
+ } else {
+ this._contents = [];
+ }
+}
+
+ArrayEnumerator.prototype = {
+ _index: 0,
+
+ hasMoreElements: function ArrayEnumerator_hasMoreElements() {
+ return this._index < this._contents.length;
+ },
+
+ getNext: function ArrayEnumerator_getNext() {
+ return this._contents[this._index++];
+ }
+};
+
+/**
+ * An enumeration of files in a JS array.
+ * @param files
+ * The files to enumerate
+ * @constructor
+ */
+function FileEnumerator(files) {
+ if (files) {
+ for (var i = 0; i < files.length; ++i) {
+ if (!files[i])
+ files.splice(i--, 1);
+ }
+ this._contents = files;
+ } else {
+ this._contents = [];
+ }
+}
+
+FileEnumerator.prototype = {
+ _index: 0,
+
+ /**
+ * Gets the next file in the sequence.
+ */
+ get nextFile() {
+ if (this._index < this._contents.length)
+ return this._contents[this._index++];
+ return null;
+ },
+
+ /**
+ * Stop enumerating. Nothing to do here.
+ */
+ close: function FileEnumerator_close() {
+ }
+};
+
+/**
+ * An object which identifies an Install Location for items, where the location
+ * relationship is each item living in a directory named with its GUID under
+ * the directory used when constructing this object.
+ *
+ * e.g. <location>\{GUID1}
+ * <location>\{GUID2}
+ * <location>\{GUID3}
+ * ...
+ *
+ * @param name
+ * The string identifier of this Install Location.
+ * @param location
+ * The directory that contains the items.
+ * @constructor
+ */
+function DirectoryInstallLocation(name, location, restricted, priority, independent) {
+ this._name = name;
+ if (location.exists()) {
+ if (!location.isDirectory())
+ throw new Error("location must be a directoy!");
+ }
+ else {
+ try {
+ location.create(Ci.nsILocalFile.DIRECTORY_TYPE, 0775);
+ }
+ catch (e) {
+ LOG("DirectoryInstallLocation: failed to create location " +
+ " directory = " + location.path + ", exception = " + e + "\n");
+ }
+ }
+
+ this._location = location;
+ this._locationToIDMap = {};
+ this._restricted = restricted;
+ this._priority = priority;
+ this._independent = independent;
+}
+DirectoryInstallLocation.prototype = {
+ _name : "",
+ _location : null,
+ _locationToIDMap: null,
+ _restricted : false,
+ _priority : 0,
+ _independent : false,
+ _canAccess : null,
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ get name() {
+ return this._name;
+ },
+
+ /**
+ * Reads a directory linked to in a file.
+ * @param file
+ * The file containing the directory path
+ * @returns A nsILocalFile object representing the linked directory.
+ */
+ _readDirectoryFromFile: function DirInstallLocation__readDirectoryFromFile(file) {
+ var fis = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ fis.init(file, -1, -1, false);
+ var line = { value: "" };
+ if (fis instanceof Ci.nsILineInputStream)
+ fis.readLine(line);
+ fis.close();
+ if (line.value) {
+ var linkedDirectory = Cc["@mozilla.org/file/local;1"].
+ createInstance(Ci.nsILocalFile);
+ try {
+ linkedDirectory.initWithPath(line.value);
+ }
+ catch (e) {
+ linkedDirectory.setRelativeDescriptor(file.parent, line.value);
+ }
+
+ return linkedDirectory;
+ }
+ return null;
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ get itemLocations() {
+ var locations = [];
+ if (!this._location.exists())
+ return new FileEnumerator(locations);
+
+ try {
+ var entries = this._location.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
+ while (true) {
+ var entry = entries.nextFile;
+ if (!entry)
+ break;
+ entry instanceof Ci.nsILocalFile;
+ if (!entry.isDirectory() && gIDTest.test(entry.leafName)) {
+ var linkedDirectory = this._readDirectoryFromFile(entry);
+ if (linkedDirectory && linkedDirectory.exists() &&
+ linkedDirectory.isDirectory()) {
+ locations.push(linkedDirectory);
+ this._locationToIDMap[linkedDirectory.persistentDescriptor] = entry.leafName;
+ }
+ }
+ else
+ locations.push(entry);
+ }
+ entries.close();
+ }
+ catch (e) {
+ }
+ return new FileEnumerator(locations);
+ },
+
+ /**
+ * Retrieves the GUID for an item at the specified location.
+ * @param file
+ * The location where an item might live.
+ * @returns The ID for an item that might live at the location specified.
+ *
+ * N.B. This function makes no promises about whether or not this path is
+ * actually maintained by this Install Location.
+ */
+ getIDForLocation: function DirInstallLocation_getIDForLocation(file) {
+ var section = file.leafName;
+ var filePD = file.persistentDescriptor;
+ if (filePD in this._locationToIDMap)
+ section = this._locationToIDMap[filePD];
+
+ if (gIDTest.test(section))
+ return RegExp.$1;
+ return undefined;
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ get location() {
+ return this._location.clone();
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ get restricted() {
+ return this._restricted;
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ get canAccess() {
+ if (this._canAccess != null)
+ return this._canAccess;
+
+ if (!this.location.exists()) {
+ this._canAccess = false;
+ return false;
+ }
+
+ var testFile = this.location;
+ testFile.append("Access Privileges Test");
+ try {
+ testFile.createUnique(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ testFile.remove(false);
+ this._canAccess = true;
+ }
+ catch (e) {
+ this._canAccess = false;
+ }
+ return this._canAccess;
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ get priority() {
+ return this._priority;
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ getItemLocation: function DirInstallLocation_getItemLocation(id) {
+ var itemLocation = this.location;
+ itemLocation.append(id);
+ if (itemLocation.exists() && !itemLocation.isDirectory())
+ return this._readDirectoryFromFile(itemLocation);
+ if (!itemLocation.exists() && this.canAccess)
+ itemLocation.create(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ return itemLocation;
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ itemIsManagedIndependently: function DirInstallLocation_itemIsManagedIndependently(id) {
+ if (this._independent)
+ return true;
+ var itemLocation = this.location;
+ itemLocation.append(id);
+ return itemLocation.exists() && !itemLocation.isDirectory();
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ getItemFile: function DirInstallLocation_getItemFile(id, filePath) {
+ var itemLocation = this.getItemLocation(id).clone();
+ var parts = filePath.split("/");
+ for (var i = 0; i < parts.length; ++i)
+ itemLocation.append(parts[i]);
+ return itemLocation;
+ },
+
+ /**
+ * Stages the specified file for later.
+ * @param file
+ * The file to stage
+ * @param id
+ * The GUID of the item the file represents
+ */
+ stageFile: function DirInstallLocation_stageFile(file, id) {
+ var stagedFile = this.location;
+ stagedFile.append(DIR_STAGE);
+ stagedFile.append(id);
+ stagedFile.append(file.leafName);
+
+ // When an incompatible update is successful the file is already staged
+ if (stagedFile.equals(file))
+ return stagedFile;
+
+ if (stagedFile.exists())
+ stagedFile.remove(false);
+
+ file.copyTo(stagedFile.parent, stagedFile.leafName);
+
+ // If the file has incorrect permissions set, correct them now.
+ if (!stagedFile.isWritable())
+ stagedFile.permissions = PERMS_FILE;
+
+ return stagedFile;
+ },
+
+ /**
+ * Returns the most recently staged package (e.g. the last XPI or JAR in a
+ * directory) for an item and removes items that do not qualify.
+ * @param id
+ * The ID of the staged package
+ * @returns an nsIFile if the package exists otherwise null.
+ */
+ getStageFile: function DirInstallLocation_getStageFile(id) {
+ var stageFile = null;
+ var stageDir = this.location;
+ stageDir.append(DIR_STAGE);
+ stageDir.append(id);
+ if (!stageDir.exists() || !stageDir.isDirectory())
+ return null;
+ try {
+ var entries = stageDir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
+ while (entries.hasMoreElements()) {
+ var file = entries.nextFile;
+ if (!(file instanceof Ci.nsILocalFile))
+ continue;
+ if (file.isDirectory())
+ removeDirRecursive(file);
+ else if (fileIsItemPackage(file)) {
+ if (stageFile)
+ stageFile.remove(false);
+ stageFile = file;
+ }
+ else
+ file.remove(false);
+ }
+ }
+ catch (e) {
+ }
+ if (entries instanceof Ci.nsIDirectoryEnumerator)
+ entries.close();
+ return stageFile;
+ },
+
+ /**
+ * Removes a file from the stage. This cleans up the stage if there is nothing
+ * else left after the remove operation.
+ * @param file
+ * The file to remove.
+ */
+ removeFile: function DirInstallLocation_removeFile(file) {
+ if (file.exists())
+ file.remove(false);
+ var parent = file.parent;
+ var entries = parent.directoryEntries;
+ try {
+ // XXXrstrong calling hasMoreElements on a nsIDirectoryEnumerator after
+ // it has been removed will cause a crash on Mac OS X - bug 292823
+ while (parent && !parent.equals(this.location) &&
+ !entries.hasMoreElements()) {
+ parent.remove(false);
+ parent = parent.parent;
+ entries = parent.directoryEntries;
+ }
+ if (entries instanceof Ci.nsIDirectoryEnumerator)
+ entries.close();
+ }
+ catch (e) {
+ ERROR("DirectoryInstallLocation::removeFile: failed to remove staged " +
+ " directory = " + parent.path + ", exception = " + e + "\n");
+ }
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIInstallLocation])
+};
+
+//@line 1509 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+
+/**
+ * An object which handles the installation of an Extension.
+ * @constructor
+ */
+function Installer(ds, id, installLocation, type) {
+ this._ds = ds;
+ this._id = id;
+ this._type = type;
+ this._installLocation = installLocation;
+}
+Installer.prototype = {
+ // Item metadata
+ _id: null,
+ _ds: null,
+ _installLocation: null,
+ _metadataDS: null,
+
+ /**
+ * Gets the Install Manifest datasource we are installing from.
+ */
+ get metadataDS() {
+ if (!this._metadataDS) {
+ var metadataFile = this._installLocation
+ .getItemFile(this._id, FILE_INSTALL_MANIFEST);
+ if (!metadataFile.exists())
+ return null;
+ this._metadataDS = getInstallManifest(metadataFile);
+ if (!this._metadataDS) {
+ LOG("Installer::install: metadata datasource for extension " +
+ this._id + " at " + metadataFile.path + " could not be loaded. " +
+ " Installation will not proceed.");
+ }
+ }
+ return this._metadataDS;
+ },
+
+ /**
+ * Installs the Extension
+ * @param file
+ * A XPI/JAR file to install from. If this is null or does not exist,
+ * the item is assumed to be an expanded directory, located at the GUID
+ * key in the supplied Install Location.
+ */
+ installFromFile: function Installer_installFromFile(file) {
+ // Move files from the staging dir into the extension's final home.
+ if (file && file.exists()) {
+ this._installExtensionFiles(file);
+ }
+
+ if (!this.metadataDS)
+ return;
+
+ // Upgrade old-style contents.rdf Chrome Manifests if necessary.
+ if (this._type == Ci.nsIUpdateItem.TYPE_THEME)
+ this.upgradeThemeChrome();
+ else
+ this.upgradeExtensionChrome();
+
+ // Add metadata for the extension to the global extension metadata set
+ this._ds.addItemMetadata(this._id, this.metadataDS, this._installLocation);
+ },
+
+ /**
+ * Safely extract the Extension's files into the target folder.
+ * @param file
+ * The XPI/JAR file to install from.
+ */
+ _installExtensionFiles: function Installer__installExtensionFiles(file) {
+ /**
+ * Callback for |safeInstallOperation| that performs file level installation
+ * steps for an Extension.
+ * @param extensionID
+ * The GUID of the Extension being installed.
+ * @param installLocation
+ * The Install Location where the Extension is being installed.
+ * @param xpiFile
+ * The source XPI file that contains the Extension.
+ */
+ function extractExtensionFiles(extensionID, installLocation, xpiFile) {
+ // Create a logger to log install operations for uninstall. This must be
+ // created in the |safeInstallOperation| callback, since it creates a file
+ // in the target directory. If we do this outside of the callback, we may
+ // be clobbering a file we should not be.
+ var zipReader = getZipReaderForFile(xpiFile);
+
+ // create directories first
+ var entries = zipReader.findEntries("*/");
+ while (entries.hasMore()) {
+ var entryName = entries.getNext();
+ var target = installLocation.getItemFile(extensionID, entryName);
+ if (!target.exists()) {
+ try {
+ target.create(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ }
+ catch (e) {
+ ERROR("extractExtensionsFiles: failed to create target directory for extraction " +
+ " file = " + target.path + ", exception = " + e + "\n");
+ }
+ }
+ }
+
+ entries = zipReader.findEntries(null);
+ while (entries.hasMore()) {
+ var entryName = entries.getNext();
+ target = installLocation.getItemFile(extensionID, entryName);
+ if (target.exists())
+ continue;
+
+ try {
+ target.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ }
+ catch (e) {
+ ERROR("extractExtensionsFiles: failed to create target file for extraction " +
+ " file = " + target.path + ", exception = " + e + "\n");
+ }
+ zipReader.extract(entryName, target);
+ }
+ zipReader.close();
+ }
+
+ /**
+ * Callback for |safeInstallOperation| that performs file level installation
+ * steps for a Theme.
+ * @param id
+ * The GUID of the Theme being installed.
+ * @param installLocation
+ * The Install Location where the Theme is being installed.
+ * @param jarFile
+ * The source JAR file that contains the Theme.
+ */
+ function extractThemeFiles(id, installLocation, jarFile) {
+ var themeDirectory = installLocation.getItemLocation(id);
+ var zipReader = getZipReaderForFile(jarFile);
+
+ // The only critical file is the install.rdf and we would not have
+ // gotten this far without one.
+ var rootFiles = [FILE_INSTALL_MANIFEST, FILE_CHROME_MANIFEST,
+ "preview.png", "icon.png"];
+ for (var i = 0; i < rootFiles.length; ++i) {
+ try {
+ var target = installLocation.getItemFile(id, rootFiles[i]);
+ zipReader.extract(rootFiles[i], target);
+ }
+ catch (e) {
+ }
+ }
+
+ var manifestFile = installLocation.getItemFile(id, FILE_CHROME_MANIFEST);
+ // new theme structure requires a chrome.manifest file
+ if (manifestFile.exists()) {
+ var entries = zipReader.findEntries(DIR_CHROME + "/*");
+ while (entries.hasMore()) {
+ var entryName = entries.getNext();
+ if (entryName.charAt(entryName.length - 1) == "/")
+ continue;
+ target = installLocation.getItemFile(id, entryName);
+ try {
+ target.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ }
+ catch (e) {
+ ERROR("extractThemeFiles: failed to create target file for extraction " +
+ " file = " + target.path + ", exception = " + e + "\n");
+ }
+ zipReader.extract(entryName, target);
+ }
+ zipReader.close();
+ }
+ else { // old theme structure requires only an install.rdf
+ try {
+ var contentsManifestFile = installLocation.getItemFile(id, FILE_CONTENTS_MANIFEST);
+ contentsManifestFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ zipReader.extract(FILE_CONTENTS_MANIFEST, contentsManifestFile);
+ }
+ catch (e) {
+ zipReader.close();
+ ERROR("extractThemeFiles: failed to extract contents.rdf: " + target.path);
+ throw e; // let the safe-op clean up
+ }
+ zipReader.close();
+ var chromeDir = installLocation.getItemFile(id, DIR_CHROME);
+ try {
+ jarFile.copyTo(chromeDir, jarFile.leafName);
+ }
+ catch (e) {
+ ERROR("extractThemeFiles: failed to copy theme JAR file to: " + chromeDir.path);
+ throw e; // let the safe-op clean up
+ }
+
+ if (!installer.metadataDS && installer._type == Ci.nsIUpdateItem.TYPE_THEME) {
+ var themeName = extensionStrings.GetStringFromName("incompatibleThemeName");
+ if (contentsManifestFile && contentsManifestFile.exists()) {
+ var contentsManifest = gRDF.GetDataSourceBlocking(getURLSpecFromFile(contentsManifestFile));
+ try {
+ var ctr = getContainer(contentsManifest,
+ gRDF.GetResource("urn:mozilla:skin:root"));
+ var elts = ctr.GetElements();
+ var nameArc = gRDF.GetResource(CHROME_NS("displayName"));
+ while (elts.hasMoreElements()) {
+ var elt = elts.getNext().QueryInterface(Ci.nsIRDFResource);
+ themeName = stringData(contentsManifest.GetTarget(elt, nameArc, true));
+ if (themeName)
+ break;
+ }
+ }
+ catch (e) {
+ themeName = extensionStrings.GetStringFromName("incompatibleThemeName");
+ }
+ }
+ showIncompatibleError({ name: themeName, version: "",
+ type: Ci.nsIUpdateItem.TYPE_THEME });
+ LOG("Theme JAR file: " + jarFile.leafName + " contains an Old-Style " +
+ "Theme that is not compatible with this version of the software.");
+ throw new Error("Old Theme"); // let the safe-op clean up
+ }
+ }
+ }
+
+ var installer = this;
+ var callback = extractExtensionFiles;
+ if (this._type == Ci.nsIUpdateItem.TYPE_THEME)
+ callback = extractThemeFiles;
+ safeInstallOperation(this._id, this._installLocation,
+ { callback: callback, data: file });
+ },
+
+ /**
+ * Upgrade contents.rdf Chrome Manifests used by this Theme to the new
+ * chrome.manifest format if necessary.
+ */
+ upgradeThemeChrome: function Installer_upgradeThemeChrome() {
+ // Use the Chrome Registry API to install the theme there
+ var cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
+ getService(Ci.nsIToolkitChromeRegistry);
+ var manifestFile = this._installLocation.getItemFile(this._id, FILE_CHROME_MANIFEST);
+ if (manifestFile.exists() ||
+ this._id == stripPrefix(RDFURI_DEFAULT_THEME, PREFIX_ITEM_URI))
+ return;
+
+ try {
+ // creates a chrome manifest for themes
+ var manifestURI = getURIFromFile(manifestFile);
+ var chromeDir = this._installLocation.getItemFile(this._id, DIR_CHROME);
+ // We're relying on the fact that there is only one JAR file
+ // in the "chrome" directory. This is a hack, but it works.
+ var entries = chromeDir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
+ var jarFile = entries.nextFile;
+ if (jarFile) {
+ var jarFileURI = getURIFromFile(jarFile);
+ var contentsURI = newURI("jar:" + jarFileURI.spec + "!/");
+ var contentsFile = this._installLocation.getItemFile(this._id, FILE_CONTENTS_MANIFEST);
+ var contentsFileURI = getURIFromFile(contentsFile.parent);
+
+ cr.processContentsManifest(contentsFileURI, manifestURI, contentsURI, false, true);
+ }
+ entries.close();
+ contentsFile.remove(false);
+ }
+ catch (e) {
+ // Failed to register chrome, for any number of reasons - non-existent
+ // contents.rdf file at the location specified, malformed contents.rdf,
+ // etc. Set the pending op to be OP_NEEDS_UNINSTALL so that the
+ // extension is uninstalled properly during the subsequent uninstall
+ // pass in |ExtensionManager::_finishOperations|
+ ERROR("upgradeThemeChrome: failed for theme " + this._id + " - why " +
+ "not convert to the new chrome.manifest format while you're at it? " +
+ "Failure exception: " + e);
+ showMessage("malformedRegistrationTitle", [], "malformedRegistrationMessage",
+ [BundleManager.appName]);
+
+ var stageFile = this._installLocation.getStageFile(this._id);
+ if (stageFile)
+ this._installLocation.removeFile(stageFile);
+
+ StartupCache.put(this._installLocation, this._id, OP_NEEDS_UNINSTALL, true);
+ StartupCache.write();
+ }
+ },
+
+ /**
+ * Upgrade contents.rdf Chrome Manifests used by this Extension to the new
+ * chrome.manifest format if necessary.
+ */
+ upgradeExtensionChrome: function Installer_upgradeExtensionChrome() {
+ // If the extension is aware of the new flat chrome manifests and has
+ // included one, just use it instead of generating one from the
+ // install.rdf/contents.rdf data.
+ var manifestFile = this._installLocation.getItemFile(this._id, FILE_CHROME_MANIFEST);
+ if (manifestFile.exists())
+ return;
+
+ try {
+ // Enumerate the metadata datasource files collection and register chrome
+ // for each file, calling _registerChrome for each.
+ var chromeDir = this._installLocation.getItemFile(this._id, DIR_CHROME);
+
+ if (!manifestFile.parent.exists())
+ return;
+
+ // Even if an extension doesn't have any chrome, we generate an empty
+ // manifest file so that we don't try to upgrade from the "old-style"
+ // chrome manifests at every startup.
+ manifestFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+
+ var manifestURI = getURIFromFile(manifestFile);
+ var files = this.metadataDS.GetTargets(gInstallManifestRoot, EM_R("file"), true);
+ while (files.hasMoreElements()) {
+ var file = files.getNext().QueryInterface(Ci.nsIRDFResource);
+ var chromeFile = chromeDir.clone();
+ var fileName = file.Value.substr("urn:mozilla:extension:file:".length, file.Value.length);
+ chromeFile.append(fileName);
+
+ var fileURLSpec = getURLSpecFromFile(chromeFile);
+ if (!chromeFile.isDirectory()) {
+ var zipReader = getZipReaderForFile(chromeFile);
+ fileURLSpec = "jar:" + fileURLSpec + "!/";
+ var contentsFile = this._installLocation.getItemFile(this._id, FILE_CONTENTS_MANIFEST);
+ contentsFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ }
+
+ var providers = [EM_R("package"), EM_R("skin"), EM_R("locale")];
+ for (var i = 0; i < providers.length; ++i) {
+ var items = this.metadataDS.GetTargets(file, providers[i], true);
+ while (items.hasMoreElements()) {
+ var item = items.getNext().QueryInterface(Ci.nsIRDFLiteral);
+ var fileURI = newURI(fileURLSpec + item.Value);
+ // Extract the contents.rdf files instead of opening them inside of
+ // the jar. This prevents the jar from being cached by the zip
+ // reader which will keep the jar in use and prevent deletion.
+ if (zipReader) {
+ zipReader.extract(item.Value + FILE_CONTENTS_MANIFEST, contentsFile);
+ var contentsFileURI = getURIFromFile(contentsFile.parent);
+ }
+ else
+ contentsFileURI = fileURI;
+
+ var cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
+ getService(Ci.nsIToolkitChromeRegistry);
+ cr.processContentsManifest(contentsFileURI, manifestURI, fileURI, true, false);
+ }
+ }
+ if (zipReader) {
+ zipReader.close();
+ zipReader = null;
+ contentsFile.remove(false);
+ }
+ }
+ }
+ catch (e) {
+ // Failed to register chrome, for any number of reasons - non-existent
+ // contents.rdf file at the location specified, malformed contents.rdf,
+ // etc. Set the pending op to be OP_NEEDS_UNINSTALL so that the
+ // extension is uninstalled properly during the subsequent uninstall
+ // pass in |ExtensionManager::_finishOperations|
+ ERROR("upgradeExtensionChrome: failed for extension " + this._id + " - why " +
+ "not convert to the new chrome.manifest format while you're at it? " +
+ "Failure exception: " + e);
+ showMessage("malformedRegistrationTitle", [], "malformedRegistrationMessage",
+ [BundleManager.appName]);
+
+ var stageFile = this._installLocation.getStageFile(this._id);
+ if (stageFile)
+ this._installLocation.removeFile(stageFile);
+
+ StartupCache.put(this._installLocation, this._id, OP_NEEDS_UNINSTALL, true);
+ StartupCache.write();
+ }
+ }
+};
+
+/**
+ * Safely attempt to perform a caller-defined install operation for a given
+ * item ID. Using aggressive success-safety checks, this function will attempt
+ * to move an existing location for an item aside and then allow installation
+ * into the appropriate folder. If any operation fails the installation will
+ * abort and roll back from the moved-aside old version.
+ * @param itemID
+ * The GUID of the item to perform the operation on.
+ * @param installLocation
+ * The Install Location where the item is installed.
+ * @param installCallback
+ * A caller supplied JS object with the following properties:
+ * "data" A data parameter to be passed to the callback.
+ * "callback" A function to perform the install operation. This
+ * function is passed three parameters:
+ * 1. The GUID of the item being operated on.
+ * 2. The Install Location where the item is installed.
+ * 3. The "data" parameter on the installCallback object.
+ */
+function safeInstallOperation(itemID, installLocation, installCallback) {
+ var movedFiles = [];
+
+ /**
+ * Reverts a deep move by moving backed up files back to their original
+ * location.
+ */
+ function rollbackMove()
+ {
+ for (var i = 0; i < movedFiles.length; ++i) {
+ var oldFile = movedFiles[i].oldFile;
+ var newFile = movedFiles[i].newFile;
+ try {
+ newFile.moveTo(oldFile.parent, newFile.leafName);
+ }
+ catch (e) {
+ ERROR("safeInstallOperation: failed to roll back files after an install " +
+ "operation failed. Failed to roll back: " + newFile.path + " to: " +
+ oldFile.path + " ... aborting installation.");
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * Moves a file to a new folder.
+ * @param file
+ * The file to move
+ * @param destination
+ * The target folder
+ */
+ function moveFile(file, destination) {
+ try {
+ var oldFile = file.clone();
+ file.moveTo(destination, file.leafName);
+ movedFiles.push({ oldFile: oldFile, newFile: file });
+ }
+ catch (e) {
+ ERROR("safeInstallOperation: failed to back up file: " + file.path + " to: " +
+ destination.path + " ... rolling back file moves and aborting " +
+ "installation.");
+ rollbackMove();
+ throw e;
+ }
+ }
+
+ /**
+ * Moves a directory to a new location. If any part of the move fails,
+ * files already moved will be rolled back.
+ * @param sourceDir
+ * The directory to move
+ * @param targetDir
+ * The destination directory
+ * @param currentDir
+ * The current directory (a subdirectory of |sourceDir| or
+ * |sourceDir| itself) we are moving files from.
+ */
+ function moveDirectory(sourceDir, targetDir, currentDir) {
+ var entries = currentDir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
+ while (true) {
+ var entry = entries.nextFile;
+ if (!entry)
+ break;
+ if (entry.isDirectory())
+ moveDirectory(sourceDir, targetDir, entry);
+ else if (entry instanceof Ci.nsILocalFile) {
+ var rd = entry.getRelativeDescriptor(sourceDir);
+ var destination = targetDir.clone().QueryInterface(Ci.nsILocalFile);
+ destination.setRelativeDescriptor(targetDir, rd);
+ moveFile(entry, destination.parent);
+ }
+ }
+ entries.close();
+ }
+
+ /**
+ * Removes the temporary backup directory where we stored files.
+ * @param directory
+ * The backup directory to remove
+ */
+ function cleanUpTrash(directory) {
+ try {
+ // Us-generated. Safe.
+ if (directory && directory.exists())
+ removeDirRecursive(directory);
+ }
+ catch (e) {
+ ERROR("safeInstallOperation: failed to clean up the temporary backup of the " +
+ "older version: " + itemLocationTrash.path);
+ // This is a non-fatal error. Annoying, but non-fatal.
+ }
+ }
+
+ if (!installLocation.itemIsManagedIndependently(itemID)) {
+ var itemLocation = installLocation.getItemLocation(itemID);
+ if (itemLocation.exists()) {
+ var trashDirName = itemID + "-trash";
+ var itemLocationTrash = itemLocation.parent.clone();
+ itemLocationTrash.append(trashDirName);
+ if (itemLocationTrash.exists()) {
+ // We can remove recursively here since this is a folder we created, not
+ // one the user specified. If this fails, it'll throw, and the caller
+ // should stop installation.
+ try {
+ removeDirRecursive(itemLocationTrash);
+ }
+ catch (e) {
+ ERROR("safeFileOperation: failed to remove existing trash directory " +
+ itemLocationTrash.path + " ... aborting installation.");
+ throw e;
+ }
+ }
+
+ // Move the directory that contains the existing version of the item aside,
+ // into {GUID}-trash. This will throw if there's a failure and the install
+ // will abort.
+ moveDirectory(itemLocation, itemLocationTrash, itemLocation);
+
+ // Clean up the original location, if necessary. Again, this is a path we
+ // generated, so it is safe to recursively delete.
+ try {
+ removeDirRecursive(itemLocation);
+ }
+ catch (e) {
+ ERROR("safeInstallOperation: failed to clean up item location after its contents " +
+ "were properly backed up. Failed to clean up: " + itemLocation.path +
+ " ... rolling back file moves and aborting installation.");
+ rollbackMove();
+ cleanUpTrash(itemLocationTrash);
+ throw e;
+ }
+ }
+ }
+ else if (installLocation.name == KEY_APP_PROFILE ||
+ installLocation.name == KEY_APP_GLOBAL ||
+ installLocation.name == KEY_APP_SYSTEM_USER) {
+ // Check for a pointer file and move it aside if it exists
+ var pointerFile = installLocation.location.clone();
+ pointerFile.append(itemID);
+ if (pointerFile.exists() && !pointerFile.isDirectory()) {
+ var trashFileName = itemID + "-trash";
+ var itemLocationTrash = installLocation.location.clone();
+ itemLocationTrash.append(trashFileName);
+ if (itemLocationTrash.exists()) {
+ // We can remove recursively here since this is a folder we created, not
+ // one the user specified. If this fails, it'll throw, and the caller
+ // should stop installation.
+ try {
+ removeDirRecursive(itemLocationTrash);
+ }
+ catch (e) {
+ ERROR("safeFileOperation: failed to remove existing trash directory " +
+ itemLocationTrash.path + " ... aborting installation.");
+ throw e;
+ }
+ }
+ itemLocationTrash.create(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ // Move the pointer file to the trash.
+ moveFile(pointerFile, itemLocationTrash);
+ }
+ }
+
+ // Now tell the client to do their stuff.
+ try {
+ installCallback.callback(itemID, installLocation, installCallback.data);
+ }
+ catch (e) {
+ // This means the install operation failed. Remove everything and roll back.
+ ERROR("safeInstallOperation: install operation (caller-supplied callback) failed, " +
+ "rolling back file moves and aborting installation.");
+ try {
+ // Us-generated. Safe.
+ removeDirRecursive(itemLocation);
+ }
+ catch (e) {
+ ERROR("safeInstallOperation: failed to remove the folder we failed to install " +
+ "an item into: " + itemLocation.path + " -- There is not much to suggest " +
+ "here... maybe restart and try again?");
+ cleanUpTrash(itemLocationTrash);
+ throw e;
+ }
+ rollbackMove();
+ cleanUpTrash(itemLocationTrash);
+ throw e;
+ }
+
+ // Now, and only now - after everything else has succeeded (against all odds!)
+ // remove the {GUID}-trash directory where we stashed the old version of the
+ // item.
+ cleanUpTrash(itemLocationTrash);
+}
+
+/**
+ * Manages the list of pending operations.
+ */
+var PendingOperations = {
+ _ops: { },
+
+ /**
+ * Adds an entry to the Pending Operations List
+ * @param opType
+ * The type of Operation to be performed
+ * @param entry
+ * A JS Object representing the item to be operated on:
+ * "locationKey" The name of the Install Location where the item
+ * is installed.
+ * "id" The GUID of the item.
+ */
+ addItem: function PendingOperations_addItem(opType, entry) {
+ if (opType == OP_NONE)
+ this.clearOpsForItem(entry.id);
+ else {
+ if (!(opType in this._ops))
+ this._ops[opType] = { };
+ this._ops[opType][entry.id] = entry.locationKey;
+ }
+ },
+
+ /**
+ * Removes a Pending Operation from the list
+ * @param opType
+ * The type of Operation being removed
+ * @param id
+ * The GUID of the item to remove the entry for
+ */
+ clearItem: function PendingOperations_clearItem(opType, id) {
+ if (opType in this._ops && id in this._ops[opType])
+ delete this._ops[opType][id];
+ },
+
+ /**
+ * Removes all Pending Operation for an item
+ * @param id
+ * The ID of the item to remove the entries for
+ */
+ clearOpsForItem: function PendingOperations_clearOpsForItem(id) {
+ for (var opType in this._ops) {
+ if (id in this._ops[opType])
+ delete this._ops[opType][id];
+ }
+ },
+
+ /**
+ * Remove all Pending Operations of a certain type
+ * @param opType
+ * The type of Operation to remove all entries for
+ */
+ clearItems: function PendingOperations_clearItems(opType) {
+ if (opType in this._ops)
+ delete this._ops[opType];
+ },
+
+ /**
+ * Get an array of operations of a certain type
+ * @param opType
+ * The type of Operation to return a list of
+ */
+ getOperations: function PendingOperations_getOperations(opType) {
+ if (!(opType in this._ops))
+ return [];
+ var ops = [];
+ for (var id in this._ops[opType])
+ ops.push( {id: id, locationKey: this._ops[opType][id] } );
+ return ops;
+ },
+
+ /**
+ * The total number of Pending Operations, for all types.
+ */
+ get size() {
+ var size = 0;
+ for (var opType in this._ops) {
+ for (var id in this._ops[opType])
+ ++size;
+ }
+ return size;
+ }
+};
+
+/**
+ * Manages registered Install Locations
+ */
+var InstallLocations = {
+ _locations: { },
+
+ /**
+ * A nsISimpleEnumerator of all available Install Locations.
+ */
+ get enumeration() {
+ var installLocations = [];
+ for (var key in this._locations)
+ installLocations.push(InstallLocations.get(key));
+ return new ArrayEnumerator(installLocations);
+ },
+
+ /**
+ * Gets a named Install Location
+ * @param name
+ * The name of the Install Location to get
+ */
+ get: function InstallLocations_get(name) {
+ return name in this._locations ? this._locations[name] : null;
+ },
+
+ /**
+ * Registers an Install Location
+ * @param installLocation
+ * The Install Location to register
+ */
+ put: function InstallLocations_put(installLocation) {
+ this._locations[installLocation.name] = installLocation;
+ }
+};
+
+/**
+ * Manages the Startup Cache. The Startup Cache is a representation
+ * of the contents of extensions.cache, a list of all
+ * items the Extension System knows about, whether or not they
+ * are active or visible.
+ */
+var StartupCache = {
+ /**
+ * Location Name -> GUID hash of entries from the Startup Cache file
+ * Each entry has the following properties:
+ * "descriptor" The location on disk of the item
+ * "mtime" The time the location was last modified
+ * "op" Any pending operations on this item.
+ * "location" The Install Location name where the item is installed.
+ */
+ entries: { },
+
+ /**
+ * Puts an entry into the Startup Cache
+ * @param installLocation
+ * The Install Location where the item is installed
+ * @param id
+ * The GUID of the item
+ * @param op
+ * The name of the operation to be performed
+ * @param shouldCreate
+ * Whether or not we should create a new entry for this item
+ * in the cache if one does not already exist.
+ */
+ put: function StartupCache_put(installLocation, id, op, shouldCreate) {
+ var itemLocation = installLocation.getItemLocation(id);
+
+ var descriptor = null;
+ var mtime = null;
+ if (itemLocation) {
+ itemLocation.QueryInterface(Ci.nsILocalFile);
+ descriptor = getDescriptorFromFile(itemLocation, installLocation);
+ if (itemLocation.exists() && itemLocation.isDirectory())
+ mtime = Math.floor(itemLocation.lastModifiedTime / 1000);
+ }
+
+ this._putRaw(installLocation.name, id, descriptor, mtime, op, shouldCreate);
+ },
+
+ /**
+ * Private helper function for putting an entry into the Startup Cache
+ * without relying on the presence of its associated nsIInstallLocation
+ * instance.
+ *
+ * @param key
+ * The install location name.
+ * @param id
+ * The ID of the item.
+ * @param descriptor
+ * Value returned from absoluteDescriptor. May be null, in which
+ * case the descriptor field is not updated.
+ * @param mtime
+ * The last modified time of the item. May be null, in which case the
+ * descriptor field is not updated.
+ * @param op
+ * The OP code to store with the entry.
+ * @param shouldCreate
+ * Boolean value indicating whether to create or delete the entry.
+ */
+ _putRaw: function StartupCache__putRaw(key, id, descriptor, mtime, op, shouldCreate) {
+ if (!(key in this.entries))
+ this.entries[key] = { };
+ if (!(id in this.entries[key]))
+ this.entries[key][id] = { };
+ if (shouldCreate) {
+ if (!this.entries[key][id])
+ this.entries[key][id] = { };
+
+ var entry = this.entries[key][id];
+
+ if (descriptor)
+ entry.descriptor = descriptor;
+ if (mtime)
+ entry.mtime = mtime;
+ entry.op = op;
+ entry.location = key;
+ }
+ else
+ this.entries[key][id] = null;
+ },
+
+ /**
+ * Clears an entry from the Startup Cache
+ * @param installLocation
+ * The Install Location where item is installed
+ * @param id
+ * The GUID of the item.
+ */
+ clearEntry: function StartupCache_clearEntry(installLocation, id) {
+ var key = installLocation.name;
+ if (key in this.entries && id in this.entries[key])
+ this.entries[key][id] = null;
+ },
+
+ /**
+ * Get all the startup cache entries for a particular ID.
+ * @param id
+ * The GUID of the item to locate.
+ * @returns An array of Startup Cache entries for the specified ID.
+ */
+ findEntries: function StartupCache_findEntries(id) {
+ var entries = [];
+ for (var key in this.entries) {
+ if (id in this.entries[key])
+ entries.push(this.entries[key][id]);
+ }
+ return entries;
+ },
+
+ /**
+ * Read the Item-Change manifest file into a hash of properties.
+ * The Item-Change manifest currently holds a list of paths, with the last
+ * mtime for each path, and the GUID of the item at that path.
+ */
+ read: function StartupCache_read() {
+ var itemChangeManifest = getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS_STARTUP_CACHE]);
+ if (!itemChangeManifest.exists()) {
+ // There is no change manifest for some reason, either we're in an initial
+ // state or something went wrong with one of the other files and the
+ // change manifest was removed. Return an empty dataset and rebuild.
+ gFirstRun = true;
+ return;
+ }
+ var fis = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ fis.init(itemChangeManifest, -1, -1, false);
+ if (fis instanceof Ci.nsILineInputStream) {
+ var line = { value: "" };
+ var more = false;
+ do {
+ more = fis.readLine(line);
+ if (line.value) {
+ // The Item-Change manifest is formatted like so:
+ // (pd = descriptor)
+ // location-key\tguid-of-item\tpd-to-extension1\tmtime-of-pd\tpending-op
+ // location-key\tguid-of-item\tpd-to-extension2\tmtime-of-pd\tpending-op
+ // ...
+ // We hash on location-key first, because we don't want to have to
+ // spin up the main extensions datasource on every start to determine
+ // the Install Location for an item.
+ // We hash on guid second, because we want a way to quickly determine
+ // item GUID during a check loop that runs on every startup.
+ var parts = line.value.split("\t");
+ // Silently drop any entries in unknown install locations
+ if (!InstallLocations.get(parts[0]))
+ continue;
+ var op = parts[4];
+ this._putRaw(parts[0], parts[1], parts[2], parts[3], op, true);
+ if (op)
+ PendingOperations.addItem(op, { locationKey: parts[0], id: parts[1] });
+ }
+ }
+ while (more);
+ }
+ fis.close();
+ },
+
+ /**
+ * Writes the Startup Cache to disk
+ */
+ write: function StartupCache_write() {
+ var extensionsCacheFile = getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS_STARTUP_CACHE]);
+ var fos = openSafeFileOutputStream(extensionsCacheFile);
+ for (var locationKey in this.entries) {
+ for (var id in this.entries[locationKey]) {
+ var entry = this.entries[locationKey][id];
+ if (entry) {
+ try {
+ var itemLocation = getFileFromDescriptor(entry.descriptor, InstallLocations.get(locationKey));
+
+ // Update our knowledge of this item's last-modified-time.
+ // XXXdarin: this may cause us to miss changes in some cases.
+ var itemMTime = 0;
+ if (itemLocation.exists() && itemLocation.isDirectory())
+ itemMTime = Math.floor(itemLocation.lastModifiedTime / 1000);
+
+ // Each line in the startup cache manifest is in this form:
+ // location-key\tid-of-item\tpd-to-extension1\tmtime-of-pd\tpending-op
+ var line = locationKey + "\t" + id + "\t" + entry.descriptor + "\t" +
+ itemMTime + "\t" + entry.op + "\r\n";
+ fos.write(line, line.length);
+ }
+ catch (e) {}
+ }
+ }
+ }
+ closeSafeFileOutputStream(fos);
+ }
+};
+
+/**
+ * Installs, manages and tracks compatibility for Extensions and Themes
+ * @constructor
+ */
+function ExtensionManager() {
+ gApp = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo).QueryInterface(Ci.nsIXULRuntime);
+ gOSTarget = gApp.OS;
+ try {
+ gXPCOMABI = gApp.XPCOMABI;
+ } catch (ex) {
+ // Provide a default for gXPCOMABI. It won't be compared to an
+ // item's metadata (i.e. install.rdf can't specify e.g. WINNT_unknownABI
+ // as targetPlatform), but it will be displayed in error messages and
+ // transmitted to update URLs.
+ gXPCOMABI = UNKNOWN_XPCOM_ABI;
+ }
+ gPref = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+
+ gOS = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ gOS.addObserver(this, "xpcom-shutdown", false);
+
+ gConsole = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+
+ gRDF = Cc["@mozilla.org/rdf/rdf-service;1"].
+ getService(Ci.nsIRDFService);
+ gInstallManifestRoot = gRDF.GetResource(RDFURI_INSTALL_MANIFEST_ROOT);
+
+ // Register Global Install Location
+ var appGlobalExtensions = getDirNoCreate(KEY_APPDIR, [DIR_EXTENSIONS]);
+ var priority = Ci.nsIInstallLocation.PRIORITY_APP_SYSTEM_GLOBAL;
+ var globalLocation = new DirectoryInstallLocation(KEY_APP_GLOBAL,
+ appGlobalExtensions, true,
+ priority, false);
+ InstallLocations.put(globalLocation);
+
+ // Register App-Profile Install Location
+ var appProfileExtensions = getDirNoCreate(KEY_PROFILEDS, [DIR_EXTENSIONS]);
+ var priority = Ci.nsIInstallLocation.PRIORITY_APP_PROFILE;
+ var profileLocation = new DirectoryInstallLocation(KEY_APP_PROFILE,
+ appProfileExtensions, false,
+ priority, false);
+ InstallLocations.put(profileLocation);
+
+ // Register per-user Install Location
+ try {
+ var appSystemUExtensions = getDirNoCreate("XREUSysExt", [gApp.ID]);
+ }
+ catch(e) { }
+
+ if (appSystemUExtensions) {
+ var priority = Ci.nsIInstallLocation.PRIORITY_APP_SYSTEM_USER;
+ var systemLocation = new DirectoryInstallLocation(KEY_APP_SYSTEM_USER,
+ appSystemUExtensions, false,
+ priority, true);
+
+ InstallLocations.put(systemLocation);
+ }
+
+ // Register App-System-Shared Install Location
+ try {
+ var appSystemSExtensions = getDirNoCreate("XRESysSExtPD", [gApp.ID]);
+ }
+ catch (e) { }
+
+ if (appSystemSExtensions) {
+ var priority = Ci.nsIInstallLocation.PRIORITY_APP_SYSTEM_GLOBAL + 10;
+ var systemLocation = new DirectoryInstallLocation(KEY_APP_SYSTEM_SHARE,
+ appSystemSExtensions, true,
+ priority, true);
+ InstallLocations.put(systemLocation);
+ }
+
+ // Register App-System-Local Install Location
+ try {
+ var appSystemLExtensions = getDirNoCreate("XRESysLExtPD", [gApp.ID]);
+ }
+ catch (e) { }
+
+ if (appSystemLExtensions) {
+ var priority = Ci.nsIInstallLocation.PRIORITY_APP_SYSTEM_GLOBAL + 20;
+ var systemLocation = new DirectoryInstallLocation(KEY_APP_SYSTEM_LOCAL,
+ appSystemLExtensions, true,
+ priority, true);
+ InstallLocations.put(systemLocation);
+ }
+
+//@line 2512 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+
+ // Register Additional Install Locations
+ var categoryManager = Cc["@mozilla.org/categorymanager;1"].
+ getService(Ci.nsICategoryManager);
+ var locations = categoryManager.enumerateCategory(CATEGORY_INSTALL_LOCATIONS);
+ while (locations.hasMoreElements()) {
+ var entry = locations.getNext().QueryInterface(Ci.nsISupportsCString).data;
+ var contractID = categoryManager.getCategoryEntry(CATEGORY_INSTALL_LOCATIONS, entry);
+ var location = Cc[contractID].getService(Ci.nsIInstallLocation);
+ InstallLocations.put(location);
+ }
+}
+
+ExtensionManager.prototype = {
+ /**
+ * See nsIObserver.idl
+ */
+ observe: function EM_observe(subject, topic, data) {
+ switch (topic) {
+ case "profile-after-change":
+ this._profileSelected();
+ break;
+ case "quit-application-requested":
+ this._confirmCancelDownloadsOnQuit(subject);
+ break;
+ case "offline-requested":
+ this._confirmCancelDownloadsOnOffline(subject);
+ break;
+ case "xpcom-shutdown":
+ this._shutdown();
+ break;
+ case "nsPref:changed":
+ if (data == PREF_EM_LOGGING_ENABLED)
+ this._loggingToggled();
+ else if (data == PREF_EM_CHECK_COMPATIBILITY ||
+ data == PREF_EM_CHECK_UPDATE_SECURITY)
+ this._updateAppDisabledState();
+ else if ((data == PREF_MATCH_OS_LOCALE) || (data == PREF_SELECTED_LOCALE))
+ this._updateLocale();
+ break;
+ }
+ },
+
+ /**
+ * Refresh the logging enabled global from preferences when the user changes
+ * the preference settting.
+ */
+ _loggingToggled: function EM__loggingToggled() {
+ gLoggingEnabled = getPref("getBoolPref", PREF_EM_LOGGING_ENABLED, false);
+ },
+
+ /**
+ * Retrieves the current locale
+ */
+ _updateLocale: function EM__updateLocale() {
+ try {
+ if (gPref.getBoolPref(PREF_MATCH_OS_LOCALE)) {
+ var localeSvc = Cc["@mozilla.org/intl/nslocaleservice;1"].
+ getService(Ci.nsILocaleService);
+ gLocale = localeSvc.getLocaleComponentForUserAgent();
+ return;
+ }
+ }
+ catch (ex) {
+ }
+ gLocale = gPref.getCharPref(PREF_SELECTED_LOCALE);
+ },
+
+ /**
+ * When a preference is toggled that affects whether an item is usable or not
+ * we must app-enable or app-disable the item based on the new settings.
+ */
+ _updateAppDisabledState: function EM__updateAppDisabledState() {
+ gCheckCompatibility = getPref("getBoolPref", PREF_EM_CHECK_COMPATIBILITY, true);
+ gCheckUpdateSecurity = getPref("getBoolPref", PREF_EM_CHECK_UPDATE_SECURITY, true);
+ var ds = this.datasource;
+
+ // Enumerate all items
+ var ctr = getContainer(ds, ds._itemRoot);
+ var elements = ctr.GetElements();
+ while (elements.hasMoreElements()) {
+ var itemResource = elements.getNext().QueryInterface(Ci.nsIRDFResource);
+
+ // App disable or enable items as necessary
+ // _appEnableItem and _appDisableItem will do nothing if the item is already
+ // in the right state.
+ id = stripPrefix(itemResource.Value, PREFIX_ITEM_URI);
+ if (this._isUsableItem(id))
+ this._appEnableItem(id);
+ else
+ this._appDisableItem(id);
+ }
+ },
+
+ /**
+ * Initialize the system after a profile has been selected.
+ */
+ _profileSelected: function EM__profileSelected() {
+ // Tell the Chrome Registry which Skin to select
+ try {
+ if (gPref.getBoolPref(PREF_DSS_SWITCHPENDING)) {
+ var toSelect = gPref.getCharPref(PREF_DSS_SKIN_TO_SELECT);
+ gPref.setCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN, toSelect);
+ gPref.clearUserPref(PREF_DSS_SWITCHPENDING);
+ gPref.clearUserPref(PREF_DSS_SKIN_TO_SELECT);
+ }
+ }
+ catch (e) {
+ }
+
+ if ("nsICrashReporter" in Ci && gApp instanceof Ci.nsICrashReporter) {
+ // Annotate the crash report with the list of add-ons
+ try {
+ try {
+ gApp.annotateCrashReport("Add-ons", gPref.getCharPref(PREF_EM_ENABLED_ITEMS));
+ } catch (e) { }
+ gApp.annotateCrashReport("Theme", gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN));
+ }
+ catch (ex) {
+ // This will fail in unnofficial builds, ignorable error
+ }
+ }
+
+ gLoggingEnabled = getPref("getBoolPref", PREF_EM_LOGGING_ENABLED, false);
+ gCheckCompatibility = getPref("getBoolPref", PREF_EM_CHECK_COMPATIBILITY, true);
+ gCheckUpdateSecurity = getPref("getBoolPref", PREF_EM_CHECK_UPDATE_SECURITY, true);
+ gPref.addObserver("extensions.", this, false);
+ gPref.addObserver(PREF_MATCH_OS_LOCALE, this, false);
+ gPref.addObserver(PREF_SELECTED_LOCALE, this, false);
+ this._updateLocale();
+ },
+
+ /**
+ * Notify user that there are new addons updates
+ */
+ _showUpdatesWindow: function EM__showUpdatesWindow() {
+ if (!getPref("getBoolPref", PREF_UPDATE_NOTIFYUSER, false))
+ return;
+
+ const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
+ const EMFEATURES = "chrome,centerscreen,extra-chrome,dialog,resizable,modal";
+
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ var param = Cc["@mozilla.org/supports-array;1"].
+ createInstance(Ci.nsISupportsArray);
+ var arg = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ arg.data = "updates-only";
+ param.AppendElement(arg);
+ ww.openWindow(null, EMURL, null, EMFEATURES, param);
+ },
+
+ /**
+ * Clean up on application shutdown to avoid leaks.
+ */
+ _shutdown: function EM__shutdown() {
+ if (!gAllowFlush) {
+ // Something went wrong and there are potentially flushes pending.
+ ERROR("Reached _shutdown and without clearing any pending flushes");
+ try {
+ gAllowFlush = true;
+ if (gManifestNeedsFlush) {
+ gManifestNeedsFlush = false;
+ this._updateManifests(false);
+ }
+ if (gDSNeedsFlush) {
+ gDSNeedsFlush = false;
+ this.datasource.Flush();
+ }
+ }
+ catch (e) {
+ ERROR("Error flushing caches: " + e);
+ }
+ }
+
+ gOS.removeObserver(this, "xpcom-shutdown");
+
+ // Release strongly held services.
+ gOS = null;
+ if (this._ds) {
+ gRDF.UnregisterDataSource(this._ptr);
+ this._ptr = null;
+ this._ds.shutdown();
+ this._ds = null;
+ }
+ gRDF = null;
+ if (gPref) {
+ gPref.removeObserver("extensions.", this);
+ gPref.removeObserver(PREF_MATCH_OS_LOCALE, this);
+ gPref.removeObserver(PREF_SELECTED_LOCALE, this);
+ }
+ gPref = null;
+ gConsole = null;
+ gVersionChecker = null;
+ gDirService = null;
+ gInstallManifestRoot = null;
+ gApp = null;
+ },
+
+ /**
+ * Check for presence of critical Extension system files. If any is missing,
+ * delete the others and signal that the system needs to rebuild them all
+ * from scratch.
+ * @returns true if any critical file is missing and the system needs to
+ * be rebuilt, false otherwise.
+ */
+ _ensureDatasetIntegrity: function EM__ensureDatasetIntegrity() {
+ var profD = getDirNoCreate(KEY_PROFILEDIR, []);
+ var extensionsDS = profD.clone();
+ extensionsDS.append(FILE_EXTENSIONS);
+ var extensionsINI = profD.clone();
+ extensionsINI.append(FILE_EXTENSION_MANIFEST);
+ var extensionsCache = profD;
+ extensionsCache.append(FILE_EXTENSIONS_STARTUP_CACHE);
+
+ var dsExists = extensionsDS.exists();
+ var iniExists = extensionsINI.exists();
+ var cacheExists = extensionsCache.exists();
+
+ if (dsExists && iniExists && cacheExists)
+ return [false, !iniExists];
+
+ // If any of the files are missing, remove the .ini file
+ if (iniExists)
+ extensionsINI.remove(false);
+
+ // If the extensions datasource is missing remove the .cache file if it exists
+ if (!dsExists && cacheExists)
+ extensionsCache.remove(false);
+
+ return [true, !iniExists];
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ start: function EM_start(commandLine) {
+ var isDirty, forceAutoReg;
+
+ // Check for missing manifests - e.g. missing extensions.ini, missing
+ // extensions.cache, extensions.rdf etc. If any of these files
+ // is missing then we are in some kind of weird or initial state and need
+ // to force a regeneration.
+ [isDirty, forceAutoReg] = this._ensureDatasetIntegrity();
+
+ // Block attempts to flush for the entire startup
+ gAllowFlush = false;
+
+ // Configure any items that are being installed, uninstalled or upgraded
+ // by being added, removed or modified by another process. We must do this
+ // on every startup since there is no way we can tell if this has happened
+ // or not!
+ if (this._checkForFileChanges())
+ isDirty = true;
+
+ this._showUpdatesWindow();
+
+ if (PendingOperations.size != 0)
+ isDirty = true;
+
+ var needsRestart = false;
+ // Extension Changes
+ if (isDirty) {
+ needsRestart = this._finishOperations();
+
+ if (forceAutoReg) {
+ this._extensionListChanged = true;
+ needsRestart = true;
+ }
+ }
+
+ // Resume flushing and perform a flush for anything that was deferred
+ try {
+ gAllowFlush = true;
+ if (gManifestNeedsFlush) {
+ gManifestNeedsFlush = false;
+ this._updateManifests(false);
+ }
+ if (gDSNeedsFlush) {
+ gDSNeedsFlush = false;
+ this.datasource.Flush();
+ }
+ }
+ catch (e) {
+ ERROR("Error flushing caches: " + e);
+ }
+
+ if (!needsRestart)
+ this._startTimers();
+
+ return needsRestart;
+ },
+
+ /**
+ * Begins all background update check timers
+ */
+ _startTimers: function EM__startTimers() {
+ // Register a background update check timer
+ var tm = Cc["@mozilla.org/updates/timer-manager;1"].
+ getService(Ci.nsIUpdateTimerManager);
+ var interval = getPref("getIntPref", PREF_EM_UPDATE_INTERVAL, 86400);
+ tm.registerTimer("addon-background-update-timer", this, interval);
+ },
+
+ /**
+ * Notified when a timer fires
+ * @param timer
+ * The timer that fired
+ */
+ notify: function EM_notify(timer) {
+ if (!getPref("getBoolPref", PREF_EM_UPDATE_ENABLED, true))
+ return;
+
+ var items = this.getItemList(Ci.nsIUpdateItem.TYPE_ANY, { });
+
+ var updater = new ExtensionItemUpdater(this);
+ updater.checkForUpdates(items, items.length,
+ Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION,
+ new BackgroundUpdateCheckListener(this.datasource),
+ null, null);
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ handleCommandLineArgs: function EM_handleCommandLineArgs(commandLine) {
+ try {
+ var globalExtension = commandLine.handleFlagWithParam("install-global-extension", false);
+ if (globalExtension) {
+ var file = commandLine.resolveFile(globalExtension);
+ this._installGlobalItem(file);
+ }
+ var globalTheme = commandLine.handleFlagWithParam("install-global-theme", false);
+ if (globalTheme) {
+ file = commandLine.resolveFile(globalTheme);
+ this._installGlobalItem(file);
+ }
+ }
+ catch (e) {
+ ERROR("ExtensionManager:handleCommandLineArgs - failure, catching exception - lineno: " +
+ e.lineNumber + " - file: " + e.fileName + " - " + e);
+ }
+ commandLine.preventDefault = true;
+ },
+
+ /**
+ * Installs an XPI/JAR file into the KEY_APP_GLOBAL install location.
+ * @param file
+ * The XPI/JAR file to extract
+ */
+ _installGlobalItem: function EM__installGlobalItem(file) {
+ if (!file || !file.exists())
+ throw new Error("Unable to find the file specified on the command line!");
+//@line 2872 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+ var installManifestFile = extractRDFFileToTempDir(file, FILE_INSTALL_MANIFEST, true);
+ if (!installManifestFile.exists())
+ throw new Error("The package is missing an install manifest!");
+ var installManifest = getInstallManifest(installManifestFile);
+ installManifestFile.remove(false);
+ var installData = this._getInstallData(installManifest);
+ var installer = new Installer(installManifest, installData.id,
+ InstallLocations.get(KEY_APP_GLOBAL),
+ installData.type);
+ installer._installExtensionFiles(file);
+ if (installData.type == Ci.nsIUpdateItem.TYPE_THEME)
+ installer.upgradeThemeChrome();
+ else
+ installer.upgradeExtensionChrome();
+ },
+
+ /**
+ * Check to see if a file is a XPI/JAR file that the user dropped into this
+ * Install Location. (i.e. a XPI that is not a staged XPI from an install
+ * transaction that is currently in operation).
+ * @param file
+ * The XPI/JAR file to configure
+ * @param location
+ * The Install Location where this file was found.
+ * @returns A nsIUpdateItem representing the dropped XPI if this file was a
+ * XPI/JAR that needs installation, null otherwise.
+ */
+ _getItemForDroppedFile: function EM__getItemForDroppedFile(file, location) {
+ if (fileIsItemPackage(file)) {
+ // We know nothing about this item, it is not something we've
+ // staged in preparation for finalization, so assume it's something
+ // the user dropped in.
+ LOG("A Item Package appeared at: " + file.path + " that we know " +
+ "nothing about, assuming it was dropped in by the user and " +
+ "configuring for installation now. Location Key: " + location.name);
+
+ var installManifestFile = extractRDFFileToTempDir(file, FILE_INSTALL_MANIFEST, true);
+ if (!installManifestFile.exists())
+ return null;
+ var installManifest = getInstallManifest(installManifestFile);
+ installManifestFile.remove(false);
+ var ds = this.datasource;
+ var installData = this._getInstallData(installManifest);
+ var targetAppInfo = ds.getTargetApplicationInfo(installData.id, installManifest);
+ return makeItem(installData.id,
+ installData.version,
+ location.name,
+ targetAppInfo ? targetAppInfo.minVersion : "",
+ targetAppInfo ? targetAppInfo.maxVersion : "",
+ getManifestProperty(installManifest, "name"),
+ "", /* XPI Update URL */
+ "", /* XPI Update Hash */
+ getManifestProperty(installManifest, "iconURL"),
+ getManifestProperty(installManifest, "updateURL"),
+ getManifestProperty(installManifest, "updateKey"),
+ installData.type,
+ targetAppInfo ? targetAppInfo.appID : gApp.ID);
+ }
+ return null;
+ },
+
+ /**
+ * Configure an item that was installed or upgraded by another process
+ * so that |_finishOperations| can properly complete processing and
+ * registration.
+ * As this is the only point at which we can reliably know the Install
+ * Location of this item, we use this as an opportunity to:
+ * 1. Check that this item is compatible with this Firefox version.
+ * 2. If it is, configure the item by using the supplied callback.
+ * We do not do any special handling in the case that the item is
+ * not compatible with this version other than to simply not register
+ * it and log that fact - there is no "phone home" check for updates.
+ * It may or may not make sense to do this, but for now we'll just
+ * not register.
+ * @param id
+ * The GUID of the item to validate and configure.
+ * @param location
+ * The Install Location where this item is installed.
+ * @param callback
+ * The callback that configures the item for installation upon
+ * successful validation.
+ */
+ installItem: function EM_installItem(id, location, callback) {
+ // As this is the only pint at which we reliably know the installation
+ var installRDF = location.getItemFile(id, FILE_INSTALL_MANIFEST);
+ if (installRDF.exists()) {
+ LOG("Item Installed/Upgraded at Install Location: " + location.name +
+ " Item ID: " + id + ", attempting to register...");
+ var installManifest = getInstallManifest(installRDF);
+ var installData = this._getInstallData(installManifest);
+ if (installData.error == INSTALLERROR_SUCCESS) {
+ LOG("... success, item is compatible");
+ callback(installManifest, installData.id, location, installData.type);
+ }
+ else if (installData.error == INSTALLERROR_INCOMPATIBLE_VERSION) {
+ LOG("... success, item installed but is not compatible");
+ callback(installManifest, installData.id, location, installData.type);
+ this._appDisableItem(id);
+ }
+ else if (installData.error == INSTALLERROR_INSECURE_UPDATE) {
+ LOG("... success, item installed but does not provide updates securely");
+ callback(installManifest, installData.id, location, installData.type);
+ this._appDisableItem(id);
+ }
+ else if (installData.error == INSTALLERROR_BLOCKLISTED) {
+ LOG("... success, item installed but is blocklisted");
+ callback(installManifest, installData.id, location, installData.type);
+ this._appDisableItem(id);
+ }
+ else if (installData.error == INSTALLERROR_SOFTBLOCKED) {
+ LOG("... success, item installed but is soft blocked, item will be disabled");
+ callback(installManifest, installData.id, location, installData.type);
+ this.disableItem(id);
+ }
+ else {
+ /**
+ * Turns an error code into a message for logging
+ * @param error
+ * an Install Error code
+ * @returns A string message to be logged.
+ */
+ function translateErrorMessage(error) {
+ switch (error) {
+ case INSTALLERROR_INVALID_GUID:
+ return "Invalid GUID";
+ case INSTALLERROR_INVALID_VERSION:
+ return "Invalid Version";
+ case INSTALLERROR_INCOMPATIBLE_PLATFORM:
+ return "Incompatible Platform";
+ }
+ }
+ LOG("... failure, item is not compatible, error: " +
+ translateErrorMessage(installData.error));
+
+ // Add the item to the Startup Cache anyway, so we don't re-detect it
+ // every time the app starts.
+ StartupCache.put(location, id, OP_NONE, true);
+ }
+ }
+ },
+
+ /**
+ * Check for changes to items that were made independently of the Extension
+ * Manager, e.g. items were added or removed from a Install Location or items
+ * in an Install Location changed.
+ */
+ _checkForFileChanges: function EM__checkForFileChanges() {
+ var em = this;
+
+ /**
+ * Determines if an item can be used based on whether or not the install
+ * location of the "item" has an equal or higher priority than the install
+ * location where another version may live.
+ * @param id
+ * The GUID of the item being installed.
+ * @param location
+ * The location where an item is to be installed.
+ * @returns true if the item can be installed at that location, false
+ * otherwise.
+ */
+ function canUse(id, location) {
+ for (var locationKey in StartupCache.entries) {
+ if (locationKey != location.name &&
+ id in StartupCache.entries[locationKey]) {
+ if (StartupCache.entries[locationKey][id]) {
+ var oldInstallLocation = InstallLocations.get(locationKey);
+ if (oldInstallLocation.priority <= location.priority)
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Gets a Dialog Param Block loaded with a set of strings to initialize the
+ * XPInstall Confirmation Dialog.
+ * @param strings
+ * An array of strings
+ * @returns A nsIDialogParamBlock loaded with the strings and dialog state.
+ */
+ function getParamBlock(strings) {
+ var dpb = Cc["@mozilla.org/embedcomp/dialogparam;1"].
+ createInstance(Ci.nsIDialogParamBlock);
+ // OK and Cancel Buttons
+ dpb.SetInt(0, 2);
+ // Number of Strings
+ dpb.SetInt(1, strings.length);
+ dpb.SetNumberStrings(strings.length);
+ // Add Strings
+ for (var i = 0; i < strings.length; ++i)
+ dpb.SetString(i, strings[i]);
+
+ var supportsString = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ supportsString.data = bundle.GetStringFromName("droppedInWarning");
+ var objs = Cc["@mozilla.org/array;1"].
+ createInstance(Ci.nsIMutableArray);
+ objs.appendElement(supportsString, false);
+ dpb.objects = objs;
+ return dpb;
+ }
+
+ /**
+ * Installs a set of files which were dropped into an install location by
+ * the user, only after user confirmation.
+ * @param droppedInFiles
+ * An array of JS objects with the following properties:
+ * "file" The nsILocalFile where the XPI lives
+ * "location" The Install Location where the XPI was found.
+ * @param xpinstallStrings
+ * An array of strings used to initialize the XPInstall Confirm
+ * dialog.
+ */
+ function installDroppedInFiles(droppedInFiles, xpinstallStrings) {
+ if (droppedInFiles.length == 0)
+ return;
+
+ var dpb = getParamBlock(xpinstallStrings);
+ var ifptr = Cc["@mozilla.org/supports-interface-pointer;1"].
+ createInstance(Ci.nsISupportsInterfacePointer);
+ ifptr.data = dpb;
+ ifptr.dataIID = Ci.nsIDialogParamBlock;
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(null, URI_XPINSTALL_CONFIRM_DIALOG,
+ "", "chrome,centerscreen,modal,dialog,titlebar", ifptr);
+ if (!dpb.GetInt(0)) {
+ // User said OK - install items
+ for (var i = 0; i < droppedInFiles.length; ++i) {
+ em.installItemFromFile(droppedInFiles[i].file,
+ droppedInFiles[i].location.name);
+ // We are responsible for cleaning up this file
+ droppedInFiles[i].file.remove(false);
+ }
+ }
+ else {
+ for (i = 0; i < droppedInFiles.length; ++i) {
+ // We are responsible for cleaning up this file
+ droppedInFiles[i].file.remove(false);
+ }
+ }
+ }
+
+ var isDirty = false;
+ var ignoreMTimeChanges = getPref("getBoolPref", PREF_EM_IGNOREMTIMECHANGES,
+ false);
+ StartupCache.read();
+
+ // Array of objects with 'location' and 'id' properties to maybe install.
+ var newItems = [];
+
+ var droppedInFiles = [];
+ var xpinstallStrings = [];
+
+ // Enumerate over the install locations from low to high priority. The
+ // enumeration returned is pre-sorted.
+ var installLocations = this.installLocations;
+ while (installLocations.hasMoreElements()) {
+ var location = installLocations.getNext().QueryInterface(Ci.nsIInstallLocation);
+
+ // Hash the set of items actually held by the Install Location.
+ var actualItems = { };
+ var entries = location.itemLocations;
+ while (true) {
+ var entry = entries.nextFile;
+ if (!entry)
+ break;
+
+ // Is this location a valid item? It must be a directory, and contain
+ // an install.rdf manifest:
+ if (entry.isDirectory()) {
+ var installRDF = entry.clone();
+ installRDF.append(FILE_INSTALL_MANIFEST);
+
+ var id = location.getIDForLocation(entry);
+ if (!id || (!installRDF.exists() &&
+ !location.itemIsManagedIndependently(id)))
+ continue;
+
+ actualItems[id] = entry;
+ }
+ else {
+ // Check to see if this file is a XPI/JAR dropped into this dir
+ // by the user, installing it if necessary. We do this here rather
+ // than separately in |_finishOperations| because I don't want to
+ // walk these lists multiple times on every startup.
+ var item = this._getItemForDroppedFile(entry, location);
+ if (item) {
+ droppedInFiles.push({ file: entry, location: location });
+ var prettyName = "";
+ try {
+ var zipReader = getZipReaderForFile(entry);
+ var principal = { };
+ var certPrincipal = zipReader.getCertificatePrincipal(null, principal);
+ // XXXbz This string could be empty. This needs better
+ // UI to present principal.value.certificate's subject.
+ prettyName = principal.value.prettyName;
+ }
+ catch (e) { }
+ if (zipReader)
+ zipReader.close();
+ xpinstallStrings = xpinstallStrings.concat([item.name,
+ getURLSpecFromFile(entry),
+ item.iconURL,
+ prettyName]);
+ isDirty = true;
+ }
+ }
+ }
+
+ if (location.name in StartupCache.entries) {
+ // Look for items that have been uninstalled by removing their directory.
+ for (var id in StartupCache.entries[location.name]) {
+ if (!StartupCache.entries[location.name] ||
+ !StartupCache.entries[location.name][id])
+ continue;
+
+ // Force _finishOperations to run if we have enabled or disabled items.
+ // XXXdarin this should be unnecessary now that we check
+ // PendingOperations.size in start()
+ if (StartupCache.entries[location.name][id].op == OP_NEEDS_ENABLE ||
+ StartupCache.entries[location.name][id].op == OP_NEEDS_DISABLE)
+ isDirty = true;
+
+ if (!(id in actualItems) &&
+ StartupCache.entries[location.name][id].op != OP_NEEDS_UNINSTALL &&
+ StartupCache.entries[location.name][id].op != OP_NEEDS_INSTALL &&
+ StartupCache.entries[location.name][id].op != OP_NEEDS_UPGRADE) {
+ // We have an entry for this id in the Extensions database, for this
+ // install location, but it no longer exists in the Install Location.
+ // We can infer from this that the item has been removed, so uninstall
+ // it properly.
+ if (canUse(id, location)) {
+ LOG("Item Uninstalled via file removal from: " + StartupCache.entries[location.name][id].descriptor +
+ " Item ID: " + id + " Location Key: " + location.name + ", uninstalling item.");
+
+ // Load the Extensions Datasource and force this item into the visible
+ // items list if it is not already. This allows us to handle the case
+ // where there is an entry for an item in the Startup Cache but not
+ // in the extensions.rdf file - in that case the item will not be in
+ // the visible list and calls to |getInstallLocation| will mysteriously
+ // fail.
+ this.datasource.updateVisibleList(id, location.name, false);
+ this.uninstallItem(id);
+ isDirty = true;
+ }
+ }
+ else if (!ignoreMTimeChanges) {
+ // Look for items whose mtime has changed, and as such we can assume
+ // they have been "upgraded".
+ var lf = { path: StartupCache.entries[location.name][id].descriptor };
+ try {
+ lf = getFileFromDescriptor(StartupCache.entries[location.name][id].descriptor, location);
+ }
+ catch (e) { }
+
+ if (lf.exists && lf.exists()) {
+ var actualMTime = Math.floor(lf.lastModifiedTime / 1000);
+ if (actualMTime != StartupCache.entries[location.name][id].mtime) {
+ LOG("Item Location path changed: " + lf.path + " Item ID: " +
+ id + " Location Key: " + location.name + ", attempting to upgrade item...");
+ if (canUse(id, location)) {
+ this.installItem(id, location,
+ function(installManifest, id, location, type) {
+ em._upgradeItem(installManifest, id, location,
+ type);
+ });
+ isDirty = true;
+ }
+ }
+ }
+ else {
+ isDirty = true;
+ LOG("Install Location returned a missing or malformed item path! " +
+ "Item Path: " + lf.path + ", Location Key: " + location.name +
+ " Item ID: " + id);
+ if (canUse(id, location)) {
+ // Load the Extensions Datasource and force this item into the visible
+ // items list if it is not already. This allows us to handle the case
+ // where there is an entry for an item in the Startup Cache but not
+ // in the extensions.rdf file - in that case the item will not be in
+ // the visible list and calls to |getInstallLocation| will mysteriously
+ // fail.
+ this.datasource.updateVisibleList(id, location.name, false);
+ this.uninstallItem(id);
+ }
+ }
+ }
+ }
+ }
+
+ // Look for items that have been installed by appearing in the location.
+ for (var id in actualItems) {
+ if (!(location.name in StartupCache.entries) ||
+ !(id in StartupCache.entries[location.name]) ||
+ !StartupCache.entries[location.name][id]) {
+ // Remember that we've seen this item
+ StartupCache.put(location, id, OP_NONE, true);
+ // Push it on the stack of items to maybe install later
+ newItems.push({location: location, id: id});
+ }
+ }
+ }
+
+ // Process any newly discovered items. We do this here instead of in the
+ // previous loop so that we can be sure that we have a fully populated
+ // StartupCache.
+ for (var i = 0; i < newItems.length; ++i) {
+ var id = newItems[i].id;
+ var location = newItems[i].location;
+ if (canUse(id, location)) {
+ LOG("Item Installed via directory addition to Install Location: " +
+ location.name + " Item ID: " + id + ", attempting to register...");
+ this.installItem(id, location,
+ function(installManifest, id, location, type) {
+ em._configureForthcomingItem(installManifest, id, location,
+ type);
+ });
+ // Disable add-ons on install when the InstallDisabled file exists.
+ // This is so Talkback will be disabled on a subset of installs.
+ var installDisabled = location.getItemFile(id, "InstallDisabled");
+ if (installDisabled.exists())
+ em.disableItem(id);
+ isDirty = true;
+ }
+ }
+
+ // Ask the user if they want to install the dropped items, for security
+ // purposes.
+ installDroppedInFiles(droppedInFiles, xpinstallStrings);
+
+ return isDirty;
+ },
+
+ /**
+ * Upgrades contents.rdf files to chrome.manifest files for any existing
+ * Extensions and Themes.
+ * @returns true if actions were performed that require a restart, false
+ * otherwise.
+ */
+ _upgradeChrome: function EM__upgradeChrome() {
+ if (inSafeMode())
+ return false;
+
+ var checkForNewChrome = false;
+ var ds = this.datasource;
+ // If we have extensions that were installed before the new flat chrome
+ // manifests, and are still valid, we need to manually create the flat
+ // manifest files.
+ var extensions = this._getActiveItems(Ci.nsIUpdateItem.TYPE_EXTENSION +
+ Ci.nsIUpdateItem.TYPE_LOCALE);
+ for (var i = 0; i < extensions.length; ++i) {
+ var e = extensions[i];
+ var itemLocation = e.location.getItemLocation(e.id);
+ var manifest = itemLocation.clone();
+ manifest.append(FILE_CHROME_MANIFEST);
+ if (!manifest.exists()) {
+ var installRDF = itemLocation.clone();
+ installRDF.append(FILE_INSTALL_MANIFEST);
+ var installLocation = this.getInstallLocation(e.id);
+ if (installLocation && installRDF.exists()) {
+ var itemLocation = installLocation.getItemLocation(e.id);
+ if (itemLocation.exists() && itemLocation.isDirectory()) {
+ var installer = new Installer(ds, e.id, installLocation,
+ Ci.nsIUpdateItem.TYPE_EXTENSION);
+ installer.upgradeExtensionChrome();
+ }
+ }
+ else {
+ ds.removeItemMetadata(e.id);
+ ds.removeItemFromContainer(e.id);
+ }
+
+ checkForNewChrome = true;
+ }
+ }
+
+ var themes = this._getActiveItems(Ci.nsIUpdateItem.TYPE_THEME);
+ // If we have themes that were installed before the new flat chrome
+ // manifests, and are still valid, we need to manually create the flat
+ // manifest files.
+ for (i = 0; i < themes.length; ++i) {
+ var item = themes[i];
+ var itemLocation = item.location.getItemLocation(item.id);
+ var manifest = itemLocation.clone();
+ manifest.append(FILE_CHROME_MANIFEST);
+ if (manifest.exists() ||
+ item.id == stripPrefix(RDFURI_DEFAULT_THEME, PREFIX_ITEM_URI))
+ continue;
+
+ var entries;
+ try {
+ var manifestURI = getURIFromFile(manifest);
+ var chromeDir = itemLocation.clone();
+ chromeDir.append(DIR_CHROME);
+
+ if (!chromeDir.exists() || !chromeDir.isDirectory()) {
+ ds.removeItemMetadata(item.id);
+ ds.removeItemFromContainer(item.id);
+ continue;
+ }
+
+ // We're relying on the fact that there is only one JAR file
+ // in the "chrome" directory. This is a hack, but it works.
+ entries = chromeDir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
+ var jarFile = entries.nextFile;
+ if (jarFile) {
+ var jarFileURI = getURIFromFile(jarFile);
+ var contentsURI = newURI("jar:" + jarFileURI.spec + "!/");
+
+ // Use the Chrome Registry API to install the theme there
+ var cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
+ getService(Ci.nsIToolkitChromeRegistry);
+ cr.processContentsManifest(contentsURI, manifestURI, contentsURI, false, true);
+ }
+ entries.close();
+ }
+ catch (e) {
+ ERROR("_upgradeChrome: failed to upgrade contents manifest for " +
+ "theme: " + item.id + ", exception: " + e + "... The theme will be " +
+ "disabled.");
+ this._appDisableItem(item.id);
+ }
+ finally {
+ try {
+ entries.close();
+ }
+ catch (e) {
+ }
+ }
+ checkForNewChrome = true;
+ }
+ return checkForNewChrome;
+ },
+
+ _checkForUncoveredItem: function EM__checkForUncoveredItem(id) {
+ var ds = this.datasource;
+ var oldLocation = this.getInstallLocation(id);
+ var newLocations = [];
+ for (var locationKey in StartupCache.entries) {
+ var location = InstallLocations.get(locationKey);
+ if (id in StartupCache.entries[locationKey] &&
+ location.priority > oldLocation.priority)
+ newLocations.push(location);
+ }
+ newLocations.sort(function(a, b) { return b.priority - a.priority; });
+ if (newLocations.length > 0) {
+ for (var i = 0; i < newLocations.length; ++i) {
+ // Check to see that the item at the location exists
+ var installRDF = newLocations[i].getItemFile(id, FILE_INSTALL_MANIFEST);
+ if (installRDF.exists()) {
+ // Update the visible item cache so that |_finalizeUpgrade| is properly
+ // called from |_finishOperations|
+ var name = newLocations[i].name;
+ ds.updateVisibleList(id, name, true);
+ PendingOperations.addItem(OP_NEEDS_UPGRADE,
+ { locationKey: name, id: id });
+ PendingOperations.addItem(OP_NEEDS_INSTALL,
+ { locationKey: name, id: id });
+ break;
+ }
+ else {
+ // If no item exists at the location specified, remove this item
+ // from the visible items list and check again.
+ StartupCache.clearEntry(newLocations[i], id);
+ ds.updateVisibleList(id, null, true);
+ }
+ }
+ }
+ else
+ ds.updateVisibleList(id, null, true);
+ },
+
+ /**
+ * Finish up pending operations - perform upgrades, installs, enables/disables,
+ * uninstalls etc.
+ * @returns true if actions were performed that require a restart, false
+ * otherwise.
+ */
+ _finishOperations: function EM__finishOperations() {
+ try {
+ // Stuff has changed, load the Extensions datasource in all its RDFey
+ // glory.
+ var ds = this.datasource;
+ var updatedTargetAppInfos = [];
+
+ var needsRestart = false;
+ var upgrades = [];
+ var newAddons = [];
+ var addons = getPref("getCharPref", PREF_EM_NEW_ADDONS_LIST, "");
+ if (addons != "")
+ newAddons = addons.split(",");
+ do {
+ // Enable and disable during startup so items that are changed in the
+ // ui can be reset to a no-op.
+ // Look for extensions that need to be enabled.
+ var items = PendingOperations.getOperations(OP_NEEDS_ENABLE);
+ for (var i = items.length - 1; i >= 0; --i) {
+ var id = items[i].id;
+ var installLocation = this.getInstallLocation(id);
+ StartupCache.put(installLocation, id, OP_NONE, true);
+ PendingOperations.clearItem(OP_NEEDS_ENABLE, id);
+ needsRestart = true;
+ }
+ PendingOperations.clearItems(OP_NEEDS_ENABLE);
+
+ // Look for extensions that need to be disabled.
+ items = PendingOperations.getOperations(OP_NEEDS_DISABLE);
+ for (i = items.length - 1; i >= 0; --i) {
+ id = items[i].id;
+ installLocation = this.getInstallLocation(id);
+ StartupCache.put(installLocation, id, OP_NONE, true);
+ PendingOperations.clearItem(OP_NEEDS_DISABLE, id);
+ needsRestart = true;
+ }
+ PendingOperations.clearItems(OP_NEEDS_DISABLE);
+
+ // Look for extensions that need to be upgraded. The process here is to
+ // uninstall the old version of the extension first, then install the
+ // new version in its place.
+ items = PendingOperations.getOperations(OP_NEEDS_UPGRADE);
+ for (i = items.length - 1; i >= 0; --i) {
+ id = items[i].id;
+ var newLocation = InstallLocations.get(items[i].locationKey);
+ // check if there is updated app compatibility info
+ var newTargetAppInfo = ds.getUpdatedTargetAppInfo(id);
+ if (newTargetAppInfo)
+ updatedTargetAppInfos.push(newTargetAppInfo);
+ this._finalizeUpgrade(id, newLocation);
+ upgrades.push(id);
+ }
+ PendingOperations.clearItems(OP_NEEDS_UPGRADE);
+
+ // Install items
+ items = PendingOperations.getOperations(OP_NEEDS_INSTALL);
+ for (i = items.length - 1; i >= 0; --i) {
+ needsRestart = true;
+ id = items[i].id;
+ // check if there is updated app compatibility info
+ newTargetAppInfo = ds.getUpdatedTargetAppInfo(id);
+ if (newTargetAppInfo)
+ updatedTargetAppInfos.push(newTargetAppInfo);
+ this._finalizeInstall(id, null);
+ if (upgrades.indexOf(id) < 0 && newAddons.indexOf(id) < 0)
+ newAddons.push(id);
+ }
+ PendingOperations.clearItems(OP_NEEDS_INSTALL);
+
+ // Look for extensions that need to be removed. This MUST be done after
+ // the install operations since extensions to be installed may have to be
+ // uninstalled if there are errors during the installation process!
+ items = PendingOperations.getOperations(OP_NEEDS_UNINSTALL);
+ for (i = items.length - 1; i >= 0; --i) {
+ id = items[i].id;
+ this._finalizeUninstall(id);
+ this._checkForUncoveredItem(id);
+ needsRestart = true;
+ var pos = newAddons.indexOf(id);
+ if (pos >= 0)
+ newAddons.splice(pos, 1);
+ }
+ PendingOperations.clearItems(OP_NEEDS_UNINSTALL);
+
+ // When there have been operations and all operations have completed.
+ if (PendingOperations.size == 0) {
+ // If there is updated app compatibility info update the datasource.
+ for (i = 0; i < updatedTargetAppInfos.length; ++i)
+ ds.setTargetApplicationInfo(updatedTargetAppInfos[i].id,
+ updatedTargetAppInfos[i].targetAppID,
+ updatedTargetAppInfos[i].minVersion,
+ updatedTargetAppInfos[i].maxVersion,
+ null);
+
+ // Enumerate all items
+ var ctr = getContainer(ds, ds._itemRoot);
+ var elements = ctr.GetElements();
+ while (elements.hasMoreElements()) {
+ var itemResource = elements.getNext().QueryInterface(Ci.nsIRDFResource);
+
+ // Ensure appDisabled is in the correct state.
+ id = stripPrefix(itemResource.Value, PREFIX_ITEM_URI);
+ if (this._isUsableItem(id))
+ ds.setItemProperty(id, EM_R("appDisabled"), null);
+ else
+ ds.setItemProperty(id, EM_R("appDisabled"), EM_L("true"));
+
+ // userDisabled is set based on its value being OP_NEEDS_ENABLE or
+ // OP_NEEDS_DISABLE. This allows us to have an item to be enabled
+ // by the app and disabled by the user during a single restart.
+ var value = stringData(ds.GetTarget(itemResource, EM_R("userDisabled"), true));
+ if (value == OP_NEEDS_ENABLE)
+ ds.setItemProperty(id, EM_R("userDisabled"), null);
+ else if (value == OP_NEEDS_DISABLE)
+ ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));
+ }
+ }
+ }
+ while (PendingOperations.size > 0);
+
+ // Upgrade contents.rdf files to the new chrome.manifest format for
+ // existing Extensions and Themes
+ if (this._upgradeChrome()) {
+ var cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
+ getService(Ci.nsIChromeRegistry);
+ cr.checkForNewChrome();
+ }
+
+ // If no additional restart is required, it implies that there are
+ // no new components that need registering so we can inform the app
+ // not to do any extra startup checking next time round.
+ this._updateManifests(needsRestart);
+
+ // Remember the list of add-ons that were installed this time around
+ // unless this was a new profile.
+ if (!gFirstRun && newAddons.length > 0)
+ gPref.setCharPref(PREF_EM_NEW_ADDONS_LIST, newAddons.join(","));
+ }
+ catch (e) {
+ ERROR("ExtensionManager:_finishOperations - failure, catching exception - lineno: " +
+ e.lineNumber + " - file: " + e.fileName + " - " + e);
+ }
+ return needsRestart;
+ },
+
+ /**
+ * Checks to see if there are items that are incompatible with this version
+ * of the application, disables them to prevent incompatibility problems and
+ * invokes the Update Wizard to look for newer versions.
+ * @returns true if there were incompatible items installed and disabled, and
+ * the application must now be restarted to reinitialize XPCOM,
+ * false otherwise.
+ */
+ checkForMismatches: function EM_checkForMismatches() {
+ // Check to see if the version of the application that is being started
+ // now is the same one that was started last time.
+ var currAppVersion = gApp.version;
+ var lastAppVersion = getPref("getCharPref", PREF_EM_LAST_APP_VERSION, "");
+ if (currAppVersion == lastAppVersion)
+ return false;
+ // With a new profile lastAppVersion doesn't exist yet.
+ if (!lastAppVersion) {
+ gPref.setCharPref(PREF_EM_LAST_APP_VERSION, currAppVersion);
+ return false;
+ }
+
+ // Block attempts to flush for the entire startup
+ gAllowFlush = false;
+
+ // Version mismatch, we have to load the extensions datasource and do
+ // version checking. Time hit here doesn't matter since this doesn't happen
+ // all that often.
+ this._upgradeFromV10();
+
+ // Make the extensions datasource consistent if it isn't already.
+ var isDirty;
+ [isDirty,] = this._ensureDatasetIntegrity();
+
+ if (this._checkForFileChanges())
+ isDirty = true;
+
+ if (PendingOperations.size != 0)
+ isDirty = true;
+
+ var ds = this.datasource;
+ var inactiveItemIDs = [];
+ var ctr = getContainer(ds, ds._itemRoot);
+ var elements = ctr.GetElements();
+ while (elements.hasMoreElements()) {
+ var itemResource = elements.getNext().QueryInterface(Ci.nsIRDFResource);
+ var id = stripPrefix(itemResource.Value, PREFIX_ITEM_URI);
+ var appDisabled = ds.getItemProperty(id, "appDisabled");
+ var userDisabled = ds.getItemProperty(id, "userDisabled")
+ if (appDisabled == "true" || appDisabled == OP_NEEDS_DISABLE ||
+ userDisabled == "true" || userDisabled == OP_NEEDS_DISABLE)
+ inactiveItemIDs.push(id);
+ }
+
+ if (isDirty)
+ this._finishOperations();
+
+ // During app upgrade cleanup invalid entries in the extensions datasource.
+ ds.beginUpdateBatch();
+ var allResources = ds.GetAllResources();
+ while (allResources.hasMoreElements()) {
+ var res = allResources.getNext().QueryInterface(Ci.nsIRDFResource);
+ if (ds.GetTarget(res, EM_R("downloadURL"), true) ||
+ (!ds.GetTarget(res, EM_R("installLocation"), true) &&
+ stringData(ds.GetTarget(res, EM_R("appDisabled"), true)) == "true"))
+ ds.removeDownload(res.Value);
+ }
+ ds.endUpdateBatch();
+
+ var badItems = [];
+ var allAppManaged = true;
+ elements = ctr.GetElements();
+ while (elements.hasMoreElements()) {
+ var itemResource = elements.getNext().QueryInterface(Ci.nsIRDFResource);
+ var id = stripPrefix(itemResource.Value, PREFIX_ITEM_URI);
+ var location = this.getInstallLocation(id);
+ if (!location) {
+ // Item was in an unknown install location
+ badItems.push(id);
+ continue;
+ }
+
+ if (ds.getItemProperty(id, "appManaged") == "true") {
+ // Force an update of the metadata for appManaged extensions since the
+ // last modified time is not updated for directories on FAT / FAT32
+ // filesystems when software update applies a new version of the app.
+ if (location.name == KEY_APP_GLOBAL) {
+ var installRDF = location.getItemFile(id, FILE_INSTALL_MANIFEST);
+ if (installRDF.exists()) {
+ var metadataDS = getInstallManifest(installRDF);
+ ds.addItemMetadata(id, metadataDS, location);
+ ds.updateProperty(id, "compatible");
+ }
+ }
+ }
+ else if (allAppManaged)
+ allAppManaged = false;
+
+ var properties = {
+ availableUpdateURL: null,
+ availableUpdateVersion: null
+ };
+
+ if (ds.getItemProperty(id, "providesUpdatesSecurely") == "false") {
+ /* It's possible the previous version did not understand updateKeys so
+ * check if we can import one for this addon from its manifest. */
+ installRDF = location.getItemFile(id, FILE_INSTALL_MANIFEST);
+ if (installRDF.exists()) {
+ metadataDS = getInstallManifest(installRDF);
+ var literal = metadataDS.GetTarget(gInstallManifestRoot, EM_R("updateKey"), true);
+ if (literal && literal instanceof Ci.nsIRDFLiteral)
+ ds.setItemProperty(id, EM_R("updateKey"), literal);
+ }
+ }
+
+ // appDisabled is determined by an item being compatible, using secure
+ // updates, satisfying its dependencies, and not being blocklisted
+ if (this._isUsableItem(id)) {
+ if (ds.getItemProperty(id, "appDisabled"))
+ properties.appDisabled = null;
+ }
+ else if (!ds.getItemProperty(id, "appDisabled")) {
+ properties.appDisabled = EM_L("true");
+ }
+
+ ds.setItemProperties(id, properties);
+ }
+
+ // Must clean up outside of the loop. Modifying the container while
+ // iterating its contents is bad.
+ for (var i = 0; i < badItems.length; i++) {
+ id = badItems[i];
+ LOG("Item " + id + " was installed in an unknown location, removing.");
+ var disabled = ds.getItemProperty(id, "userDisabled") == "true";
+ // Clean up the datasource
+ ds.removeCorruptItem(id);
+ // Check for any unhidden items.
+ var entries = StartupCache.findEntries(id);
+ if (entries.length > 0) {
+ var newLocation = InstallLocations.get(entries[0].location);
+ for (var j = 1; j < entries.length; j++) {
+ location = InstallLocations.get(entries[j].location);
+ if (newLocation.priority < location.priority)
+ newLocation = location;
+ }
+ LOG("Activating item " + id + " in " + newLocation.name);
+ var em = this;
+ this.installItem(id, newLocation,
+ function(installManifest, id, location, type) {
+ em._configureForthcomingItem(installManifest, id, location,
+ type);
+ });
+ if (disabled)
+ em.disableItem(id);
+ }
+ }
+
+ // Update the manifests to reflect the items that were disabled / enabled.
+ this._updateManifests(true);
+
+ // Always check for compatibility updates when upgrading if we have add-ons
+ // that aren't managed by the application.
+ if (!allAppManaged)
+ this._showMismatchWindow(inactiveItemIDs);
+
+ // Finish any pending upgrades from the compatibility update to avoid an
+ // additional restart.
+ if (PendingOperations.size != 0)
+ this._finishOperations();
+
+ // Update the last app version so we don't do this again with this version.
+ gPref.setCharPref(PREF_EM_LAST_APP_VERSION, currAppVersion);
+
+ // Prevent extension update dialog from showing
+ gPref.setBoolPref(PREF_UPDATE_NOTIFYUSER, false);
+
+ // Re-enable flushing and flush anything that was deferred
+ try {
+ gAllowFlush = true;
+ if (gManifestNeedsFlush) {
+ gManifestNeedsFlush = false;
+ this._updateManifests(false);
+ }
+ if (gDSNeedsFlush) {
+ gDSNeedsFlush = false;
+ this.datasource.Flush();
+ }
+ }
+ catch (e) {
+ ERROR("Error flushing caches: " + e);
+ }
+
+ return true;
+ },
+
+ /**
+ * Shows the "Compatibility Updates" UI
+ * @param items
+ * an array of item IDs that were not enabled in the previous version
+ * of the application.
+ */
+ _showMismatchWindow: function EM__showMismatchWindow(items) {
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ var wizard = wm.getMostRecentWindow("Update:Wizard");
+ if (wizard)
+ wizard.focus();
+ else {
+ var variant = Cc["@mozilla.org/variant;1"].
+ createInstance(Ci.nsIWritableVariant);
+ variant.setFromVariant(items);
+ var features = "chrome,centerscreen,dialog,titlebar,modal";
+ // This *must* be modal so as not to break startup! This code is invoked before
+ // the main event loop is initiated (via checkForMismatches).
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(null, URI_EXTENSION_UPDATE_DIALOG, "", features, variant);
+ }
+ },
+
+ /*
+ * Catch all for facilitating a version 1.0 profile upgrade.
+ * 1) removes the abandoned default theme directory from the profile.
+ * 2) prepares themes installed with version 1.0 for installation.
+ * 3) initiates an install to populate the new extensions datasource.
+ * 4) migrates the disabled attribute from the old datasource.
+ * 5) migrates the app compatibility info from the old datasource.
+ */
+ _upgradeFromV10: function EM__upgradeFromV10() {
+ var extensionsDS = getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS]);
+ var dsExists = extensionsDS.exists();
+ // Toolkiit 1.7 profiles (Firefox 1.0, Thunderbird 1.0, etc.) have a default
+ // theme directory in the profile's extensions directory that will be
+ // disabled due to having a maxVersion that is incompatible with the
+ // toolkit 1.8 release of the app.
+ var profileDefaultTheme = getDirNoCreate(KEY_PROFILEDS, [DIR_EXTENSIONS,
+ stripPrefix(RDFURI_DEFAULT_THEME, PREFIX_ITEM_URI)]);
+ if (profileDefaultTheme && profileDefaultTheme.exists()) {
+ removeDirRecursive(profileDefaultTheme);
+ // Sunbird 0.3a1 didn't move the default theme into the app's extensions
+ // directory and we can't install it while uninstalling the one in the
+ // profile directory. If we have a toolkit 1.8 extensions datasource and
+ // a profile default theme deleting the toolkit 1.8 extensions datasource
+ // will fix this problem when the datasource is re-created.
+ if (dsExists)
+ extensionsDS.remove(false);
+ }
+
+ // return early if the toolkit 1.7 extensions datasource file doesn't exist.
+ var oldExtensionsFile = getFile(KEY_PROFILEDIR, [DIR_EXTENSIONS, "Extensions.rdf"]);
+ if (!oldExtensionsFile.exists())
+ return;
+
+ // Sunbird 0.2 used a different GUID for the default theme
+ profileDefaultTheme = getDirNoCreate(KEY_PROFILEDS, [DIR_EXTENSIONS,
+ "{8af2d0a7-e394-4de2-ae55-2dae532a7a9b}"]);
+ if (profileDefaultTheme && profileDefaultTheme.exists())
+ removeDirRecursive(profileDefaultTheme);
+
+ // Firefox 0.9 profiles may have DOMi 1.0 with just an install.rdf
+ var profileDOMi = getDirNoCreate(KEY_PROFILEDS, [DIR_EXTENSIONS,
+ "{641d8d09-7dda-4850-8228-ac0ab65e2ac9}"]);
+ if (profileDOMi && profileDOMi.exists())
+ removeDirRecursive(profileDOMi);
+
+ // return early to avoid migrating data twice if we already have a
+ // toolkit 1.8 extension datasource.
+ if (dsExists)
+ return;
+
+ // Prepare themes for installation
+ // Only enumerate directories in the app-profile and app-global locations.
+ var locations = [KEY_APP_PROFILE, KEY_APP_GLOBAL];
+ for (var i = 0; i < locations.length; ++i) {
+ var location = InstallLocations.get(locations[i]);
+ if (!location.canAccess)
+ continue;
+
+ var entries = location.itemLocations;
+ var entry;
+ while ((entry = entries.nextFile)) {
+ var installRDF = entry.clone();
+ installRDF.append(FILE_INSTALL_MANIFEST);
+
+ var chromeDir = entry.clone();
+ chromeDir.append(DIR_CHROME);
+
+ // It must be a directory without an install.rdf and it must contain
+ // a chrome directory
+ if (!entry.isDirectory() || installRDF.exists() || !chromeDir.exists())
+ continue;
+
+ var chromeEntries = chromeDir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
+ if (!chromeEntries.hasMoreElements())
+ continue;
+
+ // We're relying on the fact that there is only one JAR file
+ // in the "chrome" directory. This is a hack, but it works.
+ var jarFile = chromeEntries.nextFile;
+ if (jarFile.isDirectory())
+ continue;
+ var id = location.getIDForLocation(entry);
+
+ try {
+ var zipReader = getZipReaderForFile(jarFile);
+ zipReader.extract(FILE_INSTALL_MANIFEST, installRDF);
+
+ var contentsManifestFile = location.getItemFile(id, FILE_CONTENTS_MANIFEST);
+ zipReader.extract(FILE_CONTENTS_MANIFEST, contentsManifestFile);
+
+ var rootFiles = ["preview.png", "icon.png"];
+ for (var i = 0; i < rootFiles.length; ++i) {
+ try {
+ var target = location.getItemFile(id, rootFiles[i]);
+ zipReader.extract(rootFiles[i], target);
+ }
+ catch (e) {
+ }
+ }
+ zipReader.close();
+ }
+ catch (e) {
+ ERROR("ExtensionManager:_upgradeFromV10 - failed to extract theme files\r\n" +
+ "Exception: " + e);
+ }
+ }
+ }
+
+ // When upgrading from a version 1.0 profile we need to populate the
+ // extensions datasource with all items before checking for incompatible
+ // items since the datasource hasn't been created yet.
+ var itemsToCheck = [];
+ if (this._checkForFileChanges()) {
+ // Create a list of all items that are to be installed so we can migrate
+ // these items's settings to the new datasource.
+ var items = PendingOperations.getOperations(OP_NEEDS_INSTALL);
+ for (i = items.length - 1; i >= 0; --i) {
+ if (items[i].locationKey == KEY_APP_PROFILE ||
+ items[i].locationKey == KEY_APP_GLOBAL)
+ itemsToCheck.push(items[i].id);
+ }
+ this._finishOperations();
+ }
+
+ // If there are no items to migrate settings for return early.
+ if (itemsToCheck.length == 0)
+ return;
+
+ var fileURL = getURLSpecFromFile(oldExtensionsFile);
+ var oldExtensionsDS = gRDF.GetDataSourceBlocking(fileURL);
+ var versionChecker = getVersionChecker();
+ var ds = this.datasource;
+ var currAppVersion = gApp.version;
+ var currAppID = gApp.ID;
+ for (var i = 0; i < itemsToCheck.length; ++i) {
+ var item = ds.getItemForID(itemsToCheck[i]);
+ var oldPrefix = (item.type == Ci.nsIUpdateItem.TYPE_EXTENSION) ? PREFIX_EXTENSION : PREFIX_THEME;
+ var oldRes = gRDF.GetResource(oldPrefix + item.id);
+ // Disable the item if it was disabled in the version 1.0 extensions
+ // datasource.
+ if (oldExtensionsDS.GetTarget(oldRes, EM_R("disabled"), true))
+ ds.setItemProperty(item.id, EM_R("userDisabled"), EM_L("true"));
+
+ // app enable all items. If it is incompatible it will be app disabled
+ // later on.
+ ds.setItemProperty(item.id, EM_R("appDisabled"), null);
+
+ // if the item is already compatible don't attempt to migrate the
+ // item's compatibility info
+ var newRes = getResourceForID(itemsToCheck[i]);
+ if (ds.isCompatible(ds, newRes))
+ continue;
+
+ var updatedMinVersion = null;
+ var updatedMaxVersion = null;
+ var targetApps = oldExtensionsDS.GetTargets(oldRes, EM_R("targetApplication"), true);
+ while (targetApps.hasMoreElements()) {
+ var targetApp = targetApps.getNext();
+ if (targetApp instanceof Ci.nsIRDFResource) {
+ try {
+ var foundAppID = stringData(oldExtensionsDS.GetTarget(targetApp, EM_R("id"), true));
+ // Different target application? (Note: v1.0 didn't support toolkit app ID)
+ if (foundAppID != currAppID)
+ continue;
+
+ updatedMinVersion = stringData(oldExtensionsDS.GetTarget(targetApp, EM_R("minVersion"), true));
+ updatedMaxVersion = stringData(oldExtensionsDS.GetTarget(targetApp, EM_R("maxVersion"), true));
+
+ // Only set the target app info if the extension's target app info
+ // in the version 1.0 extensions datasource makes it compatible
+ if (versionChecker.compare(currAppVersion, updatedMinVersion) >= 0 &&
+ versionChecker.compare(currAppVersion, updatedMaxVersion) <= 0)
+ ds.setTargetApplicationInfo(item.id, foundAppID, updatedMinVersion,
+ updatedMaxVersion, null);
+
+ break;
+ }
+ catch (e) {
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * Write the Extensions List and the Startup Cache
+ * @param needsRestart
+ * true if the application needs to restart again, false otherwise.
+ */
+ _updateManifests: function EM__updateManifests(needsRestart) {
+ // During startup we block flushing until the startup operations are all
+ // complete to reduce file accesses that can trigger bug 431065
+ if (gAllowFlush) {
+ // Write the Startup Cache (All Items, visible or not)
+ StartupCache.write();
+ // Write the Extensions Locations Manifest (Visible, enabled items)
+ this._updateExtensionsManifest();
+ }
+ else {
+ gManifestNeedsFlush = true;
+ }
+
+ // Notify nsAppRunner to update the compatibility manifest on next startup
+ this._extensionListChanged = needsRestart;
+ },
+
+ /**
+ * Get a list of items that are currently "active" (turned on) of a specific
+ * type
+ * @param type
+ * The nsIUpdateItem type to return a list of items of
+ * @returns An array of active items of the specified type.
+ */
+ _getActiveItems: function EM__getActiveItems(type) {
+ var allItems = this.getItemList(type, { });
+ var activeItems = [];
+ var ds = this.datasource;
+ for (var i = 0; i < allItems.length; ++i) {
+ var item = allItems[i];
+
+ var installLocation = this.getInstallLocation(item.id);
+ // An entry with an invalid install location is not active.
+ if (!installLocation)
+ continue;
+ // An item entry is valid only if it is not disabled, not about to
+ // be disabled, and not about to be uninstalled.
+ if (installLocation.name in StartupCache.entries &&
+ item.id in StartupCache.entries[installLocation.name] &&
+ StartupCache.entries[installLocation.name][item.id]) {
+ var op = StartupCache.entries[installLocation.name][item.id].op;
+ if (op == OP_NEEDS_INSTALL || op == OP_NEEDS_UPGRADE ||
+ op == OP_NEEDS_UNINSTALL || op == OP_NEEDS_DISABLE)
+ continue;
+ }
+ // Suppress items that have been disabled by the user or the app.
+ if (ds.getItemProperty(item.id, "isDisabled") != "true")
+ activeItems.push({ id: item.id, version: item.version,
+ location: installLocation });
+ }
+
+ return activeItems;
+ },
+
+ /**
+ * Write the Extensions List
+ */
+ _updateExtensionsManifest: function EM__updateExtensionsManifest() {
+ // When an operation is performed that requires a component re-registration
+ // (extension enabled/disabled, installed, uninstalled), we must write the
+ // set of paths where extensions live so that the startup system can determine
+ // where additional components, preferences, chrome manifests etc live.
+ //
+ // To do this we obtain a list of active extensions and themes and write
+ // these to the extensions.ini file in the profile directory.
+ var validExtensions = this._getActiveItems(Ci.nsIUpdateItem.TYPE_ANY -
+ Ci.nsIUpdateItem.TYPE_THEME);
+ var validThemes = this._getActiveItems(Ci.nsIUpdateItem.TYPE_THEME);
+
+ var extensionsLocationsFile = getFile(KEY_PROFILEDIR, [FILE_EXTENSION_MANIFEST]);
+ var fos = openSafeFileOutputStream(extensionsLocationsFile);
+
+ var enabledItems = [];
+ var extensionSectionHeader = "[ExtensionDirs]\r\n";
+ fos.write(extensionSectionHeader, extensionSectionHeader.length);
+ for (var i = 0; i < validExtensions.length; ++i) {
+ var e = validExtensions[i];
+ var itemLocation = e.location.getItemLocation(e.id).QueryInterface(Ci.nsILocalFile);
+ var descriptor = getAbsoluteDescriptor(itemLocation);
+ var line = "Extension" + i + "=" + descriptor + "\r\n";
+ fos.write(line, line.length);
+ enabledItems.push(e.id + ":" + e.version);
+ }
+
+ var themeSectionHeader = "[ThemeDirs]\r\n";
+ fos.write(themeSectionHeader, themeSectionHeader.length);
+ for (i = 0; i < validThemes.length; ++i) {
+ var e = validThemes[i];
+ var itemLocation = e.location.getItemLocation(e.id).QueryInterface(Ci.nsILocalFile);
+ var descriptor = getAbsoluteDescriptor(itemLocation);
+ var line = "Extension" + i + "=" + descriptor + "\r\n";
+ fos.write(line, line.length);
+ enabledItems.push(e.id + ":" + e.version);
+ }
+
+ closeSafeFileOutputStream(fos);
+
+ // Cache the enabled list for annotating the crash report subsequently
+ gPref.setCharPref(PREF_EM_ENABLED_ITEMS, enabledItems.join(","));
+ },
+
+ /**
+ * Say whether or not the Extension List has changed (and thus whether or not
+ * the system will have to restart the next time it is started).
+ * @param val
+ * true if the Extension List has changed, false otherwise.
+ * @returns |val|
+ */
+ set _extensionListChanged(val) {
+ // When an extension has an operation perform on it (e.g. install, upgrade,
+ // disable, etc.) we are responsible for creating the .autoreg file and
+ // nsAppRunner is responsible for removing it on restart. At some point it
+ // may make sense to be able to cancel a registration but for now we only
+ // create the file.
+ try {
+ var autoregFile = getFile(KEY_PROFILEDIR, [FILE_AUTOREG]);
+ if (val && !autoregFile.exists())
+ autoregFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ }
+ catch (e) {
+ }
+ return val;
+ },
+
+ /**
+ * Gathers data about an item specified by the supplied Install Manifest
+ * and determines whether or not it can be installed as-is. It makes this
+ * determination by validating the item's GUID, Version, and determining
+ * if it is compatible with this application.
+ * @param installManifest
+ * A nsIRDFDataSource representing the Install Manifest of the
+ * item to be installed.
+ * @return A JS Object with the following properties:
+ * "id" The GUID of the Item being installed.
+ * "version" The Version string of the Item being installed.
+ * "name" The Name of the Item being installed.
+ * "type" The nsIUpdateItem type of the Item being installed.
+ * "targetApps" An array of TargetApplication Info Objects
+ * with "id", "minVersion" and "maxVersion" properties,
+ * representing applications targeted by this item.
+ * "error" The result code:
+ * INSTALLERROR_SUCCESS
+ * no error, item can be installed
+ * INSTALLERROR_INVALID_GUID
+ * error, GUID is not well-formed
+ * INSTALLERROR_INVALID_VERSION
+ * error, Version is not well-formed
+ * INSTALLERROR_INCOMPATIBLE_VERSION
+ * error, item is not compatible with this version
+ * of the application.
+ * INSTALLERROR_INCOMPATIBLE_PLATFORM
+ * error, item is not compatible with the operating
+ * system or ABI the application was built for.
+ * INSTALLERROR_INSECURE_UPDATE
+ * error, item has no secure method of providing updates
+ * INSTALLERROR_BLOCKLISTED
+ * error, item is blocklisted
+ */
+ _getInstallData: function EM__getInstallData(installManifest) {
+ var installData = { id : "",
+ version : "",
+ name : "",
+ type : 0,
+ error : INSTALLERROR_SUCCESS,
+ targetApps : [],
+ updateURL : "",
+ updateKey : "",
+ currentApp : null };
+
+ // Fetch properties from the Install Manifest
+ installData.id = getManifestProperty(installManifest, "id");
+ installData.version = getManifestProperty(installManifest, "version");
+ installData.name = getManifestProperty(installManifest, "name");
+ installData.type = getAddonTypeFromInstallManifest(installManifest);
+ installData.updateURL= getManifestProperty(installManifest, "updateURL");
+ installData.updateKey= getManifestProperty(installManifest, "updateKey");
+
+ /**
+ * Reads a property off a Target Application resource
+ * @param resource
+ * The RDF Resource for a Target Application
+ * @param property
+ * The property (less EM_NS) to read
+ * @returns The string literal value of the property.
+ */
+ function readTAProperty(resource, property) {
+ return stringData(installManifest.GetTarget(resource, EM_R(property), true));
+ }
+
+ var targetApps = installManifest.GetTargets(gInstallManifestRoot,
+ EM_R("targetApplication"),
+ true);
+ while (targetApps.hasMoreElements()) {
+ var targetApp = targetApps.getNext();
+ if (targetApp instanceof Ci.nsIRDFResource) {
+ try {
+ var data = { id : readTAProperty(targetApp, "id"),
+ minVersion: readTAProperty(targetApp, "minVersion"),
+ maxVersion: readTAProperty(targetApp, "maxVersion") };
+ installData.targetApps.push(data);
+ if ((data.id == gApp.ID) ||
+ (data.id == TOOLKIT_ID) && !installData.currentApp)
+ installData.currentApp = data;
+ }
+ catch (e) {
+ continue;
+ }
+ }
+ }
+
+ // If the item specifies one or more target platforms, make sure our OS/ABI
+ // combination is in the list - otherwise, refuse to install the item.
+ var targetPlatforms = null;
+ try {
+ targetPlatforms = installManifest.GetTargets(gInstallManifestRoot,
+ EM_R("targetPlatform"),
+ true);
+ } catch(e) {
+ // No targetPlatform nodes, continue.
+ }
+ if (targetPlatforms != null && targetPlatforms.hasMoreElements()) {
+ var foundMatchingOS = false;
+ var foundMatchingOSAndABI = false;
+ var requireABICompatibility = false;
+ while (targetPlatforms.hasMoreElements()) {
+ var targetPlatform = stringData(targetPlatforms.getNext());
+ var os = targetPlatform.split("_")[0];
+ var index = targetPlatform.indexOf("_");
+ var abi = index != -1 ? targetPlatform.substr(index + 1) : null;
+ if (os == gOSTarget) {
+ foundMatchingOS = true;
+ // The presence of any ABI part after our OS means ABI is important.
+ if (abi != null) {
+ requireABICompatibility = true;
+ // If we don't know our ABI, we can't be compatible
+ if (abi == gXPCOMABI && abi != UNKNOWN_XPCOM_ABI) {
+ foundMatchingOSAndABI = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!foundMatchingOS || (requireABICompatibility && !foundMatchingOSAndABI)) {
+ installData.error = INSTALLERROR_INCOMPATIBLE_PLATFORM;
+ return installData;
+ }
+ }
+
+ // Validate the Item ID
+ if (!gIDTest.test(installData.id)) {
+ installData.error = INSTALLERROR_INVALID_GUID;
+ return installData;
+ }
+
+ // Check that the add-on provides a secure update method.
+ if (gCheckUpdateSecurity &&
+ installData.updateURL &&
+ installData.updateURL.substring(0, 6) != "https:" &&
+ !installData.updateKey) {
+ installData.error = INSTALLERROR_INSECURE_UPDATE;
+ return installData;
+ }
+
+ // Check that the target application range allows compatibility with the app
+ if (gCheckCompatibility &&
+ !this.datasource.isCompatible(installManifest, gInstallManifestRoot, undefined)) {
+ installData.error = INSTALLERROR_INCOMPATIBLE_VERSION;
+ return installData;
+ }
+
+ // Check if the item is blocklisted.
+ if (!gBlocklist)
+ gBlocklist = Cc["@mozilla.org/extensions/blocklist;1"].
+ getService(Ci.nsIBlocklistService);
+ var state = gBlocklist.getAddonBlocklistState(installData.id, installData.version);
+ if (state == Ci.nsIBlocklistService.STATE_BLOCKED)
+ installData.error = INSTALLERROR_BLOCKLISTED;
+ else if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
+ installData.error = INSTALLERROR_SOFTBLOCKED;
+
+ return installData;
+ },
+
+ /**
+ * Installs an item from a XPI/JAR file.
+ * This is the main entry point into the Install system from outside code
+ * (e.g. XPInstall).
+ * @param aXPIFile
+ * The file to install from.
+ * @param aInstallLocationKey
+ * The name of the Install Location where this item should be
+ * installed.
+ */
+ installItemFromFile: function EM_installItemFromFile(xpiFile, installLocationKey) {
+ this.installItemFromFileInternal(xpiFile, installLocationKey, null);
+
+ // If there are no compatibility checks running and no downloads in
+ // progress then the install operations are complete.
+ if (this._compatibilityCheckCount == 0 && this._transactions.length == 0) {
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onInstallsCompleted();
+ }
+ },
+
+ /**
+ * Installs an item from a XPI/JAR file.
+ * @param aXPIFile
+ * The file to install from.
+ * @param aInstallLocationKey
+ * The name of the Install Location where this item should be
+ * installed.
+ * @param aInstallManifest
+ * An updated Install Manifest from the Version Update check.
+ * Can be null when invoked from callers other than the Version
+ * Update check.
+ * @returns The install result code. If this is INSTALLERROR_PHONING_HOME
+ * then a remote update check has been started to attempt to resolve
+ * compatibility problems.
+ */
+ installItemFromFileInternal: function EM_installItemFromFileInternal(aXPIFile,
+ aInstallLocationKey,
+ aInstallManifest) {
+ var em = this;
+ /**
+ * Gets the Install Location for an Item.
+ * @param itemID
+ * The GUID of the item to find an Install Location for.
+ * @return An object implementing nsIInstallLocation which represents the
+ * location where the specified item should be installed.
+ * This can be:
+ * 1. an object that corresponds to the location key supplied to
+ * |installItemFromFileInternal|,
+ * 2. the default install location (the App Profile Extensions Folder)
+ * if no location key was supplied, or the location key supplied
+ * was not in the set of registered locations
+ * 3. null, if the location selected by 1 or 2 above does not support
+ * installs from XPI/JAR files, or that location is not writable
+ * with the current access privileges.
+ */
+ function getInstallLocation(itemID) {
+ // Here I use "upgrade" to mean "install a different version of an item".
+ var installLocation = em.getInstallLocation(itemID);
+ if (!installLocation) {
+ // This is not an "upgrade", since we don't have any location data for the
+ // extension ID specified - that is, it's not in our database.
+
+ // Caller supplied a key to a registered location, use that location
+ // for the installation
+ installLocation = InstallLocations.get(aInstallLocationKey);
+ if (installLocation) {
+ // If the specified location does not have a common metadata location
+ // (e.g. extensions have no common root, or other location specified
+ // by the location implementation) - e.g. for a Registry Key enumeration
+ // location - we cannot install or upgrade using a XPI file, probably
+ // because these application types will be handling upgrading themselves.
+ // Just bail.
+ if (!installLocation.location) {
+ LOG("Install Location \"" + installLocation.name + "\" does not support " +
+ "installation of items from XPI/JAR files. You must manage " +
+ "installation and update of these items yourself.");
+ installLocation = null;
+ }
+ }
+ else {
+ // In the absence of a preferred install location, just default to
+ // the App-Profile
+ installLocation = InstallLocations.get(KEY_APP_PROFILE);
+ }
+ }
+ else {
+ // This is an "upgrade", but not through the Update System, because the
+ // Update code will not let an extension with an incompatible target
+ // app version range through to this point. This is an "upgrade" in the
+ // sense that the user found a different version of an installed extension
+ // and installed it through the web interface, so we have metadata.
+
+ // If the location is different, return the preferred location rather than
+ // the location of the currently installed version, because we may be in
+ // the situation where an item is being installed into the global app
+ // dir when there's a version in the profile dir.
+ if (installLocation.name != aInstallLocationKey)
+ installLocation = InstallLocations.get(aInstallLocationKey);
+ }
+ if (!installLocation.canAccess) {
+ LOG("Install Location\"" + installLocation.name + "\" cannot be written " +
+ "to with your access privileges. Installation will not proceed.");
+ installLocation = null;
+ }
+ return installLocation;
+ }
+
+ /**
+ * Stages a XPI file in the default item location specified by other
+ * applications when they registered with XulRunner if the item's
+ * install manifest specified compatibility with them.
+ */
+ function stageXPIForOtherApps(xpiFile, installData) {
+ for (var i = 0; i < installData.targetApps.length; ++i) {
+ var targetApp = installData.targetApps[i];
+ if (targetApp.id != gApp.ID && targetApp.id != TOOLKIT_ID) {
+ /* XXXben uncomment when this works!
+ var settingsThingy = Cc[].
+ getService(Ci.nsIXULRunnerSettingsThingy);
+ try {
+ var appPrefix = "SOFTWARE\\Mozilla\\XULRunner\\Applications\\";
+ var branch = settingsThingy.getBranch(appPrefix + targetApp.id);
+ var path = branch.getProperty("ExtensionsLocation");
+ var destination = Cc["@mozilla.org/file/local;1"].
+ createInstance(Ci.nsILocalFile);
+ destination.initWithPath(path);
+ xpiFile.copyTo(file, xpiFile.leafName);
+ }
+ catch (e) {
+ }
+ */
+ }
+ }
+ }
+
+ /**
+ * Extracts and then starts the install for extensions / themes contained
+ * within a xpi.
+ */
+ function installMultiXPI(xpiFile, installData) {
+ var fileURL = getURIFromFile(xpiFile).QueryInterface(Ci.nsIURL);
+ if (fileURL.fileExtension.toLowerCase() != "xpi") {
+ LOG("Invalid File Extension: Item: \"" + fileURL.fileName + "\" has an " +
+ "invalid file extension. Only xpi file extensions are allowed for " +
+ "multiple item packages.");
+ var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ showMessage("invalidFileExtTitle", [],
+ "invalidFileExtMessage", [installData.name,
+ fileURL.fileExtension,
+ bundle.GetStringFromName("type-" + installData.type)]);
+ return;
+ }
+
+ try {
+ var zipReader = getZipReaderForFile(xpiFile);
+ }
+ catch (e) {
+ LOG("installMultiXPI: failed to open xpi file: " + xpiFile.path);
+ throw e;
+ }
+
+ var searchForEntries = ["*.xpi", "*.jar"];
+ var files = [];
+ for (var i = 0; i < searchForEntries.length; ++i) {
+ var entries = zipReader.findEntries(searchForEntries[i]);
+ while (entries.hasMore()) {
+ var entryName = entries.getNext();
+ var target = getFile(KEY_TEMPDIR, [entryName]);
+ try {
+ target.createUnique(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ }
+ catch (e) {
+ LOG("installMultiXPI: failed to create target file for extraction " +
+ " file = " + target.path + ", exception = " + e + "\n");
+ }
+ zipReader.extract(entryName, target);
+ files.push(target);
+ }
+ }
+ zipReader.close();
+
+ if (files.length == 0) {
+ LOG("Multiple Item Package: Item: \"" + fileURL.fileName + "\" does " +
+ "not contain a valid package to install.");
+ var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ showMessage("missingPackageFilesTitle",
+ [bundle.GetStringFromName("type-" + installData.type)],
+ "missingPackageFilesMessage", [installData.name,
+ bundle.GetStringFromName("type-" + installData.type)]);
+ return;
+ }
+
+ for (i = 0; i < files.length; ++i) {
+ em.installItemFromFileInternal(files[i], aInstallLocationKey, null);
+ files[i].remove(false);
+ }
+ }
+
+ /**
+ * An observer for the Extension Update System.
+ * @constructor
+ */
+ function IncompatibleObserver() {}
+ IncompatibleObserver.prototype = {
+ _xpi: null,
+ _installManifest: null,
+
+ /**
+ * Ask the Extension Update System if there are any version updates for
+ * this item that will allow it to be compatible with this version of
+ * the Application.
+ * @param item
+ * An nsIUpdateItem representing the item being installed.
+ * @param installManifest
+ * The Install Manifest datasource for the item.
+ * @param xpiFile
+ * The staged source XPI file that contains the item. Cleaned
+ * up by this process.
+ * @param installRDF
+ * The install.rdf file that was extracted from the xpi.
+ */
+ checkForUpdates: function IncObs_checkForUpdates(item, installManifest, xpiFile) {
+ this._xpi = xpiFile;
+ this._installManifest = installManifest;
+
+ for (var i = 0; i < em._installListeners.length; ++i)
+ em._installListeners[i].onCompatibilityCheckStarted(item);
+ em._compatibilityCheckCount++;
+ em.update([item], 1, Ci.nsIExtensionManager.UPDATE_CHECK_COMPATIBILITY, this);
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onUpdateStarted: function IncObs_onUpdateStarted() {
+ LOG("Phone Home Listener: Update Started");
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onUpdateEnded: function IncObs_onUpdateEnded() {
+ LOG("Phone Home Listener: Update Ended");
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onAddonUpdateStarted: function IncObs_onAddonUpdateStarted(addon) {
+ if (!addon)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ LOG("Phone Home Listener: Update For " + addon.id + " started");
+ em.datasource.addIncompatibleUpdateItem(addon.name, this._xpi.path,
+ addon.type, addon.version);
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onAddonUpdateEnded: function IncObs_onAddonUpdateEnded(addon, status) {
+ if (!addon)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ LOG("Phone Home Listener: Update For " + addon.id + " ended, status = " + status);
+ em.datasource.removeDownload(this._xpi.path);
+ LOG("Version Check Phone Home Completed");
+
+ for (var i = 0; i < em._installListeners.length; ++i)
+ em._installListeners[i].onCompatibilityCheckEnded(addon, status);
+
+ // Only compatibility updates (e.g. STATUS_VERSIONINFO) are currently
+ // supported
+ if (status == Ci.nsIAddonUpdateCheckListener.STATUS_VERSIONINFO) {
+ em.datasource.setTargetApplicationInfo(addon.id,
+ addon.targetAppID,
+ addon.minAppVersion,
+ addon.maxAppVersion,
+ this._installManifest);
+
+ // Try and install again, but use the updated compatibility DB.
+ // This will send out an apropriate onInstallEnded notification for us.
+ var status = em.installItemFromFileInternal(this._xpi,
+ aInstallLocationKey,
+ this._installManifest);
+
+ // The install may still have failed at this point due to the blocklist
+ if (status == INSTALLERROR_SUCCESS) {
+ // Add the updated compatibility info to the datasource if done
+ if (StartupCache.entries[aInstallLocationKey][addon.id].op == OP_NONE) {
+ em.datasource.setTargetApplicationInfo(addon.id,
+ addon.targetAppID,
+ addon.minAppVersion,
+ addon.maxAppVersion,
+ null);
+ }
+ else { // needs a restart
+ // Add updatedMinVersion and updatedMaxVersion so it can be used
+ // to update the datasource during the installation or upgrade.
+ em.datasource.setUpdatedTargetAppInfo(addon.id,
+ addon.targetAppID,
+ addon.minAppVersion,
+ addon.maxAppVersion,
+ null);
+ }
+ }
+ }
+ else {
+ em.datasource.removeDownload(this._xpi.path);
+ showIncompatibleError(installData);
+ LOG("Add-on " + addon.id + " is incompatible with " +
+ BundleManager.appName + " " + gApp.version + ", Toolkit " +
+ gApp.platformVersion + ". Remote compatibility check did not " +
+ "resolve this.");
+
+ for (var i = 0; i < em._installListeners.length; ++i)
+ em._installListeners[i].onInstallEnded(addon, INSTALLERROR_INCOMPATIBLE_VERSION);
+
+ // We are responsible for cleaning up this file!
+ InstallLocations.get(aInstallLocationKey).removeFile(this._xpi);
+ }
+
+ em._compatibilityCheckCount--;
+ // If there are no more compatibility checks running and no downloads in
+ // progress then the install operations are complete.
+ if (em._compatibilityCheckCount == 0 && em._transactions.length == 0) {
+ for (var i = 0; i < em._installListeners.length; ++i)
+ em._installListeners[i].onInstallsCompleted();
+ }
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonUpdateCheckListener])
+ }
+
+ var shouldPhoneHomeIfNecessary = false;
+ if (!aInstallManifest) {
+ // If we were not called with an Install Manifest, we were called from
+ // some other path than the Phone Home system, so we do want to phone
+ // home if the version is incompatible. As this is the first point in the
+ // install process we must notify observers here.
+
+ var addon = makeItem(getURIFromFile(aXPIFile).spec, "",
+ aInstallLocationKey, "", "", "",
+ getURIFromFile(aXPIFile).spec,
+ "", "", "", "", 0, gApp.id);
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onInstallStarted(addon);
+
+ shouldPhoneHomeIfNecessary = true;
+ var installManifest = null;
+ var installManifestFile = extractRDFFileToTempDir(aXPIFile,
+ FILE_INSTALL_MANIFEST,
+ true);
+ if (installManifestFile.exists()) {
+ installManifest = getInstallManifest(installManifestFile);
+ installManifestFile.remove(false);
+ }
+ if (!installManifest) {
+ LOG("The Install Manifest supplied by this item is not well-formed. " +
+ "Installation will not proceed.");
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onInstallEnded(addon, INSTALLERROR_INVALID_MANIFEST);
+ return INSTALLERROR_INVALID_MANIFEST;
+ }
+ }
+ else
+ installManifest = aInstallManifest;
+
+ var installData = this._getInstallData(installManifest);
+ // Recreate the add-on item with the full detail from the install manifest
+ addon = makeItem(installData.id, installData.version,
+ aInstallLocationKey,
+ installData.currentApp ? installData.currentApp.minVersion : "",
+ installData.currentApp ? installData.currentApp.maxVersion : "",
+ installData.name,
+ getURIFromFile(aXPIFile).spec,
+ "", /* XPI Update Hash */
+ "", /* Icon URL */
+ installData.updateURL || "",
+ installData.updateKey || "",
+ installData.type,
+ installData.currentApp ? installData.currentApp.id : "");
+
+ switch (installData.error) {
+ case INSTALLERROR_INCOMPATIBLE_VERSION:
+ // Since the caller cleans up |aXPIFile|, and we're not yet sure whether or
+ // not we need it (we may need it if a remote version bump that makes it
+ // compatible is discovered by the call home) - so we must stage it for
+ // later ourselves.
+ if (shouldPhoneHomeIfNecessary && installData.currentApp) {
+ var installLocation = getInstallLocation(installData.id, aInstallLocationKey);
+ if (!installLocation)
+ return INSTALLERROR_INCOMPATIBLE_VERSION;
+ var stagedFile = installLocation.stageFile(aXPIFile, installData.id);
+ (new IncompatibleObserver(this)).checkForUpdates(addon, installManifest,
+ stagedFile);
+ // Return early to prevent deletion of the install manifest file.
+ return INSTALLERROR_PHONING_HOME;
+ }
+ else {
+ // XXXben Look up XULRunnerSettingsThingy to see if there is a registered
+ // app that can handle this item, if so just stage and don't show
+ // this error!
+ showIncompatibleError(installData);
+ LOG("Add-on " + installData.id + " is incompatible with " +
+ BundleManager.appName + " " + gApp.version + ", Toolkit " +
+ gApp.platformVersion + ". Remote compatibility check was not performed.");
+ }
+ break;
+ case INSTALLERROR_SOFTBLOCKED:
+ if (!showBlocklistMessage(installData, true))
+ break;
+ installData.error = INSTALLERROR_SUCCESS;
+ // Fall through to continue the install
+ case INSTALLERROR_SUCCESS:
+ // Installation of multiple extensions / themes contained within a single xpi.
+ if (installData.type == Ci.nsIUpdateItem.TYPE_MULTI_XPI) {
+ installMultiXPI(aXPIFile, installData);
+ break;
+ }
+
+ // Stage the extension's XPI so it can be extracted at the next restart.
+ var installLocation = getInstallLocation(installData.id, aInstallLocationKey);
+ if (!installLocation) {
+ // No cleanup of any of the staged XPI files should be required here,
+ // because this should only ever fail on the first recurse through
+ // this function, BEFORE staging takes place... technically speaking
+ // a location could become readonly during the phone home process,
+ // but that's an edge case I don't care about.
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onInstallEnded(addon, INSTALLERROR_RESTRICTED);
+ return INSTALLERROR_RESTRICTED;
+ }
+
+ // Stage a copy of the XPI/JAR file for our own evil purposes...
+ stagedFile = installLocation.stageFile(aXPIFile, installData.id);
+
+ var restartRequired = this.installRequiresRestart(installData.id,
+ installData.type);
+ // Determine which configuration function to use based on whether or not
+ // there is data about this item in our datasource already - if there is
+ // we want to upgrade, otherwise we install fresh.
+ var ds = this.datasource;
+ if (installData.id in ds.visibleItems && ds.visibleItems[installData.id]) {
+ // We enter this function if any data corresponding to an existing GUID
+ // is found, regardless of its Install Location. We need to check before
+ // "upgrading" an item that Install Location of the new item is of equal
+ // or higher priority than the old item, to make sure the datasource only
+ // ever tracks metadata for active items.
+ var oldInstallLocation = this.getInstallLocation(installData.id);
+ if (oldInstallLocation.priority >= installLocation.priority) {
+ this._upgradeItem(installManifest, installData.id, installLocation,
+ installData.type);
+ if (!restartRequired) {
+ this._finalizeUpgrade(installData.id, installLocation);
+ this._finalizeInstall(installData.id, stagedFile);
+ }
+ }
+ }
+ else {
+ this._configureForthcomingItem(installManifest, installData.id,
+ installLocation, installData.type);
+ if (!restartRequired) {
+ this._finalizeInstall(installData.id, stagedFile);
+ if (installData.type == Ci.nsIUpdateItem.TYPE_THEME) {
+ var internalName = this.datasource.getItemProperty(installData.id, "internalName");
+ if (gPref.getBoolPref(PREF_EM_DSS_ENABLED)) {
+ gPref.setCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN, internalName);
+ }
+ else {
+ gPref.setBoolPref(PREF_DSS_SWITCHPENDING, true);
+ gPref.setCharPref(PREF_DSS_SKIN_TO_SELECT, internalName);
+ }
+ }
+ }
+ }
+ this._updateManifests(restartRequired);
+ break;
+ case INSTALLERROR_INVALID_GUID:
+ LOG("Invalid GUID: Item has GUID: \"" + installData.id + "\"" +
+ " which is not well-formed.");
+ var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ showMessage("incompatibleTitle",
+ [bundle.GetStringFromName("type-" + installData.type)],
+ "invalidGUIDMessage", [installData.name, installData.id]);
+ break;
+ case INSTALLERROR_INVALID_VERSION:
+ LOG("Invalid Version: Item: \"" + installData.id + "\" has version " +
+ installData.version + " which is not well-formed.");
+ var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ showMessage("incompatibleTitle",
+ [bundle.GetStringFromName("type-" + installData.type)],
+ "invalidVersionMessage", [installData.name, installData.version]);
+ break;
+ case INSTALLERROR_INCOMPATIBLE_PLATFORM:
+ const osABI = gOSTarget + "_" + gXPCOMABI;
+ LOG("Incompatible Platform: Item: \"" + installData.id + "\" is not " +
+ "compatible with '" + osABI + "'.");
+ var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ showMessage("incompatibleTitle",
+ [bundle.GetStringFromName("type-" + installData.type)],
+ "incompatiblePlatformMessage",
+ [installData.name, BundleManager.appName, osABI]);
+ break;
+ case INSTALLERROR_BLOCKLISTED:
+ LOG("Blocklisted Item: Item: \"" + installData.id + "\" version " +
+ installData.version + " was not installed.");
+ showBlocklistMessage(installData, false);
+ break;
+ case INSTALLERROR_INSECURE_UPDATE:
+ LOG("No secure updates: Item: \"" + installData.id + "\" version " +
+ installData.version + " was not installed.");
+ var bundle = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ showMessage("incompatibleTitle",
+ [bundle.GetStringFromName("type-" + installData.type)],
+ "insecureUpdateMessage", [installData.name]);
+ break;
+ default:
+ break;
+ }
+
+ // Check to see if this item supports other applications and in that case
+ // stage the the XPI file in the location specified by those applications.
+ stageXPIForOtherApps(aXPIFile, installData);
+
+ // The install of this item is complete, notify observers
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onInstallEnded(addon, installData.error);
+
+ return installData.error;
+ },
+
+ /**
+ * Whether or not this type's installation/uninstallation requires
+ * the application to be restarted.
+ * @param id
+ * The GUID of the item
+ * @param type
+ * The nsIUpdateItem type of the item
+ * @returns true if installation of an item of this type requires a
+ * restart.
+ */
+ installRequiresRestart: function EM_installRequiresRestart(id, type) {
+ switch (type) {
+ case Ci.nsIUpdateItem.TYPE_THEME:
+ var internalName = this.datasource.getItemProperty(id, "internalName");
+ var needsRestart = false;
+ if (gPref.prefHasUserValue(PREF_DSS_SKIN_TO_SELECT))
+ needsRestart = internalName == gPref.getCharPref(PREF_DSS_SKIN_TO_SELECT);
+ if (!needsRestart &&
+ gPref.prefHasUserValue(PREF_GENERAL_SKINS_SELECTEDSKIN))
+ needsRestart = internalName == gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
+ return needsRestart;
+ }
+ return ((type & Ci.nsIUpdateItem.TYPE_ADDON) > 0);
+ },
+
+ /**
+ * Perform initial configuration on an item that has just or will be
+ * installed. This inserts the item into the appropriate container in the
+ * datasource, so that the application UI shows the item even if it will
+ * not actually be installed until the next restart.
+ * @param installManifest
+ * The Install Manifest datasource that describes this item.
+ * @param id
+ * The GUID of this item.
+ * @param installLocation
+ * The Install Location where this item is installed.
+ * @param type
+ * The nsIUpdateItem type of this item.
+ */
+ _configureForthcomingItem: function EM__configureForthcomingItem(installManifest,
+ id,
+ installLocation,
+ type) {
+ var ds = this.datasource;
+ ds.updateVisibleList(id, installLocation.name, false);
+
+ var name = null;
+ var localized = findClosestLocalizedResource(installManifest, gInstallManifestRoot);
+ if (localized)
+ name = installManifest.GetTarget(localized, EM_R("name"), true);
+ else
+ name = EM_L(getManifestProperty(installManifest, "name"));
+
+ var props = { name : name,
+ version : EM_L(getManifestProperty(installManifest, "version")),
+ newVersion : EM_L(getManifestProperty(installManifest, "version")),
+ installLocation : EM_L(installLocation.name),
+ type : EM_I(type),
+ availableUpdateURL : null,
+ availableUpdateHash : null,
+ availableUpdateVersion: null,
+ availableUpdateInfo : null };
+ ds.setItemProperties(id, props);
+ ds.updateProperty(id, "availableUpdateURL");
+
+ this._setOp(id, OP_NEEDS_INSTALL);
+
+ // Insert it into the child list NOW rather than later because:
+ // - extensions installed using the command line need to be a member
+ // of a container during the install phase for the code to be able
+ // to identify profile vs. global
+ // - extensions installed through the UI should show some kind of
+ // feedback to indicate their presence is forthcoming (i.e. they
+ // will be available after a restart).
+ ds.insertItemIntoContainer(id);
+
+ this._notifyAction(id, EM_ITEM_INSTALLED);
+ },
+
+ /**
+ * Perform configuration on an item that has just or will be upgraded.
+ * @param installManifest
+ * The Install Manifest datasource that describes this item.
+ * @param itemID
+ * The GUID of this item.
+ * @param installLocation
+ * The Install Location where this item is installed.
+ * @param type
+ * The nsIUpdateItem type of this item.
+ */
+ _upgradeItem: function EM__upgradeItem(installManifest, id, installLocation, type) {
+ // Don't change any props that would need to be reset if the install fails.
+ // They will be reset as appropriate by the upgrade/install process.
+ var ds = this.datasource;
+ ds.updateVisibleList(id, installLocation.name, false);
+ var props = { installLocation : EM_L(installLocation.name),
+ type : EM_I(type),
+ newVersion : EM_L(getManifestProperty(installManifest, "version")),
+ availableUpdateURL : null,
+ availableUpdateHash : null,
+ availableUpdateVersion : null,
+ availableUpdateInfo : null };
+ ds.setItemProperties(id, props);
+ ds.updateProperty(id, "availableUpdateURL");
+
+ this._setOp(id, OP_NEEDS_UPGRADE);
+ this._notifyAction(id, EM_ITEM_UPGRADED);
+ },
+
+ /**
+ * Completes an Extension's installation.
+ * @param id
+ * The GUID of the Extension to install.
+ * @param file
+ * The XPI/JAR file to install from. If this is null, we try to
+ * determine the stage file location from the ID.
+ */
+ _finalizeInstall: function EM__finalizeInstall(id, file) {
+ var ds = this.datasource;
+ var type = ds.getItemProperty(id, "type");
+ if (id == 0 || id == -1) {
+ ds.removeCorruptItem(id);
+ return;
+ }
+ var installLocation = this.getInstallLocation(id);
+ if (!installLocation) {
+ // If the install location is null, that means we've reached the finalize
+ // state without the item ever having metadata added for it, which implies
+ // bogus data in the Startup Cache. Clear the entries and don't do anything
+ // else.
+ var entries = StartupCache.findEntries(id);
+ for (var i = 0; i < entries.length; ++i) {
+ var location = InstallLocations.get(entries[i].location);
+ StartupCache.clearEntry(location, id);
+ PendingOperations.clearItem(OP_NEEDS_INSTALL, id);
+ }
+ return;
+ }
+ var itemLocation = installLocation.getItemLocation(id);
+
+ if (!file && "stageFile" in installLocation)
+ file = installLocation.getStageFile(id);
+
+ // If |file| is null or does not exist, the installer assumes the item is
+ // a dropped-in directory.
+ var installer = new Installer(this.datasource, id, installLocation, type);
+ installer.installFromFile(file);
+
+ // If the file was staged, we must clean it up ourselves, otherwise the
+ // EM caller is responsible for doing so (e.g. XPInstall)
+ if (file)
+ installLocation.removeFile(file);
+
+ // Clear the op flag from the Startup Cache and Pending Operations sets
+ StartupCache.put(installLocation, id, OP_NONE, true);
+ PendingOperations.clearItem(OP_NEEDS_INSTALL, id);
+ },
+
+ /**
+ * Removes an item's metadata in preparation for an upgrade-install.
+ * @param id
+ * The GUID of the item to uninstall.
+ * @param installLocation
+ * The nsIInstallLocation of the item
+ */
+ _finalizeUpgrade: function EM__finalizeUpgrade(id, installLocation) {
+ // Retrieve the item properties *BEFORE* we clean the resource!
+ var ds = this.datasource;
+
+ var stagedFile = null;
+ if ("getStageFile" in installLocation)
+ stagedFile = installLocation.getStageFile(id);
+
+ if (stagedFile)
+ var installRDF = extractRDFFileToTempDir(stagedFile, FILE_INSTALL_MANIFEST, true);
+ else
+ installRDF = installLocation.getItemFile(id, FILE_INSTALL_MANIFEST);
+ if (installRDF.exists()) {
+ var installManifest = getInstallManifest(installRDF);
+ if (installManifest) {
+ var type = getAddonTypeFromInstallManifest(installManifest);
+ var userDisabled = ds.getItemProperty(id, "userDisabled") == "true";
+
+ // Clean the item resource
+ ds.removeItemMetadata(id);
+ // Now set up the properties on the item to mimic an item in its
+ // "initial state" for installation.
+ this._configureForthcomingItem(installManifest, id, installLocation,
+ type);
+ if (userDisabled)
+ ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));
+ }
+ if (stagedFile)
+ installRDF.remove(false);
+ }
+ // Clear the op flag from the Pending Operations set. Do NOT clear op flag in
+ // the startup cache since this may have been reset to OP_NEEDS_INSTALL by
+ // |_configureForthcomingItem|.
+ PendingOperations.clearItem(OP_NEEDS_UPGRADE, id);
+ },
+
+ /**
+ * Completes an item's uninstallation.
+ * @param id
+ * The GUID of the item to uninstall.
+ */
+ _finalizeUninstall: function EM__finalizeUninstall(id) {
+ var ds = this.datasource;
+
+ var installLocation = this.getInstallLocation(id);
+ if (!installLocation.itemIsManagedIndependently(id)) {
+ try {
+ // Having a callback that does nothing just causes the directory to be
+ // removed.
+ safeInstallOperation(id, installLocation,
+ { data: null, callback: function() { } });
+ }
+ catch (e) {
+ ERROR("_finalizeUninstall: failed to remove directory for item: " + id +
+ " at Install Location: " + installLocation.name + ", rolling back uninstall");
+ var manifest = installLocation.getItemFile(id, "FILE_INSTALL_MANIFEST");
+ // If there is no manifest then either the rollback failed, or there was
+ // no manifest in the first place. Either way this item is now invalid
+ // and we shouldn't try to re-install it.
+ if (manifest.exists()) {
+ // Removal of the files failed, reset the uninstalled flag and rewrite
+ // the install manifests so this item's components are registered.
+ // Clear the op flag from the Startup Cache
+ StartupCache.put(installLocation, id, OP_NONE, true);
+ var restartRequired = this.installRequiresRestart(id, ds.getItemProperty(id, "type"))
+ this._updateManifests(restartRequired);
+ return;
+ }
+ }
+ }
+ else if (installLocation.name == KEY_APP_PROFILE ||
+ installLocation.name == KEY_APP_GLOBAL ||
+ installLocation.name == KEY_APP_SYSTEM_USER) {
+ // Check for a pointer file and remove it if it exists
+ var pointerFile = installLocation.location.clone();
+ pointerFile.append(id);
+ if (pointerFile.exists() && !pointerFile.isDirectory())
+ pointerFile.remove(false);
+ }
+
+ // Clean the item resource
+ ds.removeItemMetadata(id);
+
+ // Do this LAST since inferences are made about an item based on
+ // what container it's in.
+ ds.removeItemFromContainer(id);
+
+ // Clear the op flag from the Startup Cache and the Pending Operations set.
+ StartupCache.clearEntry(installLocation, id);
+ PendingOperations.clearItem(OP_NEEDS_UNINSTALL, id);
+ },
+
+ /**
+ * Uninstalls an item. If the uninstallation cannot be performed immediately
+ * it is scheduled for the next restart.
+ * @param id
+ * The GUID of the item to uninstall.
+ */
+ uninstallItem: function EM_uninstallItem(id) {
+ var ds = this.datasource;
+ ds.updateDownloadState(PREFIX_ITEM_URI + id, null);
+ if (!ds.isDownloadItem(id)) {
+ var opType = ds.getItemProperty(id, "opType");
+ var installLocation = this.getInstallLocation(id);
+ // Removes any staged xpis for this item.
+ if (opType == OP_NEEDS_UPGRADE || opType == OP_NEEDS_INSTALL) {
+ var stageFile = installLocation.getStageFile(id);
+ if (stageFile)
+ installLocation.removeFile(stageFile);
+ }
+ // Addons with an opType of OP_NEEDS_INSTALL only have a staged xpi file
+ // and are removed immediately since the uninstall can't be canceled.
+ if (opType == OP_NEEDS_INSTALL) {
+ ds.removeItemMetadata(id);
+ ds.removeItemFromContainer(id);
+ ds.updateVisibleList(id, null, true);
+ StartupCache.clearEntry(installLocation, id);
+ this._updateManifests(false);
+ }
+ else {
+ if (opType == OP_NEEDS_UPGRADE)
+ ds.setItemProperty(id, "newVersion", null);
+ this._setOp(id, OP_NEEDS_UNINSTALL);
+ var type = ds.getItemProperty(id, "type");
+ var restartRequired = this.installRequiresRestart(id, type);
+ if (!restartRequired) {
+ this._finalizeUninstall(id);
+ this._updateManifests(restartRequired);
+ }
+ }
+ }
+ else {
+ // Bad download entry - uri is url, e.g. "http://www.foo.com/test.xpi"
+ // ... just remove it from the list.
+ ds.removeCorruptDLItem(id);
+ }
+
+ this._notifyAction(id, EM_ITEM_UNINSTALLED);
+ },
+
+ /* See nsIExtensionManager.idl */
+ cancelInstallItem: function EM_cancelInstallItem(id) {
+ var ds = this.datasource;
+ var opType = ds.getItemProperty(id, "opType");
+ if (opType != OP_NEEDS_UPGRADE && opType != OP_NEEDS_INSTALL)
+ return;
+
+ ds.updateDownloadState(PREFIX_ITEM_URI + id, null);
+ var installLocation = this.getInstallLocation(id);
+ // Removes any staged xpis for this item.
+ var stageFile = installLocation.getStageFile(id);
+ if (stageFile)
+ installLocation.removeFile(stageFile);
+ // Addons with an opType of OP_NEEDS_INSTALL only have a staged xpi file
+ // and just need to be removed completely from the ds.
+ if (opType == OP_NEEDS_INSTALL) {
+ ds.removeItemMetadata(id);
+ ds.removeItemFromContainer(id);
+ ds.updateVisibleList(id, null, true);
+ StartupCache.clearEntry(installLocation, id);
+ this._updateManifests(false);
+ this._notifyAction(id, EM_ITEM_CANCEL);
+ }
+ else {
+ // Clear upgrade information and reset any request to enable/disable.
+ ds.setItemProperty(id, EM_R("newVersion"), null);
+ var appDisabled = ds.getItemProperty(id, "appDisabled");
+ var userDisabled = ds.getItemProperty(id, "userDisabled");
+ if (appDisabled == "true" || appDisabled == OP_NONE && userDisabled == OP_NONE) {
+ this._setOp(id, OP_NONE);
+ this._notifyAction(id, EM_ITEM_CANCEL);
+ }
+ else if (appDisabled == OP_NEEDS_DISABLE || userDisabled == OP_NEEDS_DISABLE) {
+ this._setOp(id, OP_NEEDS_DISABLE);
+ this._notifyAction(id, EM_ITEM_DISABLED);
+ }
+ else if (appDisabled == OP_NEEDS_ENABLE || userDisabled == OP_NEEDS_ENABLE) {
+ this._setOp(id, OP_NEEDS_ENABLE);
+ this._notifyAction(id, EM_ITEM_ENABLED);
+ }
+ else {
+ this._setOp(id, OP_NONE);
+ this._notifyAction(id, EM_ITEM_CANCEL);
+ }
+ }
+ },
+
+ /**
+ * Cancels a pending uninstall of an item
+ * @param id
+ * The ID of the item.
+ */
+ cancelUninstallItem: function EM_cancelUninstallItem(id) {
+ var ds = this.datasource;
+ var appDisabled = ds.getItemProperty(id, "appDisabled");
+ var userDisabled = ds.getItemProperty(id, "userDisabled");
+ if (appDisabled == "true" || appDisabled == OP_NONE && userDisabled == OP_NONE) {
+ this._setOp(id, OP_NONE);
+ this._notifyAction(id, EM_ITEM_CANCEL);
+ }
+ else if (appDisabled == OP_NEEDS_DISABLE || userDisabled == OP_NEEDS_DISABLE) {
+ this._setOp(id, OP_NEEDS_DISABLE);
+ this._notifyAction(id, EM_ITEM_DISABLED);
+ }
+ else if (appDisabled == OP_NEEDS_ENABLE || userDisabled == OP_NEEDS_ENABLE) {
+ this._setOp(id, OP_NEEDS_ENABLE);
+ this._notifyAction(id, EM_ITEM_ENABLED);
+ }
+ else {
+ this._setOp(id, OP_NONE);
+ this._notifyAction(id, EM_ITEM_CANCEL);
+ }
+ },
+
+ /**
+ * Sets the pending operation for a visible item.
+ * @param id
+ * The GUID of the item
+ * @param op
+ * The name of the operation to be performed
+ */
+ _setOp: function EM__setOp(id, op) {
+ var location = this.getInstallLocation(id);
+ StartupCache.put(location, id, op, true);
+ PendingOperations.addItem(op, { locationKey: location.name, id: id });
+ var ds = this.datasource;
+ if (op == OP_NEEDS_INSTALL || op == OP_NEEDS_UPGRADE)
+ ds.updateDownloadState(PREFIX_ITEM_URI + id, "success");
+
+ ds.updateProperty(id, "opType");
+ ds.updateProperty(id, "updateable");
+ ds.updateProperty(id, "satisfiesDependencies");
+ var restartRequired = this.installRequiresRestart(id, ds.getItemProperty(id, "type"))
+ this._updateDependentItemsForID(id);
+ this._updateManifests(restartRequired);
+ },
+
+ /**
+ * Note on appDisabled and userDisabled property arcs.
+ * The appDisabled and userDisabled RDF property arcs are used to store
+ * the pending operation for app disabling and user disabling for an item as
+ * well as the user and app disabled status after the pending operation has
+ * been completed upon restart. When the appDisabled value changes the value
+ * of userDisabled is reset to prevent the state of widgets and status
+ * messages from being in an incorrect state.
+ */
+
+ /**
+ * Enables an item for the application (e.g. the item satisfies all
+ * requirements like app compatibility for it to be enabled). The appDisabled
+ * property arc will be removed if the item will be app disabled on next
+ * restart to cancel the app disabled operation for the item otherwise the
+ * property value will be set to OP_NEEDS_ENABLE. The item's pending
+ * operations are then evaluated in order to set the operation to perform
+ * and notify the observers if the operation has been changed.
+ * See "Note on appDisabled and userDisabled property arcs" above.
+ * @param id
+ * The ID of the item to be enabled by the application.
+ */
+ _appEnableItem: function EM__appEnableItem(id) {
+ var ds = this.datasource;
+ var appDisabled = ds.getItemProperty(id, "appDisabled");
+ if (appDisabled == OP_NONE || appDisabled == OP_NEEDS_ENABLE)
+ return;
+
+ var opType = ds.getItemProperty(id, "opType");
+ var userDisabled = ds.getItemProperty(id, "userDisabled");
+ // reset user disabled if it has a pending operation to prevent the ui
+ // state from getting confused as to an item's current state.
+ if (userDisabled == OP_NEEDS_DISABLE)
+ ds.setItemProperty(id, EM_R("userDisabled"), null);
+ else if (userDisabled == OP_NEEDS_ENABLE)
+ ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));
+
+ if (appDisabled == OP_NEEDS_DISABLE)
+ ds.setItemProperty(id, EM_R("appDisabled"), null);
+ else if (appDisabled == "true")
+ ds.setItemProperty(id, EM_R("appDisabled"), EM_L(OP_NEEDS_ENABLE));
+
+ // Don't set a new operation when there is a pending uninstall operation.
+ if (opType == OP_NEEDS_UNINSTALL) {
+ this._updateDependentItemsForID(id);
+ return;
+ }
+
+ var operation, action;
+ // if this item is already enabled or user disabled don't set a pending
+ // operation - instead immediately enable it and reset the operation type
+ // if needed.
+ if (appDisabled == OP_NEEDS_DISABLE || appDisabled == OP_NONE ||
+ userDisabled == "true") {
+ if (opType != OP_NONE) {
+ operation = OP_NONE;
+ action = EM_ITEM_CANCEL;
+ }
+ }
+ else {
+ if (opType != OP_NEEDS_ENABLE) {
+ operation = OP_NEEDS_ENABLE;
+ action = EM_ITEM_ENABLED;
+ }
+ }
+
+ if (action) {
+ this._setOp(id, operation);
+ this._notifyAction(id, action);
+ }
+ else {
+ ds.updateProperty(id, "satisfiesDependencies");
+ this._updateDependentItemsForID(id);
+ }
+ },
+
+ /**
+ * Disables an item for the application (e.g. the item doesn't satisfy all
+ * requirements like app compatibility for it to be enabled). The appDisabled
+ * property arc will be set to true if the item will be app enabled on next
+ * restart to cancel the app enabled operation for the item otherwise the
+ * property value will be set to OP_NEEDS_DISABLE. The item's pending
+ * operations are then evaluated in order to set the operation to perform
+ * and notify the observers if the operation has been changed.
+ * See "Note on appDisabled and userDisabled property arcs" above.
+ * @param id
+ * The ID of the item to be disabled by the application.
+ */
+ _appDisableItem: function EM__appDisableItem(id) {
+ var ds = this.datasource;
+ var appDisabled = ds.getItemProperty(id, "appDisabled");
+ if (appDisabled == "true" || appDisabled == OP_NEEDS_DISABLE)
+ return;
+
+ var opType = ds.getItemProperty(id, "opType");
+ var userDisabled = ds.getItemProperty(id, "userDisabled");
+
+ // reset user disabled if it has a pending operation to prevent the ui
+ // state from getting confused as to an item's current state.
+ if (userDisabled == OP_NEEDS_DISABLE)
+ ds.setItemProperty(id, EM_R("userDisabled"), null);
+ else if (userDisabled == OP_NEEDS_ENABLE)
+ ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));
+
+ if (appDisabled == OP_NEEDS_ENABLE || userDisabled == OP_NEEDS_ENABLE ||
+ ds.getItemProperty(id, "userDisabled") == "true")
+ ds.setItemProperty(id, EM_R("appDisabled"), EM_L("true"));
+ else if (appDisabled == OP_NONE)
+ ds.setItemProperty(id, EM_R("appDisabled"), EM_L(OP_NEEDS_DISABLE));
+
+ // Don't set a new operation when there is a pending uninstall operation.
+ if (opType == OP_NEEDS_UNINSTALL) {
+ this._updateDependentItemsForID(id);
+ return;
+ }
+
+ var operation, action;
+ // if this item is already disabled don't set a pending operation - instead
+ // immediately disable it and reset the operation type if needed.
+ if (appDisabled == OP_NEEDS_ENABLE || appDisabled == "true" ||
+ userDisabled == OP_NEEDS_ENABLE || userDisabled == "true") {
+ if (opType != OP_NONE) {
+ operation = OP_NONE;
+ action = EM_ITEM_CANCEL;
+ }
+ }
+ else {
+ if (opType != OP_NEEDS_DISABLE) {
+ operation = OP_NEEDS_DISABLE;
+ action = EM_ITEM_DISABLED;
+ }
+ }
+
+ if (action) {
+ this._setOp(id, operation);
+ this._notifyAction(id, action);
+ }
+ else {
+ ds.updateProperty(id, "satisfiesDependencies");
+ this._updateDependentItemsForID(id);
+ }
+ },
+
+ /**
+ * Sets an item to be enabled by the user. If the item is already enabled this
+ * clears the needs-enable operation for the next restart.
+ * See "Note on appDisabled and userDisabled property arcs" above.
+ * @param id
+ * The ID of the item to be enabled by the user.
+ */
+ enableItem: function EM_enableItem(id) {
+ var ds = this.datasource;
+ var opType = ds.getItemProperty(id, "opType");
+ var appDisabled = ds.getItemProperty(id, "appDisabled");
+ var userDisabled = ds.getItemProperty(id, "userDisabled");
+
+ var operation, action;
+ // if this item is already enabled don't set a pending operation - instead
+ // immediately enable it and reset the operation type if needed.
+ if (appDisabled == OP_NONE &&
+ userDisabled == OP_NEEDS_DISABLE || userDisabled == OP_NONE) {
+ if (userDisabled == OP_NEEDS_DISABLE)
+ ds.setItemProperty(id, EM_R("userDisabled"), null);
+ if (opType != OP_NONE) {
+ operation = OP_NONE;
+ action = EM_ITEM_CANCEL;
+ }
+ }
+ else {
+ if (userDisabled == "true")
+ ds.setItemProperty(id, EM_R("userDisabled"), EM_L(OP_NEEDS_ENABLE));
+ if (opType != OP_NEEDS_ENABLE) {
+ operation = OP_NEEDS_ENABLE;
+ action = EM_ITEM_ENABLED;
+ }
+ }
+
+ if (action) {
+ this._setOp(id, operation);
+ this._notifyAction(id, action);
+ }
+ else {
+ ds.updateProperty(id, "satisfiesDependencies");
+ this._updateDependentItemsForID(id);
+ }
+ },
+
+ /**
+ * Sets an item to be disabled by the user. If the item is already disabled
+ * this clears the needs-disable operation for the next restart.
+ * See "Note on appDisabled and userDisabled property arcs" above.
+ * @param id
+ * The ID of the item to be disabled by the user.
+ */
+ disableItem: function EM_disableItem(id) {
+ var ds = this.datasource;
+ var opType = ds.getItemProperty(id, "opType");
+ var appDisabled = ds.getItemProperty(id, "appDisabled");
+ var userDisabled = ds.getItemProperty(id, "userDisabled");
+
+ var operation, action;
+ // if this item is already disabled don't set a pending operation - instead
+ // immediately disable it and reset the operation type if needed.
+ if (userDisabled == OP_NEEDS_ENABLE || userDisabled == "true" ||
+ appDisabled == OP_NEEDS_ENABLE) {
+ if (userDisabled != "true")
+ ds.setItemProperty(id, EM_R("userDisabled"), EM_L("true"));
+ if (opType != OP_NONE) {
+ operation = OP_NONE;
+ action = EM_ITEM_CANCEL;
+ }
+ }
+ else {
+ if (userDisabled == OP_NONE)
+ ds.setItemProperty(id, EM_R("userDisabled"), EM_L(OP_NEEDS_DISABLE));
+ if (opType != OP_NEEDS_DISABLE) {
+ operation = OP_NEEDS_DISABLE;
+ action = EM_ITEM_DISABLED;
+ }
+ }
+
+ if (action) {
+ this._setOp(id, operation);
+ this._notifyAction(id, action);
+ }
+ else {
+ ds.updateProperty(id, "satisfiesDependencies");
+ this._updateDependentItemsForID(id);
+ }
+ },
+
+ /**
+ * Determines whether an item should be disabled by the application.
+ * @param id
+ * The ID of the item to check
+ */
+ _isUsableItem: function EM__isUsableItem(id) {
+ var ds = this.datasource;
+ /* If we're not compatibility checking or if the item is compatible
+ * and if it isn't blocklisted and has all dependencies satisfied then
+ * proceed to the security check */
+ if ((!gCheckCompatibility || ds.getItemProperty(id, "compatible") == "true") &&
+ ds.getItemProperty(id, "blocklisted") == "false" &&
+ ds.getItemProperty(id, "satisfiesDependencies") == "true") {
+
+ // appManaged items aren't updated so no need to check update security.
+ if (ds.getItemProperty(id, "appManaged") == "true")
+ return true;
+
+ /* If we are not ignoring update security then check that the item has
+ * a secure update mechanism */
+ return (!gCheckUpdateSecurity ||
+ ds.getItemProperty(id, "providesUpdatesSecurely") == "true");
+ }
+ return false;
+ },
+
+ /**
+ * Sets an item's dependent items disabled state for the app based on whether
+ * its dependencies are met and the item is compatible.
+ * @param id
+ * The ID of the item whose dependent items will be checked
+ */
+ _updateDependentItemsForID: function EM__updateDependentItemsForID(id) {
+ var ds = this.datasource;
+ var dependentItems = this.getDependentItemListForID(id, true, { });
+ for (var i = 0; i < dependentItems.length; ++i) {
+ var dependentID = dependentItems[i].id;
+ ds.updateProperty(dependentID, "satisfiesDependencies");
+ if (this._isUsableItem(dependentID))
+ this._appEnableItem(dependentID);
+ else
+ this._appDisableItem(dependentID);
+ }
+ },
+
+ /**
+ * Notify observers of a change to an item that has been requested by the
+ * user.
+ */
+ _notifyAction: function EM__notifyAction(id, reason) {
+ gOS.notifyObservers(this.datasource.getItemForID(id),
+ EM_ACTION_REQUESTED_TOPIC, reason);
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ update: function EM_update(items, itemCount, updateCheckType, listener,
+ appVersion, platformVersion) {
+ for (i = 0; i < itemCount; ++i) {
+ var currItem = items[i];
+ if (!currItem)
+ throw Cr.NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ if (items.length == 0)
+ items = this.getItemList(Ci.nsIUpdateItem.TYPE_ANY, { });
+
+ var updater = new ExtensionItemUpdater(this);
+ updater.checkForUpdates(items, items.length, updateCheckType, listener,
+ appVersion, platformVersion);
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ updateAndGetNewBlocklistedItems: function EM_updateAndGetNewBlocklistedItems(itemCount) {
+ if (!gBlocklist)
+ gBlocklist = Cc["@mozilla.org/extensions/blocklist;1"].
+ getService(Ci.nsIBlocklistService);
+
+ var list = [];
+ var ds = this.datasource;
+ var items = this.getItemList(Ci.nsIUpdateItem.TYPE_ANY, { });
+ for (var i = 0; i < items.length; ++i) {
+ var id = items[i].id;
+
+ // Get whether the add-on is currently disabled or set to be disabled.
+ var appDisabled = (ds.getItemProperty(id, "appDisabled") == "true" ||
+ ds.getItemProperty(id, "appDisabled") == OP_NEEDS_DISABLE);
+ var userDisabled = (ds.getItemProperty(id, "userDisabled") == "true" ||
+ ds.getItemProperty(id, "userDisabled") == OP_NEEDS_DISABLE);
+ var usable = this._isUsableItem(id);
+ var state = gBlocklist.getAddonBlocklistState(items[i].id, items[i].version);
+
+ // We only return items that are now blocked or to be warned about and aren't
+ // already disabled for some reason.
+ if (!appDisabled && !userDisabled && state != Ci.nsIBlocklistService.STATE_NOT_BLOCKED)
+ list.push(items[i]);
+
+ // Update the appDisabled status based on the new blocked state
+ if (usable)
+ this._appEnableItem(id);
+ else
+ this._appDisableItem(id);
+
+ // If the item was appDisabled and is now usable then it is something
+ // that is no longer hard blocked. If it is still to be warned about then
+ // just user disable it.
+ if (appDisabled && usable && !userDisabled &&
+ state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
+ this.disableItem(id);
+
+ ds.updateProperty(id, "blocklisted");
+ ds.updateProperty(id, "blocklistedsoft");
+ }
+
+ itemCount.value = list.length;
+ return list;
+ },
+
+ /**
+ * @returns An enumeration of all registered Install Locations.
+ */
+ get installLocations () {
+ return InstallLocations.enumeration;
+ },
+
+ /**
+ * Gets the Install Location where a visible Item is stored.
+ * @param id
+ * The GUID of the item to locate an Install Location for.
+ * @returns The Install Location object where the item is stored.
+ */
+ getInstallLocation: function EM_getInstallLocation(id) {
+ var key = this.datasource.visibleItems[id];
+ return key ? InstallLocations.get(this.datasource.visibleItems[id]) : null;
+ },
+
+ /**
+ * Gets a nsIUpdateItem for the item with the specified id.
+ * @param id
+ * The GUID of the item to construct a nsIUpdateItem for.
+ * @returns The nsIUpdateItem representing the item.
+ */
+ getItemForID: function EM_getItemForID(id) {
+ return this.datasource.getItemForID(id);
+ },
+
+ /**
+ * Retrieves a list of installed nsIUpdateItems of items that are dependent
+ * on another item.
+ * @param id
+ * The ID of the item that other items depend on.
+ * @param includeDisabled
+ * Whether to include disabled items in the set returned.
+ * @param countRef
+ * The XPCJS reference to the number of items returned.
+ * @returns An array of installed nsIUpdateItems that depend on the item
+ * specified by the id parameter.
+ */
+ getDependentItemListForID: function EM_getDependentItemListForID(id,
+ includeDisabled,
+ countRef) {
+ return this.datasource.getDependentItemListForID(id, includeDisabled, countRef);
+ },
+
+ /* See nsIExtensionManager.idl */
+ getItemList: function EM_getItemList(type, countRef) {
+ return this.datasource.getItemList(type, countRef);
+ },
+
+ /* See nsIExtensionManager.idl */
+ getIncompatibleItemList: function EM_getIncompatibleItemList(id, appVersion,
+ platformVersion,
+ type,
+ includeDisabled,
+ countRef) {
+ var items = this.datasource.getIncompatibleItemList(id, appVersion ? appVersion : undefined,
+ platformVersion ? platformVersion : undefined,
+ type, includeDisabled);
+ countRef.value = items.length;
+ return items;
+ },
+
+ /**
+ * Move an Item to the index of another item in its container.
+ * @param movingID
+ * The ID of the item to be moved.
+ * @param destinationID
+ * The ID of an item to move another item to.
+ */
+ moveToIndexOf: function EM_moveToIndexOf(movingID, destinationID) {
+ this.datasource.moveToIndexOf(movingID, destinationID);
+ },
+
+ /**
+ * Sorts addons of the specified type by the specified property starting from
+ * the top of their container. If the addons are already sorted then no action
+ * is performed.
+ * @param type
+ * The nsIUpdateItem type of the items to sort.
+ * @param propertyName
+ * The RDF property name used for sorting.
+ * @param isAscending
+ * true to sort ascending and false to sort descending
+ */
+ sortTypeByProperty: function EM_sortTypeByProperty(type, propertyName, isAscending) {
+ this.datasource.sortTypeByProperty(type, propertyName, isAscending);
+ },
+
+ /////////////////////////////////////////////////////////////////////////////
+ // Downloads
+ _transactions: [],
+ _downloadCount: 0,
+ _compatibilityCheckCount: 0,
+
+ /**
+ * Ask the user if they really want to quit the application, since this will
+ * cancel one or more Extension/Theme downloads.
+ * @param subject
+ * A nsISupportsPRBool which this function sets to false if the user
+ * wishes to cancel all active downloads and quit the application,
+ * false otherwise.
+ */
+ _confirmCancelDownloadsOnQuit: function EM__confirmCancelDownloadsOnQuit(subject) {
+ // If user has already dismissed quit request, then do nothing
+ if ((subject instanceof Ci.nsISupportsPRBool) && subject.data)
+ return;
+
+ if (this._downloadCount > 0) {
+ // The observers will be notified again after this so set the download
+ // count to 0 to prevent this dialog from being displayed again.
+ this._downloadCount = 0;
+ var result;
+//@line 5691 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+ result = this._confirmCancelDownloads(this._downloadCount,
+ "quitCancelDownloadsAlertTitle",
+ "quitCancelDownloadsAlertMsgMultiple",
+ "quitCancelDownloadsAlertMsg",
+ "dontQuitButtonWin");
+//@line 5703 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+ if (subject instanceof Ci.nsISupportsPRBool)
+ subject.data = result;
+ }
+ },
+
+ /**
+ * Ask the user if they really want to go offline, since this will cancel
+ * one or more Extension/Theme downloads.
+ * @param subject
+ * A nsISupportsPRBool which this function sets to false if the user
+ * wishes to cancel all active downloads and go offline, false
+ * otherwise.
+ */
+ _confirmCancelDownloadsOnOffline: function EM__confirmCancelDownloadsOnOffline(subject) {
+ if (this._downloadCount > 0) {
+ result = this._confirmCancelDownloads(this._downloadCount,
+ "offlineCancelDownloadsAlertTitle",
+ "offlineCancelDownloadsAlertMsgMultiple",
+ "offlineCancelDownloadsAlertMsg",
+ "dontGoOfflineButton");
+ if (subject instanceof Ci.nsISupportsPRBool)
+ subject.data = result;
+ }
+ },
+
+ /**
+ * Ask the user whether or not they wish to cancel the Extension/Theme
+ * downloads which are currently under way.
+ * @param count
+ * The number of active downloads.
+ * @param title
+ * The key of the title for the message box to be displayed
+ * @param cancelMessageMultiple
+ * The key of the message to be displayed in the message box
+ * when there are > 1 active downloads.
+ * @param cancelMessageSingle
+ * The key of the message to be displayed in the message box
+ * when there is just one active download.
+ * @param dontCancelButton
+ * The key of the label to be displayed on the "Don't Cancel
+ * Downloads" button.
+ */
+ _confirmCancelDownloads: function EM__confirmCancelDownloads(count, title,
+ cancelMessageMultiple,
+ cancelMessageSingle,
+ dontCancelButton) {
+ var bundle = BundleManager.getBundle(URI_DOWNLOADS_PROPERTIES);
+ var title = bundle.GetStringFromName(title);
+ var message, quitButton;
+ if (count > 1) {
+ message = bundle.formatStringFromName(cancelMessageMultiple, [count], 1);
+ quitButton = bundle.formatStringFromName("cancelDownloadsOKTextMultiple", [count], 1);
+ }
+ else {
+ message = bundle.GetStringFromName(cancelMessageSingle);
+ quitButton = bundle.GetStringFromName("cancelDownloadsOKText");
+ }
+ var dontQuitButton = bundle.GetStringFromName(dontCancelButton);
+
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ var win = wm.getMostRecentWindow("Extension:Manager");
+ const nsIPromptService = Ci.nsIPromptService;
+ var ps = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(nsIPromptService);
+ var flags = (nsIPromptService.BUTTON_TITLE_IS_STRING * nsIPromptService.BUTTON_POS_0) +
+ (nsIPromptService.BUTTON_TITLE_IS_STRING * nsIPromptService.BUTTON_POS_1);
+ var rv = ps.confirmEx(win, title, message, flags, quitButton, dontQuitButton, null, null, { });
+ return rv == 1;
+ },
+
+ /* See nsIExtensionManager.idl */
+ addDownloads: function EM_addDownloads(items, itemCount, manager) {
+ if (itemCount == 0)
+ throw Cr.NS_ERROR_ILLEGAL_VALUE;
+
+ for (i = 0; i < itemCount; ++i) {
+ var currItem = items[i];
+ if (!currItem)
+ throw Cr.NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ var ds = this.datasource;
+ // Add observers only if they aren't already added for an active download
+ if (this._downloadCount == 0) {
+ gOS.addObserver(this, "offline-requested", false);
+ gOS.addObserver(this, "quit-application-requested", false);
+ }
+ this._downloadCount += itemCount;
+
+ var urls = [];
+ var hashes = [];
+ var txnID = Math.round(Math.random() * 100);
+ var txn = new ItemDownloadTransaction(this, txnID);
+ for (var i = 0; i < itemCount; ++i) {
+ var currItem = items[i];
+
+ txn.addDownload(currItem);
+ urls.push(currItem.xpiURL);
+ hashes.push(currItem.xpiHash ? currItem.xpiHash : null);
+ // if this is an update remove the update metadata to prevent it from
+ // being updated during an install.
+ if (!manager) {
+ var id = currItem.id
+ ds.setItemProperties(id, {
+ availableUpdateURL: null,
+ availableUpdateHash: null,
+ availableUpdateVersion: null,
+ availableUpdateInfo: null
+ });
+ ds.updateProperty(id, "availableUpdateURL");
+ ds.updateProperty(id, "updateable");
+ }
+ var id = !manager ? PREFIX_ITEM_URI + currItem.id : currItem.xpiURL;
+ ds.updateDownloadState(id, "waiting");
+ }
+ this._transactions.push(txn);
+
+ if (manager) {
+ // XPIManager initiated -- let it know we're ready
+ manager.observe(txn, "xpinstall-progress", "open");
+ }
+ else {
+ // Initiate an install from chrome
+ var xpimgr = Cc["@mozilla.org/xpinstall/install-manager;1"].
+ createInstance(Ci.nsIXPInstallManager);
+ xpimgr.initManagerWithHashes(urls, hashes, urls.length, txn);
+ }
+ },
+
+ /**
+ * Download Operation State has changed from one to another.
+ *
+ * The nsIXPIProgressDialog implementation in the download transaction object
+ * forwards notifications through these methods which we then pass on to any
+ * front end objects implementing nsIExtensionDownloadListener that
+ * are listening. We maintain the master state of download operations HERE,
+ * not in the front end, because if the user closes the extension or theme
+ * managers during the downloads we need to maintain state and not terminate
+ * the download/install process.
+ *
+ * @param transaction
+ * The ItemDownloadTransaction object receiving the download
+ * notifications from XPInstall.
+ * @param addon
+ * An object representing nsIUpdateItem for the addon being updated
+ * @param state
+ * The state we are entering
+ * @param value
+ * ???
+ */
+ onStateChange: function EM_onStateChange(transaction, addon, state, value) {
+ var ds = this.datasource;
+ var id = addon.id != addon.xpiURL ? PREFIX_ITEM_URI + addon.id : addon.xpiURL;
+ const nsIXPIProgressDialog = Ci.nsIXPIProgressDialog;
+ switch (state) {
+ case nsIXPIProgressDialog.DOWNLOAD_START:
+ ds.updateDownloadState(id, "downloading");
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onDownloadStarted(addon);
+ break;
+ case nsIXPIProgressDialog.DOWNLOAD_DONE:
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onDownloadEnded(addon);
+ break;
+ case nsIXPIProgressDialog.INSTALL_START:
+ ds.updateDownloadState(id, "finishing");
+ ds.updateDownloadProgress(id, null);
+ break;
+ case nsIXPIProgressDialog.INSTALL_DONE:
+ --this._downloadCount;
+ // From nsInstall.h
+ // SUCCESS = 0
+ // USER_CANCELLED = -210
+ if (value != 0 && value != -210 && id != addon.xpiURL) {
+ ds.updateDownloadState(id, "failure");
+ ds.updateDownloadProgress(id, null);
+ }
+ transaction.removeDownload(addon.xpiURL);
+ // A successful install will be passing notifications via installItemFromFile
+ if (value != 0) {
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onInstallEnded(addon, value);
+ }
+ break;
+ case nsIXPIProgressDialog.DIALOG_CLOSE:
+ for (var i = 0; i < this._transactions.length; ++i) {
+ if (this._transactions[i].id == transaction.id) {
+ this._transactions.splice(i, 1);
+ // Remove the observers when all transactions have completed.
+ if (this._transactions.length == 0) {
+ gOS.removeObserver(this, "offline-requested");
+ gOS.removeObserver(this, "quit-application-requested");
+
+ // If there are no compatibility checks running then the install
+ // operations are complete.
+ if (this._compatibilityCheckCount == 0) {
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onInstallsCompleted();
+ }
+ }
+ break;
+ }
+ }
+ // Remove any remaining downloads from this transaction
+ transaction.removeAllDownloads();
+ break;
+ }
+ },
+
+ onProgress: function EM_onProgress(addon, value, maxValue) {
+ for (var i = 0; i < this._installListeners.length; ++i)
+ this._installListeners[i].onDownloadProgress(addon, value, maxValue);
+
+ var id = addon.id != addon.xpiURL ? PREFIX_ITEM_URI + addon.id : addon.xpiURL;
+ var progress = Math.round((value / maxValue) * 100);
+ this.datasource.updateDownloadProgress(id, progress);
+ },
+
+ _installListeners: [],
+ addInstallListener: function EM_addInstallListener(listener) {
+ for (var i = 0; i < this._installListeners.length; ++i) {
+ if (this._installListeners[i] == listener)
+ return i;
+ }
+ this._installListeners.push(listener);
+ return this._installListeners.length - 1;
+ },
+
+ removeInstallListenerAt: function EM_removeInstallListenerAt(index) {
+ this._installListeners.splice(index, 1);
+ },
+
+ /**
+ * The Extensions RDF Datasource
+ */
+ _ds: null,
+ _ptr: null,
+
+ /**
+ * Loads the Extensions Datasource. This should not be called unless:
+ * - a piece of Extensions UI is being shown, or
+ * - on startup and there has been a change to an Install Location
+ * ... it should NOT be called on every startup!
+ */
+ _ensureDS: function EM__ensureDS() {
+ if (!this._ds) {
+ this._ds = new ExtensionsDataSource(this);
+ if (this._ds) {
+ this._ds.loadExtensions();
+ this._ptr = getContainer(this._ds, this._ds._itemRoot).DataSource;
+ gRDF.RegisterDataSource(this._ptr, true);
+ }
+ }
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ get datasource() {
+ this._ensureDS();
+ return this._ds;
+ },
+
+ // nsIClassInfo
+ flags: Ci.nsIClassInfo.SINGLETON,
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ getHelperForLanguage: function(language) null,
+ getInterfaces: function(count) {
+ var interfaces = [Ci.nsIExtensionManager, Ci.nsIObserver];
+ count.value = interfaces.length;
+ return interfaces;
+ },
+
+ classDescription: "Extension Manager",
+ contractID: "@mozilla.org/extensions/manager;1",
+ classID: Components.ID("{8A115FAA-7DCB-4e8f-979B-5F53472F51CF}"),
+ _xpcom_categories: [{ category: "profile-after-change" }],
+ _xpcom_factory: {
+ createInstance: function(outer, iid) {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+
+ if (!gEmSingleton)
+ gEmSingleton = new ExtensionManager();
+ return gEmSingleton.QueryInterface(iid);
+ }
+ },
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIExtensionManager,
+ Ci.nsITimerCallback,
+ Ci.nsIObserver,
+ Ci.nsIClassInfo])
+};
+
+/**
+ * This object implements nsIXPIProgressDialog and represents a collection of
+ * XPI/JAR download and install operations. There is one
+ * ItemDownloadTransaction per back-end XPInstallManager object. We maintain
+ * a collection of separate transaction objects because it's possible to have
+ * multiple separate XPInstall download/install operations going on
+ * simultaneously, each with its own XPInstallManager instance. For instance
+ * you could start downloading two extensions and then download a theme. Each
+ * of these operations would open the appropriate FE and have to be able to
+ * track each operation independently.
+ *
+ * @constructor
+ * @param manager
+ * The extension manager creating this transaction
+ * @param id
+ * The integer identifier of this transaction
+ */
+function ItemDownloadTransaction(manager, id) {
+ this._manager = manager;
+ this._downloads = [];
+ this.id = id;
+}
+ItemDownloadTransaction.prototype = {
+ _manager : null,
+ _downloads : [],
+ id : -1,
+
+ /**
+ * Add a download to this transaction
+ * @param addon
+ * An object implementing nsIUpdateItem for the item to be downloaded
+ */
+ addDownload: function ItemDownloadTransaction_addDownload(addon) {
+ this._downloads.push({ addon: addon, waiting: true });
+ this._manager.datasource.addDownload(addon);
+ },
+
+ /**
+ * Removes a download from this transaction
+ * @param url
+ * The URL to remove
+ */
+ removeDownload: function ItemDownloadTransaction_removeDownload(url) {
+ this._manager.datasource.removeDownload(url);
+ },
+
+ /**
+ * Remove all downloads from this transaction
+ */
+ removeAllDownloads: function ItemDownloadTransaction_removeAllDownloads() {
+ for (var i = 0; i < this._downloads.length; ++i) {
+ var addon = this._downloads[i].addon;
+ this.removeDownload(addon.xpiURL);
+ }
+ },
+
+ /**
+ * Determine if this transaction is handling the download of a url.
+ * @param url
+ * The URL to look for
+ * @returns true if this transaction is downloading the supplied url.
+ */
+ containsURL: function ItemDownloadTransaction_containsURL(url) {
+ for (var i = 0; i < this._downloads.length; ++i) {
+ if (this._downloads[i].addon.xpiURL == url)
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * See nsIXPIProgressDialog.idl
+ */
+ onStateChange: function ItemDownloadTransaction_onStateChange(index, state, value) {
+ this._manager.onStateChange(this, this._downloads[index].addon,
+ state, value);
+ },
+
+ /**
+ * See nsIXPIProgressDialog.idl
+ */
+ onProgress: function ItemDownloadTransaction_onProgress(index, value, maxValue) {
+ this._manager.onProgress(this._downloads[index].addon, value, maxValue);
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIXPIProgressDialog])
+};
+
+/**
+ * A listener object that watches the background update check and notifies the
+ * user of any updates found.
+ */
+function BackgroundUpdateCheckListener(datasource) {
+ this._emDS = datasource;
+}
+BackgroundUpdateCheckListener.prototype = {
+ _updateCount: 0,
+ _emDS: null,
+
+ // nsIObserver implementation
+ observe: function BackgroundUpdateListener_observe(aSubject, aTopic, aData) {
+ if (aTopic != "alertclickcallback")
+ return;
+
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ var win = wm.getMostRecentWindow("Extension:Manager");
+ if (win) {
+ win.focus();
+ win.showView("updates");
+ // Don't show the update notification on next startup
+ gPref.setBoolPref(PREF_UPDATE_NOTIFYUSER, false);
+ }
+ else {
+ const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
+ const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
+
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ var param = Cc["@mozilla.org/supports-array;1"].
+ createInstance(Ci.nsISupportsArray);
+ var arg = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ arg.data = "updates";
+ param.AppendElement(arg);
+ ww.openWindow(null, EMURL, null, EMFEATURES, param);
+ }
+ },
+
+ // nsIAddonUpdateCheckListener implementation
+ onUpdateStarted: function BackgroundUpdateListener_onUpdateStarted() {
+ },
+
+ onUpdateEnded: function BackgroundUpdateListener_onUpdateEnded() {
+ if (this._updateCount > 0 && Cc["@mozilla.org/alerts-service;1"]) {
+ var extensionStrings = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ var title = extensionStrings.GetStringFromName("updateNotificationTitle");
+ var text;
+ if (this._updateCount > 1)
+ text = extensionStrings.formatStringFromName("multipleUpdateNotificationText",
+ [BundleManager.appName, this._updateCount], 2);
+ else
+ text = extensionStrings.formatStringFromName("updateNotificationText",
+ [BundleManager.appName], 1);
+
+ try {
+ var notifier = Cc["@mozilla.org/alerts-service;1"].
+ getService(Ci.nsIAlertsService);
+ notifier.showAlertNotification(URI_GENERIC_ICON_XPINSTALL,
+ title, text, true, "", this);
+ }
+ catch (e) {
+ LOG("Failed to retrieve alerts service, probably an unsupported " +
+ "platform - " + e);
+ }
+ }
+ },
+
+ onAddonUpdateStarted: function BackgroundUpdateListener_onAddonUpdateStarted(item) {
+ },
+
+ onAddonUpdateEnded: function BackgroundUpdateListener_onAddonUpdateEnded(item, status) {
+ if (status == Ci.nsIAddonUpdateCheckListener.STATUS_UPDATE) {
+ var lastupdate = this._emDS.getItemProperty(item.id, "availableUpdateVersion");
+ if (lastupdate != item.version) {
+ gPref.setBoolPref(PREF_UPDATE_NOTIFYUSER, true);
+ this._updateCount++;
+ }
+ }
+ }
+};
+
+
+/**
+ * A listener object to the update check process that routes notifications to
+ * the right places and keeps the datasource up to date.
+ */
+function AddonUpdateCheckListener(listener, datasource) {
+ this._listener = listener;
+ this._ds = datasource;
+}
+AddonUpdateCheckListener.prototype = {
+ _listener: null,
+ _ds: null,
+
+ onUpdateStarted: function AddonUpdateListener_onUpdateStarted() {
+ if (this._listener)
+ this._listener.onUpdateStarted();
+ this._ds.onUpdateStarted();
+ },
+
+ onUpdateEnded: function AddonUpdateListener_onUpdateEnded() {
+ if (this._listener)
+ this._listener.onUpdateEnded();
+ this._ds.onUpdateEnded();
+ },
+
+ onAddonUpdateStarted: function AddonUpdateListener_onAddonUpdateStarted(addon) {
+ if (this._listener)
+ this._listener.onAddonUpdateStarted(addon);
+ this._ds.onAddonUpdateStarted(addon);
+ },
+
+ onAddonUpdateEnded: function AddonUpdateListener_onAddonUpdateEnded(addon, status) {
+ if (this._listener)
+ this._listener.onAddonUpdateEnded(addon, status);
+ this._ds.onAddonUpdateEnded(addon, status);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// ExtensionItemUpdater
+//
+function ExtensionItemUpdater(aEM)
+{
+ this._emDS = aEM._ds;
+ this._em = aEM;
+
+ getVersionChecker();
+}
+
+ExtensionItemUpdater.prototype = {
+ _emDS : null,
+ _em : null,
+ _updateCheckType : 0,
+ _items : [],
+ _listener : null,
+
+ /* ExtensionItemUpdater
+//@line 6253 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+ */
+ checkForUpdates: function ExtensionItemUpdater_checkForUpdates(aItems,
+ aItemCount,
+ aUpdateCheckType,
+ aListener,
+ aAppVersion,
+ aPlatformVersion) {
+ if (aUpdateCheckType == Ci.nsIExtensionManager.UPDATE_NOTIFY_NEWVERSION) {
+ this._listener = aListener;
+ this._appVersion = aAppVersion ? aAppVersion : gApp.version;
+ this._platformVersion = aPlatformVersion ? aPlatformVersion
+ : gApp.platformVersion;
+ }
+ else {
+ this._listener = new AddonUpdateCheckListener(aListener, this._emDS);
+ this._appVersion = gApp.version;
+ this._platformVersion = gApp.platformVersion;
+ }
+
+ if (this._listener)
+ this._listener.onUpdateStarted();
+ this._updateCheckType = aUpdateCheckType;
+ this._items = aItems;
+ this._responseCount = aItemCount;
+
+ // This is the number of extensions/themes/etc that we found updates for.
+ this._updateCount = 0;
+
+ for (var i = 0; i < aItemCount; ++i) {
+ var e = this._items[i];
+ if (this._listener)
+ this._listener.onAddonUpdateStarted(e);
+ (new RDFItemUpdater(this)).checkForUpdates(e, aUpdateCheckType);
+ }
+
+ if (this._listener && aItemCount == 0)
+ this._listener.onUpdateEnded();
+ },
+
+ /////////////////////////////////////////////////////////////////////////////
+ // ExtensionItemUpdater
+ _applyVersionUpdates: function ExtensionItemUpdater__applyVersionUpdates(aLocalItem,
+ aRemoteItem) {
+ var targetAppInfo = this._emDS.getTargetApplicationInfo(aLocalItem.id, this._emDS);
+ // If targetAppInfo is null this is for a new install. If the local item's
+ // maxVersion does not equal the targetAppInfo maxVersion then this is for
+ // an upgrade. In both of these cases return true if the remotely specified
+ // maxVersion is greater than the local item's maxVersion.
+ if (!targetAppInfo ||
+ gVersionChecker.compare(aLocalItem.maxAppVersion, targetAppInfo.maxVersion) != 0) {
+ if (gVersionChecker.compare(aLocalItem.maxAppVersion, aRemoteItem.maxAppVersion) < 0)
+ return true;
+ else
+ return false;
+ }
+
+ if (gVersionChecker.compare(targetAppInfo.maxVersion, aRemoteItem.maxAppVersion) < 0) {
+ // Remotely specified maxVersion is newer than the maxVersion
+ // for the installed Extension. Apply that change to the datasources.
+ this._emDS.setTargetApplicationInfo(aLocalItem.id,
+ aRemoteItem.targetAppID,
+ aRemoteItem.minAppVersion,
+ aRemoteItem.maxAppVersion,
+ null);
+
+ // If we got here through |checkForMismatches|, this extension has
+ // already been disabled, re-enable it.
+ var op = StartupCache.entries[aLocalItem.installLocationKey][aLocalItem.id].op;
+ if (op == OP_NEEDS_DISABLE ||
+ this._emDS.getItemProperty(aLocalItem.id, "appDisabled") == "true")
+ this._em._appEnableItem(aLocalItem.id);
+ return true;
+ }
+ else if (this._updateCheckType == Ci.nsIExtensionManager.UPDATE_SYNC_COMPATIBILITY)
+ this._emDS.setTargetApplicationInfo(aLocalItem.id,
+ aRemoteItem.targetAppID,
+ aRemoteItem.minAppVersion,
+ aRemoteItem.maxAppVersion,
+ null);
+ return false;
+ },
+
+ /**
+ * Checks whether a discovered update is valid for install
+ * @param aLocalItem
+ * The already installed nsIUpdateItem that the update is for
+ * @param aRemoteItem
+ * The nsIUpdateItem we are trying to update to
+ * @param aUpdateCheckType
+ * The type of update check being performed
+ *
+ * @returns true if the item is compatible and is not blocklisted.
+ * false if the item is not compatible or is blocklisted.
+ */
+ _isValidUpdate: function _isValidUpdate(aLocalItem, aRemoteItem, aUpdateCheckType) {
+ var appExtensionsVersion = (aRemoteItem.targetAppID != TOOLKIT_ID) ?
+ this._appVersion :
+ this._platformVersion;
+
+ var min = aRemoteItem.minAppVersion;
+ var max = aRemoteItem.maxAppVersion;
+ // Check if the update will only run on a newer version of the application.
+ if (!min || gVersionChecker.compare(appExtensionsVersion, min) < 0)
+ return false;
+
+ // Check if the update will only run on an older version of the application.
+ if (!max || gVersionChecker.compare(appExtensionsVersion, max) > 0)
+ return false;
+
+ // Ignore the blocklist for compatibility only checks.
+ if (aUpdateCheckType != Ci.nsIExtensionManager.UPDATE_CHECK_COMPATIBILITY) {
+ if (!gBlocklist)
+ gBlocklist = Cc["@mozilla.org/extensions/blocklist;1"].
+ getService(Ci.nsIBlocklistService);
+ // Denies updates that are hard blocked, soft blocked items will be warned
+ // about during the install.
+ if (gBlocklist.isAddonBlocklisted(aLocalItem.id, aRemoteItem.version,
+ this._appVersion, this._platformVersion))
+ return false;
+ }
+
+ return true;
+ },
+
+ checkForDone: function ExtensionItemUpdater_checkForDone(item, status) {
+ if (this._listener) {
+ try {
+ this._listener.onAddonUpdateEnded(item, status);
+ }
+ catch (e) {
+ LOG("ExtensionItemUpdater:checkForDone: Failure in listener's onAddonUpdateEnded: " + e);
+ }
+ }
+ if (--this._responseCount == 0 && this._listener) {
+ try {
+ this._listener.onUpdateEnded();
+ }
+ catch (e) {
+ LOG("ExtensionItemUpdater:checkForDone: Failure in listener's onUpdateEnded: " + e);
+ }
+ }
+ },
+};
+
+/**
+ * Replaces %...% strings in an addon url (update and updateInfo) with
+ * appropriate values.
+ * @param aItem
+ * The nsIUpdateItem representing the item
+ * @param aURI
+ * The uri to escape
+ * @param aDS
+ * The extensions datasource
+ *
+ * @returns the appropriately escaped uri.
+ */
+function escapeAddonURI(aItem, aAppVersion, aURI, aDS)
+{
+ var itemStatus = "userEnabled";
+ if (aDS.getItemProperty(aItem.id, "userDisabled") == "true" ||
+ aDS.getItemProperty(aItem.id, "userDisabled") == OP_NEEDS_ENABLE)
+ itemStatus = "userDisabled";
+ else if (aDS.getItemProperty(aItem.id, "type") == Ci.nsIUpdateItem.TYPE_THEME) {
+ var currentSkin = gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
+ if (aDS.getItemProperty(aItem.id, "internalName") != currentSkin)
+ itemStatus = "userDisabled";
+ }
+
+ if (aDS.getItemProperty(aItem.id, "compatible") == "false")
+ itemStatus += ",incompatible";
+ if (aDS.getItemProperty(aItem.id, "blocklisted") == "true")
+ itemStatus += ",blocklisted";
+ if (aDS.getItemProperty(aItem.id, "satisfiesDependencies") == "false")
+ itemStatus += ",needsDependencies";
+
+ aURI = aURI.replace(/%ITEM_ID%/g, aItem.id);
+ aURI = aURI.replace(/%ITEM_VERSION%/g, aItem.version);
+ aURI = aURI.replace(/%ITEM_MAXAPPVERSION%/g, aItem.maxAppVersion);
+ aURI = aURI.replace(/%ITEM_STATUS%/g, itemStatus);
+ aURI = aURI.replace(/%APP_ID%/g, gApp.ID);
+ aURI = aURI.replace(/%APP_VERSION%/g, aAppVersion ? aAppVersion : gApp.version);
+ aURI = aURI.replace(/%REQ_VERSION%/g, REQ_VERSION);
+ aURI = aURI.replace(/%APP_OS%/g, gOSTarget);
+ aURI = aURI.replace(/%APP_ABI%/g, gXPCOMABI);
+ aURI = aURI.replace(/%APP_LOCALE%/g, gLocale);
+ aURI = aURI.replace(/%CURRENT_APP_VERSION%/g, gApp.version);
+
+ // Replace custom parameters (names of custom parameters must have at
+ // least 3 characters to prevent lookups for something like %D0%C8)
+ var catMan = null;
+ aURI = aURI.replace(/%(\w{3,})%/g, function(match, param) {
+ if (!catMan) {
+ catMan = Cc["@mozilla.org/categorymanager;1"].
+ getService(Ci.nsICategoryManager);
+ }
+
+ try {
+ var contractID = catMan.getCategoryEntry(CATEGORY_UPDATE_PARAMS, param);
+ var paramHandler = Cc[contractID].
+ getService(Ci.nsIPropertyBag2);
+ return paramHandler.getPropertyAsAString(param);
+ }
+ catch(e) {
+ return match;
+ }
+ });
+
+ // escape() does not properly encode + symbols in any embedded FVF strings.
+ return aURI.replace(/\+/g, "%2B");
+}
+
+function RDFItemUpdater(aUpdater) {
+ this._updater = aUpdater;
+}
+
+RDFItemUpdater.prototype = {
+ _updater : null,
+ _updateCheckType : 0,
+ _item : null,
+
+ checkForUpdates: function RDFItemUpdater_checkForUpdates(aItem, aUpdateCheckType) {
+ // A preference setting can disable updating for this item
+ try {
+ if (!gPref.getBoolPref(PREF_EM_ITEM_UPDATE_ENABLED.replace(/%UUID%/, aItem.id))) {
+ var status = Ci.nsIAddonUpdateCheckListener.STATUS_DISABLED;
+ this._updater.checkForDone(aItem, status);
+ return;
+ }
+ }
+ catch (e) { }
+
+ // Items managed by the app are not checked for updates.
+ var emDS = this._updater._emDS;
+ if (emDS.getItemProperty(aItem.id, "appManaged") == "true") {
+ var status = Ci.nsIAddonUpdateCheckListener.STATUS_APP_MANAGED;
+ this._updater.checkForDone(aItem, status);
+ return;
+ }
+
+ // Items that have a pending install, uninstall, or upgrade are not checked
+ // for updates.
+ var opType = emDS.getItemProperty(aItem.id, "opType");
+ if (opType) {
+ var status = Ci.nsIAddonUpdateCheckListener.STATUS_PENDING_OP;
+ this._updater.checkForDone(aItem, status);
+ return;
+ }
+
+ var installLocation = InstallLocations.get(emDS.getInstallLocationKey(aItem.id));
+ // Don't check items for updates that are managed independently
+ if (installLocation && installLocation.itemIsManagedIndependently(aItem.id)) {
+ var status = Ci.nsIAddonUpdateCheckListener.STATUS_NOT_MANAGED;
+ this._updater.checkForDone(aItem, status);
+ return;
+ }
+
+ // Don't check items for updates if the location can't be written to except
+ // when performing a version only update.
+ if ((aUpdateCheckType == Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION ||
+ aUpdateCheckType == Ci.nsIExtensionManager.UPDATE_NOTIFY_NEWVERSION) &&
+ (!installLocation || !installLocation.canAccess)) {
+ var status = Ci.nsIAddonUpdateCheckListener.STATUS_READ_ONLY;
+ this._updater.checkForDone(aItem, status);
+ return;
+ }
+
+ this._updateCheckType = aUpdateCheckType;
+ this._item = aItem;
+
+ // Look for a custom update URI: 1) supplied by a pref, 2) supplied by the
+ // install manifest, 3) the default configuration
+ try {
+ var dsURI = gPref.getComplexValue(PREF_EM_ITEM_UPDATE_URL.replace(/%UUID%/, aItem.id),
+ Ci.nsIPrefLocalizedString).data;
+ }
+ catch (e) { }
+ if (!dsURI)
+ dsURI = aItem.updateRDF;
+ if (!dsURI)
+ dsURI = gPref.getCharPref(PREF_UPDATE_DEFAULT_URL);
+
+ dsURI = escapeAddonURI(aItem, this._updater._appVersion, dsURI, emDS);
+
+ // Verify that the URI provided is valid
+ try {
+ var uri = newURI(dsURI);
+ }
+ catch (e) {
+ LOG("RDFItemUpdater:checkForUpdates: There was an error loading the \r\n" +
+ " update datasource for: " + dsURI + ", item = " + aItem.id + ", error: " + e);
+ this._updater.checkForDone(aItem,
+ Ci.nsIAddonUpdateCheckListener.STATUS_FAILURE);
+ return;
+ }
+
+ LOG("RDFItemUpdater:checkForUpdates sending a request to server for: " +
+ uri.spec + ", item = " + aItem.objectSource);
+
+ var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ request.open("GET", uri.spec, true);
+ request.channel.notificationCallbacks = new BadCertHandler();
+ request.overrideMimeType("text/xml");
+ request.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
+
+ var self = this;
+ request.onerror = function(event) { self.onXMLError(event, aItem); };
+ request.onload = function(event) { self.onXMLLoad(event, aItem); };
+ request.send(null);
+ },
+
+ onXMLLoad: function RDFItemUpdater_onXMLLoad(aEvent, aItem) {
+ var request = aEvent.target;
+ try {
+ checkCert(request.channel);
+ }
+ catch (e) {
+ // This may be overly restrictive in two cases: corporate installations
+ // with a corporate update server using an in-house CA cert (installed
+ // but not "built-in") and lone developers hosting their updates on a
+ // site with a self-signed cert (permanently accepted, otherwise the
+ // BadCertHandler would prevent getting this far). Update checks will
+ // fail in both these scenarios.
+ // How else can we protect the vast majority of updates served from AMO
+ // from the spoofing attack described in bug 340198 while allowing those
+ // other cases? A "hackme" pref? Domain-control certs are cheap, getting
+ // one should not be a barrier in either case.
+ LOG("RDFItemUpdater::onXMLLoad: " + e);
+ this._updater.checkForDone(aItem,
+ Ci.nsIAddonUpdateCheckListener.STATUS_FAILURE);
+ return;
+ }
+ var responseXML = request.responseXML;
+
+ // If the item does not have an update RDF and returns an error it is not
+ // treated as a failure since all items without an updateURL are checked
+ // for updates on AMO even if they are not hosted there.
+ if (!responseXML || responseXML.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
+ (request.status != 200 && request.status != 0)) {
+ this._updater.checkForDone(aItem, (aItem.updateRDF ? Ci.nsIAddonUpdateCheckListener.STATUS_FAILURE :
+ Ci.nsIAddonUpdateCheckListener.STATUS_NONE));
+ return;
+ }
+
+ var rdfParser = Cc["@mozilla.org/rdf/xml-parser;1"].
+ createInstance(Ci.nsIRDFXMLParser)
+ var ds = Cc["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].
+ createInstance(Ci.nsIRDFDataSource);
+ rdfParser.parseString(ds, request.channel.URI, request.responseText);
+
+ this.onDatasourceLoaded(ds, aItem);
+ },
+
+ onXMLError: function RDFItemUpdater_onXMLError(aEvent, aItem) {
+ try {
+ var request = aEvent.target;
+ // the following may throw (e.g. a local file or timeout)
+ var status = request.status;
+ }
+ catch (e) {
+ request = aEvent.target.channel.QueryInterface(Ci.nsIRequest);
+ status = request.status;
+ }
+ // this can fail when a network connection is not present.
+ try {
+ var statusText = request.statusText;
+ }
+ catch (e) {
+ status = 0;
+ }
+ // When status is 0 we don't have a valid channel.
+ if (status == 0)
+ statusText = "nsIXMLHttpRequest channel unavailable";
+
+ LOG("RDFItemUpdater:onError: There was an error loading the \r\n" +
+ "the update datasource for item " + aItem.id + ", error: " + statusText);
+ this._updater.checkForDone(aItem,
+ Ci.nsIAddonUpdateCheckListener.STATUS_FAILURE);
+ },
+
+ onDatasourceLoaded: function RDFItemUpdater_onDatasourceLoaded(aDatasource, aLocalItem) {
+ /*
+//@line 6676 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/extensions/src/nsExtensionManager.js.in"
+ */
+ if (!aDatasource.GetAllResources().hasMoreElements()) {
+ LOG("RDFItemUpdater:onDatasourceLoaded: Datasource empty.\r\n" +
+ "If you are an Extension developer and were expecting there to be\r\n" +
+ "updates, this could mean any number of things, since the RDF system\r\n" +
+ "doesn't give up much in the way of information when the load fails.\r\n" +
+ "\r\nTry checking that: \r\n" +
+ " 1. Your remote RDF file exists at the location.\r\n" +
+ " 2. Your RDF file is valid XML (starts with <?xml version=\"1.0\"?>\r\n" +
+ " and loads in Firefox displaying pretty printed like other XML documents\r\n" +
+ " 3. Your server is sending the data in the correct MIME\r\n" +
+ " type (text/xml)");
+ }
+
+ // If we have an update key then the update manifest must be signed
+ if (aLocalItem.updateKey) {
+ var extensionRes = gRDF.GetResource(getItemPrefix(aLocalItem.type) + aLocalItem.id);
+ LOG(extensionRes.Value);
+ var signature = this._getPropertyFromResource(aDatasource, extensionRes, "signature", null);
+ if (signature) {
+ var serializer = new RDFSerializer();
+ try {
+ var updateString = serializer.serializeResource(aDatasource, extensionRes);
+ var verifier = Cc["@mozilla.org/security/datasignatureverifier;1"].
+ getService(Ci.nsIDataSignatureVerifier);
+ try {
+ if (!verifier.verifyData(updateString, signature, aLocalItem.updateKey)) {
+ LOG("RDFItemUpdater:onDatasourceLoaded: Update manifest for " +
+ aLocalItem.id + " failed signature check.");
+ this._updater.checkForDone(aLocalItem, Ci.nsIAddonUpdateCheckListener.STATUS_FAILURE);
+ return;
+ }
+ }
+ catch (e) {
+ LOG("RDFItemUpdater:onDatasourceLoaded: Failed to verify signature for " +
+ aLocalItem.id + ". This indicates a malformed update key or signature.");
+ this._updater.checkForDone(aLocalItem, Ci.nsIAddonUpdateCheckListener.STATUS_FAILURE);
+ return;
+ }
+ }
+ catch (e) {
+ LOG("RDFItemUpdater:onDatasourceLoaded: Failed to generate signature " +
+ "string for " + aLocalItem.id + ". Serializer threw " + e);
+ this._updater.checkForDone(aLocalItem, Ci.nsIAddonUpdateCheckListener.STATUS_FAILURE);
+ return;
+ }
+ }
+ else {
+ LOG("RDFItemUpdater:onDatasourceLoaded: Update manifest for " +
+ aLocalItem.id + " did not contain a signature.");
+ this._updater.checkForDone(aLocalItem, Ci.nsIAddonUpdateCheckListener.STATUS_FAILURE);
+ return;
+ }
+ }
+ /* If there is no updateKey either the update was over SSL, or it is an old
+ * addon that we are allowing a grace update. */
+
+ // Parse the response RDF
+ var newerItem, sameItem;
+
+ // Firefox 1.0PR+ update.rdf format
+ if (this._updateCheckType == Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION ||
+ this._updateCheckType == Ci.nsIExtensionManager.UPDATE_NOTIFY_NEWVERSION) {
+ // Look for newer versions of this item, we only do this in "normal"
+ // mode... see comment by ExtensionItemUpdater_checkForUpdates
+ // about how we do this in all cases but Install Phone Home - which
+ // only needs to do a version check.
+ newerItem = this._parseV20UpdateInfo(aDatasource, aLocalItem,
+ this._updateCheckType);
+
+ if (newerItem) {
+ ++this._updater._updateCount;
+ LOG("RDFItemUpdater:onDatasourceLoaded: Found a newer version of this item:\r\n" +
+ newerItem.objectSource);
+ }
+ }
+
+ // Now look for updated version compatibility metadata for the currently
+ // installed version...
+ sameItem = this._parseV20UpdateInfo(aDatasource, aLocalItem,
+ Ci.nsIExtensionManager.UPDATE_CHECK_COMPATIBILITY);
+
+ if (sameItem) {
+ // Install-time updates are not written to the DS because there is no
+ // entry yet, EM just uses the notifications to ascertain (by hand)
+ // whether or not there is a remote maxVersion tweak that makes the
+ // item being installed compatible.
+ if (!this._updater._applyVersionUpdates(aLocalItem, sameItem))
+ sameItem = null;
+ else
+ LOG("RDFItemUpdater:onDatasourceLoaded: Found info about the installed\r\n" +
+ "version of this item: " + sameItem.objectSource);
+ }
+ var item = null, status = Ci.nsIAddonUpdateCheckListener.STATUS_NONE;
+ if ((this._updateCheckType == Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION ||
+ this._updateCheckType == Ci.nsIExtensionManager.UPDATE_NOTIFY_NEWVERSION)
+ && newerItem) {
+ item = newerItem;
+ status = Ci.nsIAddonUpdateCheckListener.STATUS_UPDATE;
+ }
+ else if (sameItem) {
+ item = sameItem;
+ status = Ci.nsIAddonUpdateCheckListener.STATUS_VERSIONINFO;
+ }
+ else {
+ item = aLocalItem;
+ status = Ci.nsIAddonUpdateCheckListener.STATUS_NO_UPDATE;
+ }
+ // Only one call of this._updater.checkForDone is needed for RDF
+ // responses, since there is only one response per item.
+ this._updater.checkForDone(item, status);
+ },
+
+ // Get a compulsory property from a resource. Reports an error if the
+ // property was not present.
+ _getPropertyFromResource: function RDFItemUpdater__getPropertyFromResource(aDataSource,
+ aSourceResource,
+ aProperty,
+ aLocalItem) {
+ var rv;
+ try {
+ var property = gRDF.GetResource(EM_NS(aProperty));
+ rv = stringData(aDataSource.GetTarget(aSourceResource, property, true));
+ if (rv === undefined)
+ throw Cr.NS_ERROR_FAILURE;
+ }
+ catch (e) {
+ // XXXben show console message "aProperty" not found on aSourceResource.
+ return null;
+ }
+ return rv;
+ },
+
+ /**
+ * Parses the Firefox 1.0RC1+ update manifest format looking for new versions
+ * of updated compatibility information about the given add-on.
+ * @param aDataSource
+ * The update manifest's datasource
+ * @param aLocalItem
+ * The nsIUpdateItem representing the add-on being checked for updates.
+ * @param aUpdateCheckType
+ * The type of update check being performed. See the constants in
+ * nsIExtensionManager
+ * @returns An nsIUpdateItem holding the update's information if a valid
+ * update is found or null if not.
+ */
+ _parseV20UpdateInfo: function RDFItemUpdater__parseV20UpdateInfo(aDataSource,
+ aLocalItem,
+ aUpdateCheckType) {
+ var extensionRes = gRDF.GetResource(getItemPrefix(aLocalItem.type) + aLocalItem.id);
+
+ var updatesArc = gRDF.GetResource(EM_NS("updates"));
+ var updates = aDataSource.GetTarget(extensionRes, updatesArc, true);
+
+ try {
+ updates = updates.QueryInterface(Ci.nsIRDFResource);
+ }
+ catch (e) {
+ LOG("RDFItemUpdater:_parseV20UpdateInfo: No updates were found for:\r\n" +
+ aLocalItem.id + "\r\n" +
+ "If you are an Extension developer and were expecting there to be\r\n" +
+ "updates, this could mean any number of things, since the RDF system\r\n" +
+ "doesn't give up much in the way of information when the load fails.\r\n" +
+ "\r\nTry checking that: \r\n" +
+ " 1. Your RDF File is correct - e.g. check that there is a top level\r\n" +
+ " RDF Resource with a URI urn:mozilla:extension:{GUID}, and that\r\n" +
+ " the <em:updates> listed all have matching GUIDs.");
+ return null;
+ }
+
+ // Track the newest update found
+ var updatedItem = null;
+
+ var cu = Cc["@mozilla.org/rdf/container-utils;1"].
+ getService(Ci.nsIRDFContainerUtils);
+ if (cu.IsContainer(aDataSource, updates)) {
+ var ctr = getContainer(aDataSource, updates);
+
+ var versions = ctr.GetElements();
+ while (versions.hasMoreElements()) {
+ // There are two different methodologies for collecting version
+ // information depending on whether or not we've been invoked in
+ // "version updates only" mode or "version+newest" mode.
+ var version = versions.getNext().QueryInterface(Ci.nsIRDFResource);
+ var foundItem = this._parseV20Update(aDataSource, version, aLocalItem,
+ updatedItem ? updatedItem.version : aLocalItem.version,
+ aUpdateCheckType);
+ if (foundItem) {
+ // When not checking for new versions we can bail out on the first
+ // result.
+ if (aUpdateCheckType)
+ return foundItem;
+ updatedItem = foundItem;
+ }
+ }
+ }
+ return updatedItem;
+ },
+
+ /**
+ * Parses a single version's update entry looking for the best matching
+ * targetApplication entry.
+ * @param aDataSource
+ * The update manifest's datasource
+ * @param aUpdateResource
+ * The nsIRDFResource of the update entry.
+ * @param aLocalItem
+ * The nsIUpdateItem representing the add-on being checked for updates.
+ * @param aNewestVersionFound
+ * When checking for new versions holds the newest version of this
+ * add-on that we know about. Otherwise holds the current version.
+ * @param aUpdateCheckType
+ * The type of update check being performed. See the constants in
+ * nsIExtensionManager
+ * @returns An nsIUpdateItem holding the update's information if a valid
+ * update is found or null if not.
+ */
+ _parseV20Update: function RDFItemUpdater__parseV20Update(aDataSource,
+ aUpdateResource,
+ aLocalItem,
+ aNewestVersionFound,
+ aUpdateCheckType) {
+ var version = this._getPropertyFromResource(aDataSource, aUpdateResource,
+ "version", aLocalItem);
+ /* If we are looking for new versions then test whether this discovered
+ * version is greater than any previously found update. Otherwise check
+ * if this update is for the same version as we have installed. */
+ var result = gVersionChecker.compare(version, aNewestVersionFound);
+ if ((aUpdateCheckType == Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION ||
+ aUpdateCheckType == Ci.nsIExtensionManager.UPDATE_NOTIFY_NEWVERSION) ? result <= 0 : result != 0)
+ return null;
+
+ var taArc = gRDF.GetResource(EM_NS("targetApplication"));
+ var targetApps = aDataSource.GetTargets(aUpdateResource, taArc, true);
+
+ // Track the best update we have found so far
+ var newestUpdateItem = null;
+ while (targetApps.hasMoreElements()) {
+ var targetApp = targetApps.getNext().QueryInterface(Ci.nsIRDFResource);
+ var appID = this._getPropertyFromResource(aDataSource, targetApp, "id", aLocalItem);
+ if (appID != gApp.ID && appID != TOOLKIT_ID)
+ continue;
+
+ var updateLink = this._getPropertyFromResource(aDataSource, targetApp, "updateLink", aLocalItem);
+ var updateHash = this._getPropertyFromResource(aDataSource, targetApp, "updateHash", aLocalItem);
+ if (aUpdateCheckType == Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION ||
+ aUpdateCheckType == Ci.nsIExtensionManager.UPDATE_NOTIFY_NEWVERSION) {
+ // New version information is useless without a link to get it from
+ if (!updateLink)
+ continue;
+
+ /* If the update link is non-ssl and we do not have a hash or the hash
+ * is of an insecure nature then we must ignore this update. Bypass
+ * this if not checking update security. Currently we only consider
+ * the sha hashing algorithms as secure. */
+ if (gCheckUpdateSecurity && updateLink.substring(0, 6) != "https:" &&
+ (!updateHash || updateHash.substring(0, 3) != "sha")) {
+ LOG("RDFItemUpdater:_parseV20Update: Update for " + aLocalItem.id +
+ " at " + updateLink + " ignored because it is insecure. updateLink " +
+ " must be a https url or an updateHash must be specified.");
+ continue;
+ }
+ }
+
+ var updatedItem = makeItem(aLocalItem.id,
+ version,
+ aLocalItem.installLocationKey,
+ this._getPropertyFromResource(aDataSource, targetApp, "minVersion", aLocalItem),
+ this._getPropertyFromResource(aDataSource, targetApp, "maxVersion", aLocalItem),
+ aLocalItem.name,
+ updateLink,
+ updateHash,
+ "", /* Icon URL */
+ "", /* RDF Update URL */
+ "", /* Update Key */
+ aLocalItem.type,
+ appID);
+
+ if (this._updater._isValidUpdate(aLocalItem, updatedItem, aUpdateCheckType)) {
+ if (aUpdateCheckType == Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION) {
+ var infourl = this._getPropertyFromResource(aDataSource, targetApp,
+ "updateInfoURL");
+ if (infourl)
+ infourl = EM_L(infourl);
+ this._updater._emDS.setItemProperty(aLocalItem.id,
+ EM_R("availableUpdateInfo"),
+ infourl);
+ }
+ if (appID == gApp.ID) {
+ // App takes precedence over toolkit. If we found the app, bail out.
+ return updatedItem;
+ }
+ newestUpdateItem = updatedItem;
+ }
+ }
+ return newestUpdateItem;
+ }
+};
+
+/**
+ * A serialisation method for RDF data that produces an identical string
+ * provided that the RDF assertions match.
+ * The serialisation is not complete, only assertions stemming from a given
+ * resource are included, multiple references to the same resource are not
+ * permitted, and the RDF prolog and epilog are not included.
+ * RDF Blob and Date literals are not supported.
+ */
+function RDFSerializer()
+{
+ this.cUtils = Cc["@mozilla.org/rdf/container-utils;1"].
+ getService(Ci.nsIRDFContainerUtils);
+ this.resources = [];
+}
+
+RDFSerializer.prototype = {
+ INDENT: " ", // The indent used for pretty-printing
+ resources: null, // Array of the resources that have been found
+
+ /**
+ * Escapes characters from a string that should not appear in XML.
+ * @param string The string to be escaped
+ * @returns a string with all characters invalid in XML character data
+ * converted to entity references.
+ */
+ escapeEntities: function RDFSerializer_escapeEntities(string)
+ {
+ string = string.replace(/&/g, "&amp;");
+ string = string.replace(/</g, "&lt;");
+ string = string.replace(/>/g, "&gt;");
+ string = string.replace(/"/g, "&quot;");
+ return string;
+ },
+
+ /**
+ * Serializes all the elements of an RDF container.
+ * @param ds The datasource holding the data
+ * @param container The RDF container to output the child elements of
+ * @param indent The current level of indent for pretty-printing
+ * @returns a string containing the serialized elements.
+ */
+ serializeContainerItems: function RDFSerializer_serializeContainerItems(ds, container, indent)
+ {
+ var result = "";
+ var items = container.GetElements();
+ while (items.hasMoreElements()) {
+ var item = items.getNext().QueryInterface(Ci.nsIRDFResource);
+ result += indent + "<RDF:li>\n"
+ result += this.serializeResource(ds, item, indent + this.INDENT);
+ result += indent + "</RDF:li>\n"
+ }
+ return result;
+ },
+
+ /**
+ * Serializes all em:* (see EM_NS) properties of an RDF resource except for
+ * the em:signature property. As this serialization is to be compared against
+ * the manifest signature it cannot contain the em:signature property itself.
+ * @param ds The datasource holding the data
+ * @param resource The RDF resource to output the properties of
+ * @param indent The current level of indent for pretty-printing
+ * @returns a string containing the serialized properties.
+ */
+ serializeResourceProperties: function RDFSerializer_serializeResourceProperties(ds, resource, indent)
+ {
+ var result = "";
+ var items = [];
+ var arcs = ds.ArcLabelsOut(resource);
+ while (arcs.hasMoreElements()) {
+ var arc = arcs.getNext().QueryInterface(Ci.nsIRDFResource);
+ if (arc.ValueUTF8.substring(0, PREFIX_NS_EM.length) != PREFIX_NS_EM)
+ continue;
+ var prop = arc.ValueUTF8.substring(PREFIX_NS_EM.length);
+ if (prop == "signature")
+ continue;
+
+ var targets = ds.GetTargets(resource, arc, true);
+ while (targets.hasMoreElements()) {
+ var target = targets.getNext();
+ if (target instanceof Ci.nsIRDFResource) {
+ var item = indent + "<em:" + prop + ">\n";
+ item += this.serializeResource(ds, target, indent + this.INDENT);
+ item += indent + "</em:" + prop + ">\n";
+ items.push(item);
+ }
+ else if (target instanceof Ci.nsIRDFLiteral) {
+ items.push(indent + "<em:" + prop + ">" + this.escapeEntities(target.Value) + "</em:" + prop + ">\n");
+ }
+ else if (target instanceof Ci.nsIRDFInt) {
+ items.push(indent + "<em:" + prop + " NC:parseType=\"Integer\">" + target.Value + "</em:" + prop + ">\n");
+ }
+ else {
+ throw new Error("Cannot serialize unknown literal type");
+ }
+ }
+ }
+ items.sort();
+ result += items.join("");
+ return result;
+ },
+
+ /**
+ * Recursively serializes an RDF resource and all resources it links to.
+ * This will only output EM_NS properties and will ignore any em:signature
+ * property.
+ * @param ds The datasource holding the data
+ * @param resource The RDF resource to serialize
+ * @param indent The current level of indent for pretty-printing.
+ * Leave undefined for no indent
+ * @returns a string containing the serialized resource.
+ * @throws if the RDF data contains multiple references to the same resource.
+ */
+ serializeResource: function RDFSerializer_serializeResource(ds, resource, indent)
+ {
+ if (this.resources.indexOf(resource) != -1 ) {
+ // We cannot output multiple references to the same resource.
+ throw new Error("Cannot serialize multiple references to "+resource.Value);
+ }
+ if (indent === undefined)
+ indent = "";
+
+ this.resources.push(resource);
+ var container = null;
+ var type = "Description";
+ if (this.cUtils.IsSeq(ds, resource)) {
+ type = "Seq";
+ container = this.cUtils.MakeSeq(ds, resource);
+ }
+ else if (this.cUtils.IsAlt(ds, resource)) {
+ type = "Alt";
+ container = this.cUtils.MakeAlt(ds, resource);
+ }
+ else if (this.cUtils.IsBag(ds, resource)) {
+ type = "Bag";
+ container = this.cUtils.MakeBag(ds, resource);
+ }
+
+ var result = indent + "<RDF:" + type;
+ if (!gRDF.IsAnonymousResource(resource))
+ result += " about=\"" + this.escapeEntities(resource.ValueUTF8) + "\"";
+ result += ">\n";
+
+ if (container)
+ result += this.serializeContainerItems(ds, container, indent + this.INDENT);
+
+ result += this.serializeResourceProperties(ds, resource, indent + this.INDENT);
+
+ result += indent + "</RDF:" + type + ">\n";
+ return result;
+ }
+}
+
+/**
+ * A Datasource that holds Extensions.
+ * - Implements nsIRDFDataSource to drive UI
+ * - Uses a RDF/XML datasource for storage (this is undesirable)
+ *
+ * @constructor
+ */
+function ExtensionsDataSource(em) {
+ this._em = em;
+
+ this._itemRoot = gRDF.GetResource(RDFURI_ITEM_ROOT);
+ this._defaultTheme = gRDF.GetResource(RDFURI_DEFAULT_THEME);
+}
+ExtensionsDataSource.prototype = {
+ _inner : null,
+ _em : null,
+ _itemRoot : null,
+ _defaultTheme : null,
+
+ /**
+ * Called during application shutdown to clear any references held.
+ * The ExtensionsDataSource is unusable after calling this.
+ */
+ shutdown: function EMDS_shutdown() {
+ this._inner = null;
+ this._em = null;
+ this._itemRoot = null;
+ this._defaultTheme = null;
+ },
+
+ /**
+ * Determines if an item's dependencies are satisfied. An item's dependencies
+ * are satisifed when all items specified in the item's em:requires arc are
+ * installed, enabled, and the version is compatible based on the em:requires
+ * minVersion and maxVersion.
+ * @param id
+ * The ID of the item
+ * @returns true if the item's dependencies are satisfied.
+ * false if the item's dependencies are not satisfied.
+ */
+ satisfiesDependencies: function EMDS_satisfiesDependencies(id) {
+ var ds = this._inner;
+ var itemResource = getResourceForID(id);
+ var targets = ds.GetTargets(itemResource, EM_R("requires"), true);
+ if (!targets.hasMoreElements())
+ return true;
+
+ getVersionChecker();
+ var idRes = EM_R("id");
+ var minVersionRes = EM_R("minVersion");
+ var maxVersionRes = EM_R("maxVersion");
+ while (targets.hasMoreElements()) {
+ var target = targets.getNext().QueryInterface(Ci.nsIRDFResource);
+ var dependencyID = stringData(ds.GetTarget(target, idRes, true));
+ var version = null;
+ version = this.getItemProperty(dependencyID, "version");
+ if (version) {
+ var opType = this.getItemProperty(dependencyID, "opType");
+ if (opType == OP_NEEDS_DISABLE || opType == OP_NEEDS_UNINSTALL)
+ return false;
+
+ if (this.getItemProperty(dependencyID, "userDisabled") == "true" ||
+ this.getItemProperty(dependencyID, "appDisabled") == "true" ||
+ this.getItemProperty(dependencyID, "userDisabled") == OP_NEEDS_DISABLE ||
+ this.getItemProperty(dependencyID, "appDisabled") == OP_NEEDS_DISABLE)
+ return false;
+
+ var minVersion = stringData(ds.GetTarget(target, minVersionRes, true));
+ var maxVersion = stringData(ds.GetTarget(target, maxVersionRes, true));
+ var compatible = (gVersionChecker.compare(version, minVersion) >= 0 &&
+ gVersionChecker.compare(version, maxVersion) <= 0);
+ if (!compatible)
+ return false;
+ }
+ else {
+ return false;
+ }
+ }
+
+ return true;
+ },
+
+ /**
+ * Determine if an item is compatible
+ * @param datasource
+ * The datasource to inspect for compatibility - can be the main
+ * datasource or an Install Manifest.
+ * @param source
+ * The RDF Resource of the item to inspect for compatibility.
+ * @param appVersion
+ * The version of the application we are checking for compatibility
+ * against. If this parameter is undefined, the version of the running
+ * application is used.
+ * @param platformVersion
+ * The version of the toolkit to check compatibility against
+ * @returns true if the item is compatible with this version of the
+ * application, false, otherwise.
+ */
+ isCompatible: function EMDS_isCompatible(datasource, source, appVersion, platformVersion) {
+ // The Default Theme is always compatible.
+ if (source.EqualsNode(this._defaultTheme))
+ return true;
+
+ var appID = gApp.ID;
+ if (appVersion === undefined)
+ appVersion = gApp.version;
+ if (platformVersion === undefined)
+ var platformVersion = gApp.platformVersion;
+
+ var targets = datasource.GetTargets(source, EM_R("targetApplication"), true);
+ var idRes = EM_R("id");
+ var minVersionRes = EM_R("minVersion");
+ var maxVersionRes = EM_R("maxVersion");
+ var versionChecker = getVersionChecker();
+ var rv = false;
+ while (targets.hasMoreElements()) {
+ var targetApp = targets.getNext().QueryInterface(Ci.nsIRDFResource);
+ var id = stringData(datasource.GetTarget(targetApp, idRes, true));
+ var minVersion = stringData(datasource.GetTarget(targetApp, minVersionRes, true));
+ var maxVersion = stringData(datasource.GetTarget(targetApp, maxVersionRes, true));
+ if (id == appID) {
+ rv = (versionChecker.compare(appVersion, minVersion) >= 0) &&
+ (versionChecker.compare(appVersion, maxVersion) <= 0);
+ return rv; // App takes precedence over toolkit.
+ }
+
+ if (id == TOOLKIT_ID) {
+ rv = (versionChecker.compare(platformVersion, minVersion) >= 0) &&
+ (versionChecker.compare(platformVersion, maxVersion) <= 0);
+ // Keep looping, in case the app id is later.
+ }
+ }
+ return rv;
+ },
+
+ /**
+ * Gets a list of items that are incompatible with a specific application version.
+ * @param appID
+ * The ID of the application - XXXben unused?
+ * @param appVersion
+ * The Version of the application to check for incompatibility against.
+ * @param platformVersion
+ * The version of the toolkit to check compatibility against
+ * @param desiredType
+ * The nsIUpdateItem type of items to look for
+ * @param includeDisabled
+ * Whether or not disabled items should be included in the set returned
+ * @returns An array of nsIUpdateItems that are incompatible with the application
+ * ID/Version supplied.
+ */
+ getIncompatibleItemList: function EMDS_getIncompatibleItemList(appID,
+ appVersion,
+ platformVersion,
+ desiredType,
+ includeDisabled) {
+ var items = [];
+ var ctr = getContainer(this._inner, this._itemRoot);
+ var elements = ctr.GetElements();
+ while (elements.hasMoreElements()) {
+ var item = elements.getNext().QueryInterface(Ci.nsIRDFResource);
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var type = this.getItemProperty(id, "type");
+ // Skip this item if we're not seeking disabled items
+ if (!includeDisabled && this.getItemProperty(id, "isDisabled") == "true")
+ continue;
+
+ // If the id of this item matches one of the items potentially installed
+ // with and maintained by this application AND it is installed in the
+ // global install location (i.e. the place installed by the app installer)
+ // it is and can be managed by the update file - it's not an item that has
+ // been manually installed by the user into their profile dir, and as such
+ // it is always compatible with the next release of the application since
+ // we will continue to support it.
+ var locationKey = this.getItemProperty(id, "installLocation");
+ var appManaged = this.getItemProperty(id, "appManaged") == "true";
+ if (appManaged && locationKey == KEY_APP_GLOBAL)
+ continue;
+
+ if (type != -1 && (type & desiredType) &&
+ !this.isCompatible(this, item, appVersion, platformVersion))
+ items.push(this.getItemForID(id));
+ }
+ return items;
+ },
+
+ /**
+ * Gets a list of items of a specific type
+ * @param desiredType
+ * The nsIUpdateItem type of items to return
+ * @param countRef
+ * The XPCJS reference to the size of the returned array
+ * @returns An array of nsIUpdateItems, populated only with an item for |id|
+ * if |id| is non-null, otherwise all items matching the specified
+ * type.
+ */
+ getItemList: function EMDS_getItemList(desiredType, countRef) {
+ var items = [];
+ var ctr = getContainer(this, this._itemRoot);
+ var elements = ctr.GetElements();
+ while (elements.hasMoreElements()) {
+ var e = elements.getNext().QueryInterface(Ci.nsIRDFResource);
+ var eID = stripPrefix(e.Value, PREFIX_ITEM_URI);
+ var type = this.getItemProperty(eID, "type");
+ if (type != -1 && type & desiredType)
+ items.push(this.getItemForID(eID));
+ }
+ countRef.value = items.length;
+ return items;
+ },
+
+ /**
+ * Retrieves a list of installed nsIUpdateItems of items that are dependent
+ * on another item.
+ * @param id
+ * The ID of the item that other items depend on.
+ * @param includeDisabled
+ * Whether to include disabled items in the set returned.
+ * @param countRef
+ * The XPCJS reference to the number of items returned.
+ * @returns An array of installed nsIUpdateItems that depend on the item
+ * specified by the id parameter.
+ */
+ getDependentItemListForID: function EMDS_getDependentItemListForID(id,
+ includeDisabled,
+ countRef) {
+ var items = [];
+ var ds = this._inner;
+ var ctr = getContainer(this, this._itemRoot);
+ var elements = ctr.GetElements();
+ while (elements.hasMoreElements()) {
+ var e = elements.getNext().QueryInterface(Ci.nsIRDFResource);
+ var dependentID = stripPrefix(e.Value, PREFIX_ITEM_URI);
+ var targets = ds.GetTargets(e, EM_R("requires"), true);
+ var idRes = EM_R("id");
+ while (targets.hasMoreElements()) {
+ var target = targets.getNext().QueryInterface(Ci.nsIRDFResource);
+ var dependencyID = stringData(ds.GetTarget(target, idRes, true));
+ if (dependencyID == id) {
+ if (!includeDisabled && this.getItemProperty(dependentID, "isDisabled") == "true")
+ continue;
+ items.push(this.getItemForID(dependentID));
+ break;
+ }
+ }
+ }
+ countRef.value = items.length;
+ return items;
+ },
+
+ /**
+ * Constructs an nsIUpdateItem for the given item ID
+ * @param id
+ * The GUID of the item to construct a nsIUpdateItem for
+ * @returns The nsIUpdateItem for the id.
+ */
+ getItemForID: function EMDS_getItemForID(id) {
+ if (!this.visibleItems[id])
+ return null;
+
+ var r = getResourceForID(id);
+ if (!r)
+ return null;
+
+ var targetAppInfo = this.getTargetApplicationInfo(id, this);
+ var updateHash = this.getItemProperty(id, "availableUpdateHash");
+ return makeItem(id,
+ this.getItemProperty(id, "version"),
+ this.getItemProperty(id, "installLocation"),
+ targetAppInfo ? targetAppInfo.minVersion : "",
+ targetAppInfo ? targetAppInfo.maxVersion : "",
+ this.getItemProperty(id, "name"),
+ this.getItemProperty(id, "availableUpdateURL"),
+ updateHash ? updateHash : "",
+ this.getItemProperty(id, "iconURL"),
+ this.getItemProperty(id, "updateURL"),
+ this.getItemProperty(id, "updateKey"),
+ this.getItemProperty(id, "type"),
+ targetAppInfo ? targetAppInfo.appID : gApp.ID);
+ },
+
+ /**
+ * Gets the name of the Install Location where an item is installed.
+ * @param id
+ * The GUID of the item to locate an Install Location for
+ * @returns The string name of the Install Location where the item is
+ * installed.
+ */
+ getInstallLocationKey: function EMDS_getInstallLocationKey(id) {
+ return this.getItemProperty(id, "installLocation");
+ },
+
+ /**
+ * Sets an RDF property on an item in a datasource. Does not create
+ * multiple assertions
+ * @param datasource
+ * The target datasource where the property should be set
+ * @param source
+ * The RDF Resource to set the property on
+ * @param property
+ * The RDF Resource of the property to set
+ * @param newValue
+ * The RDF Node containing the new property value
+ */
+ _setProperty: function EMDS__setProperty(datasource, source, property, newValue) {
+ var oldValue = datasource.GetTarget(source, property, true);
+ if (oldValue) {
+ if (newValue)
+ datasource.Change(source, property, oldValue, newValue);
+ else
+ datasource.Unassert(source, property, oldValue);
+ }
+ else if (newValue)
+ datasource.Assert(source, property, newValue, true);
+ },
+
+ /**
+ * Gets the updated target application info if it exists for an item from
+ * the Extensions datasource during an installation or upgrade.
+ * @param id
+ * The ID of the item to discover updated target application info for
+ * @returns A JS Object with the following properties:
+ * "id" The id of the item
+ * "minVersion" The updated minimum version of the target
+ * application that this item can run in
+ * "maxVersion" The updated maximum version of the target
+ * application that this item can run in
+ */
+ getUpdatedTargetAppInfo: function EMDS_getUpdatedTargetAppInfo(id) {
+ // The default theme is always compatible so there is never update info.
+ if (getResourceForID(id).EqualsNode(this._defaultTheme))
+ return null;
+
+ var appID = gApp.ID;
+ var r = getResourceForID(id);
+ var targetApps = this._inner.GetTargets(r, EM_R("targetApplication"), true);
+ if (!targetApps.hasMoreElements())
+ targetApps = this._inner.GetTargets(gInstallManifestRoot, EM_R("targetApplication"), true);
+ var outData = null;
+ while (targetApps.hasMoreElements()) {
+ var targetApp = targetApps.getNext();
+ if (targetApp instanceof Ci.nsIRDFResource) {
+ try {
+ var foundAppID = stringData(this._inner.GetTarget(targetApp, EM_R("id"), true));
+ // Different target application?
+ if (foundAppID != appID && foundAppID != TOOLKIT_ID)
+ continue;
+ var updatedMinVersion = this._inner.GetTarget(targetApp, EM_R("updatedMinVersion"), true);
+ var updatedMaxVersion = this._inner.GetTarget(targetApp, EM_R("updatedMaxVersion"), true);
+ if (updatedMinVersion && updatedMaxVersion)
+ outData = { id : id,
+ targetAppID : foundAppID,
+ minVersion : stringData(updatedMinVersion),
+ maxVersion : stringData(updatedMaxVersion) };
+ if (foundAppID == appID)
+ return outData;
+ }
+ catch (e) {
+ continue;
+ }
+ }
+ }
+ return outData;
+ },
+
+ /**
+ * Sets the updated target application info for an item in the Extensions
+ * datasource during an installation or upgrade.
+ * @param id
+ * The ID of the item to set updated target application info for
+ * @param targetAppID
+ * The target application ID used for checking compatibility for this item.
+ * @param updatedMinVersion
+ * The updated minimum version of the target application that this
+ * item can run in
+ * @param updatedMaxVersion
+ * The updated maximum version of the target application that this
+ * item can run in
+ *
+ * @note Add-ons can specify a targetApplication id of toolkit@mozilla.org in
+ * their install manifest for compatibility with all apps using a
+ * specific release of the toolkit.
+ */
+ setUpdatedTargetAppInfo: function EMDS_setUpdatedTargetAppInfo(id, targetAppID,
+ updatedMinVersion,
+ updatedMaxVersion) {
+ // The default theme is always compatible so it is never updated.
+ if (getResourceForID(id).EqualsNode(this._defaultTheme))
+ return;
+
+ // Version/Dependency Info
+ var updatedMinVersionRes = EM_R("updatedMinVersion");
+ var updatedMaxVersionRes = EM_R("updatedMaxVersion");
+
+ var appID = gApp.ID;
+ var r = getResourceForID(id);
+ var targetApps = this._inner.GetTargets(r, EM_R("targetApplication"), true);
+ // add updatedMinVersion and updatedMaxVersion for an install else an upgrade
+ if (!targetApps.hasMoreElements()) {
+ var idRes = EM_R("id");
+ var targetRes = getResourceForID(id);
+ var property = EM_R("targetApplication");
+ var anon = gRDF.GetAnonymousResource();
+ this._inner.Assert(anon, idRes, EM_L(appID), true);
+ this._inner.Assert(anon, updatedMinVersionRes, EM_L(updatedMinVersion), true);
+ this._inner.Assert(anon, updatedMaxVersionRes, EM_L(updatedMaxVersion), true);
+ this._inner.Assert(targetRes, property, anon, true);
+ }
+ else {
+ while (targetApps.hasMoreElements()) {
+ var targetApp = targetApps.getNext();
+ if (targetApp instanceof Ci.nsIRDFResource) {
+ var foundAppID = stringData(this._inner.GetTarget(targetApp, EM_R("id"), true));
+ // Different target application?
+ if (foundAppID != targetAppID)
+ continue;
+ this._inner.Assert(targetApp, updatedMinVersionRes, EM_L(updatedMinVersion), true);
+ this._inner.Assert(targetApp, updatedMaxVersionRes, EM_L(updatedMaxVersion), true);
+ break;
+ }
+ }
+ }
+ this.Flush();
+ },
+
+ /**
+ * Gets the target application info for an item from a datasource.
+ * @param id
+ * The GUID of the item to discover target application info for
+ * @param datasource
+ * The datasource to look up target application info in
+ * @returns A JS Object with the following properties:
+ * "appID" The target application ID used for checking
+ * compatibility for this item.
+ * "minVersion" The minimum version of the target application
+ * that this item can run in
+ * "maxVersion" The maximum version of the target application
+ * that this item can run in
+ * or null, if no target application data exists for the specified
+ * id in the supplied datasource.
+ */
+ getTargetApplicationInfo: function EMDS_getTargetApplicationInfo(id, datasource) {
+ var appID = gApp.ID;
+ // The default theme is always compatible.
+ if (getResourceForID(id).EqualsNode(this._defaultTheme)) {
+ var ver = gApp.version;
+ return { appID: appID, minVersion: ver, maxVersion: ver };
+ }
+
+ var r = getResourceForID(id);
+ var targetApps = datasource.GetTargets(r, EM_R("targetApplication"), true);
+ if (!targetApps)
+ return null;
+
+ if (!targetApps.hasMoreElements())
+ targetApps = datasource.GetTargets(gInstallManifestRoot, EM_R("targetApplication"), true);
+ var outData = null;
+ while (targetApps.hasMoreElements()) {
+ var targetApp = targetApps.getNext();
+ if (targetApp instanceof Ci.nsIRDFResource) {
+ try {
+ var foundAppID = stringData(datasource.GetTarget(targetApp, EM_R("id"), true));
+ // Different target application?
+ if (foundAppID != appID && foundAppID != TOOLKIT_ID)
+ continue;
+
+ outData = { appID: foundAppID,
+ minVersion: stringData(datasource.GetTarget(targetApp, EM_R("minVersion"), true)),
+ maxVersion: stringData(datasource.GetTarget(targetApp, EM_R("maxVersion"), true)) };
+ if (foundAppID == appID)
+ return outData;
+ }
+ catch (e) {
+ continue;
+ }
+ }
+ }
+ return outData;
+ },
+
+ /**
+ * Sets the target application info for an item in a datasource.
+ * @param id
+ * The GUID of the item to discover target application info for
+ * @param targetAppID
+ * The target application ID used for checking compatibility for this
+ * item.
+ * @param minVersion
+ * The minimum version of the target application that this item can
+ * run in
+ * @param maxVersion
+ * The maximum version of the target application that this item can
+ * run in
+ * @param datasource
+ * The datasource to look up target application info in
+ *
+ * @note Add-ons can specify a targetApplication id of toolkit@mozilla.org in
+ * their install manifest for compatibility with all apps using a
+ * specific release of the toolkit.
+ */
+ setTargetApplicationInfo: function EMDS_setTargetApplicationInfo(id, targetAppID,
+ minVersion,
+ maxVersion,
+ datasource) {
+ var targetDataSource = datasource;
+ if (!targetDataSource)
+ targetDataSource = this._inner;
+
+ var appID = gApp.ID;
+ var r = getResourceForID(id);
+ var targetApps = targetDataSource.GetTargets(r, EM_R("targetApplication"), true);
+ if (!targetApps.hasMoreElements())
+ targetApps = datasource.GetTargets(gInstallManifestRoot, EM_R("targetApplication"), true);
+ while (targetApps.hasMoreElements()) {
+ var targetApp = targetApps.getNext();
+ if (targetApp instanceof Ci.nsIRDFResource) {
+ var foundAppID = stringData(targetDataSource.GetTarget(targetApp, EM_R("id"), true));
+ // Different target application?
+ if (foundAppID != targetAppID)
+ continue;
+
+ this._setProperty(targetDataSource, targetApp, EM_R("minVersion"), EM_L(minVersion));
+ this._setProperty(targetDataSource, targetApp, EM_R("maxVersion"), EM_L(maxVersion));
+
+ // If we were setting these properties on the main datasource, flush
+ // it now. (Don't flush changes set on Install Manifests - they are
+ // fleeting).
+ if (!datasource)
+ this.Flush();
+
+ break;
+ }
+ }
+ },
+
+ /**
+ * Gets a property of an item
+ * @param id
+ * The GUID of the item
+ * @param property
+ * The name of the property (excluding EM_NS)
+ * @returns The literal value of the property, or undefined if there is no
+ * value.
+ */
+ getItemProperty: function EMDS_getItemProperty(id, property) {
+ var item = getResourceForID(id);
+ if (!item) {
+ LOG("getItemProperty failing for lack of an item. This means getResourceForItem \
+ failed to locate a resource for aItemID (item ID = " + id + ", property = " + property + ")");
+ }
+ else
+ return this._getItemProperty(item, property);
+ return undefined;
+ },
+
+ /**
+ * Gets a property of an item resource
+ * @param itemResource
+ * The RDF Resource of the item
+ * @param property
+ * The name of the property (excluding EM_NS)
+ * @returns The literal value of the property, or undefined if there is no
+ * value.
+ */
+ _getItemProperty: function EMDS__getItemProperty(itemResource, property) {
+ var target = this.GetTarget(itemResource, EM_R(property), true);
+ var value = stringData(target);
+ if (value === undefined)
+ value = intData(target);
+ return value === undefined ? "" : value;
+ },
+
+ /**
+ * Sets a property on an item.
+ * @param id
+ * The GUID of the item
+ * @param propertyArc
+ * The RDF Resource of the property arc
+ * @param propertyValue
+ * A nsIRDFLiteral value of the property to be set
+ */
+ setItemProperty: function EMDS_setItemProperty(id, propertyArc, propertyValue) {
+ var item = getResourceForID(id);
+ this._setProperty(this._inner, item, propertyArc, propertyValue);
+ this.Flush();
+ },
+
+ /**
+ * Sets one or more properties for an item.
+ * @param id
+ * The ID of the item
+ * @param properties
+ * A JS object which maps properties to values.
+ */
+ setItemProperties: function EMDS_setItemProperties(id, properties) {
+ var item = getResourceForID(id);
+ for (var key in properties)
+ this._setProperty(this._inner, item, EM_R(key), properties[key]);
+ this.Flush();
+ },
+
+ /**
+ * Inserts the RDF resource for an item into a container.
+ * @param id
+ * The GUID of the item
+ */
+ insertItemIntoContainer: function EMDS_insertItemIntoContainer(id) {
+ // Get the target container and resource
+ var ctr = getContainer(this._inner, this._itemRoot);
+ var itemResource = getResourceForID(id);
+ // Don't bother adding the extension to the list if it's already there.
+ // (i.e. we're upgrading)
+ var oldIndex = ctr.IndexOf(itemResource);
+ if (oldIndex == -1)
+ ctr.AppendElement(itemResource);
+ this.Flush();
+ },
+
+ /**
+ * Removes the RDF resource for an item from its container.
+ * @param id
+ * The GUID of the item
+ */
+ removeItemFromContainer: function EMDS_removeItemFromContainer(id) {
+ var ctr = getContainer(this._inner, this._itemRoot);
+ var itemResource = getResourceForID(id);
+ ctr.RemoveElement(itemResource, true);
+ this.Flush();
+ },
+
+ /**
+ * Removes a corrupt item entry from the extension list added due to buggy
+ * code in previous EM versions!
+ * @param id
+ * The GUID of the item
+ */
+ removeCorruptItem: function EMDS_removeCorruptItem(id) {
+ this.removeItemMetadata(id);
+ this.removeItemFromContainer(id);
+ this.visibleItems[id] = null;
+ },
+
+ /**
+ * Removes a corrupt download entry from the list
+ * @param uri
+ * The RDF URI of the item.
+ * @returns The RDF Resource of the removed entry
+ */
+ removeCorruptDLItem: function EMDS_removeCorruptDLItem(uri) {
+ var itemResource = gRDF.GetResource(uri);
+ var ctr = getContainer(this._inner, this._itemRoot);
+ if (ctr.IndexOf(itemResource) != -1) {
+ ctr.RemoveElement(itemResource, true);
+ this._cleanResource(itemResource);
+ this.Flush();
+ }
+ return itemResource;
+ },
+
+ /**
+ * Copies localized properties from an install manifest to the datasource
+ *
+ * @param installManifest
+ * The Install Manifest datasource we are copying from
+ * @param source
+ * The source resource of the localized properties
+ * @param target
+ * The target resource to store the localized properties
+ */
+ _addLocalizedMetadata: function EMDS__addLocalizedMetadata(installManifest,
+ sourceRes, targetRes)
+ {
+ var singleProps = ["name", "description", "creator", "homepageURL"];
+
+ for (var i = 0; i < singleProps.length; ++i) {
+ var property = EM_R(singleProps[i]);
+ var literal = installManifest.GetTarget(sourceRes, property, true);
+ // If literal is null, _setProperty will remove any existing.
+ this._setProperty(this._inner, targetRes, property, literal);
+ }
+
+ // Assert properties with multiple values
+ var manyProps = ["developer", "translator", "contributor"];
+ for (var i = 0; i < manyProps.length; ++i) {
+ var property = EM_R(manyProps[i]);
+ var literals = installManifest.GetTargets(sourceRes, property, true);
+
+ var oldValues = this._inner.GetTargets(targetRes, property, true);
+ while (oldValues.hasMoreElements()) {
+ var oldValue = oldValues.getNext().QueryInterface(Ci.nsIRDFNode);
+ this._inner.Unassert(targetRes, property, oldValue);
+ }
+ while (literals.hasMoreElements()) {
+ var literal = literals.getNext().QueryInterface(Ci.nsIRDFNode);
+ this._inner.Assert(targetRes, property, literal, true);
+ }
+ }
+
+ },
+
+ /**
+ * Copies metadata from an Install Manifest Datasource into the Extensions
+ * DataSource.
+ * @param id
+ * The GUID of the item
+ * @param installManifest
+ * The Install Manifest datasource we are copying from
+ * @param installLocation
+ * The Install Location of the item.
+ */
+ addItemMetadata: function EMDS_addItemMetadata(id, installManifest, installLocation) {
+ var targetRes = getResourceForID(id);
+ // Remove any temporary assertions used for the install process
+ this._setProperty(this._inner, targetRes, EM_R("newVersion"), null);
+ // Copy the assertions over from the source datasource.
+ // Assert properties with single values
+ var singleProps = ["version", "updateURL", "updateService", "optionsURL",
+ "aboutURL", "iconURL", "internalName", "updateKey"];
+
+ // Items installed into restricted Install Locations can also be locked
+ // (can't be removed or disabled), and hidden (not shown in the UI)
+ if (installLocation.restricted)
+ singleProps = singleProps.concat(["locked", "hidden"]);
+ if (installLocation.name == KEY_APP_GLOBAL)
+ singleProps = singleProps.concat(["appManaged"]);
+ for (var i = 0; i < singleProps.length; ++i) {
+ var property = EM_R(singleProps[i]);
+ var literal = installManifest.GetTarget(gInstallManifestRoot, property, true);
+ // If literal is null, _setProperty will remove any existing.
+ this._setProperty(this._inner, targetRes, property, literal);
+ }
+
+ var localizedProp = EM_R("localized");
+ var localeProp = EM_R("locale");
+ // Remove old localized properties
+ var oldValues = this._inner.GetTargets(targetRes, localizedProp, true);
+ while (oldValues.hasMoreElements()) {
+ var oldValue = oldValues.getNext().QueryInterface(Ci.nsIRDFNode);
+ this._cleanResource(oldValue);
+ this._inner.Unassert(targetRes, localizedProp, oldValue);
+ }
+ // Add each localized property
+ var localizations = installManifest.GetTargets(gInstallManifestRoot, localizedProp, true);
+ while (localizations.hasMoreElements()) {
+ var localization = localizations.getNext().QueryInterface(Ci.nsIRDFResource);
+ var anon = gRDF.GetAnonymousResource();
+ var literals = installManifest.GetTargets(localization, localeProp, true);
+ while (literals.hasMoreElements()) {
+ var literal = literals.getNext().QueryInterface(Ci.nsIRDFNode);
+ this._inner.Assert(anon, localeProp, literal, true);
+ }
+ this._addLocalizedMetadata(installManifest, localization, anon);
+ this._inner.Assert(targetRes, localizedProp, anon, true);
+ }
+ // Add the fallback properties
+ this._addLocalizedMetadata(installManifest, gInstallManifestRoot, targetRes);
+
+ // Version/Dependency Info
+ var versionProps = ["targetApplication", "requires"];
+ var idRes = EM_R("id");
+ var minVersionRes = EM_R("minVersion");
+ var maxVersionRes = EM_R("maxVersion");
+ for (var i = 0; i < versionProps.length; ++i) {
+ var property = EM_R(versionProps[i]);
+ var newVersionInfos = installManifest.GetTargets(gInstallManifestRoot, property, true);
+
+ var oldVersionInfos = this._inner.GetTargets(targetRes, property, true);
+ while (oldVersionInfos.hasMoreElements()) {
+ var oldVersionInfo = oldVersionInfos.getNext().QueryInterface(Ci.nsIRDFResource);
+ this._cleanResource(oldVersionInfo);
+ this._inner.Unassert(targetRes, property, oldVersionInfo);
+ }
+ while (newVersionInfos.hasMoreElements()) {
+ var newVersionInfo = newVersionInfos.getNext().QueryInterface(Ci.nsIRDFResource);
+ var anon = gRDF.GetAnonymousResource();
+ this._inner.Assert(anon, idRes, installManifest.GetTarget(newVersionInfo, idRes, true), true);
+ this._inner.Assert(anon, minVersionRes, installManifest.GetTarget(newVersionInfo, minVersionRes, true), true);
+ this._inner.Assert(anon, maxVersionRes, installManifest.GetTarget(newVersionInfo, maxVersionRes, true), true);
+ this._inner.Assert(targetRes, property, anon, true);
+ }
+ }
+ this.updateProperty(id, "opType");
+ this.updateProperty(id, "updateable");
+ this.Flush();
+ },
+
+ /**
+ * Strips an item entry of all assertions.
+ * @param id
+ * The GUID of the item
+ */
+ removeItemMetadata: function EMDS_removeItemMetadata(id) {
+ var item = getResourceForID(id);
+ var resources = ["targetApplication", "requires", "localized"];
+ for (var i = 0; i < resources.length; ++i) {
+ var targetApps = this._inner.GetTargets(item, EM_R(resources[i]), true);
+ while (targetApps.hasMoreElements()) {
+ var targetApp = targetApps.getNext().QueryInterface(Ci.nsIRDFResource);
+ this._cleanResource(targetApp);
+ }
+ }
+
+ this._cleanResource(item);
+ },
+
+ /**
+ * Strips a resource of all outbound assertions. We use methods like this
+ * since the RDFXMLDatasource will write out all assertions, even if they
+ * are not connected through our root.
+ * @param resource
+ * The resource to clean.
+ */
+ _cleanResource: function EMDS__cleanResource(resource) {
+ // Remove outward arcs
+ var arcs = this._inner.ArcLabelsOut(resource);
+ while (arcs.hasMoreElements()) {
+ var arc = arcs.getNext().QueryInterface(Ci.nsIRDFResource);
+ var targets = this._inner.GetTargets(resource, arc, true);
+ while (targets.hasMoreElements()) {
+ var value = targets.getNext().QueryInterface(Ci.nsIRDFNode);
+ if (value)
+ this._inner.Unassert(resource, arc, value);
+ }
+ }
+ },
+
+ /**
+ * Notify views that this propery has changed (this is for properties that
+ * are implemented by this datasource rather than by the inner in-memory
+ * datasource and thus do not get free change handling).
+ * @param id
+ * The GUID of the item to update the property for.
+ * @param property
+ * The property (less EM_NS) to update.
+ */
+ updateProperty: function EMDS_updateProperty(id, property) {
+ var item = getResourceForID(id);
+ this._updateProperty(item, property);
+ },
+
+ /**
+ * Notify views that this propery has changed (this is for properties that
+ * are implemented by this datasource rather than by the inner in-memory
+ * datasource and thus do not get free change handling). This allows updating
+ * properties for download items which don't have the em item prefix in there
+ ( resource value. In most instances updateProperty should be used.
+ * @param item
+ * The item to update the property for.
+ * @param property
+ * The property (less EM_NS) to update.
+ */
+ _updateProperty: function EMDS__updateProperty(item, property) {
+ if (item) {
+ var propertyResource = EM_R(property);
+ var value = this.GetTarget(item, propertyResource, true);
+ for (var i = 0; i < this._observers.length; ++i) {
+ if (value)
+ this._observers[i].onChange(this, item, propertyResource,
+ EM_L(""), value);
+ else
+ this._observers[i].onUnassert(this, item, propertyResource,
+ EM_L(""));
+ }
+ }
+ },
+
+ /**
+ * Move an Item to the index of another item in its container.
+ * @param movingID
+ * The ID of the item to be moved.
+ * @param destinationID
+ * The ID of an item to move another item to.
+ */
+ moveToIndexOf: function EMDS_moveToIndexOf(movingID, destinationID) {
+ var extensions = gRDF.GetResource(RDFURI_ITEM_ROOT);
+ var ctr = getContainer(this._inner, extensions);
+ var item = gRDF.GetResource(movingID);
+ var index = ctr.IndexOf(gRDF.GetResource(destinationID));
+ if (index == -1)
+ index = 1; // move to the beginning if destinationID is not found
+ this._inner.beginUpdateBatch();
+ ctr.RemoveElement(item, true);
+ ctr.InsertElementAt(item, index, true);
+ this._inner.endUpdateBatch();
+ this.Flush();
+ },
+
+ /**
+ * Sorts addons of the specified type by the specified property starting from
+ * the top of their container. If the addons are already sorted then no action
+ * is performed.
+ * @param type
+ * The nsIUpdateItem type of the items to sort.
+ * @param propertyName
+ * The RDF property name used for sorting.
+ * @param isAscending
+ * true to sort ascending and false to sort descending
+ */
+ sortTypeByProperty: function EMDS_sortTypeByProperty(type, propertyName, isAscending) {
+ var items = [];
+ var ctr = getContainer(this._inner, this._itemRoot);
+ var elements = ctr.GetElements();
+ // Base 0 ordinal for checking against the existing order after sorting
+ var ordinal = 0;
+ while (elements.hasMoreElements()) {
+ var item = elements.getNext().QueryInterface(Ci.nsIRDFResource);
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var itemType = this.getItemProperty(id, "type");
+ if (itemType & type) {
+ items.push({ item : item,
+ ordinal: ordinal,
+ sortkey: this.getItemProperty(id, propertyName) });
+ ordinal++;
+ }
+ }
+
+ var direction = isAscending ? 1 : -1;
+ // Locale sensitive sort
+ function compare(a, b) {
+ return String.localeCompare(a.sortkey, b.sortkey) * direction;
+ }
+ items.sort(compare);
+
+ // Check if there are any changes in the order of the items
+ var isDirty = false;
+ for (var i = 0; i < items.length; i++) {
+ if (items[i].ordinal != i) {
+ isDirty = true;
+ break;
+ }
+ }
+
+ // If there are no changes then early return to avoid the perf impact
+ if (!isDirty)
+ return;
+
+ // Reorder the items by moving them to the top of the container
+ this.beginUpdateBatch();
+ for (i = 0; i < items.length; i++) {
+ ctr.RemoveElement(items[i].item, true);
+ ctr.InsertElementAt(items[i].item, i + 1, true);
+ }
+ this.endUpdateBatch();
+ this.Flush();
+ },
+
+ /**
+ * Determines if an Item is an active download
+ * @param id
+ * The ID of the item. This will be a uri scheme without the
+ * em item prefix so getProperty shouldn't be used.
+ * @returns true if the item is an active download, false otherwise.
+ */
+ isDownloadItem: function EMDS_isDownloadItem(id) {
+ var downloadURL = stringData(this.GetTarget(gRDF.GetResource(id), EM_R("downloadURL"), true));
+ return downloadURL && downloadURL != "";
+ },
+
+ /**
+ * Adds an entry representing an active download to the appropriate container
+ * @param addon
+ * An object implementing nsIUpdateItem for the addon being
+ * downloaded.
+ */
+ addDownload: function EMDS_addDownload(addon) {
+ // Updates have already been added to the datasource so we just update the
+ // download state.
+ if (addon.id != addon.xpiURL) {
+ this.updateDownloadState(PREFIX_ITEM_URI + addon.id, "waiting");
+ return;
+ }
+ var res = gRDF.GetResource(addon.xpiURL);
+ this._setProperty(this._inner, res, EM_R("name"), EM_L(addon.name));
+ this._setProperty(this._inner, res, EM_R("version"), EM_L(addon.version));
+ this._setProperty(this._inner, res, EM_R("iconURL"), EM_L(addon.iconURL));
+ this._setProperty(this._inner, res, EM_R("downloadURL"), EM_L(addon.xpiURL));
+ this._setProperty(this._inner, res, EM_R("type"), EM_I(addon.type));
+
+ var ctr = getContainer(this._inner, this._itemRoot);
+ if (ctr.IndexOf(res) == -1)
+ ctr.AppendElement(res);
+
+ this.updateDownloadState(addon.xpiURL, "waiting");
+ this.Flush();
+ },
+
+ /**
+ * Adds an entry representing an item that is incompatible and is being
+ * checked for a compatibility update.
+ * @param name
+ * The display name of the item being checked
+ * @param url
+ * The URL string of the xpi file that has been staged.
+ * @param type
+ * The nsIUpdateItem type of the item
+ * @param version
+ * The version of the item
+ */
+ addIncompatibleUpdateItem: function EMDS_addIncompatibleUpdateItem(name, url, type, version) {
+ var iconURL = (type == Ci.nsIUpdateItem.TYPE_THEME) ? URI_GENERIC_ICON_THEME :
+ URI_GENERIC_ICON_XPINSTALL;
+ var extensionsStrings = BundleManager.getBundle(URI_EXTENSIONS_PROPERTIES);
+ var updateMsg = extensionsStrings.formatStringFromName("incompatibleUpdateMessage",
+ [BundleManager.appName, name], 2)
+
+ var res = gRDF.GetResource(url);
+ this._setProperty(this._inner, res, EM_R("name"), EM_L(name));
+ this._setProperty(this._inner, res, EM_R("iconURL"), EM_L(iconURL));
+ this._setProperty(this._inner, res, EM_R("downloadURL"), EM_L(url));
+ this._setProperty(this._inner, res, EM_R("type"), EM_I(type));
+ this._setProperty(this._inner, res, EM_R("version"), EM_L(version));
+ this._setProperty(this._inner, res, EM_R("incompatibleUpdate"), EM_L("true"));
+ this._setProperty(this._inner, res, EM_R("description"), EM_L(updateMsg));
+
+ var ctr = getContainer(this._inner, this._itemRoot);
+ if (ctr.IndexOf(res) == -1)
+ ctr.AppendElement(res);
+
+ this.updateDownloadState(url, "incompatibleUpdate");
+ this.Flush();
+ },
+
+ /**
+ * Removes an active download from the appropriate container
+ * @param url
+ * The URL string of the active download to be removed
+ */
+ removeDownload: function EMDS_removeDownload(url) {
+ var res = gRDF.GetResource(url);
+ var ctr = getContainer(this._inner, this._itemRoot);
+ if (ctr.IndexOf(res) != -1)
+ ctr.RemoveElement(res, true);
+ this._cleanResource(res);
+ this.updateDownloadState(url, null);
+ this.Flush();
+ },
+
+ /**
+ * A hash of RDF resource values (e.g. Add-on IDs or XPI URLs) that represent
+ * installation progress for a single browser session.
+ */
+ _progressData: { },
+
+ /**
+ * Updates the install progress data for a given ID (e.g. Add-on IDs or
+ * XPI URLs).
+ * @param id
+ * The URL string of the active download to be removed
+ * @param state
+ * The current state in the installation process. If null the object
+ * is deleted from _progressData.
+ */
+ updateDownloadState: function EMDS_updateDownloadState(id, state) {
+ if (!state) {
+ if (id in this._progressData)
+ delete this._progressData[id];
+ return;
+ }
+ else {
+ if (!(id in this._progressData))
+ this._progressData[id] = { };
+ this._progressData[id].state = state;
+ }
+ var item = gRDF.GetResource(id);
+ this._updateProperty(item, "state");
+ },
+
+ updateDownloadProgress: function EMDS_updateDownloadProgress(id, progress) {
+ if (!progress) {
+ if (!(id in this._progressData))
+ return;
+ this._progressData[id].progress = null;
+ }
+ else {
+ if (!(id in this._progressData))
+ this.updateDownloadState(id, "downloading");
+
+ if (this._progressData[id].progress == progress)
+ return;
+
+ this._progressData[id].progress = progress;
+ }
+ var item = gRDF.GetResource(id);
+ this._updateProperty(item, "progress");
+ },
+
+ /**
+ * A GUID->location-key hash of items that are visible to the application.
+ * These are items that show up in the Extension/Themes etc UI. If there is
+ * an instance of the same item installed in Install Locations of differing
+ * profiles, the item at the highest priority location will appear in this
+ * list.
+ */
+ visibleItems: { },
+
+ /**
+ * Walk the list of installed items and determine what the visible list is,
+ * based on which items are visible at the highest priority locations.
+ */
+ _buildVisibleItemList: function EMDS__buildVisibleItemList() {
+ var ctr = getContainer(this, this._itemRoot);
+ var items = ctr.GetElements();
+ while (items.hasMoreElements()) {
+ var item = items.getNext().QueryInterface(Ci.nsIRDFResource);
+ // Resource URIs adopt the format: location-key,item-id
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ this.visibleItems[id] = this.getItemProperty(id, "installLocation");
+ }
+ },
+
+ /**
+ * Updates an item's location in the visible item list.
+ * @param id
+ * The GUID of the item to update
+ * @param locationKey
+ * The name of the Install Location where the item is installed.
+ * @param forceReplace
+ * true if the new location should be used, regardless of its
+ * priority relationship to existing entries, false if the location
+ * should only be updated if its priority is lower than the existing
+ * value.
+ */
+ updateVisibleList: function EMDS_updateVisibleList(id, locationKey, forceReplace) {
+ if (id in this.visibleItems && this.visibleItems[id]) {
+ var oldLocation = InstallLocations.get(this.visibleItems[id]);
+ var newLocation = InstallLocations.get(locationKey);
+ if (forceReplace || !oldLocation || newLocation.priority < oldLocation.priority)
+ this.visibleItems[id] = locationKey;
+ }
+ else
+ this.visibleItems[id] = locationKey;
+ },
+
+ /**
+ * Load the Extensions Datasource from disk.
+ */
+ loadExtensions: function EMDS_loadExtensions() {
+ var extensionsFile = getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS]);
+ try {
+ this._inner = gRDF.GetDataSourceBlocking(getURLSpecFromFile(extensionsFile));
+ }
+ catch (e) {
+ ERROR("Datasource::loadExtensions: removing corrupted extensions datasource " +
+ " file = " + extensionsFile.path + ", exception = " + e + "\n");
+ extensionsFile.remove(false);
+ return;
+ }
+
+ var cu = Cc["@mozilla.org/rdf/container-utils;1"].
+ getService(Ci.nsIRDFContainerUtils);
+ cu.MakeSeq(this._inner, this._itemRoot);
+
+ this._buildVisibleItemList();
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onUpdateStarted: function EMDS_onUpdateStarted() {
+ LOG("Datasource: Update Started");
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onUpdateEnded: function EMDS_onUpdateEnded() {
+ LOG("Datasource: Update Ended");
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onAddonUpdateStarted: function EMDS_onAddonUpdateStarted(addon) {
+ if (!addon)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ LOG("Datasource: Addon Update Started: " + addon.id);
+ this.updateProperty(addon.id, "availableUpdateURL");
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onAddonUpdateEnded: function EMDS_onAddonUpdateEnded(addon, status) {
+ if (!addon)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ LOG("Datasource: Addon Update Ended: " + addon.id + ", status: " + status);
+ var url = null, hash = null, version = null;
+ var updateAvailable = status == Ci.nsIAddonUpdateCheckListener.STATUS_UPDATE;
+ if (updateAvailable) {
+ url = EM_L(addon.xpiURL);
+ if (addon.xpiHash)
+ hash = EM_L(addon.xpiHash);
+ version = EM_L(addon.version);
+ }
+ this.setItemProperties(addon.id, {
+ availableUpdateURL: url,
+ availableUpdateHash: hash,
+ availableUpdateVersion: version
+ });
+ this.updateProperty(addon.id, "availableUpdateURL");
+ },
+
+ /////////////////////////////////////////////////////////////////////////////
+ // nsIRDFDataSource
+ get URI() {
+ return "rdf:extensions";
+ },
+
+ GetSource: function EMDS_GetSource(property, target, truthValue) {
+ return this._inner.GetSource(property, target, truthValue);
+ },
+
+ GetSources: function EMDS_GetSources(property, target, truthValue) {
+ return this._inner.GetSources(property, target, truthValue);
+ },
+
+ /**
+ * Gets an URL to a theme's image file
+ * @param item
+ * The RDF Resource representing the item
+ * @param fileName
+ * The file to locate a URL for
+ * @param fallbackURL
+ * If the location fails, supply this URL instead
+ * @returns An RDF Resource to the URL discovered, or the fallback
+ * if the discovery failed.
+ */
+ _getThemeImageURL: function EMDS__getThemeImageURL(item, fileName, fallbackURL) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var installLocation = this._em.getInstallLocation(id);
+ if (!installLocation)
+ return fallbackURL;
+ var file = installLocation.getItemFile(id, fileName)
+ if (file.exists())
+ return gRDF.GetResource(getURLSpecFromFile(file));
+
+ if (id == stripPrefix(RDFURI_DEFAULT_THEME, PREFIX_ITEM_URI)) {
+ var jarFile = getFile(KEY_APPDIR, [DIR_CHROME, FILE_DEFAULT_THEME_JAR]);
+ var url = "jar:" + getURLSpecFromFile(jarFile) + "!/" + fileName;
+ return gRDF.GetResource(url);
+ }
+
+ return fallbackURL ? gRDF.GetResource(fallbackURL) : null;
+ },
+
+ /**
+ * Get the em:iconURL property (icon url of the item)
+ */
+ _rdfGet_iconURL: function EMDS__rdfGet_iconURL(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var type = this.getItemProperty(id, "type");
+ if (type & Ci.nsIUpdateItem.TYPE_THEME)
+ return this._getThemeImageURL(item, "icon.png", URI_GENERIC_ICON_THEME);
+
+ if (inSafeMode())
+ return gRDF.GetResource(URI_GENERIC_ICON_XPINSTALL);
+
+ var hasIconURL = this._inner.hasArcOut(item, property);
+ // If the addon doesn't have an IconURL property or it is disabled use the
+ // generic icon URL instead.
+ if (!hasIconURL || this.getItemProperty(id, "isDisabled") == "true")
+ return gRDF.GetResource(URI_GENERIC_ICON_XPINSTALL);
+ var iconURL = stringData(this._inner.GetTarget(item, property, true));
+ try {
+ var uri = newURI(iconURL);
+ var scheme = uri.scheme;
+ // Only allow chrome URIs or when installing http(s) URIs.
+ if (scheme == "chrome" || (scheme == "http" || scheme == "https") &&
+ this._inner.hasArcOut(item, EM_R("downloadURL")))
+ return null;
+ }
+ catch (e) {
+ }
+ // Use a generic icon URL for addons that have an invalid iconURL.
+ return gRDF.GetResource(URI_GENERIC_ICON_XPINSTALL);
+ },
+
+ /**
+ * Get the em:previewImage property (preview image of the item)
+ */
+ _rdfGet_previewImage: function EMDS__rdfGet_previewImage(item, property) {
+ var type = this.getItemProperty(stripPrefix(item.Value, PREFIX_ITEM_URI), "type");
+ if (type != -1 && type & Ci.nsIUpdateItem.TYPE_THEME)
+ return this._getThemeImageURL(item, "preview.png", null);
+ return null;
+ },
+
+ /**
+ * If we're in safe mode, the item is disabled by the user or app, or the
+ * item is to be upgraded force the generic about dialog for the item.
+ */
+ _rdfGet_aboutURL: function EMDS__rdfGet_aboutURL(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ if (inSafeMode() || this.getItemProperty(id, "isDisabled") == "true" ||
+ this.getItemProperty(id, "opType") == OP_NEEDS_UPGRADE)
+ return EM_L("");
+
+ return null;
+ },
+
+ _rdfGet_installDate: function EMDS__rdfGet_installDate(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var key = this.getItemProperty(id, "installLocation");
+ if (key && key in StartupCache.entries && id in StartupCache.entries[key] &&
+ StartupCache.entries[key][id] && StartupCache.entries[key][id].mtime)
+ return EM_D(StartupCache.entries[key][id].mtime * 1000000);
+ return null;
+ },
+
+ /**
+ * Get the em:compatible property (whether or not this item is compatible)
+ */
+ _rdfGet_compatible: function EMDS__rdfGet_compatible(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var targetAppInfo = this.getTargetApplicationInfo(id, this);
+ if (!targetAppInfo) {
+ // When installing a new addon targetAppInfo does not exist yet
+ if (this.getItemProperty(id, "opType") == OP_NEEDS_INSTALL)
+ return EM_L("true");
+ return EM_L("false");
+ }
+
+ getVersionChecker();
+ var appVersion = targetAppInfo.appID == TOOLKIT_ID ? gApp.platformVersion : gApp.version;
+ if (gVersionChecker.compare(targetAppInfo.maxVersion, appVersion) < 0 ||
+ gVersionChecker.compare(appVersion, targetAppInfo.minVersion) < 0) {
+ // OK, this item is incompatible.
+ return EM_L("false");
+ }
+ return EM_L("true");
+ },
+
+ /**
+ * Get the providesUpdatesSecurely property (whether or not this item has a
+ * secure update mechanism)
+ */
+ _rdfGet_providesUpdatesSecurely: function EMDS__rdfGet_providesUpdatesSecurely(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ if (this.getItemProperty(id, "updateKey") ||
+ !this.getItemProperty(id, "updateURL") ||
+ this.getItemProperty(id, "updateURL").substring(0, 6) == "https:")
+ return EM_L("true");
+ return EM_L("false");
+ },
+
+ /**
+ * Get the em:blocklisted property (whether or not this item is blocklisted)
+ */
+ _rdfGet_blocklisted: function EMDS__rdfGet_blocklisted(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var version = this.getItemProperty(id, "version");
+ if (!gBlocklist)
+ gBlocklist = Cc["@mozilla.org/extensions/blocklist;1"].
+ getService(Ci.nsIBlocklistService);
+ if (gBlocklist.getAddonBlocklistState(id, version) == Ci.nsIBlocklistService.STATE_BLOCKED)
+ return EM_L("true");
+
+ return EM_L("false");
+ },
+
+ /**
+ * Get the em:blocklistedsoft property (whether or not this item is listed in the blocklist
+ * at a low severity)
+ */
+ _rdfGet_blocklistedsoft: function EMDS__rdfGet_blocklistedsoft(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var version = this.getItemProperty(id, "version");
+ if (!gBlocklist)
+ gBlocklist = Cc["@mozilla.org/extensions/blocklist;1"].
+ getService(Ci.nsIBlocklistService);
+ if (gBlocklist.getAddonBlocklistState(id, version) == Ci.nsIBlocklistService.STATE_SOFTBLOCKED)
+ return EM_L("true");
+
+ return EM_L("false");
+ },
+
+ /**
+ * Get the em:state property (represents the current phase of an install).
+ */
+ _rdfGet_state: function EMDS__rdfGet_state(item, property) {
+ var id = item.Value;
+ if (id in this._progressData)
+ return EM_L(this._progressData[id].state);
+ return null;
+ },
+
+ /**
+ * Get the em:progress property from the _progressData js object. By storing
+ * progress which is updated repeastedly during a download we avoid
+ * repeastedly writing it to the rdf file.
+ */
+ _rdfGet_progress: function EMDS__rdfGet_progress(item, property) {
+ var id = item.Value;
+ if (id in this._progressData)
+ return EM_I(this._progressData[id].progress);
+ return null;
+ },
+
+ /**
+ * Get the em:appManaged property. This prevents extensions from hiding
+ * extensions installed into locations other than the app-global location.
+ */
+ _rdfGet_appManaged: function EMDS__rdfGet_appManaged(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var locationKey = this.getItemProperty(id, "installLocation");
+ if (locationKey != KEY_APP_GLOBAL)
+ return EM_L("false");
+ return null;
+ },
+
+ /**
+ * Get the em:hidden property. This prevents extensions from hiding
+ * extensions installed into locations other than restricted locations.
+ */
+ _rdfGet_hidden: function EMDS__rdfGet_hidden(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var installLocation = InstallLocations.get(this.getInstallLocationKey(id));
+ if (!installLocation || !installLocation.restricted)
+ return EM_L("false");
+ return null;
+ },
+
+ /**
+ * Get the em:locked property. This prevents extensions from locking
+ * extensions installed into locations other than restricted locations.
+ */
+ _rdfGet_locked: function EMDS__rdfGet_locked(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var installLocation = InstallLocations.get(this.getInstallLocationKey(id));
+ if (!installLocation || !installLocation.restricted)
+ return EM_L("false");
+ return null;
+ },
+
+ /**
+ * Get the em:satisfiesDependencies property - literal string "false" for
+ * dependencies not satisfied (e.g. dependency disabled, incorrect version,
+ * not installed etc.), and literal string "true" for dependencies satisfied.
+ */
+ _rdfGet_satisfiesDependencies: function EMDS__rdfGet_satisfiesDependencies(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ if (this.satisfiesDependencies(id))
+ return EM_L("true");
+ return EM_L("false");
+ },
+
+ /**
+ * Get the em:opType property (controls widget state for the EM UI)
+ * from the Startup Cache (e.g. extensions.cache)
+ */
+ _rdfGet_opType: function EMDS__rdfGet_opType(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var key = this.getItemProperty(id, "installLocation");
+ if (key in StartupCache.entries && id in StartupCache.entries[key] &&
+ StartupCache.entries[key][id] && StartupCache.entries[key][id].op != OP_NONE)
+ return EM_L(StartupCache.entries[key][id].op);
+ return null;
+ },
+
+ /**
+ * Gets a localizable property. Install Manifests are generally only in one
+ * language, however an item can customize by providing localized prefs in
+ * the form:
+ *
+ * extensions.{GUID}.[name|description|creator|homepageURL]
+ *
+ * to specify localized text for each of these properties.
+ */
+ _getLocalizablePropertyValue: function EMDS__getLocalizablePropertyValue(item, property) {
+ // These are localizable properties that a language pack supplied by the
+ // Extension may override.
+ var prefName = PREF_EM_EXTENSION_FORMAT.replace(/%UUID%/,
+ stripPrefix(item.Value, PREFIX_ITEM_URI)) +
+ stripPrefix(property.Value, PREFIX_NS_EM);
+ try {
+ var value = gPref.getComplexValue(prefName,
+ Ci.nsIPrefLocalizedString);
+ if (value.data)
+ return EM_L(value.data);
+ }
+ catch (e) {
+ }
+
+ var localized = findClosestLocalizedResource(this._inner, item);
+ if (localized) {
+ var value = this._inner.GetTarget(localized, property, true);
+ return value ? value : EM_L("");
+ }
+ return null;
+ },
+
+ /**
+ * Get the em:name property (name of the item)
+ */
+ _rdfGet_name: function EMDS__rdfGet_name(item, property) {
+ return this._getLocalizablePropertyValue(item, property);
+ },
+
+ /**
+ * Get the em:description property (description of the item)
+ */
+ _rdfGet_description: function EMDS__rdfGet_description(item, property) {
+ return this._getLocalizablePropertyValue(item, property);
+ },
+
+ /**
+ * Get the em:creator property (creator of the item)
+ */
+ _rdfGet_creator: function EMDS__rdfGet_creator(item, property) {
+ return this._getLocalizablePropertyValue(item, property);
+ },
+
+ /**
+ * Get the em:homepageURL property (homepage URL of the item)
+ */
+ _rdfGet_homepageURL: function EMDS__rdfGet_homepageURL(item, property) {
+ return this._getLocalizablePropertyValue(item, property);
+ },
+
+ _rdfGet_availableUpdateInfo: function EMDS__rdfGet_availableUpdateInfo(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var uri = stringData(this._inner.GetTarget(item, EM_R("availableUpdateInfo"), true));
+ if (uri) {
+ uri = escapeAddonURI(this.getItemForID(id), null, uri, this);
+ return EM_L(uri);
+ }
+ return null;
+ },
+
+ /**
+ * Get the em:isDisabled property. This will be true if the item has a
+ * appDisabled or a userDisabled property that is true or OP_NEEDS_ENABLE.
+ */
+ _rdfGet_isDisabled: function EMDS__rdfGet_isDisabled(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ if (this.getItemProperty(id, "userDisabled") == "true" ||
+ this.getItemProperty(id, "appDisabled") == "true" ||
+ this.getItemProperty(id, "userDisabled") == OP_NEEDS_ENABLE ||
+ this.getItemProperty(id, "appDisabled") == OP_NEEDS_ENABLE)
+ return EM_L("true");
+ return EM_L("false");
+ },
+
+ _rdfGet_addonID: function EMDS__rdfGet_addonID(item, property) {
+ var id = this._inner.GetTarget(item, EM_R("downloadURL"), true) ? item.Value :
+ stripPrefix(item.Value, PREFIX_ITEM_URI);
+ return EM_L(id);
+ },
+
+ /**
+ * Get the em:updateable property - this specifies whether the item is
+ * allowed to be updated
+ */
+ _rdfGet_updateable: function EMDS__rdfGet_updateable(item, property) {
+ var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
+ var opType = this.getItemProperty(id, "opType");
+ if (opType != OP_NONE || this.getItemProperty(id, "appManaged") == "true")
+ return EM_L("false");
+
+ if (getPref("getBoolPref", (PREF_EM_ITEM_UPDATE_ENABLED.replace(/%UUID%/, id), false)) == true)
+ return EM_L("false");
+
+ var installLocation = InstallLocations.get(this.getInstallLocationKey(id));
+ if (!installLocation || !installLocation.canAccess)
+ return EM_L("false");
+
+ return EM_L("true");
+ },
+
+ /**
+ * See nsIRDFDataSource.idl
+ */
+ GetTarget: function EMDS_GetTarget(source, property, truthValue) {
+ if (!source)
+ return null;
+
+ var target = null;
+ var getter = "_rdfGet_" + stripPrefix(property.Value, PREFIX_NS_EM);
+ if (getter in this)
+ target = this[getter](source, property);
+
+ return target || this._inner.GetTarget(source, property, truthValue);
+ },
+
+ /**
+ * Gets an enumeration of values of a localizable property. Install Manifests
+ * are generally only in one language, however an item can customize by
+ * providing localized prefs in the form:
+ *
+ * extensions.{GUID}.[contributor].1
+ * extensions.{GUID}.[contributor].2
+ * extensions.{GUID}.[contributor].3
+ * ...
+ *
+ * to specify localized text for each of these properties.
+ */
+ _getLocalizablePropertyValues: function EMDS__getLocalizablePropertyValues(item, property) {
+ // These are localizable properties that a language pack supplied by the
+ // Extension may override.
+ var values = [];
+ var prefName = PREF_EM_EXTENSION_FORMAT.replace(/%UUID%/,
+ stripPrefix(item.Value, PREFIX_ITEM_URI)) +
+ stripPrefix(property.Value, PREFIX_NS_EM);
+ var i = 0;
+ while (true) {
+ try {
+ var value = gPref.getComplexValue(prefName + "." + ++i,
+ Ci.nsIPrefLocalizedString);
+ if (value.data)
+ values.push(EM_L(value.data));
+ }
+ catch (e) {
+ try {
+ var value = gPref.getComplexValue(prefName,
+ Ci.nsIPrefLocalizedString);
+ if (value.data)
+ values.push(EM_L(value.data));
+ }
+ catch (e) {
+ }
+ break;
+ }
+ }
+ if (values.length > 0)
+ return values;
+
+ var localized = findClosestLocalizedResource(this._inner, item);
+ if (localized) {
+ var targets = this._inner.GetTargets(localized, property, true);
+ while (targets.hasMoreElements())
+ values.push(targets.getNext());
+ return values;
+ }
+ return null;
+ },
+
+ /**
+ * Get the em:developer property (developers of the extension)
+ */
+ _rdfGets_developer: function EMDS__rdfGets_developer(item, property) {
+ return this._getLocalizablePropertyValues(item, property);
+ },
+
+ /**
+ * Get the em:translator property (translators of the extension)
+ */
+ _rdfGets_translator: function EMDS__rdfGets_translator(item, property) {
+ return this._getLocalizablePropertyValues(item, property);
+ },
+
+ /**
+ * Get the em:contributor property (contributors to the extension)
+ */
+ _rdfGets_contributor: function EMDS__rdfGets_contributor(item, property) {
+ return this._getLocalizablePropertyValues(item, property);
+ },
+
+ /**
+ * See nsIRDFDataSource.idl
+ */
+ GetTargets: function EMDS_GetTargets(source, property, truthValue) {
+ if (!source)
+ return null;
+
+ var ary = null;
+ var propertyName = stripPrefix(property.Value, PREFIX_NS_EM);
+ var getter = "_rdfGets_" + propertyName;
+ if (getter in this)
+ ary = this[getter](source, property);
+ else {
+ // The template builder calls GetTargets when single value properties
+ // are used in a triple.
+ getter = "_rdfGet_" + propertyName;
+ if (getter in this)
+ ary = [ this[getter](source, property) ];
+ }
+
+ return ary ? new ArrayEnumerator(ary)
+ : this._inner.GetTargets(source, property, truthValue);
+ },
+
+ Assert: function EMDS_Assert(source, property, target, truthValue) {
+ this._inner.Assert(source, property, target, truthValue);
+ },
+
+ Unassert: function EMDS_Unassert(source, property, target) {
+ this._inner.Unassert(source, property, target);
+ },
+
+ Change: function EMDS_Change(source, property, oldTarget, newTarget) {
+ this._inner.Change(source, property, oldTarget, newTarget);
+ },
+
+ Move: function EMDS_Move(oldSource, newSource, property, target) {
+ this._inner.Move(oldSource, newSource, property, target);
+ },
+
+ HasAssertion: function EMDS_HasAssertion(source, property, target, truthValue) {
+ if (!source || !property || !target)
+ return false;
+
+ var getter = "_rdfGet_" + stripPrefix(property.Value, PREFIX_NS_EM);
+ if (getter in this)
+ return this[getter](source, property) == target;
+ return this._inner.HasAssertion(source, property, target, truthValue);
+ },
+
+ _observers: [],
+ AddObserver: function EMDS_AddObserver(observer) {
+ for (var i = 0; i < this._observers.length; ++i) {
+ if (this._observers[i] == observer)
+ return;
+ }
+ this._observers.push(observer);
+ this._inner.AddObserver(observer);
+ },
+
+ RemoveObserver: function EMDS_RemoveObserver(observer) {
+ for (var i = 0; i < this._observers.length; ++i) {
+ if (this._observers[i] == observer)
+ this._observers.splice(i, 1);
+ }
+ this._inner.RemoveObserver(observer);
+ },
+
+ ArcLabelsIn: function EMDS_ArcLabelsIn(node) {
+ return this._inner.ArcLabelsIn(node);
+ },
+
+ ArcLabelsOut: function EMDS_ArcLabelsOut(source) {
+ return this._inner.ArcLabelsOut(source);
+ },
+
+ GetAllResources: function EMDS_GetAllResources() {
+ return this._inner.GetAllResources();
+ },
+
+ IsCommandEnabled: function EMDS_IsCommandEnabled(sources, command, arguments) {
+ return this._inner.IsCommandEnabled(sources, command, arguments);
+ },
+
+ DoCommand: function EMDS_DoCommand(sources, command, arguments) {
+ this._inner.DoCommand(sources, command, arguments);
+ },
+
+ GetAllCmds: function EMDS_GetAllCmds(source) {
+ return this._inner.GetAllCmds(source);
+ },
+
+ hasArcIn: function EMDS_hasArcIn(node, arc) {
+ return this._inner.hasArcIn(node, arc);
+ },
+
+ hasArcOut: function EMDS_hasArcOut(source, arc) {
+ return this._inner.hasArcOut(source, arc);
+ },
+
+ beginUpdateBatch: function EMDS_beginUpdateBatch() {
+ return this._inner.beginUpdateBatch();
+ },
+
+ endUpdateBatch: function EMDS_endUpdateBatch() {
+ return this._inner.endUpdateBatch();
+ },
+
+ /**
+ * See nsIRDFRemoteDataSource.idl
+ */
+ get loaded() {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ Init: function EMDS_Init(uri) {
+ },
+
+ Refresh: function EMDS_Refresh(blocking) {
+ },
+
+ Flush: function EMDS_Flush() {
+ // For some operations we block repeated flushing until all operations
+ // are complete to reduce file accesses that can trigger bug 431065
+ if (!gAllowFlush) {
+ gDSNeedsFlush = true;
+ return;
+ }
+ if (this._inner instanceof Ci.nsIRDFRemoteDataSource)
+ this._inner.Flush();
+ },
+
+ FlushTo: function EMDS_FlushTo(uri) {
+ },
+
+ classDescription: "Extension Manager Data Source",
+ contractID: "@mozilla.org/rdf/datasource;1?name=extensions",
+ classID: Components.ID("{69BB8313-2D4F-45EC-97E0-D39DA58ECCE9}"),
+ _xpcom_factory: {
+ createInstance: function() Cc[ExtensionManager.prototype.contractID].
+ getService(Ci.nsIExtensionManager).datasource
+ },
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIRDFDataSource,
+ Ci.nsIRDFRemoteDataSource])
+};
+
+function UpdateItem () {}
+UpdateItem.prototype = {
+ /**
+ * See nsIUpdateService.idl
+ */
+ init: function(id, version, installLocationKey, minAppVersion, maxAppVersion,
+ name, downloadURL, xpiHash, iconURL, updateURL, updateKey, type,
+ targetAppID) {
+ this._id = id;
+ this._version = version;
+ this._installLocationKey = installLocationKey;
+ this._minAppVersion = minAppVersion;
+ this._maxAppVersion = maxAppVersion;
+ this._name = name;
+ this._downloadURL = downloadURL;
+ this._xpiHash = xpiHash;
+ this._iconURL = iconURL;
+ this._updateURL = updateURL;
+ this._updateKey = updateKey;
+ this._type = type;
+ this._targetAppID = targetAppID;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get id() { return this._id; },
+ get version() { return this._version; },
+ get installLocationKey(){ return this._installLocationKey;},
+ get minAppVersion() { return this._minAppVersion; },
+ get maxAppVersion() { return this._maxAppVersion; },
+ get name() { return this._name; },
+ get xpiURL() { return this._downloadURL; },
+ get xpiHash() { return this._xpiHash; },
+ get iconURL() { return this._iconURL },
+ get updateRDF() { return this._updateURL; },
+ get updateKey() { return this._updateKey; },
+ get type() { return this._type; },
+ get targetAppID() { return this._targetAppID; },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get objectSource() {
+ return { id : this._id,
+ version : this._version,
+ installLocationKey : this._installLocationKey,
+ minAppVersion : this._minAppVersion,
+ maxAppVersion : this._maxAppVersion,
+ name : this._name,
+ xpiURL : this._downloadURL,
+ xpiHash : this._xpiHash,
+ iconURL : this._iconURL,
+ updateRDF : this._updateURL,
+ updateKey : this._updateKey,
+ type : this._type,
+ targetAppID : this._targetAppID
+ }.toSource();
+ },
+
+ classDescription: "Update Item",
+ contractID: "@mozilla.org/updates/item;1",
+ classID: Components.ID("{F3294B1C-89F4-46F8-98A0-44E1EAE92518}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateItem])
+};
+
+function NSGetModule(compMgr, fileSpec)
+ XPCOMUtils.generateModule([ExtensionManager, ExtensionsDataSource, UpdateItem]);
+
diff --git a/bundles/XO/components/nsFilePicker.js b/bundles/XO/components/nsFilePicker.js
new file mode 100755
index 0000000..0f08fb8
--- /dev/null
+++ b/bundles/XO/components/nsFilePicker.js
@@ -0,0 +1,350 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Stuart Parmenter <pavlov@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * No magic constructor behaviour, as is de rigeur for XPCOM.
+ * If you must perform some initialization, and it could possibly fail (even
+ * due to an out-of-memory condition), you should use an Init method, which
+ * can convey failure appropriately (thrown exception in JS,
+ * NS_FAILED(nsresult) return in C++).
+ *
+ * In JS, you can actually cheat, because a thrown exception will cause the
+ * CreateInstance call to fail in turn, but not all languages are so lucky.
+ * (Though ANSI C++ provides exceptions, they are verboten in Mozilla code
+ * for portability reasons -- and even when you're building completely
+ * platform-specific code, you can't throw across an XPCOM method boundary.)
+ */
+
+
+const DEBUG = false; /* set to true to enable debug messages */
+
+const FILEPICKER_CONTRACTID = "@mozilla.org/filepicker;1";
+const FILEPICKER_CID = Components.ID("{54ae32f8-1dd2-11b2-a209-df7c505370f8}");
+const LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1";
+const APPSHELL_SERV_CONTRACTID = "@mozilla.org/appshell/appShellService;1";
+const STRBUNDLE_SERV_CONTRACTID = "@mozilla.org/intl/stringbundle;1";
+
+const nsIAppShellService = Components.interfaces.nsIAppShellService;
+const nsILocalFile = Components.interfaces.nsILocalFile;
+const nsIFileURL = Components.interfaces.nsIFileURL;
+const nsISupports = Components.interfaces.nsISupports;
+const nsIFactory = Components.interfaces.nsIFactory;
+const nsIFilePicker = Components.interfaces.nsIFilePicker;
+const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor
+const nsIDOMWindow = Components.interfaces.nsIDOMWindow;
+const nsIStringBundleService = Components.interfaces.nsIStringBundleService;
+const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
+const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
+const nsIBaseWindow = Components.interfaces.nsIBaseWindow;
+
+var bundle = null;
+var lastDirectory = null;
+
+function nsFilePicker()
+{
+ if (!bundle)
+ bundle = srGetStrBundle("chrome://global/locale/filepicker.properties");
+
+ /* attributes */
+ this.mDefaultString = "";
+ this.mFilterIndex = 0;
+ this.mFilterTitles = new Array();
+ this.mFilters = new Array();
+ this.mDisplayDirectory = null;
+ if (lastDirectory) {
+ try {
+ var dir = Components.classes[LOCAL_FILE_CONTRACTID].createInstance(nsILocalFile);
+ dir.initWithPath(lastDirectory);
+ this.mDisplayDirectory = dir;
+ } catch (e) {}
+ }
+}
+
+nsFilePicker.prototype = {
+
+ /* attribute nsILocalFile displayDirectory; */
+ set displayDirectory(a) {
+ this.mDisplayDirectory = a &&
+ a.clone().QueryInterface(nsILocalFile);
+ },
+ get displayDirectory() {
+ return this.mDisplayDirectory &&
+ this.mDisplayDirectory.clone()
+ .QueryInterface(nsILocalFile);
+ },
+
+ /* readonly attribute nsILocalFile file; */
+ set file(a) { throw "readonly property"; },
+ get file() { return this.mFilesEnumerator.mFiles[0]; },
+
+ /* readonly attribute nsISimpleEnumerator files; */
+ set files(a) { throw "readonly property"; },
+ get files() { return this.mFilesEnumerator; },
+
+ /* readonly attribute nsIURI fileURL; */
+ set fileURL(a) { throw "readonly property"; },
+ get fileURL() {
+ if (this.mFileURL)
+ return this.mFileURL;
+
+ if (!this.mFilesEnumerator)
+ return null;
+
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+
+ return this.mFileURL = ioService.newFileURI(this.file);
+ },
+
+ /* attribute wstring defaultString; */
+ set defaultString(a) { this.mDefaultString = a; },
+ get defaultString() { return this.mDefaultString; },
+
+ /* attribute wstring defaultExtension */
+ set defaultExtension(ext) { },
+ get defaultExtension() { return ""; },
+
+ /* attribute long filterIndex; */
+ set filterIndex(a) { this.mFilterIndex = a; },
+ get filterIndex() { return this.mFilterIndex; },
+
+ /* members */
+ mFilesEnumerator: undefined,
+ mParentWindow: null,
+
+ /* methods */
+ init: function(parent, title, mode) {
+ this.mParentWindow = parent;
+ this.mTitle = title;
+ this.mMode = mode;
+ },
+
+ appendFilters: function(filterMask) {
+ if (filterMask & nsIFilePicker.filterHTML) {
+ this.appendFilter(bundle.GetStringFromName("htmlTitle"),
+ bundle.GetStringFromName("htmlFilter"));
+ }
+ if (filterMask & nsIFilePicker.filterText) {
+ this.appendFilter(bundle.GetStringFromName("textTitle"),
+ bundle.GetStringFromName("textFilter"));
+ }
+ if (filterMask & nsIFilePicker.filterImages) {
+ this.appendFilter(bundle.GetStringFromName("imageTitle"),
+ bundle.GetStringFromName("imageFilter"));
+ }
+ if (filterMask & nsIFilePicker.filterXML) {
+ this.appendFilter(bundle.GetStringFromName("xmlTitle"),
+ bundle.GetStringFromName("xmlFilter"));
+ }
+ if (filterMask & nsIFilePicker.filterXUL) {
+ this.appendFilter(bundle.GetStringFromName("xulTitle"),
+ bundle.GetStringFromName("xulFilter"));
+ }
+ this.mAllowURLs = !!(filterMask & nsIFilePicker.filterAllowURLs);
+ if (filterMask & nsIFilePicker.filterApps) {
+ // We use "..apps" as a special filter for executable files
+ this.appendFilter(bundle.GetStringFromName("appsTitle"),
+ "..apps");
+ }
+ if (filterMask & nsIFilePicker.filterAll) {
+ this.appendFilter(bundle.GetStringFromName("allTitle"),
+ bundle.GetStringFromName("allFilter"));
+ }
+ },
+
+ appendFilter: function(title, extensions) {
+ this.mFilterTitles.push(title);
+ this.mFilters.push(extensions);
+ },
+
+ QueryInterface: function(iid) {
+ if (iid.equals(nsIFilePicker) ||
+ iid.equals(nsISupports))
+ return this;
+
+ Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
+ return null;
+ },
+
+ show: function() {
+ var o = new Object();
+ o.title = this.mTitle;
+ o.mode = this.mMode;
+ o.displayDirectory = this.mDisplayDirectory;
+ o.defaultString = this.mDefaultString;
+ o.filterIndex = this.mFilterIndex;
+ o.filters = new Object();
+ o.filters.titles = this.mFilterTitles;
+ o.filters.types = this.mFilters;
+ o.allowURLs = this.mAllowURLs;
+ o.retvals = new Object();
+
+ var parent;
+ if (this.mParentWindow) {
+ parent = this.mParentWindow;
+ } else if (typeof(window) == "object" && window != null) {
+ parent = window;
+ } else {
+ try {
+ var appShellService = Components.classes[APPSHELL_SERV_CONTRACTID].getService(nsIAppShellService);
+ parent = appShellService.hiddenDOMWindow;
+ } catch(ex) {
+ debug("Can't get parent. xpconnect hates me so we can't get one from the appShellService.\n");
+ debug(ex + "\n");
+ }
+ }
+
+ var parentWin = null;
+ try {
+ parentWin = parent.QueryInterface(nsIInterfaceRequestor)
+ .getInterface(nsIWebNavigation)
+ .QueryInterface(nsIDocShellTreeItem)
+ .treeOwner
+ .QueryInterface(nsIInterfaceRequestor)
+ .getInterface(nsIBaseWindow);
+ } catch(ex) {
+ dump("file picker couldn't get base window\n"+ex+"\n");
+ }
+ try {
+ if (parentWin)
+ parentWin.blurSuppression = true;
+ parent.openDialog("chrome://global/content/filepicker.xul",
+ "",
+ "chrome,modal,titlebar,resizable=yes,dependent=yes",
+ o);
+ if (parentWin)
+ parentWin.blurSuppression = false;
+
+ this.mFilterIndex = o.retvals.filterIndex;
+ this.mFilesEnumerator = o.retvals.files;
+ this.mFileURL = o.retvals.fileURL;
+ lastDirectory = o.retvals.directory;
+ return o.retvals.buttonStatus;
+ } catch(ex) { dump("unable to open file picker\n" + ex + "\n"); }
+
+ return null;
+ }
+}
+
+if (DEBUG)
+ debug = function (s) { dump("-*- filepicker: " + s + "\n"); }
+else
+ debug = function (s) {}
+
+/* module foo */
+
+var filePickerModule = new Object();
+
+filePickerModule.registerSelf =
+function (compMgr, fileSpec, location, type)
+{
+ debug("registering (all right -- a JavaScript module!)");
+ compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+
+ compMgr.registerFactoryLocation(FILEPICKER_CID,
+ "FilePicker JS Component",
+//@line 284 "/builds/moz2_slave/linux_build/build/toolkit/components/filepicker/src/nsFilePicker.js.in"
+ "",
+//@line 286 "/builds/moz2_slave/linux_build/build/toolkit/components/filepicker/src/nsFilePicker.js.in"
+ fileSpec,
+ location,
+ type);
+}
+
+filePickerModule.getClassObject =
+function (compMgr, cid, iid) {
+ if (!cid.equals(FILEPICKER_CID))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+
+ if (!iid.equals(Components.interfaces.nsIFactory))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ return filePickerFactory;
+}
+
+filePickerModule.canUnload =
+function(compMgr)
+{
+ debug("Unloading component.");
+ return true;
+}
+
+/* factory object */
+var filePickerFactory = new Object();
+
+filePickerFactory.createInstance =
+function (outer, iid) {
+ debug("CI: " + iid);
+ debug("IID:" + nsIFilePicker);
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ return (new nsFilePicker()).QueryInterface(iid);
+}
+
+/* entrypoint */
+function NSGetModule(compMgr, fileSpec) {
+ return filePickerModule;
+}
+
+
+
+/* crap from strres.js that I want to use for string bundles since I can't include another .js file.... */
+
+var strBundleService = null;
+
+function srGetStrBundle(path)
+{
+ var strBundle = null;
+
+ if (!strBundleService) {
+ try {
+ strBundleService = Components.classes[STRBUNDLE_SERV_CONTRACTID].getService(nsIStringBundleService);
+ } catch (ex) {
+ dump("\n--** strBundleService createInstance failed **--\n");
+ return null;
+ }
+ }
+
+ strBundle = strBundleService.createBundle(path);
+ if (!strBundle) {
+ dump("\n--** strBundle createInstance failed **--\n");
+ }
+ return strBundle;
+}
+
diff --git a/bundles/XO/components/nsHandlerService.js b/bundles/XO/components/nsHandlerService.js
new file mode 100755
index 0000000..e5c21f0
--- /dev/null
+++ b/bundles/XO/components/nsHandlerService.js
@@ -0,0 +1,1431 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Myk Melez <myk@mozilla.org>
+ * Dan Mosedale <dmose@mozilla.org>
+ * Florian Queze <florian@queze.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+
+const CLASS_MIMEINFO = "mimetype";
+const CLASS_PROTOCOLINFO = "scheme";
+
+
+// namespace prefix
+const NC_NS = "http://home.netscape.com/NC-rdf#";
+
+// the most recent default handlers that have been injected. Note that
+// this is used to construct an RDF resource, which needs to have NC_NS
+// prepended, since that hasn't been done yet
+const DEFAULT_HANDLERS_VERSION = "defaultHandlersVersion";
+
+// type list properties
+
+const NC_MIME_TYPES = NC_NS + "MIME-types";
+const NC_PROTOCOL_SCHEMES = NC_NS + "Protocol-Schemes";
+
+// content type ("type") properties
+
+// nsIHandlerInfo::type
+const NC_VALUE = NC_NS + "value";
+const NC_DESCRIPTION = NC_NS + "description";
+
+// additional extensions
+const NC_FILE_EXTENSIONS = NC_NS + "fileExtensions";
+
+// references nsIHandlerInfo record
+const NC_HANDLER_INFO = NC_NS + "handlerProp";
+
+// handler info ("info") properties
+
+// nsIHandlerInfo::preferredAction
+const NC_SAVE_TO_DISK = NC_NS + "saveToDisk";
+const NC_HANDLE_INTERNALLY = NC_NS + "handleInternal";
+const NC_USE_SYSTEM_DEFAULT = NC_NS + "useSystemDefault";
+
+// nsIHandlerInfo::alwaysAskBeforeHandling
+const NC_ALWAYS_ASK = NC_NS + "alwaysAsk";
+
+// references nsIHandlerApp records
+const NC_PREFERRED_APP = NC_NS + "externalApplication";
+const NC_POSSIBLE_APP = NC_NS + "possibleApplication";
+
+// handler app ("handler") properties
+
+// nsIHandlerApp::name
+const NC_PRETTY_NAME = NC_NS + "prettyName";
+
+// nsILocalHandlerApp::executable
+const NC_PATH = NC_NS + "path";
+
+// nsIWebHandlerApp::uriTemplate
+const NC_URI_TEMPLATE = NC_NS + "uriTemplate";
+
+// nsIDBusHandlerApp::service
+const NC_SERVICE = NC_NS + "service";
+
+// nsIDBusHandlerApp::method
+const NC_METHOD = NC_NS + "method";
+
+// nsIDBusHandlerApp::objectPath
+const NC_OBJPATH = NC_NS + "objectPath";
+
+// nsIDBusHandlerApp::dbusInterface
+const NC_INTERFACE = NC_NS + "dBusInterface";
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+
+function HandlerService() {
+ this._init();
+}
+
+HandlerService.prototype = {
+ //**************************************************************************//
+ // XPCOM Plumbing
+
+ classDescription: "Handler Service",
+ classID: Components.ID("{32314cc8-22f7-4f7f-a645-1a45453ba6a6}"),
+ contractID: "@mozilla.org/uriloader/handler-service;1",
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIHandlerService]),
+
+
+ //**************************************************************************//
+ // Initialization & Destruction
+
+ _init: function HS__init() {
+ // Observe profile-before-change so we can switch to the datasource
+ // in the new profile when the user changes profiles.
+ this._observerSvc.addObserver(this, "profile-before-change", false);
+
+ // Observe xpcom-shutdown so we can remove these observers
+ // when the application shuts down.
+ this._observerSvc.addObserver(this, "xpcom-shutdown", false);
+
+ // Observe profile-do-change so that non-default profiles get upgraded too
+ this._observerSvc.addObserver(this, "profile-do-change", false);
+
+ // do any necessary updating of the datastore
+ this._updateDB();
+ },
+
+ _updateDB: function HS__updateDB() {
+ try {
+ var defaultHandlersVersion = this._datastoreDefaultHandlersVersion;
+ } catch(ex) {
+ // accessing the datastore failed, we can't update anything
+ return;
+ }
+
+ try {
+ // if we don't have the current version of the default prefs for
+ // this locale, inject any new default handers into the datastore
+ if (defaultHandlersVersion < this._prefsDefaultHandlersVersion) {
+
+ // set the new version first so that if we recurse we don't
+ // call _injectNewDefaults several times
+ this._datastoreDefaultHandlersVersion =
+ this._prefsDefaultHandlersVersion;
+ this._injectNewDefaults();
+ }
+ } catch (ex) {
+ // if injecting the defaults failed, set the version back to the
+ // previous value
+ this._datastoreDefaultHandlersVersion = defaultHandlersVersion;
+ }
+ },
+
+ get _currentLocale() {
+ var chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].
+ getService(Ci.nsIXULChromeRegistry);
+ var currentLocale = chromeRegistry.getSelectedLocale("global");
+ return currentLocale;
+ },
+
+ _destroy: function HS__destroy() {
+ this._observerSvc.removeObserver(this, "profile-before-change");
+ this._observerSvc.removeObserver(this, "xpcom-shutdown");
+ this._observerSvc.removeObserver(this, "profile-do-change");
+
+ // XXX Should we also null references to all the services that get stored
+ // by our memoizing getters in the Convenience Getters section?
+ },
+
+ _onProfileChange: function HS__onProfileChange() {
+ // Lose our reference to the datasource so we reacquire it
+ // from the new profile the next time we need it.
+ this.__ds = null;
+ },
+
+ _isInHandlerArray: function HS__isInHandlerArray(aArray, aHandler) {
+ var enumerator = aArray.enumerate();
+ while (enumerator.hasMoreElements()) {
+ let handler = enumerator.getNext();
+ handler.QueryInterface(Ci.nsIHandlerApp);
+ if (handler.equals(aHandler))
+ return true;
+ }
+
+ return false;
+ },
+
+ // note that this applies to the current locale only
+ get _datastoreDefaultHandlersVersion() {
+ var version = this._getValue("urn:root", NC_NS + this._currentLocale +
+ "_" + DEFAULT_HANDLERS_VERSION);
+
+ return version ? version : -1;
+ },
+
+ set _datastoreDefaultHandlersVersion(aNewVersion) {
+ return this._setLiteral("urn:root", NC_NS + this._currentLocale + "_" +
+ DEFAULT_HANDLERS_VERSION, aNewVersion);
+ },
+
+ get _prefsDefaultHandlersVersion() {
+ // get handler service pref branch
+ var prefSvc = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ var handlerSvcBranch = prefSvc.getBranch("gecko.handlerService.");
+
+ // get the version of the preferences for this locale
+ return Number(handlerSvcBranch.
+ getComplexValue("defaultHandlersVersion",
+ Ci.nsIPrefLocalizedString).data);
+ },
+
+ _injectNewDefaults: function HS__injectNewDefaults() {
+ // get handler service pref branch
+ var prefSvc = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+
+ let schemesPrefBranch = prefSvc.getBranch("gecko.handlerService.schemes.");
+ let schemePrefList = schemesPrefBranch.getChildList("", {});
+
+ var schemes = {};
+
+ // read all the scheme prefs into a hash
+ for each (var schemePrefName in schemePrefList) {
+
+ let [scheme, handlerNumber, attribute] = schemePrefName.split(".");
+
+ try {
+ var attrData =
+ schemesPrefBranch.getComplexValue(schemePrefName,
+ Ci.nsIPrefLocalizedString).data;
+ if (!(scheme in schemes))
+ schemes[scheme] = {};
+
+ if (!(handlerNumber in schemes[scheme]))
+ schemes[scheme][handlerNumber] = {};
+
+ schemes[scheme][handlerNumber][attribute] = attrData;
+ } catch (ex) {}
+ }
+
+ let protoSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
+ getService(Ci.nsIExternalProtocolService);
+ for (var scheme in schemes) {
+
+ // This clause is essentially a reimplementation of
+ // nsIExternalProtocolHandlerService.getProtocolHandlerInfo().
+ // Necessary because calling that from here would make XPConnect barf
+ // when getService tried to re-enter the constructor for this
+ // service.
+ let osDefaultHandlerFound = {};
+ let protoInfo = protoSvc.getProtocolHandlerInfoFromOS(scheme,
+ osDefaultHandlerFound);
+
+ if (this.exists(protoInfo))
+ this.fillHandlerInfo(protoInfo, null);
+ else
+ protoSvc.setProtocolHandlerDefaults(protoInfo,
+ osDefaultHandlerFound.value);
+
+ // cache the possible handlers to avoid extra xpconnect traversals.
+ let possibleHandlers = protoInfo.possibleApplicationHandlers;
+
+ for each (var handlerPrefs in schemes[scheme]) {
+
+ let handlerApp = Cc["@mozilla.org/uriloader/web-handler-app;1"].
+ createInstance(Ci.nsIWebHandlerApp);
+
+ handlerApp.uriTemplate = handlerPrefs.uriTemplate;
+ handlerApp.name = handlerPrefs.name;
+
+ if (!this._isInHandlerArray(possibleHandlers, handlerApp)) {
+ possibleHandlers.appendElement(handlerApp, false);
+ }
+ }
+
+ this.store(protoInfo);
+ }
+ },
+
+ //**************************************************************************//
+ // nsIObserver
+
+ observe: function HS__observe(subject, topic, data) {
+ switch(topic) {
+ case "profile-before-change":
+ this._onProfileChange();
+ break;
+ case "xpcom-shutdown":
+ this._destroy();
+ break;
+ case "profile-do-change":
+ this._updateDB();
+ break;
+ }
+ },
+
+
+ //**************************************************************************//
+ // nsIHandlerService
+
+ enumerate: function HS_enumerate() {
+ var handlers = Cc["@mozilla.org/array;1"].
+ createInstance(Ci.nsIMutableArray);
+ this._appendHandlers(handlers, CLASS_MIMEINFO);
+ this._appendHandlers(handlers, CLASS_PROTOCOLINFO);
+ return handlers.enumerate();
+ },
+
+ fillHandlerInfo: function HS_fillHandlerInfo(aHandlerInfo, aOverrideType) {
+ var type = aOverrideType || aHandlerInfo.type;
+ var typeID = this._getTypeID(this._getClass(aHandlerInfo), type);
+
+ // Determine whether or not information about this handler is available
+ // in the datastore by looking for its "value" property, which stores its
+ // type and should always be present.
+ if (!this._hasValue(typeID, NC_VALUE))
+ throw Cr.NS_ERROR_NOT_AVAILABLE;
+
+ // Retrieve the human-readable description of the type.
+ if (this._hasValue(typeID, NC_DESCRIPTION))
+ aHandlerInfo.description = this._getValue(typeID, NC_DESCRIPTION);
+
+ // Note: for historical reasons, we don't actually check that the type
+ // record has a "handlerProp" property referencing the info record. It's
+ // unclear whether or not we should start doing this check; perhaps some
+ // legacy datasources don't have such references.
+ var infoID = this._getInfoID(this._getClass(aHandlerInfo), type);
+
+ aHandlerInfo.preferredAction = this._retrievePreferredAction(infoID);
+
+ var preferredHandlerID =
+ this._getPreferredHandlerID(this._getClass(aHandlerInfo), type);
+
+ // Retrieve the preferred handler.
+ // Note: for historical reasons, we don't actually check that the info
+ // record has an "externalApplication" property referencing the preferred
+ // handler record. It's unclear whether or not we should start doing
+ // this check; perhaps some legacy datasources don't have such references.
+ aHandlerInfo.preferredApplicationHandler =
+ this._retrieveHandlerApp(preferredHandlerID);
+
+ // Fill the array of possible handlers with the ones in the datastore.
+ this._fillPossibleHandlers(infoID,
+ aHandlerInfo.possibleApplicationHandlers,
+ aHandlerInfo.preferredApplicationHandler);
+
+ // If we have an "always ask" flag stored in the RDF, always use its
+ // value. Otherwise, use the default value stored in the pref service.
+ var alwaysAsk;
+ if (this._hasValue(infoID, NC_ALWAYS_ASK)) {
+ alwaysAsk = (this._getValue(infoID, NC_ALWAYS_ASK) != "false");
+ } else {
+ var prefSvc = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ var prefBranch = prefSvc.getBranch("network.protocol-handler.");
+ try {
+ alwaysAsk = prefBranch.getBoolPref("warn-external." + type);
+ } catch (e) {
+ // will throw if pref didn't exist.
+ try {
+ alwaysAsk = prefBranch.getBoolPref("warn-external-default");
+ } catch (e) {
+ // Nothing to tell us what to do, so be paranoid and prompt.
+ alwaysAsk = true;
+ }
+ }
+ }
+ aHandlerInfo.alwaysAskBeforeHandling = alwaysAsk;
+
+ // If the object represents a MIME type handler, then also retrieve
+ // any file extensions.
+ if (aHandlerInfo instanceof Ci.nsIMIMEInfo)
+ for each (let fileExtension in this._retrieveFileExtensions(typeID))
+ aHandlerInfo.appendExtension(fileExtension);
+ },
+
+ store: function HS_store(aHandlerInfo) {
+ // FIXME: when we switch from RDF to something with transactions (like
+ // SQLite), enclose the following changes in a transaction so they all
+ // get rolled back if any of them fail and we don't leave the datastore
+ // in an inconsistent state.
+
+ this._ensureRecordsForType(aHandlerInfo);
+ this._storePreferredAction(aHandlerInfo);
+ this._storePreferredHandler(aHandlerInfo);
+ this._storePossibleHandlers(aHandlerInfo);
+ this._storeAlwaysAsk(aHandlerInfo);
+
+ // Write the changes to the database immediately so we don't lose them
+ // if the application crashes.
+ if (this._ds instanceof Ci.nsIRDFRemoteDataSource)
+ this._ds.Flush();
+ },
+
+ exists: function HS_exists(aHandlerInfo) {
+ var found;
+
+ try {
+ var typeID = this._getTypeID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+ found = this._hasLiteralAssertion(typeID, NC_VALUE, aHandlerInfo.type);
+ } catch (e) {
+ // If the RDF threw (eg, corrupt file), treat as non-existent.
+ found = false;
+ }
+
+ return found;
+ },
+
+ remove: function HS_remove(aHandlerInfo) {
+ var preferredHandlerID =
+ this._getPreferredHandlerID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+ this._removeAssertions(preferredHandlerID);
+
+ var infoID = this._getInfoID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+
+ // Get a list of possible handlers. After we have removed the info record,
+ // we'll check if any other info records reference these handlers, and we'll
+ // remove the handler records that aren't referenced by other info records.
+ var possibleHandlerIDs = [];
+ var possibleHandlerTargets = this._getTargets(infoID, NC_POSSIBLE_APP);
+ while (possibleHandlerTargets.hasMoreElements()) {
+ let possibleHandlerTarget = possibleHandlerTargets.getNext();
+ // Note: possibleHandlerTarget should always be an nsIRDFResource.
+ // The conditional is just here in case of a corrupt RDF datasource.
+ if (possibleHandlerTarget instanceof Ci.nsIRDFResource)
+ possibleHandlerIDs.push(possibleHandlerTarget.ValueUTF8);
+ }
+
+ // Remove the info record.
+ this._removeAssertions(infoID);
+
+ // Now that we've removed the info record, remove any possible handlers
+ // that aren't referenced by other info records.
+ for each (let possibleHandlerID in possibleHandlerIDs)
+ if (!this._existsResourceTarget(NC_POSSIBLE_APP, possibleHandlerID))
+ this._removeAssertions(possibleHandlerID);
+
+ var typeID = this._getTypeID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+ this._removeAssertions(typeID);
+
+ // Now that there's no longer a handler for this type, remove the type
+ // from the list of types for which there are known handlers.
+ var typeList = this._ensureAndGetTypeList(this._getClass(aHandlerInfo));
+ var type = this._rdf.GetResource(typeID);
+ var typeIndex = typeList.IndexOf(type);
+ if (typeIndex != -1)
+ typeList.RemoveElementAt(typeIndex, true);
+
+ // Write the changes to the database immediately so we don't lose them
+ // if the application crashes.
+ // XXX If we're removing a bunch of handlers at once, will flushing
+ // after every removal cause a significant performance hit?
+ if (this._ds instanceof Ci.nsIRDFRemoteDataSource)
+ this._ds.Flush();
+ },
+
+ getTypeFromExtension: function HS_getTypeFromExtension(aFileExtension) {
+ var fileExtension = aFileExtension.toLowerCase();
+ var typeID;
+
+ if (this._existsLiteralTarget(NC_FILE_EXTENSIONS, fileExtension))
+ typeID = this._getSourceForLiteral(NC_FILE_EXTENSIONS, fileExtension);
+
+ if (typeID && this._hasValue(typeID, NC_VALUE)) {
+ let type = this._getValue(typeID, NC_VALUE);
+ if (type == "")
+ throw Cr.NS_ERROR_FAILURE;
+ return type;
+ }
+
+ return "";
+ },
+
+
+ //**************************************************************************//
+ // Retrieval Methods
+
+ /**
+ * Retrieve the preferred action for the info record with the given ID.
+ *
+ * @param aInfoID {string} the info record ID
+ *
+ * @returns {integer} the preferred action enumeration value
+ */
+ _retrievePreferredAction: function HS__retrievePreferredAction(aInfoID) {
+ if (this._getValue(aInfoID, NC_SAVE_TO_DISK) == "true")
+ return Ci.nsIHandlerInfo.saveToDisk;
+
+ if (this._getValue(aInfoID, NC_USE_SYSTEM_DEFAULT) == "true")
+ return Ci.nsIHandlerInfo.useSystemDefault;
+
+ if (this._getValue(aInfoID, NC_HANDLE_INTERNALLY) == "true")
+ return Ci.nsIHandlerInfo.handleInternal;
+
+ return Ci.nsIHandlerInfo.useHelperApp;
+ },
+
+ /**
+ * Fill an array of possible handlers with the handlers for the given info ID.
+ *
+ * @param aInfoID {string} the ID of the info record
+ * @param aPossibleHandlers {nsIMutableArray} the array of possible handlers
+ * @param aPreferredHandler {nsIHandlerApp} the preferred handler, if any
+ */
+ _fillPossibleHandlers: function HS__fillPossibleHandlers(aInfoID,
+ aPossibleHandlers,
+ aPreferredHandler) {
+ // The set of possible handlers should include the preferred handler,
+ // but legacy datastores (from before we added possible handlers) won't
+ // include the preferred handler, so check if it's included as we build
+ // the list of handlers, and, if it's not included, add it to the list.
+ if (aPreferredHandler)
+ aPossibleHandlers.appendElement(aPreferredHandler, false);
+
+ var possibleHandlerTargets = this._getTargets(aInfoID, NC_POSSIBLE_APP);
+
+ while (possibleHandlerTargets.hasMoreElements()) {
+ let possibleHandlerTarget = possibleHandlerTargets.getNext();
+ if (!(possibleHandlerTarget instanceof Ci.nsIRDFResource))
+ continue;
+
+ let possibleHandlerID = possibleHandlerTarget.ValueUTF8;
+ let possibleHandler = this._retrieveHandlerApp(possibleHandlerID);
+ if (possibleHandler && (!aPreferredHandler ||
+ !possibleHandler.equals(aPreferredHandler)))
+ aPossibleHandlers.appendElement(possibleHandler, false);
+ }
+ },
+
+ /**
+ * Retrieve the handler app object with the given ID.
+ *
+ * @param aHandlerAppID {string} the ID of the handler app to retrieve
+ *
+ * @returns {nsIHandlerApp} the handler app, if any; otherwise null
+ */
+ _retrieveHandlerApp: function HS__retrieveHandlerApp(aHandlerAppID) {
+ var handlerApp;
+
+ // If it has a path, it's a local handler; otherwise, it's a web handler.
+ if (this._hasValue(aHandlerAppID, NC_PATH)) {
+ let executable =
+ this._getFileWithPath(this._getValue(aHandlerAppID, NC_PATH));
+ if (!executable)
+ return null;
+
+ handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+ createInstance(Ci.nsILocalHandlerApp);
+ handlerApp.executable = executable;
+ }
+ else if (this._hasValue(aHandlerAppID, NC_URI_TEMPLATE)) {
+ let uriTemplate = this._getValue(aHandlerAppID, NC_URI_TEMPLATE);
+ if (!uriTemplate)
+ return null;
+
+ handlerApp = Cc["@mozilla.org/uriloader/web-handler-app;1"].
+ createInstance(Ci.nsIWebHandlerApp);
+ handlerApp.uriTemplate = uriTemplate;
+ }
+ else if (this._hasValue(aHandlerAppID, NC_SERVICE)) {
+ let service = this._getValue(aHandlerAppID, NC_SERVICE);
+ if (!service)
+ return null;
+
+ let method = this._getValue(aHandlerAppID, NC_METHOD);
+ if (!method)
+ return null;
+
+ let objpath = this._getValue(aHandlerAppID, NC_OBJPATH);
+ if (!objpath)
+ return null;
+
+ let interface = this._getValue(aHandlerAppID, NC_INTERFACE);
+ if (!interface)
+ return null;
+
+ handlerApp = Cc["@mozilla.org/uriloader/dbus-handler-app;1"].
+ createInstance(Ci.nsIDBusHandlerApp);
+ handlerApp.service = service;
+ handlerApp.method = method;
+ handlerApp.objectPath = objpath;
+ handlerApp.dBusInterface = interface;
+
+ }
+ else
+ return null;
+
+ handlerApp.name = this._getValue(aHandlerAppID, NC_PRETTY_NAME);
+
+ return handlerApp;
+ },
+
+ /*
+ * Retrieve file extensions, if any, for the MIME type with the given type ID.
+ *
+ * @param aTypeID {string} the type record ID
+ */
+ _retrieveFileExtensions: function HS__retrieveFileExtensions(aTypeID) {
+ var fileExtensions = [];
+
+ var fileExtensionTargets = this._getTargets(aTypeID, NC_FILE_EXTENSIONS);
+
+ while (fileExtensionTargets.hasMoreElements()) {
+ let fileExtensionTarget = fileExtensionTargets.getNext();
+ if (fileExtensionTarget instanceof Ci.nsIRDFLiteral &&
+ fileExtensionTarget.Value != "")
+ fileExtensions.push(fileExtensionTarget.Value);
+ }
+
+ return fileExtensions;
+ },
+
+ /**
+ * Get the file with the given path. This is not as simple as merely
+ * initializing a local file object with the path, because the path might be
+ * relative to the current process directory, in which case we have to
+ * construct a path starting from that directory.
+ *
+ * @param aPath {string} a path to a file
+ *
+ * @returns {nsILocalFile} the file, or null if the file does not exist
+ */
+ _getFileWithPath: function HS__getFileWithPath(aPath) {
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+
+ try {
+ file.initWithPath(aPath);
+
+ if (file.exists())
+ return file;
+ }
+ catch(ex) {
+ // Note: for historical reasons, we don't actually check to see
+ // if the exception is NS_ERROR_FILE_UNRECOGNIZED_PATH, which is what
+ // nsILocalFile::initWithPath throws when a path is relative.
+
+ file = this._dirSvc.get("XCurProcD", Ci.nsIFile);
+
+ try {
+ file.append(aPath);
+ if (file.exists())
+ return file;
+ }
+ catch(ex) {}
+ }
+
+ return null;
+ },
+
+
+ //**************************************************************************//
+ // Storage Methods
+
+ _storePreferredAction: function HS__storePreferredAction(aHandlerInfo) {
+ var infoID = this._getInfoID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+
+ switch(aHandlerInfo.preferredAction) {
+ case Ci.nsIHandlerInfo.saveToDisk:
+ this._setLiteral(infoID, NC_SAVE_TO_DISK, "true");
+ this._removeTarget(infoID, NC_HANDLE_INTERNALLY);
+ this._removeTarget(infoID, NC_USE_SYSTEM_DEFAULT);
+ break;
+
+ case Ci.nsIHandlerInfo.handleInternally:
+ this._setLiteral(infoID, NC_HANDLE_INTERNALLY, "true");
+ this._removeTarget(infoID, NC_SAVE_TO_DISK);
+ this._removeTarget(infoID, NC_USE_SYSTEM_DEFAULT);
+ break;
+
+ case Ci.nsIHandlerInfo.useSystemDefault:
+ this._setLiteral(infoID, NC_USE_SYSTEM_DEFAULT, "true");
+ this._removeTarget(infoID, NC_SAVE_TO_DISK);
+ this._removeTarget(infoID, NC_HANDLE_INTERNALLY);
+ break;
+
+ // This value is indicated in the datastore either by the absence of
+ // the three properties or by setting them all "false". Of these two
+ // options, the former seems preferable, because it reduces the size
+ // of the RDF file and thus the amount of stuff we have to parse.
+ case Ci.nsIHandlerInfo.useHelperApp:
+ default:
+ this._removeTarget(infoID, NC_SAVE_TO_DISK);
+ this._removeTarget(infoID, NC_HANDLE_INTERNALLY);
+ this._removeTarget(infoID, NC_USE_SYSTEM_DEFAULT);
+ break;
+ }
+ },
+
+ _storePreferredHandler: function HS__storePreferredHandler(aHandlerInfo) {
+ var infoID = this._getInfoID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+ var handlerID =
+ this._getPreferredHandlerID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+
+ var handler = aHandlerInfo.preferredApplicationHandler;
+
+ if (handler) {
+ this._storeHandlerApp(handlerID, handler);
+
+ // Make this app be the preferred app for the handler info.
+ //
+ // Note: nsExternalHelperAppService::FillContentHandlerProperties ignores
+ // this setting and instead identifies the preferred app as the resource
+ // whose URI follows the pattern urn:<class>:externalApplication:<type>.
+ // But the old downloadactions.js code used to set this property, so just
+ // in case there is still some code somewhere that relies on its presence,
+ // we set it here.
+ this._setResource(infoID, NC_PREFERRED_APP, handlerID);
+ }
+ else {
+ // There isn't a preferred handler. Remove the existing record for it,
+ // if any.
+ this._removeTarget(infoID, NC_PREFERRED_APP);
+ this._removeAssertions(handlerID);
+ }
+ },
+
+ /**
+ * Store the list of possible handler apps for the content type represented
+ * by the given handler info object.
+ *
+ * @param aHandlerInfo {nsIHandlerInfo} the handler info object
+ */
+ _storePossibleHandlers: function HS__storePossibleHandlers(aHandlerInfo) {
+ var infoID = this._getInfoID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+
+ // First, retrieve the set of handler apps currently stored for the type,
+ // keeping track of their IDs in a hash that we'll use to determine which
+ // ones are no longer valid and should be removed.
+ var currentHandlerApps = {};
+ var currentHandlerTargets = this._getTargets(infoID, NC_POSSIBLE_APP);
+ while (currentHandlerTargets.hasMoreElements()) {
+ let handlerApp = currentHandlerTargets.getNext();
+ if (handlerApp instanceof Ci.nsIRDFResource) {
+ let handlerAppID = handlerApp.ValueUTF8;
+ currentHandlerApps[handlerAppID] = true;
+ }
+ }
+
+ // Next, store any new handler apps.
+ var newHandlerApps =
+ aHandlerInfo.possibleApplicationHandlers.enumerate();
+ while (newHandlerApps.hasMoreElements()) {
+ let handlerApp =
+ newHandlerApps.getNext().QueryInterface(Ci.nsIHandlerApp);
+ let handlerAppID = this._getPossibleHandlerAppID(handlerApp);
+ if (!this._hasResourceAssertion(infoID, NC_POSSIBLE_APP, handlerAppID)) {
+ this._storeHandlerApp(handlerAppID, handlerApp);
+ this._addResourceAssertion(infoID, NC_POSSIBLE_APP, handlerAppID);
+ }
+ delete currentHandlerApps[handlerAppID];
+ }
+
+ // Finally, remove any old handler apps that aren't being used anymore,
+ // and if those handler apps aren't being used by any other type either,
+ // then completely remove their record from the datastore so we don't
+ // leave it clogged up with information about handler apps we don't care
+ // about anymore.
+ for (let handlerAppID in currentHandlerApps) {
+ this._removeResourceAssertion(infoID, NC_POSSIBLE_APP, handlerAppID);
+ if (!this._existsResourceTarget(NC_POSSIBLE_APP, handlerAppID))
+ this._removeAssertions(handlerAppID);
+ }
+ },
+
+ /**
+ * Store the given handler app.
+ *
+ * Note: the reason this method takes the ID of the handler app in a param
+ * is that the ID is different than it usually is when the handler app
+ * in question is a preferred handler app, so this method can't just derive
+ * the ID of the handler app by calling _getPossibleHandlerAppID, its callers
+ * have to do that for it.
+ *
+ * @param aHandlerAppID {string} the ID of the handler app to store
+ * @param aHandlerApp {nsIHandlerApp} the handler app to store
+ */
+ _storeHandlerApp: function HS__storeHandlerApp(aHandlerAppID, aHandlerApp) {
+ aHandlerApp.QueryInterface(Ci.nsIHandlerApp);
+ this._setLiteral(aHandlerAppID, NC_PRETTY_NAME, aHandlerApp.name);
+
+ // In the case of the preferred handler, the handler ID could have been
+ // used to refer to a different kind of handler in the past (i.e. either
+ // a local hander or a web handler), so if the new handler is a local
+ // handler, then we remove any web handler properties and vice versa.
+ // This is unnecessary but harmless for possible handlers.
+
+ if (aHandlerApp instanceof Ci.nsILocalHandlerApp) {
+ this._setLiteral(aHandlerAppID, NC_PATH, aHandlerApp.executable.path);
+ this._removeTarget(aHandlerAppID, NC_URI_TEMPLATE);
+ this._removeTarget(aHandlerAppID, NC_METHOD);
+ this._removeTarget(aHandlerAppID, NC_SERVICE);
+ this._removeTarget(aHandlerAppID, NC_OBJPATH);
+ this._removeTarget(aHandlerAppID, NC_INTERFACE);
+ }
+ else if(aHandlerApp instanceof Ci.nsIWebHandlerApp){
+ aHandlerApp.QueryInterface(Ci.nsIWebHandlerApp);
+ this._setLiteral(aHandlerAppID, NC_URI_TEMPLATE, aHandlerApp.uriTemplate);
+ this._removeTarget(aHandlerAppID, NC_PATH);
+ this._removeTarget(aHandlerAppID, NC_METHOD);
+ this._removeTarget(aHandlerAppID, NC_SERVICE);
+ this._removeTarget(aHandlerAppID, NC_OBJPATH);
+ this._removeTarget(aHandlerAppID, NC_INTERFACE);
+ }
+ else if(aHandlerApp instanceof Ci.nsIDBusHandlerApp){
+ aHandlerApp.QueryInterface(Ci.nsIDBusHandlerApp);
+ this._setLiteral(aHandlerAppID, NC_SERVICE, aHandlerApp.service);
+ this._setLiteral(aHandlerAppID, NC_METHOD, aHandlerApp.method);
+ this._setLiteral(aHandlerAppID, NC_OBJPATH, aHandlerApp.objectPath);
+ this._setLiteral(aHandlerAppID, NC_INTERFACE, aHandlerApp.dBusInterface);
+ this._removeTarget(aHandlerAppID, NC_PATH);
+ this._removeTarget(aHandlerAppID, NC_URI_TEMPLATE);
+ }
+ else {
+ throw "unknown handler type";
+ }
+
+ },
+
+ _storeAlwaysAsk: function HS__storeAlwaysAsk(aHandlerInfo) {
+ var infoID = this._getInfoID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+ this._setLiteral(infoID,
+ NC_ALWAYS_ASK,
+ aHandlerInfo.alwaysAskBeforeHandling ? "true" : "false");
+ },
+
+
+ //**************************************************************************//
+ // Convenience Getters
+
+ // Observer Service
+ __observerSvc: null,
+ get _observerSvc() {
+ if (!this.__observerSvc)
+ this.__observerSvc =
+ Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ return this.__observerSvc;
+ },
+
+ // Directory Service
+ __dirSvc: null,
+ get _dirSvc() {
+ if (!this.__dirSvc)
+ this.__dirSvc =
+ Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ return this.__dirSvc;
+ },
+
+ // MIME Service
+ __mimeSvc: null,
+ get _mimeSvc() {
+ if (!this.__mimeSvc)
+ this.__mimeSvc =
+ Cc["@mozilla.org/mime;1"].
+ getService(Ci.nsIMIMEService);
+ return this.__mimeSvc;
+ },
+
+ // Protocol Service
+ __protocolSvc: null,
+ get _protocolSvc() {
+ if (!this.__protocolSvc)
+ this.__protocolSvc =
+ Cc["@mozilla.org/uriloader/external-protocol-service;1"].
+ getService(Ci.nsIExternalProtocolService);
+ return this.__protocolSvc;
+ },
+
+ // RDF Service
+ __rdf: null,
+ get _rdf() {
+ if (!this.__rdf)
+ this.__rdf = Cc["@mozilla.org/rdf/rdf-service;1"].
+ getService(Ci.nsIRDFService);
+ return this.__rdf;
+ },
+
+ // RDF Container Utils
+ __containerUtils: null,
+ get _containerUtils() {
+ if (!this.__containerUtils)
+ this.__containerUtils = Cc["@mozilla.org/rdf/container-utils;1"].
+ getService(Ci.nsIRDFContainerUtils);
+ return this.__containerUtils;
+ },
+
+ // RDF datasource containing content handling config (i.e. mimeTypes.rdf)
+ __ds: null,
+ get _ds() {
+ if (!this.__ds) {
+ var file = this._dirSvc.get("UMimTyp", Ci.nsIFile);
+ // FIXME: make this a memoizing getter if we use it anywhere else.
+ var ioService = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var fileHandler = ioService.getProtocolHandler("file").
+ QueryInterface(Ci.nsIFileProtocolHandler);
+ this.__ds =
+ this._rdf.GetDataSourceBlocking(fileHandler.getURLSpecFromFile(file));
+ }
+
+ return this.__ds;
+ },
+
+
+ //**************************************************************************//
+ // Datastore Utils
+
+ /**
+ * Get the string identifying whether this is a MIME or a protocol handler.
+ * This string is used in the URI IDs of various RDF properties.
+ *
+ * @param aHandlerInfo {nsIHandlerInfo} the handler for which to get the class
+ *
+ * @returns {string} the class
+ */
+ _getClass: function HS__getClass(aHandlerInfo) {
+ if (aHandlerInfo instanceof Ci.nsIMIMEInfo)
+ return CLASS_MIMEINFO;
+ else
+ return CLASS_PROTOCOLINFO;
+ },
+
+ /**
+ * Return the unique identifier for a content type record, which stores
+ * the value field plus a reference to the content type's handler info record.
+ *
+ * |urn:<class>:<type>|
+ *
+ * XXX: should this be a property of nsIHandlerInfo?
+ *
+ * @param aClass {string} the class (CLASS_MIMEINFO or CLASS_PROTOCOLINFO)
+ * @param aType {string} the type (a MIME type or protocol scheme)
+ *
+ * @returns {string} the ID
+ */
+ _getTypeID: function HS__getTypeID(aClass, aType) {
+ return "urn:" + aClass + ":" + aType;
+ },
+
+ /**
+ * Return the unique identifier for a handler info record, which stores
+ * the preferredAction and alwaysAsk fields plus a reference to the preferred
+ * handler app. Roughly equivalent to the nsIHandlerInfo interface.
+ *
+ * |urn:<class>:handler:<type>|
+ *
+ * FIXME: the type info record should be merged into the type record,
+ * since there's a one to one relationship between them, and this record
+ * merely stores additional attributes of a content type.
+ *
+ * @param aClass {string} the class (CLASS_MIMEINFO or CLASS_PROTOCOLINFO)
+ * @param aType {string} the type (a MIME type or protocol scheme)
+ *
+ * @returns {string} the ID
+ */
+ _getInfoID: function HS__getInfoID(aClass, aType) {
+ return "urn:" + aClass + ":handler:" + aType;
+ },
+
+ /**
+ * Return the unique identifier for a preferred handler record, which stores
+ * information about the preferred handler for a given content type, including
+ * its human-readable name and the path to its executable (for a local app)
+ * or its URI template (for a web app).
+ *
+ * |urn:<class>:externalApplication:<type>|
+ *
+ * XXX: should this be a property of nsIHandlerApp?
+ *
+ * FIXME: this should be an arbitrary ID, and we should retrieve it from
+ * the datastore for a given content type via the NC:ExternalApplication
+ * property rather than looking for a specific ID, so a handler doesn't
+ * have to change IDs when it goes from being a possible handler to being
+ * the preferred one (once we support possible handlers).
+ *
+ * @param aClass {string} the class (CLASS_MIMEINFO or CLASS_PROTOCOLINFO)
+ * @param aType {string} the type (a MIME type or protocol scheme)
+ *
+ * @returns {string} the ID
+ */
+ _getPreferredHandlerID: function HS__getPreferredHandlerID(aClass, aType) {
+ return "urn:" + aClass + ":externalApplication:" + aType;
+ },
+
+ /**
+ * Return the unique identifier for a handler app record, which stores
+ * information about a possible handler for one or more content types,
+ * including its human-readable name and the path to its executable (for a
+ * local app) or its URI template (for a web app).
+ *
+ * Note: handler app IDs for preferred handlers are different. For those,
+ * see the _getPreferredHandlerID method.
+ *
+ * @param aHandlerApp {nsIHandlerApp} the handler app object
+ */
+ _getPossibleHandlerAppID: function HS__getPossibleHandlerAppID(aHandlerApp) {
+ var handlerAppID = "urn:handler:";
+
+ if (aHandlerApp instanceof Ci.nsILocalHandlerApp)
+ handlerAppID += "local:" + aHandlerApp.executable.path;
+ else if(aHandlerApp instanceof Ci.nsIWebHandlerApp){
+ aHandlerApp.QueryInterface(Ci.nsIWebHandlerApp);
+ handlerAppID += "web:" + aHandlerApp.uriTemplate;
+ }
+ else if(aHandlerApp instanceof Ci.nsIDBusHandlerApp){
+ aHandlerApp.QueryInterface(Ci.nsIDBusHandlerApp);
+ handlerAppID += "dbus:" + aHandlerApp.service + " " + aHandlerApp.method + " " + aHandlerApp.uriTemplate;
+ }else{
+ throw "unknown handler type";
+ }
+
+ return handlerAppID;
+ },
+
+ /**
+ * Get the list of types for the given class, creating the list if it doesn't
+ * already exist. The class can be either CLASS_MIMEINFO or CLASS_PROTOCOLINFO
+ * (i.e. the result of a call to _getClass).
+ *
+ * |urn:<class>s|
+ * |urn:<class>s:root|
+ *
+ * @param aClass {string} the class for which to retrieve a list of types
+ *
+ * @returns {nsIRDFContainer} the list of types
+ */
+ _ensureAndGetTypeList: function HS__ensureAndGetTypeList(aClass) {
+ var source = this._rdf.GetResource("urn:" + aClass + "s");
+ var property =
+ this._rdf.GetResource(aClass == CLASS_MIMEINFO ? NC_MIME_TYPES
+ : NC_PROTOCOL_SCHEMES);
+ var target = this._rdf.GetResource("urn:" + aClass + "s:root");
+
+ // Make sure we have an arc from the source to the target.
+ if (!this._ds.HasAssertion(source, property, target, true))
+ this._ds.Assert(source, property, target, true);
+
+ // Make sure the target is a container.
+ if (!this._containerUtils.IsContainer(this._ds, target))
+ this._containerUtils.MakeSeq(this._ds, target);
+
+ // Get the type list as an RDF container.
+ var typeList = Cc["@mozilla.org/rdf/container;1"].
+ createInstance(Ci.nsIRDFContainer);
+ typeList.Init(this._ds, target);
+
+ return typeList;
+ },
+
+ /**
+ * Make sure there are records in the datasource for the given content type
+ * by creating them if they don't already exist. We have to do this before
+ * storing any specific data, because we can't assume the presence
+ * of the records (the nsIHandlerInfo object might have been created
+ * from the OS), and the records have to all be there in order for the helper
+ * app service to properly construct an nsIHandlerInfo object for the type.
+ *
+ * Based on old downloadactions.js::_ensureMIMERegistryEntry.
+ *
+ * @param aHandlerInfo {nsIHandlerInfo} the type to make sure has a record
+ */
+ _ensureRecordsForType: function HS__ensureRecordsForType(aHandlerInfo) {
+ // Get the list of types.
+ var typeList = this._ensureAndGetTypeList(this._getClass(aHandlerInfo));
+
+ // If there's already a record in the datastore for this type, then we
+ // don't need to do anything more.
+ var typeID = this._getTypeID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+ var type = this._rdf.GetResource(typeID);
+ if (typeList.IndexOf(type) != -1)
+ return;
+
+ // Create a basic type record for this type.
+ typeList.AppendElement(type);
+ this._setLiteral(typeID, NC_VALUE, aHandlerInfo.type);
+
+ // Create a basic info record for this type.
+ var infoID = this._getInfoID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+ this._setLiteral(infoID, NC_ALWAYS_ASK, "false");
+ this._setResource(typeID, NC_HANDLER_INFO, infoID);
+ // XXX Shouldn't we set preferredAction to useSystemDefault?
+ // That's what it is if there's no record in the datastore; why should it
+ // change to useHelperApp just because we add a record to the datastore?
+
+ // Create a basic preferred handler record for this type.
+ // XXX Not sure this is necessary, since preferred handlers are optional,
+ // and nsExternalHelperAppService::FillHandlerInfoForTypeFromDS doesn't seem
+ // to require the record , but downloadactions.js::_ensureMIMERegistryEntry
+ // used to create it, so we'll do the same.
+ var preferredHandlerID =
+ this._getPreferredHandlerID(this._getClass(aHandlerInfo), aHandlerInfo.type);
+ this._setLiteral(preferredHandlerID, NC_PATH, "");
+ this._setResource(infoID, NC_PREFERRED_APP, preferredHandlerID);
+ },
+
+ /**
+ * Append known handlers of the given class to the given array. The class
+ * can be either CLASS_MIMEINFO or CLASS_PROTOCOLINFO.
+ *
+ * @param aHandlers {array} the array of handlers to append to
+ * @param aClass {string} the class for which to append handlers
+ */
+ _appendHandlers: function HS__appendHandlers(aHandlers, aClass) {
+ var typeList = this._ensureAndGetTypeList(aClass);
+ var enumerator = typeList.GetElements();
+
+ while (enumerator.hasMoreElements()) {
+ var element = enumerator.getNext();
+
+ // This should never happen. If it does, that means our datasource
+ // is corrupted with type list entries that point to literal values
+ // instead of resources. If it does happen, let's just do our best
+ // to recover by ignoring this entry and moving on to the next one.
+ if (!(element instanceof Ci.nsIRDFResource))
+ continue;
+
+ // Get the value of the element's NC:value property, which contains
+ // the MIME type or scheme for which we're retrieving a handler info.
+ var type = this._getValue(element.ValueUTF8, NC_VALUE);
+ if (!type)
+ continue;
+
+ var handler;
+ if (typeList.Resource.ValueUTF8 == "urn:mimetypes:root")
+ handler = this._mimeSvc.getFromTypeAndExtension(type, null);
+ else
+ handler = this._protocolSvc.getProtocolHandlerInfo(type);
+
+ aHandlers.appendElement(handler, false);
+ }
+ },
+
+ /**
+ * Whether or not a property of an RDF source has a value.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ * @returns {boolean} whether or not the property has a value
+ */
+ _hasValue: function HS__hasValue(sourceURI, propertyURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+ return this._ds.hasArcOut(source, property);
+ },
+
+ /**
+ * Get the value of a property of an RDF source.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ * @returns {string} the value of the property
+ */
+ _getValue: function HS__getValue(sourceURI, propertyURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+
+ var target = this._ds.GetTarget(source, property, true);
+
+ if (!target)
+ return null;
+
+ if (target instanceof Ci.nsIRDFResource)
+ return target.ValueUTF8;
+
+ if (target instanceof Ci.nsIRDFLiteral)
+ return target.Value;
+
+ return null;
+ },
+
+ /**
+ * Get all targets for the property of an RDF source.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ *
+ * @returns {nsISimpleEnumerator} an enumerator of targets
+ */
+ _getTargets: function HS__getTargets(sourceURI, propertyURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+
+ return this._ds.GetTargets(source, property, true);
+ },
+
+ /**
+ * Set a property of an RDF source to a literal value.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ * @param value {string} the literal value
+ */
+ _setLiteral: function HS__setLiteral(sourceURI, propertyURI, value) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetLiteral(value);
+
+ this._setTarget(source, property, target);
+ },
+
+ /**
+ * Set a property of an RDF source to a resource target.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ * @param targetURI {string} the URI of the target
+ */
+ _setResource: function HS__setResource(sourceURI, propertyURI, targetURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetResource(targetURI);
+
+ this._setTarget(source, property, target);
+ },
+
+ /**
+ * Assert an arc into the RDF datasource if there is no arc with the given
+ * source and property; otherwise, if there is already an existing arc,
+ * change it to point to the given target. _setLiteral and _setResource
+ * call this after converting their string arguments into resources
+ * and literals, and most callers should call one of those two methods
+ * instead of this one.
+ *
+ * @param source {nsIRDFResource} the source
+ * @param property {nsIRDFResource} the property
+ * @param target {nsIRDFNode} the target
+ */
+ _setTarget: function HS__setTarget(source, property, target) {
+ if (this._ds.hasArcOut(source, property)) {
+ var oldTarget = this._ds.GetTarget(source, property, true);
+ this._ds.Change(source, property, oldTarget, target);
+ }
+ else
+ this._ds.Assert(source, property, target, true);
+ },
+
+ /**
+ * Assert that a property of an RDF source has a resource target.
+ *
+ * The difference between this method and _setResource is that this one adds
+ * an assertion even if one already exists, which allows its callers to make
+ * sets of assertions (i.e. to set a property to multiple targets).
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ * @param targetURI {string} the URI of the target
+ */
+ _addResourceAssertion: function HS__addResourceAssertion(sourceURI,
+ propertyURI,
+ targetURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetResource(targetURI);
+
+ this._ds.Assert(source, property, target, true);
+ },
+
+ /**
+ * Remove an assertion with a resource target.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ * @param targetURI {string} the URI of the target
+ */
+ _removeResourceAssertion: function HS__removeResourceAssertion(sourceURI,
+ propertyURI,
+ targetURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetResource(targetURI);
+
+ this._ds.Unassert(source, property, target);
+ },
+
+ /**
+ * Whether or not a property of an RDF source has a given resource target.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ * @param targetURI {string} the URI of the target
+ *
+ * @returns {boolean} whether or not there is such an assertion
+ */
+ _hasResourceAssertion: function HS__hasResourceAssertion(sourceURI,
+ propertyURI,
+ targetURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetResource(targetURI);
+
+ return this._ds.HasAssertion(source, property, target, true);
+ },
+
+ /**
+ * Whether or not a property of an RDF source has a given literal value.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ * @param value {string} the literal value
+ *
+ * @returns {boolean} whether or not there is such an assertion
+ */
+ _hasLiteralAssertion: function HS__hasLiteralAssertion(sourceURI,
+ propertyURI,
+ value) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetLiteral(value);
+
+ return this._ds.HasAssertion(source, property, target, true);
+ },
+
+ /**
+ * Whether or not there is an RDF source that has the given property set to
+ * the given literal value.
+ *
+ * @param propertyURI {string} the URI of the property
+ * @param value {string} the literal value
+ *
+ * @returns {boolean} whether or not there is a source
+ */
+ _existsLiteralTarget: function HS__existsLiteralTarget(propertyURI, value) {
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetLiteral(value);
+
+ return this._ds.hasArcIn(target, property);
+ },
+
+ /**
+ * Get the source for a property set to a given literal value.
+ *
+ * @param propertyURI {string} the URI of the property
+ * @param value {string} the literal value
+ */
+ _getSourceForLiteral: function HS__getSourceForLiteral(propertyURI, value) {
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetLiteral(value);
+
+ var source = this._ds.GetSource(property, target, true);
+ if (source)
+ return source.ValueUTF8;
+
+ return null;
+ },
+
+ /**
+ * Whether or not there is an RDF source that has the given property set to
+ * the given resource target.
+ *
+ * @param propertyURI {string} the URI of the property
+ * @param targetURI {string} the URI of the target
+ *
+ * @returns {boolean} whether or not there is a source
+ */
+ _existsResourceTarget: function HS__existsResourceTarget(propertyURI,
+ targetURI) {
+ var property = this._rdf.GetResource(propertyURI);
+ var target = this._rdf.GetResource(targetURI);
+
+ return this._ds.hasArcIn(target, property);
+ },
+
+ /**
+ * Remove a property of an RDF source.
+ *
+ * @param sourceURI {string} the URI of the source
+ * @param propertyURI {string} the URI of the property
+ */
+ _removeTarget: function HS__removeTarget(sourceURI, propertyURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var property = this._rdf.GetResource(propertyURI);
+
+ if (this._ds.hasArcOut(source, property)) {
+ var target = this._ds.GetTarget(source, property, true);
+ this._ds.Unassert(source, property, target);
+ }
+ },
+
+ /**
+ * Remove all assertions about a given RDF source.
+ *
+ * Note: not recursive. If some assertions point to other resources,
+ * and you want to remove assertions about those resources too, you need
+ * to do so manually.
+ *
+ * @param sourceURI {string} the URI of the source
+ */
+ _removeAssertions: function HS__removeAssertions(sourceURI) {
+ var source = this._rdf.GetResource(sourceURI);
+ var properties = this._ds.ArcLabelsOut(source);
+
+ while (properties.hasMoreElements()) {
+ let property = properties.getNext();
+ let targets = this._ds.GetTargets(source, property, true);
+ while (targets.hasMoreElements()) {
+ let target = targets.getNext();
+ this._ds.Unassert(source, property, target);
+ }
+ }
+ }
+
+};
+
+
+//****************************************************************************//
+// More XPCOM Plumbing
+
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule([HandlerService]);
+}
diff --git a/bundles/XO/components/nsHelperAppDlg.js b/bundles/XO/components/nsHelperAppDlg.js
new file mode 100755
index 0000000..5f7845c
--- /dev/null
+++ b/bundles/XO/components/nsHelperAppDlg.js
@@ -0,0 +1,1039 @@
+/*
+//@line 45 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+*/
+
+/* This file implements the nsIHelperAppLauncherDialog interface.
+ *
+ * The implementation consists of a JavaScript "class" named nsUnknownContentTypeDialog,
+ * comprised of:
+ * - a JS constructor function
+ * - a prototype providing all the interface methods and implementation stuff
+ *
+ * In addition, this file implements an nsIModule object that registers the
+ * nsUnknownContentTypeDialog component.
+ */
+
+const PREF_BD_USEDOWNLOADDIR = "browser.download.useDownloadDir";
+const nsITimer = Components.interfaces.nsITimer;
+
+Components.utils.import("resource://gre/modules/DownloadLastDir.jsm");
+
+/* ctor
+ */
+function nsUnknownContentTypeDialog() {
+ // Initialize data properties.
+ this.mLauncher = null;
+ this.mContext = null;
+ this.mSourcePath = null;
+ this.chosenApp = null;
+ this.givenDefaultApp = false;
+ this.updateSelf = true;
+ this.mTitle = "";
+}
+
+nsUnknownContentTypeDialog.prototype = {
+ nsIMIMEInfo : Components.interfaces.nsIMIMEInfo,
+
+ QueryInterface: function (iid) {
+ if (!iid.equals(Components.interfaces.nsIHelperAppLauncherDialog) &&
+ !iid.equals(Components.interfaces.nsITimerCallback) &&
+ !iid.equals(Components.interfaces.nsISupports)) {
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ }
+ return this;
+ },
+
+ // ---------- nsIHelperAppLauncherDialog methods ----------
+
+ // show: Open XUL dialog using window watcher. Since the dialog is not
+ // modal, it needs to be a top level window and the way to open
+ // one of those is via that route).
+ show: function(aLauncher, aContext, aReason) {
+ this.mLauncher = aLauncher;
+ this.mContext = aContext;
+
+ const nsITimer = Components.interfaces.nsITimer;
+ this._showTimer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(nsITimer);
+ this._showTimer.initWithCallback(this, 0, nsITimer.TYPE_ONE_SHOT);
+ },
+
+ // When opening from new tab, if tab closes while dialog is opening,
+ // (which is a race condition on the XUL file being cached and the timer
+ // in nsExternalHelperAppService), the dialog gets a blur and doesn't
+ // activate the OK button. So we wait a bit before doing opening it.
+ reallyShow: function() {
+ try {
+ var ir = this.mContext.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
+ var dwi = ir.getInterface(Components.interfaces.nsIDOMWindowInternal);
+ var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
+ .getService(Components.interfaces.nsIWindowWatcher);
+ this.mDialog = ww.openWindow(dwi,
+ "chrome://mozapps/content/downloads/unknownContentType.xul",
+ null,
+ "chrome,centerscreen,titlebar,dialog=yes,dependent",
+ null);
+ } catch (ex) {
+ // The containing window may have gone away. Break reference
+ // cycles and stop doing the download.
+ const NS_BINDING_ABORTED = 0x804b0002;
+ this.mLauncher.cancel(NS_BINDING_ABORTED);
+ return;
+ }
+
+ // Hook this object to the dialog.
+ this.mDialog.dialog = this;
+
+ // Hook up utility functions.
+ this.getSpecialFolderKey = this.mDialog.getSpecialFolderKey;
+
+ // Watch for error notifications.
+ this.progressListener.helperAppDlg = this;
+ this.mLauncher.setWebProgressListener(this.progressListener);
+ },
+
+ // promptForSaveToFile: Display file picker dialog and return selected file.
+ // This is called by the External Helper App Service
+ // after the ucth dialog calls |saveToDisk| with a null
+ // target filename (no target, therefore user must pick).
+ //
+ // Alternatively, if the user has selected to have all
+ // files download to a specific location, return that
+ // location and don't ask via the dialog.
+ //
+ // Note - this function is called without a dialog, so it cannot access any part
+ // of the dialog XUL as other functions on this object do.
+ promptForSaveToFile: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) {
+ var result = null;
+
+ this.mLauncher = aLauncher;
+
+ let prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+
+ if (!aForcePrompt) {
+ // Check to see if the user wishes to auto save to the default download
+ // folder without prompting. Note that preference might not be set.
+ let autodownload = false;
+ try {
+ autodownload = prefs.getBoolPref(PREF_BD_USEDOWNLOADDIR);
+ } catch (e) { }
+
+ if (autodownload) {
+ // Retrieve the user's default download directory
+ let dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
+ .getService(Components.interfaces.nsIDownloadManager);
+ let defaultFolder = dnldMgr.userDownloadsDirectory;
+ result = this.validateLeafName(defaultFolder, aDefaultFile, aSuggestedFileExtension);
+
+ // Check to make sure we have a valid directory, otherwise, prompt
+ if (result)
+ return result;
+ }
+ }
+
+ // Use file picker to show dialog.
+ var nsIFilePicker = Components.interfaces.nsIFilePicker;
+ var picker = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+
+ var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
+ bundle = bundle.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties");
+
+ var windowTitle = bundle.GetStringFromName("saveDialogTitle");
+ var parent = aContext.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowInternal);
+ picker.init(parent, windowTitle, nsIFilePicker.modeSave);
+ picker.defaultString = aDefaultFile;
+
+ if (aSuggestedFileExtension) {
+ // aSuggestedFileExtension includes the period, so strip it
+ picker.defaultExtension = aSuggestedFileExtension.substring(1);
+ }
+ else {
+ try {
+ picker.defaultExtension = this.mLauncher.MIMEInfo.primaryExtension;
+ }
+ catch (ex) { }
+ }
+
+ var wildCardExtension = "*";
+ if (aSuggestedFileExtension) {
+ wildCardExtension += aSuggestedFileExtension;
+ picker.appendFilter(this.mLauncher.MIMEInfo.description, wildCardExtension);
+ }
+
+ picker.appendFilters( nsIFilePicker.filterAll );
+
+ var inPrivateBrowsing = false;
+ try {
+ var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
+ .getService(Components.interfaces.nsIPrivateBrowsingService);
+ inPrivateBrowsing = pbs.privateBrowsingEnabled;
+ }
+ catch (e) {
+ }
+
+ // Default to lastDir if it's valid, use the user's default
+ // downloads directory otherwise.
+ var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
+ .getService(Components.interfaces.nsIDownloadManager);
+ try {
+ var lastDir;
+ if (inPrivateBrowsing && gDownloadLastDir.file)
+ lastDir = gDownloadLastDir.file;
+ else
+ lastDir = prefs.getComplexValue("browser.download.lastDir",
+ Components.interfaces.nsILocalFile);
+ if (lastDir.exists())
+ picker.displayDirectory = lastDir;
+ else
+ picker.displayDirectory = dnldMgr.userDownloadsDirectory;
+ } catch (ex) {
+ picker.displayDirectory = dnldMgr.userDownloadsDirectory;
+ }
+
+ if (picker.show() == nsIFilePicker.returnCancel) {
+ // null result means user cancelled.
+ return null;
+ }
+
+ // Be sure to save the directory the user chose through the Save As...
+ // dialog as the new browser.download.dir since the old one
+ // didn't exist.
+ result = picker.file;
+
+ if (result) {
+ try {
+ // Remove the file so that it's not there when we ensure non-existence later;
+ // this is safe because for the file to exist, the user would have had to
+ // confirm that he wanted the file overwritten.
+ if (result.exists())
+ result.remove(false);
+ }
+ catch (e) { }
+ var newDir = result.parent.QueryInterface(Components.interfaces.nsILocalFile);
+
+ // Do not store the last save directory as a pref inside the private browsing mode
+ if (inPrivateBrowsing)
+ gDownloadLastDir.file = newDir;
+ else
+ prefs.setComplexValue("browser.download.lastDir", Components.interfaces.nsILocalFile, newDir);
+
+ result = this.validateLeafName(newDir, result.leafName, null);
+ }
+ return result;
+ },
+
+ /**
+ * Ensures that a local folder/file combination does not already exist in
+ * the file system (or finds such a combination with a reasonably similar
+ * leaf name), creates the corresponding file, and returns it.
+ *
+ * @param aLocalFile
+ * the folder where the file resides
+ * @param aLeafName
+ * the string name of the file (may be empty if no name is known,
+ * in which case a name will be chosen)
+ * @param aFileExt
+ * the extension of the file, if one is known; this will be ignored
+ * if aLeafName is non-empty
+ * @returns nsILocalFile
+ * the created file
+ */
+ validateLeafName: function (aLocalFile, aLeafName, aFileExt)
+ {
+ if (!aLocalFile || !aLocalFile.exists())
+ return null;
+
+ // Remove any leading periods, since we don't want to save hidden files
+ // automatically.
+ aLeafName = aLeafName.replace(/^\.+/, "");
+
+ if (aLeafName == "")
+ aLeafName = "unnamed" + (aFileExt ? "." + aFileExt : "");
+ aLocalFile.append(aLeafName);
+
+ this.makeFileUnique(aLocalFile);
+
+//@line 318 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+
+ return aLocalFile;
+ },
+
+ /**
+ * Generates and returns a uniquely-named file from aLocalFile. If
+ * aLocalFile does not exist, it will be the file returned; otherwise, a
+ * file whose name is similar to that of aLocalFile will be returned.
+ */
+ makeFileUnique: function (aLocalFile)
+ {
+ try {
+ // Note - this code is identical to that in
+ // toolkit/content/contentAreaUtils.js.
+ // If you are updating this code, update that code too! We can't share code
+ // here since this is called in a js component.
+ var collisionCount = 0;
+ while (aLocalFile.exists()) {
+ collisionCount++;
+ if (collisionCount == 1) {
+ // Append "(2)" before the last dot in (or at the end of) the filename
+ // special case .ext.gz etc files so we don't wind up with .tar(2).gz
+ if (aLocalFile.leafName.match(/\.[^\.]{1,3}\.(gz|bz2|Z)$/i)) {
+ aLocalFile.leafName = aLocalFile.leafName.replace(/\.[^\.]{1,3}\.(gz|bz2|Z)$/i, "(2)$&");
+ }
+ else {
+ aLocalFile.leafName = aLocalFile.leafName.replace(/(\.[^\.]*)?$/, "(2)$&");
+ }
+ }
+ else {
+ // replace the last (n) in the filename with (n+1)
+ aLocalFile.leafName = aLocalFile.leafName.replace(/^(.*\()\d+\)/, "$1" + (collisionCount+1) + ")");
+ }
+ }
+ aLocalFile.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0600);
+ }
+ catch (e) {
+ dump("*** exception in validateLeafName: " + e + "\n");
+ if (aLocalFile.leafName == "" || aLocalFile.isDirectory()) {
+ aLocalFile.append("unnamed");
+ if (aLocalFile.exists())
+ aLocalFile.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0600);
+ }
+ }
+ },
+
+ // ---------- implementation methods ----------
+
+ // Web progress listener so we can detect errors while mLauncher is
+ // streaming the data to a temporary file.
+ progressListener: {
+ // Implementation properties.
+ helperAppDlg: null,
+
+ // nsIWebProgressListener methods.
+ // Look for error notifications and display alert to user.
+ onStatusChange: function( aWebProgress, aRequest, aStatus, aMessage ) {
+ if ( aStatus != Components.results.NS_OK ) {
+ // Get prompt service.
+ var prompter = Components.classes[ "@mozilla.org/embedcomp/prompt-service;1" ]
+ .getService( Components.interfaces.nsIPromptService );
+ // Display error alert (using text supplied by back-end).
+ prompter.alert( this.dialog, this.helperAppDlg.mTitle, aMessage );
+
+ // Close the dialog.
+ this.helperAppDlg.onCancel();
+ if ( this.helperAppDlg.mDialog ) {
+ this.helperAppDlg.mDialog.close();
+ }
+ }
+ },
+
+ // Ignore onProgressChange, onProgressChange64, onStateChange, onLocationChange, onSecurityChange, and onRefreshAttempted notifications.
+ onProgressChange: function( aWebProgress,
+ aRequest,
+ aCurSelfProgress,
+ aMaxSelfProgress,
+ aCurTotalProgress,
+ aMaxTotalProgress ) {
+ },
+
+ onProgressChange64: function( aWebProgress,
+ aRequest,
+ aCurSelfProgress,
+ aMaxSelfProgress,
+ aCurTotalProgress,
+ aMaxTotalProgress ) {
+ },
+
+
+
+ onStateChange: function( aWebProgress, aRequest, aStateFlags, aStatus ) {
+ },
+
+ onLocationChange: function( aWebProgress, aRequest, aLocation ) {
+ },
+
+ onSecurityChange: function( aWebProgress, aRequest, state ) {
+ },
+
+ onRefreshAttempted: function( aWebProgress, aURI, aDelay, aSameURI ) {
+ return true;
+ }
+ },
+
+ // initDialog: Fill various dialog fields with initial content.
+ initDialog : function() {
+ // Put file name in window title.
+ var suggestedFileName = this.mLauncher.suggestedFileName;
+
+ // Some URIs do not implement nsIURL, so we can't just QI.
+ var url = this.mLauncher.source;
+ var fname = "";
+ this.mSourcePath = url.prePath;
+ try {
+ url = url.QueryInterface( Components.interfaces.nsIURL );
+ // A url, use file name from it.
+ fname = url.fileName;
+ this.mSourcePath += url.directory;
+ } catch (ex) {
+ // A generic uri, use path.
+ fname = url.path;
+ this.mSourcePath += url.path;
+ }
+
+ if (suggestedFileName)
+ fname = suggestedFileName;
+
+ var displayName = fname.replace(/ +/g, " ");
+
+ this.mTitle = this.dialogElement("strings").getFormattedString("title", [displayName]);
+ this.mDialog.document.title = this.mTitle;
+
+ // Put content type, filename and location into intro.
+ this.initIntro(url, fname, displayName);
+
+ var iconString = "moz-icon://" + fname + "?size=16&contentType=" + this.mLauncher.MIMEInfo.MIMEType;
+ this.dialogElement("contentTypeImage").setAttribute("src", iconString);
+
+ // if always-save and is-executable and no-handler
+ // then set up simple ui
+ var mimeType = this.mLauncher.MIMEInfo.MIMEType;
+ var shouldntRememberChoice = (mimeType == "application/octet-stream" ||
+ mimeType == "application/x-msdownload" ||
+ this.mLauncher.targetFileIsExecutable);
+ if (shouldntRememberChoice && !this.openWithDefaultOK()) {
+ // hide featured choice
+ this.dialogElement("normalBox").collapsed = true;
+ // show basic choice
+ this.dialogElement("basicBox").collapsed = false;
+ // change button labels and icons; use "save" icon for the accept
+ // button since it's the only action possible
+ let acceptButton = this.mDialog.document.documentElement
+ .getButton("accept");
+ acceptButton.label = this.dialogElement("strings")
+ .getString("unknownAccept.label");
+ acceptButton.setAttribute("icon", "save");
+ this.mDialog.document.documentElement.getButton("cancel").label = this.dialogElement("strings").getString("unknownCancel.label");
+ // hide other handler
+ this.dialogElement("openHandler").collapsed = true;
+ // set save as the selected option
+ this.dialogElement("mode").selectedItem = this.dialogElement("save");
+ }
+ else {
+ this.initAppAndSaveToDiskValues();
+
+ // Initialize "always ask me" box. This should always be disabled
+ // and set to true for the ambiguous type application/octet-stream.
+ // We don't also check for application/x-msdownload here since we
+ // want users to be able to autodownload .exe files.
+ var rememberChoice = this.dialogElement("rememberChoice");
+
+//@line 509 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ if (shouldntRememberChoice) {
+ rememberChoice.checked = false;
+ rememberChoice.disabled = true;
+ }
+ else {
+ rememberChoice.checked = !this.mLauncher.MIMEInfo.alwaysAskBeforeHandling;
+ }
+ this.toggleRememberChoice(rememberChoice);
+
+ // XXXben - menulist won't init properly, hack.
+ var openHandler = this.dialogElement("openHandler");
+ openHandler.parentNode.removeChild(openHandler);
+ var openHandlerBox = this.dialogElement("openHandlerBox");
+ openHandlerBox.appendChild(openHandler);
+ }
+
+ this.mDialog.setTimeout("dialog.postShowCallback()", 0);
+
+ this.mDialog.document.documentElement.getButton("accept").disabled = true;
+ this._showTimer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(nsITimer);
+ this._showTimer.initWithCallback(this, 250, nsITimer.TYPE_ONE_SHOT);
+ },
+
+ notify: function (aTimer) {
+ if (aTimer == this._showTimer) {
+ if (!this.mDialog) {
+ this.reallyShow();
+ } else {
+ // The user may have already canceled the dialog.
+ try {
+ if (!this._blurred) {
+ this.mDialog.document.documentElement.getButton("accept").disabled = false;
+ }
+ } catch (ex) {}
+ this._delayExpired = true;
+ }
+ // The timer won't release us, so we have to release it.
+ this._showTimer = null;
+ }
+ else if (aTimer == this._saveToDiskTimer) {
+ // Since saveToDisk may open a file picker and therefore block this routine,
+ // we should only call it once the dialog is closed.
+ this.mLauncher.saveToDisk(null, false);
+ this._saveToDiskTimer = null;
+ }
+ },
+
+ postShowCallback: function () {
+ this.mDialog.sizeToContent();
+
+ // Set initial focus
+ this.dialogElement("mode").focus();
+ },
+
+ // initIntro:
+ initIntro: function(url, filename, displayname) {
+ this.dialogElement( "location" ).value = displayname;
+ this.dialogElement( "location" ).setAttribute("realname", filename);
+ this.dialogElement( "location" ).setAttribute("tooltiptext", displayname);
+
+ // if mSourcePath is a local file, then let's use the pretty path name instead of an ugly
+ // url...
+ var pathString = this.mSourcePath;
+ try
+ {
+ var fileURL = url.QueryInterface(Components.interfaces.nsIFileURL);
+ if (fileURL)
+ {
+ var fileObject = fileURL.file;
+ if (fileObject)
+ {
+ var parentObject = fileObject.parent;
+ if (parentObject)
+ {
+ pathString = parentObject.path;
+ }
+ }
+ }
+ } catch(ex) {}
+
+ if (pathString == this.mSourcePath)
+ {
+ // wasn't a fileURL
+ var tmpurl = url.clone(); // don't want to change the real url
+ try {
+ tmpurl.userPass = "";
+ } catch (ex) {}
+ pathString = tmpurl.prePath;
+ }
+
+ // Set the location text, which is separate from the intro text so it can be cropped
+ var location = this.dialogElement( "source" );
+ location.value = pathString;
+ location.setAttribute("tooltiptext", this.mSourcePath);
+
+ // Show the type of file.
+ var type = this.dialogElement("type");
+ var mimeInfo = this.mLauncher.MIMEInfo;
+
+ // 1. Try to use the pretty description of the type, if one is available.
+ var typeString = mimeInfo.description;
+
+ if (typeString == "") {
+ // 2. If there is none, use the extension to identify the file, e.g. "ZIP file"
+ var primaryExtension = "";
+ try {
+ primaryExtension = mimeInfo.primaryExtension;
+ }
+ catch (ex) {
+ }
+ if (primaryExtension != "")
+ typeString = this.dialogElement("strings").getFormattedString("fileType", [primaryExtension.toUpperCase()]);
+ // 3. If we can't even do that, just give up and show the MIME type.
+ else
+ typeString = mimeInfo.MIMEType;
+ }
+
+ type.value = typeString;
+ },
+
+ _blurred: false,
+ _delayExpired: false,
+ onBlur: function(aEvent) {
+ this._blurred = true;
+ this.mDialog.document.documentElement.getButton("accept").disabled = true;
+ },
+
+ onFocus: function(aEvent) {
+ this._blurred = false;
+ if (this._delayExpired) {
+ var script = "document.documentElement.getButton('accept').disabled = false";
+ this.mDialog.setTimeout(script, 250);
+ }
+ },
+
+ // Returns true if opening the default application makes sense.
+ openWithDefaultOK: function() {
+ // The checking is different on Windows...
+//@line 659 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ // On other platforms, default is Ok if there is a default app.
+ // Note that nsIMIMEInfo providers need to ensure that this holds true
+ // on each platform.
+ return this.mLauncher.MIMEInfo.hasDefaultHandler;
+//@line 664 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ },
+
+ // Set "default" application description field.
+ initDefaultApp: function() {
+ // Use description, if we can get one.
+ var desc = this.mLauncher.MIMEInfo.defaultDescription;
+ if (desc) {
+ var defaultApp = this.dialogElement("strings").getFormattedString("defaultApp", [desc]);
+ this.dialogElement("defaultHandler").label = defaultApp;
+ }
+ else {
+ this.dialogElement("modeDeck").setAttribute("selectedIndex", "1");
+ // Hide the default handler item too, in case the user picks a
+ // custom handler at a later date which triggers the menulist to show.
+ this.dialogElement("defaultHandler").hidden = true;
+ }
+ },
+
+ // getPath:
+ getPath: function (aFile) {
+//@line 687 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ return aFile.path;
+//@line 689 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ },
+
+ // initAppAndSaveToDiskValues:
+ initAppAndSaveToDiskValues: function() {
+ var modeGroup = this.dialogElement("mode");
+
+ // We don't let users open .exe files or random binary data directly
+ // from the browser at the moment because of security concerns.
+ var openWithDefaultOK = this.openWithDefaultOK();
+ var mimeType = this.mLauncher.MIMEInfo.MIMEType;
+ if (this.mLauncher.targetFileIsExecutable || (
+ (mimeType == "application/octet-stream" ||
+ mimeType == "application/x-msdownload") &&
+ !openWithDefaultOK)) {
+ this.dialogElement("open").disabled = true;
+ var openHandler = this.dialogElement("openHandler");
+ openHandler.disabled = true;
+ openHandler.selectedItem = null;
+ modeGroup.selectedItem = this.dialogElement("save");
+ return;
+ }
+
+ // Fill in helper app info, if there is any.
+ try {
+ this.chosenApp =
+ this.mLauncher.MIMEInfo.preferredApplicationHandler
+ .QueryInterface(Components.interfaces.nsILocalHandlerApp);
+ } catch (e) {
+ this.chosenApp = null;
+ }
+ // Initialize "default application" field.
+ this.initDefaultApp();
+
+ var otherHandler = this.dialogElement("otherHandler");
+
+ // Fill application name textbox.
+ if (this.chosenApp && this.chosenApp.executable &&
+ this.chosenApp.executable.path) {
+ otherHandler.setAttribute("path",
+ this.getPath(this.chosenApp.executable));
+
+//@line 734 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ otherHandler.label = this.chosenApp.executable.leafName;
+//@line 736 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ otherHandler.hidden = false;
+ }
+
+ var useDefault = this.dialogElement("useSystemDefault");
+ var openHandler = this.dialogElement("openHandler");
+ openHandler.selectedIndex = 0;
+
+ if (this.mLauncher.MIMEInfo.preferredAction == this.nsIMIMEInfo.useSystemDefault) {
+ // Open (using system default).
+ modeGroup.selectedItem = this.dialogElement("open");
+ } else if (this.mLauncher.MIMEInfo.preferredAction == this.nsIMIMEInfo.useHelperApp) {
+ // Open with given helper app.
+ modeGroup.selectedItem = this.dialogElement("open");
+ openHandler.selectedIndex = 1;
+ } else {
+ // Save to disk.
+ modeGroup.selectedItem = this.dialogElement("save");
+ }
+
+ // If we don't have a "default app" then disable that choice.
+ if (!openWithDefaultOK) {
+ var useDefault = this.dialogElement("defaultHandler");
+ var isSelected = useDefault.selected;
+
+ // Disable that choice.
+ useDefault.hidden = true;
+ // If that's the default, then switch to "save to disk."
+ if (isSelected) {
+ openHandler.selectedIndex = 1;
+ modeGroup.selectedItem = this.dialogElement("save");
+ }
+ }
+
+ otherHandler.nextSibling.hidden = otherHandler.nextSibling.nextSibling.hidden = false;
+ this.updateOKButton();
+ },
+
+ // Returns the user-selected application
+ helperAppChoice: function() {
+ return this.chosenApp;
+ },
+
+ get saveToDisk() {
+ return this.dialogElement("save").selected;
+ },
+
+ get useOtherHandler() {
+ return this.dialogElement("open").selected && this.dialogElement("openHandler").selectedIndex == 1;
+ },
+
+ get useSystemDefault() {
+ return this.dialogElement("open").selected && this.dialogElement("openHandler").selectedIndex == 0;
+ },
+
+ toggleRememberChoice: function (aCheckbox) {
+ this.dialogElement("settingsChange").hidden = !aCheckbox.checked;
+ this.mDialog.sizeToContent();
+ },
+
+ openHandlerCommand: function () {
+ var openHandler = this.dialogElement("openHandler");
+ if (openHandler.selectedItem.id == "choose")
+ this.chooseApp();
+ else
+ openHandler.setAttribute("lastSelectedItemID", openHandler.selectedItem.id);
+ },
+
+ updateOKButton: function() {
+ var ok = false;
+ if (this.dialogElement("save").selected) {
+ // This is always OK.
+ ok = true;
+ }
+ else if (this.dialogElement("open").selected) {
+ switch (this.dialogElement("openHandler").selectedIndex) {
+ case 0:
+ // No app need be specified in this case.
+ ok = true;
+ break;
+ case 1:
+ // only enable the OK button if we have a default app to use or if
+ // the user chose an app....
+ ok = this.chosenApp || /\S/.test(this.dialogElement("otherHandler").getAttribute("path"));
+ break;
+ }
+ }
+
+ // Enable Ok button if ok to press.
+ this.mDialog.document.documentElement.getButton("accept").disabled = !ok;
+ },
+
+ // Returns true iff the user-specified helper app has been modified.
+ appChanged: function() {
+ return this.helperAppChoice() != this.mLauncher.MIMEInfo.preferredApplicationHandler;
+ },
+
+ updateMIMEInfo: function() {
+ var needUpdate = false;
+ // If current selection differs from what's in the mime info object,
+ // then we need to update.
+ if (this.saveToDisk) {
+ needUpdate = this.mLauncher.MIMEInfo.preferredAction != this.nsIMIMEInfo.saveToDisk;
+ if (needUpdate)
+ this.mLauncher.MIMEInfo.preferredAction = this.nsIMIMEInfo.saveToDisk;
+ }
+ else if (this.useSystemDefault) {
+ needUpdate = this.mLauncher.MIMEInfo.preferredAction != this.nsIMIMEInfo.useSystemDefault;
+ if (needUpdate)
+ this.mLauncher.MIMEInfo.preferredAction = this.nsIMIMEInfo.useSystemDefault;
+ }
+ else {
+ // For "open with", we need to check both preferred action and whether the user chose
+ // a new app.
+ needUpdate = this.mLauncher.MIMEInfo.preferredAction != this.nsIMIMEInfo.useHelperApp || this.appChanged();
+ if (needUpdate) {
+ this.mLauncher.MIMEInfo.preferredAction = this.nsIMIMEInfo.useHelperApp;
+ // App may have changed - Update application
+ var app = this.helperAppChoice();
+ this.mLauncher.MIMEInfo.preferredApplicationHandler = app;
+ }
+ }
+ // We will also need to update if the "always ask" flag has changed.
+ needUpdate = needUpdate || this.mLauncher.MIMEInfo.alwaysAskBeforeHandling != (!this.dialogElement("rememberChoice").checked);
+
+ // One last special case: If the input "always ask" flag was false, then we always
+ // update. In that case we are displaying the helper app dialog for the first
+ // time for this mime type and we need to store the user's action in the mimeTypes.rdf
+ // data source (whether that action has changed or not; if it didn't change, then we need
+ // to store the "always ask" flag so the helper app dialog will or won't display
+ // next time, per the user's selection).
+ needUpdate = needUpdate || !this.mLauncher.MIMEInfo.alwaysAskBeforeHandling;
+
+ // Make sure mime info has updated setting for the "always ask" flag.
+ this.mLauncher.MIMEInfo.alwaysAskBeforeHandling = !this.dialogElement("rememberChoice").checked;
+
+ return needUpdate;
+ },
+
+ // See if the user changed things, and if so, update the
+ // mimeTypes.rdf entry for this mime type.
+ updateHelperAppPref: function() {
+ var ha = new this.mDialog.HelperApps();
+ ha.updateTypeInfo(this.mLauncher.MIMEInfo);
+ ha.destroy();
+ },
+
+ // onOK:
+ onOK: function() {
+ // Verify typed app path, if necessary.
+ if (this.useOtherHandler) {
+ var helperApp = this.helperAppChoice();
+ if (!helperApp || !helperApp.executable ||
+ !helperApp.executable.exists()) {
+ // Show alert and try again.
+ var bundle = this.dialogElement("strings");
+ var msg = bundle.getFormattedString("badApp", [this.dialogElement("otherHandler").path]);
+ var svc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
+ svc.alert(this.mDialog, bundle.getString("badApp.title"), msg);
+
+ // Disable the OK button.
+ this.mDialog.document.documentElement.getButton("accept").disabled = true;
+ this.dialogElement("mode").focus();
+
+ // Clear chosen application.
+ this.chosenApp = null;
+
+ // Leave dialog up.
+ return false;
+ }
+ }
+
+ // Remove our web progress listener (a progress dialog will be
+ // taking over).
+ this.mLauncher.setWebProgressListener(null);
+
+ // saveToDisk and launchWithApplication can return errors in
+ // certain circumstances (e.g. The user clicks cancel in the
+ // "Save to Disk" dialog. In those cases, we don't want to
+ // update the helper application preferences in the RDF file.
+ try {
+ var needUpdate = this.updateMIMEInfo();
+
+ if (this.dialogElement("save").selected) {
+ // If we're using a default download location, create a path
+ // for the file to be saved to to pass to |saveToDisk| - otherwise
+ // we must ask the user to pick a save name.
+
+//@line 937 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+
+ // see @notify
+ // we cannot use opener's setTimeout, see bug 420405
+ this._saveToDiskTimer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(nsITimer);
+ this._saveToDiskTimer.initWithCallback(this, 0,
+ nsITimer.TYPE_ONE_SHOT);
+ }
+ else
+ this.mLauncher.launchWithApplication(null, false);
+
+ // Update user pref for this mime type (if necessary). We do not
+ // store anything in the mime type preferences for the ambiguous
+ // type application/octet-stream. We do NOT do this for
+ // application/x-msdownload since we want users to be able to
+ // autodownload these to disk.
+ if (needUpdate && this.mLauncher.MIMEInfo.MIMEType != "application/octet-stream")
+ this.updateHelperAppPref();
+ } catch(e) { }
+
+ // Unhook dialog from this object.
+ this.mDialog.dialog = null;
+
+ // Close up dialog by returning true.
+ return true;
+ },
+
+ // onCancel:
+ onCancel: function() {
+ // Remove our web progress listener.
+ this.mLauncher.setWebProgressListener(null);
+
+ // Cancel app launcher.
+ try {
+ const NS_BINDING_ABORTED = 0x804b0002;
+ this.mLauncher.cancel(NS_BINDING_ABORTED);
+ } catch(exception) {
+ }
+
+ // Unhook dialog from this object.
+ this.mDialog.dialog = null;
+
+ // Close up dialog by returning true.
+ return true;
+ },
+
+ // dialogElement: Convenience.
+ dialogElement: function(id) {
+ return this.mDialog.document.getElementById(id);
+ },
+
+ // Retrieve the pretty description from the file
+ getFileDisplayName: function getFileDisplayName(file)
+ {
+//@line 999 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ return file.leafName;
+ },
+
+ // chooseApp: Open file picker and prompt user for application.
+ chooseApp: function() {
+//@line 1070 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ var nsIFilePicker = Components.interfaces.nsIFilePicker;
+ var fp = Components.classes["@mozilla.org/filepicker;1"]
+ .createInstance(nsIFilePicker);
+ fp.init(this.mDialog,
+ this.dialogElement("strings").getString("chooseAppFilePickerTitle"),
+ nsIFilePicker.modeOpen);
+
+ fp.appendFilters(nsIFilePicker.filterApps);
+
+ if (fp.show() == nsIFilePicker.returnOK && fp.file) {
+ // Show the "handler" menulist since we have a (user-specified)
+ // application now.
+ this.dialogElement("modeDeck").setAttribute("selectedIndex", "0");
+
+ // Remember the file they chose to run.
+ var localHandlerApp =
+ Components.classes["@mozilla.org/uriloader/local-handler-app;1"].
+ createInstance(Components.interfaces.nsILocalHandlerApp);
+ localHandlerApp.executable = fp.file;
+ this.chosenApp = localHandlerApp;
+
+ // Update dialog.
+ var otherHandler = this.dialogElement("otherHandler");
+ otherHandler.removeAttribute("hidden");
+ otherHandler.setAttribute("path", this.getPath(this.chosenApp.executable));
+//@line 1100 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ otherHandler.label = this.chosenApp.executable.leafName;
+//@line 1102 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ this.dialogElement("openHandler").selectedIndex = 1;
+ this.dialogElement("openHandler").setAttribute("lastSelectedItemID", "otherHandler");
+
+ this.dialogElement("mode").selectedItem = this.dialogElement("open");
+ }
+ else {
+ var openHandler = this.dialogElement("openHandler");
+ var lastSelectedID = openHandler.getAttribute("lastSelectedItemID");
+ if (!lastSelectedID)
+ lastSelectedID = "defaultHandler";
+ openHandler.selectedItem = this.dialogElement(lastSelectedID);
+ }
+//@line 1115 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/downloads/src/nsHelperAppDlg.js.in"
+ },
+
+ // Turn this on to get debugging messages.
+ debug: false,
+
+ // Dump text (if debug is on).
+ dump: function( text ) {
+ if ( this.debug ) {
+ dump( text );
+ }
+ },
+
+ // dumpInfo:
+ doDebug: function() {
+ const nsIProgressDialog = Components.interfaces.nsIProgressDialog;
+ // Open new progress dialog.
+ var progress = Components.classes[ "@mozilla.org/progressdialog;1" ]
+ .createInstance( nsIProgressDialog );
+ // Show it.
+ progress.open( this.mDialog );
+ },
+
+ // dumpObj:
+ dumpObj: function( spec ) {
+ var val = "<undefined>";
+ try {
+ val = eval( "this."+spec ).toString();
+ } catch( exception ) {
+ }
+ this.dump( spec + "=" + val + "\n" );
+ },
+
+ // dumpObjectProperties
+ dumpObjectProperties: function( desc, obj ) {
+ for( prop in obj ) {
+ this.dump( desc + "." + prop + "=" );
+ var val = "<undefined>";
+ try {
+ val = obj[ prop ];
+ } catch ( exception ) {
+ }
+ this.dump( val + "\n" );
+ }
+ }
+}
+
+// This Component's module implementation. All the code below is used to get this
+// component registered and accessible via XPCOM.
+var module = {
+ firstTime: true,
+
+ // registerSelf: Register this component.
+ registerSelf: function (compMgr, fileSpec, location, type) {
+ if (this.firstTime) {
+ this.firstTime = false;
+ throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
+ }
+ compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+
+ compMgr.registerFactoryLocation( this.cid,
+ "Unknown Content Type Dialog",
+ this.contractId,
+ fileSpec,
+ location,
+ type );
+ },
+
+ // getClassObject: Return this component's factory object.
+ getClassObject: function (compMgr, cid, iid) {
+ if (!cid.equals(this.cid)) {
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ }
+
+ if (!iid.equals(Components.interfaces.nsIFactory)) {
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ return this.factory;
+ },
+
+ /* CID for this class */
+ cid: Components.ID("{F68578EB-6EC2-4169-AE19-8C6243F0ABE1}"),
+
+ /* Contract ID for this class */
+ contractId: "@mozilla.org/helperapplauncherdialog;1",
+
+ /* factory object */
+ factory: {
+ // createInstance: Return a new nsProgressDialog object.
+ createInstance: function (outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ return (new nsUnknownContentTypeDialog()).QueryInterface(iid);
+ }
+ },
+
+ // canUnload: n/a (returns true)
+ canUnload: function(compMgr) {
+ return true;
+ }
+};
+
+// NSGetModule: Return the nsIModule object.
+function NSGetModule(compMgr, fileSpec) {
+ return module;
+}
diff --git a/bundles/XO/components/nsLivemarkService.js b/bundles/XO/components/nsLivemarkService.js
new file mode 100755
index 0000000..62d906d
--- /dev/null
+++ b/bundles/XO/components/nsLivemarkService.js
@@ -0,0 +1,1140 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is the Places JS Livemark Service.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Annie Sullivan <annie.sullivan@gmail.com> (C++ author)
+ * Joe Hughes <joe@retrovirus.com>
+ * Vladimir Vukicevic <vladimir@pobox.com>
+ * Masayuki Nakano <masayuki@d-toybox.com>
+ * Robert Sayre <sayrer@gmail.com> (JS port)
+ * Phil Ringnalda <philringnalda@gmail.com>
+ * Marco Bonardo <mak77@bonardo.net>
+ * Takeshi Ichimaru <ayakawa.m@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of either the GNU General Public License Version 2 or later
+ * (the "GPL"), or the GNU Lesser General Public License Version 2.1
+ * or later (the "LGPL"), in which case the provisions of the GPL or
+ * the LGPL are applicable instead of those above. If you wish to
+ * allow use of your version of this file only under the terms of
+ * either the GPL or the LGPL, and not to allow others to use your
+ * version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the
+ * notice and other provisions required by the GPL or the LGPL. If you
+ * do not delete the provisions above, a recipient may use your
+ * version of this file under the terms of any one of the MPL, the GPL
+ * or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/lang.js"
+
+
+/**
+ * lang.js - Some missing JavaScript language features
+ */
+
+/**
+ * Partially applies a function to a particular "this object" and zero or
+ * more arguments. The result is a new function with some arguments of the first
+ * function pre-filled and the value of |this| "pre-specified".
+ *
+ * Remaining arguments specified at call-time are appended to the pre-
+ * specified ones.
+ *
+ * Usage:
+ * var barMethBound = BindToObject(myFunction, myObj, "arg1", "arg2");
+ * barMethBound("arg3", "arg4");
+ *
+ * @param fn {string} Reference to the function to be bound
+ *
+ * @param self {object} Specifies the object which |this| should point to
+ * when the function is run. If the value is null or undefined, it will default
+ * to the global object.
+ *
+ * @returns {function} A partially-applied form of the speficied function.
+ */
+function BindToObject(fn, self, opt_args) {
+ var boundargs = fn.boundArgs_ || [];
+ boundargs = boundargs.concat(Array.slice(arguments, 2, arguments.length));
+
+ if (fn.boundSelf_)
+ self = fn.boundSelf_;
+ if (fn.boundFn_)
+ fn = fn.boundFn_;
+
+ var newfn = function() {
+ // Combine the static args and the new args into one big array
+ var args = boundargs.concat(Array.slice(arguments));
+ return fn.apply(self, args);
+ }
+
+ newfn.boundArgs_ = boundargs;
+ newfn.boundSelf_ = self;
+ newfn.boundFn_ = fn;
+
+ return newfn;
+}
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * Usage:
+ *
+ * function ParentClass(a, b) { }
+ * ParentClass.prototype.foo = function(a) { }
+ *
+ * function ChildClass(a, b, c) {
+ * ParentClass.call(this, a, b);
+ * }
+ *
+ * ChildClass.inherits(ParentClass);
+ *
+ * var child = new ChildClass("a", "b", "see");
+ * child.foo(); // works
+ *
+ * In addition, a superclass' implementation of a method can be invoked
+ * as follows:
+ *
+ * ChildClass.prototype.foo = function(a) {
+ * ChildClass.superClass_.foo.call(this, a);
+ * // other code
+ * };
+ */
+Function.prototype.inherits = function(parentCtor) {
+ var tempCtor = function(){};
+ tempCtor.prototype = parentCtor.prototype;
+ this.superClass_ = parentCtor.prototype;
+ this.prototype = new tempCtor();
+}
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/observer.js"
+
+
+// A couple of classes to simplify creating observers.
+//
+// // Example1:
+//
+// function doSomething() { ... }
+// var observer = new G_ObserverWrapper(topic, doSomething);
+// someObj.addObserver(topic, observer);
+//
+// // Example2:
+//
+// function doSomething() { ... }
+// new G_ObserverServiceObserver("profile-after-change",
+// doSomething,
+// true /* run only once */);
+
+
+/**
+ * This class abstracts the admittedly simple boilerplate required of
+ * an nsIObserver. It saves you the trouble of implementing the
+ * indirection of your own observe() function.
+ *
+ * @param topic String containing the topic the observer will filter for
+ *
+ * @param observeFunction Reference to the function to call when the
+ * observer fires
+ *
+ * @constructor
+ */
+function G_ObserverWrapper(topic, observeFunction) {
+ this.debugZone = "observer";
+ this.topic_ = topic;
+ this.observeFunction_ = observeFunction;
+}
+
+/**
+ * XPCOM
+ */
+G_ObserverWrapper.prototype.QueryInterface = function(iid) {
+ if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsIObserver))
+ return this;
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+}
+
+/**
+ * Invoked by the thingy being observed
+ */
+G_ObserverWrapper.prototype.observe = function(subject, topic, data) {
+ if (topic == this.topic_)
+ this.observeFunction_(subject, topic, data);
+}
+
+
+/**
+ * This class abstracts the admittedly simple boilerplate required of
+ * observing an observerservice topic. It implements the indirection
+ * required, and automatically registers to hear the topic.
+ *
+ * @param topic String containing the topic the observer will filter for
+ *
+ * @param observeFunction Reference to the function to call when the
+ * observer fires
+ *
+ * @param opt_onlyOnce Boolean indicating if the observer should unregister
+ * after it has fired
+ *
+ * @constructor
+ */
+function G_ObserverServiceObserver(topic, observeFunction, opt_onlyOnce) {
+ this.debugZone = "observerserviceobserver";
+ this.topic_ = topic;
+ this.observeFunction_ = observeFunction;
+ this.onlyOnce_ = !!opt_onlyOnce;
+
+ this.observer_ = new G_ObserverWrapper(this.topic_,
+ BindToObject(this.observe_, this));
+ this.observerService_ = Cc["@mozilla.org/observer-service;1"]
+ .getService(Ci.nsIObserverService);
+ this.observerService_.addObserver(this.observer_, this.topic_, false);
+}
+
+/**
+ * Unregister the observer from the observerservice
+ */
+G_ObserverServiceObserver.prototype.unregister = function() {
+ this.observerService_.removeObserver(this.observer_, this.topic_);
+ this.observerService_ = null;
+}
+
+/**
+ * Invoked by the observerservice
+ */
+G_ObserverServiceObserver.prototype.observe_ = function(subject, topic, data) {
+ this.observeFunction_(subject, topic, data);
+ if (this.onlyOnce_)
+ this.unregister();
+}
+
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/alarm.js"
+
+
+// An Alarm fires a callback after a certain amount of time, or at
+// regular intervals. It's a convenient replacement for
+// setTimeout/Interval when you don't want to bind to a specific
+// window.
+//
+// The ConditionalAlarm is an Alarm that cancels itself if its callback
+// returns a value that type-converts to true.
+//
+// Example:
+//
+// function foo() { dump('hi'); };
+// new G_Alarm(foo, 10*1000); // Fire foo in 10 seconds
+// new G_Alarm(foo, 10*1000, true /*repeat*/); // Fire foo every 10 seconds
+// new G_Alarm(foo, 10*1000, true, 7); // Fire foo every 10 seconds
+// // seven times
+// new G_ConditionalAlarm(foo, 1000, true); // Fire every sec until foo()==true
+//
+// // Fire foo every 10 seconds until foo returns true or until it fires seven
+// // times, whichever happens first.
+// new G_ConditionalAlarm(foo, 10*1000, true /*repeating*/, 7);
+//
+// TODO: maybe pass an isFinal flag to the callback if they opted to
+// set maxTimes and this is the last iteration?
+
+
+/**
+ * Set an alarm to fire after a given amount of time, or at specific
+ * intervals.
+ *
+ * @param callback Function to call when the alarm fires
+ * @param delayMS Number indicating the length of the alarm period in ms
+ * @param opt_repeating Boolean indicating whether this should fire
+ * periodically
+ * @param opt_maxTimes Number indicating a maximum number of times to
+ * repeat (obviously only useful when opt_repeating==true)
+ */
+function G_Alarm(callback, delayMS, opt_repeating, opt_maxTimes) {
+ this.debugZone = "alarm";
+ this.callback_ = callback;
+ this.repeating_ = !!opt_repeating;
+ this.timer_ = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ var type = opt_repeating ?
+ this.timer_.TYPE_REPEATING_SLACK :
+ this.timer_.TYPE_ONE_SHOT;
+ this.maxTimes_ = opt_maxTimes ? opt_maxTimes : null;
+ this.nTimes_ = 0;
+
+ this.observerServiceObserver_ = new G_ObserverServiceObserver(
+ 'xpcom-shutdown',
+ BindToObject(this.cancel, this));
+
+ // Ask the timer to use nsITimerCallback (.notify()) when ready
+ this.timer_.initWithCallback(this, delayMS, type);
+}
+
+/**
+ * Cancel this timer
+ */
+G_Alarm.prototype.cancel = function() {
+ if (!this.timer_) {
+ return;
+ }
+
+ this.timer_.cancel();
+ // Break circular reference created between this.timer_ and the G_Alarm
+ // instance (this)
+ this.timer_ = null;
+ this.callback_ = null;
+
+ // We don't need the shutdown observer anymore
+ this.observerServiceObserver_.unregister();
+}
+
+/**
+ * Invoked by the timer when it fires
+ *
+ * @param timer Reference to the nsITimer which fired (not currently
+ * passed along)
+ */
+G_Alarm.prototype.notify = function(timer) {
+ // fire callback and save results
+ var ret = this.callback_();
+
+ // If they've given us a max number of times to fire, enforce it
+ this.nTimes_++;
+ if (this.repeating_ &&
+ typeof this.maxTimes_ == "number"
+ && this.nTimes_ >= this.maxTimes_) {
+ this.cancel();
+ } else if (!this.repeating_) {
+ // Clear out the callback closure for TYPE_ONE_SHOT timers
+ this.cancel();
+ }
+ // We don't cancel/cleanup timers that repeat forever until either
+ // xpcom-shutdown occurs or cancel() is called explicitly.
+
+ return ret;
+}
+
+G_Alarm.prototype.setDelay = function(delay) {
+ this.timer_.delay = delay;
+}
+
+/**
+ * XPCOM cruft
+ */
+G_Alarm.prototype.QueryInterface = function(iid) {
+ if (iid.equals(Components.interfaces.nsISupports) ||
+ iid.equals(Components.interfaces.nsITimerCallback))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+}
+
+
+/**
+ * An alarm with the additional property that it cancels itself if its
+ * callback returns true.
+ *
+ * For parameter documentation, see G_Alarm
+ */
+function G_ConditionalAlarm(callback, delayMS, opt_repeating, opt_maxTimes) {
+ G_Alarm.call(this, callback, delayMS, opt_repeating, opt_maxTimes);
+ this.debugZone = "conditionalalarm";
+}
+
+G_ConditionalAlarm.inherits(G_Alarm);
+
+/**
+ * Invoked by the timer when it fires
+ *
+ * @param timer Reference to the nsITimer which fired (not currently
+ * passed along)
+ */
+G_ConditionalAlarm.prototype.notify = function(timer) {
+ // Call G_Alarm::notify
+ var rv = G_Alarm.prototype.notify.call(this, timer);
+
+ if (this.repeating_ && rv) {
+ G_Debug(this, "Callback of a repeating alarm returned true; cancelling.");
+ this.cancel();
+ }
+}
+//@line 54 "/builds/moz2_slave/linux_build/build/toolkit/components/places/src/nsLivemarkService.js"
+
+const LS_CLASSID = Components.ID("{dca61eb5-c7cd-4df1-b0fb-d0722baba251}");
+const LS_CLASSNAME = "Livemark Service";
+const LS_CONTRACTID = "@mozilla.org/browser/livemark-service;2";
+
+const LMANNO_FEEDURI = "livemark/feedURI";
+const LMANNO_SITEURI = "livemark/siteURI";
+const LMANNO_EXPIRATION = "livemark/expiration";
+const LMANNO_LOADFAILED = "livemark/loadfailed";
+const LMANNO_LOADING = "livemark/loading";
+
+const PS_CONTRACTID = "@mozilla.org/preferences-service;1";
+const NH_CONTRACTID = "@mozilla.org/browser/nav-history-service;1";
+const AS_CONTRACTID = "@mozilla.org/browser/annotation-service;1";
+const OS_CONTRACTID = "@mozilla.org/observer-service;1";
+const SB_CONTRACTID = "@mozilla.org/intl/stringbundle;1";
+const IO_CONTRACTID = "@mozilla.org/network/io-service;1";
+const BMS_CONTRACTID = "@mozilla.org/browser/nav-bookmarks-service;1";
+const FAV_CONTRACTID = "@mozilla.org/browser/favicon-service;1";
+const LG_CONTRACTID = "@mozilla.org/network/load-group;1";
+const FP_CONTRACTID = "@mozilla.org/feed-processor;1";
+const SEC_CONTRACTID = "@mozilla.org/scriptsecuritymanager;1";
+const IS_CONTRACTID = "@mozilla.org/widget/idleservice;1";
+const SEC_FLAGS = Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL;
+
+// Expire livemarks after 1 hour by default
+var gExpiration = 3600000;
+
+// Number of livemarks that are read at once
+var gLimitCount = 1;
+
+// Interval when livemarks are loaded
+var gDelayTime = 3;
+
+// Expire livemarks after 10 minutes on error
+const ERROR_EXPIRATION = 600000;
+
+// Don't check when the user is idle for longer than half an hour
+const IDLE_TIMELIMIT = 1800000;
+
+// We should check for expiration _at least_ every hour
+// This cap is used only if the user sets a very high expiration time (>4h)
+const MAX_REFRESH_TIME = 3600000;
+
+/* We don't have strings, so this is currently not used.
+const PLACES_BUNDLE_URI = "chrome://places/locale/places.properties";
+
+function LOG(str) {
+ dump("*** " + str + "\n");
+}
+
+var gStringBundle;
+function GetString(name)
+{
+ try {
+ if (!gStringBundle) {
+ var bundleService = Cc[SB_CONTRACTID].getService();
+ bundleService = bundleService.QueryInterface(Ci.nsIStringBundleService);
+ gStringBundle = bundleService.createBundle(PLACES_BUNDLE_URI);
+ }
+
+ if (gStringBundle)
+ return gStringBundle.GetStringFromName(name);
+ } catch (ex) {
+ LOG("Exception loading string bundle: " + ex.message);
+ }
+
+ return null;
+}
+*/
+
+function MarkLivemarkLoadFailed(aFolderId) {
+ var ans = Cc[AS_CONTRACTID].getService(Ci.nsIAnnotationService);
+ // if it failed before, nothing more to do
+ if (ans.itemHasAnnotation(aFolderId, LMANNO_LOADFAILED))
+ return;
+
+ // removeItemAnnotation can safely be used even when the anno isn't set
+ ans.removeItemAnnotation(aFolderId, LMANNO_LOADING);
+ ans.setItemAnnotation(aFolderId, LMANNO_LOADFAILED, true,
+ 0, ans.EXPIRE_NEVER);
+}
+
+function LivemarkService() {
+
+ try {
+ var prefs = Cc[PS_CONTRACTID].getService(Ci.nsIPrefBranch);
+ var livemarkRefresh =
+ prefs.getIntPref("browser.bookmarks.livemark_refresh_seconds");
+ // Reset global expiration variable to reflect hidden pref (in ms)
+ // with a lower limit of 1 minute (60000 ms)
+ gExpiration = Math.max(livemarkRefresh * 1000, 60000);
+ }
+ catch (ex) { }
+
+ try {
+ gLimitCount = prefs.getIntPref("browser.bookmarks.livemark_refresh_limit_count");
+ if ( gLimitCount < 1 ) gLimitCount = 1;
+ }
+ catch (ex) { }
+
+ try {
+ gDelayTime = prefs.getIntPref("browser.bookmarks.livemark_refresh_delay_time");
+ if ( gDelayTime < 1 ) gDelayTime = 1;
+ }
+ catch (ex) { }
+
+ // [ {folderId:, folderURI:, feedURI:, loadGroup:, locked: } ];
+ this._livemarks = [];
+
+ this._observerServiceObserver =
+ new G_ObserverServiceObserver('xpcom-shutdown',
+ BindToObject(this._shutdown, this),
+ true /*only once*/);
+
+ var livemarks = this._ans.getItemsWithAnnotation(LMANNO_FEEDURI, {});
+ for (var i = 0; i < livemarks.length; i++) {
+ var feedURI = this._ios.newURI(this._ans.getItemAnnotation(livemarks[i],
+ LMANNO_FEEDURI),
+ null, null);
+ this._pushLivemark(livemarks[i], feedURI);
+ }
+
+ this._bms.addObserver(this, false);
+}
+
+LivemarkService.prototype = {
+
+ get _bms() {
+ if (!this.__bms)
+ this.__bms = Cc[BMS_CONTRACTID].getService(Ci.nsINavBookmarksService);
+ return this.__bms;
+ },
+
+ get _history() {
+ if (!this.__history)
+ this.__history = Cc[NH_CONTRACTID].getService(Ci.nsINavHistoryService);
+ return this.__history;
+ },
+
+ get _ans() {
+ if (!this.__ans)
+ this.__ans = Cc[AS_CONTRACTID].getService(Ci.nsIAnnotationService);
+ return this.__ans;
+ },
+
+ get _ios() {
+ if (!this.__ios)
+ this.__ios = Cc[IO_CONTRACTID].getService(Ci.nsIIOService);
+ return this.__ios;
+ },
+
+ get _idleService() {
+ if (!(IS_CONTRACTID in Cc))
+ return null;
+ if (!this.__idleService)
+ this.__idleService = Cc[IS_CONTRACTID].getService(Ci.nsIIdleService);
+ return this.__idleService;
+ },
+
+ _updateTimer: null,
+ start: function LS_start() {
+ if (this._updateTimer)
+ return;
+ // start is called in delayed startup, 5s after browser startup
+ // we do a first check of the livemarks here, next checks will be on timer
+ // browser start => 5s => this.start() => check => refresh_time => check
+ this._checkAllLivemarks();
+ },
+
+ stopUpdateLivemarks: function LS_stopUpdateLivemarks() {
+ for (var livemark in this._livemarks) {
+ if (livemark.loadGroup)
+ livemark.loadGroup.cancel(Components.results.NS_BINDING_ABORTED);
+ }
+ // kill timer
+ if (this._updateTimer) {
+ this._updateTimer.cancel();
+ this._updateTimer = null;
+ }
+ },
+
+ _pushLivemark: function LS__pushLivemark(aFolderId, aFeedURI) {
+ // returns new length of _livemarks
+ return this._livemarks.push({folderId: aFolderId, feedURI: aFeedURI});
+ },
+
+ _getLivemarkIndex: function LS__getLivemarkIndex(aFolderId) {
+ for (var i = 0; i < this._livemarks.length; ++i) {
+ if (this._livemarks[i].folderId == aFolderId)
+ return i;
+ }
+ throw Cr.NS_ERROR_INVALID_ARG;
+ },
+
+ _shutdown: function LS__shutdown() {
+ // remove bookmarks observer
+ this._bms.removeObserver(this);
+
+ // stop to update livemarks
+ this.stopUpdateLivemarks();
+ },
+
+ // We try to distribute the load of the livemark update.
+ // load gLimitCount Livemarks per gDelayTime sec.
+ _nextUpdateStartIndex : 0,
+ _checkAllLivemarks: function LS__checkAllLivemarks() {
+ var startNo = this._nextUpdateStartIndex;
+ var count = 0;
+ for (var i = startNo; (i < this._livemarks.length) && (count < gLimitCount); ++i ) {
+ // check if livemarks are expired, update if needed
+ try {
+ if (this._updateLivemarkChildren(i, false)) count++;
+ }
+ catch (ex) { }
+ this._nextUpdateStartIndex = i+1;
+ }
+ if ( this._nextUpdateStartIndex >= this._livemarks.length ) {
+ // all livemarks are checked, sleeping until next period
+ this._nextUpdateStartIndex = 0;
+ var refresh_time = Math.min(Math.floor(gExpiration / 4), MAX_REFRESH_TIME);
+ this._updateTimer = new G_Alarm(BindToObject(this._checkAllLivemarks, this),
+ refresh_time);
+ } else {
+ // wait gDelayTime sec.
+ this._updateTimer = new G_Alarm(BindToObject(this._checkAllLivemarks, this),
+ gDelayTime*1000);
+ }
+ },
+
+ deleteLivemarkChildren: function LS_deleteLivemarkChildren(aFolderId) {
+ this._bms.removeFolderChildren(aFolderId);
+ },
+
+ _updateLivemarkChildren:
+ function LS__updateLivemarkChildren(aIndex, aForceUpdate) {
+ if (this._livemarks[aIndex].locked)
+ return false;
+
+ var livemark = this._livemarks[aIndex];
+ livemark.locked = true;
+ try {
+ // Check the TTL/expiration on this. If there isn't one,
+ // then we assume it's never been loaded. We perform this
+ // check even when the update is being forced, in case the
+ // livemark has somehow never been loaded.
+ var expireTime = this._ans.getItemAnnotation(livemark.folderId,
+ LMANNO_EXPIRATION);
+ if (!aForceUpdate && expireTime > Date.now()) {
+ // no need to refresh
+ livemark.locked = false;
+ return false;
+ }
+
+ // Check the user idle time.
+ // If the user is away from the computer, don't bother updating,
+ // so we save some bandwidth.
+ // If we can't get the idle time, assume the user is not idle.
+ var idleTime = 0;
+ try {
+ idleTime = this._idleService.idleTime;
+ }
+ catch (ex) { /* We don't care */ }
+ if (idleTime > IDLE_TIMELIMIT) {
+ livemark.locked = false;
+ return false;
+ }
+ }
+ catch (ex) {
+ // This livemark has never been loaded, since it has no expire time.
+ }
+
+ var loadgroup;
+ try {
+ // Create a load group for the request. This will allow us to
+ // automatically keep track of redirects, so we can always
+ // cancel the channel.
+ loadgroup = Cc[LG_CONTRACTID].createInstance(Ci.nsILoadGroup);
+ var uriChannel = this._ios.newChannel(livemark.feedURI.spec, null, null);
+ uriChannel.loadGroup = loadgroup;
+ uriChannel.loadFlags |= Ci.nsIRequest.LOAD_BACKGROUND |
+ Ci.nsIRequest.VALIDATE_ALWAYS;
+ var httpChannel = uriChannel.QueryInterface(Ci.nsIHttpChannel);
+ httpChannel.requestMethod = "GET";
+ httpChannel.setRequestHeader("X-Moz", "livebookmarks", false);
+
+ // Stream the result to the feed parser with this listener
+ var listener = new LivemarkLoadListener(livemark);
+ // removeItemAnnotation can safely be used even when the anno isn't set
+ this._ans.removeItemAnnotation(livemark.folderId, LMANNO_LOADFAILED);
+ this._ans.setItemAnnotation(livemark.folderId, LMANNO_LOADING, true,
+ 0, this._ans.EXPIRE_NEVER);
+ httpChannel.notificationCallbacks = listener;
+ httpChannel.asyncOpen(listener, null);
+ }
+ catch (ex) {
+ MarkLivemarkLoadFailed(livemark.folderId);
+ livemark.locked = false;
+ return false;
+ }
+ livemark.loadGroup = loadgroup;
+ return true;
+ },
+
+ createLivemark: function LS_createLivemark(aParentId, aName, aSiteURI,
+ aFeedURI, aIndex) {
+ if (!aParentId || !aFeedURI)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ // Don't add livemarks to livemarks
+ if (this.isLivemark(aParentId))
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ var folderId = this._createFolder(aParentId, aName, aSiteURI,
+ aFeedURI, aIndex);
+
+ // do a first update of the livemark children
+ this._updateLivemarkChildren(this._pushLivemark(folderId, aFeedURI) - 1,
+ false);
+
+ return folderId;
+ },
+
+ createLivemarkFolderOnly:
+ function LS_createLivemarkFolderOnly(aParentId, aName, aSiteURI,
+ aFeedURI, aIndex) {
+ if (aParentId < 1 || !aFeedURI)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ // Don't add livemarks to livemarks
+ if (this.isLivemark(aParentId))
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ var folderId = this._createFolder(aParentId, aName, aSiteURI,
+ aFeedURI, aIndex);
+
+ var livemarkIndex = this._pushLivemark(folderId, aFeedURI) - 1;
+ var livemark = this._livemarks[livemarkIndex];
+ return folderId;
+ },
+
+ _createFolder:
+ function LS__createFolder(aParentId, aName, aSiteURI, aFeedURI, aIndex) {
+ var folderId = this._bms.createFolder(aParentId, aName, aIndex);
+ this._bms.setFolderReadonly(folderId, true);
+
+ // Add an annotation to map the folder id to the livemark feed URI
+ this._ans.setItemAnnotation(folderId, LMANNO_FEEDURI, aFeedURI.spec,
+ 0, this._ans.EXPIRE_NEVER);
+
+ if (aSiteURI) {
+ // Add an annotation to map the folder URI to the livemark site URI
+ this._setSiteURISecure(folderId, aFeedURI, aSiteURI);
+ }
+
+ return folderId;
+ },
+
+ isLivemark: function LS_isLivemark(aFolderId) {
+ if (aFolderId < 1)
+ throw Cr.NS_ERROR_INVALID_ARG;
+ return this._ans.itemHasAnnotation(aFolderId, LMANNO_FEEDURI);
+ },
+
+ _ensureLivemark: function LS__ensureLivemark(aFolderId) {
+ if (!this.isLivemark(aFolderId))
+ throw Cr.NS_ERROR_INVALID_ARG;
+ },
+
+ getSiteURI: function LS_getSiteURI(aFolderId) {
+ this._ensureLivemark(aFolderId);
+
+ if (this._ans.itemHasAnnotation(aFolderId, LMANNO_SITEURI)) {
+ var siteURIString =
+ this._ans.getItemAnnotation(aFolderId, LMANNO_SITEURI);
+
+ return this._ios.newURI(siteURIString, null, null);
+ }
+ return null;
+ },
+
+ setSiteURI: function LS_setSiteURI(aFolderId, aSiteURI) {
+ this._ensureLivemark(aFolderId);
+
+ if (!aSiteURI) {
+ this._ans.removeItemAnnotation(aFolderId, LMANNO_SITEURI);
+ return;
+ }
+
+ var livemarkIndex = this._getLivemarkIndex(aFolderId);
+ var livemark = this._livemarks[livemarkIndex];
+ this._setSiteURISecure(aFolderId, livemark.feedURI, aSiteURI);
+ },
+
+ _setSiteURISecure:
+ function LS__setSiteURISecure(aFolderId, aFeedURI, aSiteURI) {
+ var secMan = Cc[SEC_CONTRACTID].getService(Ci.nsIScriptSecurityManager);
+ var feedPrincipal = secMan.getCodebasePrincipal(aFeedURI);
+ try {
+ secMan.checkLoadURIWithPrincipal(feedPrincipal, aSiteURI, SEC_FLAGS);
+ }
+ catch (e) {
+ return;
+ }
+ this._ans.setItemAnnotation(aFolderId, LMANNO_SITEURI, aSiteURI.spec,
+ 0, this._ans.EXPIRE_NEVER);
+ },
+
+ getFeedURI: function LS_getFeedURI(aFolderId) {
+ if (this._ans.itemHasAnnotation(aFolderId, LMANNO_FEEDURI))
+ return this._ios.newURI(this._ans.getItemAnnotation(aFolderId,
+ LMANNO_FEEDURI),
+ null, null);
+ return null;
+ },
+
+ setFeedURI: function LS_setFeedURI(aFolderId, aFeedURI) {
+ if (!aFeedURI)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ this._ans.setItemAnnotation(aFolderId, LMANNO_FEEDURI, aFeedURI.spec, 0,
+ this._ans.EXPIRE_NEVER);
+
+ // now update our internal table
+ var livemarkIndex = this._getLivemarkIndex(aFolderId);
+ this._livemarks[livemarkIndex].feedURI = aFeedURI;
+ },
+
+ reloadAllLivemarks: function LS_reloadAllLivemarks() {
+ for (var i = 0; i < this._livemarks.length; ++i) {
+ this._updateLivemarkChildren(i, true);
+ }
+ },
+
+ reloadLivemarkFolder: function LS_reloadLivemarkFolder(aFolderId) {
+ var livemarkIndex = this._getLivemarkIndex(aFolderId);
+ this._updateLivemarkChildren(livemarkIndex, true);
+ },
+
+ // nsINavBookmarkObserver
+ onBeginUpdateBatch: function() { },
+ onEndUpdateBatch: function() { },
+ onItemAdded: function() { },
+ onItemChanged: function() { },
+ onItemVisited: function() { },
+ onItemMoved: function() { },
+
+ onItemRemoved: function(aItemId, aParentId, aIndex) {
+ // we don't need to remove annotations since itemAnnotations
+ // are already removed with the bookmark
+ try {
+ var livemarkIndex = this._getLivemarkIndex(aItemId);
+ }
+ catch(ex) {
+ // not a livemark
+ return;
+ }
+ var livemark = this._livemarks[livemarkIndex];
+
+ // remove the livemark from the update array
+ this._livemarks.splice(livemarkIndex, 1);
+
+ if (livemark.loadGroup)
+ livemark.loadGroup.cancel(Components.results.NS_BINDING_ABORTED);
+ },
+
+ createInstance: function LS_createInstance(aOuter, aIID) {
+ if (aOuter != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return this.QueryInterface(aIID);
+ },
+
+ QueryInterface: function LS_QueryInterface(aIID) {
+ if (aIID.equals(Ci.nsILivemarkService) ||
+ aIID.equals(Ci.nsIFactory) ||
+ aIID.equals(Ci.nsINavBookmarkObserver) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ }
+};
+
+function LivemarkLoadListener(aLivemark) {
+ this._livemark = aLivemark;
+ this._processor = null;
+ this._isAborted = false;
+ this._ttl = gExpiration;
+}
+
+LivemarkLoadListener.prototype = {
+
+ abort: function LLL_abort() {
+ this._isAborted = true;
+ },
+
+ get _bms() {
+ if (!this.__bms)
+ this.__bms = Cc[BMS_CONTRACTID].getService(Ci.nsINavBookmarksService);
+ return this.__bms;
+ },
+
+ get _history() {
+ if (!this.__history)
+ this.__history = Cc[NH_CONTRACTID].getService(Ci.nsINavHistoryService);
+ return this.__history;
+ },
+
+ get _ans() {
+ if (!this.__ans)
+ this.__ans = Cc[AS_CONTRACTID].getService(Ci.nsIAnnotationService);
+ return this.__ans;
+ },
+
+ // called back from handleResult
+ runBatched: function LLL_runBatched(aUserData) {
+ var result = aUserData.QueryInterface(Ci.nsIFeedResult);
+
+ // We need this to make sure the item links are safe
+ var secMan = Cc[SEC_CONTRACTID].getService(Ci.nsIScriptSecurityManager);
+ var feedPrincipal = secMan.getCodebasePrincipal(this._livemark.feedURI);
+
+ var lmService = Cc[LS_CONTRACTID].getService(Ci.nsILivemarkService);
+
+ // Enforce well-formedness because the existing code does
+ if (!result || !result.doc || result.bozo) {
+ MarkLivemarkLoadFailed(this._livemark.folderId);
+ this._ttl = gExpiration;
+ throw Cr.NS_ERROR_FAILURE;
+ }
+
+ // Clear out any child nodes of the livemark folder, since
+ // they're about to be replaced.
+ this.deleteLivemarkChildren(this._livemark.folderId);
+ var feed = result.doc.QueryInterface(Ci.nsIFeed);
+ if (feed.link) {
+ var oldSiteURI = lmService.getSiteURI(this._livemark.folderId);
+ if (!oldSiteURI || !feed.link.equals(oldSiteURI))
+ lmService.setSiteURI(this._livemark.folderId, feed.link);
+ }
+ // Loop through and check for a link and a title
+ // as the old code did
+ for (var i = 0; i < feed.items.length; ++i) {
+ let entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
+ let href = entry.link;
+ if (!href)
+ continue;
+
+ let title = entry.title ? entry.title.plainText() : "";
+
+ try {
+ secMan.checkLoadURIWithPrincipal(feedPrincipal, href, SEC_FLAGS);
+ }
+ catch(ex) {
+ continue;
+ }
+
+ this.insertLivemarkChild(this._livemark.folderId, href, title);
+ }
+ },
+
+ /**
+ * See nsIFeedResultListener.idl
+ */
+ handleResult: function LLL_handleResult(aResult) {
+ if (this._isAborted) {
+ MarkLivemarkLoadFailed(this._livemark.folderId);
+ this._livemark.locked = false;
+ return;
+ }
+ try {
+ // The actual work is done in runBatched, see above.
+ this._bms.runInBatchMode(this, aResult);
+ }
+ finally {
+ this._processor.listener = null;
+ this._processor = null;
+ this._livemark.locked = false;
+ this._ans.removeItemAnnotation(this._livemark.folderId, LMANNO_LOADING);
+ }
+ },
+
+ deleteLivemarkChildren: LivemarkService.prototype.deleteLivemarkChildren,
+
+ insertLivemarkChild:
+ function LS_insertLivemarkChild(aFolderId, aUri, aTitle) {
+ this._bms.insertBookmark(aFolderId, aUri, this._bms.DEFAULT_INDEX, aTitle);
+ },
+
+ /**
+ * See nsIStreamListener.idl
+ */
+ onDataAvailable: function LLL_onDataAvailable(aRequest, aContext, aInputStream,
+ aSourceOffset, aCount) {
+ if (this._processor)
+ this._processor.onDataAvailable(aRequest, aContext, aInputStream,
+ aSourceOffset, aCount);
+ },
+
+ /**
+ * See nsIRequestObserver.idl
+ */
+ onStartRequest: function LLL_onStartRequest(aRequest, aContext) {
+ if (this._isAborted)
+ throw Cr.NS_ERROR_UNEXPECTED;
+
+ var channel = aRequest.QueryInterface(Ci.nsIChannel);
+
+ // Parse feed data as it comes in
+ this._processor = Cc[FP_CONTRACTID].createInstance(Ci.nsIFeedProcessor);
+ this._processor.listener = this;
+ this._processor.parseAsync(null, channel.URI);
+
+ this._processor.onStartRequest(aRequest, aContext);
+ },
+
+ /**
+ * See nsIRequestObserver.idl
+ */
+ onStopRequest: function LLL_onStopRequest(aRequest, aContext, aStatus) {
+ if (!Components.isSuccessCode(aStatus)) {
+ // Something went wrong, try to load again in a bit
+ this._setResourceTTL(ERROR_EXPIRATION);
+ this._isAborted = true;
+ MarkLivemarkLoadFailed(this._livemark.folderId);
+ this._livemark.locked = false;
+ return;
+ }
+ // Set an expiration on the livemark, for reloading the data
+ try {
+ if (this._processor)
+ this._processor.onStopRequest(aRequest, aContext, aStatus);
+
+ // Calculate a new ttl
+ var channel = aRequest.QueryInterface(Ci.nsICachingChannel);
+ if (channel) {
+ var entryInfo = channel.cacheToken.QueryInterface(Ci.nsICacheEntryInfo);
+ if (entryInfo) {
+ // nsICacheEntryInfo returns value as seconds,
+ // expireTime stores as milliseconds
+ var expireTime = entryInfo.expirationTime * 1000;
+ var nowTime = Date.now();
+
+ // note, expireTime can be 0, see bug 383538
+ if (expireTime > nowTime) {
+ this._setResourceTTL(Math.max((expireTime - nowTime),
+ gExpiration));
+ return;
+ }
+ }
+ }
+ }
+ catch (ex) { }
+ this._setResourceTTL(this._ttl);
+ },
+
+ _setResourceTTL: function LLL__setResourceTTL(aMilliseconds) {
+ var expireTime = Date.now() + aMilliseconds;
+ this._ans.setItemAnnotation(this._livemark.folderId, LMANNO_EXPIRATION,
+ expireTime, 0,
+ Ci.nsIAnnotationService.EXPIRE_NEVER);
+ },
+
+ /**
+ * See nsIBadCertListener2
+ */
+ notifyCertProblem: function LLL_certProblem(aSocketInfo, aStatus, aTargetSite) {
+ return true;
+ },
+
+ /**
+ * See nsISSLErrorListener
+ */
+ notifySSLError: function LLL_SSLError(aSocketInfo, aError, aTargetSite) {
+ return true;
+ },
+
+ /**
+ * See nsIInterfaceRequestor
+ */
+ getInterface: function LLL_getInterface(aIID) {
+ return this.QueryInterface(aIID);
+ },
+
+ /**
+ * See nsISupports.idl
+ */
+ QueryInterface: function LLL_QueryInterface(aIID) {
+ if (aIID.equals(Ci.nsIFeedResultListener) ||
+ aIID.equals(Ci.nsIStreamListener) ||
+ aIID.equals(Ci.nsIRequestObserver)||
+ aIID.equals(Ci.nsINavHistoryBatchCallback) ||
+ aIID.equals(Ci.nsIBadCertListener2) ||
+ aIID.equals(Ci.nsISSLErrorListener) ||
+ aIID.equals(Ci.nsIInterfaceRequestor) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+}
+
+function GenericComponentFactory(aCtor) {
+ this._ctor = aCtor;
+}
+
+GenericComponentFactory.prototype = {
+
+ _ctor: null,
+
+ // nsIFactory
+ createInstance: function(aOuter, aIID) {
+ if (aOuter != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return (new this._ctor()).QueryInterface(aIID);
+ },
+
+ // nsISupports
+ QueryInterface: function(aIID) {
+ if (aIID.equals(Ci.nsIFactory) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+};
+
+var Module = {
+ QueryInterface: function(aIID) {
+ if (aIID.equals(Ci.nsIModule) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ getClassObject: function M_getClassObject(aCompMgr, aCID, aIID) {
+ if (!aIID.equals(Ci.nsIFactory))
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ if (aCID.equals(LS_CLASSID))
+ return new GenericComponentFactory(LivemarkService);
+
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ registerSelf: function(aCompMgr, aFile, aLocation, aType) {
+ var cr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
+
+ cr.registerFactoryLocation(LS_CLASSID, LS_CLASSNAME,
+ LS_CONTRACTID, aFile, aLocation, aType);
+ },
+
+ unregisterSelf: function M_unregisterSelf(aCompMgr, aLocation, aType) {
+ var cr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ cr.unregisterFactoryLocation(LS_CLASSID, aLocation);
+ },
+
+ canUnload: function M_canUnload(aCompMgr) {
+ return true;
+ }
+};
+
+function NSGetModule(aCompMgr, aFile) {
+ return Module;
+}
diff --git a/bundles/XO/components/nsLoginInfo.js b/bundles/XO/components/nsLoginInfo.js
new file mode 100755
index 0000000..3fd10bf
--- /dev/null
+++ b/bundles/XO/components/nsLoginInfo.js
@@ -0,0 +1,139 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Dolske <dolske@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function nsLoginInfo() {}
+
+nsLoginInfo.prototype = {
+
+ classDescription : "LoginInfo",
+ contractID : "@mozilla.org/login-manager/loginInfo;1",
+ classID : Components.ID("{0f2f347c-1e4f-40cc-8efd-792dea70a85e}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsILoginInfo, Ci.nsILoginMetaInfo]),
+
+ // Allow storage-Legacy.js to get at the JS object so it can
+ // slap on a few extra properties for internal use.
+ get wrappedJSObject() {
+ return this;
+ },
+
+ //
+ // nsILoginInfo interfaces...
+ //
+
+ hostname : null,
+ formSubmitURL : null,
+ httpRealm : null,
+ username : null,
+ password : null,
+ usernameField : null,
+ passwordField : null,
+
+ init : function (aHostname, aFormSubmitURL, aHttpRealm,
+ aUsername, aPassword,
+ aUsernameField, aPasswordField) {
+ this.hostname = aHostname;
+ this.formSubmitURL = aFormSubmitURL;
+ this.httpRealm = aHttpRealm;
+ this.username = aUsername;
+ this.password = aPassword;
+ this.usernameField = aUsernameField;
+ this.passwordField = aPasswordField;
+ },
+
+ matches : function (aLogin, ignorePassword) {
+ if (this.hostname != aLogin.hostname ||
+ this.httpRealm != aLogin.httpRealm ||
+ this.username != aLogin.username)
+ return false;
+
+ if (!ignorePassword && this.password != aLogin.password)
+ return false;
+
+ // If either formSubmitURL is blank (but not null), then match.
+ if (this.formSubmitURL != "" && aLogin.formSubmitURL != "" &&
+ this.formSubmitURL != aLogin.formSubmitURL)
+ return false;
+
+ // The .usernameField and .passwordField values are ignored.
+
+ return true;
+ },
+
+ equals : function (aLogin) {
+ if (this.hostname != aLogin.hostname ||
+ this.formSubmitURL != aLogin.formSubmitURL ||
+ this.httpRealm != aLogin.httpRealm ||
+ this.username != aLogin.username ||
+ this.password != aLogin.password ||
+ this.usernameField != aLogin.usernameField ||
+ this.passwordField != aLogin.passwordField)
+ return false;
+
+ return true;
+ },
+
+ clone : function() {
+ let clone = Cc["@mozilla.org/login-manager/loginInfo;1"].
+ createInstance(Ci.nsILoginInfo);
+ clone.init(this.hostname, this.formSubmitURL, this.httpRealm,
+ this.username, this.password,
+ this.usernameField, this.passwordField);
+
+ // Copy nsILoginMetaInfo props
+ clone.QueryInterface(Ci.nsILoginMetaInfo);
+ clone.guid = this.guid;
+
+ return clone;
+ },
+
+ //
+ // nsILoginMetaInfo interfaces...
+ //
+
+ guid : null
+
+}; // end of nsLoginInfo implementation
+
+var component = [nsLoginInfo];
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(component);
+}
diff --git a/bundles/XO/components/nsLoginManager.js b/bundles/XO/components/nsLoginManager.js
new file mode 100755
index 0000000..770fd6c
--- /dev/null
+++ b/bundles/XO/components/nsLoginManager.js
@@ -0,0 +1,1382 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Dolske <dolske@mozilla.com> (original author)
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function LoginManager() {
+ this.init();
+}
+
+LoginManager.prototype = {
+
+ classDescription: "LoginManager",
+ contractID: "@mozilla.org/login-manager;1",
+ classID: Components.ID("{cb9e0de8-3598-4ed7-857b-827f011ad5d8}"),
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsILoginManager,
+ Ci.nsISupportsWeakReference,
+ Ci.nsILoginManager_MOZILLA_1_9_1,
+ Ci.nsIClassInfo]),
+
+ /* ---------- extra requirements for nsIClassInfo ---------- */
+ getInterfaces: function(countRef) {
+ let interfaces = [Ci.nsILoginManager, Ci.nsISupportsWeakReference,
+ Ci.nsILoginManager_MOZILLA_1_9_1, Ci.nsIClassInfo];
+ countRef.value = interfaces.length;
+ return interfaces;
+ },
+ getHelperForLanguage: function (language) null,
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ flags: Ci.nsIClassInfo.SINGLETON,
+
+
+ /* ---------- private memebers ---------- */
+
+
+ __logService : null, // Console logging service, used for debugging.
+ get _logService() {
+ if (!this.__logService)
+ this.__logService = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ return this.__logService;
+ },
+
+
+ __ioService: null, // IO service for string -> nsIURI conversion
+ get _ioService() {
+ if (!this.__ioService)
+ this.__ioService = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__ioService;
+ },
+
+
+ __formFillService : null, // FormFillController, for username autocompleting
+ get _formFillService() {
+ if (!this.__formFillService)
+ this.__formFillService =
+ Cc["@mozilla.org/satchel/form-fill-controller;1"].
+ getService(Ci.nsIFormFillController);
+ return this.__formFillService;
+ },
+
+
+ __observerService : null, // Observer Service, for notifications
+ get _observerService() {
+ if (!this.__observerService)
+ this.__observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ return this.__observerService;
+ },
+
+
+ __storage : null, // Storage component which contains the saved logins
+ get _storage() {
+ if (!this.__storage) {
+
+ var contractID = "@mozilla.org/login-manager/storage/mozStorage;1";
+ try {
+ var catMan = Cc["@mozilla.org/categorymanager;1"].
+ getService(Ci.nsICategoryManager);
+ contractID = catMan.getCategoryEntry("login-manager-storage",
+ "nsILoginManagerStorage");
+ this.log("Found alternate nsILoginManagerStorage with " +
+ "contract ID: " + contractID);
+ } catch (e) {
+ this.log("No alternate nsILoginManagerStorage registered");
+ }
+
+ this.__storage = Cc[contractID].
+ createInstance(Ci.nsILoginManagerStorage);
+ try {
+ this.__storage.init();
+ } catch (e) {
+ this.log("Initialization of storage component failed: " + e);
+ this.__storage = null;
+ }
+ }
+
+ return this.__storage;
+ },
+
+
+ // Private Browsing Service
+ // If the service is not available, null will be returned.
+ __privateBrowsingService : undefined,
+ get _privateBrowsingService() {
+ if (this.__privateBrowsingService == undefined) {
+ if ("@mozilla.org/privatebrowsing;1" in Cc)
+ this.__privateBrowsingService = Cc["@mozilla.org/privatebrowsing;1"].
+ getService(Ci.nsIPrivateBrowsingService);
+ else
+ this.__privateBrowsingService = null;
+ }
+ return this.__privateBrowsingService;
+ },
+
+
+ // Whether we are in private browsing mode
+ get _inPrivateBrowsing() {
+ var pbSvc = this._privateBrowsingService;
+ if (pbSvc)
+ return pbSvc.privateBrowsingEnabled;
+ else
+ return false;
+ },
+
+ _prefBranch : null, // Preferences service
+ _nsLoginInfo : null, // Constructor for nsILoginInfo implementation
+
+ _remember : true, // mirrors signon.rememberSignons preference
+ _debug : false, // mirrors signon.debug
+
+
+ /*
+ * init
+ *
+ * Initialize the Login Manager. Automatically called when service
+ * is created.
+ *
+ * Note: Service created in /browser/base/content/browser.js,
+ * delayedStartup()
+ */
+ init : function () {
+
+ // Cache references to current |this| in utility objects
+ this._webProgressListener._domEventListener = this._domEventListener;
+ this._webProgressListener._pwmgr = this;
+ this._domEventListener._pwmgr = this;
+ this._observer._pwmgr = this;
+
+ // Preferences. Add observer so we get notified of changes.
+ this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).getBranch("signon.");
+ this._prefBranch.QueryInterface(Ci.nsIPrefBranch2);
+ this._prefBranch.addObserver("", this._observer, false);
+
+ // Get current preference values.
+ this._debug = this._prefBranch.getBoolPref("debug");
+
+ this._remember = this._prefBranch.getBoolPref("rememberSignons");
+
+
+ // Get constructor for nsILoginInfo
+ this._nsLoginInfo = new Components.Constructor(
+ "@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo);
+
+
+ // Form submit observer checks forms for new logins and pw changes.
+ this._observerService.addObserver(this._observer, "earlyformsubmit", false);
+ this._observerService.addObserver(this._observer, "xpcom-shutdown", false);
+
+ // WebProgressListener for getting notification of new doc loads.
+ var progress = Cc["@mozilla.org/docloaderservice;1"].
+ getService(Ci.nsIWebProgress);
+ progress.addProgressListener(this._webProgressListener,
+ Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
+
+
+ },
+
+
+ /*
+ * log
+ *
+ * Internal function for logging debug messages to the Error Console window
+ */
+ log : function (message) {
+ if (!this._debug)
+ return;
+ dump("Login Manager: " + message + "\n");
+ this._logService.logStringMessage("Login Manager: " + message);
+ },
+
+
+ /* ---------- Utility objects ---------- */
+
+
+ /*
+ * _observer object
+ *
+ * Internal utility object, implements the nsIObserver interface.
+ * Used to receive notification for: form submission, preference changes.
+ */
+ _observer : {
+ _pwmgr : null,
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsIFormSubmitObserver,
+ Ci.nsISupportsWeakReference]),
+
+
+ // nsFormSubmitObserver
+ notify : function (formElement, aWindow, actionURI) {
+ this._pwmgr.log("observer notified for form submission.");
+
+ // We're invoked before the content's |onsubmit| handlers, so we
+ // can grab form data before it might be modified (see bug 257781).
+
+ try {
+ this._pwmgr._onFormSubmit(formElement);
+ } catch (e) {
+ this._pwmgr.log("Caught error in onFormSubmit: " + e);
+ }
+
+ return true; // Always return true, or form submit will be canceled.
+ },
+
+ // nsObserver
+ observe : function (subject, topic, data) {
+
+ if (topic == "nsPref:changed") {
+ var prefName = data;
+ this._pwmgr.log("got change to " + prefName + " preference");
+
+ if (prefName == "debug") {
+ this._pwmgr._debug =
+ this._pwmgr._prefBranch.getBoolPref("debug");
+ } else if (prefName == "rememberSignons") {
+ this._pwmgr._remember =
+ this._pwmgr._prefBranch.getBoolPref("rememberSignons");
+ } else {
+ this._pwmgr.log("Oops! Pref not handled, change ignored.");
+ }
+ } else if (topic == "xpcom-shutdown") {
+ for (let i in this._pwmgr) {
+ try {
+ this._pwmgr[i] = null;
+ } catch(ex) {}
+ }
+ this._pwmgr = null;
+ } else {
+ this._pwmgr.log("Oops! Unexpected notification: " + topic);
+ }
+ }
+ },
+
+
+ /*
+ * _webProgressListener object
+ *
+ * Internal utility object, implements nsIWebProgressListener interface.
+ * This is attached to the document loader service, so we get
+ * notifications about all page loads.
+ */
+ _webProgressListener : {
+ _pwmgr : null,
+ _domEventListener : null,
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
+ Ci.nsISupportsWeakReference]),
+
+
+ onStateChange : function (aWebProgress, aRequest,
+ aStateFlags, aStatus) {
+
+ // STATE_START is too early, doc is still the old page.
+ if (!(aStateFlags & Ci.nsIWebProgressListener.STATE_TRANSFERRING))
+ return;
+
+ if (!this._pwmgr._remember)
+ return;
+
+ var domWin = aWebProgress.DOMWindow;
+ var domDoc = domWin.document;
+
+ // Only process things which might have HTML forms.
+ if (!(domDoc instanceof Ci.nsIDOMHTMLDocument))
+ return;
+
+ this._pwmgr.log("onStateChange accepted: req = " +
+ (aRequest ? aRequest.name : "(null)") +
+ ", flags = 0x" + aStateFlags.toString(16));
+
+ // Fastback doesn't fire DOMContentLoaded, so process forms now.
+ if (aStateFlags & Ci.nsIWebProgressListener.STATE_RESTORING) {
+ this._pwmgr.log("onStateChange: restoring document");
+ return this._pwmgr._fillDocument(domDoc);
+ }
+
+ // Add event listener to process page when DOM is complete.
+ domDoc.addEventListener("DOMContentLoaded",
+ this._domEventListener, false);
+ return;
+ },
+
+ // stubs for the nsIWebProgressListener interfaces which we don't use.
+ onProgressChange : function() { throw "Unexpected onProgressChange"; },
+ onLocationChange : function() { throw "Unexpected onLocationChange"; },
+ onStatusChange : function() { throw "Unexpected onStatusChange"; },
+ onSecurityChange : function() { throw "Unexpected onSecurityChange"; }
+ },
+
+
+ /*
+ * _domEventListener object
+ *
+ * Internal utility object, implements nsIDOMEventListener
+ * Used to catch certain DOM events needed to properly implement form fill.
+ */
+ _domEventListener : {
+ _pwmgr : null,
+
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
+ Ci.nsISupportsWeakReference]),
+
+
+ handleEvent : function (event) {
+ this._pwmgr.log("domEventListener: got event " + event.type);
+
+ switch (event.type) {
+ case "DOMContentLoaded":
+ this._pwmgr._fillDocument(event.target);
+ return;
+
+ case "DOMAutoComplete":
+ case "blur":
+ var acInputField = event.target;
+ var acForm = acInputField.form;
+
+ // If the username is blank, bail out now -- we don't want
+ // fillForm() to try filling in a login without a username
+ // to filter on (bug 471906).
+ if (!acInputField.value)
+ return;
+
+ // Make sure the username field fillForm will use is the
+ // same field as the autocomplete was activated on. If
+ // not, the DOM has been altered and we'll just give up.
+ var [usernameField, passwordField, ignored] =
+ this._pwmgr._getFormFields(acForm, false);
+ if (usernameField == acInputField && passwordField) {
+ // Clobber any existing password.
+ passwordField.value = "";
+ this._pwmgr._fillForm(acForm, true, true, null);
+ } else {
+ this._pwmgr.log("Oops, form changed before AC invoked");
+ }
+ return;
+
+ default:
+ this._pwmgr.log("Oops! This event unexpected.");
+ return;
+ }
+ }
+ },
+
+
+
+
+ /* ---------- Primary Public interfaces ---------- */
+
+
+
+
+ /*
+ * addLogin
+ *
+ * Add a new login to login storage.
+ */
+ addLogin : function (login) {
+ // Sanity check the login
+ if (login.hostname == null || login.hostname.length == 0)
+ throw "Can't add a login with a null or empty hostname.";
+
+ // For logins w/o a username, set to "", not null.
+ if (login.username == null)
+ throw "Can't add a login with a null username.";
+
+ if (login.password == null || login.password.length == 0)
+ throw "Can't add a login with a null or empty password.";
+
+ if (login.formSubmitURL || login.formSubmitURL == "") {
+ // We have a form submit URL. Can't have a HTTP realm.
+ if (login.httpRealm != null)
+ throw "Can't add a login with both a httpRealm and formSubmitURL.";
+ } else if (login.httpRealm) {
+ // We have a HTTP realm. Can't have a form submit URL.
+ if (login.formSubmitURL != null)
+ throw "Can't add a login with both a httpRealm and formSubmitURL.";
+ } else {
+ // Need one or the other!
+ throw "Can't add a login without a httpRealm or formSubmitURL.";
+ }
+
+
+ // Look for an existing entry.
+ var logins = this.findLogins({}, login.hostname, login.formSubmitURL,
+ login.httpRealm);
+
+ if (logins.some(function(l) login.matches(l, true)))
+ throw "This login already exists.";
+
+ this.log("Adding login: " + login);
+ return this._storage.addLogin(login);
+ },
+
+
+ /*
+ * removeLogin
+ *
+ * Remove the specified login from the stored logins.
+ */
+ removeLogin : function (login) {
+ this.log("Removing login: " + login);
+ return this._storage.removeLogin(login);
+ },
+
+
+ /*
+ * modifyLogin
+ *
+ * Change the specified login to match the new login.
+ */
+ modifyLogin : function (oldLogin, newLogin) {
+ this.log("Modifying oldLogin: " + oldLogin + " newLogin: " + newLogin);
+ return this._storage.modifyLogin(oldLogin, newLogin);
+ },
+
+
+ /*
+ * getAllLogins
+ *
+ * Get a dump of all stored logins. Used by the login manager UI.
+ *
+ * |count| is only needed for XPCOM.
+ *
+ * Returns an array of logins. If there are no logins, the array is empty.
+ */
+ getAllLogins : function (count) {
+ this.log("Getting a list of all logins");
+ return this._storage.getAllLogins(count);
+ },
+
+
+ /*
+ * removeAllLogins
+ *
+ * Remove all stored logins.
+ */
+ removeAllLogins : function () {
+ this.log("Removing all logins");
+ this._storage.removeAllLogins();
+ },
+
+ /*
+ * getAllDisabledHosts
+ *
+ * Get a list of all hosts for which logins are disabled.
+ *
+ * |count| is only needed for XPCOM.
+ *
+ * Returns an array of disabled logins. If there are no disabled logins,
+ * the array is empty.
+ */
+ getAllDisabledHosts : function (count) {
+ this.log("Getting a list of all disabled hosts");
+ return this._storage.getAllDisabledHosts(count);
+ },
+
+
+ /*
+ * findLogins
+ *
+ * Search for the known logins for entries matching the specified criteria.
+ */
+ findLogins : function (count, hostname, formSubmitURL, httpRealm) {
+ this.log("Searching for logins matching host: " + hostname +
+ ", formSubmitURL: " + formSubmitURL + ", httpRealm: " + httpRealm);
+
+ return this._storage.findLogins(count, hostname, formSubmitURL,
+ httpRealm);
+ },
+
+
+ /*
+ * searchLogins
+ *
+ * Public wrapper around _searchLogins to convert the nsIPropertyBag to a
+ * JavaScript object and decrypt the results.
+ *
+ * Returns an array of decrypted nsILoginInfo.
+ */
+ searchLogins : function(count, matchData) {
+ this.log("Searching for logins");
+
+ return this._storage.searchLogins(count, matchData);
+ },
+
+
+ /*
+ * countLogins
+ *
+ * Search for the known logins for entries matching the specified criteria,
+ * returns only the count.
+ */
+ countLogins : function (hostname, formSubmitURL, httpRealm) {
+ this.log("Counting logins matching host: " + hostname +
+ ", formSubmitURL: " + formSubmitURL + ", httpRealm: " + httpRealm);
+
+ return this._storage.countLogins(hostname, formSubmitURL, httpRealm);
+ },
+
+
+ /*
+ * getLoginSavingEnabled
+ *
+ * Check to see if user has disabled saving logins for the host.
+ */
+ getLoginSavingEnabled : function (host) {
+ this.log("Checking if logins to " + host + " can be saved.");
+ if (!this._remember)
+ return false;
+
+ return this._storage.getLoginSavingEnabled(host);
+ },
+
+
+ /*
+ * setLoginSavingEnabled
+ *
+ * Enable or disable storing logins for the specified host.
+ */
+ setLoginSavingEnabled : function (hostname, enabled) {
+ // Nulls won't round-trip with getAllDisabledHosts().
+ if (hostname.indexOf("\0") != -1)
+ throw "Invalid hostname";
+
+ this.log("Saving logins for " + hostname + " enabled? " + enabled);
+ return this._storage.setLoginSavingEnabled(hostname, enabled);
+ },
+
+
+ /*
+ * autoCompleteSearch
+ *
+ * Yuck. This is called directly by satchel:
+ * nsFormFillController::StartSearch()
+ * [toolkit/components/satchel/src/nsFormFillController.cpp]
+ *
+ * We really ought to have a simple way for code to register an
+ * auto-complete provider, and not have satchel calling pwmgr directly.
+ */
+ autoCompleteSearch : function (aSearchString, aPreviousResult, aElement) {
+ // aPreviousResult & aResult are nsIAutoCompleteResult,
+ // aElement is nsIDOMHTMLInputElement
+
+ if (!this._remember)
+ return false;
+
+ this.log("AutoCompleteSearch invoked. Search is: " + aSearchString);
+
+ var result = null;
+
+ if (aPreviousResult) {
+ this.log("Using previous autocomplete result");
+ result = aPreviousResult;
+
+ // We have a list of results for a shorter search string, so just
+ // filter them further based on the new search string.
+ // Count backwards, because result.matchCount is decremented
+ // when we remove an entry.
+ for (var i = result.matchCount - 1; i >= 0; i--) {
+ var match = result.getValueAt(i);
+
+ // Remove results that are too short, or have different prefix.
+ if (aSearchString.length > match.length ||
+ aSearchString.toLowerCase() !=
+ match.substr(0, aSearchString.length).toLowerCase())
+ {
+ this.log("Removing autocomplete entry '" + match + "'");
+ result.removeValueAt(i, false);
+ }
+ }
+ } else {
+ this.log("Creating new autocomplete search result.");
+
+ var doc = aElement.ownerDocument;
+ var origin = this._getPasswordOrigin(doc.documentURI);
+ var actionOrigin = this._getActionOrigin(aElement.form);
+
+ var logins = this.findLogins({}, origin, actionOrigin, null);
+ var matchingLogins = [];
+
+ // Filter out logins that don't match the search prefix. Also
+ // filter logins without a username, since that's confusing to see
+ // in the dropdown and we can't autocomplete them anyway.
+ for (i = 0; i < logins.length; i++) {
+ var username = logins[i].username.toLowerCase();
+ if (username &&
+ aSearchString.length <= username.length &&
+ aSearchString.toLowerCase() ==
+ username.substr(0, aSearchString.length))
+ {
+ matchingLogins.push(logins[i]);
+ }
+ }
+ this.log(matchingLogins.length + " autocomplete logins avail.");
+ result = new UserAutoCompleteResult(aSearchString, matchingLogins);
+ }
+
+ return result;
+ },
+
+
+
+
+ /* ------- Internal methods / callbacks for document integration ------- */
+
+
+
+
+ /*
+ * _getPasswordFields
+ *
+ * Returns an array of password field elements for the specified form.
+ * If no pw fields are found, or if more than 3 are found, then null
+ * is returned.
+ *
+ * skipEmptyFields can be set to ignore password fields with no value.
+ */
+ _getPasswordFields : function (form, skipEmptyFields) {
+ // Locate the password fields in the form.
+ var pwFields = [];
+ for (var i = 0; i < form.elements.length; i++) {
+ var element = form.elements[i];
+ if (!(element instanceof Ci.nsIDOMHTMLInputElement) ||
+ element.type != "password")
+ continue;
+
+ if (skipEmptyFields && !element.value)
+ continue;
+
+ pwFields[pwFields.length] = {
+ index : i,
+ element : element
+ };
+ }
+
+ // If too few or too many fields, bail out.
+ if (pwFields.length == 0) {
+ this.log("(form ignored -- no password fields.)");
+ return null;
+ } else if (pwFields.length > 3) {
+ this.log("(form ignored -- too many password fields. [got " +
+ pwFields.length + "])");
+ return null;
+ }
+
+ return pwFields;
+ },
+
+
+ /*
+ * _getFormFields
+ *
+ * Returns the username and password fields found in the form.
+ * Can handle complex forms by trying to figure out what the
+ * relevant fields are.
+ *
+ * Returns: [usernameField, newPasswordField, oldPasswordField]
+ *
+ * usernameField may be null.
+ * newPasswordField will always be non-null.
+ * oldPasswordField may be null. If null, newPasswordField is just
+ * "theLoginField". If not null, the form is apparently a
+ * change-password field, with oldPasswordField containing the password
+ * that is being changed.
+ */
+ _getFormFields : function (form, isSubmission) {
+ var usernameField = null;
+
+ // Locate the password field(s) in the form. Up to 3 supported.
+ // If there's no password field, there's nothing for us to do.
+ var pwFields = this._getPasswordFields(form, isSubmission);
+ if (!pwFields)
+ return [null, null, null];
+
+
+ // Locate the username field in the form by searching backwards
+ // from the first passwordfield, assume the first text field is the
+ // username. We might not find a username field if the user is
+ // already logged in to the site.
+ for (var i = pwFields[0].index - 1; i >= 0; i--) {
+ if (form.elements[i].type == "text") {
+ usernameField = form.elements[i];
+ break;
+ }
+ }
+
+ if (!usernameField)
+ this.log("(form -- no username field found)");
+
+
+ // If we're not submitting a form (it's a page load), there are no
+ // password field values for us to use for identifying fields. So,
+ // just assume the first password field is the one to be filled in.
+ if (!isSubmission || pwFields.length == 1)
+ return [usernameField, pwFields[0].element, null];
+
+
+ // Try to figure out WTF is in the form based on the password values.
+ var oldPasswordField, newPasswordField;
+ var pw1 = pwFields[0].element.value;
+ var pw2 = pwFields[1].element.value;
+ var pw3 = (pwFields[2] ? pwFields[2].element.value : null);
+
+ if (pwFields.length == 3) {
+ // Look for two identical passwords, that's the new password
+
+ if (pw1 == pw2 && pw2 == pw3) {
+ // All 3 passwords the same? Weird! Treat as if 1 pw field.
+ newPasswordField = pwFields[0].element;
+ oldPasswordField = null;
+ } else if (pw1 == pw2) {
+ newPasswordField = pwFields[0].element;
+ oldPasswordField = pwFields[2].element;
+ } else if (pw2 == pw3) {
+ oldPasswordField = pwFields[0].element;
+ newPasswordField = pwFields[2].element;
+ } else if (pw1 == pw3) {
+ // A bit odd, but could make sense with the right page layout.
+ newPasswordField = pwFields[0].element;
+ oldPasswordField = pwFields[1].element;
+ } else {
+ // We can't tell which of the 3 passwords should be saved.
+ this.log("(form ignored -- all 3 pw fields differ)");
+ return [null, null, null];
+ }
+ } else { // pwFields.length == 2
+ if (pw1 == pw2) {
+ // Treat as if 1 pw field
+ newPasswordField = pwFields[0].element;
+ oldPasswordField = null;
+ } else {
+ // Just assume that the 2nd password is the new password
+ oldPasswordField = pwFields[0].element;
+ newPasswordField = pwFields[1].element;
+ }
+ }
+
+ return [usernameField, newPasswordField, oldPasswordField];
+ },
+
+
+ /*
+ * _isAutoCompleteDisabled
+ *
+ * Returns true if the page requests autocomplete be disabled for the
+ * specified form input.
+ */
+ _isAutocompleteDisabled : function (element) {
+ if (element && element.hasAttribute("autocomplete") &&
+ element.getAttribute("autocomplete").toLowerCase() == "off")
+ return true;
+
+ return false;
+ },
+
+ /*
+ * _onFormSubmit
+ *
+ * Called by the our observer when notified of a form submission.
+ * [Note that this happens before any DOM onsubmit handlers are invoked.]
+ * Looks for a password change in the submitted form, so we can update
+ * our stored password.
+ */
+ _onFormSubmit : function (form) {
+
+ // local helper function
+ function getPrompter(aWindow) {
+ var prompterSvc = Cc["@mozilla.org/login-manager/prompter;1"].
+ createInstance(Ci.nsILoginManagerPrompter);
+ prompterSvc.init(aWindow);
+ return prompterSvc;
+ }
+
+ if (this._inPrivateBrowsing) {
+ // We won't do anything in private browsing mode anyway,
+ // so there's no need to perform further checks.
+ this.log("(form submission ignored in private browsing mode)");
+ return;
+ }
+
+ var doc = form.ownerDocument;
+ var win = doc.defaultView;
+
+ // If password saving is disabled (globally or for host), bail out now.
+ if (!this._remember)
+ return;
+
+ var hostname = this._getPasswordOrigin(doc.documentURI);
+ var formSubmitURL = this._getActionOrigin(form)
+ if (!this.getLoginSavingEnabled(hostname)) {
+ this.log("(form submission ignored -- saving is " +
+ "disabled for: " + hostname + ")");
+ return;
+ }
+
+
+ // Get the appropriate fields from the form.
+ var [usernameField, newPasswordField, oldPasswordField] =
+ this._getFormFields(form, true);
+
+ // Need at least 1 valid password field to do anything.
+ if (newPasswordField == null)
+ return;
+
+ // Check for autocomplete=off attribute. We don't use it to prevent
+ // autofilling (for existing logins), but won't save logins when it's
+ // present.
+ if (this._isAutocompleteDisabled(form) ||
+ this._isAutocompleteDisabled(usernameField) ||
+ this._isAutocompleteDisabled(newPasswordField) ||
+ this._isAutocompleteDisabled(oldPasswordField)) {
+ this.log("(form submission ignored -- autocomplete=off found)");
+ return;
+ }
+
+
+ var formLogin = new this._nsLoginInfo();
+ formLogin.init(hostname, formSubmitURL, null,
+ (usernameField ? usernameField.value : ""),
+ newPasswordField.value,
+ (usernameField ? usernameField.name : ""),
+ newPasswordField.name);
+
+ // If we didn't find a username field, but seem to be changing a
+ // password, allow the user to select from a list of applicable
+ // logins to update the password for.
+ if (!usernameField && oldPasswordField) {
+
+ var logins = this.findLogins({}, hostname, formSubmitURL, null);
+
+ if (logins.length == 0) {
+ // Could prompt to save this as a new password-only login.
+ // This seems uncommon, and might be wrong, so ignore.
+ this.log("(no logins for this host -- pwchange ignored)");
+ return;
+ }
+
+ var prompter = getPrompter(win);
+
+ if (logins.length == 1) {
+ var oldLogin = logins[0];
+ formLogin.username = oldLogin.username;
+ formLogin.usernameField = oldLogin.usernameField;
+
+ prompter.promptToChangePassword(oldLogin, formLogin);
+ } else {
+ prompter.promptToChangePasswordWithUsernames(
+ logins, logins.length, formLogin);
+ }
+
+ return;
+ }
+
+
+ // Look for an existing login that matches the form login.
+ var existingLogin = null;
+ var logins = this.findLogins({}, hostname, formSubmitURL, null);
+
+ for (var i = 0; i < logins.length; i++) {
+ var same, login = logins[i];
+
+ // If one login has a username but the other doesn't, ignore
+ // the username when comparing and only match if they have the
+ // same password. Otherwise, compare the logins and match even
+ // if the passwords differ.
+ if (!login.username && formLogin.username) {
+ var restoreMe = formLogin.username;
+ formLogin.username = "";
+ same = formLogin.matches(login, false);
+ formLogin.username = restoreMe;
+ } else if (!formLogin.username && login.username) {
+ formLogin.username = login.username;
+ same = formLogin.matches(login, false);
+ formLogin.username = ""; // we know it's always blank.
+ } else {
+ same = formLogin.matches(login, true);
+ }
+
+ if (same) {
+ existingLogin = login;
+ break;
+ }
+ }
+
+ if (existingLogin) {
+ this.log("Found an existing login matching this form submission");
+
+ // Change password if needed.
+ if (existingLogin.password != formLogin.password) {
+ this.log("...passwords differ, prompting to change.");
+ prompter = getPrompter(win);
+ prompter.promptToChangePassword(existingLogin, formLogin);
+ }
+
+ return;
+ }
+
+
+ // Prompt user to save login (via dialog or notification bar)
+ prompter = getPrompter(win);
+ prompter.promptToSavePassword(formLogin);
+ },
+
+
+ /*
+ * _getPasswordOrigin
+ *
+ * Get the parts of the URL we want for identification.
+ */
+ _getPasswordOrigin : function (uriString, allowJS) {
+ var realm = "";
+ try {
+ var uri = this._ioService.newURI(uriString, null, null);
+
+ if (allowJS && uri.scheme == "javascript")
+ return "javascript:"
+
+ realm = uri.scheme + "://" + uri.host;
+
+ // If the URI explicitly specified a port, only include it when
+ // it's not the default. (We never want "http://foo.com:80")
+ var port = uri.port;
+ if (port != -1) {
+ var handler = this._ioService.getProtocolHandler(uri.scheme);
+ if (port != handler.defaultPort)
+ realm += ":" + port;
+ }
+
+ } catch (e) {
+ // bug 159484 - disallow url types that don't support a hostPort.
+ // (although we handle "javascript:..." as a special case above.)
+ this.log("Couldn't parse origin for " + uriString);
+ realm = null;
+ }
+
+ return realm;
+ },
+
+ _getActionOrigin : function (form) {
+ var uriString = form.action;
+
+ // A blank or mission action submits to where it came from.
+ if (uriString == "")
+ uriString = form.baseURI; // ala bug 297761
+
+ return this._getPasswordOrigin(uriString, true);
+ },
+
+
+ /*
+ * _fillDocument
+ *
+ * Called when a page has loaded. For each form in the document,
+ * we check to see if it can be filled with a stored login.
+ */
+ _fillDocument : function (doc) {
+ var forms = doc.forms;
+ if (!forms || forms.length == 0)
+ return;
+
+ var formOrigin = this._getPasswordOrigin(doc.documentURI);
+
+ // If there are no logins for this site, bail out now.
+ if (!this.countLogins(formOrigin, "", null))
+ return;
+
+ this.log("fillDocument processing " + forms.length +
+ " forms on " + doc.documentURI);
+
+ var autofillForm = !this._inPrivateBrowsing &&
+ this._prefBranch.getBoolPref("autofillForms");
+ var previousActionOrigin = null;
+ var foundLogins = null;
+
+ for (var i = 0; i < forms.length; i++) {
+ var form = forms[i];
+
+ // Only the actionOrigin might be changing, so if it's the same
+ // as the last form on the page we can reuse the same logins.
+ var actionOrigin = this._getActionOrigin(form);
+ if (actionOrigin != previousActionOrigin) {
+ foundLogins = null;
+ previousActionOrigin = actionOrigin;
+ }
+ this.log("_fillDocument processing form[" + i + "]");
+ foundLogins = this._fillForm(form, autofillForm, false, foundLogins)[1];
+ } // foreach form
+ },
+
+
+ /*
+ * _fillform
+ *
+ * Fill the form with login information if we can find it. This will find
+ * an array of logins if not given any, otherwise it will use the logins
+ * passed in. The logins are returned so they can be reused for
+ * optimization. Success of action is also returned in format
+ * [success, foundLogins]. autofillForm denotes if we should fill the form
+ * in automatically, ignoreAutocomplete denotes if we should ignore
+ * autocomplete=off attributes, and foundLogins is an array of nsILoginInfo
+ * for optimization
+ */
+ _fillForm : function (form, autofillForm, ignoreAutocomplete, foundLogins) {
+ // Heuristically determine what the user/pass fields are
+ // We do this before checking to see if logins are stored,
+ // so that the user isn't prompted for a master password
+ // without need.
+ var [usernameField, passwordField, ignored] =
+ this._getFormFields(form, false);
+
+ // Need a valid password field to do anything.
+ if (passwordField == null)
+ return [false, foundLogins];
+
+ // If the fields are disabled or read-only, there's nothing to do.
+ if (passwordField.disabled || passwordField.readOnly ||
+ usernameField && (usernameField.disabled ||
+ usernameField.readOnly)) {
+ this.log("not filling form, login fields disabled");
+ return [false, foundLogins];
+ }
+
+ // Need to get a list of logins if we weren't given them
+ if (foundLogins == null) {
+ var formOrigin =
+ this._getPasswordOrigin(form.ownerDocument.documentURI);
+ var actionOrigin = this._getActionOrigin(form);
+ foundLogins = this.findLogins({}, formOrigin, actionOrigin, null);
+ this.log("found " + foundLogins.length + " matching logins.");
+ } else {
+ this.log("reusing logins from last form.");
+ }
+
+ // Discard logins which have username/password values that don't
+ // fit into the fields (as specified by the maxlength attribute).
+ // The user couldn't enter these values anyway, and it helps
+ // with sites that have an extra PIN to be entered (bug 391514)
+ var maxUsernameLen = Number.MAX_VALUE;
+ var maxPasswordLen = Number.MAX_VALUE;
+
+ // If attribute wasn't set, default is -1.
+ if (usernameField && usernameField.maxLength >= 0)
+ maxUsernameLen = usernameField.maxLength;
+ if (passwordField.maxLength >= 0)
+ maxPasswordLen = passwordField.maxLength;
+
+ var logins = foundLogins.filter(function (l) {
+ var fit = (l.username.length <= maxUsernameLen &&
+ l.password.length <= maxPasswordLen);
+ if (!fit)
+ this.log("Ignored " + l.username + " login: won't fit");
+
+ return fit;
+ }, this);
+
+
+ // Nothing to do if we have no matching logins available.
+ if (logins.length == 0)
+ return [false, foundLogins];
+
+
+ // The reason we didn't end up filling the form, if any. We include
+ // this in the formInfo object we send with the passwordmgr-found-logins
+ // notification. See the _notifyFoundLogins docs for possible values.
+ var didntFillReason = null;
+
+ // Attach autocomplete stuff to the username field, if we have
+ // one. This is normally used to select from multiple accounts,
+ // but even with one account we should refill if the user edits.
+ if (usernameField)
+ this._attachToInput(usernameField);
+
+ // Don't clobber an existing password.
+ if (passwordField.value) {
+ didntFillReason = "existingPassword";
+ this._notifyFoundLogins(didntFillReason, usernameField,
+ passwordField, foundLogins, null);
+ return [false, foundLogins];
+ }
+
+ // If the form has an autocomplete=off attribute in play, don't
+ // fill in the login automatically. We check this after attaching
+ // the autocomplete stuff to the username field, so the user can
+ // still manually select a login to be filled in.
+ var isFormDisabled = false;
+ if (!ignoreAutocomplete &&
+ (this._isAutocompleteDisabled(form) ||
+ this._isAutocompleteDisabled(usernameField) ||
+ this._isAutocompleteDisabled(passwordField))) {
+
+ isFormDisabled = true;
+ this.log("form not filled, has autocomplete=off");
+ }
+
+ // Variable such that we reduce code duplication and can be sure we
+ // should be firing notifications if and only if we can fill the form.
+ var selectedLogin = null;
+
+ if (usernameField && usernameField.value) {
+ // If username was specified in the form, only fill in the
+ // password if we find a matching login.
+ var username = usernameField.value.toLowerCase();
+
+ let matchingLogins = logins.filter(function(l)
+ l.username.toLowerCase() == username);
+ if (matchingLogins.length) {
+ selectedLogin = matchingLogins[0];
+ } else {
+ didntFillReason = "existingUsername";
+ this.log("Password not filled. None of the stored " +
+ "logins match the username already present.");
+ }
+ } else if (logins.length == 1) {
+ selectedLogin = logins[0];
+ } else {
+ // We have multiple logins. Handle a special case here, for sites
+ // which have a normal user+pass login *and* a password-only login
+ // (eg, a PIN). Prefer the login that matches the type of the form
+ // (user+pass or pass-only) when there's exactly one that matches.
+ let matchingLogins;
+ if (usernameField)
+ matchingLogins = logins.filter(function(l) l.username);
+ else
+ matchingLogins = logins.filter(function(l) !l.username);
+ if (matchingLogins.length == 1) {
+ selectedLogin = matchingLogins[0];
+ } else {
+ didntFillReason = "multipleLogins";
+ this.log("Multiple logins for form, so not filling any.");
+ }
+ }
+
+ var didFillForm = false;
+ if (selectedLogin && autofillForm && !isFormDisabled) {
+ // Fill the form
+ if (usernameField)
+ usernameField.value = selectedLogin.username;
+ passwordField.value = selectedLogin.password;
+ didFillForm = true;
+ } else if (selectedLogin && !autofillForm) {
+ // For when autofillForm is false, but we still have the information
+ // to fill a form, we notify observers.
+ didntFillReason = "noAutofillForms";
+ this._observerService.notifyObservers(form, "passwordmgr-found-form", didntFillReason);
+ this.log("autofillForms=false but form can be filled; notified observers");
+ } else if (selectedLogin && isFormDisabled) {
+ // For when autocomplete is off, but we still have the information
+ // to fill a form, we notify observers.
+ didntFillReason = "autocompleteOff";
+ this._observerService.notifyObservers(form, "passwordmgr-found-form", didntFillReason);
+ this.log("autocomplete=off but form can be filled; notified observers");
+ }
+
+ this._notifyFoundLogins(didntFillReason, usernameField, passwordField,
+ foundLogins, selectedLogin);
+
+ return [didFillForm, foundLogins];
+ },
+
+ /**
+ * Notify observers about an attempt to fill a form that resulted in some
+ * saved logins being found for the form.
+ *
+ * This does not get called if the login manager attempts to fill a form
+ * but does not find any saved logins. It does, however, get called when
+ * the login manager does find saved logins whether or not it actually
+ * fills the form with one of them.
+ *
+ * @param didntFillReason {String}
+ * the reason the login manager didn't fill the form, if any;
+ * if the value of this parameter is null, then the form was filled;
+ * otherwise, this parameter will be one of these values:
+ * existingUsername: the username field already contains a username
+ * that doesn't match any stored usernames
+ * existingPassword: the password field already contains a password
+ * autocompleteOff: autocomplete has been disabled for the form
+ * or its username or password fields
+ * multipleLogins: we have multiple logins for the form
+ * noAutofillForms: the autofillForms pref is set to false
+ *
+ * @param usernameField {HTMLInputElement}
+ * the username field detected by the login manager, if any;
+ * otherwise null
+ *
+ * @param passwordField {HTMLInputElement}
+ * the password field detected by the login manager
+ *
+ * @param foundLogins {Array}
+ * an array of nsILoginInfos that can be used to fill the form
+ *
+ * @param selectedLogin {nsILoginInfo}
+ * the nsILoginInfo that was/would be used to fill the form, if any;
+ * otherwise null; whether or not it was actually used depends on
+ * the value of the didntFillReason parameter
+ */
+ _notifyFoundLogins : function (didntFillReason, usernameField,
+ passwordField, foundLogins, selectedLogin) {
+ let formInfo = Cc["@mozilla.org/hash-property-bag;1"].
+ createInstance(Ci.nsIWritablePropertyBag2);
+
+ formInfo.setPropertyAsACString("didntFillReason", didntFillReason);
+ formInfo.setPropertyAsInterface("usernameField", usernameField);
+ formInfo.setPropertyAsInterface("passwordField", passwordField);
+ formInfo.setPropertyAsInterface("foundLogins", foundLogins.concat());
+ formInfo.setPropertyAsInterface("selectedLogin", selectedLogin);
+
+ this._observerService.notifyObservers(formInfo,
+ "passwordmgr-found-logins",
+ null);
+ },
+
+ /*
+ * fillForm
+ *
+ * Fill the form with login information if we can find it.
+ */
+ fillForm : function (form) {
+ this.log("fillForm processing form[id=" + form.id + "]");
+ return this._fillForm(form, true, true, null)[0];
+ },
+
+
+ /*
+ * _attachToInput
+ *
+ * Hooks up autocomplete support to a username field, to allow
+ * a user editing the field to select an existing login and have
+ * the password field filled in.
+ */
+ _attachToInput : function (element) {
+ this.log("attaching autocomplete stuff");
+ element.addEventListener("blur",
+ this._domEventListener, false);
+ element.addEventListener("DOMAutoComplete",
+ this._domEventListener, false);
+ this._formFillService.markAsLoginManagerField(element);
+ }
+}; // end of LoginManager implementation
+
+
+
+
+// nsIAutoCompleteResult implementation
+function UserAutoCompleteResult (aSearchString, matchingLogins) {
+ function loginSort(a,b) {
+ var userA = a.username.toLowerCase();
+ var userB = b.username.toLowerCase();
+
+ if (userA < userB)
+ return -1;
+
+ if (userB > userA)
+ return 1;
+
+ return 0;
+ };
+
+ this.searchString = aSearchString;
+ this.logins = matchingLogins.sort(loginSort);
+ this.matchCount = matchingLogins.length;
+
+ if (this.matchCount > 0) {
+ this.searchResult = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
+ this.defaultIndex = 0;
+ }
+}
+
+UserAutoCompleteResult.prototype = {
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsIAutoCompleteResult,
+ Ci.nsISupportsWeakReference]),
+
+ // private
+ logins : null,
+
+ // Interfaces from idl...
+ searchString : null,
+ searchResult : Ci.nsIAutoCompleteResult.RESULT_NOMATCH,
+ defaultIndex : -1,
+ errorDescription : "",
+ matchCount : 0,
+
+ getValueAt : function (index) {
+ if (index < 0 || index >= this.logins.length)
+ throw "Index out of range.";
+
+ return this.logins[index].username;
+ },
+
+ getCommentAt : function (index) {
+ return "";
+ },
+
+ getStyleAt : function (index) {
+ return "";
+ },
+
+ getImageAt : function (index) {
+ return "";
+ },
+
+ removeValueAt : function (index, removeFromDB) {
+ if (index < 0 || index >= this.logins.length)
+ throw "Index out of range.";
+
+ var [removedLogin] = this.logins.splice(index, 1);
+
+ this.matchCount--;
+ if (this.defaultIndex > this.logins.length)
+ this.defaultIndex--;
+
+ if (removeFromDB) {
+ var pwmgr = Cc["@mozilla.org/login-manager;1"].
+ getService(Ci.nsILoginManager);
+ pwmgr.removeLogin(removedLogin);
+ }
+ }
+};
+
+var component = [LoginManager];
+function NSGetModule (compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(component);
+}
diff --git a/bundles/XO/components/nsLoginManagerPrompter.js b/bundles/XO/components/nsLoginManagerPrompter.js
new file mode 100755
index 0000000..4af1738
--- /dev/null
+++ b/bundles/XO/components/nsLoginManagerPrompter.js
@@ -0,0 +1,1229 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Dolske <dolske@mozilla.com> (original author)
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+/*
+ * LoginManagerPromptFactory
+ *
+ * Implements nsIPromptFactory
+ *
+ * Invoked by NS_NewAuthPrompter2()
+ * [embedding/components/windowwatcher/src/nsPrompt.cpp]
+ */
+function LoginManagerPromptFactory() {}
+
+LoginManagerPromptFactory.prototype = {
+
+ classDescription : "LoginManagerPromptFactory",
+ contractID : "@mozilla.org/passwordmanager/authpromptfactory;1",
+ classID : Components.ID("{749e62f4-60ae-4569-a8a2-de78b649660e}"),
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsIPromptFactory]),
+
+ getPrompt : function (aWindow, aIID) {
+ var prompt = new LoginManagerPrompter().QueryInterface(aIID);
+ prompt.init(aWindow);
+ return prompt;
+ }
+}; // end of LoginManagerPromptFactory implementation
+
+
+
+
+/* ==================== LoginManagerPrompter ==================== */
+
+
+
+
+/*
+ * LoginManagerPrompter
+ *
+ * Implements interfaces for prompting the user to enter/save/change auth info.
+ *
+ * nsIAuthPrompt: Used by SeaMonkey, Thunderbird, but not Firefox.
+ *
+ * nsIAuthPrompt2: Is invoked by a channel for protocol-based authentication
+ * (eg HTTP Authenticate, FTP login).
+ *
+ * nsILoginManagerPrompter: Used by Login Manager for saving/changing logins
+ * found in HTML forms.
+ */
+function LoginManagerPrompter() {}
+
+LoginManagerPrompter.prototype = {
+
+ classDescription : "LoginManagerPrompter",
+ contractID : "@mozilla.org/login-manager/prompter;1",
+ classID : Components.ID("{8aa66d77-1bbb-45a6-991e-b8f47751c291}"),
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsIAuthPrompt,
+ Ci.nsIAuthPrompt2,
+ Ci.nsILoginManagerPrompter]),
+
+ _window : null,
+ _debug : false, // mirrors signon.debug
+
+ __pwmgr : null, // Password Manager service
+ get _pwmgr() {
+ if (!this.__pwmgr)
+ this.__pwmgr = Cc["@mozilla.org/login-manager;1"].
+ getService(Ci.nsILoginManager);
+ return this.__pwmgr;
+ },
+
+ __logService : null, // Console logging service, used for debugging.
+ get _logService() {
+ if (!this.__logService)
+ this.__logService = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ return this.__logService;
+ },
+
+ __promptService : null, // Prompt service for user interaction
+ get _promptService() {
+ if (!this.__promptService)
+ this.__promptService =
+ Cc["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Ci.nsIPromptService2);
+ return this.__promptService;
+ },
+
+
+ __strBundle : null, // String bundle for L10N
+ get _strBundle() {
+ if (!this.__strBundle) {
+ var bunService = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ this.__strBundle = bunService.createBundle(
+ "chrome://passwordmgr/locale/passwordmgr.properties");
+ if (!this.__strBundle)
+ throw "String bundle for Login Manager not present!";
+ }
+
+ return this.__strBundle;
+ },
+
+
+ __brandBundle : null, // String bundle for L10N
+ get _brandBundle() {
+ if (!this.__brandBundle) {
+ var bunService = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ this.__brandBundle = bunService.createBundle(
+ "chrome://branding/locale/brand.properties");
+ if (!this.__brandBundle)
+ throw "Branding string bundle not present!";
+ }
+
+ return this.__brandBundle;
+ },
+
+
+ __ioService: null, // IO service for string -> nsIURI conversion
+ get _ioService() {
+ if (!this.__ioService)
+ this.__ioService = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__ioService;
+ },
+
+
+ __ellipsis : null,
+ get _ellipsis() {
+ if (!this.__ellipsis) {
+ this.__ellipsis = "\u2026";
+ try {
+ var prefSvc = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ this.__ellipsis = prefSvc.getComplexValue("intl.ellipsis",
+ Ci.nsIPrefLocalizedString).data;
+ } catch (e) { }
+ }
+ return this.__ellipsis;
+ },
+
+
+ // Whether we are in private browsing mode
+ get _inPrivateBrowsing() {
+ // The Private Browsing service might not be available.
+ try {
+ var pbs = Cc["@mozilla.org/privatebrowsing;1"].
+ getService(Ci.nsIPrivateBrowsingService);
+ return pbs.privateBrowsingEnabled;
+ } catch (e) {
+ return false;
+ }
+ },
+
+
+ /*
+ * log
+ *
+ * Internal function for logging debug messages to the Error Console window.
+ */
+ log : function (message) {
+ if (!this._debug)
+ return;
+
+ dump("Pwmgr Prompter: " + message + "\n");
+ this._logService.logStringMessage("Pwmgr Prompter: " + message);
+ },
+
+
+
+
+ /* ---------- nsIAuthPrompt prompts ---------- */
+
+
+ /*
+ * prompt
+ *
+ * Wrapper around the prompt service prompt. Saving random fields here
+ * doesn't really make sense and therefore isn't implemented.
+ */
+ prompt : function (aDialogTitle, aText, aPasswordRealm,
+ aSavePassword, aDefaultText, aResult) {
+ if (aSavePassword != Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER)
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ this.log("===== prompt() called =====");
+
+ if (aDefaultText) {
+ aResult.value = aDefaultText;
+ }
+
+ return this._promptService.prompt(this._window,
+ aDialogTitle, aText, aResult, null, {});
+ },
+
+
+ /*
+ * promptUsernameAndPassword
+ *
+ * Looks up a username and password in the database. Will prompt the user
+ * with a dialog, even if a username and password are found.
+ */
+ promptUsernameAndPassword : function (aDialogTitle, aText, aPasswordRealm,
+ aSavePassword, aUsername, aPassword) {
+ this.log("===== promptUsernameAndPassword() called =====");
+
+ if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ var selectedLogin = null;
+ var checkBox = { value : false };
+ var checkBoxLabel = null;
+ var [hostname, realm, unused] = this._getRealmInfo(aPasswordRealm);
+
+ // If hostname is null, we can't save this login.
+ if (hostname) {
+ var canRememberLogin;
+ if (this._inPrivateBrowsing)
+ canRememberLogin = false;
+ else
+ canRememberLogin = (aSavePassword ==
+ Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) &&
+ this._pwmgr.getLoginSavingEnabled(hostname);
+
+ // if checkBoxLabel is null, the checkbox won't be shown at all.
+ if (canRememberLogin)
+ checkBoxLabel = this._getLocalizedString("rememberPassword");
+
+ // Look for existing logins.
+ var foundLogins = this._pwmgr.findLogins({}, hostname, null,
+ realm);
+
+ // XXX Like the original code, we can't deal with multiple
+ // account selection. (bug 227632)
+ if (foundLogins.length > 0) {
+ selectedLogin = foundLogins[0];
+
+ // If the caller provided a username, try to use it. If they
+ // provided only a password, this will try to find a password-only
+ // login (or return null if none exists).
+ if (aUsername.value)
+ selectedLogin = this._repickSelectedLogin(foundLogins,
+ aUsername.value);
+
+ if (selectedLogin) {
+ checkBox.value = true;
+ aUsername.value = selectedLogin.username;
+ // If the caller provided a password, prefer it.
+ if (!aPassword.value)
+ aPassword.value = selectedLogin.password;
+ }
+ }
+ }
+
+ var ok = this._promptService.promptUsernameAndPassword(this._window,
+ aDialogTitle, aText, aUsername, aPassword,
+ checkBoxLabel, checkBox);
+
+ if (!ok || !checkBox.value || !hostname)
+ return ok;
+
+ if (!aPassword.value) {
+ this.log("No password entered, so won't offer to save.");
+ return ok;
+ }
+
+ var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
+ createInstance(Ci.nsILoginInfo);
+ newLogin.init(hostname, null, realm, aUsername.value, aPassword.value,
+ "", "");
+
+ // XXX We can't prompt with multiple logins yet (bug 227632), so
+ // the entered login might correspond to an existing login
+ // other than the one we originally selected.
+ selectedLogin = this._repickSelectedLogin(foundLogins, aUsername.value);
+
+ // If we didn't find an existing login, or if the username
+ // changed, save as a new login.
+ if (!selectedLogin) {
+ // add as new
+ this.log("New login seen for " + realm);
+ this._pwmgr.addLogin(newLogin);
+ } else if (aPassword.value != selectedLogin.password) {
+ // update password
+ this.log("Updating password for " + realm);
+ this._pwmgr.modifyLogin(selectedLogin, newLogin);
+ } else {
+ this.log("Login unchanged, no further action needed.");
+ }
+
+ return ok;
+ },
+
+
+ /*
+ * promptPassword
+ *
+ * If a password is found in the database for the password realm, it is
+ * returned straight away without displaying a dialog.
+ *
+ * If a password is not found in the database, the user will be prompted
+ * with a dialog with a text field and ok/cancel buttons. If the user
+ * allows it, then the password will be saved in the database.
+ */
+ promptPassword : function (aDialogTitle, aText, aPasswordRealm,
+ aSavePassword, aPassword) {
+ this.log("===== promptPassword called() =====");
+
+ if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ var checkBox = { value : false };
+ var checkBoxLabel = null;
+ var [hostname, realm, username] = this._getRealmInfo(aPasswordRealm);
+
+ username = decodeURIComponent(username);
+
+ // If hostname is null, we can't save this login.
+ if (hostname && !this._inPrivateBrowsing) {
+ var canRememberLogin = (aSavePassword ==
+ Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) &&
+ this._pwmgr.getLoginSavingEnabled(hostname);
+
+ // if checkBoxLabel is null, the checkbox won't be shown at all.
+ if (canRememberLogin)
+ checkBoxLabel = this._getLocalizedString("rememberPassword");
+
+ if (!aPassword.value) {
+ // Look for existing logins.
+ var foundLogins = this._pwmgr.findLogins({}, hostname, null,
+ realm);
+
+ // XXX Like the original code, we can't deal with multiple
+ // account selection (bug 227632). We can deal with finding the
+ // account based on the supplied username - but in this case we'll
+ // just return the first match.
+ for (var i = 0; i < foundLogins.length; ++i) {
+ if (foundLogins[i].username == username) {
+ aPassword.value = foundLogins[i].password;
+ // wallet returned straight away, so this mimics that code
+ return true;
+ }
+ }
+ }
+ }
+
+ var ok = this._promptService.promptPassword(this._window, aDialogTitle,
+ aText, aPassword,
+ checkBoxLabel, checkBox);
+
+ if (ok && checkBox.value && hostname && aPassword.value) {
+ var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
+ createInstance(Ci.nsILoginInfo);
+ newLogin.init(hostname, null, realm, username,
+ aPassword.value, "", "");
+
+ this.log("New login seen for " + realm);
+
+ this._pwmgr.addLogin(newLogin);
+ }
+
+ return ok;
+ },
+
+ /* ---------- nsIAuthPrompt helpers ---------- */
+
+
+ /**
+ * Given aRealmString, such as "http://user@example.com/foo", returns an
+ * array of:
+ * - the formatted hostname
+ * - the realm (hostname + path)
+ * - the username, if present
+ *
+ * If aRealmString is in the format produced by NS_GetAuthKey for HTTP[S]
+ * channels, e.g. "example.com:80 (httprealm)", null is returned for all
+ * arguments to let callers know the login can't be saved because we don't
+ * know whether it's http or https.
+ */
+ _getRealmInfo : function (aRealmString) {
+ var httpRealm = /^.+ \(.+\)$/;
+ if (httpRealm.test(aRealmString))
+ return [null, null, null];
+
+ var uri = this._ioService.newURI(aRealmString, null, null);
+ var pathname = "";
+
+ if (uri.path != "/")
+ pathname = uri.path;
+
+ var formattedHostname = this._getFormattedHostname(uri);
+
+ return [formattedHostname, formattedHostname + pathname, uri.username];
+ },
+
+ /* ---------- nsIAuthPrompt2 prompts ---------- */
+
+
+
+
+ /*
+ * promptAuth
+ *
+ * Implementation of nsIAuthPrompt2.
+ *
+ * nsIChannel aChannel
+ * int aLevel
+ * nsIAuthInformation aAuthInfo
+ */
+ promptAuth : function (aChannel, aLevel, aAuthInfo) {
+ var selectedLogin = null;
+ var checkbox = { value : false };
+ var checkboxLabel = null;
+ var epicfail = false;
+
+ try {
+
+ this.log("===== promptAuth called =====");
+
+ // If the user submits a login but it fails, we need to remove the
+ // notification bar that was displayed. Conveniently, the user will
+ // be prompted for authentication again, which brings us here.
+ var notifyBox = this._getNotifyBox();
+ if (notifyBox)
+ this._removeLoginNotifications(notifyBox);
+
+ var [hostname, httpRealm] = this._getAuthTarget(aChannel, aAuthInfo);
+
+
+ // Looks for existing logins to prefill the prompt with.
+ var foundLogins = this._pwmgr.findLogins({},
+ hostname, null, httpRealm);
+ this.log("found " + foundLogins.length + " matching logins.");
+
+ // XXX Can't select from multiple accounts yet. (bug 227632)
+ if (foundLogins.length > 0) {
+ selectedLogin = foundLogins[0];
+ this._SetAuthInfo(aAuthInfo, selectedLogin.username,
+ selectedLogin.password);
+ checkbox.value = true;
+ }
+
+ var canRememberLogin = this._pwmgr.getLoginSavingEnabled(hostname);
+ if (this._inPrivateBrowsing)
+ canRememberLogin = false;
+
+ // if checkboxLabel is null, the checkbox won't be shown at all.
+ if (canRememberLogin && !notifyBox)
+ checkboxLabel = this._getLocalizedString("rememberPassword");
+ } catch (e) {
+ // Ignore any errors and display the prompt anyway.
+ epicfail = true;
+ Components.utils.reportError("LoginManagerPrompter: " +
+ "Epic fail in promptAuth: " + e + "\n");
+ }
+
+ var ok = this._promptService.promptAuth(this._window, aChannel,
+ aLevel, aAuthInfo, checkboxLabel, checkbox);
+
+ // If there's a notification box, use it to allow the user to
+ // determine if the login should be saved. If there isn't a
+ // notification box, only save the login if the user set the
+ // checkbox to do so.
+ var rememberLogin = notifyBox ? canRememberLogin : checkbox.value;
+ if (!ok || !rememberLogin || epicfail)
+ return ok;
+
+ try {
+ var [username, password] = this._GetAuthInfo(aAuthInfo);
+
+ if (!password) {
+ this.log("No password entered, so won't offer to save.");
+ return ok;
+ }
+
+ var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
+ createInstance(Ci.nsILoginInfo);
+ newLogin.init(hostname, null, httpRealm,
+ username, password, "", "");
+
+ // XXX We can't prompt with multiple logins yet (bug 227632), so
+ // the entered login might correspond to an existing login
+ // other than the one we originally selected.
+ selectedLogin = this._repickSelectedLogin(foundLogins, username);
+
+ // If we didn't find an existing login, or if the username
+ // changed, save as a new login.
+ if (!selectedLogin) {
+ // add as new
+ this.log("New login seen for " + username +
+ " @ " + hostname + " (" + httpRealm + ")");
+ if (notifyBox)
+ this._showSaveLoginNotification(notifyBox, newLogin);
+ else
+ this._pwmgr.addLogin(newLogin);
+
+ } else if (password != selectedLogin.password) {
+
+ this.log("Updating password for " + username +
+ " @ " + hostname + " (" + httpRealm + ")");
+ if (notifyBox)
+ this._showChangeLoginNotification(notifyBox,
+ selectedLogin, newLogin);
+ else
+ this._pwmgr.modifyLogin(selectedLogin, newLogin);
+
+ } else {
+ this.log("Login unchanged, no further action needed.");
+ }
+ } catch (e) {
+ Components.utils.reportError("LoginManagerPrompter: " +
+ "Fail2 in promptAuth: " + e + "\n");
+ }
+
+ return ok;
+ },
+
+ asyncPromptAuth : function () {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+
+
+
+ /* ---------- nsILoginManagerPrompter prompts ---------- */
+
+
+
+
+ /*
+ * init
+ *
+ */
+ init : function (aWindow) {
+ this._window = aWindow;
+
+ var prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).getBranch("signon.");
+ this._debug = prefBranch.getBoolPref("debug");
+ this.log("===== initialized =====");
+ },
+
+
+ /*
+ * promptToSavePassword
+ *
+ */
+ promptToSavePassword : function (aLogin) {
+ var notifyBox = this._getNotifyBox();
+
+ if (notifyBox)
+ this._showSaveLoginNotification(notifyBox, aLogin);
+ else
+ this._showSaveLoginDialog(aLogin);
+ },
+
+
+ /*
+ * _showLoginNotification
+ *
+ * Displays a notification bar.
+ *
+ */
+ _showLoginNotification : function (aNotifyBox, aName, aText, aButtons) {
+ var oldBar = aNotifyBox.getNotificationWithValue(aName);
+ const priority = aNotifyBox.PRIORITY_INFO_MEDIUM;
+
+ this.log("Adding new " + aName + " notification bar");
+ var newBar = aNotifyBox.appendNotification(
+ aText, aName,
+ "chrome://mozapps/skin/passwordmgr/key.png",
+ priority, aButtons);
+
+ // The page we're going to hasn't loaded yet, so we want to persist
+ // across the first location change.
+ newBar.persistence++;
+
+ // Sites like Gmail perform a funky redirect dance before you end up
+ // at the post-authentication page. I don't see a good way to
+ // heuristically determine when to ignore such location changes, so
+ // we'll try ignoring location changes based on a time interval.
+ newBar.timeout = Date.now() + 20000; // 20 seconds
+
+ if (oldBar) {
+ this.log("(...and removing old " + aName + " notification bar)");
+ aNotifyBox.removeNotification(oldBar);
+ }
+ },
+
+
+ /*
+ * _showSaveLoginNotification
+ *
+ * Displays a notification bar (rather than a popup), to allow the user to
+ * save the specified login. This allows the user to see the results of
+ * their login, and only save a login which they know worked.
+ *
+ */
+ _showSaveLoginNotification : function (aNotifyBox, aLogin) {
+
+ // Ugh. We can't use the strings from the popup window, because they
+ // have the access key marked in the string (eg "Mo&zilla"), along
+ // with some weird rules for handling access keys that do not occur
+ // in the string, for L10N. See commonDialog.js's setLabelForNode().
+ var neverButtonText =
+ this._getLocalizedString("notifyBarNeverForSiteButtonText");
+ var neverButtonAccessKey =
+ this._getLocalizedString("notifyBarNeverForSiteButtonAccessKey");
+ var rememberButtonText =
+ this._getLocalizedString("notifyBarRememberButtonText");
+ var rememberButtonAccessKey =
+ this._getLocalizedString("notifyBarRememberButtonAccessKey");
+ var notNowButtonText =
+ this._getLocalizedString("notifyBarNotNowButtonText");
+ var notNowButtonAccessKey =
+ this._getLocalizedString("notifyBarNotNowButtonAccessKey");
+
+ var brandShortName =
+ this._brandBundle.GetStringFromName("brandShortName");
+ var displayHost = this._getShortDisplayHost(aLogin.hostname);
+ var notificationText;
+ if (aLogin.username) {
+ var displayUser = this._sanitizeUsername(aLogin.username);
+ notificationText = this._getLocalizedString(
+ "saveLoginText",
+ [brandShortName, displayUser, displayHost]);
+ } else {
+ notificationText = this._getLocalizedString(
+ "saveLoginTextNoUsername",
+ [brandShortName, displayHost]);
+ }
+
+ // The callbacks in |buttons| have a closure to access the variables
+ // in scope here; set one to |this._pwmgr| so we can get back to pwmgr
+ // without a getService() call.
+ var pwmgr = this._pwmgr;
+
+
+ var buttons = [
+ // "Remember" button
+ {
+ label: rememberButtonText,
+ accessKey: rememberButtonAccessKey,
+ popup: null,
+ callback: function(aNotificationBar, aButton) {
+ pwmgr.addLogin(aLogin);
+ }
+ },
+
+ // "Never for this site" button
+ {
+ label: neverButtonText,
+ accessKey: neverButtonAccessKey,
+ popup: null,
+ callback: function(aNotificationBar, aButton) {
+ pwmgr.setLoginSavingEnabled(aLogin.hostname, false);
+ }
+ },
+
+ // "Not now" button
+ {
+ label: notNowButtonText,
+ accessKey: notNowButtonAccessKey,
+ popup: null,
+ callback: function() { /* NOP */ }
+ }
+ ];
+
+ this._showLoginNotification(aNotifyBox, "password-save",
+ notificationText, buttons);
+ },
+
+
+ /*
+ * _removeLoginNotifications
+ *
+ */
+ _removeLoginNotifications : function (aNotifyBox) {
+ var oldBar = aNotifyBox.getNotificationWithValue("password-save");
+ if (oldBar) {
+ this.log("Removing save-password notification bar.");
+ aNotifyBox.removeNotification(oldBar);
+ }
+
+ oldBar = aNotifyBox.getNotificationWithValue("password-change");
+ if (oldBar) {
+ this.log("Removing change-password notification bar.");
+ aNotifyBox.removeNotification(oldBar);
+ }
+ },
+
+
+ /*
+ * _showSaveLoginDialog
+ *
+ * Called when we detect a new login in a form submission,
+ * asks the user what to do.
+ *
+ */
+ _showSaveLoginDialog : function (aLogin) {
+ const buttonFlags = Ci.nsIPrompt.BUTTON_POS_1_DEFAULT +
+ (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) +
+ (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1) +
+ (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_2);
+
+ var brandShortName =
+ this._brandBundle.GetStringFromName("brandShortName");
+ var displayHost = this._getShortDisplayHost(aLogin.hostname);
+
+ var dialogText;
+ if (aLogin.username) {
+ var displayUser = this._sanitizeUsername(aLogin.username);
+ dialogText = this._getLocalizedString(
+ "saveLoginText",
+ [brandShortName, displayUser, displayHost]);
+ } else {
+ dialogText = this._getLocalizedString(
+ "saveLoginTextNoUsername",
+ [brandShortName, displayHost]);
+ }
+ var dialogTitle = this._getLocalizedString(
+ "savePasswordTitle");
+ var neverButtonText = this._getLocalizedString(
+ "neverForSiteButtonText");
+ var rememberButtonText = this._getLocalizedString(
+ "rememberButtonText");
+ var notNowButtonText = this._getLocalizedString(
+ "notNowButtonText");
+
+ this.log("Prompting user to save/ignore login");
+ var userChoice = this._promptService.confirmEx(this._window,
+ dialogTitle, dialogText,
+ buttonFlags, rememberButtonText,
+ notNowButtonText, neverButtonText,
+ null, {});
+ // Returns:
+ // 0 - Save the login
+ // 1 - Ignore the login this time
+ // 2 - Never save logins for this site
+ if (userChoice == 2) {
+ this.log("Disabling " + aLogin.hostname + " logins by request.");
+ this._pwmgr.setLoginSavingEnabled(aLogin.hostname, false);
+ } else if (userChoice == 0) {
+ this.log("Saving login for " + aLogin.hostname);
+ this._pwmgr.addLogin(aLogin);
+ } else {
+ // userChoice == 1 --> just ignore the login.
+ this.log("Ignoring login.");
+ }
+ },
+
+
+ /*
+ * promptToChangePassword
+ *
+ * Called when we think we detect a password change for an existing
+ * login, when the form being submitted contains multiple password
+ * fields.
+ *
+ */
+ promptToChangePassword : function (aOldLogin, aNewLogin) {
+ var notifyBox = this._getNotifyBox();
+
+ if (notifyBox)
+ this._showChangeLoginNotification(notifyBox, aOldLogin, aNewLogin);
+ else
+ this._showChangeLoginDialog(aOldLogin, aNewLogin);
+ },
+
+
+ /*
+ * _showChangeLoginNotification
+ *
+ * Shows the Change Password notification bar.
+ *
+ */
+ _showChangeLoginNotification : function (aNotifyBox, aOldLogin, aNewLogin) {
+ var notificationText;
+ if (aOldLogin.username)
+ notificationText = this._getLocalizedString(
+ "passwordChangeText",
+ [aOldLogin.username]);
+ else
+ notificationText = this._getLocalizedString(
+ "passwordChangeTextNoUser");
+
+ var changeButtonText =
+ this._getLocalizedString("notifyBarChangeButtonText");
+ var changeButtonAccessKey =
+ this._getLocalizedString("notifyBarChangeButtonAccessKey");
+ var dontChangeButtonText =
+ this._getLocalizedString("notifyBarDontChangeButtonText");
+ var dontChangeButtonAccessKey =
+ this._getLocalizedString("notifyBarDontChangeButtonAccessKey");
+
+ // The callbacks in |buttons| have a closure to access the variables
+ // in scope here; set one to |this._pwmgr| so we can get back to pwmgr
+ // without a getService() call.
+ var pwmgr = this._pwmgr;
+
+ var buttons = [
+ // "Yes" button
+ {
+ label: changeButtonText,
+ accessKey: changeButtonAccessKey,
+ popup: null,
+ callback: function(aNotificationBar, aButton) {
+ pwmgr.modifyLogin(aOldLogin, aNewLogin);
+ }
+ },
+
+ // "No" button
+ {
+ label: dontChangeButtonText,
+ accessKey: dontChangeButtonAccessKey,
+ popup: null,
+ callback: function(aNotificationBar, aButton) {
+ // do nothing
+ }
+ }
+ ];
+
+ this._showLoginNotification(aNotifyBox, "password-change",
+ notificationText, buttons);
+ },
+
+
+ /*
+ * _showChangeLoginDialog
+ *
+ * Shows the Change Password dialog.
+ *
+ */
+ _showChangeLoginDialog : function (aOldLogin, aNewLogin) {
+ const buttonFlags = Ci.nsIPrompt.STD_YES_NO_BUTTONS;
+
+ var dialogText;
+ if (aOldLogin.username)
+ dialogText = this._getLocalizedString(
+ "passwordChangeText",
+ [aOldLogin.username]);
+ else
+ dialogText = this._getLocalizedString(
+ "passwordChangeTextNoUser");
+
+ var dialogTitle = this._getLocalizedString(
+ "passwordChangeTitle");
+
+ // returns 0 for yes, 1 for no.
+ var ok = !this._promptService.confirmEx(this._window,
+ dialogTitle, dialogText, buttonFlags,
+ null, null, null,
+ null, {});
+ if (ok) {
+ this.log("Updating password for user " + aOldLogin.username);
+ this._pwmgr.modifyLogin(aOldLogin, aNewLogin);
+ }
+ },
+
+
+ /*
+ * promptToChangePasswordWithUsernames
+ *
+ * Called when we detect a password change in a form submission, but we
+ * don't know which existing login (username) it's for. Asks the user
+ * to select a username and confirm the password change.
+ *
+ * Note: The caller doesn't know the username for aNewLogin, so this
+ * function fills in .username and .usernameField with the values
+ * from the login selected by the user.
+ *
+ * Note; XPCOM stupidity: |count| is just |logins.length|.
+ */
+ promptToChangePasswordWithUsernames : function (logins, count, aNewLogin) {
+ const buttonFlags = Ci.nsIPrompt.STD_YES_NO_BUTTONS;
+
+ var usernames = logins.map(function (l) l.username);
+ var dialogText = this._getLocalizedString("userSelectText");
+ var dialogTitle = this._getLocalizedString("passwordChangeTitle");
+ var selectedIndex = { value: null };
+
+ // If user selects ok, outparam.value is set to the index
+ // of the selected username.
+ var ok = this._promptService.select(this._window,
+ dialogTitle, dialogText,
+ usernames.length, usernames,
+ selectedIndex);
+ if (ok) {
+ // Now that we know which login to change the password for,
+ // update the missing username info in the aNewLogin.
+
+ var selectedLogin = logins[selectedIndex.value];
+
+ this.log("Updating password for user " + selectedLogin.username);
+
+ aNewLogin.username = selectedLogin.username;
+ aNewLogin.usernameField = selectedLogin.usernameField;
+
+ this._pwmgr.modifyLogin(selectedLogin, aNewLogin);
+ }
+ },
+
+
+
+
+ /* ---------- Internal Methods ---------- */
+
+
+
+
+ /*
+ * _getNotifyBox
+ *
+ * Returns the notification box to this prompter, or null if there isn't
+ * a notification box available.
+ */
+ _getNotifyBox : function () {
+ var notifyBox = null;
+
+ // Given a content DOM window, returns the chrome window it's in.
+ function getChromeWindow(aWindow) {
+ var chromeWin = aWindow
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .QueryInterface(Ci.nsIDOMChromeWindow);
+ return chromeWin;
+ }
+
+ try {
+ // Get topmost window, in case we're in a frame.
+ var notifyWindow = this._window.top
+
+ // Some sites pop up a temporary login window, when disappears
+ // upon submission of credentials. We want to put the notification
+ // bar in the opener window if this seems to be happening.
+ if (notifyWindow.opener) {
+ var chromeDoc = getChromeWindow(notifyWindow)
+ .document.documentElement;
+ var webnav = notifyWindow
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation);
+
+ // Check to see if the current window was opened with chrome
+ // disabled, and if so use the opener window. But if the window
+ // has been used to visit other pages (ie, has a history),
+ // assume it'll stick around and *don't* use the opener.
+ if (chromeDoc.getAttribute("chromehidden") &&
+ webnav.sessionHistory.count == 1) {
+ this.log("Using opener window for notification bar.");
+ notifyWindow = notifyWindow.opener;
+ }
+ }
+
+
+ // Get the chrome window for the content window we're using.
+ // .wrappedJSObject needed here -- see bug 422974 comment 5.
+ var chromeWin = getChromeWindow(notifyWindow).wrappedJSObject;
+
+ if (chromeWin.getNotificationBox)
+ notifyBox = chromeWin.getNotificationBox(notifyWindow);
+ else
+ this.log("getNotificationBox() not available on window");
+
+ } catch (e) {
+ // If any errors happen, just assume no notification box.
+ this.log("No notification box available: " + e)
+ }
+
+ return notifyBox;
+ },
+
+
+ /*
+ * _repickSelectedLogin
+ *
+ * The user might enter a login that isn't the one we prefilled, but
+ * is the same as some other existing login. So, pick a login with a
+ * matching username, or return null.
+ */
+ _repickSelectedLogin : function (foundLogins, username) {
+ for (var i = 0; i < foundLogins.length; i++)
+ if (foundLogins[i].username == username)
+ return foundLogins[i];
+ return null;
+ },
+
+
+ /*
+ * _getLocalizedString
+ *
+ * Can be called as:
+ * _getLocalizedString("key1");
+ * _getLocalizedString("key2", ["arg1"]);
+ * _getLocalizedString("key3", ["arg1", "arg2"]);
+ * (etc)
+ *
+ * Returns the localized string for the specified key,
+ * formatted if required.
+ *
+ */
+ _getLocalizedString : function (key, formatArgs) {
+ if (formatArgs)
+ return this._strBundle.formatStringFromName(
+ key, formatArgs, formatArgs.length);
+ else
+ return this._strBundle.GetStringFromName(key);
+ },
+
+
+ /*
+ * _sanitizeUsername
+ *
+ * Sanitizes the specified username, by stripping quotes and truncating if
+ * it's too long. This helps prevent an evil site from messing with the
+ * "save password?" prompt too much.
+ */
+ _sanitizeUsername : function (username) {
+ if (username.length > 30) {
+ username = username.substring(0, 30);
+ username += this._ellipsis;
+ }
+ return username.replace(/['"]/g, "");
+ },
+
+
+ /*
+ * _getFormattedHostname
+ *
+ * The aURI parameter may either be a string uri, or an nsIURI instance.
+ *
+ * Returns the hostname to use in a nsILoginInfo object (for example,
+ * "http://example.com").
+ */
+ _getFormattedHostname : function (aURI) {
+ var uri;
+ if (aURI instanceof Ci.nsIURI) {
+ uri = aURI;
+ } else {
+ uri = this._ioService.newURI(aURI, null, null);
+ }
+ var scheme = uri.scheme;
+
+ var hostname = scheme + "://" + uri.host;
+
+ // If the URI explicitly specified a port, only include it when
+ // it's not the default. (We never want "http://foo.com:80")
+ port = uri.port;
+ if (port != -1) {
+ var handler = this._ioService.getProtocolHandler(scheme);
+ if (port != handler.defaultPort)
+ hostname += ":" + port;
+ }
+
+ return hostname;
+ },
+
+
+ /*
+ * _getShortDisplayHost
+ *
+ * Converts a login's hostname field (a URL) to a short string for
+ * prompting purposes. Eg, "http://foo.com" --> "foo.com", or
+ * "ftp://www.site.co.uk" --> "site.co.uk".
+ */
+ _getShortDisplayHost: function (aURIString) {
+ var displayHost;
+
+ var eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"].
+ getService(Ci.nsIEffectiveTLDService);
+ var idnService = Cc["@mozilla.org/network/idn-service;1"].
+ getService(Ci.nsIIDNService);
+ try {
+ var uri = this._ioService.newURI(aURIString, null, null);
+ var baseDomain = eTLDService.getBaseDomain(uri);
+ displayHost = idnService.convertToDisplayIDN(baseDomain, {});
+ } catch (e) {
+ this.log("_getShortDisplayHost couldn't process " + aURIString);
+ }
+
+ if (!displayHost)
+ displayHost = aURIString;
+
+ return displayHost;
+ },
+
+
+ /*
+ * _getAuthTarget
+ *
+ * Returns the hostname and realm for which authentication is being
+ * requested, in the format expected to be used with nsILoginInfo.
+ */
+ _getAuthTarget : function (aChannel, aAuthInfo) {
+ var hostname, realm;
+
+ // If our proxy is demanding authentication, don't use the
+ // channel's actual destination.
+ if (aAuthInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY) {
+ this.log("getAuthTarget is for proxy auth");
+ if (!(aChannel instanceof Ci.nsIProxiedChannel))
+ throw "proxy auth needs nsIProxiedChannel";
+
+ var info = aChannel.proxyInfo;
+ if (!info)
+ throw "proxy auth needs nsIProxyInfo";
+
+ // Proxies don't have a scheme, but we'll use "moz-proxy://"
+ // so that it's more obvious what the login is for.
+ var idnService = Cc["@mozilla.org/network/idn-service;1"].
+ getService(Ci.nsIIDNService);
+ hostname = "moz-proxy://" +
+ idnService.convertUTF8toACE(info.host) +
+ ":" + info.port;
+ realm = aAuthInfo.realm;
+ if (!realm)
+ realm = hostname;
+
+ return [hostname, realm];
+ }
+
+ hostname = this._getFormattedHostname(aChannel.URI);
+
+ // If a HTTP WWW-Authenticate header specified a realm, that value
+ // will be available here. If it wasn't set or wasn't HTTP, we'll use
+ // the formatted hostname instead.
+ realm = aAuthInfo.realm;
+ if (!realm)
+ realm = hostname;
+
+ return [hostname, realm];
+ },
+
+
+ /**
+ * Returns [username, password] as extracted from aAuthInfo (which
+ * holds this info after having prompted the user).
+ *
+ * If the authentication was for a Windows domain, we'll prepend the
+ * return username with the domain. (eg, "domain\user")
+ */
+ _GetAuthInfo : function (aAuthInfo) {
+ var username, password;
+
+ var flags = aAuthInfo.flags;
+ if (flags & Ci.nsIAuthInformation.NEED_DOMAIN && aAuthInfo.domain)
+ username = aAuthInfo.domain + "\\" + aAuthInfo.username;
+ else
+ username = aAuthInfo.username;
+
+ password = aAuthInfo.password;
+
+ return [username, password];
+ },
+
+
+ /**
+ * Given a username (possibly in DOMAIN\user form) and password, parses the
+ * domain out of the username if necessary and sets domain, username and
+ * password on the auth information object.
+ */
+ _SetAuthInfo : function (aAuthInfo, username, password) {
+ var flags = aAuthInfo.flags;
+ if (flags & Ci.nsIAuthInformation.NEED_DOMAIN) {
+ // Domain is separated from username by a backslash
+ var idx = username.indexOf("\\");
+ if (idx == -1) {
+ aAuthInfo.username = username;
+ } else {
+ aAuthInfo.domain = username.substring(0, idx);
+ aAuthInfo.username = username.substring(idx+1);
+ }
+ } else {
+ aAuthInfo.username = username;
+ }
+ aAuthInfo.password = password;
+ }
+
+}; // end of LoginManagerPrompter implementation
+
+
+var component = [LoginManagerPromptFactory, LoginManagerPrompter];
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(component);
+}
diff --git a/bundles/XO/components/nsMicrosummaryService.js b/bundles/XO/components/nsMicrosummaryService.js
new file mode 100755
index 0000000..f51c0cd
--- /dev/null
+++ b/bundles/XO/components/nsMicrosummaryService.js
@@ -0,0 +1,2260 @@
+//@line 40 "/builds/moz2_slave/linux_build/build/browser/components/microsummaries/src/nsMicrosummaryService.js"
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+const PERMS_FILE = 0644;
+const MODE_WRONLY = 0x02;
+const MODE_CREATE = 0x08;
+const MODE_TRUNCATE = 0x20;
+
+const NS_ERROR_MODULE_DOM = 2152923136;
+const NS_ERROR_DOM_BAD_URI = NS_ERROR_MODULE_DOM + 1012;
+
+// How often to check for microsummaries that need updating, in milliseconds.
+const CHECK_INTERVAL = 15 * 1000; // 15 seconds
+// How often to check for generator updates, in seconds
+const GENERATOR_INTERVAL = 7 * 86400; // 1 week
+
+const MICSUM_NS = "http://www.mozilla.org/microsummaries/0.1";
+const XSLT_NS = "http://www.w3.org/1999/XSL/Transform";
+
+const ANNO_MICSUM_GEN_URI = "microsummary/generatorURI";
+const ANNO_MICSUM_EXPIRATION = "microsummary/expiration";
+const ANNO_STATIC_TITLE = "bookmarks/staticTitle";
+const ANNO_CONTENT_TYPE = "bookmarks/contentType";
+
+const MAX_SUMMARY_LENGTH = 4096;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function MicrosummaryService() {
+ this._obs.addObserver(this, "xpcom-shutdown", true);
+
+ Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).
+ getBranch("browser.microsummary.").
+ QueryInterface(Ci.nsIPrefBranch2).
+ addObserver("", this, true);
+
+ this._initTimers();
+ this._cacheLocalGenerators();
+}
+
+MicrosummaryService.prototype = {
+ // Bookmarks Service
+ __bms: null,
+ get _bms() {
+ if (!this.__bms)
+ this.__bms = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+ getService(Ci.nsINavBookmarksService);
+ return this.__bms;
+ },
+
+ // Annotation Service
+ __ans: null,
+ get _ans() {
+ if (!this.__ans)
+ this.__ans = Cc["@mozilla.org/browser/annotation-service;1"].
+ getService(Ci.nsIAnnotationService);
+ return this.__ans;
+ },
+
+ // IO Service
+ __ios: null,
+ get _ios() {
+ if (!this.__ios)
+ this.__ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__ios;
+ },
+
+ // Observer Service
+ __obs: null,
+ get _obs() {
+ if (!this.__obs)
+ this.__obs = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ return this.__obs;
+ },
+
+ /**
+ * Make a URI from a spec.
+ * @param spec
+ * The string spec of the URI.
+ * @returns An nsIURI object.
+ */
+ _uri: function MSS__uri(spec) {
+ return this._ios.newURI(spec, null, null);
+ },
+
+ // Directory Locator
+ __dirs: null,
+ get _dirs() {
+ if (!this.__dirs)
+ this.__dirs = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ return this.__dirs;
+ },
+
+ // The update interval as specified by the user (defaults to 30 minutes)
+ get _updateInterval() {
+ var updateInterval =
+ getPref("browser.microsummary.updateInterval", 30);
+ // the minimum update interval is 1 minute
+ return Math.max(updateInterval, 1) * 60 * 1000;
+ },
+
+ // A cache of local microsummary generators. This gets built on startup
+ // by the _cacheLocalGenerators() method.
+ _localGenerators: {},
+
+ // The timer that periodically checks for microsummaries needing updating.
+ _timer: null,
+
+ // XPCOM registration
+ classDescription: "Microsummary Service",
+ contractID: "@mozilla.org/microsummary/service;1",
+ classID: Components.ID("{460a9792-b154-4f26-a922-0f653e2c8f91}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIMicrosummaryService,
+ Ci.nsISupportsWeakReference,
+ Ci.nsIObserver]),
+
+ // nsIObserver
+ observe: function MSS_observe(subject, topic, data) {
+ switch (topic) {
+ case "xpcom-shutdown":
+ this._destroy();
+ break;
+ case "nsPref:changed":
+ if (data == "enabled")
+ this._initTimers();
+ break;
+ }
+ },
+
+ _initTimers: function MSS__initTimers() {
+ if (this._timer)
+ this._timer.cancel();
+
+ if (!getPref("browser.microsummary.enabled", true))
+ return;
+
+ // Periodically update microsummaries that need updating.
+ this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ var callback = {
+ _svc: this,
+ notify: function(timer) { this._svc._updateMicrosummaries() }
+ };
+ this._timer.initWithCallback(callback,
+ CHECK_INTERVAL,
+ this._timer.TYPE_REPEATING_SLACK);
+
+ // Setup a cross-session timer to periodically check for generator updates.
+ var updateManager = Cc["@mozilla.org/updates/timer-manager;1"].
+ getService(Ci.nsIUpdateTimerManager);
+ var interval = getPref("browser.microsummary.generatorUpdateInterval",
+ GENERATOR_INTERVAL);
+ var updateCallback = {
+ _svc: this,
+ notify: function(timer) { this._svc._updateGenerators() }
+ };
+ updateManager.registerTimer("microsummary-generator-update-timer",
+ updateCallback, interval);
+ },
+
+ _destroy: function MSS__destroy() {
+ this._timer.cancel();
+ this._timer = null;
+ },
+
+ _updateMicrosummaries: function MSS__updateMicrosummaries() {
+ var bookmarks = this._getBookmarks();
+
+ var now = Date.now();
+ var updateInterval = this._updateInterval;
+ for ( var i = 0; i < bookmarks.length; i++ ) {
+ var bookmarkID = bookmarks[i];
+
+ // Skip this page if its microsummary hasn't expired yet.
+ if (this._ans.itemHasAnnotation(bookmarkID, ANNO_MICSUM_EXPIRATION) &&
+ this._ans.getItemAnnotation(bookmarkID, ANNO_MICSUM_EXPIRATION) > now)
+ continue;
+
+ // Reset the expiration time immediately, so if the refresh is failing
+ // we don't try it every 15 seconds, potentially overloading the server.
+ this._setAnnotation(bookmarkID, ANNO_MICSUM_EXPIRATION, now + updateInterval);
+
+ // Try to update the microsummary, but trap errors, so an update
+ // that throws doesn't prevent us from updating the rest of them.
+ try {
+ this.refreshMicrosummary(bookmarkID);
+ }
+ catch(ex) {
+ Cu.reportError(ex);
+ }
+ }
+ },
+
+ _updateGenerators: function MSS__updateGenerators() {
+ var generators = this._localGenerators;
+ var update = getPref("browser.microsummary.updateGenerators", true);
+ if (!generators || !update)
+ return;
+
+ for (let uri in generators)
+ generators[uri].update();
+ },
+
+ _updateMicrosummary: function MSS__updateMicrosummary(bookmarkID, microsummary) {
+ var title = this._bms.getItemTitle(bookmarkID);
+
+ // Ensure the user-given title is cached
+ if (!this._ans.itemHasAnnotation(bookmarkID, ANNO_STATIC_TITLE))
+ this._setAnnotation(bookmarkID, ANNO_STATIC_TITLE, title);
+
+ // A string identifying the bookmark to use when logging the update.
+ var bookmarkIdentity = bookmarkID;
+
+ // Update if the microsummary differs from the current title.
+ if (!title || title != microsummary.content) {
+ this._bms.setItemTitle(bookmarkID, microsummary.content);
+ var subject = new LiveTitleNotificationSubject(bookmarkID, microsummary);
+ LOG("updated live title for " + bookmarkIdentity +
+ " from '" + (title == null ? "<no live title>" : title) +
+ "' to '" + microsummary.content + "'");
+ this._obs.notifyObservers(subject, "microsummary-livetitle-updated", title);
+ }
+ else {
+ LOG("didn't update live title for " + bookmarkIdentity + "; it hasn't changed");
+ }
+
+ // Whether or not the title itself has changed, we still save any changes
+ // to the update interval, since the interval represents how long to wait
+ // before checking again for updates, and that can vary across updates,
+ // even when the title itself hasn't changed.
+ this._setAnnotation(bookmarkID, ANNO_MICSUM_EXPIRATION,
+ Date.now() + (microsummary.updateInterval || this._updateInterval));
+ },
+
+ /**
+ * Load local generators into the cache.
+ *
+ */
+ _cacheLocalGenerators: function MSS__cacheLocalGenerators() {
+ // Load generators from the application directory.
+ var appDir = this._dirs.get("MicsumGens", Ci.nsIFile);
+ if (appDir.exists())
+ this._cacheLocalGeneratorDir(appDir);
+
+ // Load generators from the user's profile.
+ var profileDir = this._dirs.get("UsrMicsumGens", Ci.nsIFile);
+ if (profileDir.exists())
+ this._cacheLocalGeneratorDir(profileDir);
+ },
+
+ /**
+ * Load local generators from a directory into the cache.
+ *
+ * @param dir
+ * nsIFile object pointing to directory containing generator files
+ *
+ */
+ _cacheLocalGeneratorDir: function MSS__cacheLocalGeneratorDir(dir) {
+ var files = dir.directoryEntries.QueryInterface(Ci.nsIDirectoryEnumerator);
+ var file = files.nextFile;
+
+ while (file) {
+ // Recursively load generators so support packs containing
+ // lots of generators can organize them into multiple directories.
+ if (file.isDirectory())
+ this._cacheLocalGeneratorDir(file);
+ else
+ this._cacheLocalGeneratorFile(file);
+
+ file = files.nextFile;
+ }
+ files.close();
+ },
+
+ /**
+ * Load a local generator from a file into the cache.
+ *
+ * @param file
+ * nsIFile object pointing to file from which to load generator
+ *
+ */
+ _cacheLocalGeneratorFile: function MSS__cacheLocalGeneratorFile(file) {
+ var uri = this._ios.newFileURI(file);
+
+ var t = this;
+ var callback =
+ function MSS_cacheLocalGeneratorCallback(resource) {
+ try { t._handleLocalGenerator(resource) }
+ finally { resource.destroy() }
+ };
+
+ var resource = new MicrosummaryResource(uri);
+ resource.load(callback);
+ },
+
+ _handleLocalGenerator: function MSS__handleLocalGenerator(resource) {
+ if (!resource.isXML)
+ throw(resource.uri.spec + " microsummary generator loaded, but not XML");
+
+ var generator = new MicrosummaryGenerator(null, resource.uri);
+ generator.initFromXML(resource.content);
+
+ // Add the generator to the local generators cache.
+ // XXX Figure out why Firefox crashes on shutdown if we index generators
+ // by uri.spec but doesn't crash if we index by uri.spec.split().join().
+ //this._localGenerators[generator.uri.spec] = generator;
+ this._localGenerators[generator.uri.spec.split().join()] = generator;
+
+ LOG("loaded local microsummary generator\n" +
+ " file: " + generator.localURI.spec + "\n" +
+ " ID: " + generator.uri.spec);
+ },
+
+ // nsIMicrosummaryService
+
+ /**
+ * Return a microsummary generator for the given URI.
+ *
+ * @param generatorURI
+ * the URI of the generator
+ */
+ getGenerator: function MSS_getGenerator(generatorURI) {
+ return this._localGenerators[generatorURI.spec] ||
+ new MicrosummaryGenerator(generatorURI);
+ },
+
+ /**
+ * Install the microsummary generator from the resource at the supplied URI.
+ * Callable by content via the addMicrosummaryGenerator() sidebar method.
+ *
+ * @param generatorURI
+ * the URI of the resource providing the generator
+ *
+ */
+ addGenerator: function MSS_addGenerator(generatorURI) {
+ var t = this;
+ var callback =
+ function MSS_addGeneratorCallback(resource) {
+ try { t._handleNewGenerator(resource) }
+ finally { resource.destroy() }
+ };
+
+ var resource = new MicrosummaryResource(generatorURI);
+ resource.load(callback);
+ },
+
+ _handleNewGenerator: function MSS__handleNewGenerator(resource) {
+ if (!resource.isXML)
+ throw(resource.uri.spec + " microsummary generator loaded, but not XML");
+
+ // XXX Make sure it's a valid microsummary generator.
+
+ var rootNode = resource.content.documentElement;
+
+ // Add a reference to the URI from which we got this generator so we have
+ // a unique identifier for the generator and also so we can check back later
+ // for updates.
+ rootNode.setAttribute("uri", "urn:source:" + resource.uri.spec);
+
+ this.installGenerator(resource.content);
+ },
+
+ /**
+ * Install a microsummary generator from the given XML definition.
+ *
+ * @param xmlDefinition
+ * an nsIDOMDocument XML document defining the generator
+ *
+ * @returns the newly-installed nsIMicrosummaryGenerator generator
+ *
+ */
+ installGenerator: function MSS_installGenerator(xmlDefinition) {
+ var rootNode = xmlDefinition.getElementsByTagNameNS(MICSUM_NS, "generator")[0];
+
+ var generatorID = rootNode.getAttribute("uri");
+
+ // The existing cache entry for this generator, if it is already installed.
+ var generator = this._localGenerators[generatorID];
+
+ var topic;
+ if (generator)
+ topic = "microsummary-generator-updated";
+ else {
+ // This generator is not already installed. Save it as a new file.
+ topic = "microsummary-generator-installed";
+ var generatorName = rootNode.getAttribute("name");
+ var fileName = sanitizeName(generatorName) + ".xml";
+ var file = this._dirs.get("UsrMicsumGens", Ci.nsIFile);
+ file.append(fileName);
+ file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ generator = new MicrosummaryGenerator(null, this._ios.newFileURI(file));
+ this._localGenerators[generatorID] = generator;
+ }
+
+ // Initialize (or reinitialize) the generator from its XML definition,
+ // the save the definition to the generator's file.
+ generator.initFromXML(xmlDefinition);
+ generator.saveXMLToFile(xmlDefinition);
+
+ LOG("installed generator " + generatorID);
+
+ this._obs.notifyObservers(generator, topic, null);
+
+ return generator;
+ },
+
+ /**
+ * Get the set of microsummaries available for a given page. The set
+ * might change after this method returns, since this method will trigger
+ * an asynchronous load of the page in question (if it isn't already loaded)
+ * to see if it references any page-specific microsummaries.
+ *
+ * If the caller passes a bookmark ID, and one of the microsummaries
+ * is the current one for the bookmark, this method will retrieve content
+ * from the datastore for that microsummary, which is useful when callers
+ * want to display a list of microsummaries for a page that isn't loaded,
+ * and they want to display the actual content of the selected microsummary
+ * immediately (rather than after the content is asynchronously loaded).
+ *
+ * @param pageURI
+ * the URI of the page for which to retrieve available microsummaries
+ *
+ * @param bookmarkID (optional)
+ * the ID of the bookmark for which this method is being called
+ *
+ * @returns an nsIMicrosummarySet of nsIMicrosummaries for the given page
+ *
+ */
+ getMicrosummaries: function MSS_getMicrosummaries(pageURI, bookmarkID) {
+ var microsummaries = new MicrosummarySet();
+
+ if (!getPref("browser.microsummary.enabled", true))
+ return microsummaries;
+
+ // Get microsummaries defined by local generators.
+ for (var genURISpec in this._localGenerators) {
+ var generator = this._localGenerators[genURISpec];
+
+ if (generator.appliesToURI(pageURI)) {
+ var microsummary = new Microsummary(pageURI, generator);
+
+ // If this is the current microsummary for this bookmark, load the content
+ // from the datastore so it shows up immediately in microsummary picking UI.
+ if (bookmarkID != -1 && this.isMicrosummary(bookmarkID, microsummary))
+ microsummary._content = this._bms.getItemTitle(bookmarkID);
+
+ microsummaries.AppendElement(microsummary);
+ }
+ }
+
+ // If a bookmark identifier has been provided, list its microsummary
+ // synchronously, if any.
+ if (bookmarkID != -1 && this.hasMicrosummary(bookmarkID)) {
+ var currentMicrosummary = this.getMicrosummary(bookmarkID);
+ if (!microsummaries.hasItemForMicrosummary(currentMicrosummary))
+ microsummaries.AppendElement(currentMicrosummary);
+ }
+
+ // Get microsummaries defined by the page. If we don't have the page,
+ // download it asynchronously, and then finish populating the set.
+ var resource = getLoadedMicrosummaryResource(pageURI);
+ if (resource) {
+ try { microsummaries.extractFromPage(resource) }
+ finally { resource.destroy() }
+ }
+ else {
+ // Load the page with a callback that will add the page's microsummaries
+ // to the set once the page has loaded.
+ var callback = function MSS_extractFromPageCallback(resource) {
+ try { microsummaries.extractFromPage(resource) }
+ finally { resource.destroy() }
+ };
+
+ try {
+ resource = new MicrosummaryResource(pageURI);
+ resource.load(callback);
+ }
+ catch(e) {
+ // We don't have to do anything special if the call fails besides
+ // destroying the Resource object. We can just return the list
+ // of microsummaries without including page-defined microsummaries.
+ if (resource)
+ resource.destroy();
+ LOG("error downloading page to extract its microsummaries: " + e);
+ }
+ }
+
+ return microsummaries;
+ },
+
+ /**
+ * Change all occurrences of a specific value in a given field to a new value.
+ *
+ * @param fieldName
+ * the name of the field whose values should be changed
+ * @param oldValue
+ * the value that should be changed
+ * @param newValue
+ * the value to which it should be changed
+ *
+ */
+ _changeField: function MSS__changeField(fieldName, oldValue, newValue) {
+ var bookmarks = this._getBookmarks();
+
+ for ( var i = 0; i < bookmarks.length; i++ ) {
+ var bookmarkID = bookmarks[i];
+
+ if (this._ans.itemHasAnnotation(bookmarkID, fieldName) &&
+ this._ans.getItemAnnotation(bookmarkID, fieldName) == oldValue)
+ this._setAnnotation(bookmarkID, fieldName, newValue);
+ }
+ },
+
+ /**
+ * Get the set of bookmarks with microsummaries.
+ *
+ * This is the internal version of this method, which is not accessible
+ * via XPCOM but is more performant; inside this component, use this version.
+ * Outside the component, use getBookmarks (no underscore prefix) instead.
+ *
+ * @returns an array of place: uris representing bookmarks items
+ *
+ */
+ _getBookmarks: function MSS__getBookmarks() {
+ var bookmarks;
+
+ // This try/catch block is a temporary workaround for bug 336194.
+ try {
+ bookmarks = this._ans.getItemsWithAnnotation(ANNO_MICSUM_GEN_URI, {});
+ }
+ catch(e) {
+ bookmarks = [];
+ }
+
+ return bookmarks;
+ },
+
+ _setAnnotation: function MSS__setAnnotation(aBookmarkId, aFieldName, aFieldValue) {
+ this._ans.setItemAnnotation(aBookmarkId,
+ aFieldName,
+ aFieldValue,
+ 0,
+ this._ans.EXPIRE_NEVER);
+ },
+
+ /**
+ * Get the set of bookmarks with microsummaries.
+ *
+ * This is the external version of this method and is accessible via XPCOM.
+ * Use it outside this component. Inside the component, use _getBookmarks
+ * (with underscore prefix) instead for performance.
+ *
+ * @returns an nsISimpleEnumerator enumeration of bookmark IDs
+ *
+ */
+ getBookmarks: function MSS_getBookmarks() {
+ return new ArrayEnumerator(this._getBookmarks());
+ },
+
+ /**
+ * Get the current microsummary for the given bookmark.
+ *
+ * @param bookmarkID
+ * the bookmark for which to get the current microsummary
+ *
+ * @returns the current microsummary for the bookmark, or null
+ * if the bookmark does not have a current microsummary
+ *
+ */
+ getMicrosummary: function MSS_getMicrosummary(bookmarkID) {
+ if (!this.hasMicrosummary(bookmarkID))
+ return null;
+
+ var pageURI = this._bms.getBookmarkURI(bookmarkID);
+ var generatorURI = this._uri(this._ans.getItemAnnotation(bookmarkID,
+ ANNO_MICSUM_GEN_URI));
+ var generator = this.getGenerator(generatorURI);
+
+ return new Microsummary(pageURI, generator);
+ },
+
+ /**
+ * Get a microsummary for a given page URI and generator URI.
+ *
+ * @param pageURI
+ * the URI of the page to be summarized
+ *
+ * @param generatorURI
+ * the URI of the microsummary generator
+ *
+ * @returns an nsIMicrosummary for the given page and generator URIs.
+ *
+ */
+ createMicrosummary: function MSS_createMicrosummary(pageURI, generatorURI) {
+ var generator = this.getGenerator(generatorURI);
+ return new Microsummary(pageURI, generator);
+ },
+
+ /**
+ * Set the current microsummary for the given bookmark.
+ *
+ * @param bookmarkID
+ * the bookmark for which to set the current microsummary
+ *
+ * @param microsummary
+ * the microsummary to set as the current one
+ *
+ */
+ setMicrosummary: function MSS_setMicrosummary(bookmarkID, microsummary) {
+ this._setAnnotation(bookmarkID, ANNO_MICSUM_GEN_URI, microsummary.generator.uri.spec);
+
+ if (microsummary.content)
+ this._updateMicrosummary(bookmarkID, microsummary);
+ else
+ this.refreshMicrosummary(bookmarkID);
+ },
+
+ /**
+ * Remove the current microsummary for the given bookmark.
+ *
+ * @param bookmarkID
+ * the bookmark for which to remove the current microsummary
+ *
+ */
+ removeMicrosummary: function MSS_removeMicrosummary(bookmarkID) {
+ // Restore the user's title
+ if (this._ans.itemHasAnnotation(bookmarkID, ANNO_STATIC_TITLE))
+ this._bms.setItemTitle(bookmarkID, this._ans.getItemAnnotation(bookmarkID, ANNO_STATIC_TITLE));
+
+ var fields = [ANNO_MICSUM_GEN_URI,
+ ANNO_MICSUM_EXPIRATION,
+ ANNO_STATIC_TITLE,
+ ANNO_CONTENT_TYPE];
+
+ for (let i = 0; i < fields.length; i++) {
+ var field = fields[i];
+ if (this._ans.itemHasAnnotation(bookmarkID, field))
+ this._ans.removeItemAnnotation(bookmarkID, field);
+ }
+ },
+
+ /**
+ * Whether or not the given bookmark has a current microsummary.
+ *
+ * @param bookmarkID
+ * the bookmark for which to set the current microsummary
+ *
+ * @returns a boolean representing whether or not the given bookmark
+ * has a current microsummary
+ *
+ */
+ hasMicrosummary: function MSS_hasMicrosummary(bookmarkID) {
+ return this._ans.itemHasAnnotation(bookmarkID, ANNO_MICSUM_GEN_URI);
+ },
+
+ /**
+ * Whether or not the given microsummary is the current microsummary
+ * for the given bookmark.
+ *
+ * @param bookmarkID
+ * the bookmark to check
+ *
+ * @param microsummary
+ * the microsummary to check
+ *
+ * @returns whether or not the microsummary is the current one
+ * for the bookmark
+ *
+ */
+ isMicrosummary: function MSS_isMicrosummary(aBookmarkID, aMicrosummary) {
+ if (!aMicrosummary || !aBookmarkID)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ if (this.hasMicrosummary(aBookmarkID)) {
+ currentMicrosummarry = this.getMicrosummary(aBookmarkID);
+ if (aMicrosummary.equals(currentMicrosummarry))
+ return true;
+ }
+ return false
+ },
+
+ /**
+ * Refresh a microsummary, updating its value in the datastore and UI.
+ * If this method can refresh the microsummary instantly, it will.
+ * Otherwise, it'll asynchronously download the necessary information
+ * (the generator and/or page) before refreshing the microsummary.
+ *
+ * Callers should check the "content" property of the returned microsummary
+ * object to distinguish between sync and async refreshes. If its value
+ * is "null", then it's an async refresh, and the caller should register
+ * itself as an nsIMicrosummaryObserver via nsIMicrosummary.addObserver()
+ * to find out when the refresh completes.
+ *
+ * @param bookmarkID
+ * the bookmark whose microsummary is being refreshed
+ *
+ * @returns the microsummary being refreshed
+ *
+ */
+ refreshMicrosummary: function MSS_refreshMicrosummary(bookmarkID) {
+ if (!this.hasMicrosummary(bookmarkID))
+ throw "bookmark " + bookmarkID + " does not have a microsummary";
+
+ var pageURI = this._bms.getBookmarkURI(bookmarkID);
+ if (!pageURI)
+ throw("can't get URL for bookmark with ID " + bookmarkID);
+ var generatorURI = this._uri(this._ans.getItemAnnotation(bookmarkID,
+ ANNO_MICSUM_GEN_URI));
+
+ var generator = this._localGenerators[generatorURI.spec] ||
+ new MicrosummaryGenerator(generatorURI);
+
+ var microsummary = new Microsummary(pageURI, generator);
+
+ // A microsummary observer that calls the microsummary service
+ // to update the datastore when the microsummary finishes loading.
+ var observer = {
+ _svc: this,
+ _bookmarkID: bookmarkID,
+ onContentLoaded: function MSS_observer_onContentLoaded(microsummary) {
+ try {
+ this._svc._updateMicrosummary(this._bookmarkID, microsummary);
+ }
+ finally {
+ this._svc = null;
+ this._bookmarkID = null;
+ microsummary.removeObserver(this);
+ }
+ },
+
+ onError: function MSS_observer_onError(microsummary) {
+ if (microsummary.needsRemoval)
+ this._svc.removeMicrosummary(this._bookmarkID);
+ }
+ };
+
+ // Register the observer with the microsummary and trigger the microsummary
+ // to update itself.
+ microsummary.addObserver(observer);
+ microsummary.update();
+
+ return microsummary;
+ }
+};
+
+
+
+
+
+function LiveTitleNotificationSubject(bookmarkID, microsummary) {
+ this.bookmarkID = bookmarkID;
+ this.microsummary = microsummary;
+}
+
+LiveTitleNotificationSubject.prototype = {
+ bookmarkID: null,
+ microsummary: null,
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsILiveTitleNotificationSubject]),
+};
+
+
+
+
+
+function Microsummary(aPageURI, aGenerator) {
+ this._observers = [];
+ this._pageURI = aPageURI || null;
+ this._generator = aGenerator || null;
+ this._content = null;
+ this._pageContent = null;
+ this._updateInterval = null;
+ this._needsRemoval = false;
+}
+
+Microsummary.prototype = {
+ // The microsummary service.
+ __mss: null,
+ get _mss() {
+ if (!this.__mss)
+ this.__mss = Cc["@mozilla.org/microsummary/service;1"].
+ getService(Ci.nsIMicrosummaryService);
+ return this.__mss;
+ },
+
+ // IO Service
+ __ios: null,
+ get _ios() {
+ if (!this.__ios)
+ this.__ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__ios;
+ },
+
+ /**
+ * Make a URI from a spec.
+ * @param spec
+ * The string spec of the URI.
+ * @returns An nsIURI object.
+ */
+ _uri: function MSS__uri(spec) {
+ return this._ios.newURI(spec, null, null);
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIMicrosummary]),
+
+ // nsIMicrosummary
+ get content() {
+ // If we have everything we need to generate the content, generate it.
+ if (!this._content &&
+ this.generator.loaded &&
+ (this.pageContent || !this.generator.needsPageContent)) {
+ this._content = this.generator.generateMicrosummary(this.pageContent);
+ this._updateInterval = this.generator.calculateUpdateInterval(this.pageContent);
+ }
+
+ // Note: we return "null" if the content wasn't already generated and we
+ // couldn't retrieve it from the generated title annotation or generate it
+ // ourselves. So callers shouldn't count on getting content; instead,
+ // they should call update if the return value of this getter is "null",
+ // setting an observer to tell them when content generation is done.
+ return this._content;
+ },
+
+ get generator() { return this._generator },
+ set generator(newValue) { return this._generator = newValue },
+
+ get pageURI() { return this._pageURI },
+
+ equals: function(aOther) {
+ if (this._generator &&
+ this._pageURI.equals(aOther.pageURI) &&
+ this._generator.equals(aOther.generator))
+ return true;
+
+ return false;
+ },
+
+ get pageContent() {
+ if (!this._pageContent) {
+ // If the page is currently loaded into a browser window, use that.
+ var resource = getLoadedMicrosummaryResource(this.pageURI);
+ if (resource) {
+ this._pageContent = resource.content;
+ resource.destroy();
+ }
+ }
+
+ return this._pageContent;
+ },
+ set pageContent(newValue) { return this._pageContent = newValue },
+
+ get updateInterval() { return this._updateInterval; },
+ set updateInterval(newValue) { return this._updateInterval = newValue; },
+
+ get needsRemoval() { return this._needsRemoval; },
+
+ // nsIMicrosummary
+
+ addObserver: function MS_addObserver(observer) {
+ // Register the observer, but only if it isn't already registered,
+ // so that we don't call the same observer twice for any given change.
+ if (this._observers.indexOf(observer) == -1)
+ this._observers.push(observer);
+ },
+
+ removeObserver: function MS_removeObserver(observer) {
+ //NS_ASSERT(this._observers.indexOf(observer) != -1,
+ // "can't remove microsummary observer " + observer + ": not registered");
+
+ //this._observers =
+ // this._observers.filter(function(i) { observer != i });
+ if (this._observers.indexOf(observer) != -1)
+ this._observers.splice(this._observers.indexOf(observer), 1);
+ },
+
+ /**
+ * Regenerates the microsummary, asynchronously downloading its generator
+ * and content as needed.
+ *
+ */
+ update: function MS_update() {
+ LOG("microsummary.update called for page:\n " + this.pageURI.spec +
+ "\nwith generator:\n " + this.generator.uri.spec);
+
+ var t = this;
+
+ // We use a common error callback here to flag this microsummary for removal
+ // if either the generator or page content have gone permanently missing.
+ var errorCallback = function MS_errorCallback(resource) {
+ if (resource.status == 410) {
+ t._needsRemoval = true;
+ LOG("server indicated " + resource.uri.spec + " is gone. flagging for removal");
+ }
+
+ resource.destroy();
+
+ for (let i = 0; i < t._observers.length; i++)
+ t._observers[i].onError(t);
+ };
+
+ // If we don't have the generator, download it now. After it downloads,
+ // we'll re-call this method to continue updating the microsummary.
+ if (!this.generator.loaded) {
+ // If this generator is identified by a URN, then it's a local generator
+ // that should have been cached on application start, so it's missing.
+ if (this.generator.uri.scheme == "urn") {
+ // If it was installed via nsSidebar::addMicrosummaryGenerator (i.e. it
+ // has a URN that identifies the source URL from which we installed it),
+ // try to reinstall it (once).
+ if (/^source:/.test(this.generator.uri.path)) {
+ this._reinstallMissingGenerator();
+ return;
+ }
+ else
+ throw "missing local generator: " + this.generator.uri.spec;
+ }
+
+ LOG("generator not yet loaded; downloading it");
+ var generatorCallback =
+ function MS_generatorCallback(resource) {
+ try { t._handleGeneratorLoad(resource) }
+ finally { resource.destroy() }
+ };
+ var resource = new MicrosummaryResource(this.generator.uri);
+ resource.load(generatorCallback, errorCallback);
+ return;
+ }
+
+ // If we need the page content, and we don't have it, download it now.
+ // Afterwards we'll re-call this method to continue updating the microsummary.
+ if (this.generator.needsPageContent && !this.pageContent) {
+ LOG("page content not yet loaded; downloading it");
+ var pageCallback =
+ function MS_pageCallback(resource) {
+ try { t._handlePageLoad(resource) }
+ finally { resource.destroy() }
+ };
+ var resource = new MicrosummaryResource(this.pageURI);
+ resource.load(pageCallback, errorCallback);
+ return;
+ }
+
+ LOG("generator (and page, if needed) both loaded; generating microsummary");
+
+ // Now that we have both the generator and (if needed) the page content,
+ // generate the microsummary, then let the observers know about it.
+ this._content = this.generator.generateMicrosummary(this.pageContent);
+ this._updateInterval = this.generator.calculateUpdateInterval(this.pageContent);
+ this.pageContent = null;
+ for ( var i = 0; i < this._observers.length; i++ )
+ this._observers[i].onContentLoaded(this);
+
+ LOG("generated microsummary: " + this.content);
+ },
+
+ _handleGeneratorLoad: function MS__handleGeneratorLoad(resource) {
+ LOG(this.generator.uri.spec + " microsummary generator downloaded");
+ if (resource.isXML)
+ this.generator.initFromXML(resource.content);
+ else if (resource.contentType == "text/plain")
+ this.generator.initFromText(resource.content);
+ else if (resource.contentType == "text/html")
+ this.generator.initFromText(resource.content.body.textContent);
+ else
+ throw("generator is neither XML nor plain text");
+
+ // Only trigger a [content] update if we were able to init the generator.
+ if (this.generator.loaded)
+ this.update();
+ },
+
+ _handlePageLoad: function MS__handlePageLoad(resource) {
+ if (!resource.isXML && resource.contentType != "text/html")
+ throw("page is neither HTML nor XML");
+
+ this.pageContent = resource.content;
+ this.update();
+ },
+
+ /**
+ * Try to reinstall a missing local generator that was originally installed
+ * from a URL using nsSidebar::addMicrosumaryGenerator.
+ *
+ */
+ _reinstallMissingGenerator: function MS__reinstallMissingGenerator() {
+ LOG("attempting to reinstall missing generator " + this.generator.uri.spec);
+
+ var t = this;
+
+ var loadCallback =
+ function MS_missingGeneratorLoadCallback(resource) {
+ try { t._handleMissingGeneratorLoad(resource) }
+ finally { resource.destroy() }
+ };
+
+ var errorCallback =
+ function MS_missingGeneratorErrorCallback(resource) {
+ try { t._handleMissingGeneratorError(resource) }
+ finally { resource.destroy() }
+ };
+
+ try {
+ // Extract the URI from which the generator was originally installed.
+ var sourceURL = this.generator.uri.path.replace(/^source:/, "");
+ var sourceURI = this._uri(sourceURL);
+
+ var resource = new MicrosummaryResource(sourceURI);
+ resource.load(loadCallback, errorCallback);
+ }
+ catch(ex) {
+ Cu.reportError(ex);
+ this._handleMissingGeneratorError();
+ }
+ },
+
+ /**
+ * Handle a load event for a missing local generator by trying to reinstall
+ * the generator. If this fails, call _handleMissingGeneratorError to unset
+ * microsummaries for bookmarks using this generator so we don't repeatedly
+ * try to reinstall the generator, creating too much traffic to the website
+ * from which we downloaded it.
+ *
+ * @param resource
+ * the nsIMicrosummaryResource representing the downloaded generator
+ *
+ */
+ _handleMissingGeneratorLoad: function MS__handleMissingGeneratorLoad(resource) {
+ try {
+ // Make sure the generator is XML, since local generators have to be.
+ if (!resource.isXML)
+ throw("downloaded, but not XML " + this.generator.uri.spec);
+
+ // Store the generator's ID in its XML definition.
+ var generatorID = this.generator.uri.spec;
+ resource.content.documentElement.setAttribute("uri", generatorID);
+
+ // Reinstall the generator and replace our placeholder generator object
+ // with the newly installed generator.
+ this.generator = this._mss.installGenerator(resource.content);
+
+ // A reinstalled generator should always be loaded. But just in case
+ // it isn't, throw an error so we don't get into an infinite loop
+ // (otherwise this._update would try again to reinstall it).
+ if (!this.generator.loaded)
+ throw("supposedly installed, but not in cache " + this.generator.uri.spec);
+ }
+ catch(ex) {
+ Cu.reportError(ex);
+ this._handleMissingGeneratorError(resource);
+ return;
+ }
+
+ LOG("reinstall succeeded; resuming update " + this.generator.uri.spec);
+ this.update();
+ },
+
+ /**
+ * Handle an error event for a missing local generator load by unsetting
+ * the microsummaries for bookmarks using this generator so we don't
+ * repeatedly try to reinstall the generator, creating too much traffic
+ * to the website from which we downloaded it.
+ *
+ * @param resource
+ * the nsIMicrosummaryResource representing the downloaded generator
+ *
+ */
+ _handleMissingGeneratorError: function MS__handleMissingGeneratorError(resource) {
+ LOG("reinstall failed; removing microsummaries " + this.generator.uri.spec);
+ var bookmarks = this._mss.getBookmarks();
+ while (bookmarks.hasMoreElements()) {
+ var bookmarkID = bookmarks.getNext();
+ var microsummary = this._mss.getMicrosummary(bookmarkID);
+ if (microsummary.generator.uri.equals(this.generator.uri)) {
+ LOG("removing microsummary for " + microsummary.pageURI.spec);
+ this._mss.removeMicrosummary(bookmarkID);
+ }
+ }
+ }
+
+};
+
+
+
+
+
+function MicrosummaryGenerator(aURI, aLocalURI, aName) {
+ this._uri = aURI || null;
+ this._localURI = aLocalURI || null;
+ this._name = aName || null;
+ this._loaded = false;
+ this._rules = [];
+ this._template = null;
+ this._content = null;
+}
+
+MicrosummaryGenerator.prototype = {
+
+ // IO Service
+ __ios: null,
+ get _ios() {
+ if (!this.__ios)
+ this.__ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__ios;
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIMicrosummaryGenerator]),
+
+ // nsIMicrosummaryGenerator
+
+ // Normally this is just the URL from which we download the generator,
+ // but for generators stored in the app or profile generators directory
+ // it's the value of the generator tag's "uri" attribute (or its local URI
+ // should the "uri" attribute be missing).
+ get uri() { return this._uri || this.localURI },
+
+ // For generators bundled with the browser or installed by the user,
+ // the local URI is the URI of the local file containing the generator XML.
+ get localURI() { return this._localURI },
+ get name() { return this._name },
+ get loaded() { return this._loaded },
+
+ equals: function(aOther) {
+ // XXX: could the uri attribute for an exposed generator ever be null?
+ return aOther.uri.equals(this.uri);
+ },
+
+ /**
+ * Determines whether or not the generator applies to a given URI.
+ * By default, the generator does not apply to any URI. In order for it
+ * to apply to a URI, the URI must match one or more of the generator's
+ * "include" rules and not match any of the generator's "exclude" rules.
+ *
+ * @param uri
+ * the URI to test to see if this generator applies to it
+ *
+ * @returns boolean
+ * whether or not the generator applies to the given URI
+ *
+ */
+ appliesToURI: function(uri) {
+ var applies = false;
+
+ for ( var i = 0 ; i < this._rules.length ; i++ ) {
+ var rule = this._rules[i];
+
+ switch (rule.type) {
+ case "include":
+ if (rule.regexp.test(uri.spec))
+ applies = true;
+ break;
+ case "exclude":
+ if (rule.regexp.test(uri.spec))
+ return false;
+ break;
+ }
+ }
+
+ return applies;
+ },
+
+ get needsPageContent() {
+ if (this._template)
+ return true;
+ if (this._content)
+ return false;
+
+ throw("needsPageContent called on uninitialized microsummary generator");
+ },
+
+ /**
+ * Initializes a generator from text content. Generators initialized
+ * from text content merely return that content when their generate() method
+ * gets called.
+ *
+ * @param text
+ * the text content
+ */
+ initFromText: function(text) {
+ this._content = text;
+ this._loaded = true;
+ },
+
+ /**
+ * Initializes a generator from an XML description of it.
+ *
+ * @param xmlDocument
+ * An XMLDocument object describing a microsummary generator.
+ *
+ */
+ initFromXML: function(xmlDocument) {
+ // XXX Make sure the argument is a valid generator XML document.
+
+ // XXX I would have wanted to retrieve the info from the XML via E4X,
+ // but we'll need to pass the XSLT transform sheet to the XSLT processor,
+ // and the processor can't deal with an E4X-wrapped template node.
+
+ // XXX Right now the code retrieves the first "generator" element
+ // in the microsummaries namespace, regardless of whether or not
+ // it's the root element. Should it matter?
+ var generatorNode = xmlDocument.getElementsByTagNameNS(MICSUM_NS, "generator")[0];
+ if (!generatorNode)
+ throw Cr.NS_ERROR_FAILURE;
+
+ this._name = generatorNode.getAttribute("name");
+
+ // We have to retrieve the URI from local generators via the "uri" attribute
+ // of its generator tag.
+ if (this.localURI && generatorNode.hasAttribute("uri"))
+ this._uri = this._ios.newURI(generatorNode.getAttribute("uri"), null, null);
+
+ function getFirstChildByTagName(tagName, parentNode, namespace) {
+ var nodeList = parentNode.getElementsByTagNameNS(namespace, tagName);
+ for (var i = 0; i < nodeList.length; i++) {
+ // Make sure that the node is a direct descendent of the generator node
+ if (nodeList[i].parentNode == parentNode)
+ return nodeList[i];
+ }
+ return null;
+ }
+
+ // Slurp the include/exclude rules that determine the pages to which
+ // this generator applies. Order is important, so we add the rules
+ // in the order in which they appear in the XML.
+ this._rules.splice(0);
+ var pages = getFirstChildByTagName("pages", generatorNode, MICSUM_NS);
+ if (pages) {
+ // XXX Make sure the pages tag exists.
+ for ( var i = 0; i < pages.childNodes.length ; i++ ) {
+ var node = pages.childNodes[i];
+ if (node.nodeType != node.ELEMENT_NODE ||
+ node.namespaceURI != MICSUM_NS ||
+ (node.nodeName != "include" && node.nodeName != "exclude"))
+ continue;
+ var urlRegexp = node.textContent.replace(/^\s+|\s+$/g, "");
+ this._rules.push({ type: node.nodeName, regexp: new RegExp(urlRegexp) });
+ }
+ }
+
+ // allow the generators to set individual update values (even varying
+ // depending on certain XPath expressions)
+ var update = getFirstChildByTagName("update", generatorNode, MICSUM_NS);
+ if (update) {
+ function _parseInterval(string) {
+ // convert from minute fractions to milliseconds
+ // and ensure a minimum value of 1 minute
+ return Math.round(Math.max(parseFloat(string) || 0, 1) * 60 * 1000);
+ }
+
+ this._unconditionalUpdateInterval =
+ update.hasAttribute("interval") ?
+ _parseInterval(update.getAttribute("interval")) : null;
+
+ // collect the <condition expression="XPath Expression" interval="time"/> clauses
+ this._updateIntervals = new Array();
+ for (i = 0; i < update.childNodes.length; i++) {
+ node = update.childNodes[i];
+ if (node.nodeType != node.ELEMENT_NODE || node.namespaceURI != MICSUM_NS ||
+ node.nodeName != "condition")
+ continue;
+ if (!node.getAttribute("expression") || !node.getAttribute("interval")) {
+ LOG("ignoring incomplete conditional update interval for " + this.uri.spec);
+ continue;
+ }
+ this._updateIntervals.push({
+ expression: node.getAttribute("expression"),
+ interval: _parseInterval(node.getAttribute("interval"))
+ });
+ }
+ }
+
+ var templateNode = getFirstChildByTagName("template", generatorNode, MICSUM_NS);
+ if (templateNode) {
+ this._template = getFirstChildByTagName("transform", templateNode, XSLT_NS) ||
+ getFirstChildByTagName("stylesheet", templateNode, XSLT_NS);
+ }
+ // XXX Make sure the template is a valid XSL transform sheet.
+
+ this._loaded = true;
+ },
+
+ generateMicrosummary: function MSD_generateMicrosummary(pageContent) {
+
+ var content;
+
+ if (this._content)
+ content = this._content;
+ else if (this._template)
+ content = this._processTemplate(pageContent);
+ else
+ throw("generateMicrosummary called on uninitialized microsummary generator");
+
+ // Clean up the output
+ content = content.replace(/^\s+|\s+$/g, "");
+ if (content.length > MAX_SUMMARY_LENGTH)
+ content = content.substring(0, MAX_SUMMARY_LENGTH);
+
+ return content;
+ },
+
+ calculateUpdateInterval: function MSD_calculateUpdateInterval(doc) {
+ if (this._content || !this._updateIntervals || !doc)
+ return null;
+
+ for (var i = 0; i < this._updateIntervals.length; i++) {
+ try {
+ if (doc.evaluate(this._updateIntervals[i].expression, doc, null,
+ Ci.nsIDOMXPathResult.BOOLEAN_TYPE, null).booleanValue)
+ return this._updateIntervals[i].interval;
+ }
+ catch (ex) {
+ Cu.reportError(ex);
+ // remove the offending conditional update interval
+ this._updateIntervals.splice(i--, 1);
+ }
+ }
+
+ return this._unconditionalUpdateInterval;
+ },
+
+ _processTemplate: function MSD__processTemplate(doc) {
+ LOG("processing template " + this._template + " against document " + doc);
+
+ // XXX Should we just have one global instance of the processor?
+ var processor = Cc["@mozilla.org/document-transformer;1?type=xslt"].
+ createInstance(Ci.nsIXSLTProcessor);
+
+ // Turn off document loading of all kinds (document(), <include>, <import>)
+ // for security (otherwise local generators would be able to load local files).
+ processor.flags |= Ci.nsIXSLTProcessorPrivate.DISABLE_ALL_LOADS;
+
+ processor.importStylesheet(this._template);
+ var fragment = processor.transformToFragment(doc, doc);
+
+ LOG("template processing result: " + fragment.textContent);
+
+ // XXX When we support HTML microsummaries we'll need to do something
+ // more sophisticated than just returning the text content of the fragment.
+ return fragment.textContent;
+ },
+
+ saveXMLToFile: function MSD_saveXMLToFile(xmlDefinition) {
+ var file = this.localURI.QueryInterface(Ci.nsIFileURL).file.clone();
+
+ LOG("saving definition to " + file.path);
+
+ // Write the generator XML to the local file.
+ var outputStream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ var localFile = file.QueryInterface(Ci.nsILocalFile);
+ outputStream.init(localFile, (MODE_WRONLY | MODE_TRUNCATE | MODE_CREATE),
+ PERMS_FILE, 0);
+ var serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"].
+ createInstance(Ci.nsIDOMSerializer);
+ serializer.serializeToStream(xmlDefinition, outputStream, null);
+ if (outputStream instanceof Ci.nsISafeOutputStream) {
+ try { outputStream.finish() }
+ catch (e) { outputStream.close() }
+ }
+ else
+ outputStream.close();
+ },
+
+ update: function MSD_update() {
+ // Update this generator if it was downloaded from a remote source and has
+ // been modified since we last downloaded it.
+ var genURI = this.uri;
+ if (genURI && /^urn:source:/i.test(genURI.spec)) {
+ let genURL = genURI.spec.replace(/^urn:source:/, "");
+ genURI = this._ios.newURI(genURL, null, null);
+ }
+
+ // Only continue if we have a valid remote URI
+ if (!genURI || !/^https?/.test(genURI.scheme)) {
+ LOG("generator did not have valid URI; skipping update: " + genURI.spec);
+ return;
+ }
+
+ // We use a HEAD request to check if the generator has been modified since
+ // the last time we downloaded it. If it has, we move to _preformUpdate() to
+ // actually download and save the new generator.
+ var t = this;
+ var loadCallback = function(resource) {
+ if (resource.status != 304)
+ t._performUpdate(genURI);
+ else
+ LOG("generator is already up to date: " + genURI.spec);
+ resource.destroy();
+ };
+ var errorCallback = function(resource) {
+ resource.destroy();
+ };
+
+ var file = this.localURI.QueryInterface(Ci.nsIFileURL).file.clone();
+ var lastmod = new Date(file.lastModifiedTime);
+ LOG("updating generator: " + genURI.spec);
+ var resource = new MicrosummaryResource(genURI);
+ resource.lastMod = lastmod.toUTCString();
+ resource.method = "HEAD";
+ resource.load(loadCallback, errorCallback);
+ },
+
+ _performUpdate: function MSD__performUpdate(uri) {
+ var t = this;
+ var loadCallback = function(resource) {
+ try { t._handleUpdateLoad(resource) }
+ finally { resource.destroy() }
+ };
+ var errorCallback = function(resource) {
+ resource.destroy();
+ };
+
+ var resource = new MicrosummaryResource(uri);
+ resource.load(loadCallback, errorCallback);
+ },
+
+ _handleUpdateLoad: function MSD__handleUpdateLoad(resource) {
+ if (!resource.isXML)
+ throw("update failed, downloaded resource is not XML: " + this.uri.spec);
+
+ // Preserve the generator's ID.
+ // XXX Check for redirects and update the URI if it changes.
+ var generatorID = this.uri.spec;
+ resource.content.documentElement.setAttribute("uri", generatorID);
+
+ // Reinitialize this generator with the newly downloaded XML and save to disk.
+ this.initFromXML(resource.content);
+ this.saveXMLToFile(resource.content);
+
+ // Let observers know we've updated this generator
+ var obs = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ obs.notifyObservers(this, "microsummary-generator-updated", null);
+ }
+};
+
+
+
+
+
+// Microsummary sets are collections of microsummaries. They allow callers
+// to register themselves as observers of the set, and when any microsummary
+// in the set changes, the observers get notified. Thus a caller can observe
+// the set instead of each individual microsummary.
+
+function MicrosummarySet() {
+ this._observers = [];
+ this._elements = [];
+}
+
+MicrosummarySet.prototype = {
+ // IO Service
+ __ios: null,
+ get _ios() {
+ if (!this.__ios)
+ this.__ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__ios;
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIMicrosummarySet,
+ Ci.nsIMicrosummaryObserver]),
+
+ // nsIMicrosummaryObserver
+
+ onContentLoaded: function MSSet_onContentLoaded(microsummary) {
+ for ( var i = 0; i < this._observers.length; i++ )
+ this._observers[i].onContentLoaded(microsummary);
+ },
+
+ onError: function MSSet_onError(microsummary) {
+ for ( var i = 0; i < this._observers.length; i++ )
+ this._observers[i].onError(microsummary);
+ },
+
+ // nsIMicrosummarySet
+
+ addObserver: function MSSet_addObserver(observer) {
+ if (this._observers.length == 0) {
+ for ( var i = 0 ; i < this._elements.length ; i++ )
+ this._elements[i].addObserver(this);
+ }
+
+ // Register the observer, but only if it isn't already registered,
+ // so that we don't call the same observer twice for any given change.
+ if (this._observers.indexOf(observer) == -1)
+ this._observers.push(observer);
+ },
+
+ removeObserver: function MSSet_removeObserver(observer) {
+ //NS_ASSERT(this._observers.indexOf(observer) != -1,
+ // "can't remove microsummary observer " + observer + ": not registered");
+
+ //this._observers =
+ // this._observers.filter(function(i) { observer != i });
+ if (this._observers.indexOf(observer) != -1)
+ this._observers.splice(this._observers.indexOf(observer), 1);
+
+ if (this._observers.length == 0) {
+ for ( var i = 0 ; i < this._elements.length ; i++ )
+ this._elements[i].removeObserver(this);
+ }
+ },
+
+ extractFromPage: function MSSet_extractFromPage(resource) {
+ if (!resource.isXML && resource.contentType != "text/html")
+ throw("page is neither HTML nor XML");
+
+ // XXX Handle XML documents, whose microsummaries are specified
+ // via processing instructions.
+
+ var links = resource.content.getElementsByTagName("link");
+ for ( var i = 0; i < links.length; i++ ) {
+ var link = links[i];
+
+ if(!link.hasAttribute("rel"))
+ continue;
+
+ var relAttr = link.getAttribute("rel");
+
+ // The attribute's value can be a space-separated list of link types,
+ // check to see if "microsummary" is one of them.
+ var linkTypes = relAttr.split(/\s+/);
+ if (!linkTypes.some( function(v) { return v.toLowerCase() == "microsummary"; }))
+ continue;
+
+
+ // Look for a TITLE attribute to give the generator a nice name in the UI.
+ var linkTitle = link.getAttribute("title");
+
+
+ // Unlike the "href" attribute, the "href" property contains
+ // an absolute URI spec, so we use it here to create the URI.
+ var generatorURI = this._ios.newURI(link.href,
+ resource.content.characterSet,
+ null);
+
+ if (!/^https?$/i.test(generatorURI.scheme)) {
+ LOG("can't load generator " + generatorURI.spec + " from page " +
+ resource.uri.spec);
+ continue;
+ }
+
+ var generator = new MicrosummaryGenerator(generatorURI, null, linkTitle);
+ var microsummary = new Microsummary(resource.uri, generator);
+ if (!this.hasItemForMicrosummary(microsummary))
+ this.AppendElement(microsummary);
+ }
+ },
+
+ /**
+ * Determines whether the given microsumary is already represented in the
+ * set.
+ */
+ hasItemForMicrosummary: function MSSet_hasItemForMicrosummary(aMicrosummary) {
+ for (var i = 0; i < this._elements.length; i++) {
+ if (this._elements[i].equals(aMicrosummary))
+ return true;
+ }
+ return false;
+ },
+
+ // XXX Turn this into a complete implementation of nsICollection?
+ AppendElement: function MSSet_AppendElement(element) {
+ // Query the element to a microsummary.
+ // XXX Should we NS_ASSERT if this fails?
+ element = element.QueryInterface(Ci.nsIMicrosummary);
+
+ if (this._elements.indexOf(element) == -1) {
+ this._elements.push(element);
+ element.addObserver(this);
+ }
+
+ // Notify observers that an element has been appended.
+ for ( var i = 0; i < this._observers.length; i++ )
+ this._observers[i].onElementAppended(element);
+ },
+
+ Enumerate: function MSSet_Enumerate() {
+ return new ArrayEnumerator(this._elements);
+ }
+};
+
+
+
+
+
+/**
+ * An enumeration of items in a JS array.
+ * @constructor
+ */
+function ArrayEnumerator(aItems) {
+ if (aItems) {
+ for (var i = 0; i < aItems.length; ++i) {
+ if (!aItems[i])
+ aItems.splice(i--, 1);
+ }
+ this._contents = aItems;
+ } else {
+ this._contents = [];
+ }
+}
+
+ArrayEnumerator.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
+
+ _index: 0,
+
+ hasMoreElements: function() {
+ return this._index < this._contents.length;
+ },
+
+ getNext: function() {
+ return this._contents[this._index++];
+ }
+};
+
+
+
+
+
+/**
+ * Outputs aText to the JavaScript console as well as to stdout if the
+ * microsummary logging pref (browser.microsummary.log) is set to true.
+ *
+ * @param aText
+ * the text to log
+ */
+function LOG(aText) {
+ var f = arguments.callee;
+ if (!("_enabled" in f))
+ f._enabled = getPref("browser.microsummary.log", false);
+ if (f._enabled) {
+ dump("*** Microsummaries: " + aText + "\n");
+ var consoleService = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ consoleService.logStringMessage(aText);
+ }
+}
+
+
+
+
+
+/**
+ * A resource (page, microsummary, generator, etc.) identifiable by URI.
+ * This object abstracts away much of the code for loading resources
+ * and parsing their content if they are XML or HTML.
+ *
+ * @constructor
+ *
+ * @param uri
+ * the location of the resource
+ *
+ */
+function MicrosummaryResource(uri) {
+ // Make sure we're not loading javascript: or data: URLs, which could
+ // take advantage of the load to run code with chrome: privileges.
+ // XXX Perhaps use nsIScriptSecurityManager.checkLoadURI instead.
+ if (!(uri.schemeIs("http") || uri.schemeIs("https") || uri.schemeIs("file")))
+ throw NS_ERROR_DOM_BAD_URI;
+
+ this._uri = uri;
+ this._content = null;
+ this._contentType = null;
+ this._isXML = false;
+ this.__authFailed = false;
+ this._status = null;
+ this._method = "GET";
+ this._lastMod = null;
+
+ // A function to call when we finish loading/parsing the resource.
+ this._loadCallback = null;
+ // A function to call if we get an error while loading/parsing the resource.
+ this._errorCallback = null;
+ // A hidden iframe to parse HTML content.
+ this._iframe = null;
+}
+
+MicrosummaryResource.prototype = {
+ // IO Service
+ __ios: null,
+ get _ios() {
+ if (!this.__ios)
+ this.__ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__ios;
+ },
+
+ get uri() {
+ return this._uri;
+ },
+
+ get content() {
+ return this._content;
+ },
+
+ get contentType() {
+ return this._contentType;
+ },
+
+ get isXML() {
+ return this._isXML;
+ },
+
+ get status() { return this._status },
+ set status(aStatus) { this._status = aStatus },
+
+ get method() { return this._method },
+ set method(aMethod) { this._method = aMethod },
+
+ get lastMod() { return this._lastMod },
+ set lastMod(aMod) { this._lastMod = aMod },
+
+ // Implement notification callback interfaces so we can suppress UI
+ // and abort loads for bad SSL certs and HTTP authorization requests.
+
+ // Interfaces this component implements.
+ interfaces: [Ci.nsIAuthPromptProvider,
+ Ci.nsIAuthPrompt,
+ Ci.nsIBadCertListener2,
+ Ci.nsISSLErrorListener,
+ Ci.nsIPrompt,
+ Ci.nsIProgressEventSink,
+ Ci.nsIInterfaceRequestor,
+ Ci.nsISupports],
+
+ // nsISupports
+
+ QueryInterface: function MSR_QueryInterface(iid) {
+ if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
+ throw Cr.NS_ERROR_NO_INTERFACE;
+
+ // nsIAuthPrompt and nsIPrompt need separate implementations because
+ // their method signatures conflict. The other interfaces we implement
+ // within MicrosummaryResource itself.
+ switch(iid) {
+ case Ci.nsIAuthPrompt:
+ return this.authPrompt;
+ case Ci.nsIPrompt:
+ return this.prompt;
+ default:
+ return this;
+ }
+ },
+
+ // nsIInterfaceRequestor
+
+ getInterface: function MSR_getInterface(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ // nsIBadCertListener2
+ // Suppress any certificate errors
+ notifyCertProblem: function MSR_certProblem(socketInfo, status, targetSite) {
+ return true;
+ },
+
+ // nsISSLErrorListener
+ // Suppress any ssl errors
+ notifySSLError: function MSR_SSLError(socketInfo, error, targetSite) {
+ return true;
+ },
+
+
+ // Suppress UI and abort loads for files secured by authentication.
+
+ // Auth requests appear to succeed when we cancel them (since the server
+ // redirects us to a "you're not authorized" page), so we have to set a flag
+ // to let the load handler know to treat the load as a failure.
+ get _authFailed() { return this.__authFailed; },
+ set _authFailed(newValue) { return this.__authFailed = newValue },
+
+ // nsIAuthPromptProvider
+
+ getAuthPrompt: function(aPromptReason, aIID) {
+ this._authFailed = true;
+ throw Cr.NS_ERROR_NOT_AVAILABLE;
+ },
+
+ // HTTP always requests nsIAuthPromptProvider first, so it never needs
+ // nsIAuthPrompt, but not all channels use nsIAuthPromptProvider, so we
+ // implement nsIAuthPrompt too.
+
+ // nsIAuthPrompt
+
+ get authPrompt() {
+ var resource = this;
+ return {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrompt]),
+ prompt: function(dialogTitle, text, passwordRealm, savePassword, defaultText, result) {
+ resource._authFailed = true;
+ return false;
+ },
+ promptUsernameAndPassword: function(dialogTitle, text, passwordRealm, savePassword, user, pwd) {
+ resource._authFailed = true;
+ return false;
+ },
+ promptPassword: function(dialogTitle, text, passwordRealm, savePassword, pwd) {
+ resource._authFailed = true;
+ return false;
+ }
+ };
+ },
+
+ // nsIPrompt
+
+ get prompt() {
+ var resource = this;
+ return {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrompt]),
+ alert: function(dialogTitle, text) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ alertCheck: function(dialogTitle, text, checkMessage, checkValue) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ confirm: function(dialogTitle, text) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ confirmCheck: function(dialogTitle, text, checkMessage, checkValue) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ confirmEx: function(dialogTitle, text, buttonFlags, button0Title, button1Title, button2Title, checkMsg, checkValue) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ prompt: function(dialogTitle, text, value, checkMsg, checkValue) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ promptPassword: function(dialogTitle, text, password, checkMsg, checkValue) {
+ resource._authFailed = true;
+ return false;
+ },
+ promptUsernameAndPassword: function(dialogTitle, text, username, password, checkMsg, checkValue) {
+ resource._authFailed = true;
+ return false;
+ },
+ select: function(dialogTitle, text, count, selectList, outSelection) {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ }
+ };
+ },
+
+ // XXX We implement nsIProgressEventSink because otherwise bug 253127
+ // would cause too many extraneous errors to get reported to the console.
+ // Fortunately this doesn't screw up XMLHttpRequest, because it ensures
+ // that its implementation of nsIProgressEventSink will always get called
+ // in addition to whatever notification callbacks we set on the channel.
+
+ // nsIProgressEventSink
+
+ onProgress: function(aRequest, aContext, aProgress, aProgressMax) {},
+ onStatus: function(aRequest, aContext, aStatus, aStatusArg) {},
+
+ /**
+ * Initialize the resource from an existing DOM document object.
+ *
+ * @param document
+ * a DOM document object
+ *
+ */
+ initFromDocument: function MSR_initFromDocument(document) {
+ this._content = document;
+ this._contentType = document.contentType;
+
+ // Normally we set this property based on whether or not
+ // XMLHttpRequest parsed the content into an XML document object,
+ // but since we already have the content, we have to analyze
+ // its content type ourselves to see if it is XML.
+ this._isXML = (this.contentType == "text/xml" ||
+ this.contentType == "application/xml" ||
+ /^.+\/.+\+xml$/.test(this.contentType));
+ },
+
+ /**
+ * Destroy references to avoid leak-causing cycles. Instantiators must call
+ * this method on all instances they instantiate once they're done with them.
+ *
+ */
+ destroy: function MSR_destroy() {
+ this._uri = null;
+ this._content = null;
+ this._loadCallback = null;
+ this._errorCallback = null;
+ this._loadTimer = null;
+ this._authFailed = false;
+ if (this._iframe) {
+ if (this._iframe && this._iframe.parentNode)
+ this._iframe.parentNode.removeChild(this._iframe);
+ this._iframe = null;
+ }
+ },
+
+ /**
+ * Load the resource.
+ *
+ * @param loadCallback
+ * a function to invoke when the resource finishes loading
+ * @param errorCallback
+ * a function to invoke when an error occurs during the load
+ *
+ */
+ load: function MSR_load(loadCallback, errorCallback) {
+ LOG(this.uri.spec + " loading");
+
+ this._loadCallback = loadCallback;
+ this._errorCallback = errorCallback;
+
+ var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
+
+ var loadHandler = {
+ _self: this,
+ handleEvent: function MSR_loadHandler_handleEvent(event) {
+ if (this._self._loadTimer)
+ this._self._loadTimer.cancel();
+
+ this._self.status = event.target.status;
+
+ if (this._self._authFailed || this._self.status >= 400) {
+ // Technically the request succeeded, but we treat it as a failure,
+ // since we won't be able to extract anything relevant from the result.
+
+ // XXX For now HTTP is the only protocol we handle that might fail
+ // auth. This message will need to change once we support FTP, which
+ // returns 0 for all statuses.
+ LOG(this._self.uri.spec + " load failed; HTTP status: " + this._self.status);
+ try { this._self._handleError(event) }
+ finally { this._self = null }
+ }
+ else if (event.target.channel.contentType == "multipart/x-mixed-replace") {
+ // Technically the request succeeded, but we treat it as a failure,
+ // since we aren't able to handle multipart content.
+ LOG(this._self.uri.spec + " load failed; contains multipart content");
+ try { this._self._handleError(event) }
+ finally { this._self = null }
+ }
+ else {
+ LOG(this._self.uri.spec + " load succeeded; invoking callback");
+ try { this._self._handleLoad(event) }
+ finally { this._self = null }
+ }
+ }
+ };
+
+ var errorHandler = {
+ _self: this,
+ handleEvent: function MSR_errorHandler_handleEvent(event) {
+ if (this._self._loadTimer)
+ this._self._loadTimer.cancel();
+
+ LOG(this._self.uri.spec + " load failed");
+ try { this._self._handleError(event) }
+ finally { this._self = null }
+ }
+ };
+
+ // cancel loads that take too long
+ // timeout specified in seconds at browser.microsummary.requestTimeout,
+ // or 300 seconds (five minutes)
+ var timeout = getPref("browser.microsummary.requestTimeout", 300) * 1000;
+ var timerObserver = {
+ _self: this,
+ observe: function MSR_timerObserver_observe() {
+ LOG("timeout loading microsummary resource " + this._self.uri.spec + ", aborting request");
+ request.abort();
+ try { this._self.destroy() }
+ finally { this._self = null }
+ }
+ };
+ this._loadTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._loadTimer.init(timerObserver, timeout, Ci.nsITimer.TYPE_ONE_SHOT);
+
+ request = request.QueryInterface(Ci.nsIDOMEventTarget);
+ request.addEventListener("load", loadHandler, false);
+ request.addEventListener("error", errorHandler, false);
+
+ request = request.QueryInterface(Ci.nsIXMLHttpRequest);
+ request.open(this.method, this.uri.spec, true);
+ request.setRequestHeader("X-Moz", "microsummary");
+ if (this.lastMod)
+ request.setRequestHeader("If-Modified-Since", this.lastMod);
+
+ // Register ourselves as a listener for notification callbacks so we
+ // can handle authorization requests and SSL issues like cert mismatches.
+ // XMLHttpRequest will handle the notifications we don't handle.
+ request.channel.notificationCallbacks = this;
+
+ // If this is a bookmarked resource, and the bookmarks service recorded
+ // its charset in the bookmarks datastore the last time the user visited it,
+ // then specify the charset in the channel so XMLHttpRequest loads
+ // the resource correctly.
+ try {
+ var resolver = Cc["@mozilla.org/embeddor.implemented/bookmark-charset-resolver;1"].
+ getService(Ci.nsICharsetResolver);
+ if (resolver) {
+ var charset = resolver.requestCharset(null, request.channel, {}, {});
+ if (charset != "")
+ request.channel.contentCharset = charset;
+ }
+ }
+ catch(ex) {}
+
+ request.send(null);
+ },
+
+ _handleLoad: function MSR__handleLoad(event) {
+ var request = event.target;
+
+ if (request.responseXML) {
+ this._isXML = true;
+ // XXX Figure out the parsererror format and log a specific error.
+ if (request.responseXML.documentElement.nodeName == "parsererror") {
+ this._handleError(event);
+ return;
+ }
+ this._content = request.responseXML;
+ this._contentType = request.channel.contentType;
+ this._loadCallback(this);
+ }
+
+ else if (request.channel.contentType == "text/html") {
+ this._parse(request.responseText);
+ }
+
+ else {
+ // This catches text/plain as well as any other content types
+ // not accounted for by the content type-specific code above.
+ this._content = request.responseText;
+ this._contentType = request.channel.contentType;
+ this._loadCallback(this);
+ }
+ },
+
+ _handleError: function MSR__handleError(event) {
+ // Call the error callback, then destroy ourselves to prevent memory leaks.
+ try { if (this._errorCallback) this._errorCallback(this) }
+ finally { this.destroy() }
+ },
+
+ /**
+ * Parse a string of HTML text. Used by _load() when it retrieves HTML.
+ * We do this via hidden XUL iframes, which according to bz is the best way
+ * to do it currently, since bug 102699 is hard to fix.
+ *
+ * @param htmlText
+ * a string containing the HTML content
+ *
+ */
+ _parse: function MSR__parse(htmlText) {
+ // Find a window to stick our hidden iframe into.
+ var windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
+ getService(Ci.nsIWindowMediator);
+ var window = windowMediator.getMostRecentWindow("navigator:browser");
+ // XXX We can use other windows, too, so perhaps we should try to get
+ // some other window if there's no browser window open. Perhaps we should
+ // even prefer other windows, since there's less chance of any browser
+ // window machinery like throbbers treating our load like one initiated
+ // by the user.
+ if (!window) {
+ this._handleError(event);
+ return;
+ }
+ var document = window.document;
+ var rootElement = document.documentElement;
+
+ // Create an iframe, make it hidden, and secure it against untrusted content.
+ this._iframe = document.createElement('iframe');
+ this._iframe.setAttribute("collapsed", true);
+ this._iframe.setAttribute("type", "content");
+
+ // Insert the iframe into the window, creating the doc shell.
+ rootElement.appendChild(this._iframe);
+
+ // When we insert the iframe into the window, it immediately starts loading
+ // about:blank, which we don't need and could even hurt us (for example
+ // by triggering bugs like bug 344305), so cancel that load.
+ var webNav = this._iframe.docShell.QueryInterface(Ci.nsIWebNavigation);
+ webNav.stop(Ci.nsIWebNavigation.STOP_NETWORK);
+
+ // Turn off JavaScript and auth dialogs for security and other things
+ // to reduce network load.
+ // XXX We should also turn off CSS.
+ this._iframe.docShell.allowJavascript = false;
+ this._iframe.docShell.allowAuth = false;
+ this._iframe.docShell.allowPlugins = false;
+ this._iframe.docShell.allowMetaRedirects = false;
+ this._iframe.docShell.allowSubframes = false;
+ this._iframe.docShell.allowImages = false;
+
+ var parseHandler = {
+ _self: this,
+ handleEvent: function MSR_parseHandler_handleEvent(event) {
+ event.target.removeEventListener("DOMContentLoaded", this, false);
+ try { this._self._handleParse(event) }
+ finally { this._self = null }
+ }
+ };
+
+ // Convert the HTML text into an input stream.
+ var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
+ createInstance(Ci.nsIScriptableUnicodeConverter);
+ converter.charset = "UTF-8";
+ var stream = converter.convertToInputStream(htmlText);
+
+ // Set up a channel to load the input stream.
+ var channel = Cc["@mozilla.org/network/input-stream-channel;1"].
+ createInstance(Ci.nsIInputStreamChannel);
+ channel.setURI(this._uri);
+ channel.contentStream = stream;
+
+ // Load in the background so we don't trigger web progress listeners.
+ var request = channel.QueryInterface(Ci.nsIRequest);
+ request.loadFlags |= Ci.nsIRequest.LOAD_BACKGROUND;
+
+ // Specify the content type since we're not loading content from a server,
+ // so it won't get specified for us, and if we don't specify it ourselves,
+ // then Firefox will prompt the user to download content of "unknown type".
+ var baseChannel = channel.QueryInterface(Ci.nsIChannel);
+ baseChannel.contentType = "text/html";
+
+ // Load as UTF-8, which it'll always be, because XMLHttpRequest converts
+ // the text (i.e. XMLHTTPRequest.responseText) from its original charset
+ // to UTF-16, then the string input stream component converts it to UTF-8.
+ baseChannel.contentCharset = "UTF-8";
+
+ // Register the parse handler as a load event listener and start the load.
+ // Listen for "DOMContentLoaded" instead of "load" because background loads
+ // don't fire "load" events.
+ this._iframe.addEventListener("DOMContentLoaded", parseHandler, true);
+ var uriLoader = Cc["@mozilla.org/uriloader;1"].getService(Ci.nsIURILoader);
+ uriLoader.openURI(channel, true, this._iframe.docShell);
+ },
+
+ /**
+ * Handle a load event for the iframe-based parser.
+ *
+ * @param event
+ * the event object representing the load event
+ *
+ */
+ _handleParse: function MSR__handleParse(event) {
+ // XXX Make sure the parse was successful?
+
+ this._content = this._iframe.contentDocument;
+ this._contentType = this._iframe.contentDocument.contentType;
+ this._loadCallback(this);
+ }
+
+};
+
+/**
+ * Get a resource currently loaded into a browser window. Checks windows
+ * one at a time, starting with the frontmost (a.k.a. most recent) one.
+ *
+ * @param uri
+ * the URI of the resource
+ *
+ * @returns a Resource object, if the resource is currently loaded
+ * into a browser window; otherwise null
+ *
+ */
+function getLoadedMicrosummaryResource(uri) {
+ var mediator = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+
+ // Apparently the Z order enumerator is broken on Linux per bug 156333.
+ //var windows = mediator.getZOrderDOMWindowEnumerator("navigator:browser", true);
+ var windows = mediator.getEnumerator("navigator:browser");
+
+ while (windows.hasMoreElements()) {
+ var win = windows.getNext();
+ var tabBrowser = win.document.getElementById("content");
+ for ( var i = 0; i < tabBrowser.browsers.length; i++ ) {
+ var browser = tabBrowser.browsers[i];
+ if (uri.equals(browser.currentURI)) {
+ var resource = new MicrosummaryResource(uri);
+ resource.initFromDocument(browser.contentDocument);
+ return resource;
+ }
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Get a value from a pref or a default value if the pref doesn't exist.
+ *
+ * @param prefName
+ * @param defaultValue
+ * @returns the pref's value or the default (if it is missing)
+ */
+function getPref(prefName, defaultValue) {
+ try {
+ var prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ var type = prefBranch.getPrefType(prefName);
+ switch (type) {
+ case prefBranch.PREF_BOOL:
+ return prefBranch.getBoolPref(prefName);
+ case prefBranch.PREF_INT:
+ return prefBranch.getIntPref(prefName);
+ }
+ }
+ catch (ex) { /* return the default value */ }
+
+ return defaultValue;
+}
+
+
+// From http://lxr.mozilla.org/mozilla/source/browser/components/search/nsSearchService.js
+
+/**
+ * Removes all characters not in the "chars" string from aName.
+ *
+ * @returns a sanitized name to be used as a filename, or a random name
+ * if a sanitized name cannot be obtained (if aName contains
+ * no valid characters).
+ */
+function sanitizeName(aName) {
+ const chars = "-abcdefghijklmnopqrstuvwxyz0123456789";
+ const maxLength = 60;
+
+ var name = aName.toLowerCase();
+ name = name.replace(/ /g, "-");
+ //name = name.split("").filter(function (el) {
+ // return chars.indexOf(el) != -1;
+ // }).join("");
+ var filteredName = "";
+ for ( var i = 0 ; i < name.length ; i++ )
+ if (chars.indexOf(name[i]) != -1)
+ filteredName += name[i];
+ name = filteredName;
+
+ if (!name) {
+ // Our input had no valid characters - use a random name
+ for (var i = 0; i < 8; ++i)
+ name += chars.charAt(Math.round(Math.random() * (chars.length - 1)));
+ }
+
+ if (name.length > maxLength)
+ name = name.substring(0, maxLength);
+
+ return name;
+}
+
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule([MicrosummaryService]);
+}
diff --git a/bundles/XO/components/nsPlacesDBFlush.js b/bundles/XO/components/nsPlacesDBFlush.js
new file mode 100755
index 0000000..4e84d5f
--- /dev/null
+++ b/bundles/XO/components/nsPlacesDBFlush.js
@@ -0,0 +1,360 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2 expandtab
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ * Marco Bonardo <mak77@bonardo.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+const kQuitApplication = "quit-application";
+const kSyncFinished = "places-sync-finished";
+
+const kSyncPrefName = "syncDBTableIntervalInSecs";
+const kDefaultSyncInterval = 120;
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsPlacesDBFlush class
+
+function nsPlacesDBFlush()
+{
+ this._prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).
+ getBranch("places.");
+
+ // Get our sync interval
+ try {
+ // We want to silently fail if the preference does not exist, and use a
+ // default to fallback to.
+ this._syncInterval = this._prefs.getIntPref(kSyncPrefName);
+ if (this._syncInterval <= 0)
+ this._syncInterval = kDefaultSyncInterval;
+ }
+ catch (e) {
+ // The preference did not exist, so default to two minutes.
+ this._syncInterval = kDefaultSyncInterval;
+ }
+
+ // Register observers
+ this._os = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ this._os.addObserver(this, kQuitApplication, false);
+
+ this._prefs.QueryInterface(Ci.nsIPrefBranch2)
+ .addObserver("", this, false);
+
+ // Create our timer to update everything
+ this._timer = this._newTimer();
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// Smart Getters
+
+ this.__defineGetter__("_db", function() {
+ delete this._db;
+ return this._db = Cc["@mozilla.org/browser/nav-history-service;1"].
+ getService(Ci.nsPIPlacesDatabase).
+ DBConnection;
+ });
+
+ this.__defineGetter__("_bs", function() {
+ delete this._bs;
+ return this._bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+ getService(Ci.nsINavBookmarksService);
+ });
+}
+
+nsPlacesDBFlush.prototype = {
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsIObserver
+
+ observe: function DBFlush_observe(aSubject, aTopic, aData)
+ {
+ if (aTopic == kQuitApplication) {
+ this._os.removeObserver(this, kQuitApplication);
+ this._prefs.QueryInterface(Ci.nsIPrefBranch2).removeObserver("", this);
+ this._timer.cancel();
+ this._timer = null;
+ // Other components could still make changes to history at this point,
+ // for example to clear private data on shutdown, so here we dispatch
+ // an event to the main thread so that we will sync after
+ // quit-application ensuring all data have been saved.
+ let tm = Cc["@mozilla.org/thread-manager;1"].
+ getService(Ci.nsIThreadManager);
+ tm.mainThread.dispatch({
+ _self: this,
+ run: function() {
+ let pip = Cc["@mozilla.org/browser/nav-history-service;1"].
+ getService(Ci.nsPIPlacesDatabase);
+ pip.commitPendingChanges();
+ this._self._syncTables(["places", "historyvisits"]);
+ // Close the database connection, this was the last sync and we can't
+ // ensure database coherence from now on.
+ pip.finalizeInternalStatements();
+ this._self._finalizeInternalStatements();
+ this._self._db.close();
+ }
+ }, Ci.nsIThread.DISPATCH_NORMAL);
+
+ }
+ else if (aTopic == "nsPref:changed" && aData == kSyncPrefName) {
+ // Get the new pref value, and then update our timer
+ this._syncInterval = aSubject.getIntPref(kSyncPrefName);
+ if (this._syncInterval <= 0)
+ this._syncInterval = kDefaultSyncInterval;
+
+ // We may have canceled the timer already for batch updates, so we want to
+ // exit early.
+ if (!this._timer)
+ return;
+
+ this._timer.cancel();
+ this._timer = this._newTimer();
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsINavBookmarkObserver
+
+ onBeginUpdateBatch: function DBFlush_onBeginUpdateBatch()
+ {
+ this._inBatchMode = true;
+
+ // We do not want to sync while we are doing batch work.
+ this._timer.cancel();
+ this._timer = null;
+ },
+
+ onEndUpdateBatch: function DBFlush_onEndUpdateBatch()
+ {
+ this._inBatchMode = false;
+
+ // Restore our timer
+ this._timer = this._newTimer();
+
+ // We need to sync now
+ this._syncTables(["places", "historyvisits"]);
+ },
+
+ onItemAdded: function(aItemId, aParentId, aIndex)
+ {
+ // Sync only if we added a TYPE_BOOKMARK item
+ if (!this._inBatchMode &&
+ this._bs.getItemType(aItemId) == this._bs.TYPE_BOOKMARK)
+ this._syncTables(["places"]);
+ },
+
+ onItemChanged: function DBFlush_onItemChanged(aItemId, aProperty,
+ aIsAnnotationProperty,
+ aValue)
+ {
+ if (!this._inBatchMode && aProperty == "uri")
+ this._syncTables(["places"]);
+ },
+
+ onItemRemoved: function() { },
+ onItemVisited: function() { },
+ onItemMoved: function() { },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsINavHistoryObserver
+
+ // We currently only use the history observer to know when the history service
+ // is activated. At that point, we actually get initialized, and our timer
+ // to sync history is added.
+
+ // These methods share the name of the ones on nsINavBookmarkObserver, so
+ // the implementations can be found above.
+ //onBeginUpdateBatch: function() { },
+ //onEndUpdateBatch: function() { },
+ onVisit: function(aURI, aVisitID, aTime, aSessionID, aReferringID, aTransitionType) { },
+ onTitleChanged: function(aURI, aPageTitle) { },
+ onDeleteURI: function(aURI) { },
+ onClearHistory: function() { },
+ onPageChanged: function(aURI, aWhat, aValue) { },
+ onPageExpired: function(aURI, aVisitTime, aWholeEntry) { },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsITimerCallback
+
+ notify: function() this._syncTables(["places", "historyvisits"]),
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// mozIStorageStatementCallback
+
+ handleError: function DBFlush_handleError(aError)
+ {
+ Cu.reportError("Async statement execution returned with '" +
+ aError.result + "', '" + aError.message + "'");
+ },
+
+ handleCompletion: function DBFlush_handleCompletion(aReason)
+ {
+ if (aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED) {
+ // Dispatch a notification that sync has finished.
+ this._os.notifyObservers(null, kSyncFinished, null);
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsPlacesDBFlush
+ _syncInterval: kDefaultSyncInterval,
+
+ /**
+ * Execute async statements to sync temporary places table.
+ * @param aTableNames
+ * array of table names that should be synced, as moz_{TableName}_temp.
+ */
+ _syncTables: function DBFlush_syncTables(aTableNames)
+ {
+ // No need to do extra work if we are in batch mode
+ if (this._inBatchMode)
+ return;
+
+ let statements = [];
+ for (let i = 0; i < aTableNames.length; i++)
+ statements.push(this._getSyncTableStatement(aTableNames[i]));
+
+ // Execute sync statements async in a transaction
+ this._db.executeAsync(statements, statements.length, this);
+ },
+
+ /**
+ * Finalizes all of our mozIStorageStatements so we can properly close the
+ * database.
+ */
+ _finalizeInternalStatements: function DBFlush_finalizeInternalStatements()
+ {
+ for each (let stmt in this._cachedStatements)
+ if (stmt instanceof Ci.mozIStorageStatement)
+ stmt.finalize();
+ },
+
+ /**
+ * Generate the statement to synchronizes the moz_{aTableName} and
+ * moz_{aTableName}_temp by copying all the data from the temporary table
+ * into the permanent one.
+ * Most of the work is done through triggers defined in nsPlacesTriggers.h,
+ * they sync back to disk, then delete the data in the temporary table.
+ * @param aTableName
+ * name of the table to build statement for, as moz_{TableName}_temp.
+ */
+ _cachedStatements: {},
+ _getSyncTableStatement: function DBFlush_getSyncTableStatement(aTableName)
+ {
+ // Statement creating can be expensive, so always cache if we can.
+ if (aTableName in this._cachedStatements)
+ return this._cachedStatements[aTableName];
+
+ // Delete all the data in the temp table.
+ // We have triggers setup that ensure that the data is transferred over
+ // upon deletion.
+ let condition = "";
+ switch(aTableName) {
+ case "historyvisits":
+ // For history table we want to leave embed visits in memory, since
+ // those are expired with current session, so we are filtering them out.
+ condition = "WHERE visit_type <> " + Ci.nsINavHistoryService.TRANSITION_EMBED;
+ break;
+ case "places":
+ // For places table we want to leave places associated with embed visits
+ // in memory, they usually have hidden = 1 and at least an embed visit
+ // in historyvisits_temp table.
+ condition = "WHERE id IN (SELECT id FROM moz_places_temp h " +
+ "WHERE h.hidden <> 1 OR NOT EXISTS ( " +
+ "SELECT id FROM moz_historyvisits_temp " +
+ "WHERE place_id = h.id AND visit_type = " +
+ Ci.nsINavHistoryService.TRANSITION_EMBED +
+ " LIMIT 1) " +
+ ")";
+ break;
+ }
+
+ let sql = "DELETE FROM moz_" + aTableName + "_temp " + condition;
+ return this._cachedStatements[aTableName] = this._db.createStatement(sql);
+ },
+
+ /**
+ * Creates a new timer based on this._syncInterval.
+ *
+ * @returns a REPEATING_SLACK nsITimer that runs every this._syncInterval.
+ */
+ _newTimer: function DBFlush_newTimer()
+ {
+ let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ timer.initWithCallback(this, this._syncInterval * 1000,
+ Ci.nsITimer.TYPE_REPEATING_SLACK);
+ return timer;
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsISupports
+
+ classDescription: "Used to synchronize the temporary and permanent tables of Places",
+ classID: Components.ID("c1751cfc-e8f1-4ade-b0bb-f74edfb8ef6a"),
+ contractID: "@mozilla.org/places/sync;1",
+
+ // Registering in these categories makes us get initialized when either of
+ // those listeners would be notified.
+ _xpcom_categories: [
+ { category: "bookmark-observers" },
+ { category: "history-observers" },
+ ],
+
+ QueryInterface: XPCOMUtils.generateQI([
+ Ci.nsIObserver,
+ Ci.nsINavBookmarkObserver,
+ Ci.nsINavHistoryObserver,
+ Ci.nsITimerCallback,
+ Ci.mozIStorageStatementCallback,
+ ])
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// Module Registration
+
+let components = [nsPlacesDBFlush];
+function NSGetModule(compMgr, fileSpec)
+{
+ return XPCOMUtils.generateModule(components);
+}
diff --git a/bundles/XO/components/nsPlacesTransactionsService.js b/bundles/XO/components/nsPlacesTransactionsService.js
new file mode 100755
index 0000000..7f0e43c
--- /dev/null
+++ b/bundles/XO/components/nsPlacesTransactionsService.js
@@ -0,0 +1,1116 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Places Command Controller.
+ *
+ * The Initial Developer of the Original Code is Google Inc.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Sungjoon Steve Won <stevewon@gmail.com> (Original Author)
+ * Asaf Romano <mano@mozilla.com>
+ * Marco Bonarco <mak77@bonardo.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let Ci = Components.interfaces;
+let Cc = Components.classes;
+let Cr = Components.results;
+
+const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
+const DESCRIPTION_ANNO = "bookmarkProperties/description";
+
+const CLASS_ID = Components.ID("c0844a84-5a12-4808-80a8-809cb002bb4f");
+const CONTRACT_ID = "@mozilla.org/browser/placesTransactionsService;1";
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+__defineGetter__("PlacesUtils", function() {
+ delete this.PlacesUtils
+ var tmpScope = {};
+ Components.utils.import("resource://gre/modules/utils.js", tmpScope);
+ return this.PlacesUtils = tmpScope.PlacesUtils;
+});
+
+// The minimum amount of transactions we should tell our observers to begin
+// batching (rather than letting them do incremental drawing).
+const MIN_TRANSACTIONS_FOR_BATCH = 5;
+
+function placesTransactionsService() {
+ this.mTransactionManager = Cc["@mozilla.org/transactionmanager;1"].
+ createInstance(Ci.nsITransactionManager);
+}
+
+placesTransactionsService.prototype = {
+ classDescription: "Places Transaction Manager",
+ classID: CLASS_ID,
+ contractID: CONTRACT_ID,
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIPlacesTransactionsService,
+ Ci.nsITransactionManager]),
+
+ aggregateTransactions:
+ function placesTxn_aggregateTransactions(aName, aTransactions) {
+ return new placesAggregateTransactions(aName, aTransactions);
+ },
+
+ createFolder:
+ function placesTxn_createFolder(aName, aContainer, aIndex,
+ aAnnotations, aChildItemsTransactions) {
+ return new placesCreateFolderTransactions(aName, aContainer, aIndex,
+ aAnnotations, aChildItemsTransactions);
+ },
+
+ createItem:
+ function placesTxn_createItem(aURI, aContainer, aIndex, aTitle,
+ aKeyword, aAnnotations, aChildTransactions) {
+ return new placesCreateItemTransactions(aURI, aContainer, aIndex, aTitle,
+ aKeyword, aAnnotations, aChildTransactions);
+ },
+
+ createSeparator:
+ function placesTxn_createSeparator(aContainer, aIndex) {
+ return new placesCreateSeparatorTransactions(aContainer, aIndex);
+ },
+
+ createLivemark:
+ function placesTxn_createLivemark(aFeedURI, aSiteURI, aName,
+ aContainer, aIndex, aAnnotations) {
+ return new placesCreateLivemarkTransactions(aFeedURI, aSiteURI, aName,
+ aContainer, aIndex, aAnnotations);
+ },
+
+ moveItem:
+ function placesTxn_moveItem(aItemId, aNewContainer, aNewIndex) {
+ return new placesMoveItemTransactions(aItemId, aNewContainer, aNewIndex);
+ },
+
+ removeItem:
+ function placesTxn_removeItem(aItemId) {
+ if (aItemId == PlacesUtils.tagsFolderId ||
+ aItemId == PlacesUtils.placesRootId ||
+ aItemId == PlacesUtils.bookmarksMenuFolderId ||
+ aItemId == PlacesUtils.toolbarFolderId)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ // if the item lives within a tag container, use the tagging transactions
+ var parent = PlacesUtils.bookmarks.getFolderIdForItem(aItemId);
+ var grandparent = PlacesUtils.bookmarks.getFolderIdForItem(parent);
+ if (grandparent == PlacesUtils.tagsFolderId) {
+ var uri = PlacesUtils.bookmarks.getBookmarkURI(aItemId);
+ return this.untagURI(uri, [parent]);
+ }
+
+ // if the item is a livemark container we will not save its children and
+ // will use createLivemark to undo.
+ if (PlacesUtils.livemarks.isLivemark(aItemId))
+ return new placesRemoveLivemarkTransaction(aItemId);
+
+ return new placesRemoveItemTransaction(aItemId);
+ },
+
+ editItemTitle:
+ function placesTxn_editItemTitle(aItemId, aNewTitle) {
+ return new placesEditItemTitleTransactions(aItemId, aNewTitle);
+ },
+
+ editBookmarkURI:
+ function placesTxn_editBookmarkURI(aItemId, aNewURI) {
+ return new placesEditBookmarkURITransactions(aItemId, aNewURI);
+ },
+
+ setItemAnnotation:
+ function placesTxn_setItemAnnotation(aItemId, aAnnotationObject) {
+ return new placesSetItemAnnotationTransactions(aItemId, aAnnotationObject);
+ },
+
+ setPageAnnotation:
+ function placesTxn_setPageAnnotation(aURI, aAnnotationObject) {
+ return new placesSetPageAnnotationTransactions(aURI, aAnnotationObject);
+ },
+
+ setLoadInSidebar:
+ function placesTxn_setLoadInSidebar(aItemId, aLoadInSidebar) {
+ var annoObj = { name: LOAD_IN_SIDEBAR_ANNO,
+ type: Ci.nsIAnnotationService.TYPE_INT32,
+ flags: 0,
+ value: aLoadInSidebar,
+ expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+ return this.setItemAnnotation(aItemId, annoObj);
+ },
+
+ editItemDescription:
+ function placesTxn_editItemDescription(aItemId, aDescription) {
+ var annoObj = { name: DESCRIPTION_ANNO,
+ type: Ci.nsIAnnotationService.TYPE_STRING,
+ flags: 0,
+ value: aDescription,
+ expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+ return this.setItemAnnotation(aItemId, annoObj);
+ },
+
+ editBookmarkKeyword:
+ function placesTxn_editBookmarkKeyword(aItemId, aNewKeyword) {
+ return new placesEditBookmarkKeywordTransactions(aItemId, aNewKeyword);
+ },
+
+ editBookmarkPostData:
+ function placesTxn_editBookmarkPostdata(aItemId, aPostData) {
+ return new placesEditBookmarkPostDataTransactions(aItemId, aPostData);
+ },
+
+ editLivemarkSiteURI:
+ function placesTxn_editLivemarkSiteURI(aLivemarkId, aSiteURI) {
+ return new placesEditLivemarkSiteURITransactions(aLivemarkId, aSiteURI);
+ },
+
+ editLivemarkFeedURI:
+ function placesTxn_editLivemarkFeedURI(aLivemarkId, aFeedURI) {
+ return new placesEditLivemarkFeedURITransactions(aLivemarkId, aFeedURI);
+ },
+
+ editBookmarkMicrosummary:
+ function placesTxn_editBookmarkMicrosummary(aItemId, aNewMicrosummary) {
+ return new placesEditBookmarkMicrosummaryTransactions(aItemId, aNewMicrosummary);
+ },
+
+ editItemDateAdded:
+ function placesTxn_editItemDateAdded(aItemId, aNewDateAdded) {
+ return new placesEditItemDateAddedTransaction(aItemId, aNewDateAdded);
+ },
+
+ editItemLastModified:
+ function placesTxn_editItemLastModified(aItemId, aNewLastModified) {
+ return new placesEditItemLastModifiedTransaction(aItemId, aNewLastModified);
+ },
+
+ sortFolderByName:
+ function placesTxn_sortFolderByName(aFolderId) {
+ return new placesSortFolderByNameTransactions(aFolderId);
+ },
+
+ tagURI:
+ function placesTxn_tagURI(aURI, aTags) {
+ return new placesTagURITransaction(aURI, aTags);
+ },
+
+ untagURI:
+ function placesTxn_untagURI(aURI, aTags) {
+ return new placesUntagURITransaction(aURI, aTags);
+ },
+
+ // Update commands in the undo group of the active window
+ // commands in inactive windows will are updated on-focus
+ _updateCommands: function placesTxn__updateCommands() {
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ var win = wm.getMostRecentWindow(null);
+ if (win)
+ win.updateCommands("undo");
+ },
+
+ // nsITransactionManager
+ beginBatch: function() {
+ this.mTransactionManager.beginBatch();
+
+ // A no-op transaction is pushed to the stack, in order to make safe and
+ // easy to implement "Undo" an unknown number of transactions (including 0),
+ // "above" beginBatch and endBatch. Otherwise,implementing Undo that way
+ // head to dataloss: for example, if no changes were done in the
+ // edit-item panel, the last transaction on the undo stack would be the
+ // initial createItem transaction, or even worse, the batched editing of
+ // some other item.
+ // DO NOT MOVE this to the window scope, that would leak (bug 490068)!
+ this.doTransaction({ doTransaction: function() { },
+ undoTransaction: function() { },
+ redoTransaction: function() { },
+ isTransient: false,
+ merge: function() { return false; } });
+ },
+
+ endBatch: function() this.mTransactionManager.endBatch(),
+
+ doTransaction: function placesTxn_doTransaction(txn) {
+ this.mTransactionManager.doTransaction(txn);
+ this._updateCommands();
+ },
+
+ undoTransaction: function placesTxn_undoTransaction() {
+ this.mTransactionManager.undoTransaction();
+ this._updateCommands();
+ },
+
+ redoTransaction: function placesTxn_redoTransaction() {
+ this.mTransactionManager.redoTransaction();
+ this._updateCommands();
+ },
+
+ clear: function() this.mTransactionManager.clear(),
+
+ get numberOfUndoItems() {
+ return this.mTransactionManager.numberOfUndoItems;
+ },
+
+ get numberOfRedoItems() {
+ return this.mTransactionManager.numberOfRedoItems;
+ },
+
+ get maxTransactionCount() {
+ return this.mTransactionManager.maxTransactionCount;
+ },
+ set maxTransactionCount(val) {
+ return this.mTransactionManager.maxTransactionCount = val;
+ },
+
+ peekUndoStack: function() this.mTransactionManager.peekUndoStack(),
+ peekRedoStack: function() this.mTransactionManager.peekRedoStack(),
+ getUndoStack: function() this.mTransactionManager.getUndoStack(),
+ getRedoStack: function() this.mTransactionManager.getRedoStack(),
+ AddListener: function(l) this.mTransactionManager.AddListener(l),
+ RemoveListener: function(l) this.mTransactionManager.RemoveListener(l)
+};
+
+/**
+ * Method and utility stubs for Places Edit Transactions
+ */
+function placesBaseTransaction() {
+}
+
+placesBaseTransaction.prototype = {
+ // for child-transactions
+ get wrappedJSObject() {
+ return this;
+ },
+
+ // nsITransaction
+ redoTransaction: function PBT_redoTransaction() {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ get isTransient() {
+ return false;
+ },
+
+ merge: function mergeFunc(transaction) {
+ return false;
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsITransaction]),
+};
+
+function placesAggregateTransactions(name, transactions) {
+ this._transactions = transactions;
+ this._name = name;
+ this.container = -1;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesAggregateTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PAT_doTransaction() {
+ if (this._transactions.length >= MIN_TRANSACTIONS_FOR_BATCH) {
+ var callback = {
+ _self: this,
+ runBatched: function() {
+ this._self.commit(false);
+ }
+ };
+ PlacesUtils.bookmarks.runInBatchMode(callback, null);
+ }
+ else
+ this.commit(false);
+ },
+
+ undoTransaction: function PAT_undoTransaction() {
+ if (this._transactions.length >= MIN_TRANSACTIONS_FOR_BATCH) {
+ var callback = {
+ _self: this,
+ runBatched: function() {
+ this._self.commit(true);
+ }
+ };
+ PlacesUtils.bookmarks.runInBatchMode(callback, null);
+ }
+ else
+ this.commit(true);
+ },
+
+ commit: function PAT_commit(aUndo) {
+ var transactions = this._transactions;
+ if (aUndo)
+ transactions.reverse();
+ for (var i = 0; i < transactions.length; i++) {
+ var txn = transactions[i];
+ if (this.container > -1)
+ txn.wrappedJSObject.container = this.container;
+ if (aUndo)
+ txn.undoTransaction();
+ else
+ txn.doTransaction();
+ }
+ }
+};
+
+function placesCreateFolderTransactions(aName, aContainer, aIndex,
+ aAnnotations,
+ aChildItemsTransactions) {
+ this._name = aName;
+ this._container = aContainer;
+ this._index = typeof(aIndex) == "number" ? aIndex : -1;
+ this._annotations = aAnnotations;
+ this._id = null;
+ this._childItemsTransactions = aChildItemsTransactions || [];
+ this.redoTransaction = this.doTransaction;
+}
+
+placesCreateFolderTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ // childItemsTransaction support
+ get container() { return this._container; },
+ set container(val) { return this._container = val; },
+
+ doTransaction: function PCFT_doTransaction() {
+ this._id = PlacesUtils.bookmarks.createFolder(this._container,
+ this._name, this._index);
+ if (this._annotations && this._annotations.length > 0)
+ PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
+
+ for (var i = 0; i < this._childItemsTransactions.length; ++i) {
+ var txn = this._childItemsTransactions[i];
+ txn.wrappedJSObject.container = this._id;
+ txn.doTransaction();
+ }
+ },
+
+ undoTransaction: function PCFT_undoTransaction() {
+ // Undo transactions should always be done in reverse order.
+ for (var i = this._childItemsTransactions.length - 1; i >= 0 ; i--) {
+ var txn = this._childItemsTransactions[i];
+ txn.undoTransaction();
+ }
+ // Remove item only after all child transactions have been reverted.
+ PlacesUtils.bookmarks.removeFolder(this._id);
+ }
+};
+
+function placesCreateItemTransactions(aURI, aContainer, aIndex, aTitle,
+ aKeyword, aAnnotations,
+ aChildTransactions) {
+ this._uri = aURI;
+ this._container = aContainer;
+ this._index = typeof(aIndex) == "number" ? aIndex : -1;
+ this._title = aTitle;
+ this._keyword = aKeyword;
+ this._annotations = aAnnotations;
+ this._childTransactions = aChildTransactions || [];
+ this.redoTransaction = this.doTransaction;
+}
+
+placesCreateItemTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ // childItemsTransactions support for the create-folder transaction
+ get container() { return this._container; },
+ set container(val) { return this._container = val; },
+
+ doTransaction: function PCIT_doTransaction() {
+ this._id = PlacesUtils.bookmarks.insertBookmark(this.container, this._uri,
+ this._index, this._title);
+ if (this._keyword)
+ PlacesUtils.bookmarks.setKeywordForBookmark(this._id, this._keyword);
+ if (this._annotations && this._annotations.length > 0)
+ PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
+
+ for (var i = 0; i < this._childTransactions.length; ++i) {
+ var txn = this._childTransactions[i];
+ txn.wrappedJSObject.id = this._id;
+ txn.doTransaction();
+ }
+ },
+
+ undoTransaction: function PCIT_undoTransaction() {
+ // Undo transactions should always be done in reverse order.
+ for (var i = this._childTransactions.length - 1; i >= 0; i--) {
+ var txn = this._childTransactions[i];
+ txn.undoTransaction();
+ }
+ // Remove item only after all child transactions have been reverted.
+ PlacesUtils.bookmarks.removeItem(this._id);
+ }
+};
+
+function placesCreateSeparatorTransactions(aContainer, aIndex) {
+ this._container = aContainer;
+ this._index = typeof(aIndex) == "number" ? aIndex : -1;
+ this._id = null;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesCreateSeparatorTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ // childItemsTransaction support
+ get container() { return this._container; },
+ set container(val) { return this._container = val; },
+
+ doTransaction: function PCST_doTransaction() {
+ this._id = PlacesUtils.bookmarks
+ .insertSeparator(this.container, this._index);
+ },
+
+ undoTransaction: function PCST_undoTransaction() {
+ PlacesUtils.bookmarks.removeItem(this._id);
+ }
+};
+
+function placesCreateLivemarkTransactions(aFeedURI, aSiteURI, aName,
+ aContainer, aIndex,
+ aAnnotations) {
+ this.redoTransaction = this.doTransaction;
+ this._feedURI = aFeedURI;
+ this._siteURI = aSiteURI;
+ this._name = aName;
+ this._container = aContainer;
+ this._index = typeof(aIndex) == "number" ? aIndex : -1;
+ this._annotations = aAnnotations;
+}
+
+placesCreateLivemarkTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ // childItemsTransaction support
+ get container() { return this._container; },
+ set container(val) { return this._container = val; },
+
+ doTransaction: function PCLT_doTransaction() {
+ this._id = PlacesUtils.livemarks.createLivemark(this._container, this._name,
+ this._siteURI, this._feedURI,
+ this._index);
+ if (this._annotations && this._annotations.length > 0)
+ PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
+ },
+
+ undoTransaction: function PCLT_undoTransaction() {
+ PlacesUtils.bookmarks.removeFolder(this._id);
+ }
+};
+
+function placesRemoveLivemarkTransaction(aFolderId) {
+ this.redoTransaction = this.doTransaction;
+ this._id = aFolderId;
+ this._title = PlacesUtils.bookmarks.getItemTitle(this._id);
+ this._container = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
+ var annos = PlacesUtils.getAnnotationsForItem(this._id);
+ // Exclude livemark service annotations, those will be recreated automatically
+ var annosToExclude = ["livemark/feedURI",
+ "livemark/siteURI",
+ "livemark/expiration",
+ "livemark/loadfailed",
+ "livemark/loading"];
+ this._annotations = annos.filter(function(aValue, aIndex, aArray) {
+ return annosToExclude.indexOf(aValue.name) == -1;
+ });
+ this._feedURI = PlacesUtils.livemarks.getFeedURI(this._id);
+ this._siteURI = PlacesUtils.livemarks.getSiteURI(this._id);
+ this._dateAdded = PlacesUtils.bookmarks.getItemDateAdded(this._id);
+ this._lastModified = PlacesUtils.bookmarks.getItemLastModified(this._id);
+}
+
+placesRemoveLivemarkTransaction.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PRLT_doTransaction() {
+ this._index = PlacesUtils.bookmarks.getItemIndex(this._id);
+ PlacesUtils.bookmarks.removeItem(this._id);
+ },
+
+ undoTransaction: function PRLT_undoTransaction() {
+ this._id = PlacesUtils.livemarks.createLivemark(this._container,
+ this._title,
+ this._siteURI,
+ this._feedURI,
+ this._index);
+ PlacesUtils.bookmarks.setItemDateAdded(this._id, this._dateAdded);
+ PlacesUtils.bookmarks.setItemLastModified(this._id, this._lastModified);
+ // Restore annotations
+ PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
+ }
+};
+
+function placesMoveItemTransactions(aItemId, aNewContainer, aNewIndex) {
+ this._id = aItemId;
+ this._oldContainer = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
+ this._newContainer = aNewContainer;
+ this._newIndex = aNewIndex;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesMoveItemTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PMIT_doTransaction() {
+ this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
+ PlacesUtils.bookmarks.moveItem(this._id, this._newContainer, this._newIndex);
+ this._undoIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
+ },
+
+ undoTransaction: function PMIT_undoTransaction() {
+ // moving down in the same container takes in count removal of the item
+ // so to revert positions we must move to oldIndex + 1
+ if (this._newContainer == this._oldContainer &&
+ this._oldIndex > this._undoIndex)
+ PlacesUtils.bookmarks.moveItem(this._id, this._oldContainer, this._oldIndex + 1);
+ else
+ PlacesUtils.bookmarks.moveItem(this._id, this._oldContainer, this._oldIndex);
+ }
+};
+
+function placesRemoveItemTransaction(aItemId) {
+ this.redoTransaction = this.doTransaction;
+ this._id = aItemId;
+ this._itemType = PlacesUtils.bookmarks.getItemType(this._id);
+ if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
+ this._transactions = [];
+ this._removeTxn = PlacesUtils.bookmarks
+ .getRemoveFolderTransaction(this._id);
+ }
+ else if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
+ this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._id);
+ this._keyword = PlacesUtils.bookmarks.getKeywordForBookmark(this._id);
+ }
+
+ if (this._itemType != Ci.nsINavBookmarksService.TYPE_SEPARATOR)
+ this._title = PlacesUtils.bookmarks.getItemTitle(this._id);
+
+ this._oldContainer = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
+ this._annotations = PlacesUtils.getAnnotationsForItem(this._id);
+ this._dateAdded = PlacesUtils.bookmarks.getItemDateAdded(this._id);
+ this._lastModified = PlacesUtils.bookmarks.getItemLastModified(this._id);
+}
+
+placesRemoveItemTransaction.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PRIT_doTransaction() {
+ this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
+
+ if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
+ this._saveFolderContents();
+
+ // Remove children backwards to preserve parent-child relationships.
+ for (var i = this._transactions.length - 1; i >= 0; --i)
+ this._transactions[i].doTransaction();
+
+ // Remove this folder itself.
+ this._removeTxn.doTransaction();
+ }
+ else {
+ PlacesUtils.bookmarks.removeItem(this._id);
+ if (this._uri) {
+ // if this was the last bookmark (excluding tag-items and livemark
+ // children, see getMostRecentBookmarkForURI) for the bookmark's url,
+ // remove the url from tag containers as well.
+ if (PlacesUtils.getMostRecentBookmarkForURI(this._uri) == -1) {
+ this._tags = PlacesUtils.tagging.getTagsForURI(this._uri, {});
+ PlacesUtils.tagging.untagURI(this._uri, this._tags);
+ }
+ }
+ }
+ },
+
+ undoTransaction: function PRIT_undoTransaction() {
+ if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
+ this._id = PlacesUtils.bookmarks.insertBookmark(this._oldContainer,
+ this._uri,
+ this._oldIndex,
+ this._title);
+ if (this._tags && this._tags.length > 0)
+ PlacesUtils.tagging.tagURI(this._uri, this._tags);
+ if (this._keyword)
+ PlacesUtils.bookmarks.setKeywordForBookmark(this._id, this._keyword);
+ }
+ else if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
+ this._removeTxn.undoTransaction();
+ // Create children forwards to preserve parent-child relationships.
+ for (var i = 0; i < this._transactions.length; ++i)
+ this._transactions[i].undoTransaction();
+ }
+ else // TYPE_SEPARATOR
+ this._id = PlacesUtils.bookmarks.insertSeparator(this._oldContainer, this._oldIndex);
+
+ if (this._annotations.length > 0)
+ PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
+
+ PlacesUtils.bookmarks.setItemDateAdded(this._id, this._dateAdded);
+ PlacesUtils.bookmarks.setItemLastModified(this._id, this._lastModified);
+ },
+
+ /**
+ * Create a flat, ordered list of transactions for a depth-first recreation
+ * of items within this folder.
+ */
+ _saveFolderContents: function PRIT__saveFolderContents() {
+ this._transactions = [];
+ var contents =
+ PlacesUtils.getFolderContents(this._id, false, false).root;
+ for (var i = 0; i < contents.childCount; ++i) {
+ this._transactions
+ .push(new placesRemoveItemTransaction(contents.getChild(i).itemId));
+ }
+ }
+};
+
+function placesEditItemTitleTransactions(id, newTitle) {
+ this._id = id;
+ this._newTitle = newTitle;
+ this._oldTitle = "";
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditItemTitleTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PEITT_doTransaction() {
+ this._oldTitle = PlacesUtils.bookmarks.getItemTitle(this._id);
+ PlacesUtils.bookmarks.setItemTitle(this._id, this._newTitle);
+ },
+
+ undoTransaction: function PEITT_undoTransaction() {
+ PlacesUtils.bookmarks.setItemTitle(this._id, this._oldTitle);
+ }
+};
+
+function placesEditBookmarkURITransactions(aBookmarkId, aNewURI) {
+ this._id = aBookmarkId;
+ this._newURI = aNewURI;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditBookmarkURITransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PEBUT_doTransaction() {
+ this._oldURI = PlacesUtils.bookmarks.getBookmarkURI(this._id);
+ PlacesUtils.bookmarks.changeBookmarkURI(this._id, this._newURI);
+ // move tags from old URI to new URI
+ this._tags = PlacesUtils.tagging.getTagsForURI(this._oldURI, {});
+ if (this._tags.length != 0) {
+ // only untag the old URI if this is the only bookmark
+ if (PlacesUtils.getBookmarksForURI(this._oldURI, {}).length == 0)
+ PlacesUtils.tagging.untagURI(this._oldURI, this._tags);
+ PlacesUtils.tagging.tagURI(this._newURI, this._tags);
+ }
+ },
+
+ undoTransaction: function PEBUT_undoTransaction() {
+ PlacesUtils.bookmarks.changeBookmarkURI(this._id, this._oldURI);
+ // move tags from new URI to old URI
+ if (this._tags.length != 0) {
+ // only untag the new URI if this is the only bookmark
+ if (PlacesUtils.getBookmarksForURI(this._newURI, {}).length == 0)
+ PlacesUtils.tagging.untagURI(this._newURI, this._tags);
+ PlacesUtils.tagging.tagURI(this._oldURI, this._tags);
+ }
+ }
+};
+
+function placesSetItemAnnotationTransactions(aItemId, aAnnotationObject) {
+ this.id = aItemId;
+ this._anno = aAnnotationObject;
+ // create an empty old anno
+ this._oldAnno = { name: this._anno.name,
+ type: Ci.nsIAnnotationService.TYPE_STRING,
+ flags: 0,
+ value: null,
+ expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+ this.redoTransaction = this.doTransaction;
+}
+
+placesSetItemAnnotationTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PSIAT_doTransaction() {
+ // Since this can be used as a child transaction this.id will be known
+ // only at this point, after the external caller has set it.
+ if (PlacesUtils.annotations.itemHasAnnotation(this.id, this._anno.name)) {
+ // Save the old annotation if it is set.
+ var flags = {}, expires = {}, mimeType = {}, type = {};
+ PlacesUtils.annotations.getItemAnnotationInfo(this.id, this._anno.name,
+ flags, expires, mimeType,
+ type);
+ this._oldAnno.flags = flags.value;
+ this._oldAnno.expires = expires.value;
+ this._oldAnno.mimeType = mimeType.value;
+ this._oldAnno.type = type.value;
+ this._oldAnno.value = PlacesUtils.annotations
+ .getItemAnnotation(this.id,
+ this._anno.name);
+ }
+
+ PlacesUtils.setAnnotationsForItem(this.id, [this._anno]);
+ },
+
+ undoTransaction: function PSIAT_undoTransaction() {
+ PlacesUtils.setAnnotationsForItem(this.id, [this._oldAnno]);
+ }
+};
+
+function placesSetPageAnnotationTransactions(aURI, aAnnotationObject) {
+ this._uri = aURI;
+ this._anno = aAnnotationObject;
+ // create an empty old anno
+ this._oldAnno = { name: this._anno.name,
+ type: Ci.nsIAnnotationService.TYPE_STRING,
+ flags: 0,
+ value: null,
+ expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
+
+ if (PlacesUtils.annotations.pageHasAnnotation(this._uri, this._anno.name)) {
+ // fill the old anno if it is set
+ var flags = {}, expires = {}, mimeType = {}, type = {};
+ PlacesUtils.annotations.getPageAnnotationInfo(this._uri, this._anno.name,
+ flags, expires, mimeType, type);
+ this._oldAnno.flags = flags.value;
+ this._oldAnno.expires = expires.value;
+ this._oldAnno.mimeType = mimeType.value;
+ this._oldAnno.type = type.value;
+ this._oldAnno.value = PlacesUtils.annotations
+ .getPageAnnotation(this._uri, this._anno.name);
+ }
+
+ this.redoTransaction = this.doTransaction;
+}
+
+placesSetPageAnnotationTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PSPAT_doTransaction() {
+ PlacesUtils.setAnnotationsForURI(this._uri, [this._anno]);
+ },
+
+ undoTransaction: function PSPAT_undoTransaction() {
+ PlacesUtils.setAnnotationsForURI(this._uri, [this._oldAnno]);
+ }
+};
+
+function placesEditBookmarkKeywordTransactions(id, newKeyword) {
+ this.id = id;
+ this._newKeyword = newKeyword;
+ this._oldKeyword = "";
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditBookmarkKeywordTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PEBKT_doTransaction() {
+ this._oldKeyword = PlacesUtils.bookmarks.getKeywordForBookmark(this.id);
+ PlacesUtils.bookmarks.setKeywordForBookmark(this.id, this._newKeyword);
+ },
+
+ undoTransaction: function PEBKT_undoTransaction() {
+ PlacesUtils.bookmarks.setKeywordForBookmark(this.id, this._oldKeyword);
+ }
+};
+
+function placesEditBookmarkPostDataTransactions(aItemId, aPostData) {
+ this.id = aItemId;
+ this._newPostData = aPostData;
+ this._oldPostData = null;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditBookmarkPostDataTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PEUPDT_doTransaction() {
+ this._oldPostData = PlacesUtils.getPostDataForBookmark(this.id);
+ PlacesUtils.setPostDataForBookmark(this.id, this._newPostData);
+ },
+
+ undoTransaction: function PEUPDT_undoTransaction() {
+ PlacesUtils.setPostDataForBookmark(this.id, this._oldPostData);
+ }
+};
+
+function placesEditLivemarkSiteURITransactions(folderId, uri) {
+ this._folderId = folderId;
+ this._newURI = uri;
+ this._oldURI = null;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditLivemarkSiteURITransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PELSUT_doTransaction() {
+ this._oldURI = PlacesUtils.livemarks.getSiteURI(this._folderId);
+ PlacesUtils.livemarks.setSiteURI(this._folderId, this._newURI);
+ },
+
+ undoTransaction: function PELSUT_undoTransaction() {
+ PlacesUtils.livemarks.setSiteURI(this._folderId, this._oldURI);
+ }
+};
+
+function placesEditLivemarkFeedURITransactions(folderId, uri) {
+ this._folderId = folderId;
+ this._newURI = uri;
+ this._oldURI = null;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditLivemarkFeedURITransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PELFUT_doTransaction() {
+ this._oldURI = PlacesUtils.livemarks.getFeedURI(this._folderId);
+ PlacesUtils.livemarks.setFeedURI(this._folderId, this._newURI);
+ PlacesUtils.livemarks.reloadLivemarkFolder(this._folderId);
+ },
+
+ undoTransaction: function PELFUT_undoTransaction() {
+ PlacesUtils.livemarks.setFeedURI(this._folderId, this._oldURI);
+ PlacesUtils.livemarks.reloadLivemarkFolder(this._folderId);
+ }
+};
+
+function placesEditBookmarkMicrosummaryTransactions(aItemId, newMicrosummary) {
+ this.id = aItemId;
+ this._mss = Cc["@mozilla.org/microsummary/service;1"].
+ getService(Ci.nsIMicrosummaryService);
+ this._newMicrosummary = newMicrosummary;
+ this._oldMicrosummary = null;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditBookmarkMicrosummaryTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PEBMT_doTransaction() {
+ this._oldMicrosummary = this._mss.getMicrosummary(this.id);
+ if (this._newMicrosummary)
+ this._mss.setMicrosummary(this.id, this._newMicrosummary);
+ else
+ this._mss.removeMicrosummary(this.id);
+ },
+
+ undoTransaction: function PEBMT_undoTransaction() {
+ if (this._oldMicrosummary)
+ this._mss.setMicrosummary(this.id, this._oldMicrosummary);
+ else
+ this._mss.removeMicrosummary(this.id);
+ }
+};
+
+function placesEditItemDateAddedTransaction(id, newDateAdded) {
+ this.id = id;
+ this._newDateAdded = newDateAdded;
+ this._oldDateAdded = null;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditItemDateAddedTransaction.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ // to support folders as well
+ get container() { return this.id; },
+ set container(val) { return this.id = val; },
+
+ doTransaction: function PEIDA_doTransaction() {
+ this._oldDateAdded = PlacesUtils.bookmarks.getItemDateAdded(this.id);
+ PlacesUtils.bookmarks.setItemDateAdded(this.id, this._newDateAdded);
+ },
+
+ undoTransaction: function PEIDA_undoTransaction() {
+ PlacesUtils.bookmarks.setItemDateAdded(this.id, this._oldDateAdded);
+ }
+};
+
+function placesEditItemLastModifiedTransaction(id, newLastModified) {
+ this.id = id;
+ this._newLastModified = newLastModified;
+ this._oldLastModified = null;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesEditItemLastModifiedTransaction.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ // to support folders as well
+ get container() { return this.id; },
+ set container(val) { return this.id = val; },
+
+ doTransaction: function PEILM_doTransaction() {
+ this._oldLastModified = PlacesUtils.bookmarks.getItemLastModified(this.id);
+ PlacesUtils.bookmarks.setItemLastModified(this.id, this._newLastModified);
+ },
+
+ undoTransaction: function PEILM_undoTransaction() {
+ PlacesUtils.bookmarks.setItemLastModified(this.id, this._oldLastModified);
+ }
+};
+
+function placesSortFolderByNameTransactions(aFolderId) {
+ this._folderId = aFolderId;
+ this._oldOrder = null,
+ this.redoTransaction = this.doTransaction;
+}
+
+placesSortFolderByNameTransactions.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PSSFBN_doTransaction() {
+ this._oldOrder = [];
+
+ var contents = PlacesUtils.getFolderContents(this._folderId, false, false).root;
+ var count = contents.childCount;
+
+ // sort between separators
+ var newOrder = [];
+ var preSep = []; // temporary array for sorting each group of items
+ var sortingMethod =
+ function (a, b) {
+ if (PlacesUtils.nodeIsContainer(a) && !PlacesUtils.nodeIsContainer(b))
+ return -1;
+ if (!PlacesUtils.nodeIsContainer(a) && PlacesUtils.nodeIsContainer(b))
+ return 1;
+ return a.title.localeCompare(b.title);
+ };
+
+ for (var i = 0; i < count; ++i) {
+ var item = contents.getChild(i);
+ this._oldOrder[item.itemId] = i;
+ if (PlacesUtils.nodeIsSeparator(item)) {
+ if (preSep.length > 0) {
+ preSep.sort(sortingMethod);
+ newOrder = newOrder.concat(preSep);
+ preSep.splice(0);
+ }
+ newOrder.push(item);
+ }
+ else
+ preSep.push(item);
+ }
+ if (preSep.length > 0) {
+ preSep.sort(sortingMethod);
+ newOrder = newOrder.concat(preSep);
+ }
+
+ // set the nex indexes
+ var callback = {
+ runBatched: function() {
+ for (var i = 0; i < newOrder.length; ++i) {
+ PlacesUtils.bookmarks.setItemIndex(newOrder[i].itemId, i);
+ }
+ }
+ };
+ PlacesUtils.bookmarks.runInBatchMode(callback, null);
+ },
+
+ undoTransaction: function PSSFBN_undoTransaction() {
+ var callback = {
+ _self: this,
+ runBatched: function() {
+ for (item in this._self._oldOrder)
+ PlacesUtils.bookmarks.setItemIndex(item, this._self._oldOrder[item]);
+ }
+ };
+ PlacesUtils.bookmarks.runInBatchMode(callback, null);
+ }
+};
+
+function placesTagURITransaction(aURI, aTags) {
+ this._uri = aURI;
+ this._tags = aTags;
+ this._unfiledItemId = -1;
+ this.redoTransaction = this.doTransaction;
+}
+
+placesTagURITransaction.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PTU_doTransaction() {
+ if (PlacesUtils.getMostRecentBookmarkForURI(this._uri) == -1) {
+ // Force an unfiled bookmark first
+ this._unfiledItemId =
+ PlacesUtils.bookmarks
+ .insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
+ this._uri,
+ PlacesUtils.bookmarks.DEFAULT_INDEX,
+ PlacesUtils.history.getPageTitle(this._uri));
+ }
+ PlacesUtils.tagging.tagURI(this._uri, this._tags);
+ },
+
+ undoTransaction: function PTU_undoTransaction() {
+ if (this._unfiledItemId != -1) {
+ PlacesUtils.bookmarks.removeItem(this._unfiledItemId);
+ this._unfiledItemId = -1;
+ }
+ PlacesUtils.tagging.untagURI(this._uri, this._tags);
+ }
+};
+
+function placesUntagURITransaction(aURI, aTags) {
+ this._uri = aURI;
+ if (aTags) {
+ // Within this transaction, we cannot rely on tags given by itemId
+ // since the tag containers may be gone after we call untagURI.
+ // Thus, we convert each tag given by its itemId to name.
+ this._tags = aTags;
+ for (var i=0; i < aTags.length; i++) {
+ if (typeof(this._tags[i]) == "number")
+ this._tags[i] = PlacesUtils.bookmarks.getItemTitle(this._tags[i]);
+ }
+ }
+ else
+ this._tags = PlacesUtils.tagging.getTagsForURI(this._uri, {});
+
+ this.redoTransaction = this.doTransaction;
+}
+
+placesUntagURITransaction.prototype = {
+ __proto__: placesBaseTransaction.prototype,
+
+ doTransaction: function PUTU_doTransaction() {
+ PlacesUtils.tagging.untagURI(this._uri, this._tags);
+ },
+
+ undoTransaction: function PUTU_undoTransaction() {
+ PlacesUtils.tagging.tagURI(this._uri, this._tags);
+ }
+};
+
+
+function NSGetModule(aCompMgr, aFileSpec) {
+ return XPCOMUtils.generateModule([placesTransactionsService]);
+}
diff --git a/bundles/XO/components/nsPrivateBrowsingService.js b/bundles/XO/components/nsPrivateBrowsingService.js
new file mode 100755
index 0000000..af54693
--- /dev/null
+++ b/bundles/XO/components/nsPrivateBrowsingService.js
@@ -0,0 +1,512 @@
+//@line 38 "/builds/moz2_slave/linux_build/build/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js"
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+////////////////////////////////////////////////////////////////////////////////
+//// Utilities
+
+/**
+ * Returns true if the string passed in is part of the root domain of the
+ * current string. For example, if this is "www.mozilla.org", and we pass in
+ * "mozilla.org", this will return true. It would return false the other way
+ * around.
+ */
+String.prototype.hasRootDomain = function hasRootDomain(aDomain)
+{
+ let index = this.indexOf(aDomain);
+ // If aDomain is not found, we know we do not have it as a root domain.
+ if (index == -1)
+ return false;
+
+ // If the strings are the same, we obviously have a match.
+ if (this == aDomain)
+ return true;
+
+ // Otherwise, we have aDomain as our root domain iff the index of aDomain is
+ // aDomain.length subtracted from our length and (since we do not have an
+ // exact match) the character before the index is a dot or slash.
+ let prevChar = this[index - 1];
+ return (index == (this.length - aDomain.length)) &&
+ (prevChar == "." || prevChar == "/");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cr = Components.results;
+
+////////////////////////////////////////////////////////////////////////////////
+//// PrivateBrowsingService
+
+function PrivateBrowsingService() {
+ this._obs.addObserver(this, "profile-after-change", true);
+ this._obs.addObserver(this, "quit-application-granted", true);
+ this._obs.addObserver(this, "private-browsing", true);
+}
+
+PrivateBrowsingService.prototype = {
+ // Observer Service
+ __obs: null,
+ get _obs() {
+ if (!this.__obs)
+ this.__obs = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ return this.__obs;
+ },
+
+ // Preferences Service
+ __prefs: null,
+ get _prefs() {
+ if (!this.__prefs)
+ this.__prefs = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ return this.__prefs;
+ },
+
+ // Whether the private browsing mode is currently active or not.
+ _inPrivateBrowsing: false,
+
+ // Saved browser state before entering the private mode.
+ _savedBrowserState: null,
+
+ // Whether we're in the process of shutting down
+ _quitting: false,
+
+ // How to treat the non-private session
+ _saveSession: true,
+
+ // Make sure we don't allow re-enterant changing of the private mode
+ _alreadyChangingMode: false,
+
+ // Whether we're entering the private browsing mode at application startup
+ _autoStart: false,
+
+ // Whether the private browsing mode has been started automatically
+ _autoStarted: false,
+
+ // XPCOM registration
+ classDescription: "PrivateBrowsing Service",
+ contractID: "@mozilla.org/privatebrowsing;1",
+ classID: Components.ID("{c31f4883-839b-45f6-82ad-a6a9bc5ad599}"),
+ _xpcom_categories: [
+ { category: "app-startup", service: true }
+ ],
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIPrivateBrowsingService,
+ Ci.nsIObserver,
+ Ci.nsISupportsWeakReference]),
+
+ _unload: function PBS__destroy() {
+ // Force an exit from the private browsing mode on shutdown
+ this._quitting = true;
+ if (this._inPrivateBrowsing)
+ this.privateBrowsingEnabled = false;
+ },
+
+ _onBeforePrivateBrowsingModeChange: function PBS__onBeforePrivateBrowsingModeChange() {
+ // nothing needs to be done here if we're auto-starting
+ if (!this._autoStart) {
+ let ss = Cc["@mozilla.org/browser/sessionstore;1"].
+ getService(Ci.nsISessionStore);
+ let blankState = JSON.stringify({
+ "windows": [{
+ "tabs": [{
+ "entries": [{
+ "url": "about:blank"
+ }]
+ }],
+ "_closedTabs": []
+ }]
+ });
+
+ // whether we should save and close the current session
+ this._saveSession = true;
+ try {
+ if (this._prefs.getBoolPref("browser.privatebrowsing.keep_current_session"))
+ this._saveSession = false;
+ } catch (ex) {}
+
+ if (this._inPrivateBrowsing) {
+ // save the whole browser state in order to restore all windows/tabs later
+ if (this._saveSession && !this._savedBrowserState) {
+ if (this._getBrowserWindow())
+ this._savedBrowserState = ss.getBrowserState();
+ else // no open browser windows, just restore a blank state on exit
+ this._savedBrowserState = blankState;
+ }
+ }
+
+ this._closePageInfoWindows();
+
+ if (!this._quitting && this._saveSession) {
+ let browserWindow = this._getBrowserWindow();
+
+ // if there are open browser windows, load a dummy session to get a distinct
+ // separation between private and non-private sessions
+ if (browserWindow) {
+ // set an empty session to transition from/to pb mode, see bug 476463
+ ss.setBrowserState(blankState);
+
+ // just in case the only remaining window after setBrowserState is different.
+ // it probably shouldn't be with the current sessionstore impl, but we shouldn't
+ // rely on behaviour the API doesn't guarantee
+ let browser = this._getBrowserWindow().gBrowser;
+
+ // this ensures a clean slate from which to transition into or out of
+ // private browsing
+ browser.addTab();
+ browser.removeTab(browser.tabContainer.firstChild);
+ }
+ }
+ }
+ else
+ this._saveSession = false;
+ },
+
+ _onAfterPrivateBrowsingModeChange: function PBS__onAfterPrivateBrowsingModeChange() {
+ // nothing to do here if we're auto-starting or the current session is being
+ // used
+ if (!this._autoStart && this._saveSession) {
+ let ss = Cc["@mozilla.org/browser/sessionstore;1"].
+ getService(Ci.nsISessionStore);
+ // if we have transitioned out of private browsing mode and the session is
+ // to be restored, do it now
+ if (!this._inPrivateBrowsing) {
+ ss.setBrowserState(this._savedBrowserState);
+ this._savedBrowserState = null;
+
+ this._closePageInfoWindows();
+ }
+ else {
+ // otherwise, if we have transitioned into private browsing mode, load
+ // about:privatebrowsing
+ let privateBrowsingState = {
+ "windows": [{
+ "tabs": [{
+ "entries": [{
+ "url": "about:privatebrowsing"
+ }]
+ }],
+ "_closedTabs": []
+ }]
+ };
+ // Transition into private browsing mode
+ ss.setBrowserState(JSON.stringify(privateBrowsingState));
+ }
+ }
+ },
+
+ _canEnterPrivateBrowsingMode: function PBS__canEnterPrivateBrowsingMode() {
+ let cancelEnter = Cc["@mozilla.org/supports-PRBool;1"].
+ createInstance(Ci.nsISupportsPRBool);
+ cancelEnter.data = false;
+ this._obs.notifyObservers(cancelEnter, "private-browsing-cancel-vote", "enter");
+ return !cancelEnter.data;
+ },
+
+ _canLeavePrivateBrowsingMode: function PBS__canLeavePrivateBrowsingMode() {
+ let cancelLeave = Cc["@mozilla.org/supports-PRBool;1"].
+ createInstance(Ci.nsISupportsPRBool);
+ cancelLeave.data = false;
+ this._obs.notifyObservers(cancelLeave, "private-browsing-cancel-vote", "exit");
+ return !cancelLeave.data;
+ },
+
+ _getBrowserWindow: function PBS__getBrowserWindow() {
+ return Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator).
+ getMostRecentWindow("navigator:browser");
+ },
+
+ _closePageInfoWindows: function PBS__closePageInfoWindows() {
+ let pageInfoEnum = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator).
+ getEnumerator("Browser:page-info");
+ while (pageInfoEnum.hasMoreElements()) {
+ let win = pageInfoEnum.getNext();
+ win.close();
+ }
+ },
+
+ // nsIObserver
+
+ observe: function PBS_observe(aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "profile-after-change":
+ // If the autostart prefs has been set, simulate entering the
+ // private browsing mode upon startup.
+ // This won't interfere with the session store component, because
+ // that component will be initialized on final-ui-startup.
+ this._autoStart = this._prefs.getBoolPref("browser.privatebrowsing.autostart");
+ if (this._autoStart) {
+ this._autoStarted = true;
+ this.privateBrowsingEnabled = true;
+ this._autoStart = false;
+ }
+ this._obs.removeObserver(this, "profile-after-change");
+ break;
+ case "quit-application-granted":
+ this._unload();
+ break;
+ case "private-browsing":
+ // clear all auth tokens
+ let sdr = Cc["@mozilla.org/security/sdr;1"].
+ getService(Ci.nsISecretDecoderRing);
+ sdr.logoutAndTeardown();
+
+ // clear plain HTTP auth sessions
+ let authMgr = Cc['@mozilla.org/network/http-auth-manager;1'].
+ getService(Ci.nsIHttpAuthManager);
+ authMgr.clearAll();
+
+ // Prevent any SSL sockets from remaining open. Without this, SSL
+ // websites may fail to load after switching the private browsing mode
+ // because the SSL sockets may still be open while the corresponding
+ // NSS resources have been destroyed by the logoutAndTeardown call
+ // above. See bug 463256 for more information.
+ let ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ if (!ios.offline) {
+ ios.offline = true;
+ ios.offline = false;
+ }
+
+ if (!this._inPrivateBrowsing) {
+ // Clear the error console
+ let consoleService = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ consoleService.logStringMessage(null); // trigger the listeners
+ consoleService.reset();
+ }
+ break;
+ }
+ },
+
+ // nsIPrivateBrowsingService
+
+ /**
+ * Return the current status of private browsing.
+ */
+ get privateBrowsingEnabled PBS_get_privateBrowsingEnabled() {
+ return this._inPrivateBrowsing;
+ },
+
+ /**
+ * Enter or leave private browsing mode.
+ */
+ set privateBrowsingEnabled PBS_set_privateBrowsingEnabled(val) {
+ // Allowing observers to set the private browsing status from their
+ // notification handlers is not desired, because it will change the
+ // status of the service while it's in the process of another transition.
+ // So, we detect a reentrant call here and throw an error.
+ // This is documented in nsIPrivateBrowsingService.idl.
+ if (this._alreadyChangingMode)
+ throw Cr.NS_ERROR_FAILURE;
+
+ try {
+ this._alreadyChangingMode = true;
+
+ if (val != this._inPrivateBrowsing) {
+ if (val) {
+ if (!this._canEnterPrivateBrowsingMode())
+ return;
+ }
+ else {
+ if (!this._canLeavePrivateBrowsingMode())
+ return;
+ }
+
+ this._autoStarted = val ?
+ this._prefs.getBoolPref("browser.privatebrowsing.autostart") : false;
+ this._inPrivateBrowsing = val != false;
+
+ let data = val ? "enter" : "exit";
+
+ let quitting = Cc["@mozilla.org/supports-PRBool;1"].
+ createInstance(Ci.nsISupportsPRBool);
+ quitting.data = this._quitting;
+
+ // notify observers of the pending private browsing mode change
+ this._obs.notifyObservers(quitting, "private-browsing-change-granted", data);
+
+ // destroy the current session and start initial cleanup
+ this._onBeforePrivateBrowsingModeChange();
+
+ this._obs.notifyObservers(quitting, "private-browsing", data);
+
+ // load the appropriate session
+ this._onAfterPrivateBrowsingModeChange();
+ }
+ } catch (ex) {
+ Cu.reportError("Exception thrown while processing the " +
+ "private browsing mode change request: " + ex.toString());
+ } finally {
+ this._alreadyChangingMode = false;
+ }
+ },
+
+ /**
+ * Whether private browsing has been started automatically.
+ */
+ get autoStarted PBS_get_autoStarted() {
+ return this._autoStarted;
+ },
+
+ removeDataFromDomain: function PBS_removeDataFromDomain(aDomain)
+ {
+
+ // clear any and all network geolocation provider sessions
+ try {
+ this._prefs.deleteBranch("geo.wifi.access_token.");
+ } catch (e) {}
+
+ // History
+ let (bh = Cc["@mozilla.org/browser/global-history;2"].
+ getService(Ci.nsIBrowserHistory)) {
+ bh.removePagesFromHost(aDomain, true);
+ }
+
+ // Cache
+ let (cs = Cc["@mozilla.org/network/cache-service;1"].
+ getService(Ci.nsICacheService)) {
+ // NOTE: there is no way to clear just that domain, so we clear out
+ // everything)
+ try {
+ cs.evictEntries(Ci.nsICache.STORE_ANYWHERE);
+ } catch (ex) {
+ Cu.reportError("Exception thrown while clearing the cache: " +
+ ex.toString());
+ }
+ }
+
+ // Cookies
+ let (cm = Cc["@mozilla.org/cookiemanager;1"].
+ getService(Ci.nsICookieManager)) {
+ let enumerator = cm.enumerator;
+ while (enumerator.hasMoreElements()) {
+ let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
+ if (cookie.host.hasRootDomain(aDomain))
+ cm.remove(cookie.host, cookie.name, cookie.path, false);
+ }
+ }
+
+ // Downloads
+ let (dm = Cc["@mozilla.org/download-manager;1"].
+ getService(Ci.nsIDownloadManager)) {
+ // Active downloads
+ let enumerator = dm.activeDownloads;
+ while (enumerator.hasMoreElements()) {
+ let dl = enumerator.getNext().QueryInterface(Ci.nsIDownload);
+ if (dl.source.host.hasRootDomain(aDomain)) {
+ dm.cancelDownload(dl.id);
+ dm.removeDownload(dl.id);
+ }
+ }
+
+ // Completed downloads
+ let db = dm.DBConnection;
+ // NOTE: This is lossy, but we feel that it is OK to be lossy here and not
+ // invoke the cost of creating a URI for each download entry and
+ // ensure that the hostname matches.
+ let stmt = db.createStatement(
+ "DELETE FROM moz_downloads " +
+ "WHERE source LIKE ?1 ESCAPE '/' " +
+ "AND state NOT IN (?2, ?3, ?4)"
+ );
+ let pattern = stmt.escapeStringForLIKE(aDomain, "/");
+ stmt.bindStringParameter(0, "%" + pattern + "%");
+ stmt.bindInt32Parameter(1, Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING);
+ stmt.bindInt32Parameter(2, Ci.nsIDownloadManager.DOWNLOAD_PAUSED);
+ stmt.bindInt32Parameter(3, Ci.nsIDownloadManager.DOWNLOAD_QUEUED);
+ try {
+ stmt.execute();
+ }
+ finally {
+ stmt.finalize();
+ }
+
+ // We want to rebuild the list if the UI is showing, so dispatch the
+ // observer topic
+ let os = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ os.notifyObservers(null, "download-manager-remove-download", null);
+ }
+
+ // Passwords
+ let (lm = Cc["@mozilla.org/login-manager;1"].
+ getService(Ci.nsILoginManager)) {
+ // Clear all passwords for domain
+ try {
+ let logins = lm.getAllLogins({});
+ for (let i = 0; i < logins.length; i++)
+ if (logins[i].hostname.hasRootDomain(aDomain))
+ lm.removeLogin(logins[i]);
+ }
+ // XXXehsan: is there a better way to do this rather than this
+ // hacky comparison?
+ catch (ex if ex.message.indexOf("User canceled Master Password entry") != -1) { }
+
+ // Clear any "do not save for this site" for this domain
+ let disabledHosts = lm.getAllDisabledHosts({});
+ for (let i = 0; i < disabledHosts.length; i++)
+ if (disabledHosts[i].hasRootDomain(aDomain))
+ lm.setLoginSavingEnabled(disabledHosts, true);
+ }
+
+ // Permissions
+ let (pm = Cc["@mozilla.org/permissionmanager;1"].
+ getService(Ci.nsIPermissionManager)) {
+ // Enumerate all of the permissions, and if one matches, remove it
+ let enumerator = pm.enumerator;
+ while (enumerator.hasMoreElements()) {
+ let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission);
+ if (perm.host.hasRootDomain(aDomain))
+ pm.remove(perm.host, perm.type);
+ }
+ }
+
+ // Content Preferences
+ let (cp = Cc["@mozilla.org/content-pref/service;1"].
+ getService(Ci.nsIContentPrefService)) {
+ let db = cp.DBConnection;
+ // First we need to get the list of "groups" which are really just domains
+ let names = [];
+ let stmt = db.createStatement(
+ "SELECT name " +
+ "FROM groups " +
+ "WHERE name LIKE ?1 ESCAPE '/'"
+ );
+ let pattern = stmt.escapeStringForLIKE(aDomain, "/");
+ stmt.bindStringParameter(0, "%" + pattern);
+ try {
+ while (stmt.executeStep())
+ if (stmt.getString(0).hasRootDomain(aDomain))
+ names.push(stmt.getString(0));
+ }
+ finally {
+ stmt.finalize();
+ }
+
+ // Now, for each name we got back, remove all of its prefs.
+ for (let i = 0; i < names.length; i++) {
+ // The service only cares about the host of the URI, so we don't need a
+ // full nsIURI object here.
+ let uri = { host: names[i]};
+ let enumerator = cp.getPrefs(uri).enumerator;
+ while (enumerator.hasMoreElements()) {
+ let pref = enumerator.getNext().QueryInterface(Ci.nsIProperty);
+ cp.removePref(uri, pref.name);
+ }
+ }
+ }
+
+ // Everybody else (including extensions)
+ this._obs.notifyObservers(null, "browser:purge-domain-data", aDomain);
+ }
+};
+
+function NSGetModule(compMgr, fileSpec)
+ XPCOMUtils.generateModule([PrivateBrowsingService]);
diff --git a/bundles/XO/components/nsProxyAutoConfig.js b/bundles/XO/components/nsProxyAutoConfig.js
new file mode 100755
index 0000000..2afa6b2
--- /dev/null
+++ b/bundles/XO/components/nsProxyAutoConfig.js
@@ -0,0 +1,401 @@
+/* -*- Mode: Java; tab-width: 4; c-basic-offset: 4; -*- */
+/* vim:set ts=4 sw=4 sts=4 et: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Akhil Arora <akhil.arora@sun.com>
+ * Tomi Leppikangas <Tomi.Leppikangas@oulu.fi>
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ Script for Proxy Auto Config in the new world order.
+ - Gagan Saksena 04/24/00
+*/
+
+const kDNS_CONTRACTID = "@mozilla.org/network/dns-service;1";
+const kPAC_CONTRACTID = "@mozilla.org/network/proxy-auto-config;1";
+const kPAC_CID = Components.ID("{63ac8c66-1dd2-11b2-b070-84d00d3eaece}");
+
+const nsISupports = Components.interfaces.nsISupports;
+const nsIProxyAutoConfig = Components.interfaces.nsIProxyAutoConfig;
+const nsIDNSService = Components.interfaces.nsIDNSService;
+
+// implementor of nsIProxyAutoConfig
+function nsProxyAutoConfig() {};
+
+nsProxyAutoConfig.prototype = {
+ // sandbox in which we eval loaded autoconfig js file
+ _sandBox: null,
+
+ QueryInterface: function(iid) {
+ if (iid.Equals(nsIProxyAutoConfig) ||
+ iid.Equals(nsISupports))
+ return this;
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ init: function(pacURI, pacText) {
+ // remove PAC configuration if requested
+ if (pacURI == "" || pacText == "") {
+ this._sandBox = null;
+ return;
+ }
+
+ // allocate a fresh Sandbox to clear global scope for new PAC script
+ this._sandBox = new Components.utils.Sandbox(pacURI);
+ Components.utils.evalInSandbox(pacUtils, this._sandBox);
+
+ // add predefined functions to pac
+ this._sandBox.importFunction(myIpAddress);
+ this._sandBox.importFunction(dnsResolve);
+ this._sandBox.importFunction(proxyAlert, "alert");
+
+ // evaluate loaded js file
+ Components.utils.evalInSandbox(pacText, this._sandBox);
+
+ // We can no longer trust this._sandBox. Touching it directly can
+ // cause all sorts of pain, so wrap it in an XPCSafeJSObjectWrapper
+ // and do all of our work through there.
+ this._sandBox = new XPCSafeJSObjectWrapper(this._sandBox);
+ },
+
+ getProxyForURI: function(testURI, testHost) {
+ if (!("FindProxyForURL" in this._sandBox))
+ return null;
+
+ // Call the original function
+ try {
+ var rval = this._sandBox.FindProxyForURL(testURI, testHost);
+ } catch (e) {
+ throw XPCSafeJSObjectWrapper(e);
+ }
+ return rval;
+ }
+}
+
+function proxyAlert(msg) {
+ msg = XPCSafeJSObjectWrapper(msg);
+ try {
+ // It would appear that the console service is threadsafe.
+ var cns = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+ cns.logStringMessage("PAC-alert: "+msg);
+ } catch (e) {
+ dump("PAC: proxyAlert ERROR: "+e+"\n");
+ }
+}
+
+// wrapper for getting local IP address called by PAC file
+function myIpAddress() {
+ try {
+ return dns.resolve(dns.myHostName, 0).getNextAddrAsString();
+ } catch (e) {
+ return '127.0.0.1';
+ }
+}
+
+// wrapper for resolving hostnames called by PAC file
+function dnsResolve(host) {
+ host = XPCSafeJSObjectWrapper(host);
+ try {
+ return dns.resolve(host, 0).getNextAddrAsString();
+ } catch (e) {
+ return null;
+ }
+}
+
+var pacModule = new Object();
+
+pacModule.registerSelf =
+ function (compMgr, fileSpec, location, type) {
+ compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+ compMgr.registerFactoryLocation(kPAC_CID,
+ "nsProxyAutoConfig",
+ kPAC_CONTRACTID,
+ fileSpec,
+ location,
+ type);
+ }
+
+pacModule.getClassObject =
+function (compMgr, cid, iid) {
+ if (!cid.equals(kPAC_CID))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+
+ if (!iid.equals(Components.interfaces.nsIFactory))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ return pacFactory;
+ }
+
+pacModule.canUnload =
+ function (compMgr) {
+ return true;
+ }
+
+var pacFactory = new Object();
+pacFactory.createInstance =
+ function (outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ if (!iid.equals(nsIProxyAutoConfig) &&
+ !iid.equals(Components.interfaces.nsISupports)) {
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ }
+ return pac;
+ }
+
+function NSGetModule(compMgr, fileSpec) {
+ return pacModule;
+}
+
+var pac = new nsProxyAutoConfig() ;
+var dns = Components.classes[kDNS_CONTRACTID].getService(nsIDNSService);
+
+var pacUtils =
+"function dnsDomainIs(host, domain) {\n" +
+" return (host.length >= domain.length &&\n" +
+" host.substring(host.length - domain.length) == domain);\n" +
+"}\n" +
+
+"function dnsDomainLevels(host) {\n" +
+" return host.split('.').length-1;\n" +
+"}\n" +
+
+"function convert_addr(ipchars) {\n"+
+" var bytes = ipchars.split('.');\n"+
+" var result = ((bytes[0] & 0xff) << 24) |\n"+
+" ((bytes[1] & 0xff) << 16) |\n"+
+" ((bytes[2] & 0xff) << 8) |\n"+
+" (bytes[3] & 0xff);\n"+
+" return result;\n"+
+"}\n"+
+
+"function isInNet(ipaddr, pattern, maskstr) {\n"+
+" var test = /^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$/(ipaddr);\n"+
+" if (test == null) {\n"+
+" ipaddr = dnsResolve(ipaddr);\n"+
+" if (ipaddr == null)\n"+
+" return false;\n"+
+" } else if (test[1] > 255 || test[2] > 255 || \n"+
+" test[3] > 255 || test[4] > 255) {\n"+
+" return false; // not an IP address\n"+
+" }\n"+
+" var host = convert_addr(ipaddr);\n"+
+" var pat = convert_addr(pattern);\n"+
+" var mask = convert_addr(maskstr);\n"+
+" return ((host & mask) == (pat & mask));\n"+
+" \n"+
+"}\n"+
+
+"function isPlainHostName(host) {\n" +
+" return (host.search('\\\\.') == -1);\n" +
+"}\n" +
+
+"function isResolvable(host) {\n" +
+" var ip = dnsResolve(host);\n" +
+" return (ip != null);\n" +
+"}\n" +
+
+"function localHostOrDomainIs(host, hostdom) {\n" +
+" return (host == hostdom) ||\n" +
+" (hostdom.lastIndexOf(host + '.', 0) == 0);\n" +
+"}\n" +
+
+"function shExpMatch(url, pattern) {\n" +
+" pattern = pattern.replace(/\\./g, '\\\\.');\n" +
+" pattern = pattern.replace(/\\*/g, '.*');\n" +
+" pattern = pattern.replace(/\\?/g, '.');\n" +
+" var newRe = new RegExp('^'+pattern+'$');\n" +
+" return newRe.test(url);\n" +
+"}\n" +
+
+"var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" +
+
+"var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n"+
+
+"function weekdayRange() {\n" +
+" function getDay(weekday) {\n" +
+" if (weekday in wdays) {\n" +
+" return wdays[weekday];\n" +
+" }\n" +
+" return -1;\n" +
+" }\n" +
+" var date = new Date();\n" +
+" var argc = arguments.length;\n" +
+" var wday;\n" +
+" if (argc < 1)\n" +
+" return false;\n" +
+" if (arguments[argc - 1] == 'GMT') {\n" +
+" argc--;\n" +
+" wday = date.getUTCDay();\n" +
+" } else {\n" +
+" wday = date.getDay();\n" +
+" }\n" +
+" var wd1 = getDay(arguments[0]);\n" +
+" var wd2 = (argc == 2) ? getDay(arguments[1]) : wd1;\n" +
+" return (wd1 == -1 || wd2 == -1) ? false\n" +
+" : (wd1 <= wday && wday <= wd2);\n" +
+"}\n" +
+
+"function dateRange() {\n" +
+" function getMonth(name) {\n" +
+" if (name in months) {\n" +
+" return months[name];\n" +
+" }\n" +
+" return -1;\n" +
+" }\n" +
+" var date = new Date();\n" +
+" var argc = arguments.length;\n" +
+" if (argc < 1) {\n" +
+" return false;\n" +
+" }\n" +
+" var isGMT = (arguments[argc - 1] == 'GMT');\n" +
+"\n" +
+" if (isGMT) {\n" +
+" argc--;\n" +
+" }\n" +
+" // function will work even without explict handling of this case\n" +
+" if (argc == 1) {\n" +
+" var tmp = parseInt(arguments[0]);\n" +
+" if (isNaN(tmp)) {\n" +
+" return ((isGMT ? date.getUTCMonth() : date.getMonth()) ==\n" +
+"getMonth(arguments[0]));\n" +
+" } else if (tmp < 32) {\n" +
+" return ((isGMT ? date.getUTCDate() : date.getDate()) == tmp);\n" +
+" } else { \n" +
+" return ((isGMT ? date.getUTCFullYear() : date.getFullYear()) ==\n" +
+"tmp);\n" +
+" }\n" +
+" }\n" +
+" var year = date.getFullYear();\n" +
+" var date1, date2;\n" +
+" date1 = new Date(year, 0, 1, 0, 0, 0);\n" +
+" date2 = new Date(year, 11, 31, 23, 59, 59);\n" +
+" var adjustMonth = false;\n" +
+" for (var i = 0; i < (argc >> 1); i++) {\n" +
+" var tmp = parseInt(arguments[i]);\n" +
+" if (isNaN(tmp)) {\n" +
+" var mon = getMonth(arguments[i]);\n" +
+" date1.setMonth(mon);\n" +
+" } else if (tmp < 32) {\n" +
+" adjustMonth = (argc <= 2);\n" +
+" date1.setDate(tmp);\n" +
+" } else {\n" +
+" date1.setFullYear(tmp);\n" +
+" }\n" +
+" }\n" +
+" for (var i = (argc >> 1); i < argc; i++) {\n" +
+" var tmp = parseInt(arguments[i]);\n" +
+" if (isNaN(tmp)) {\n" +
+" var mon = getMonth(arguments[i]);\n" +
+" date2.setMonth(mon);\n" +
+" } else if (tmp < 32) {\n" +
+" date2.setDate(tmp);\n" +
+" } else {\n" +
+" date2.setFullYear(tmp);\n" +
+" }\n" +
+" }\n" +
+" if (adjustMonth) {\n" +
+" date1.setMonth(date.getMonth());\n" +
+" date2.setMonth(date.getMonth());\n" +
+" }\n" +
+" if (isGMT) {\n" +
+" var tmp = date;\n" +
+" tmp.setFullYear(date.getUTCFullYear());\n" +
+" tmp.setMonth(date.getUTCMonth());\n" +
+" tmp.setDate(date.getUTCDate());\n" +
+" tmp.setHours(date.getUTCHours());\n" +
+" tmp.setMinutes(date.getUTCMinutes());\n" +
+" tmp.setSeconds(date.getUTCSeconds());\n" +
+" date = tmp;\n" +
+" }\n" +
+" return ((date1 <= date) && (date <= date2));\n" +
+"}\n" +
+
+"function timeRange() {\n" +
+" var argc = arguments.length;\n" +
+" var date = new Date();\n" +
+" var isGMT= false;\n"+
+"\n" +
+" if (argc < 1) {\n" +
+" return false;\n" +
+" }\n" +
+" if (arguments[argc - 1] == 'GMT') {\n" +
+" isGMT = true;\n" +
+" argc--;\n" +
+" }\n" +
+"\n" +
+" var hour = isGMT ? date.getUTCHours() : date.getHours();\n" +
+" var date1, date2;\n" +
+" date1 = new Date();\n" +
+" date2 = new Date();\n" +
+"\n" +
+" if (argc == 1) {\n" +
+" return (hour == arguments[0]);\n" +
+" } else if (argc == 2) {\n" +
+" return ((arguments[0] <= hour) && (hour <= arguments[1]));\n" +
+" } else {\n" +
+" switch (argc) {\n" +
+" case 6:\n" +
+" date1.setSeconds(arguments[2]);\n" +
+" date2.setSeconds(arguments[5]);\n" +
+" case 4:\n" +
+" var middle = argc >> 1;\n" +
+" date1.setHours(arguments[0]);\n" +
+" date1.setMinutes(arguments[1]);\n" +
+" date2.setHours(arguments[middle]);\n" +
+" date2.setMinutes(arguments[middle + 1]);\n" +
+" if (middle == 2) {\n" +
+" date2.setSeconds(59);\n" +
+" }\n" +
+" break;\n" +
+" default:\n" +
+" throw 'timeRange: bad number of arguments'\n" +
+" }\n" +
+" }\n" +
+"\n" +
+" if (isGMT) {\n" +
+" date.setFullYear(date.getUTCFullYear());\n" +
+" date.setMonth(date.getUTCMonth());\n" +
+" date.setDate(date.getUTCDate());\n" +
+" date.setHours(date.getUTCHours());\n" +
+" date.setMinutes(date.getUTCMinutes());\n" +
+" date.setSeconds(date.getUTCSeconds());\n" +
+" }\n" +
+" return ((date1 <= date) && (date <= date2));\n" +
+"}\n"
+
diff --git a/bundles/XO/components/nsSafebrowsingApplication.js b/bundles/XO/components/nsSafebrowsingApplication.js
new file mode 100755
index 0000000..cba7a15
--- /dev/null
+++ b/bundles/XO/components/nsSafebrowsingApplication.js
@@ -0,0 +1,745 @@
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+// This is copied from toolkit/components/content/js/lang.js.
+// It seems cleaner to copy this rather than #include from so far away.
+Function.prototype.inherits = function(parentCtor) {
+ var tempCtor = function(){};
+ tempCtor.prototype = parentCtor.prototype;
+ this.superClass_ = parentCtor.prototype;
+ this.prototype = new tempCtor();
+}
+
+//@line 36 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/content/application.js"
+
+// We instantiate this variable when we create the application.
+var gDataProvider = null;
+
+// An instance of our application is a PROT_Application object. It
+// basically just populates a few globals and instantiates wardens,
+// the listmanager, and the about:blocked error page.
+
+/**
+ * An instance of our application. There should be exactly one of these.
+ *
+ * Note: This object should instantiated only at profile-after-change
+ * or later because the listmanager and the cryptokeymanager need to
+ * read and write data files. Additionally, NSS isn't loaded until
+ * some time around then (Moz bug #321024).
+ *
+ * @constructor
+ */
+function PROT_Application() {
+ this.debugZone= "application";
+
+//@line 83 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/content/application.js"
+
+ // expose some classes
+ this.PROT_PhishingWarden = PROT_PhishingWarden;
+ this.PROT_MalwareWarden = PROT_MalwareWarden;
+
+ // Load data provider pref values
+ gDataProvider = new PROT_DataProvider();
+
+ // expose the object
+ this.wrappedJSObject = this;
+}
+
+var gInitialized = false;
+PROT_Application.prototype.initialize = function() {
+ if (gInitialized)
+ return;
+ gInitialized = true;
+
+ var obs = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ obs.addObserver(this, "xpcom-shutdown", true);
+
+ // XXX: move table names to a pref that we originally will download
+ // from the provider (need to workout protocol details)
+ this.malwareWarden = new PROT_MalwareWarden();
+ this.malwareWarden.registerBlackTable("goog-malware-shavar");
+ this.malwareWarden.maybeToggleUpdateChecking();
+
+ this.phishWarden = new PROT_PhishingWarden();
+ this.phishWarden.registerBlackTable("goog-phish-shavar");
+ this.phishWarden.maybeToggleUpdateChecking();
+}
+
+PROT_Application.prototype.observe = function(subject, topic, data) {
+ switch (topic) {
+ case "xpcom-shutdown":
+ this.malwareWarden.shutdown();
+ this.phishWarden.shutdown();
+ break;
+ }
+}
+
+/**
+ * @param name String The type of url to get (either Phish or Error).
+ * @return String the report phishing URL (localized).
+ */
+PROT_Application.prototype.getReportURL = function(name) {
+ return gDataProvider["getReport" + name + "URL"]();
+}
+
+/**
+ * about:blocked implementation
+ */
+PROT_Application.prototype.newChannel = function(uri) {
+ var ioService = Cc["@mozilla.org/network/io-service;1"]
+ .getService(Ci.nsIIOService);
+ var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
+ .getService(Ci.nsIScriptSecurityManager);
+
+ var childURI = ioService.newURI("chrome://browser/content/safebrowsing/blockedSite.xhtml",
+ null, null);
+ var channel = ioService.newChannelFromURI(childURI);
+ channel.originalURI = uri;
+
+ // Drop chrome privilege
+ var principal = secMan.getCodebasePrincipal(uri);
+ channel.owner = principal;
+
+ return channel;
+}
+
+PROT_Application.prototype.getURIFlags = function(uri) {
+ // We don't particularly *want* people linking to this from
+ // untrusted content, but given that bad sites can cause this page
+ // to appear (e.g. by having an iframe pointing to known malware),
+ // we should code as though this is explicitly possible.
+ return Ci.nsIAboutModule.ALLOW_SCRIPT |
+ Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT;
+}
+
+PROT_Application.prototype.QueryInterface = function(iid) {
+ if (iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsISupportsWeakReference) ||
+ iid.equals(Ci.nsIObserver) ||
+ iid.equals(Ci.nsIAboutModule))
+ return this;
+
+ Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
+ return null;
+}
+//@line 37 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/content/globalstore.js"
+
+
+// A class that encapsulates data provider specific values. The
+// root of the provider pref tree is browser.safebrowsing.provider.
+// followed by a number, followed by specific properties. The properties
+// that a data provider can supply are:
+//
+// name: The name of the provider
+// lookupURL: The URL to send requests to in enhanced mode
+// keyURL: Before we send URLs in enhanced mode, we need to encrypt them
+// reportURL: When shown a warning bubble, we send back the user decision
+// (get me out of here/ignore warning) to this URL (strip cookies
+// first). This is optional.
+// gethashURL: Url for requesting complete hashes from the provider.
+// reportGenericURL: HTML page for general user feedback
+// reportPhishURL: HTML page for notifying the provider of a new phishing page
+// reportErrorURL: HTML page for notifying the provider of a false positive
+
+const kDataProviderIdPref = 'browser.safebrowsing.dataProvider';
+const kProviderBasePref = 'browser.safebrowsing.provider.';
+
+//@line 59 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/content/globalstore.js"
+const MOZ_OFFICIAL_BUILD = true;
+//@line 63 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/content/globalstore.js"
+
+const MOZ_PARAM_LOCALE = /\{moz:locale\}/g;
+const MOZ_PARAM_CLIENT = /\{moz:client\}/g;
+const MOZ_PARAM_BUILDID = /\{moz:buildid\}/g;
+const MOZ_PARAM_VERSION = /\{moz:version\}/g;
+
+/**
+ * Information regarding the data provider.
+ */
+function PROT_DataProvider() {
+ this.prefs_ = new G_Preferences();
+
+ this.loadDataProviderPrefs_();
+
+ // Watch for changes in the data provider and update accordingly.
+ this.prefs_.addObserver(kDataProviderIdPref,
+ BindToObject(this.loadDataProviderPrefs_, this));
+
+ // Watch for when anti-phishing is toggled on or off.
+ this.prefs_.addObserver(kPhishWardenEnabledPref,
+ BindToObject(this.loadDataProviderPrefs_, this));
+}
+
+/**
+ * Populate all the provider variables. We also call this when whenever
+ * the provider id changes.
+ */
+PROT_DataProvider.prototype.loadDataProviderPrefs_ = function() {
+ // Currently, there's no UI for changing local list provider so we
+ // hard code the value for provider 0.
+ this.updateURL_ = this.getUrlPref_(
+ 'browser.safebrowsing.provider.0.updateURL');
+
+ var id = this.prefs_.getPref(kDataProviderIdPref, null);
+
+ // default to 0
+ if (null == id)
+ id = 0;
+
+ var basePref = kProviderBasePref + id + '.';
+
+ this.name_ = this.prefs_.getPref(basePref + "name", "");
+
+ // Urls used to get data from a provider
+ this.lookupURL_ = this.getUrlPref_(basePref + "lookupURL");
+ this.keyURL_ = this.getUrlPref_(basePref + "keyURL");
+ this.reportURL_ = this.getUrlPref_(basePref + "reportURL");
+ this.gethashURL_ = this.getUrlPref_(basePref + "gethashURL");
+
+ // Urls to HTML report pages
+ this.reportGenericURL_ = this.getUrlPref_(basePref + "reportGenericURL");
+ this.reportErrorURL_ = this.getUrlPref_(basePref + "reportErrorURL");
+ this.reportPhishURL_ = this.getUrlPref_(basePref + "reportPhishURL");
+ this.reportMalwareURL_ = this.getUrlPref_(basePref + "reportMalwareURL")
+ this.reportMalwareErrorURL_ = this.getUrlPref_(basePref + "reportMalwareErrorURL")
+
+ // Propagate the changes to the list-manager.
+ this.updateListManager_();
+}
+
+/**
+ * The list manager needs urls to operate. It needs a url to know where the
+ * table updates are, and it needs a url for decrypting enchash style tables.
+ */
+PROT_DataProvider.prototype.updateListManager_ = function() {
+ var listManager = Cc["@mozilla.org/url-classifier/listmanager;1"]
+ .getService(Ci.nsIUrlListManager);
+
+ // If we add support for changing local data providers, we need to add a
+ // pref observer that sets the update url accordingly.
+ listManager.setUpdateUrl(this.getUpdateURL());
+
+ // setKeyUrl has the side effect of fetching a key from the server.
+ // This shouldn't happen if anti-phishing/anti-malware is disabled.
+ var isEnabled = this.prefs_.getPref(kPhishWardenEnabledPref, false) ||
+ this.prefs_.getPref(kMalwareWardenEnabledPref, false);
+ if (isEnabled) {
+ listManager.setKeyUrl(this.keyURL_);
+ }
+
+ listManager.setGethashUrl(this.getGethashURL());
+}
+
+/**
+ * Lookup the value of a URL from prefs file and do parameter substitution.
+ */
+PROT_DataProvider.prototype.getUrlPref_ = function(prefName) {
+ var url = this.prefs_.getPref(prefName);
+
+ var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
+ .getService(Components.interfaces.nsIXULAppInfo);
+
+ var mozClientStr = this.prefs_.getPref("browser.safebrowsing.clientid",
+ MOZ_OFFICIAL_BUILD ? 'navclient-auto-ffox' : appInfo.name);
+
+ var versionStr = this.prefs_.getPref("browser.safebrowsing.clientver",
+ appInfo.version);
+
+ // Parameter substitution
+ url = url.replace(MOZ_PARAM_LOCALE, this.getLocale_());
+ url = url.replace(MOZ_PARAM_CLIENT, mozClientStr);
+ url = url.replace(MOZ_PARAM_BUILDID, appInfo.appBuildID);
+ url = url.replace(MOZ_PARAM_VERSION, versionStr);
+ return url;
+}
+
+/**
+ * @return String the browser locale (similar code is in nsSearchService.js)
+ */
+PROT_DataProvider.prototype.getLocale_ = function() {
+ const localePref = "general.useragent.locale";
+ var locale = this.getLocalizedPref_(localePref);
+ if (locale)
+ return locale;
+
+ // Not localized
+ var prefs = new G_Preferences();
+ return prefs.getPref(localePref, "");
+}
+
+/**
+ * @return String name of the localized pref, null if none exists.
+ */
+PROT_DataProvider.prototype.getLocalizedPref_ = function(aPrefName) {
+ // G_Preferences doesn't know about complex values, so we use the
+ // xpcom object directly.
+ var prefs = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefBranch);
+ try {
+ return prefs.getComplexValue(aPrefName, Ci.nsIPrefLocalizedString).data;
+ } catch (ex) {
+ }
+ return "";
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Getters for the remote provider pref values mentioned above.
+PROT_DataProvider.prototype.getName = function() {
+ return this.name_;
+}
+
+PROT_DataProvider.prototype.getUpdateURL = function() {
+ return this.updateURL_;
+}
+
+PROT_DataProvider.prototype.getLookupURL = function() {
+ return this.lookupURL_;
+}
+
+PROT_DataProvider.prototype.getGethashURL = function() {
+ return this.gethashURL_;
+}
+
+PROT_DataProvider.prototype.getReportGenericURL = function() {
+ return this.reportGenericURL_;
+}
+PROT_DataProvider.prototype.getReportErrorURL = function() {
+ return this.reportErrorURL_;
+}
+PROT_DataProvider.prototype.getReportPhishURL = function() {
+ return this.reportPhishURL_;
+}
+PROT_DataProvider.prototype.getReportMalwareURL = function() {
+ return this.reportMalwareURL_;
+}
+PROT_DataProvider.prototype.getReportMalwareErrorURL = function() {
+ return this.reportMalwareErrorURL_;
+}
+//@line 37 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/content/list-warden.js"
+
+// A warden that knows how to register lists with a listmanager and keep them
+// updated if necessary. The ListWarden also provides a simple interface to
+// check if a URL is evil or not. Specialized wardens like the PhishingWarden
+// inherit from it.
+//
+// Classes that inherit from ListWarden are responsible for calling
+// enableTableUpdates or disableTableUpdates. This usually entails
+// registering prefObservers and calling enable or disable in the base
+// class as appropriate.
+//
+
+/**
+ * Abtracts the checking of user/browser actions for signs of
+ * phishing.
+ *
+ * @constructor
+ */
+function PROT_ListWarden() {
+ this.debugZone = "listwarden";
+ var listManager = Cc["@mozilla.org/url-classifier/listmanager;1"]
+ .getService(Ci.nsIUrlListManager);
+ this.listManager_ = listManager;
+
+ // Once we register tables, their respective names will be listed here.
+ this.blackTables_ = [];
+ this.whiteTables_ = [];
+}
+
+PROT_ListWarden.IN_BLACKLIST = 0
+PROT_ListWarden.IN_WHITELIST = 1
+PROT_ListWarden.NOT_FOUND = 2
+
+/**
+ * Tell the ListManger to keep all of our tables updated
+ */
+
+PROT_ListWarden.prototype.enableBlacklistTableUpdates = function() {
+ for (var i = 0; i < this.blackTables_.length; ++i) {
+ this.listManager_.enableUpdate(this.blackTables_[i]);
+ }
+}
+
+/**
+ * Tell the ListManager to stop updating our tables
+ */
+
+PROT_ListWarden.prototype.disableBlacklistTableUpdates = function() {
+ for (var i = 0; i < this.blackTables_.length; ++i) {
+ this.listManager_.disableUpdate(this.blackTables_[i]);
+ }
+}
+
+/**
+ * Tell the ListManager to update whitelist tables. They may be enabled even
+ * when other updates aren't, for performance reasons.
+ */
+PROT_ListWarden.prototype.enableWhitelistTableUpdates = function() {
+ for (var i = 0; i < this.whiteTables_.length; ++i) {
+ this.listManager_.enableUpdate(this.whiteTables_[i]);
+ }
+}
+
+/**
+ * Tell the ListManager to stop updating whitelist tables.
+ */
+PROT_ListWarden.prototype.disableWhitelistTableUpdates = function() {
+ for (var i = 0; i < this.whiteTables_.length; ++i) {
+ this.listManager_.disableUpdate(this.whiteTables_[i]);
+ }
+}
+
+/**
+ * Register a new black list table with the list manager
+ * @param tableName - name of the table to register
+ * @returns true if the table could be registered, false otherwise
+ */
+
+PROT_ListWarden.prototype.registerBlackTable = function(tableName) {
+ var result = this.listManager_.registerTable(tableName, false);
+ if (result) {
+ this.blackTables_.push(tableName);
+ }
+ return result;
+}
+
+/**
+ * Register a new white list table with the list manager
+ * @param tableName - name of the table to register
+ * @returns true if the table could be registered, false otherwise
+ */
+
+PROT_ListWarden.prototype.registerWhiteTable = function(tableName) {
+ var result = this.listManager_.registerTable(tableName, false);
+ if (result) {
+ this.whiteTables_.push(tableName);
+ }
+ return result;
+}
+//@line 36 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/content/phishing-warden.js"
+
+
+// The warden checks request to see if they are for phishy pages. It
+// does so by querying our locally stored blacklists.
+//
+// When the warden notices a problem, it queries all browser views
+// (each of which corresopnds to an open browser window) to see
+// whether one of them can handle it. A browser view can handle a
+// problem if its browser window has an HTMLDocument loaded with the
+// given URL and that Document hasn't already been flagged as a
+// problem. For every problematic URL we notice loading, at most one
+// Document is flagged as problematic. Otherwise you can get into
+// trouble if multiple concurrent phishy pages load with the same URL.
+//
+// Since we check URLs very early in the request cycle (in a progress
+// listener), the URL might not yet be associated with a Document when
+// we determine that it is phishy. So the the warden retries finding
+// a browser view to handle the problem until one can, or until it
+// determines it should give up (see complicated logic below).
+//
+// The warden has displayers that the browser view uses to render
+// different kinds of warnings (e.g., one that's shown before a page
+// loads as opposed to one that's shown after the page has already
+// loaded).
+//
+// Note: There is a single warden for the whole application.
+//
+// TODO better way to expose displayers/views to browser view
+
+const kPhishWardenEnabledPref = "browser.safebrowsing.enabled";
+
+/**
+ * Abtracts the checking of user/browser actions for signs of
+ * phishing.
+ *
+ * @param progressListener nsIDocNavStartProgressListener
+ * @param tabbrowser XUL tabbrowser element
+ * @constructor
+ */
+function PROT_PhishingWarden() {
+ PROT_ListWarden.call(this);
+
+ this.debugZone = "phishwarden";
+
+ // Use this to query preferences
+ this.prefs_ = new G_Preferences();
+
+ // We need to know whether we're enabled and whether we're in advanced
+ // mode, so reflect the appropriate preferences into our state.
+
+ // Global preference to enable the phishing warden
+ this.phishWardenEnabled_ = this.prefs_.getPref(kPhishWardenEnabledPref, null);
+
+ // Get notifications when the phishing warden enabled pref changes
+ var phishWardenPrefObserver =
+ BindToObject(this.onPhishWardenEnabledPrefChanged, this);
+ this.prefs_.addObserver(kPhishWardenEnabledPref, phishWardenPrefObserver);
+
+ G_Debug(this, "phishWarden initialized");
+}
+
+PROT_PhishingWarden.inherits(PROT_ListWarden);
+
+PROT_PhishingWarden.prototype.QueryInterface = function(iid) {
+ if (iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsISupportsWeakReference))
+ return this;
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+}
+
+/**
+ * Cleanup on shutdown.
+ */
+PROT_PhishingWarden.prototype.shutdown = function() {
+ this.prefs_.removeAllObservers();
+ this.listManager_ = null;
+}
+
+/**
+ * When a preference (either advanced features or the phishwarden
+ * enabled) changes, we might have to start or stop asking for updates.
+ *
+ * This is a little tricky; we start or stop management only when we
+ * have complete information we can use to determine whether we
+ * should. It could be the case that one pref or the other isn't set
+ * yet (e.g., they haven't opted in/out of advanced features). So do
+ * nothing unless we have both pref values -- we get notifications for
+ * both, so eventually we will start correctly.
+ */
+PROT_PhishingWarden.prototype.maybeToggleUpdateChecking = function() {
+ var phishWardenEnabled = this.prefs_.getPref(kPhishWardenEnabledPref, null);
+
+ G_Debug(this, "Maybe toggling update checking. " +
+ "Warden enabled? " + phishWardenEnabled);
+
+ // Do nothing unless both prefs are set. They can be null (unset), true, or
+ // false.
+ if (phishWardenEnabled === null)
+ return;
+
+ // We update and save to disk all tables
+ if (phishWardenEnabled === true) {
+ this.enableBlacklistTableUpdates();
+ this.enableWhitelistTableUpdates();
+ } else {
+ // Anti-phishing is off, disable table updates
+ this.disableBlacklistTableUpdates();
+ this.disableWhitelistTableUpdates();
+ }
+}
+
+/**
+ * Deal with a user changing the pref that says whether we should
+ * enable the phishing warden (i.e., that SafeBrowsing is active)
+ *
+ * @param prefName Name of the pref holding the value indicating whether
+ * we should enable the phishing warden
+ */
+PROT_PhishingWarden.prototype.onPhishWardenEnabledPrefChanged = function(
+ prefName) {
+ // Just to be safe, ignore changes to sub prefs.
+ if (prefName != "browser.safebrowsing.enabled")
+ return;
+
+ this.phishWardenEnabled_ =
+ this.prefs_.getPref(prefName, this.phishWardenEnabled_);
+ this.maybeToggleUpdateChecking();
+}
+//@line 37 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/content/malware-warden.js"
+
+// This warden manages updates to the malware list
+
+const kMalwareWardenEnabledPref = "browser.safebrowsing.malware.enabled";
+
+function PROT_MalwareWarden() {
+ PROT_ListWarden.call(this);
+
+ this.debugZone = "malwarewarden";
+
+ // Use this to query preferences
+ this.prefs_ = new G_Preferences();
+
+ // Global preference to enable the malware warden
+ this.malwareWardenEnabled_ =
+ this.prefs_.getPref(kMalwareWardenEnabledPref, null);
+
+ // Get notifications when the malware warden enabled pref changes
+ var malwareWardenPrefObserver =
+ BindToObject(this.onMalwareWardenEnabledPrefChanged, this);
+ this.prefs_.addObserver(kMalwareWardenEnabledPref, malwareWardenPrefObserver);
+
+ // Add a test chunk to the database
+ var testData = "mozilla.com/firefox/its-an-attack.html";
+
+ var testUpdate =
+ "n:1000\ni:test-malware-simple\nad:1\n" +
+ "a:1:32:" + testData.length + "\n" +
+ testData;
+
+ testData = "mozilla.com/firefox/its-a-trap.html";
+ testUpdate +=
+ "n:1000\ni:test-phish-simple\nad:1\n" +
+ "a:1:32:" + testData.length + "\n" +
+ testData;
+
+ var dbService_ = Cc["@mozilla.org/url-classifier/dbservice;1"]
+ .getService(Ci.nsIUrlClassifierDBService);
+
+ var listener = {
+ QueryInterface: function(iid)
+ {
+ if (iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsIUrlClassifierUpdateObserver))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ updateUrlRequested: function(url) { },
+ streamFinished: function(status) { },
+ updateError: function(errorCode) { },
+ updateSuccess: function(requestedTimeout) { }
+ };
+
+ try {
+ dbService_.beginUpdate(listener,
+ "test-malware-simple,test-phish-simple", "");
+ dbService_.beginStream("", "");
+ dbService_.updateStream(testUpdate);
+ dbService_.finishStream();
+ dbService_.finishUpdate();
+ } catch(ex) {
+ // beginUpdate will throw harmlessly if there's an existing update
+ // in progress, ignore failures.
+ }
+ G_Debug(this, "malwareWarden initialized");
+}
+
+PROT_MalwareWarden.inherits(PROT_ListWarden);
+
+/**
+ * Cleanup on shutdown.
+ */
+PROT_MalwareWarden.prototype.shutdown = function() {
+ this.prefs_.removeAllObservers();
+
+ this.listManager_ = null;
+}
+
+/**
+ * When a preference changes, we might have to start or stop asking for
+ * updates.
+ */
+PROT_MalwareWarden.prototype.maybeToggleUpdateChecking = function() {
+ var malwareWardenEnabled = this.prefs_.getPref(kMalwareWardenEnabledPref,
+ null);
+
+ G_Debug(this, "Maybe toggling update checking. " +
+ "Warden enabled? " + malwareWardenEnabled);
+
+ // Do nothing unless thre pref is set
+ if (malwareWardenEnabled === null)
+ return;
+
+ // We update and save to disk all tables
+ if (malwareWardenEnabled === true) {
+ this.enableBlacklistTableUpdates();
+ } else {
+ // Anti-malware is off, disable table updates
+ this.disableBlacklistTableUpdates();
+ }
+}
+
+/**
+ * Deal with a user changing the pref that says whether we should
+ * enable the malware warden.
+ *
+ * @param prefName Name of the pref holding the value indicating whether
+ * we should enable the malware warden
+ */
+PROT_MalwareWarden.prototype.onMalwareWardenEnabledPrefChanged = function(
+ prefName) {
+ // Just to be safe, ignore changes to sub prefs.
+ if (prefName != kMalwareWardenEnabledPref)
+ return;
+
+ this.malwareWardenEnabled_ =
+ this.prefs_.getPref(prefName, this.malwareWardenEnabled_);
+ this.maybeToggleUpdateChecking();
+}
+//@line 18 "/builds/moz2_slave/linux_build/build/browser/components/safebrowsing/src/nsSafebrowsingApplication.js"
+
+var modScope = this;
+function Init() {
+ var jslib = Cc["@mozilla.org/url-classifier/jslib;1"]
+ .getService().wrappedJSObject;
+ modScope.G_Debug = jslib.G_Debug;
+ modScope.G_Assert = jslib.G_Assert;
+ modScope.G_Alarm = jslib.G_Alarm;
+ modScope.G_ConditionalAlarm = jslib.G_ConditionalAlarm;
+ modScope.G_ObserverWrapper = jslib.G_ObserverWrapper;
+ modScope.G_Preferences = jslib.G_Preferences;
+ modScope.PROT_XMLFetcher = jslib.PROT_XMLFetcher;
+ modScope.BindToObject = jslib.BindToObject;
+ modScope.G_Protocol4Parser = jslib.G_Protocol4Parser;
+ modScope.PROT_UrlCrypto = jslib.PROT_UrlCrypto;
+ modScope.RequestBackoff = jslib.RequestBackoff;
+
+ // We only need to call Init once
+ modScope.Init = function() {};
+}
+
+// Module object
+function SafebrowsingApplicationMod() {
+ this.firstTime = true;
+ this.cid = Components.ID("{c64d0bcb-8270-4ca7-a0b3-3380c8ffecb5}");
+ this.progid = "@mozilla.org/safebrowsing/application;1";
+}
+
+SafebrowsingApplicationMod.prototype.registerSelf = function(compMgr, fileSpec, loc, type) {
+ if (this.firstTime) {
+ this.firstTime = false;
+ throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
+ }
+ compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ compMgr.registerFactoryLocation(this.cid,
+ "Safebrowsing Application Module",
+ this.progid,
+ fileSpec,
+ loc,
+ type);
+
+ compMgr.registerFactoryLocation(this.cid,
+ "UrlClassifier Blocked Error Page",
+ "@mozilla.org/network/protocol/about;1?what=blocked",
+ fileSpec,
+ loc,
+ type);
+};
+
+SafebrowsingApplicationMod.prototype.getClassObject = function(compMgr, cid, iid) {
+ if (!cid.equals(this.cid))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ if (!iid.equals(Ci.nsIFactory))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ return this.factory;
+}
+
+SafebrowsingApplicationMod.prototype.canUnload = function(compMgr) {
+ return true;
+}
+
+SafebrowsingApplicationMod.prototype.factory = {
+ createInstance: function(outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+ Init();
+ return new PROT_Application();
+ }
+};
+
+var ApplicationModInst = new SafebrowsingApplicationMod();
+
+function NSGetModule(compMgr, fileSpec) {
+ return ApplicationModInst;
+}
diff --git a/bundles/XO/components/nsSearchService.js b/bundles/XO/components/nsSearchService.js
new file mode 100755
index 0000000..5c40314
--- /dev/null
+++ b/bundles/XO/components/nsSearchService.js
@@ -0,0 +1,3572 @@
+//@line 40 "/builds/moz2_slave/linux_build/build/toolkit/components/search/nsSearchService.js"
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+
+const PERMS_FILE = 0644;
+const PERMS_DIRECTORY = 0755;
+
+const MODE_RDONLY = 0x01;
+const MODE_WRONLY = 0x02;
+const MODE_CREATE = 0x08;
+const MODE_APPEND = 0x10;
+const MODE_TRUNCATE = 0x20;
+
+// Directory service keys
+const NS_APP_SEARCH_DIR_LIST = "SrchPluginsDL";
+const NS_APP_USER_SEARCH_DIR = "UsrSrchPlugns";
+const NS_APP_SEARCH_DIR = "SrchPlugns";
+const NS_APP_USER_PROFILE_50_DIR = "ProfD";
+
+// Search engine "locations". If this list is changed, be sure to update
+// the engine's _isDefault function accordingly.
+const SEARCH_APP_DIR = 1;
+const SEARCH_PROFILE_DIR = 2;
+const SEARCH_IN_EXTENSION = 3;
+
+// See documentation in nsIBrowserSearchService.idl.
+const SEARCH_ENGINE_TOPIC = "browser-search-engine-modified";
+const QUIT_APPLICATION_TOPIC = "quit-application";
+
+const SEARCH_ENGINE_REMOVED = "engine-removed";
+const SEARCH_ENGINE_ADDED = "engine-added";
+const SEARCH_ENGINE_CHANGED = "engine-changed";
+const SEARCH_ENGINE_LOADED = "engine-loaded";
+const SEARCH_ENGINE_CURRENT = "engine-current";
+
+const SEARCH_TYPE_MOZSEARCH = Ci.nsISearchEngine.TYPE_MOZSEARCH;
+const SEARCH_TYPE_OPENSEARCH = Ci.nsISearchEngine.TYPE_OPENSEARCH;
+const SEARCH_TYPE_SHERLOCK = Ci.nsISearchEngine.TYPE_SHERLOCK;
+
+const SEARCH_DATA_XML = Ci.nsISearchEngine.DATA_XML;
+const SEARCH_DATA_TEXT = Ci.nsISearchEngine.DATA_TEXT;
+
+// File extensions for search plugin description files
+const XML_FILE_EXT = "xml";
+const SHERLOCK_FILE_EXT = "src";
+
+// Delay for lazy serialization (ms)
+const LAZY_SERIALIZE_DELAY = 100;
+
+// Delay for batching invalidation of the JSON cache (ms)
+const CACHE_INVALIDATION_DELAY = 1000;
+
+// Current cache version. This should be incremented if the format of the cache
+// file is modified.
+const CACHE_VERSION = 5;
+
+const ICON_DATAURL_PREFIX = "data:image/x-icon;base64,";
+
+// Supported extensions for Sherlock plugin icons
+const SHERLOCK_ICON_EXTENSIONS = [".gif", ".png", ".jpg", ".jpeg"];
+
+const NEW_LINES = /(\r\n|\r|\n)/;
+
+// Set an arbitrary cap on the maximum icon size. Without this, large icons can
+// cause big delays when loading them at startup.
+const MAX_ICON_SIZE = 10000;
+
+// Default charset to use for sending search parameters. ISO-8859-1 is used to
+// match previous nsInternetSearchService behavior.
+const DEFAULT_QUERY_CHARSET = "ISO-8859-1";
+
+const SEARCH_BUNDLE = "chrome://global/locale/search/search.properties";
+const BRAND_BUNDLE = "chrome://branding/locale/brand.properties";
+
+const OPENSEARCH_NS_10 = "http://a9.com/-/spec/opensearch/1.0/";
+const OPENSEARCH_NS_11 = "http://a9.com/-/spec/opensearch/1.1/";
+
+// Although the specification at http://opensearch.a9.com/spec/1.1/description/
+// gives the namespace names defined above, many existing OpenSearch engines
+// are using the following versions. We therefore allow either.
+const OPENSEARCH_NAMESPACES = [
+ OPENSEARCH_NS_11, OPENSEARCH_NS_10,
+ "http://a9.com/-/spec/opensearchdescription/1.1/",
+ "http://a9.com/-/spec/opensearchdescription/1.0/"
+];
+
+const OPENSEARCH_LOCALNAME = "OpenSearchDescription";
+
+const MOZSEARCH_NS_10 = "http://www.mozilla.org/2006/browser/search/";
+const MOZSEARCH_LOCALNAME = "SearchPlugin";
+
+const URLTYPE_SUGGEST_JSON = "application/x-suggestions+json";
+const URLTYPE_SEARCH_HTML = "text/html";
+const URLTYPE_OPENSEARCH = "application/opensearchdescription+xml";
+
+// Empty base document used to serialize engines to file.
+const EMPTY_DOC = "<?xml version=\"1.0\"?>\n" +
+ "<" + MOZSEARCH_LOCALNAME +
+ " xmlns=\"" + MOZSEARCH_NS_10 + "\"" +
+ " xmlns:os=\"" + OPENSEARCH_NS_11 + "\"" +
+ "/>";
+
+const BROWSER_SEARCH_PREF = "browser.search.";
+
+const USER_DEFINED = "{searchTerms}";
+
+// Custom search parameters
+//@line 149 "/builds/moz2_slave/linux_build/build/toolkit/components/search/nsSearchService.js"
+const MOZ_OFFICIAL = "official";
+//@line 153 "/builds/moz2_slave/linux_build/build/toolkit/components/search/nsSearchService.js"
+const MOZ_DISTRIBUTION_ID = "org.mozilla";
+
+const MOZ_PARAM_LOCALE = /\{moz:locale\}/g;
+const MOZ_PARAM_DIST_ID = /\{moz:distributionID\}/g;
+const MOZ_PARAM_OFFICIAL = /\{moz:official\}/g;
+
+// Supported OpenSearch parameters
+// See http://opensearch.a9.com/spec/1.1/querysyntax/#core
+const OS_PARAM_USER_DEFINED = /\{searchTerms\??\}/g;
+const OS_PARAM_INPUT_ENCODING = /\{inputEncoding\??\}/g;
+const OS_PARAM_LANGUAGE = /\{language\??\}/g;
+const OS_PARAM_OUTPUT_ENCODING = /\{outputEncoding\??\}/g;
+
+// Default values
+const OS_PARAM_LANGUAGE_DEF = "*";
+const OS_PARAM_OUTPUT_ENCODING_DEF = "UTF-8";
+const OS_PARAM_INPUT_ENCODING_DEF = "UTF-8";
+
+// "Unsupported" OpenSearch parameters. For example, we don't support
+// page-based results, so if the engine requires that we send the "page index"
+// parameter, we'll always send "1".
+const OS_PARAM_COUNT = /\{count\??\}/g;
+const OS_PARAM_START_INDEX = /\{startIndex\??\}/g;
+const OS_PARAM_START_PAGE = /\{startPage\??\}/g;
+
+// Default values
+const OS_PARAM_COUNT_DEF = "20"; // 20 results
+const OS_PARAM_START_INDEX_DEF = "1"; // start at 1st result
+const OS_PARAM_START_PAGE_DEF = "1"; // 1st page
+
+// Optional parameter
+const OS_PARAM_OPTIONAL = /\{(?:\w+:)?\w+\?\}/g;
+
+// A array of arrays containing parameters that we don't fully support, and
+// their default values. We will only send values for these parameters if
+// required, since our values are just really arbitrary "guesses" that should
+// give us the output we want.
+var OS_UNSUPPORTED_PARAMS = [
+ [OS_PARAM_COUNT, OS_PARAM_COUNT_DEF],
+ [OS_PARAM_START_INDEX, OS_PARAM_START_INDEX_DEF],
+ [OS_PARAM_START_PAGE, OS_PARAM_START_PAGE_DEF],
+];
+
+// The default engine update interval, in days. This is only used if an engine
+// specifies an updateURL, but not an updateInterval.
+const SEARCH_DEFAULT_UPDATE_INTERVAL = 7;
+
+// Returns false for whitespace-only or commented out lines in a
+// Sherlock file, true otherwise.
+function isUsefulLine(aLine) {
+ return !(/^\s*($|#)/i.test(aLine));
+}
+
+__defineGetter__("gObsSvc", function() {
+ delete this.gObsSvc;
+ return this.gObsSvc = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+});
+
+__defineGetter__("gIoSvc", function() {
+ delete this.gIoSvc;
+ return this.gIoSvc = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+});
+
+__defineGetter__("gPrefSvc", function() {
+ delete this.gPrefSvc;
+ return this.gPrefSvc = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+});
+
+/**
+ * Prefixed to all search debug output.
+ */
+const SEARCH_LOG_PREFIX = "*** Search: ";
+
+/**
+ * Outputs aText to the JavaScript console as well as to stdout.
+ */
+function DO_LOG(aText) {
+ dump(SEARCH_LOG_PREFIX + aText + "\n");
+ var consoleService = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ consoleService.logStringMessage(aText);
+}
+
+//@line 251 "/builds/moz2_slave/linux_build/build/toolkit/components/search/nsSearchService.js"
+
+/**
+ * Otherwise, don't log at all by default. This can be overridden at startup
+ * by the pref, see SearchService's _init method.
+ */
+var LOG = function(){};
+
+//@line 259 "/builds/moz2_slave/linux_build/build/toolkit/components/search/nsSearchService.js"
+
+/**
+ * Presents an assertion dialog in non-release builds and throws.
+ * @param message
+ * A message to display
+ * @param resultCode
+ * The NS_ERROR_* value to throw.
+ * @throws resultCode
+ */
+function ERROR(message, resultCode) {
+ NS_ASSERT(false, SEARCH_LOG_PREFIX + message);
+ throw Components.Exception(message, resultCode);
+}
+
+/**
+ * Logs the failure message (if browser.search.log is enabled) and throws.
+ * @param message
+ * A message to display
+ * @param resultCode
+ * The NS_ERROR_* value to throw.
+ * @throws resultCode or NS_ERROR_INVALID_ARG if resultCode isn't specified.
+ */
+function FAIL(message, resultCode) {
+ LOG(message);
+ throw Components.Exception(message, resultCode || Cr.NS_ERROR_INVALID_ARG);
+}
+
+/**
+ * Ensures an assertion is met before continuing. Should be used to indicate
+ * fatal errors.
+ * @param assertion
+ * An assertion that must be met
+ * @param message
+ * A message to display if the assertion is not met
+ * @param resultCode
+ * The NS_ERROR_* value to throw if the assertion is not met
+ * @throws resultCode
+ */
+function ENSURE_WARN(assertion, message, resultCode) {
+ NS_ASSERT(assertion, SEARCH_LOG_PREFIX + message);
+ if (!assertion)
+ throw Components.Exception(message, resultCode);
+}
+
+function loadListener(aChannel, aEngine, aCallback) {
+ this._channel = aChannel;
+ this._bytes = [];
+ this._engine = aEngine;
+ this._callback = aCallback;
+}
+loadListener.prototype = {
+ _callback: null,
+ _channel: null,
+ _countRead: 0,
+ _engine: null,
+ _stream: null,
+
+ QueryInterface: function SRCH_loadQI(aIID) {
+ if (aIID.equals(Ci.nsISupports) ||
+ aIID.equals(Ci.nsIRequestObserver) ||
+ aIID.equals(Ci.nsIStreamListener) ||
+ aIID.equals(Ci.nsIChannelEventSink) ||
+ aIID.equals(Ci.nsIInterfaceRequestor) ||
+ aIID.equals(Ci.nsIBadCertListener2) ||
+ aIID.equals(Ci.nsISSLErrorListener) ||
+ // See FIXME comment below
+ aIID.equals(Ci.nsIHttpEventSink) ||
+ aIID.equals(Ci.nsIProgressEventSink) ||
+ false)
+ return this;
+
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ // nsIRequestObserver
+ onStartRequest: function SRCH_loadStartR(aRequest, aContext) {
+ LOG("loadListener: Starting request: " + aRequest.name);
+ this._stream = Cc["@mozilla.org/binaryinputstream;1"].
+ createInstance(Ci.nsIBinaryInputStream);
+ },
+
+ onStopRequest: function SRCH_loadStopR(aRequest, aContext, aStatusCode) {
+ LOG("loadListener: Stopping request: " + aRequest.name);
+
+ var requestFailed = !Components.isSuccessCode(aStatusCode);
+ if (!requestFailed && (aRequest instanceof Ci.nsIHttpChannel))
+ requestFailed = !aRequest.requestSucceeded;
+
+ if (requestFailed || this._countRead == 0) {
+ LOG("loadListener: request failed!");
+ // send null so the callback can deal with the failure
+ this._callback(null, this._engine);
+ } else
+ this._callback(this._bytes, this._engine);
+ this._channel = null;
+ this._engine = null;
+ },
+
+ // nsIStreamListener
+ onDataAvailable: function SRCH_loadDAvailable(aRequest, aContext,
+ aInputStream, aOffset,
+ aCount) {
+ this._stream.setInputStream(aInputStream);
+
+ // Get a byte array of the data
+ this._bytes = this._bytes.concat(this._stream.readByteArray(aCount));
+ this._countRead += aCount;
+ },
+
+ // nsIChannelEventSink
+ onChannelRedirect: function SRCH_loadCRedirect(aOldChannel, aNewChannel,
+ aFlags) {
+ this._channel = aNewChannel;
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function SRCH_load_GI(aIID) {
+ return this.QueryInterface(aIID);
+ },
+
+ // nsIBadCertListener2
+ notifyCertProblem: function SRCH_certProblem(socketInfo, status, targetSite) {
+ return true;
+ },
+
+ // nsISSLErrorListener
+ notifySSLError: function SRCH_SSLError(socketInfo, error, targetSite) {
+ return true;
+ },
+
+ // FIXME: bug 253127
+ // nsIHttpEventSink
+ onRedirect: function (aChannel, aNewChannel) {},
+ // nsIProgressEventSink
+ onProgress: function (aRequest, aContext, aProgress, aProgressMax) {},
+ onStatus: function (aRequest, aContext, aStatus, aStatusArg) {}
+}
+
+
+/**
+ * Used to verify a given DOM node's localName and namespaceURI.
+ * @param aElement
+ * The element to verify.
+ * @param aLocalNameArray
+ * An array of strings to compare against aElement's localName.
+ * @param aNameSpaceArray
+ * An array of strings to compare against aElement's namespaceURI.
+ *
+ * @returns false if aElement is null, or if its localName or namespaceURI
+ * does not match one of the elements in the aLocalNameArray or
+ * aNameSpaceArray arrays, respectively.
+ * @throws NS_ERROR_INVALID_ARG if aLocalNameArray or aNameSpaceArray are null.
+ */
+function checkNameSpace(aElement, aLocalNameArray, aNameSpaceArray) {
+ if (!aLocalNameArray || !aNameSpaceArray)
+ FAIL("missing aLocalNameArray or aNameSpaceArray for checkNameSpace");
+ return (aElement &&
+ (aLocalNameArray.indexOf(aElement.localName) != -1) &&
+ (aNameSpaceArray.indexOf(aElement.namespaceURI) != -1));
+}
+
+/**
+ * Safely close a nsISafeOutputStream.
+ * @param aFOS
+ * The file output stream to close.
+ */
+function closeSafeOutputStream(aFOS) {
+ if (aFOS instanceof Ci.nsISafeOutputStream) {
+ try {
+ aFOS.finish();
+ return;
+ } catch (e) { }
+ }
+ aFOS.close();
+}
+
+/**
+ * Wrapper function for nsIIOService::newURI.
+ * @param aURLSpec
+ * The URL string from which to create an nsIURI.
+ * @returns an nsIURI object, or null if the creation of the URI failed.
+ */
+function makeURI(aURLSpec, aCharset) {
+ try {
+ return gIoSvc.newURI(aURLSpec, aCharset, null);
+ } catch (ex) { }
+
+ return null;
+}
+
+/**
+ * Gets a directory from the directory service.
+ * @param aKey
+ * The directory service key indicating the directory to get.
+ */
+let _dirSvc = null;
+function getDir(aKey, aIFace) {
+ if (!aKey)
+ FAIL("getDir requires a directory key!");
+
+ if (!_dirSvc)
+ _dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ return _dirSvc.get(aKey, aIFace || Ci.nsIFile);
+}
+
+/**
+ * The following two functions are essentially copied from
+ * nsInternetSearchService. They are required for backwards compatibility.
+ */
+function queryCharsetFromCode(aCode) {
+ const codes = [];
+ codes[0] = "x-mac-roman";
+ codes[6] = "x-mac-greek";
+ codes[35] = "x-mac-turkish";
+ codes[513] = "ISO-8859-1";
+ codes[514] = "ISO-8859-2";
+ codes[517] = "ISO-8859-5";
+ codes[518] = "ISO-8859-6";
+ codes[519] = "ISO-8859-7";
+ codes[520] = "ISO-8859-8";
+ codes[521] = "ISO-8859-9";
+ codes[1049] = "IBM864";
+ codes[1280] = "windows-1252";
+ codes[1281] = "windows-1250";
+ codes[1282] = "windows-1251";
+ codes[1283] = "windows-1253";
+ codes[1284] = "windows-1254";
+ codes[1285] = "windows-1255";
+ codes[1286] = "windows-1256";
+ codes[1536] = "us-ascii";
+ codes[1584] = "GB2312";
+ codes[1585] = "x-gbk";
+ codes[1600] = "EUC-KR";
+ codes[2080] = "ISO-2022-JP";
+ codes[2096] = "ISO-2022-CN";
+ codes[2112] = "ISO-2022-KR";
+ codes[2336] = "EUC-JP";
+ codes[2352] = "GB2312";
+ codes[2353] = "x-euc-tw";
+ codes[2368] = "EUC-KR";
+ codes[2561] = "Shift_JIS";
+ codes[2562] = "KOI8-R";
+ codes[2563] = "Big5";
+ codes[2565] = "HZ-GB-2312";
+
+ if (codes[aCode])
+ return codes[aCode];
+
+ return getLocalizedPref("intl.charset.default", DEFAULT_QUERY_CHARSET);
+}
+function fileCharsetFromCode(aCode) {
+ const codes = [
+ "x-mac-roman", // 0
+ "Shift_JIS", // 1
+ "Big5", // 2
+ "EUC-KR", // 3
+ "X-MAC-ARABIC", // 4
+ "X-MAC-HEBREW", // 5
+ "X-MAC-GREEK", // 6
+ "X-MAC-CYRILLIC", // 7
+ "X-MAC-DEVANAGARI" , // 9
+ "X-MAC-GURMUKHI", // 10
+ "X-MAC-GUJARATI", // 11
+ "X-MAC-ORIYA", // 12
+ "X-MAC-BENGALI", // 13
+ "X-MAC-TAMIL", // 14
+ "X-MAC-TELUGU", // 15
+ "X-MAC-KANNADA", // 16
+ "X-MAC-MALAYALAM", // 17
+ "X-MAC-SINHALESE", // 18
+ "X-MAC-BURMESE", // 19
+ "X-MAC-KHMER", // 20
+ "X-MAC-THAI", // 21
+ "X-MAC-LAOTIAN", // 22
+ "X-MAC-GEORGIAN", // 23
+ "X-MAC-ARMENIAN", // 24
+ "GB2312", // 25
+ "X-MAC-TIBETAN", // 26
+ "X-MAC-MONGOLIAN", // 27
+ "X-MAC-ETHIOPIC", // 28
+ "X-MAC-CENTRALEURROMAN", // 29
+ "X-MAC-VIETNAMESE", // 30
+ "X-MAC-EXTARABIC" // 31
+ ];
+ // Sherlock files have always defaulted to x-mac-roman, so do that here too
+ return codes[aCode] || codes[0];
+}
+
+/**
+ * Returns a string interpretation of aBytes using aCharset, or null on
+ * failure.
+ */
+function bytesToString(aBytes, aCharset) {
+ var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
+ createInstance(Ci.nsIScriptableUnicodeConverter);
+ LOG("bytesToString: converting using charset: " + aCharset);
+
+ try {
+ converter.charset = aCharset;
+ return converter.convertFromByteArray(aBytes, aBytes.length);
+ } catch (ex) {}
+
+ return null;
+}
+
+/**
+ * Converts an array of bytes representing a Sherlock file into an array of
+ * lines representing the useful data from the file.
+ *
+ * @param aBytes
+ * The array of bytes representing the Sherlock file.
+ * @param aCharsetCode
+ * An integer value representing a character set code to be passed to
+ * fileCharsetFromCode, or null for the default Sherlock encoding.
+ */
+function sherlockBytesToLines(aBytes, aCharsetCode) {
+ // fileCharsetFromCode returns the default encoding if aCharsetCode is null
+ var charset = fileCharsetFromCode(aCharsetCode);
+
+ var dataString = bytesToString(aBytes, charset);
+ if (!dataString)
+ FAIL("sherlockBytesToLines: Couldn't convert byte array!", Cr.NS_ERROR_FAILURE);
+
+ // Split the string into lines, and filter out comments and
+ // whitespace-only lines
+ return dataString.split(NEW_LINES).filter(isUsefulLine);
+}
+
+/**
+ * Gets the current value of the locale. It's possible for this preference to
+ * be localized, so we have to do a little extra work here. Similar code
+ * exists in nsHttpHandler.cpp when building the UA string.
+ */
+function getLocale() {
+ const localePref = "general.useragent.locale";
+ var locale = getLocalizedPref(localePref);
+ if (locale)
+ return locale;
+
+ // Not localized
+ return gPrefSvc.getCharPref(localePref);
+}
+
+/**
+ * Wrapper for nsIPrefBranch::getComplexValue.
+ * @param aPrefName
+ * The name of the pref to get.
+ * @returns aDefault if the requested pref doesn't exist.
+ */
+function getLocalizedPref(aPrefName, aDefault) {
+ const nsIPLS = Ci.nsIPrefLocalizedString;
+ try {
+ return gPrefSvc.getComplexValue(aPrefName, nsIPLS).data;
+ } catch (ex) {}
+
+ return aDefault;
+}
+
+/**
+ * Wrapper for nsIPrefBranch::setComplexValue.
+ * @param aPrefName
+ * The name of the pref to set.
+ */
+function setLocalizedPref(aPrefName, aValue) {
+ const nsIPLS = Ci.nsIPrefLocalizedString;
+ try {
+ var pls = Components.classes["@mozilla.org/pref-localizedstring;1"]
+ .createInstance(Ci.nsIPrefLocalizedString);
+ pls.data = aValue;
+ gPrefSvc.setComplexValue(aPrefName, nsIPLS, pls);
+ } catch (ex) {}
+}
+
+/**
+ * Wrapper for nsIPrefBranch::getBoolPref.
+ * @param aPrefName
+ * The name of the pref to get.
+ * @returns aDefault if the requested pref doesn't exist.
+ */
+function getBoolPref(aName, aDefault) {
+ try {
+ return gPrefSvc.getBoolPref(aName);
+ } catch (ex) {
+ return aDefault;
+ }
+}
+
+/**
+ * Get a unique nsIFile object with a sanitized name, based on the engine name.
+ * @param aName
+ * A name to "sanitize". Can be an empty string, in which case a random
+ * 8 character filename will be produced.
+ * @returns A nsIFile object in the user's search engines directory with a
+ * unique sanitized name.
+ */
+function getSanitizedFile(aName) {
+ var fileName = sanitizeName(aName) + "." + XML_FILE_EXT;
+ var file = getDir(NS_APP_USER_SEARCH_DIR);
+ file.append(fileName);
+ file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ return file;
+}
+
+/**
+ * Removes all characters not in the "chars" string from aName.
+ *
+ * @returns a sanitized name to be used as a filename, or a random name
+ * if a sanitized name cannot be obtained (if aName contains
+ * no valid characters).
+ */
+function sanitizeName(aName) {
+ const chars = "-abcdefghijklmnopqrstuvwxyz0123456789";
+ const maxLength = 60;
+
+ var name = aName.toLowerCase();
+ name = name.replace(/ /g, "-");
+ name = name.split("").filter(function (el) {
+ return chars.indexOf(el) != -1;
+ }).join("");
+
+ if (!name) {
+ // Our input had no valid characters - use a random name
+ var cl = chars.length - 1;
+ for (var i = 0; i < 8; ++i)
+ name += chars.charAt(Math.round(Math.random() * cl));
+ }
+
+ if (name.length > maxLength)
+ name = name.substring(0, maxLength);
+
+ return name;
+}
+
+/**
+ * Retrieve a pref from the search param branch.
+ *
+ * @param prefName
+ * The name of the pref.
+ **/
+function getMozParamPref(prefName)
+ gPrefSvc.getCharPref(BROWSER_SEARCH_PREF + "param." + prefName);
+
+/**
+ * Notifies watchers of SEARCH_ENGINE_TOPIC about changes to an engine or to
+ * the state of the search service.
+ *
+ * @param aEngine
+ * The nsISearchEngine object to which the change applies.
+ * @param aVerb
+ * A verb describing the change.
+ *
+ * @see nsIBrowserSearchService.idl
+ */
+function notifyAction(aEngine, aVerb) {
+ LOG("NOTIFY: Engine: \"" + aEngine.name + "\"; Verb: \"" + aVerb + "\"");
+ gObsSvc.notifyObservers(aEngine, SEARCH_ENGINE_TOPIC, aVerb);
+}
+
+/**
+ * Simple object representing a name/value pair.
+ */
+function QueryParameter(aName, aValue) {
+ if (!aName || (aValue == null))
+ FAIL("missing name or value for QueryParameter!");
+
+ this.name = aName;
+ this.value = aValue;
+}
+
+/**
+ * Perform OpenSearch parameter substitution on aParamValue.
+ *
+ * @param aParamValue
+ * A string containing OpenSearch search parameters.
+ * @param aSearchTerms
+ * The user-provided search terms. This string will inserted into
+ * aParamValue as the value of the OS_PARAM_USER_DEFINED parameter.
+ * This value must already be escaped appropriately - it is inserted
+ * as-is.
+ * @param aQueryEncoding
+ * The value to use for the OS_PARAM_INPUT_ENCODING parameter. See
+ * definition in the OpenSearch spec.
+ *
+ * @see http://opensearch.a9.com/spec/1.1/querysyntax/#core
+ */
+function ParamSubstitution(aParamValue, aSearchTerms, aEngine) {
+ var value = aParamValue;
+
+ var distributionID = MOZ_DISTRIBUTION_ID;
+ try {
+ distributionID = gPrefSvc.getCharPref(BROWSER_SEARCH_PREF + "distributionID");
+ }
+ catch (ex) { }
+
+ // Custom search parameters. These are only available to default search
+ // engines.
+ if (aEngine._isDefault) {
+ value = value.replace(MOZ_PARAM_LOCALE, getLocale());
+ value = value.replace(MOZ_PARAM_DIST_ID, distributionID);
+ value = value.replace(MOZ_PARAM_OFFICIAL, MOZ_OFFICIAL);
+ }
+
+ // Insert the OpenSearch parameters we're confident about
+ value = value.replace(OS_PARAM_USER_DEFINED, aSearchTerms);
+ value = value.replace(OS_PARAM_INPUT_ENCODING, aEngine.queryCharset);
+ value = value.replace(OS_PARAM_LANGUAGE,
+ getLocale() || OS_PARAM_LANGUAGE_DEF);
+ value = value.replace(OS_PARAM_OUTPUT_ENCODING,
+ OS_PARAM_OUTPUT_ENCODING_DEF);
+
+ // Replace any optional parameters
+ value = value.replace(OS_PARAM_OPTIONAL, "");
+
+ // Insert any remaining required params with our default values
+ for (var i = 0; i < OS_UNSUPPORTED_PARAMS.length; ++i) {
+ value = value.replace(OS_UNSUPPORTED_PARAMS[i][0],
+ OS_UNSUPPORTED_PARAMS[i][1]);
+ }
+
+ return value;
+}
+
+/**
+ * Creates a mozStorage statement that can be used to access the database we
+ * use to hold metadata.
+ *
+ * @param dbconn the database that the statement applies to
+ * @param sql a string specifying the sql statement that should be created
+ */
+function createStatement (dbconn, sql) {
+ var stmt = dbconn.createStatement(sql);
+ var wrapper = Cc["@mozilla.org/storage/statement-wrapper;1"].
+ createInstance(Ci.mozIStorageStatementWrapper);
+
+ wrapper.initialize(stmt);
+ return wrapper;
+}
+
+/**
+ * Creates an engineURL object, which holds the query URL and all parameters.
+ *
+ * @param aType
+ * A string containing the name of the MIME type of the search results
+ * returned by this URL.
+ * @param aMethod
+ * The HTTP request method. Must be a case insensitive value of either
+ * "GET" or "POST".
+ * @param aTemplate
+ * The URL to which search queries should be sent. For GET requests,
+ * must contain the string "{searchTerms}", to indicate where the user
+ * entered search terms should be inserted.
+ *
+ * @see http://opensearch.a9.com/spec/1.1/querysyntax/#urltag
+ *
+ * @throws NS_ERROR_NOT_IMPLEMENTED if aType is unsupported.
+ */
+function EngineURL(aType, aMethod, aTemplate) {
+ if (!aType || !aMethod || !aTemplate)
+ FAIL("missing type, method or template for EngineURL!");
+
+ var method = aMethod.toUpperCase();
+ var type = aType.toLowerCase();
+
+ if (method != "GET" && method != "POST")
+ FAIL("method passed to EngineURL must be \"GET\" or \"POST\"");
+
+ this.type = type;
+ this.method = method;
+ this.params = [];
+ this.rels = [];
+ // Don't serialize expanded mozparams
+ this.mozparams = {};
+
+ var templateURI = makeURI(aTemplate);
+ if (!templateURI)
+ FAIL("new EngineURL: template is not a valid URI!", Cr.NS_ERROR_FAILURE);
+
+ switch (templateURI.scheme) {
+ case "http":
+ case "https":
+ // Disable these for now, see bug 295018
+ // case "file":
+ // case "resource":
+ this.template = aTemplate;
+ break;
+ default:
+ FAIL("new EngineURL: template uses invalid scheme!", Cr.NS_ERROR_FAILURE);
+ }
+}
+EngineURL.prototype = {
+
+ addParam: function SRCH_EURL_addParam(aName, aValue) {
+ this.params.push(new QueryParameter(aName, aValue));
+ },
+
+ _addMozParam: function SRCH_EURL__addMozParam(aObj) {
+ aObj.mozparam = true;
+ this.mozparams[aObj.name] = aObj;
+ },
+
+ getSubmission: function SRCH_EURL_getSubmission(aSearchTerms, aEngine) {
+ var url = ParamSubstitution(this.template, aSearchTerms, aEngine);
+
+ // Create an application/x-www-form-urlencoded representation of our params
+ // (name=value&name=value&name=value)
+ var dataString = "";
+ for (var i = 0; i < this.params.length; ++i) {
+ var param = this.params[i];
+ var value = ParamSubstitution(param.value, aSearchTerms, aEngine);
+
+ dataString += (i > 0 ? "&" : "") + param.name + "=" + value;
+ }
+
+ var postData = null;
+ if (this.method == "GET") {
+ // GET method requests have no post data, and append the encoded
+ // query string to the url...
+ if (url.indexOf("?") == -1 && dataString)
+ url += "?";
+ url += dataString;
+ } else if (this.method == "POST") {
+ // POST method requests must wrap the encoded text in a MIME
+ // stream and supply that as POSTDATA.
+ var stringStream = Cc["@mozilla.org/io/string-input-stream;1"].
+ createInstance(Ci.nsIStringInputStream);
+ stringStream.data = dataString;
+
+ postData = Cc["@mozilla.org/network/mime-input-stream;1"].
+ createInstance(Ci.nsIMIMEInputStream);
+ postData.addHeader("Content-Type", "application/x-www-form-urlencoded");
+ postData.addContentLength = true;
+ postData.setData(stringStream);
+ }
+
+ return new Submission(makeURI(url), postData);
+ },
+
+ _hasRelation: function SRC_EURL__hasRelation(aRel)
+ this.rels.some(function(e) e == aRel.toLowerCase()),
+
+ _initWithJSON: function SRC_EURL__initWithJSON(aJson, aEngine) {
+ if (!aJson.params)
+ return;
+
+ this.rels = aJson.rels;
+
+ for (let i = 0; i < aJson.params.length; ++i) {
+ let param = aJson.params[i];
+ if (param.mozparam) {
+ if (param.condition == "defaultEngine") {
+ if (aEngine._isDefaultEngine())
+ this.addParam(param.name, param.trueValue);
+ else
+ this.addParam(param.name, param.falseValue);
+ } else if (param.condition == "pref") {
+ let value = getMozParamPref(param.pref);
+ this.addParam(param.name, value);
+ }
+ this._addMozParam(param);
+ }
+ else
+ this.addParam(param.name, param.value);
+ }
+ },
+
+ /**
+ * Creates a JavaScript object that represents this URL.
+ * @returns An object suitable for serialization as JSON.
+ **/
+ _serializeToJSON: function SRCH_EURL__serializeToJSON() {
+ var json = {
+ template: this.template,
+ rels: this.rels
+ };
+
+ if (this.type != URLTYPE_SEARCH_HTML)
+ json.type = this.type;
+ if (this.method != "GET")
+ json.method = this.method;
+
+ function collapseMozParams(aParam)
+ this.mozparams[aParam.name] || aParam;
+ json.params = this.params.map(collapseMozParams, this);
+
+ return json;
+ },
+
+ /**
+ * Serializes the engine object to a OpenSearch Url element.
+ * @param aDoc
+ * The document to use to create the Url element.
+ * @param aElement
+ * The element to which the created Url element is appended.
+ *
+ * @see http://opensearch.a9.com/spec/1.1/querysyntax/#urltag
+ */
+ _serializeToElement: function SRCH_EURL_serializeToEl(aDoc, aElement) {
+ var url = aDoc.createElementNS(OPENSEARCH_NS_11, "Url");
+ url.setAttribute("type", this.type);
+ url.setAttribute("method", this.method);
+ url.setAttribute("template", this.template);
+ if (this.rels.length)
+ url.setAttribute("rel", this.rels.join(" "));
+
+ for (var i = 0; i < this.params.length; ++i) {
+ var param = aDoc.createElementNS(OPENSEARCH_NS_11, "Param");
+ param.setAttribute("name", this.params[i].name);
+ param.setAttribute("value", this.params[i].value);
+ url.appendChild(aDoc.createTextNode("\n "));
+ url.appendChild(param);
+ }
+ url.appendChild(aDoc.createTextNode("\n"));
+ aElement.appendChild(url);
+ }
+};
+
+/**
+ * nsISearchEngine constructor.
+ * @param aLocation
+ * A nsILocalFile or nsIURI object representing the location of the
+ * search engine data file.
+ * @param aSourceDataType
+ * The data type of the file used to describe the engine. Must be either
+ * DATA_XML or DATA_TEXT.
+ * @param aIsReadOnly
+ * Boolean indicating whether the engine should be treated as read-only.
+ * Read only engines cannot be serialized to file.
+ */
+function Engine(aLocation, aSourceDataType, aIsReadOnly) {
+ this._dataType = aSourceDataType;
+ this._readOnly = aIsReadOnly;
+ this._urls = [];
+
+ if (aLocation.cached) {
+ this._file = aLocation.value;
+ } else if (aLocation instanceof Ci.nsILocalFile) {
+ // we already have a file (e.g. loading engines from disk)
+ this._file = aLocation;
+ } else if (aLocation instanceof Ci.nsIURI) {
+ this._uri = aLocation;
+ switch (aLocation.scheme) {
+ case "https":
+ case "http":
+ case "ftp":
+ case "data":
+ case "file":
+ case "resource":
+ this._uri = aLocation;
+ break;
+ default:
+ ERROR("Invalid URI passed to the nsISearchEngine constructor",
+ Cr.NS_ERROR_INVALID_ARG);
+ }
+ } else
+ ERROR("Engine location is neither a File nor a URI object",
+ Cr.NS_ERROR_INVALID_ARG);
+}
+
+Engine.prototype = {
+ // The engine's alias.
+ _alias: null,
+ // The data describing the engine. Is either an array of bytes, for Sherlock
+ // files, or an XML document element, for XML plugins.
+ _data: null,
+ // The engine's data type. See data types (DATA_) defined above.
+ _dataType: null,
+ // Whether or not the engine is readonly.
+ _readOnly: true,
+ // The engine's description
+ _description: "",
+ // Used to store the engine to replace, if we're an update to an existing
+ // engine.
+ _engineToUpdate: null,
+ // The file from which the plugin was loaded.
+ __file: null,
+ get _file() {
+ if (this.__file && !(this.__file instanceof Ci.nsILocalFile)) {
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.persistentDescriptor = this.__file;
+ return this.__file = file;
+ }
+ return this.__file;
+ },
+ set _file(aValue) {
+ this.__file = aValue;
+ },
+ // Set to true if the engine has a preferred icon (an icon that should not be
+ // overridden by a non-preferred icon).
+ _hasPreferredIcon: null,
+ // Whether the engine is hidden from the user.
+ _hidden: null,
+ // The engine's name.
+ _name: null,
+ // The engine type. See engine types (TYPE_) defined above.
+ _type: null,
+ // The name of the charset used to submit the search terms.
+ _queryCharset: null,
+ // A URL string pointing to the engine's search form.
+ __searchForm: null,
+ get _searchForm() {
+ return this.__searchForm;
+ },
+ set _searchForm(aValue) {
+ if (/^https?:/i.test(aValue))
+ this.__searchForm = aValue;
+ else
+ LOG("_searchForm: Invalid URL dropped for " + this._name ||
+ "the current engine");
+ },
+ // The URI object from which the engine was retrieved.
+ // This is null for local plugins, and is used for error messages and logging.
+ _uri: null,
+ // Whether to obtain user confirmation before adding the engine. This is only
+ // used when the engine is first added to the list.
+ _confirm: false,
+ // Whether to set this as the current engine as soon as it is loaded. This
+ // is only used when the engine is first added to the list.
+ _useNow: true,
+ // Where the engine was loaded from. Can be one of: SEARCH_APP_DIR,
+ // SEARCH_PROFILE_DIR, SEARCH_IN_EXTENSION.
+ __installLocation: null,
+ // The number of days between update checks for new versions
+ _updateInterval: null,
+ // The url to check at for a new update
+ _updateURL: null,
+ // The url to check for a new icon
+ _iconUpdateURL: null,
+ // A reference to the timer used for lazily serializing the engine to file
+ _serializeTimer: null,
+ // Whether this engine has been used since the cache was last recreated.
+ __used: null,
+ get _used() {
+ if (!this.__used)
+ this.__used = !!engineMetadataService.getAttr(this, "used");
+ return this.__used;
+ },
+ set _used(aValue) {
+ this.__used = aValue
+ engineMetadataService.setAttr(this, "used", aValue);
+ },
+
+ /**
+ * Retrieves the data from the engine's file. If the engine's dataType is
+ * XML, the document element is placed in the engine's data field. For text
+ * engines, the data is just read directly from file and placed as an array
+ * of lines in the engine's data field.
+ */
+ _initFromFile: function SRCH_ENG_initFromFile() {
+ if (!this._file || !this._file.exists())
+ FAIL("File must exist before calling initFromFile!", Cr.NS_ERROR_UNEXPECTED);
+
+ var fileInStream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+
+ fileInStream.init(this._file, MODE_RDONLY, PERMS_FILE, false);
+
+ switch (this._dataType) {
+ case SEARCH_DATA_XML:
+ var domParser = Cc["@mozilla.org/xmlextras/domparser;1"].
+ createInstance(Ci.nsIDOMParser);
+ var doc = domParser.parseFromStream(fileInStream, "UTF-8",
+ this._file.fileSize,
+ "text/xml");
+
+ this._data = doc.documentElement;
+ break;
+ case SEARCH_DATA_TEXT:
+ var binaryInStream = Cc["@mozilla.org/binaryinputstream;1"].
+ createInstance(Ci.nsIBinaryInputStream);
+ binaryInStream.setInputStream(fileInStream);
+
+ var bytes = binaryInStream.readByteArray(binaryInStream.available());
+ this._data = bytes;
+
+ break;
+ default:
+ ERROR("Bogus engine _dataType: \"" + this._dataType + "\"",
+ Cr.NS_ERROR_UNEXPECTED);
+ }
+ fileInStream.close();
+
+ // Now that the data is loaded, initialize the engine object
+ this._initFromData();
+ },
+
+ /**
+ * Retrieves the engine data from a URI.
+ */
+ _initFromURI: function SRCH_ENG_initFromURI() {
+ ENSURE_WARN(this._uri instanceof Ci.nsIURI,
+ "Must have URI when calling _initFromURI!",
+ Cr.NS_ERROR_UNEXPECTED);
+
+ LOG("_initFromURI: Downloading engine from: \"" + this._uri.spec + "\".");
+
+ var chan = gIoSvc.newChannelFromURI(this._uri);
+
+ if (this._engineToUpdate && (chan instanceof Ci.nsIHttpChannel)) {
+ var lastModified = engineMetadataService.getAttr(this._engineToUpdate,
+ "updatelastmodified");
+ if (lastModified)
+ chan.setRequestHeader("If-Modified-Since", lastModified, false);
+ }
+ var listener = new loadListener(chan, this, this._onLoad);
+ chan.notificationCallbacks = listener;
+ chan.asyncOpen(listener, null);
+ },
+
+ /**
+ * Attempts to find an EngineURL object in the set of EngineURLs for
+ * this Engine that has the given type string. (This corresponds to the
+ * "type" attribute in the "Url" node in the OpenSearch spec.)
+ * This method will return the first matching URL object found, or null
+ * if no matching URL is found.
+ *
+ * @param aType string to match the EngineURL's type attribute
+ */
+ _getURLOfType: function SRCH_ENG__getURLOfType(aType) {
+ for (var i = 0; i < this._urls.length; ++i) {
+ if (this._urls[i].type == aType)
+ return this._urls[i];
+ }
+
+ return null;
+ },
+
+ _confirmAddEngine: function SRCH_SVC_confirmAddEngine() {
+ var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ var stringBundle = sbs.createBundle(SEARCH_BUNDLE);
+ var titleMessage = stringBundle.GetStringFromName("addEngineConfirmTitle");
+
+ // Display only the hostname portion of the URL.
+ var dialogMessage =
+ stringBundle.formatStringFromName("addEngineConfirmation",
+ [this._name, this._uri.host], 2);
+ var checkboxMessage = stringBundle.GetStringFromName("addEngineUseNowText");
+ var addButtonLabel =
+ stringBundle.GetStringFromName("addEngineAddButtonLabel");
+
+ var ps = Cc["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Ci.nsIPromptService);
+ var buttonFlags = (ps.BUTTON_TITLE_IS_STRING * ps.BUTTON_POS_0) +
+ (ps.BUTTON_TITLE_CANCEL * ps.BUTTON_POS_1) +
+ ps.BUTTON_POS_0_DEFAULT;
+
+ var checked = {value: false};
+ // confirmEx returns the index of the button that was pressed. Since "Add"
+ // is button 0, we want to return the negation of that value.
+ var confirm = !ps.confirmEx(null,
+ titleMessage,
+ dialogMessage,
+ buttonFlags,
+ addButtonLabel,
+ null, null, // button 1 & 2 names not used
+ checkboxMessage,
+ checked);
+
+ return {confirmed: confirm, useNow: checked.value};
+ },
+
+ /**
+ * Handle the successful download of an engine. Initializes the engine and
+ * triggers parsing of the data. The engine is then flushed to disk. Notifies
+ * the search service once initialization is complete.
+ */
+ _onLoad: function SRCH_ENG_onLoad(aBytes, aEngine) {
+ /**
+ * Handle an error during the load of an engine by prompting the user to
+ * notify him that the load failed.
+ */
+ function onError(aErrorString, aTitleString) {
+ if (aEngine._engineToUpdate) {
+ // We're in an update, so just fail quietly
+ LOG("updating " + aEngine._engineToUpdate.name + " failed");
+ return;
+ }
+ var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+
+ var brandBundle = sbs.createBundle(BRAND_BUNDLE);
+ var brandName = brandBundle.GetStringFromName("brandShortName");
+
+ var searchBundle = sbs.createBundle(SEARCH_BUNDLE);
+ var msgStringName = aErrorString || "error_loading_engine_msg2";
+ var titleStringName = aTitleString || "error_loading_engine_title";
+ var title = searchBundle.GetStringFromName(titleStringName);
+ var text = searchBundle.formatStringFromName(msgStringName,
+ [brandName, aEngine._location],
+ 2);
+
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.getNewPrompter(null).alert(title, text);
+ }
+
+ if (!aBytes) {
+ onError();
+ return;
+ }
+
+ var engineToUpdate = null;
+ if (aEngine._engineToUpdate) {
+ engineToUpdate = aEngine._engineToUpdate.wrappedJSObject;
+
+ // Make this new engine use the old engine's file.
+ aEngine._file = engineToUpdate._file;
+ }
+
+ switch (aEngine._dataType) {
+ case SEARCH_DATA_XML:
+ var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
+ createInstance(Ci.nsIDOMParser);
+ var doc = parser.parseFromBuffer(aBytes, aBytes.length, "text/xml");
+ aEngine._data = doc.documentElement;
+ break;
+ case SEARCH_DATA_TEXT:
+ aEngine._data = aBytes;
+ break;
+ default:
+ onError();
+ LOG("_onLoad: Bogus engine _dataType: \"" + this._dataType + "\"");
+ return;
+ }
+
+ try {
+ // Initialize the engine from the obtained data
+ aEngine._initFromData();
+ } catch (ex) {
+ LOG("_onLoad: Failed to init engine!\n" + ex);
+ // Report an error to the user
+ onError();
+ return;
+ }
+
+ // Check to see if this is a duplicate engine. If we're confirming the
+ // engine load, then we display a "this is a duplicate engine" prompt,
+ // otherwise we fail silently.
+ if (!engineToUpdate) {
+ var ss = Cc["@mozilla.org/browser/search-service;1"].
+ getService(Ci.nsIBrowserSearchService);
+ if (ss.getEngineByName(aEngine.name)) {
+ if (aEngine._confirm)
+ onError("error_duplicate_engine_msg", "error_invalid_engine_title");
+
+ LOG("_onLoad: duplicate engine found, bailing");
+ return;
+ }
+ }
+
+ // If requested, confirm the addition now that we have the title.
+ // This property is only ever true for engines added via
+ // nsIBrowserSearchService::addEngine.
+ if (aEngine._confirm) {
+ var confirmation = aEngine._confirmAddEngine();
+ LOG("_onLoad: confirm is " + confirmation.confirmed +
+ "; useNow is " + confirmation.useNow);
+ if (!confirmation.confirmed)
+ return;
+ aEngine._useNow = confirmation.useNow;
+ }
+
+ // If we don't yet have a file, get one now. The only case where we would
+ // already have a file is if this is an update and _file was set above.
+ if (!aEngine._file)
+ aEngine._file = getSanitizedFile(aEngine.name);
+
+ if (engineToUpdate) {
+ // Keep track of the last modified date, so that we can make conditional
+ // requests for future updates.
+ engineMetadataService.setAttr(aEngine, "updatelastmodified",
+ (new Date()).toUTCString());
+
+ // If we're updating an app-shipped engine, ensure that the updateURLs
+ // are the same.
+ if (engineToUpdate._isInAppDir) {
+ let oldUpdateURL = engineToUpdate._updateURL;
+ let newUpdateURL = aEngine._updateURL;
+ let oldSelfURL = engineToUpdate._getURLOfType(URLTYPE_OPENSEARCH);
+ if (oldSelfURL && oldSelfURL._hasRelation("self")) {
+ oldUpdateURL = oldSelfURL.template;
+ let newSelfURL = aEngine._getURLOfType(URLTYPE_OPENSEARCH);
+ if (!newSelfURL || !newSelfURL._hasRelation("self")) {
+ LOG("_onLoad: updateURL missing in updated engine for " +
+ aEngine.name + " aborted");
+ return;
+ }
+ newUpdateURL = newSelfURL.template;
+ }
+
+ if (oldUpdateURL != newUpdateURL) {
+ LOG("_onLoad: updateURLs do not match! Update of " + aEngine.name + " aborted");
+ return;
+ }
+ }
+
+ // Set the new engine's icon, if it doesn't yet have one.
+ if (!aEngine._iconURI && engineToUpdate._iconURI)
+ aEngine._iconURI = engineToUpdate._iconURI;
+
+ // Clear the "use now" flag since we don't want to be changing the
+ // current engine for an update.
+ aEngine._useNow = false;
+ }
+
+ // Write the engine to file. For readOnly engines, they'll be stored in the
+ // cache following the notification below.
+ if (!aEngine._readOnly)
+ aEngine._serializeToFile();
+
+ // Notify the search service of the successful load. It will deal with
+ // updates by checking aEngine._engineToUpdate.
+ notifyAction(aEngine, SEARCH_ENGINE_LOADED);
+ },
+
+ /**
+ * Sets the .iconURI property of the engine.
+ *
+ * @param aIconURL
+ * A URI string pointing to the engine's icon. Must have a http[s],
+ * ftp, or data scheme. Icons with HTTP[S] or FTP schemes will be
+ * downloaded and converted to data URIs for storage in the engine
+ * XML files, if the engine is not readonly.
+ * @param aIsPreferred
+ * Whether or not this icon is to be preferred. Preferred icons can
+ * override non-preferred icons.
+ */
+ _setIcon: function SRCH_ENG_setIcon(aIconURL, aIsPreferred) {
+ // If we already have a preferred icon, and this isn't a preferred icon,
+ // just ignore it.
+ if (this._hasPreferredIcon && !aIsPreferred)
+ return;
+
+ var uri = makeURI(aIconURL);
+
+ // Ignore bad URIs
+ if (!uri)
+ return;
+
+ LOG("_setIcon: Setting icon url \"" + uri.spec + "\" for engine \""
+ + this.name + "\".");
+ // Only accept remote icons from http[s] or ftp
+ switch (uri.scheme) {
+ case "data":
+ this._iconURI = uri;
+ notifyAction(this, SEARCH_ENGINE_CHANGED);
+ this._hasPreferredIcon = aIsPreferred;
+ break;
+ case "http":
+ case "https":
+ case "ftp":
+ // No use downloading the icon if the engine file is read-only
+ if (!this._readOnly) {
+ LOG("_setIcon: Downloading icon: \"" + uri.spec +
+ "\" for engine: \"" + this.name + "\"");
+ var chan = gIoSvc.newChannelFromURI(uri);
+
+ function iconLoadCallback(aByteArray, aEngine) {
+ // This callback may run after we've already set a preferred icon,
+ // so check again.
+ if (aEngine._hasPreferredIcon && !aIsPreferred)
+ return;
+
+ if (!aByteArray || aByteArray.length > MAX_ICON_SIZE) {
+ LOG("iconLoadCallback: load failed, or the icon was too large!");
+ return;
+ }
+
+ var str = btoa(String.fromCharCode.apply(null, aByteArray));
+ aEngine._iconURI = makeURI(ICON_DATAURL_PREFIX + str);
+
+ // The engine might not have a file yet, if it's being downloaded,
+ // because the request for the engine file itself (_onLoad) may not
+ // yet be complete. In that case, this change will be written to
+ // file when _onLoad is called. For readonly engines, we'll store
+ // the changes in the cache once notified below.
+ if (aEngine._file && !aEngine._readOnly)
+ aEngine._serializeToFile();
+
+ notifyAction(aEngine, SEARCH_ENGINE_CHANGED);
+ aEngine._hasPreferredIcon = aIsPreferred;
+ }
+
+ // If we're currently acting as an "update engine", then the callback
+ // should set the icon on the engine we're updating and not us, since
+ // |this| might be gone by the time the callback runs.
+ var engineToSet = this._engineToUpdate || this;
+
+ var listener = new loadListener(chan, engineToSet, iconLoadCallback);
+ chan.notificationCallbacks = listener;
+ chan.asyncOpen(listener, null);
+ }
+ break;
+ }
+ },
+
+ /**
+ * Initialize this Engine object from the collected data.
+ */
+ _initFromData: function SRCH_ENG_initFromData() {
+
+ ENSURE_WARN(this._data, "Can't init an engine with no data!",
+ Cr.NS_ERROR_UNEXPECTED);
+
+ // Find out what type of engine we are
+ switch (this._dataType) {
+ case SEARCH_DATA_XML:
+ if (checkNameSpace(this._data, [MOZSEARCH_LOCALNAME],
+ [MOZSEARCH_NS_10])) {
+
+ LOG("_init: Initing MozSearch plugin from " + this._location);
+
+ this._type = SEARCH_TYPE_MOZSEARCH;
+ this._parseAsMozSearch();
+
+ } else if (checkNameSpace(this._data, [OPENSEARCH_LOCALNAME],
+ OPENSEARCH_NAMESPACES)) {
+
+ LOG("_init: Initing OpenSearch plugin from " + this._location);
+
+ this._type = SEARCH_TYPE_OPENSEARCH;
+ this._parseAsOpenSearch();
+
+ } else
+ FAIL(this._location + " is not a valid search plugin.", Cr.NS_ERROR_FAILURE);
+
+ break;
+ case SEARCH_DATA_TEXT:
+ LOG("_init: Initing Sherlock plugin from " + this._location);
+
+ // the only text-based format we support is Sherlock
+ this._type = SEARCH_TYPE_SHERLOCK;
+ this._parseAsSherlock();
+ }
+
+ // No need to keep a ref to our data (which in some cases can be a document
+ // element) past this point
+ this._data = null;
+ },
+
+ /**
+ * Initialize this Engine object from a collection of metadata.
+ */
+ _initFromMetadata: function SRCH_ENG_initMetaData(aName, aIconURL, aAlias,
+ aDescription, aMethod,
+ aTemplate) {
+ ENSURE_WARN(!this._readOnly,
+ "Can't call _initFromMetaData on a readonly engine!",
+ Cr.NS_ERROR_FAILURE);
+
+ this._urls.push(new EngineURL("text/html", aMethod, aTemplate));
+
+ this._name = aName;
+ this.alias = aAlias;
+ this._description = aDescription;
+ this._setIcon(aIconURL, true);
+
+ this._serializeToFile();
+ },
+
+ /**
+ * Extracts data from an OpenSearch URL element and creates an EngineURL
+ * object which is then added to the engine's list of URLs.
+ *
+ * @throws NS_ERROR_FAILURE if a URL object could not be created.
+ *
+ * @see http://opensearch.a9.com/spec/1.1/querysyntax/#urltag.
+ * @see EngineURL()
+ */
+ _parseURL: function SRCH_ENG_parseURL(aElement) {
+ var type = aElement.getAttribute("type");
+ // According to the spec, method is optional, defaulting to "GET" if not
+ // specified
+ var method = aElement.getAttribute("method") || "GET";
+ var template = aElement.getAttribute("template");
+
+ try {
+ var url = new EngineURL(type, method, template);
+ } catch (ex) {
+ FAIL("_parseURL: failed to add " + template + " as a URL",
+ Cr.NS_ERROR_FAILURE);
+ }
+
+ if (aElement.hasAttribute("rel"))
+ url.rels = aElement.getAttribute("rel").toLowerCase().split(/\s+/);
+
+ for (var i = 0; i < aElement.childNodes.length; ++i) {
+ var param = aElement.childNodes[i];
+ if (param.localName == "Param") {
+ try {
+ url.addParam(param.getAttribute("name"), param.getAttribute("value"));
+ } catch (ex) {
+ // Ignore failure
+ LOG("_parseURL: Url element has an invalid param");
+ }
+ } else if (param.localName == "MozParam" &&
+ // We only support MozParams for default search engines
+ this._isDefault) {
+ var value;
+ switch (param.getAttribute("condition")) {
+ case "defaultEngine":
+ // If this engine was the default search engine, use the true value
+ if (this._isDefaultEngine())
+ value = param.getAttribute("trueValue");
+ else
+ value = param.getAttribute("falseValue");
+ url.addParam(param.getAttribute("name"), value);
+ url._addMozParam({"name": param.getAttribute("name"),
+ "falseValue": param.getAttribute("falseValue"),
+ "trueValue": param.getAttribute("trueValue"),
+ "condition": "defaultEngine"});
+ break;
+
+ case "pref":
+ try {
+ value = getMozParamPref(param.getAttribute("pref"), value);
+ url.addParam(param.getAttribute("name"), value);
+ url._addMozParam({"pref": param.getAttribute("pref"),
+ "name": param.getAttribute("name"),
+ "condition": "pref"});
+ } catch (e) { }
+ break;
+ }
+ }
+ }
+
+ this._urls.push(url);
+ },
+
+ _isDefaultEngine: function SRCH_ENG__isDefaultEngine() {
+ let defaultPrefB = gPrefSvc.QueryInterface(Ci.nsIPrefService)
+ .getDefaultBranch(BROWSER_SEARCH_PREF);
+ let nsIPLS = Ci.nsIPrefLocalizedString;
+ let defaultEngine;
+ try {
+ defaultEngine = defaultPrefB.getComplexValue("defaultenginename", nsIPLS).data;
+ } catch (ex) {}
+ return this.name == defaultEngine;
+ },
+
+ /**
+ * Get the icon from an OpenSearch Image element.
+ * @see http://opensearch.a9.com/spec/1.1/description/#image
+ */
+ _parseImage: function SRCH_ENG_parseImage(aElement) {
+ LOG("_parseImage: Image textContent: \"" + aElement.textContent + "\"");
+ if (aElement.getAttribute("width") == "16" &&
+ aElement.getAttribute("height") == "16") {
+ this._setIcon(aElement.textContent, true);
+ }
+ },
+
+ _parseAsMozSearch: function SRCH_ENG_parseAsMoz() {
+ //forward to the OpenSearch parser
+ this._parseAsOpenSearch();
+ },
+
+ /**
+ * Extract search engine information from the collected data to initialize
+ * the engine object.
+ */
+ _parseAsOpenSearch: function SRCH_ENG_parseAsOS() {
+ var doc = this._data;
+
+ // The OpenSearch spec sets a default value for the input encoding.
+ this._queryCharset = OS_PARAM_INPUT_ENCODING_DEF;
+
+ for (var i = 0; i < doc.childNodes.length; ++i) {
+ var child = doc.childNodes[i];
+ switch (child.localName) {
+ case "ShortName":
+ this._name = child.textContent;
+ break;
+ case "Description":
+ this._description = child.textContent;
+ break;
+ case "Url":
+ try {
+ this._parseURL(child);
+ } catch (ex) {
+ // Parsing of the element failed, just skip it.
+ }
+ break;
+ case "Image":
+ this._parseImage(child);
+ break;
+ case "InputEncoding":
+ this._queryCharset = child.textContent.toUpperCase();
+ break;
+
+ // Non-OpenSearch elements
+ case "SearchForm":
+ this._searchForm = child.textContent;
+ break;
+ case "UpdateUrl":
+ this._updateURL = child.textContent;
+ break;
+ case "UpdateInterval":
+ this._updateInterval = parseInt(child.textContent);
+ break;
+ case "IconUpdateUrl":
+ this._iconUpdateURL = child.textContent;
+ break;
+ }
+ }
+ if (!this.name || (this._urls.length == 0))
+ FAIL("_parseAsOpenSearch: No name, or missing URL!", Cr.NS_ERROR_FAILURE);
+ if (!this.supportsResponseType(URLTYPE_SEARCH_HTML))
+ FAIL("_parseAsOpenSearch: No text/html result type!", Cr.NS_ERROR_FAILURE);
+ },
+
+ /**
+ * Extract search engine information from the collected data to initialize
+ * the engine object.
+ */
+ _parseAsSherlock: function SRCH_ENG_parseAsSherlock() {
+ /**
+ * Extracts one Sherlock "section" from aSource. A section is essentially
+ * an HTML element with attributes, but each attribute must be on a new
+ * line, by definition.
+ *
+ * @param aLines
+ * An array of lines from the sherlock file.
+ * @param aSection
+ * The name of the section (e.g. "search" or "browser"). This value
+ * is not case sensitive.
+ * @returns an object whose properties correspond to the section's
+ * attributes.
+ */
+ function getSection(aLines, aSection) {
+ LOG("_parseAsSherlock::getSection: Sherlock lines:\n" +
+ aLines.join("\n"));
+ var lines = aLines;
+ var startMark = new RegExp("^\\s*<" + aSection.toLowerCase() + "\\s*",
+ "gi");
+ var endMark = /\s*>\s*$/gi;
+
+ var foundStart = false;
+ var startLine, numberOfLines;
+ // Find the beginning and end of the section
+ for (var i = 0; i < lines.length; i++) {
+ if (foundStart) {
+ if (endMark.test(lines[i])) {
+ numberOfLines = i - startLine;
+ // Remove the end marker
+ lines[i] = lines[i].replace(endMark, "");
+ // If the endmarker was not the only thing on the line, include
+ // this line in the results
+ if (lines[i])
+ numberOfLines++;
+ break;
+ }
+ } else {
+ if (startMark.test(lines[i])) {
+ foundStart = true;
+ // Remove the start marker
+ lines[i] = lines[i].replace(startMark, "");
+ startLine = i;
+ // If the line is empty, don't include it in the result
+ if (!lines[i])
+ startLine++;
+ }
+ }
+ }
+ LOG("_parseAsSherlock::getSection: Start index: " + startLine +
+ "\nNumber of lines: " + numberOfLines);
+ lines = lines.splice(startLine, numberOfLines);
+ LOG("_parseAsSherlock::getSection: Section lines:\n" +
+ lines.join("\n"));
+
+ var section = {};
+ for (var i = 0; i < lines.length; i++) {
+ var line = lines[i].trim();
+
+ var els = line.split("=");
+ var name = els.shift().trim().toLowerCase();
+ var value = els.join("=").trim();
+
+ if (!name || !value)
+ continue;
+
+ // Strip leading and trailing whitespace, remove quotes from the
+ // value, and remove any trailing slashes or ">" characters
+ value = value.replace(/^["']/, "")
+ .replace(/["']\s*[\\\/]?>?\s*$/, "") || "";
+ value = value.trim();
+
+ // Don't clobber existing attributes
+ if (!(name in section))
+ section[name] = value;
+ }
+ return section;
+ }
+
+ /**
+ * Returns an array of name-value pair arrays representing the Sherlock
+ * file's input elements. User defined inputs return USER_DEFINED
+ * as the value. Elements are returned in the order they appear in the
+ * source file.
+ *
+ * Example:
+ * <input name="foo" value="bar">
+ * <input name="foopy" user>
+ * Returns:
+ * [["foo", "bar"], ["foopy", "{searchTerms}"]]
+ *
+ * @param aLines
+ * An array of lines from the source file.
+ */
+ function getInputs(aLines) {
+
+ /**
+ * Extracts an attribute value from a given a line of text.
+ * Example: <input value="foo" name="bar">
+ * Extracts the string |foo| or |bar| given an input aAttr of
+ * |value| or |name|.
+ * Attributes may be quoted or unquoted. If unquoted, any whitespace
+ * indicates the end of the attribute value.
+ * Example: < value=22 33 name=44\334 >
+ * Returns |22| for "value" and |44\334| for "name".
+ *
+ * @param aAttr
+ * The name of the attribute for which to obtain the value. This
+ * value is not case sensitive.
+ * @param aLine
+ * The line containing the attribute.
+ *
+ * @returns the attribute value, or an empty string if the attribute
+ * doesn't exist.
+ */
+ function getAttr(aAttr, aLine) {
+ // Used to determine whether an "input" line from a Sherlock file is a
+ // "user defined" input.
+ const userInput = /(\s|["'=])user(\s|[>="'\/\\+]|$)/i;
+
+ LOG("_parseAsSherlock::getAttr: Getting attr: \"" +
+ aAttr + "\" for line: \"" + aLine + "\"");
+ // We're not case sensitive, but we want to return the attribute value
+ // in its original case, so create a copy of the source
+ var lLine = aLine.toLowerCase();
+ var attr = aAttr.toLowerCase();
+
+ var attrStart = lLine.search(new RegExp("\\s" + attr, "i"));
+ if (attrStart == -1) {
+
+ // If this is the "user defined input" (i.e. contains the empty
+ // "user" attribute), return our special keyword
+ if (userInput.test(lLine) && attr == "value") {
+ LOG("_parseAsSherlock::getAttr: Found user input!\nLine:\"" + lLine
+ + "\"");
+ return USER_DEFINED;
+ }
+ // The attribute doesn't exist - ignore
+ LOG("_parseAsSherlock::getAttr: Failed to find attribute:\nLine:\""
+ + lLine + "\"\nAttr:\"" + attr + "\"");
+ return "";
+ }
+
+ var valueStart = lLine.indexOf("=", attrStart) + "=".length;
+ if (valueStart == -1)
+ return "";
+
+ var quoteStart = lLine.indexOf("\"", valueStart);
+ if (quoteStart == -1) {
+
+ // Unquoted attribute, get the rest of the line, trimmed at the first
+ // sign of whitespace. If the rest of the line is only whitespace,
+ // returns a blank string.
+ return lLine.substr(valueStart).replace(/\s.*$/, "");
+
+ } else {
+ // Make sure that there's only whitespace between the start of the
+ // value and the first quote. If there is, end the attribute value at
+ // the first sign of whitespace. This prevents us from falling into
+ // the next attribute if this is an unquoted attribute followed by a
+ // quoted attribute.
+ var betweenEqualAndQuote = lLine.substring(valueStart, quoteStart);
+ if (/\S/.test(betweenEqualAndQuote))
+ return lLine.substr(valueStart).replace(/\s.*$/, "");
+
+ // Adjust the start index to account for the opening quote
+ valueStart = quoteStart + "\"".length;
+ // Find the closing quote
+ valueEnd = lLine.indexOf("\"", valueStart);
+ // If there is no closing quote, just go to the end of the line
+ if (valueEnd == -1)
+ valueEnd = aLine.length;
+ }
+ return aLine.substring(valueStart, valueEnd);
+ }
+
+ var inputs = [];
+
+ LOG("_parseAsSherlock::getInputs: Lines:\n" + aLines);
+ // Filter out everything but non-inputs
+ lines = aLines.filter(function (line) {
+ return /^\s*<input/i.test(line);
+ });
+ LOG("_parseAsSherlock::getInputs: Filtered lines:\n" + lines);
+
+ lines.forEach(function (line) {
+ // Strip leading/trailing whitespace and remove the surrounding markup
+ // ("<input" and ">")
+ line = line.trim().replace(/^<input/i, "").replace(/>$/, "");
+
+ // If this is one of the "directional" inputs (<inputnext>/<inputprev>)
+ const directionalInput = /^(prev|next)/i;
+ if (directionalInput.test(line)) {
+
+ // Make it look like a normal input by removing "prev" or "next"
+ line = line.replace(directionalInput, "");
+
+ // If it has a name, give it a dummy value to match previous
+ // nsInternetSearchService behavior
+ if (/name\s*=/i.test(line)) {
+ line += " value=\"0\"";
+ } else
+ return; // Line has no name, skip it
+ }
+
+ var attrName = getAttr("name", line);
+ var attrValue = getAttr("value", line);
+ LOG("_parseAsSherlock::getInputs: Got input:\nName:\"" + attrName +
+ "\"\nValue:\"" + attrValue + "\"");
+ if (attrValue)
+ inputs.push([attrName, attrValue]);
+ });
+ return inputs;
+ }
+
+ function err(aErr) {
+ FAIL("_parseAsSherlock::err: Sherlock param error:\n" + aErr,
+ Cr.NS_ERROR_FAILURE);
+ }
+
+ // First try converting our byte array using the default Sherlock encoding.
+ // If this fails, or if we find a sourceTextEncoding attribute, we need to
+ // reconvert the byte array using the specified encoding.
+ var sherlockLines, searchSection, sourceTextEncoding, browserSection;
+ try {
+ sherlockLines = sherlockBytesToLines(this._data);
+ searchSection = getSection(sherlockLines, "search");
+ browserSection = getSection(sherlockLines, "browser");
+ sourceTextEncoding = parseInt(searchSection["sourcetextencoding"]);
+ if (sourceTextEncoding) {
+ // Re-convert the bytes using the found sourceTextEncoding
+ sherlockLines = sherlockBytesToLines(this._data, sourceTextEncoding);
+ searchSection = getSection(sherlockLines, "search");
+ browserSection = getSection(sherlockLines, "browser");
+ }
+ } catch (ex) {
+ // The conversion using the default charset failed. Remove any non-ascii
+ // bytes and try to find a sourceTextEncoding.
+ var asciiBytes = this._data.filter(function (n) {return !(0x80 & n);});
+ var asciiString = String.fromCharCode.apply(null, asciiBytes);
+ sherlockLines = asciiString.split(NEW_LINES).filter(isUsefulLine);
+ searchSection = getSection(sherlockLines, "search");
+ sourceTextEncoding = parseInt(searchSection["sourcetextencoding"]);
+ if (sourceTextEncoding) {
+ sherlockLines = sherlockBytesToLines(this._data, sourceTextEncoding);
+ searchSection = getSection(sherlockLines, "search");
+ browserSection = getSection(sherlockLines, "browser");
+ } else
+ ERROR("Couldn't find a working charset", Cr.NS_ERROR_FAILURE);
+ }
+
+ LOG("_parseAsSherlock: Search section:\n" + searchSection.toSource());
+
+ this._name = searchSection["name"] || err("Missing name!");
+ this._description = searchSection["description"] || "";
+ this._queryCharset = searchSection["querycharset"] ||
+ queryCharsetFromCode(searchSection["queryencoding"]);
+ this._searchForm = searchSection["searchform"];
+
+ this._updateInterval = parseInt(browserSection["updatecheckdays"]);
+
+ this._updateURL = browserSection["update"];
+ this._iconUpdateURL = browserSection["updateicon"];
+
+ var method = (searchSection["method"] || "GET").toUpperCase();
+ var template = searchSection["action"] || err("Missing action!");
+
+ var inputs = getInputs(sherlockLines);
+ LOG("_parseAsSherlock: Inputs:\n" + inputs.toSource());
+
+ var url = null;
+
+ if (method == "GET") {
+ // Here's how we construct the input string:
+ // <input> is first: Name Attr: Prefix Data Example:
+ // YES EMPTY None <value> TEMPLATE<value>
+ // YES NON-EMPTY ? <name>=<value> TEMPLATE?<name>=<value>
+ // NO EMPTY ------------- <ignored> --------------
+ // NO NON-EMPTY & <name>=<value> TEMPLATE?<n1>=<v1>&<n2>=<v2>
+ for (var i = 0; i < inputs.length; i++) {
+ var name = inputs[i][0];
+ var value = inputs[i][1];
+ if (i==0) {
+ if (name == "")
+ template += USER_DEFINED;
+ else
+ template += "?" + name + "=" + value;
+ } else if (name != "")
+ template += "&" + name + "=" + value;
+ }
+ url = new EngineURL("text/html", method, template);
+
+ } else if (method == "POST") {
+ // Create the URL object and just add the parameters directly
+ url = new EngineURL("text/html", method, template);
+ for (var i = 0; i < inputs.length; i++) {
+ var name = inputs[i][0];
+ var value = inputs[i][1];
+ if (name)
+ url.addParam(name, value);
+ }
+ } else
+ err("Invalid method!");
+
+ this._urls.push(url);
+ },
+
+ /**
+ * Init from a JSON record.
+ **/
+ _initWithJSON: function SRCH_ENG__initWithJSON(aJson) {
+ this.__id = aJson._id;
+ this._name = aJson._name;
+ this._description = aJson.description;
+ if (aJson._hasPreferredIcon == undefined)
+ this._hasPreferredIcon = true;
+ else
+ this._hasPreferredIcon = false;
+ this._hidden = aJson.hidden || null;
+ this._type = aJson.type || SEARCH_TYPE_MOZSEARCH;
+ this._queryCharset = aJson.queryCharset || DEFAULT_QUERY_CHARSET;
+ this.__searchForm = aJson.__searchForm;
+ this.__installLocation = aJson._installLocation || SEARCH_APP_DIR;
+ this._updateInterval = aJson._updateInterval || null;
+ this._updateURL = aJson._updateURL || null;
+ this._iconUpdateURL = aJson._iconUpdateURL || null;
+ if (aJson._readOnly == undefined)
+ this._readOnly = true;
+ else
+ this._readOnly = false;
+ this._iconURI = makeURI(aJson._iconURL);
+ for (let i = 0; i < aJson._urls.length; ++i) {
+ let url = aJson._urls[i];
+ let engineURL = new EngineURL(url.type || URLTYPE_SEARCH_HTML,
+ url.method || "GET", url.template);
+ engineURL._initWithJSON(url, this);
+ this._urls.push(engineURL);
+ }
+ },
+
+ /**
+ * Creates a JavaScript object that represents this engine.
+ * @param aFilter
+ * Whether or not to filter out common default values. Recommended for
+ * use with _initWithJSON().
+ * @returns An object suitable for serialization as JSON.
+ **/
+ _serializeToJSON: function SRCH_ENG__serializeToJSON(aFilter) {
+ var json = {
+ _id: this._id,
+ _name: this._name,
+ description: this.description,
+ filePath: this._file.QueryInterface(Ci.nsILocalFile).persistentDescriptor,
+ __searchForm: this.__searchForm,
+ _iconURL: this._iconURL,
+ _urls: [url._serializeToJSON() for each(url in this._urls)]
+ };
+
+ if (this._installLocation != SEARCH_APP_DIR || !aFilter)
+ json._installLocation = this._installLocation;
+ if (this._updateInterval || !aFilter)
+ json._updateInterval = this._updateInterval;
+ if (this._updateURL || !aFilter)
+ json._updateURL = this._updateURL;
+ if (this._iconUpdateURL || !aFilter)
+ json._iconUpdateURL = this._iconUpdateURL;
+ if (!this._hasPreferredIcon || !aFilter)
+ json._hasPreferredIcon = this._hasPreferredIcon;
+ if (this.hidden || !aFilter)
+ json.hidden = this.hidden;
+ if (this.type != SEARCH_TYPE_MOZSEARCH || !aFilter)
+ json.type = this.type;
+ if (this.queryCharset != DEFAULT_QUERY_CHARSET || !aFilter)
+ json.queryCharset = this.queryCharset;
+ if (this._dataType != SEARCH_DATA_XML || !aFilter)
+ json._dataType = this._dataType;
+ if (!this._readOnly || !aFilter)
+ json._readOnly = this._readOnly;
+
+ return json;
+ },
+
+ /**
+ * Returns an XML document object containing the search plugin information,
+ * which can later be used to reload the engine.
+ */
+ _serializeToElement: function SRCH_ENG_serializeToEl() {
+ function appendTextNode(aNameSpace, aLocalName, aValue) {
+ if (!aValue)
+ return null;
+ var node = doc.createElementNS(aNameSpace, aLocalName);
+ node.appendChild(doc.createTextNode(aValue));
+ docElem.appendChild(node);
+ docElem.appendChild(doc.createTextNode("\n"));
+ return node;
+ }
+
+ var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
+ createInstance(Ci.nsIDOMParser);
+
+ var doc = parser.parseFromString(EMPTY_DOC, "text/xml");
+ var docElem = doc.documentElement;
+
+ docElem.appendChild(doc.createTextNode("\n"));
+
+ appendTextNode(OPENSEARCH_NS_11, "ShortName", this.name);
+ appendTextNode(OPENSEARCH_NS_11, "Description", this._description);
+ appendTextNode(OPENSEARCH_NS_11, "InputEncoding", this._queryCharset);
+
+ if (this._iconURI) {
+ var imageNode = appendTextNode(OPENSEARCH_NS_11, "Image",
+ this._iconURI.spec);
+ if (imageNode) {
+ imageNode.setAttribute("width", "16");
+ imageNode.setAttribute("height", "16");
+ }
+ }
+
+ appendTextNode(MOZSEARCH_NS_10, "UpdateInterval", this._updateInterval);
+ appendTextNode(MOZSEARCH_NS_10, "UpdateUrl", this._updateURL);
+ appendTextNode(MOZSEARCH_NS_10, "IconUpdateUrl", this._iconUpdateURL);
+ appendTextNode(MOZSEARCH_NS_10, "SearchForm", this._searchForm);
+
+ for (var i = 0; i < this._urls.length; ++i)
+ this._urls[i]._serializeToElement(doc, docElem);
+ docElem.appendChild(doc.createTextNode("\n"));
+
+ return doc;
+ },
+
+ _lazySerializeToFile: function SRCH_ENG_serializeToFile() {
+ if (this._serializeTimer) {
+ // Reset the timer
+ this._serializeTimer.delay = LAZY_SERIALIZE_DELAY;
+ } else {
+ this._serializeTimer = Cc["@mozilla.org/timer;1"].
+ createInstance(Ci.nsITimer);
+ var timerCallback = {
+ self: this,
+ notify: function SRCH_ENG_notify(aTimer) {
+ try {
+ this.self._serializeToFile();
+ } catch (ex) {
+ LOG("Serialization from timer callback failed:\n" + ex);
+ }
+ this.self._serializeTimer = null;
+ }
+ };
+ this._serializeTimer.initWithCallback(timerCallback,
+ LAZY_SERIALIZE_DELAY,
+ Ci.nsITimer.TYPE_ONE_SHOT);
+ }
+ },
+
+ /**
+ * Serializes the engine object to file.
+ */
+ _serializeToFile: function SRCH_ENG_serializeToFile() {
+ var file = this._file;
+ ENSURE_WARN(!this._readOnly, "Can't serialize a read only engine!",
+ Cr.NS_ERROR_FAILURE);
+ ENSURE_WARN(file && file.exists(), "Can't serialize: file doesn't exist!",
+ Cr.NS_ERROR_UNEXPECTED);
+
+ var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+
+ // Serialize the engine first - we don't want to overwrite a good file
+ // if this somehow fails.
+ var doc = this._serializeToElement();
+
+ fos.init(file, (MODE_WRONLY | MODE_TRUNCATE), PERMS_FILE, 0);
+
+ try {
+ var serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"].
+ createInstance(Ci.nsIDOMSerializer);
+ serializer.serializeToStream(doc.documentElement, fos, null);
+ } catch (e) {
+ LOG("_serializeToFile: Error serializing engine:\n" + e);
+ }
+
+ closeSafeOutputStream(fos);
+ },
+
+ /**
+ * Remove the engine's file from disk. The search service calls this once it
+ * removes the engine from its internal store. This function will throw if
+ * the file cannot be removed.
+ */
+ _remove: function SRCH_ENG_remove() {
+ if (this._readOnly)
+ FAIL("Can't remove read only engine!", Cr.NS_ERROR_FAILURE);
+ if (!this._file || !this._file.exists())
+ FAIL("Can't remove engine: file doesn't exist!", Cr.NS_ERROR_FILE_NOT_FOUND);
+
+ this._file.remove(false);
+ },
+
+ // nsISearchEngine
+ get alias() {
+ if (this._alias === null)
+ this._alias = engineMetadataService.getAttr(this, "alias");
+
+ return this._alias;
+ },
+ set alias(val) {
+ this._alias = val;
+ engineMetadataService.setAttr(this, "alias", val);
+ notifyAction(this, SEARCH_ENGINE_CHANGED);
+ },
+
+ get description() {
+ return this._description;
+ },
+
+ get hidden() {
+ if (this._hidden === null)
+ this._hidden = engineMetadataService.getAttr(this, "hidden");
+ return this._hidden;
+ },
+ set hidden(val) {
+ var value = !!val;
+ if (value != this._hidden) {
+ this._hidden = value;
+ engineMetadataService.setAttr(this, "hidden", value);
+ notifyAction(this, SEARCH_ENGINE_CHANGED);
+ }
+ },
+
+ get iconURI() {
+ return this._iconURI;
+ },
+
+ get _iconURL() {
+ if (!this._iconURI)
+ return "";
+ return this._iconURI.spec;
+ },
+
+ // Where the engine is being loaded from: will return the URI's spec if the
+ // engine is being downloaded and does not yet have a file. This is only used
+ // for logging.
+ get _location() {
+ if (this._file)
+ return this._file.path;
+
+ if (this._uri)
+ return this._uri.spec;
+
+ return "";
+ },
+
+ // The file that the plugin is loaded from is a unique identifier for it. We
+ // use this as the identifier to store data in the sqlite database
+ __id: null,
+ get _id() {
+ if (!this.__id) {
+ ENSURE_WARN(this._file, "No _file for id!", Cr.NS_ERROR_FAILURE);
+
+ if (this._isInProfile)
+ return this.__id = "[profile]/" + this._file.leafName;
+ if (this._isInAppDir)
+ return this.__id = "[app]/" + this._file.leafName;
+
+ // We're not in the profile or appdir, so this must be an extension-shipped
+ // plugin. Use the full path.
+ return this.__id = this._file.path;
+ }
+ return this.__id;
+ },
+
+ get _installLocation() {
+ ENSURE_WARN(this._file && this._file.exists(),
+ "_installLocation: engine has no file!",
+ Cr.NS_ERROR_FAILURE);
+
+ if (this.__installLocation === null) {
+ if (this._file.parent.equals(getDir(NS_APP_SEARCH_DIR)))
+ this.__installLocation = SEARCH_APP_DIR;
+ else if (this._file.parent.equals(getDir(NS_APP_USER_SEARCH_DIR)))
+ this.__installLocation = SEARCH_PROFILE_DIR;
+ else
+ this.__installLocation = SEARCH_IN_EXTENSION;
+ }
+
+ return this.__installLocation;
+ },
+
+ get _isInAppDir() {
+ return this._installLocation == SEARCH_APP_DIR;
+ },
+ get _isInProfile() {
+ return this._installLocation == SEARCH_PROFILE_DIR;
+ },
+
+ get _isDefault() {
+ // For now, our concept of a "default engine" is "one that is not in the
+ // user's profile directory", which is currently equivalent to "is app- or
+ // extension-shipped".
+ return !this._isInProfile;
+ },
+
+ get _hasUpdates() {
+ // Whether or not the engine has an update URL
+ let selfURL = this._getURLOfType(URLTYPE_OPENSEARCH);
+ return !!(this._updateURL || this._iconUpdateURL || (selfURL &&
+ selfURL._hasRelation("self")));
+ },
+
+ get name() {
+ return this._name;
+ },
+
+ get type() {
+ return this._type;
+ },
+
+ get searchForm() {
+ if (!this._searchForm) {
+ // No searchForm specified in the engine definition file, use the prePath
+ // (e.g. https://foo.com for https://foo.com/search.php?q=bar).
+ var htmlUrl = this._getURLOfType(URLTYPE_SEARCH_HTML);
+ ENSURE_WARN(htmlUrl, "Engine has no HTML URL!", Cr.NS_ERROR_UNEXPECTED);
+ this._searchForm = makeURI(htmlUrl.template).prePath;
+ }
+
+ return this._searchForm;
+ },
+
+ get queryCharset() {
+ if (this._queryCharset)
+ return this._queryCharset;
+ return this._queryCharset = queryCharsetFromCode(/* get the default */);
+ },
+
+ // from nsISearchEngine
+ addParam: function SRCH_ENG_addParam(aName, aValue, aResponseType) {
+ if (!aName || (aValue == null))
+ FAIL("missing name or value for nsISearchEngine::addParam!");
+ ENSURE_WARN(!this._readOnly,
+ "called nsISearchEngine::addParam on a read-only engine!",
+ Cr.NS_ERROR_FAILURE);
+ if (!aResponseType)
+ aResponseType = URLTYPE_SEARCH_HTML;
+
+ var url = this._getURLOfType(aResponseType);
+ if (!url)
+ FAIL("Engine object has no URL for response type " + aResponseType,
+ Cr.NS_ERROR_FAILURE);
+
+ url.addParam(aName, aValue);
+
+ // Serialize the changes to file lazily
+ this._lazySerializeToFile();
+ },
+
+ // from nsISearchEngine
+ getSubmission: function SRCH_ENG_getSubmission(aData, aResponseType) {
+ if (!aResponseType)
+ aResponseType = URLTYPE_SEARCH_HTML;
+
+ // Check for updates on the first use of an app-shipped engine
+ if (this._isInAppDir && aResponseType == URLTYPE_SEARCH_HTML && !this._used) {
+ this._used = true;
+ engineUpdateService.update(this);
+ }
+
+ var url = this._getURLOfType(aResponseType);
+
+ if (!url)
+ return null;
+
+ if (!aData) {
+ // Return a dummy submission object with our searchForm attribute
+ return new Submission(makeURI(this.searchForm), null);
+ }
+
+ LOG("getSubmission: In data: \"" + aData + "\"");
+ var textToSubURI = Cc["@mozilla.org/intl/texttosuburi;1"].
+ getService(Ci.nsITextToSubURI);
+ var data = "";
+ try {
+ data = textToSubURI.ConvertAndEscape(this.queryCharset, aData);
+ } catch (ex) {
+ LOG("getSubmission: Falling back to default queryCharset!");
+ data = textToSubURI.ConvertAndEscape(DEFAULT_QUERY_CHARSET, aData);
+ }
+ LOG("getSubmission: Out data: \"" + data + "\"");
+ return url.getSubmission(data, this);
+ },
+
+ // from nsISearchEngine
+ supportsResponseType: function SRCH_ENG_supportsResponseType(type) {
+ return (this._getURLOfType(type) != null);
+ },
+
+ // nsISupports
+ QueryInterface: function SRCH_ENG_QI(aIID) {
+ if (aIID.equals(Ci.nsISearchEngine) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ get wrappedJSObject() {
+ return this;
+ }
+
+};
+
+// nsISearchSubmission
+function Submission(aURI, aPostData) {
+ this._uri = aURI;
+ this._postData = aPostData;
+}
+Submission.prototype = {
+ get uri() {
+ return this._uri;
+ },
+ get postData() {
+ return this._postData;
+ },
+ QueryInterface: function SRCH_SUBM_QI(aIID) {
+ if (aIID.equals(Ci.nsISearchSubmission) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+}
+
+// nsIBrowserSearchService
+function SearchService() {
+ this._init();
+}
+SearchService.prototype = {
+ _engines: { },
+ _sortedEngines: null,
+ // Whether or not we need to write the order of engines on shutdown. This
+ // needs to happen anytime _sortedEngines is modified after initial startup.
+ _needToSetOrderPrefs: false,
+
+ _init: function() {
+ // Replace empty LOG function with the useful one if the log pref is set.
+ if (getBoolPref(BROWSER_SEARCH_PREF + "log", false))
+ LOG = DO_LOG;
+
+ engineMetadataService.init();
+ engineUpdateService.init();
+
+ this._loadEngines();
+ this._addObservers();
+
+ // Now that all engines are loaded, build the sorted engine list
+ this._buildSortedEngineList();
+
+ let selectedEngineName = getLocalizedPref(BROWSER_SEARCH_PREF +
+ "selectedEngine");
+ this._currentEngine = this.getEngineByName(selectedEngineName) ||
+ this.defaultEngine;
+ },
+
+ _buildCache: function SRCH_SVC__buildCache() {
+ if (!getBoolPref(BROWSER_SEARCH_PREF + "cache.enabled", true))
+ return;
+
+ let cache = {};
+ let locale = getLocale();
+ let buildID = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo).platformBuildID;
+
+ // Allows us to force a cache refresh should the cache format change.
+ cache.version = CACHE_VERSION;
+ // We don't want to incur the costs of stat()ing each plugin on every
+ // startup when the only (supported) time they will change is during
+ // runtime (where we refresh for changes through the API) and app updates
+ // (where the buildID is obviously going to change).
+ // Extension-shipped plugins are the only exception to this, but their
+ // directories are blown away during updates, so we'll detect their changes.
+ cache.buildID = buildID;
+ cache.locale = locale;
+
+ cache.directories = {};
+
+ for each (let engine in this._engines) {
+ let parent = engine._file.parent;
+ if (!cache.directories[parent.path]) {
+ let cacheEntry = {};
+ cacheEntry.lastModifiedTime = parent.lastModifiedTime;
+ cacheEntry.engines = [];
+ cache.directories[parent.path] = cacheEntry;
+ }
+ cache.directories[parent.path].engines.push(engine._serializeToJSON(true));
+ }
+
+ let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
+ let stream = Cc["@mozilla.org/network/file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ let converter = Cc["@mozilla.org/intl/converter-output-stream;1"].
+ createInstance(Ci.nsIConverterOutputStream);
+ let cacheFile = getDir(NS_APP_USER_PROFILE_50_DIR);
+ cacheFile.append("search.json");
+
+ try {
+ LOG("_buildCache: Writing to cache file.");
+ stream.init(cacheFile, (MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE), PERMS_FILE, 0);
+ converter.init(stream, "UTF-8", 0, 0x0000);
+ converter.writeString(json.encode(cache));
+ } catch (ex) {
+ LOG("_buildCache: Could not write to cache file: " + ex);
+ } finally {
+ converter.close();
+ stream.close();
+ }
+ },
+
+ _loadEngines: function SRCH_SVC__loadEngines() {
+ // See if we have a cache file so we don't have to parse a bunch of XML.
+ let cache = {};
+ let cacheEnabled = getBoolPref(BROWSER_SEARCH_PREF + "cache.enabled", true);
+ if (cacheEnabled) {
+ let cacheFile = getDir(NS_APP_USER_PROFILE_50_DIR);
+ cacheFile.append("search.json");
+ if (cacheFile.exists())
+ cache = this._readCacheFile(cacheFile);
+ }
+
+ let loadDirs = [];
+ let locations = getDir(NS_APP_SEARCH_DIR_LIST, Ci.nsISimpleEnumerator);
+ while (locations.hasMoreElements()) {
+ let dir = locations.getNext().QueryInterface(Ci.nsIFile);
+ if (dir.directoryEntries.hasMoreElements())
+ loadDirs.push(dir);
+ }
+
+ function modifiedDir(aDir) {
+ return (!cache.directories[aDir.path] ||
+ cache.directories[aDir.path].lastModifiedTime != aDir.lastModifiedTime);
+ }
+
+ function notInLoadDirs(aCachePath, aIndex)
+ aCachePath != loadDirs[aIndex].path;
+
+ let buildID = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo).platformBuildID;
+ let cachePaths = [path for (path in cache.directories)];
+
+ let rebuildCache = !cache.directories ||
+ cache.version != CACHE_VERSION ||
+ cache.locale != getLocale() ||
+ cache.buildID != buildID ||
+ cachePaths.length != loadDirs.length ||
+ cachePaths.some(notInLoadDirs) ||
+ loadDirs.some(modifiedDir);
+
+ if (!cacheEnabled || rebuildCache) {
+ LOG("_loadEngines: Absent or outdated cache. Loading engines from disk.");
+ loadDirs.forEach(this._loadEnginesFromDir, this);
+
+ if (cacheEnabled)
+ this._buildCache();
+ return;
+ }
+
+ for each (let dir in cache.directories)
+ this._loadEnginesFromCache(dir);
+ },
+
+ _readCacheFile: function SRCH_SVC__readCacheFile(aFile) {
+ let stream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
+
+ try {
+ stream.init(aFile, MODE_RDONLY, PERMS_FILE, 0);
+ return json.decodeFromStream(stream, stream.available());
+ } catch(ex) {
+ LOG("_readCacheFile: Error reading cache file: " + ex);
+ } finally {
+ stream.close();
+ }
+ return false;
+ },
+
+ _batchTimer: null,
+ _batchCacheInvalidation: function SRCH_SVC__batchCacheInvalidation() {
+ let callback = {
+ self: this,
+ notify: function SRCH_SVC_batchTimerNotify(aTimer) {
+ LOG("_batchCacheInvalidation: Invalidating engine cache");
+ this.self._buildCache();
+ this.self._batchTimer = null;
+ }
+ };
+
+ if (!this._batchTimer) {
+ this._batchTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._batchTimer.initWithCallback(callback, CACHE_INVALIDATION_DELAY,
+ Ci.nsITimer.TYPE_ONE_SHOT);
+ } else {
+ this._batchTimer.delay = CACHE_INVALIDATION_DELAY;
+ LOG("_batchCacheInvalidation: Batch timer reset");
+ }
+ },
+
+ _addEngineToStore: function SRCH_SVC_addEngineToStore(aEngine) {
+ LOG("_addEngineToStore: Adding engine: \"" + aEngine.name + "\"");
+
+ // See if there is an existing engine with the same name. However, if this
+ // engine is updating another engine, it's allowed to have the same name.
+ var hasSameNameAsUpdate = (aEngine._engineToUpdate &&
+ aEngine.name == aEngine._engineToUpdate.name);
+ if (aEngine.name in this._engines && !hasSameNameAsUpdate) {
+ LOG("_addEngineToStore: Duplicate engine found, aborting!");
+ return;
+ }
+
+ if (aEngine._engineToUpdate) {
+ // We need to replace engineToUpdate with the engine that just loaded.
+ var oldEngine = aEngine._engineToUpdate;
+
+ // Remove the old engine from the hash, since it's keyed by name, and our
+ // name might change (the update might have a new name).
+ delete this._engines[oldEngine.name];
+
+ // Hack: we want to replace the old engine with the new one, but since
+ // people may be holding refs to the nsISearchEngine objects themselves,
+ // we'll just copy over all "private" properties (those without a getter
+ // or setter) from one object to the other.
+ for (var p in aEngine) {
+ if (!(aEngine.__lookupGetter__(p) || aEngine.__lookupSetter__(p)))
+ oldEngine[p] = aEngine[p];
+ }
+ aEngine = oldEngine;
+ aEngine._engineToUpdate = null;
+
+ // Add the engine back
+ this._engines[aEngine.name] = aEngine;
+ notifyAction(aEngine, SEARCH_ENGINE_CHANGED);
+ } else {
+ // Not an update, just add the new engine.
+ this._engines[aEngine.name] = aEngine;
+ // Only add the engine to the list of sorted engines if the initial list
+ // has already been built (i.e. if this._sortedEngines is non-null). If
+ // it hasn't, we're still loading engines from disk, and will build the
+ // sorted engine list when that initial loading is done.
+ if (this._sortedEngines) {
+ this._sortedEngines.push(aEngine);
+ this._needToSetOrderPrefs = true;
+ }
+ notifyAction(aEngine, SEARCH_ENGINE_ADDED);
+ }
+
+ if (aEngine._hasUpdates) {
+ // Schedule the engine's next update, if it isn't already.
+ if (!engineMetadataService.getAttr(aEngine, "updateexpir"))
+ engineUpdateService.scheduleNextUpdate(aEngine);
+
+ // We need to save the engine's _dataType, if this is the first time the
+ // engine is added to the dataStore, since ._dataType isn't persisted
+ // and will change on the next startup (since the engine will then be
+ // XML). We need this so that we know how to load any future updates from
+ // this engine.
+ if (!engineMetadataService.getAttr(aEngine, "updatedatatype"))
+ engineMetadataService.setAttr(aEngine, "updatedatatype",
+ aEngine._dataType);
+ }
+ },
+
+ _loadEnginesFromCache: function SRCH_SVC__loadEnginesFromCache(aDir) {
+ let engines = aDir.engines;
+ LOG("_loadEnginesFromCache: Loading from cache. " + engines.length + " engines to load.");
+ for (let i = 0; i < engines.length; i++) {
+ let json = engines[i];
+ let engine = new Engine({cached: true, value: json.filePath}, json._dataType,
+ json._readOnly);
+ engine._initWithJSON(json);
+ this._addEngineToStore(engine);
+ }
+ },
+
+ _loadEnginesFromDir: function SRCH_SVC__loadEnginesFromDir(aDir) {
+ LOG("_loadEnginesFromDir: Searching in " + aDir.path + " for search engines.");
+
+ // Check whether aDir is the user profile dir
+ var isInProfile = aDir.equals(getDir(NS_APP_USER_SEARCH_DIR));
+
+ var files = aDir.directoryEntries
+ .QueryInterface(Ci.nsIDirectoryEnumerator);
+
+ var addedEngines = [];
+ while (files.hasMoreElements()) {
+ var file = files.nextFile;
+
+ // Ignore hidden and empty files, and directories
+ if (!file.isFile() || file.fileSize == 0 || file.isHidden())
+ continue;
+
+ var fileURL = gIoSvc.newFileURI(file).QueryInterface(Ci.nsIURL);
+ var fileExtension = fileURL.fileExtension.toLowerCase();
+ var isWritable = isInProfile && file.isWritable();
+
+ var dataType;
+ switch (fileExtension) {
+ case XML_FILE_EXT:
+ dataType = SEARCH_DATA_XML;
+ break;
+ case SHERLOCK_FILE_EXT:
+ dataType = SEARCH_DATA_TEXT;
+ break;
+ default:
+ // Not an engine
+ continue;
+ }
+
+ var addedEngine = null;
+ try {
+ addedEngine = new Engine(file, dataType, !isWritable);
+ addedEngine._initFromFile();
+ if (addedEngine._used)
+ addedEngine._used = false;
+ } catch (ex) {
+ LOG("_loadEnginesFromDir: Failed to load " + file.path + "!\n" + ex);
+ continue;
+ }
+
+ if (fileExtension == SHERLOCK_FILE_EXT) {
+ if (isWritable) {
+ try {
+ this._convertSherlockFile(addedEngine, fileURL.fileBaseName);
+ } catch (ex) {
+ LOG("_loadEnginesFromDir: Failed to convert: " + fileURL.path + "\n" + ex);
+ // The engine couldn't be converted, mark it as read-only
+ addedEngine._readOnly = true;
+ }
+ }
+
+ // If the engine still doesn't have an icon, see if we can find one
+ if (!addedEngine._iconURI) {
+ var icon = this._findSherlockIcon(file, fileURL.fileBaseName);
+ if (icon)
+ addedEngine._iconURI = gIoSvc.newFileURI(icon);
+ }
+ }
+
+ this._addEngineToStore(addedEngine);
+ addedEngines.push(addedEngine);
+ }
+ return addedEngines;
+ },
+
+ _saveSortedEngineList: function SRCH_SVC_saveSortedEngineList() {
+ // We only need to write the prefs. if something has changed.
+ if (!this._needToSetOrderPrefs)
+ return;
+
+ // Set the useDB pref to indicate that from now on we should use the order
+ // information stored in the database.
+ gPrefSvc.setBoolPref(BROWSER_SEARCH_PREF + "useDBForOrder", true);
+
+ var engines = this._getSortedEngines(true);
+ var values = [];
+ var names = [];
+
+ for (var i = 0; i < engines.length; ++i) {
+ names[i] = "order";
+ values[i] = i + 1;
+ }
+
+ engineMetadataService.setAttrs(engines, names, values);
+ },
+
+ _buildSortedEngineList: function SRCH_SVC_buildSortedEngineList() {
+ var addedEngines = { };
+ this._sortedEngines = [];
+ var engine;
+
+ // If the user has specified a custom engine order, read the order
+ // information from the engineMetadataService instead of the default
+ // prefs.
+ if (getBoolPref(BROWSER_SEARCH_PREF + "useDBForOrder", false)) {
+ for each (engine in this._engines) {
+ var orderNumber = engineMetadataService.getAttr(engine, "order");
+
+ // Since the DB isn't regularly cleared, and engine files may disappear
+ // without us knowing, we may already have an engine in this slot. If
+ // that happens, we just skip it - it will be added later on as an
+ // unsorted engine. This problem will sort itself out when we call
+ // _saveSortedEngineList at shutdown.
+ if (orderNumber && !this._sortedEngines[orderNumber-1]) {
+ this._sortedEngines[orderNumber-1] = engine;
+ addedEngines[engine.name] = engine;
+ } else {
+ // We need to call _saveSortedEngines so this gets sorted out.
+ this._needToSetOrderPrefs = true;
+ }
+ }
+
+ // Filter out any nulls for engines that may have been removed
+ var filteredEngines = this._sortedEngines.filter(function(a) { return !!a; });
+ if (this._sortedEngines.length != filteredEngines.length)
+ this._needToSetOrderPrefs = true;
+ this._sortedEngines = filteredEngines;
+
+ } else {
+ // The DB isn't being used, so just read the engine order from the prefs
+ var i = 0;
+ var engineName;
+ var prefName;
+
+ try {
+ var extras =
+ gPrefSvc.getChildList(BROWSER_SEARCH_PREF + "order.extra.", { });
+
+ for each (prefName in extras) {
+ engineName = gPrefSvc.getCharPref(prefName);
+
+ engine = this._engines[engineName];
+ if (!engine || engine.name in addedEngines)
+ continue;
+
+ this._sortedEngines.push(engine);
+ addedEngines[engine.name] = engine;
+ }
+ }
+ catch (e) { }
+
+ while (true) {
+ engineName = getLocalizedPref(BROWSER_SEARCH_PREF + "order." + (++i));
+ if (!engineName)
+ break;
+
+ engine = this._engines[engineName];
+ if (!engine || engine.name in addedEngines)
+ continue;
+
+ this._sortedEngines.push(engine);
+ addedEngines[engine.name] = engine;
+ }
+ }
+
+ // Array for the remaining engines, alphabetically sorted
+ var alphaEngines = [];
+
+ for each (engine in this._engines) {
+ if (!(engine.name in addedEngines))
+ alphaEngines.push(this._engines[engine.name]);
+ }
+ alphaEngines = alphaEngines.sort(function (a, b) {
+ return a.name.localeCompare(b.name);
+ });
+ this._sortedEngines = this._sortedEngines.concat(alphaEngines);
+ },
+
+ /**
+ * Converts a Sherlock file and its icon into the custom XML format used by
+ * the Search Service. Saves the engine's icon (if present) into the XML as a
+ * data: URI and changes the extension of the source file from ".src" to
+ * ".xml". The engine data is then written to the file as XML.
+ * @param aEngine
+ * The Engine object that needs to be converted.
+ * @param aBaseName
+ * The basename of the Sherlock file.
+ * Example: "foo" for file "foo.src".
+ *
+ * @throws NS_ERROR_FAILURE if the file could not be converted.
+ *
+ * @see nsIURL::fileBaseName
+ */
+ _convertSherlockFile: function SRCH_SVC_convertSherlock(aEngine, aBaseName) {
+ var oldSherlockFile = aEngine._file;
+
+ // Back up the old file
+ try {
+ var backupDir = oldSherlockFile.parent;
+ backupDir.append("searchplugins-backup");
+
+ if (!backupDir.exists())
+ backupDir.create(Ci.nsIFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+
+ oldSherlockFile.copyTo(backupDir, null);
+ } catch (ex) {
+ // Just bail. Engines that can't be backed up won't be converted, but
+ // engines that aren't converted are loaded as readonly.
+ FAIL("_convertSherlockFile: Couldn't back up " + oldSherlockFile.path +
+ ":\n" + ex, Cr.NS_ERROR_FAILURE);
+ }
+
+ // Rename the file, but don't clobber existing files
+ var newXMLFile = oldSherlockFile.parent.clone();
+ newXMLFile.append(aBaseName + "." + XML_FILE_EXT);
+
+ if (newXMLFile.exists()) {
+ // There is an existing file with this name, create a unique file
+ newXMLFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ }
+
+ // Rename the .src file to .xml
+ oldSherlockFile.moveTo(null, newXMLFile.leafName);
+
+ aEngine._file = newXMLFile;
+
+ // Write the converted engine to disk
+ aEngine._serializeToFile();
+
+ // Update the engine's _type.
+ aEngine._type = SEARCH_TYPE_MOZSEARCH;
+
+ // See if it has a corresponding icon
+ try {
+ var icon = this._findSherlockIcon(aEngine._file, aBaseName);
+ if (icon && icon.fileSize < MAX_ICON_SIZE) {
+ // Use this as the engine's icon
+ var bStream = Cc["@mozilla.org/binaryinputstream;1"].
+ createInstance(Ci.nsIBinaryInputStream);
+ var fileInStream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+
+ fileInStream.init(icon, MODE_RDONLY, PERMS_FILE, 0);
+ bStream.setInputStream(fileInStream);
+
+ var bytes = [];
+ while (bStream.available() != 0)
+ bytes = bytes.concat(bStream.readByteArray(bStream.available()));
+ bStream.close();
+
+ // Convert the byte array to a base64-encoded string
+ var str = btoa(String.fromCharCode.apply(null, bytes));
+
+ aEngine._iconURI = makeURI(ICON_DATAURL_PREFIX + str);
+ LOG("_importSherlockEngine: Set sherlock iconURI to: \"" +
+ aEngine._iconURL + "\"");
+
+ // Write the engine to disk to save changes
+ aEngine._serializeToFile();
+
+ // Delete the icon now that we're sure everything's been saved
+ icon.remove(false);
+ }
+ } catch (ex) { LOG("_convertSherlockFile: Error setting icon:\n" + ex); }
+ },
+
+ /**
+ * Finds an icon associated to a given Sherlock file. Searches the provided
+ * file's parent directory looking for files with the same base name and one
+ * of the file extensions in SHERLOCK_ICON_EXTENSIONS.
+ * @param aEngineFile
+ * The Sherlock plugin file.
+ * @param aBaseName
+ * The basename of the Sherlock file.
+ * Example: "foo" for file "foo.src".
+ * @see nsIURL::fileBaseName
+ */
+ _findSherlockIcon: function SRCH_SVC_findSherlock(aEngineFile, aBaseName) {
+ for (var i = 0; i < SHERLOCK_ICON_EXTENSIONS.length; i++) {
+ var icon = aEngineFile.parent.clone();
+ icon.append(aBaseName + SHERLOCK_ICON_EXTENSIONS[i]);
+ if (icon.exists() && icon.isFile())
+ return icon;
+ }
+ return null;
+ },
+
+ /**
+ * Get a sorted array of engines.
+ * @param aWithHidden
+ * True if hidden plugins should be included in the result.
+ */
+ _getSortedEngines: function SRCH_SVC_getSorted(aWithHidden) {
+ if (aWithHidden)
+ return this._sortedEngines;
+
+ return this._sortedEngines.filter(function (engine) {
+ return !engine.hidden;
+ });
+ },
+
+ // nsIBrowserSearchService
+ getEngines: function SRCH_SVC_getEngines(aCount) {
+ LOG("getEngines: getting all engines");
+ var engines = this._getSortedEngines(true);
+ aCount.value = engines.length;
+ return engines;
+ },
+
+ getVisibleEngines: function SRCH_SVC_getVisible(aCount) {
+ LOG("getVisibleEngines: getting all visible engines");
+ var engines = this._getSortedEngines(false);
+ aCount.value = engines.length;
+ return engines;
+ },
+
+ getDefaultEngines: function SRCH_SVC_getDefault(aCount) {
+ function isDefault(engine) {
+ return engine._isDefault;
+ };
+ var engines = this._sortedEngines.filter(isDefault);
+ var engineOrder = {};
+ var engineName;
+ var i = 1;
+
+ // Build a list of engines which we have ordering information for.
+ // We're rebuilding the list here because _sortedEngines contain the
+ // current order, but we want the original order.
+
+ // First, look at the "browser.search.order.extra" branch.
+ try {
+ var extras = gPrefSvc.getChildList(BROWSER_SEARCH_PREF + "order.extra.",
+ {});
+
+ for each (var prefName in extras) {
+ engineName = gPrefSvc.getCharPref(prefName);
+
+ if (!(engineName in engineOrder))
+ engineOrder[engineName] = i++;
+ }
+ } catch (e) {
+ LOG("Getting extra order prefs failed: " + e);
+ }
+
+ // Now look through the "browser.search.order" branch.
+ for (var j = 1; ; j++) {
+ engineName = getLocalizedPref(BROWSER_SEARCH_PREF + "order." + j);
+ if (!engineName)
+ break;
+
+ if (!(engineName in engineOrder))
+ engineOrder[engineName] = i++;
+ }
+
+ LOG("getDefaultEngines: engineOrder: " + engineOrder.toSource());
+
+ function compareEngines (a, b) {
+ var aIdx = engineOrder[a.name];
+ var bIdx = engineOrder[b.name];
+
+ if (aIdx && bIdx)
+ return aIdx - bIdx;
+ if (aIdx)
+ return -1;
+ if (bIdx)
+ return 1;
+
+ return a.name.localeCompare(b.name);
+ }
+ engines.sort(compareEngines);
+
+ aCount.value = engines.length;
+ return engines;
+ },
+
+ getEngineByName: function SRCH_SVC_getEngineByName(aEngineName) {
+ return this._engines[aEngineName] || null;
+ },
+
+ getEngineByAlias: function SRCH_SVC_getEngineByAlias(aAlias) {
+ for (var engineName in this._engines) {
+ var engine = this._engines[engineName];
+ if (engine && engine.alias == aAlias)
+ return engine;
+ }
+ return null;
+ },
+
+ addEngineWithDetails: function SRCH_SVC_addEWD(aName, aIconURL, aAlias,
+ aDescription, aMethod,
+ aTemplate) {
+ if (!aName)
+ FAIL("Invalid name passed to addEngineWithDetails!");
+ if (!aMethod)
+ FAIL("Invalid method passed to addEngineWithDetails!");
+ if (!aTemplate)
+ FAIL("Invalid template passed to addEngineWithDetails!");
+ if (this._engines[aName])
+ FAIL("An engine with that name already exists!", Cr.NS_ERROR_FILE_ALREADY_EXISTS);
+
+ var engine = new Engine(getSanitizedFile(aName), SEARCH_DATA_XML, false);
+ engine._initFromMetadata(aName, aIconURL, aAlias, aDescription,
+ aMethod, aTemplate);
+ this._addEngineToStore(engine);
+ this._batchCacheInvalidation();
+ },
+
+ addEngine: function SRCH_SVC_addEngine(aEngineURL, aDataType, aIconURL,
+ aConfirm) {
+ LOG("addEngine: Adding \"" + aEngineURL + "\".");
+ try {
+ var uri = makeURI(aEngineURL);
+ var engine = new Engine(uri, aDataType, false);
+ engine._initFromURI();
+ } catch (ex) {
+ FAIL("addEngine: Error adding engine:\n" + ex, Cr.NS_ERROR_FAILURE);
+ }
+ engine._setIcon(aIconURL, false);
+ engine._confirm = aConfirm;
+ },
+
+ removeEngine: function SRCH_SVC_removeEngine(aEngine) {
+ if (!aEngine)
+ FAIL("no engine passed to removeEngine!");
+
+ var engineToRemove = null;
+ for (var e in this._engines)
+ if (aEngine.wrappedJSObject == this._engines[e])
+ engineToRemove = this._engines[e];
+
+ if (!engineToRemove)
+ FAIL("removeEngine: Can't find engine to remove!", Cr.NS_ERROR_FILE_NOT_FOUND);
+
+ if (engineToRemove == this.currentEngine)
+ this._currentEngine = null;
+
+ if (engineToRemove._readOnly) {
+ // Just hide it (the "hidden" setter will notify) and remove its alias to
+ // avoid future conflicts with other engines.
+ engineToRemove.hidden = true;
+ engineToRemove.alias = null;
+ } else {
+ // Cancel the lazy serialization timer if it's running
+ if (engineToRemove._serializeTimer) {
+ engineToRemove._serializeTimer.cancel();
+ engineToRemove._serializeTimer = null;
+ }
+
+ // Remove the engine file from disk (this might throw)
+ engineToRemove._remove();
+ engineToRemove._file = null;
+
+ // Remove the engine from _sortedEngines
+ var index = this._sortedEngines.indexOf(engineToRemove);
+ if (index == -1)
+ FAIL("Can't find engine to remove in _sortedEngines!", Cr.NS_ERROR_FAILURE);
+ this._sortedEngines.splice(index, 1);
+
+ // Remove the engine from the internal store
+ delete this._engines[engineToRemove.name];
+
+ notifyAction(engineToRemove, SEARCH_ENGINE_REMOVED);
+
+ // Since we removed an engine, we need to update the preferences.
+ this._needToSetOrderPrefs = true;
+ }
+ },
+
+ moveEngine: function SRCH_SVC_moveEngine(aEngine, aNewIndex) {
+ if ((aNewIndex > this._sortedEngines.length) || (aNewIndex < 0))
+ FAIL("SRCH_SVC_moveEngine: Index out of bounds!");
+ if (!(aEngine instanceof Ci.nsISearchEngine))
+ FAIL("SRCH_SVC_moveEngine: Invalid engine passed to moveEngine!");
+ if (aEngine.hidden)
+ FAIL("moveEngine: Can't move a hidden engine!", Cr.NS_ERROR_FAILURE);
+
+ var engine = aEngine.wrappedJSObject;
+
+ var currentIndex = this._sortedEngines.indexOf(engine);
+ if (currentIndex == -1)
+ FAIL("moveEngine: Can't find engine to move!", Cr.NS_ERROR_UNEXPECTED);
+
+ // Our callers only take into account non-hidden engines when calculating
+ // aNewIndex, but we need to move it in the array of all engines, so we
+ // need to adjust aNewIndex accordingly. To do this, we count the number
+ // of hidden engines in the list before the engine that we're taking the
+ // place of. We do this by first finding newIndexEngine (the engine that
+ // we were supposed to replace) and then iterating through the complete
+ // engine list until we reach it, increasing aNewIndex for each hidden
+ // engine we find on our way there.
+ //
+ // This could be further simplified by having our caller pass in
+ // newIndexEngine directly instead of aNewIndex.
+ var newIndexEngine = this._getSortedEngines(false)[aNewIndex];
+ if (!newIndexEngine)
+ FAIL("moveEngine: Can't find engine to replace!", Cr.NS_ERROR_UNEXPECTED);
+
+ for (var i = 0; i < this._sortedEngines.length; ++i) {
+ if (newIndexEngine == this._sortedEngines[i])
+ break;
+ if (this._sortedEngines[i].hidden)
+ aNewIndex++;
+ }
+
+ if (currentIndex == aNewIndex)
+ return; // nothing to do!
+
+ // Move the engine
+ var movedEngine = this._sortedEngines.splice(currentIndex, 1)[0];
+ this._sortedEngines.splice(aNewIndex, 0, movedEngine);
+
+ notifyAction(engine, SEARCH_ENGINE_CHANGED);
+
+ // Since we moved an engine, we need to update the preferences.
+ this._needToSetOrderPrefs = true;
+ },
+
+ restoreDefaultEngines: function SRCH_SVC_resetDefaultEngines() {
+ for each (var e in this._engines) {
+ // Unhide all default engines
+ if (e.hidden && e._isDefault)
+ e.hidden = false;
+ }
+ },
+
+ get defaultEngine() {
+ const defPref = BROWSER_SEARCH_PREF + "defaultenginename";
+ // Get the default engine - this pref should always exist, but the engine
+ // might be hidden
+ this._defaultEngine = this.getEngineByName(getLocalizedPref(defPref, ""));
+ if (!this._defaultEngine || this._defaultEngine.hidden)
+ this._defaultEngine = this._getSortedEngines(false)[0] || null;
+ return this._defaultEngine;
+ },
+
+ get currentEngine() {
+ if (!this._currentEngine || this._currentEngine.hidden)
+ this._currentEngine = this.defaultEngine;
+ return this._currentEngine;
+ },
+ set currentEngine(val) {
+ if (!(val instanceof Ci.nsISearchEngine))
+ FAIL("Invalid argument passed to currentEngine setter");
+
+ var newCurrentEngine = this.getEngineByName(val.name);
+ if (!newCurrentEngine)
+ FAIL("Can't find engine in store!", Cr.NS_ERROR_UNEXPECTED);
+
+ this._currentEngine = newCurrentEngine;
+
+ var currentEnginePref = BROWSER_SEARCH_PREF + "selectedEngine";
+
+ if (this._currentEngine == this.defaultEngine) {
+ if (gPrefSvc.prefHasUserValue(currentEnginePref))
+ gPrefSvc.clearUserPref(currentEnginePref);
+ }
+ else {
+ setLocalizedPref(currentEnginePref, this._currentEngine.name);
+ }
+
+ notifyAction(this._currentEngine, SEARCH_ENGINE_CURRENT);
+ },
+
+ // nsIObserver
+ observe: function SRCH_SVC_observe(aEngine, aTopic, aVerb) {
+ switch (aTopic) {
+ case SEARCH_ENGINE_TOPIC:
+ switch (aVerb) {
+ case SEARCH_ENGINE_LOADED:
+ var engine = aEngine.QueryInterface(Ci.nsISearchEngine);
+ LOG("nsSearchService::observe: Done installation of " + engine.name
+ + ".");
+ this._addEngineToStore(engine.wrappedJSObject);
+ if (engine.wrappedJSObject._useNow) {
+ LOG("nsSearchService::observe: setting current");
+ this.currentEngine = aEngine;
+ }
+ this._batchCacheInvalidation();
+ break;
+ case SEARCH_ENGINE_CHANGED:
+ case SEARCH_ENGINE_REMOVED:
+ this._batchCacheInvalidation();
+ break;
+ }
+ break;
+
+ case QUIT_APPLICATION_TOPIC:
+ this._removeObservers();
+ this._saveSortedEngineList();
+ if (this._batchTimer) {
+ // Flush to disk immediately
+ this._batchTimer.cancel();
+ this._buildCache();
+ }
+ break;
+ }
+ },
+
+ _addObservers: function SRCH_SVC_addObservers() {
+ gObsSvc.addObserver(this, SEARCH_ENGINE_TOPIC, false);
+ gObsSvc.addObserver(this, QUIT_APPLICATION_TOPIC, false);
+ },
+
+ _removeObservers: function SRCH_SVC_removeObservers() {
+ gObsSvc.removeObserver(this, SEARCH_ENGINE_TOPIC);
+ gObsSvc.removeObserver(this, QUIT_APPLICATION_TOPIC);
+ },
+
+ QueryInterface: function SRCH_SVC_QI(aIID) {
+ if (aIID.equals(Ci.nsIBrowserSearchService) ||
+ aIID.equals(Ci.nsIObserver) ||
+ aIID.equals(Ci.nsISupports))
+ return this;
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+};
+
+var engineMetadataService = {
+ init: function epsInit() {
+ var engineDataTable = "id INTEGER PRIMARY KEY, engineid STRING, name STRING, value STRING";
+ var file = getDir(NS_APP_USER_PROFILE_50_DIR);
+ file.append("search.sqlite");
+ var dbService = Cc["@mozilla.org/storage/service;1"].
+ getService(Ci.mozIStorageService);
+ try {
+ this.mDB = dbService.openDatabase(file);
+ } catch (ex) {
+ if (ex.result == 0x8052000b) { /* NS_ERROR_FILE_CORRUPTED */
+ // delete and try again
+ file.remove(false);
+ this.mDB = dbService.openDatabase(file);
+ } else {
+ throw ex;
+ }
+ }
+
+ try {
+ this.mDB.createTable("engine_data", engineDataTable);
+ } catch (ex) {
+ // Fails if the table already exists, which is fine
+ }
+
+ this.mGetData = createStatement (
+ this.mDB,
+ "SELECT value FROM engine_data WHERE engineid = :engineid AND name = :name");
+ this.mDeleteData = createStatement (
+ this.mDB,
+ "DELETE FROM engine_data WHERE engineid = :engineid AND name = :name");
+ this.mInsertData = createStatement (
+ this.mDB,
+ "INSERT INTO engine_data (engineid, name, value) " +
+ "VALUES (:engineid, :name, :value)");
+ },
+ getAttr: function epsGetAttr(engine, name) {
+ // attr names must be lower case
+ name = name.toLowerCase();
+
+ var stmt = this.mGetData;
+ stmt.reset();
+ var pp = stmt.params;
+ pp.engineid = engine._id;
+ pp.name = name;
+
+ var value = null;
+ if (stmt.step())
+ value = stmt.row.value;
+ stmt.reset();
+ return value;
+ },
+
+ setAttr: function epsSetAttr(engine, name, value) {
+ // attr names must be lower case
+ name = name.toLowerCase();
+
+ this.mDB.beginTransaction();
+
+ var pp = this.mDeleteData.params;
+ pp.engineid = engine._id;
+ pp.name = name;
+ this.mDeleteData.step();
+ this.mDeleteData.reset();
+
+ pp = this.mInsertData.params;
+ pp.engineid = engine._id;
+ pp.name = name;
+ pp.value = value;
+ this.mInsertData.step();
+ this.mInsertData.reset();
+
+ this.mDB.commitTransaction();
+ },
+
+ setAttrs: function epsSetAttrs(engines, names, values) {
+ this.mDB.beginTransaction();
+
+ for (var i = 0; i < engines.length; i++) {
+ // attr names must be lower case
+ var name = names[i].toLowerCase();
+
+ var pp = this.mDeleteData.params;
+ pp.engineid = engines[i]._id;
+ pp.name = names[i];
+ this.mDeleteData.step();
+ this.mDeleteData.reset();
+
+ pp = this.mInsertData.params;
+ pp.engineid = engines[i]._id;
+ pp.name = names[i];
+ pp.value = values[i];
+ this.mInsertData.step();
+ this.mInsertData.reset();
+ }
+
+ this.mDB.commitTransaction();
+ },
+
+ deleteEngineData: function epsDelData(engine, name) {
+ // attr names must be lower case
+ name = name.toLowerCase();
+
+ var pp = this.mDeleteData.params;
+ pp.engineid = engine._id;
+ pp.name = name;
+ this.mDeleteData.step();
+ this.mDeleteData.reset();
+ }
+}
+
+const SEARCH_UPDATE_LOG_PREFIX = "*** Search update: ";
+
+/**
+ * Outputs aText to the JavaScript console as well as to stdout, if the search
+ * logging pref (browser.search.update.log) is set to true.
+ */
+function ULOG(aText) {
+ if (getBoolPref(BROWSER_SEARCH_PREF + "update.log", false)) {
+ dump(SEARCH_UPDATE_LOG_PREFIX + aText + "\n");
+ var consoleService = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ consoleService.logStringMessage(aText);
+ }
+}
+
+var engineUpdateService = {
+ init: function eus_init() {
+ var tm = Cc["@mozilla.org/updates/timer-manager;1"].
+ getService(Ci.nsIUpdateTimerManager);
+ // figure out how often to check for any expired engines
+ var interval = gPrefSvc.getIntPref(BROWSER_SEARCH_PREF + "updateinterval");
+
+ // Interval is stored in hours
+ var seconds = interval * 3600;
+ tm.registerTimer("search-engine-update-timer", engineUpdateService,
+ seconds);
+ },
+
+ scheduleNextUpdate: function eus_scheduleNextUpdate(aEngine) {
+ var interval = aEngine._updateInterval || SEARCH_DEFAULT_UPDATE_INTERVAL;
+ var milliseconds = interval * 86400000; // |interval| is in days
+ engineMetadataService.setAttr(aEngine, "updateexpir",
+ Date.now() + milliseconds);
+ },
+
+ update: function eus_Update(aEngine) {
+ let engine = aEngine.wrappedJSObject;
+ ULOG("update called for " + aEngine._name);
+ if (!getBoolPref(BROWSER_SEARCH_PREF + "update", true) || !engine._hasUpdates)
+ return;
+
+ // We use the cache to store updated app engines, so refuse to update if the
+ // cache is disabled.
+ if (engine._readOnly &&
+ !getBoolPref(BROWSER_SEARCH_PREF + "cache.enabled", true))
+ return;
+
+ let testEngine = null;
+ let updateURL = engine._getURLOfType(URLTYPE_OPENSEARCH);
+ let updateURI = (updateURL && updateURL._hasRelation("self")) ?
+ updateURL.getSubmission("", engine).uri :
+ makeURI(engine._updateURL);
+ if (updateURI) {
+ if (engine._isDefault && !updateURI.schemeIs("https")) {
+ ULOG("Invalid scheme for default engine update");
+ return;
+ }
+
+ let dataType = engineMetadataService.getAttr(engine, "updatedatatype");
+ if (!dataType) {
+ ULOG("No loadtype to update engine!");
+ return;
+ }
+
+ ULOG("updating " + engine.name + " from " + updateURI.spec);
+ testEngine = new Engine(updateURI, dataType, false);
+ testEngine._engineToUpdate = engine;
+ testEngine._initFromURI();
+ } else
+ ULOG("invalid updateURI");
+
+ if (engine._iconUpdateURL) {
+ // If we're updating the engine too, use the new engine object,
+ // otherwise use the existing engine object.
+ (testEngine || engine)._setIcon(engine._iconUpdateURL, true);
+ }
+ },
+
+ notify: function eus_Notify(aTimer) {
+ ULOG("notify called");
+
+ if (!getBoolPref(BROWSER_SEARCH_PREF + "update", true))
+ return;
+
+ // Our timer has expired, but unfortunately, we can't get any data from it.
+ // Therefore, we need to walk our engine-list, looking for expired engines
+ var searchService = Cc["@mozilla.org/browser/search-service;1"].
+ getService(Ci.nsIBrowserSearchService);
+ var currentTime = Date.now();
+ ULOG("currentTime: " + currentTime);
+ for each (engine in searchService.getEngines({})) {
+ engine = engine.wrappedJSObject;
+ if (!engine._hasUpdates)
+ continue;
+
+ ULOG("checking " + engine.name);
+
+ var expirTime = engineMetadataService.getAttr(engine, "updateexpir");
+ ULOG("expirTime: " + expirTime + "\nupdateURL: " + engine._updateURL +
+ "\niconUpdateURL: " + engine._iconUpdateURL);
+
+ var engineExpired = expirTime <= currentTime;
+
+ if (!expirTime || !engineExpired) {
+ ULOG("skipping engine");
+ continue;
+ }
+
+ ULOG(engine.name + " has expired");
+
+ this.update(engine);
+
+ // Schedule the next update
+ this.scheduleNextUpdate(engine);
+
+ } // end engine iteration
+ }
+};
+
+const kClassID = Components.ID("{7319788a-fe93-4db3-9f39-818cf08f4256}");
+const kClassName = "Browser Search Service";
+const kContractID = "@mozilla.org/browser/search-service;1";
+
+// nsIFactory
+const kFactory = {
+ createInstance: function (outer, iid) {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return (new SearchService()).QueryInterface(iid);
+ }
+};
+
+// nsIModule
+const gModule = {
+ registerSelf: function (componentManager, fileSpec, location, type) {
+ componentManager.QueryInterface(Ci.nsIComponentRegistrar);
+ componentManager.registerFactoryLocation(kClassID,
+ kClassName,
+ kContractID,
+ fileSpec, location, type);
+ },
+
+ unregisterSelf: function(componentManager, fileSpec, location) {
+ componentManager.QueryInterface(Ci.nsIComponentRegistrar);
+ componentManager.unregisterFactoryLocation(kClassID, fileSpec);
+ },
+
+ getClassObject: function (componentManager, cid, iid) {
+ if (!cid.equals(kClassID))
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ if (!iid.equals(Ci.nsIFactory))
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ return kFactory;
+ },
+
+ canUnload: function (componentManager) {
+ return true;
+ }
+};
+
+function NSGetModule(componentManager, fileSpec) {
+ return gModule;
+}
+
+//@line 44 "/builds/moz2_slave/linux_build/build/toolkit/content/debug.js"
+
+var EXPORTED_SYMBOLS = ["NS_ASSERT"];
+
+var gTraceOnAssert = true;
+
+/**
+ * This function provides a simple assertion function for JavaScript.
+ * If the condition is true, this function will do nothing. If the
+ * condition is false, then the message will be printed to the console
+ * and an alert will appear showing a stack trace, so that the (alpha
+ * or nightly) user can file a bug containing it. For future enhancements,
+ * see bugs 330077 and 330078.
+ *
+ * To suppress the dialogs, you can run with the environment variable
+ * XUL_ASSERT_PROMPT set to 0 (if unset, this defaults to 1).
+ *
+ * @param condition represents the condition that we're asserting to be
+ * true when we call this function--should be
+ * something that can be evaluated as a boolean.
+ * @param message a string to be displayed upon failure of the assertion
+ */
+
+function NS_ASSERT(condition, message) {
+ if (condition)
+ return;
+
+ var releaseBuild = true;
+ var defB = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService)
+ .getDefaultBranch(null);
+ try {
+ switch (defB.getCharPref("app.update.channel")) {
+ case "nightly":
+ case "beta":
+ case "default":
+ releaseBuild = false;
+ }
+ } catch(ex) {}
+
+ var caller = arguments.callee.caller;
+ var assertionText = "ASSERT: " + message + "\n";
+
+ if (releaseBuild) {
+ // Just report the error to the console
+ Components.utils.reportError(assertionText);
+ return;
+ }
+
+ // Otherwise, dump to stdout and launch an assertion failure dialog
+ dump(assertionText);
+
+ var stackText = "";
+ if (gTraceOnAssert) {
+ stackText = "Stack Trace: \n";
+ var count = 0;
+ while (caller) {
+ stackText += count++ + ":" + caller.name + "(";
+ for (var i = 0; i < caller.arguments.length; ++i) {
+ var arg = caller.arguments[i];
+ stackText += arg;
+ if (i < caller.arguments.length - 1)
+ stackText += ",";
+ }
+ stackText += ")\n";
+ caller = caller.arguments.callee.caller;
+ }
+ }
+
+ var environment = Components.classes["@mozilla.org/process/environment;1"].
+ getService(Components.interfaces.nsIEnvironment);
+ if (environment.exists("XUL_ASSERT_PROMPT") &&
+ !parseInt(environment.get("XUL_ASSERT_PROMPT")))
+ return;
+
+ var source = null;
+ if (this.window)
+ source = this.window;
+ var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Components.interfaces.nsIPromptService);
+ ps.alert(source, "Assertion Failed", assertionText + stackText);
+}
diff --git a/bundles/XO/components/nsSearchSuggestions.js b/bundles/XO/components/nsSearchSuggestions.js
new file mode 100755
index 0000000..cfc4ad4
--- /dev/null
+++ b/bundles/XO/components/nsSearchSuggestions.js
@@ -0,0 +1,759 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Google Suggest Autocomplete Implementation for Firefox.
+ *
+ * The Initial Developer of the Original Code is Google Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ben Goodger <beng@google.com>
+ * Mike Connor <mconnor@mozilla.com>
+ * Joe Hughes <joe@retrovirus.com>
+ * Pamela Greene <pamg.bugs@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const SEARCH_RESPONSE_SUGGESTION_JSON = "application/x-suggestions+json";
+
+const BROWSER_SUGGEST_PREF = "browser.search.suggest.enabled";
+const XPCOM_SHUTDOWN_TOPIC = "xpcom-shutdown";
+const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
+const SEARCH_BUNDLE = "chrome://global/locale/search/search.properties";
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+const HTTP_OK = 200;
+const HTTP_INTERNAL_SERVER_ERROR = 500;
+const HTTP_BAD_GATEWAY = 502;
+const HTTP_SERVICE_UNAVAILABLE = 503;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+/**
+ * SuggestAutoCompleteResult contains the results returned by the Suggest
+ * service - it implements nsIAutoCompleteResult and is used by the auto-
+ * complete controller to populate the front end.
+ * @constructor
+ */
+function SuggestAutoCompleteResult(searchString,
+ searchResult,
+ defaultIndex,
+ errorDescription,
+ results,
+ comments,
+ formHistoryResult) {
+ this._searchString = searchString;
+ this._searchResult = searchResult;
+ this._defaultIndex = defaultIndex;
+ this._errorDescription = errorDescription;
+ this._results = results;
+ this._comments = comments;
+ this._formHistoryResult = formHistoryResult;
+}
+SuggestAutoCompleteResult.prototype = {
+ /**
+ * The user's query string
+ * @private
+ */
+ _searchString: "",
+
+ /**
+ * The result code of this result object, see |get searchResult| for possible
+ * values.
+ * @private
+ */
+ _searchResult: 0,
+
+ /**
+ * The default item that should be entered if none is selected
+ * @private
+ */
+ _defaultIndex: 0,
+
+ /**
+ * The reason the search failed
+ * @private
+ */
+ _errorDescription: "",
+
+ /**
+ * The list of words returned by the Suggest Service
+ * @private
+ */
+ _results: [],
+
+ /**
+ * The list of Comments (number of results - or page titles) returned by the
+ * Suggest Service.
+ * @private
+ */
+ _comments: [],
+
+ /**
+ * A reference to the form history nsIAutocompleteResult that we're wrapping.
+ * We use this to forward removeEntryAt calls as needed.
+ */
+ _formHistoryResult: null,
+
+ /**
+ * @return the user's query string
+ */
+ get searchString() {
+ return this._searchString;
+ },
+
+ /**
+ * @return the result code of this result object, either:
+ * RESULT_IGNORED (invalid searchString)
+ * RESULT_FAILURE (failure)
+ * RESULT_NOMATCH (no matches found)
+ * RESULT_SUCCESS (matches found)
+ */
+ get searchResult() {
+ return this._searchResult;
+ },
+
+ /**
+ * @return the default item that should be entered if none is selected
+ */
+ get defaultIndex() {
+ return this._defaultIndex;
+ },
+
+ /**
+ * @return the reason the search failed
+ */
+ get errorDescription() {
+ return this._errorDescription;
+ },
+
+ /**
+ * @return the number of results
+ */
+ get matchCount() {
+ return this._results.length;
+ },
+
+ /**
+ * Retrieves a result
+ * @param index the index of the result requested
+ * @return the result at the specified index
+ */
+ getValueAt: function(index) {
+ return this._results[index];
+ },
+
+ /**
+ * Retrieves a comment (metadata instance)
+ * @param index the index of the comment requested
+ * @return the comment at the specified index
+ */
+ getCommentAt: function(index) {
+ return this._comments[index];
+ },
+
+ /**
+ * Retrieves a style hint specific to a particular index.
+ * @param index the index of the style hint requested
+ * @return the style hint at the specified index
+ */
+ getStyleAt: function(index) {
+ if (!this._comments[index])
+ return null; // not a category label, so no special styling
+
+ if (index == 0)
+ return "suggestfirst"; // category label on first line of results
+
+ return "suggesthint"; // category label on any other line of results
+ },
+
+ /**
+ * Retrieves an image url.
+ * @param index the index of the image url requested
+ * @return the image url at the specified index
+ */
+ getImageAt: function(index) {
+ return "";
+ },
+
+ /**
+ * Removes a result from the resultset
+ * @param index the index of the result to remove
+ */
+ removeValueAt: function(index, removeFromDatabase) {
+ // Forward the removeValueAt call to the underlying result if we have one
+ // Note: this assumes that the form history results were added to the top
+ // of our arrays.
+ if (removeFromDatabase && this._formHistoryResult &&
+ index < this._formHistoryResult.matchCount) {
+ // Delete the history result from the DB
+ this._formHistoryResult.removeValueAt(index, true);
+ }
+ this._results.splice(index, 1);
+ this._comments.splice(index, 1);
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteResult])
+};
+
+/**
+ * SuggestAutoComplete is a base class that implements nsIAutoCompleteSearch
+ * and can collect results for a given search by using the search URL supplied
+ * by the subclass. We do it this way since the AutoCompleteController in
+ * Mozilla requires a unique XPCOM Service for every search provider, even if
+ * the logic for two providers is identical.
+ * @constructor
+ */
+function SuggestAutoComplete() {
+ this._init();
+}
+SuggestAutoComplete.prototype = {
+
+ _init: function() {
+ this._addObservers();
+ this._loadSuggestPref();
+ },
+
+ /**
+ * this._strings is the string bundle for message internationalization.
+ */
+ get _strings() {
+ if (!this.__strings) {
+ var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+
+ this.__strings = sbs.createBundle(SEARCH_BUNDLE);
+ }
+ return this.__strings;
+ },
+ __strings: null,
+
+ /**
+ * Search suggestions will be shown if this._suggestEnabled is true.
+ */
+ _loadSuggestPref: function SAC_loadSuggestPref() {
+ var prefService = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch);
+ this._suggestEnabled = prefService.getBoolPref(BROWSER_SUGGEST_PREF);
+ },
+ _suggestEnabled: null,
+
+ /*************************************************************************
+ * Server request backoff implementation fields below
+ * These allow us to throttle requests if the server is getting hammered.
+ **************************************************************************/
+
+ /**
+ * This is an array that contains the timestamps (in unixtime) of
+ * the last few backoff-triggering errors.
+ */
+ _serverErrorLog: [],
+
+ /**
+ * If we receive this number of backoff errors within the amount of time
+ * specified by _serverErrorPeriod, then we initiate backoff.
+ */
+ _maxErrorsBeforeBackoff: 3,
+
+ /**
+ * If we receive enough consecutive errors (where "enough" is defined by
+ * _maxErrorsBeforeBackoff above) within this time period,
+ * we trigger the backoff behavior.
+ */
+ _serverErrorPeriod: 600000, // 10 minutes in milliseconds
+
+ /**
+ * If we get another backoff error immediately after timeout, we increase the
+ * backoff to (2 x old period) + this value.
+ */
+ _serverErrorTimeoutIncrement: 600000, // 10 minutes in milliseconds
+
+ /**
+ * The current amount of time to wait before trying a server request
+ * after receiving a backoff error.
+ */
+ _serverErrorTimeout: 0,
+
+ /**
+ * Time (in unixtime) after which we're allowed to try requesting again.
+ */
+ _nextRequestTime: 0,
+
+ /**
+ * The last engine we requested against (so that we can tell if the
+ * user switched engines).
+ */
+ _serverErrorEngine: null,
+
+ /**
+ * The XMLHttpRequest object.
+ * @private
+ */
+ _request: null,
+
+ /**
+ * The object implementing nsIAutoCompleteObserver that we notify when
+ * we have found results
+ * @private
+ */
+ _listener: null,
+
+ /**
+ * If this is true, we'll integrate form history results with the
+ * suggest results.
+ */
+ _includeFormHistory: true,
+
+ /**
+ * True if a request for remote suggestions was sent. This is used to
+ * differentiate between the "_request is null because the request has
+ * already returned a result" and "_request is null because no request was
+ * sent" cases.
+ */
+ _sentSuggestRequest: false,
+
+ /**
+ * This is the callback for the suggest timeout timer.
+ */
+ notify: function SAC_notify(timer) {
+ // FIXME: bug 387341
+ // Need to break the cycle between us and the timer.
+ this._formHistoryTimer = null;
+
+ // If this._listener is null, we've already sent out suggest results, so
+ // nothing left to do here.
+ if (!this._listener)
+ return;
+
+ // Otherwise, the XMLHTTPRequest for suggest results is taking too long,
+ // so send out the form history results and cancel the request.
+ this._listener.onSearchResult(this, this._formHistoryResult);
+ this._reset();
+ },
+
+ /**
+ * This determines how long (in ms) we should wait before giving up on
+ * the suggestions and just showing local form history results.
+ */
+ _suggestionTimeout: 500,
+
+ /**
+ * This is the callback for that the form history service uses to
+ * send us results.
+ */
+ onSearchResult: function SAC_onSearchResult(search, result) {
+ this._formHistoryResult = result;
+
+ if (this._request) {
+ // We still have a pending request, wait a bit to give it a chance to
+ // finish.
+ this._formHistoryTimer = Cc["@mozilla.org/timer;1"].
+ createInstance(Ci.nsITimer);
+ this._formHistoryTimer.initWithCallback(this, this._suggestionTimeout,
+ Ci.nsITimer.TYPE_ONE_SHOT);
+ } else if (!this._sentSuggestRequest) {
+ // We didn't send a request, so just send back the form history results.
+ this._listener.onSearchResult(this, this._formHistoryResult);
+ this._reset();
+ }
+ },
+
+ /**
+ * This is the URI that the last suggest request was sent to.
+ */
+ _suggestURI: null,
+
+ /**
+ * Autocomplete results from the form history service get stored here.
+ */
+ _formHistoryResult: null,
+
+ /**
+ * This holds the suggest server timeout timer, if applicable.
+ */
+ _formHistoryTimer: null,
+
+ /**
+ * This clears all the per-request state.
+ */
+ _reset: function SAC_reset() {
+ // Don't let go of our listener and form history result if the timer is
+ // still pending, the timer will call _reset() when it fires.
+ if (!this._formHistoryTimer) {
+ this._listener = null;
+ this._formHistoryResult = null;
+ }
+ this._request = null;
+ },
+
+ /**
+ * This sends an autocompletion request to the form history service,
+ * which will call onSearchResults with the results of the query.
+ */
+ _startHistorySearch: function SAC_SHSearch(searchString, searchParam, previousResult) {
+ var formHistory =
+ Cc["@mozilla.org/autocomplete/search;1?name=form-history"].
+ createInstance(Ci.nsIAutoCompleteSearch);
+ formHistory.startSearch(searchString, searchParam, previousResult, this);
+ },
+
+ /**
+ * Makes a note of the fact that we've received a backoff-triggering
+ * response, so that we can adjust the backoff behavior appropriately.
+ */
+ _noteServerError: function SAC__noteServeError() {
+ var currentTime = Date.now();
+
+ this._serverErrorLog.push(currentTime);
+ if (this._serverErrorLog.length > this._maxErrorsBeforeBackoff)
+ this._serverErrorLog.shift();
+
+ if ((this._serverErrorLog.length == this._maxErrorsBeforeBackoff) &&
+ ((currentTime - this._serverErrorLog[0]) < this._serverErrorPeriod)) {
+ // increase timeout, and then don't request until timeout is over
+ this._serverErrorTimeout = (this._serverErrorTimeout * 2) +
+ this._serverErrorTimeoutIncrement;
+ this._nextRequestTime = currentTime + this._serverErrorTimeout;
+ }
+ },
+
+ /**
+ * Resets the backoff behavior; called when we get a successful response.
+ */
+ _clearServerErrors: function SAC__clearServerErrors() {
+ this._serverErrorLog = [];
+ this._serverErrorTimeout = 0;
+ this._nextRequestTime = 0;
+ },
+
+ /**
+ * This checks whether we should send a server request (i.e. we're not
+ * in a error-triggered backoff period.
+ *
+ * @private
+ */
+ _okToRequest: function SAC__okToRequest() {
+ return Date.now() > this._nextRequestTime;
+ },
+
+ /**
+ * This checks to see if the new search engine is different
+ * from the previous one, and if so clears any error state that might
+ * have accumulated for the old engine.
+ *
+ * @param engine The engine that the suggestion request would be sent to.
+ * @private
+ */
+ _checkForEngineSwitch: function SAC__checkForEngineSwitch(engine) {
+ if (engine == this._serverErrorEngine)
+ return;
+
+ // must've switched search providers, clear old errors
+ this._serverErrorEngine = engine;
+ this._clearServerErrors();
+ },
+
+ /**
+ * This returns true if the status code of the HTTP response
+ * represents a backoff-triggering error.
+ *
+ * @param status The status code from the HTTP response
+ * @private
+ */
+ _isBackoffError: function SAC__isBackoffError(status) {
+ return ((status == HTTP_INTERNAL_SERVER_ERROR) ||
+ (status == HTTP_BAD_GATEWAY) ||
+ (status == HTTP_SERVICE_UNAVAILABLE));
+ },
+
+ /**
+ * Called when the 'readyState' of the XMLHttpRequest changes. We only care
+ * about state 4 (COMPLETED) - handle the response data.
+ * @private
+ */
+ onReadyStateChange: function() {
+ // xxx use the real const here
+ if (!this._request || this._request.readyState != 4)
+ return;
+
+ try {
+ var status = this._request.status;
+ } catch (e) {
+ // The XML HttpRequest can throw NS_ERROR_NOT_AVAILABLE.
+ return;
+ }
+
+ if (this._isBackoffError(status)) {
+ this._noteServerError();
+ return;
+ }
+
+ var responseText = this._request.responseText;
+ if (status != HTTP_OK || responseText == "")
+ return;
+
+ this._clearServerErrors();
+
+ var serverResults = JSON.parse(responseText);
+ var searchString = serverResults[0] || "";
+ var results = serverResults[1] || [];
+
+ var comments = []; // "comments" column values for suggestions
+ var historyResults = [];
+ var historyComments = [];
+
+ // If form history is enabled and has results, add them to the list.
+ if (this._includeFormHistory && this._formHistoryResult &&
+ (this._formHistoryResult.searchResult ==
+ Ci.nsIAutoCompleteResult.RESULT_SUCCESS)) {
+ for (var i = 0; i < this._formHistoryResult.matchCount; ++i) {
+ var term = this._formHistoryResult.getValueAt(i);
+
+ // we don't want things to appear in both history and suggestions
+ var dupIndex = results.indexOf(term);
+ if (dupIndex != -1)
+ results.splice(dupIndex, 1);
+
+ historyResults.push(term);
+ historyComments.push("");
+ }
+ }
+
+ // fill out the comment column for the suggestions
+ for (var i = 0; i < results.length; ++i)
+ comments.push("");
+
+ // if we have any suggestions, put a label at the top
+ if (comments.length > 0)
+ comments[0] = this._strings.GetStringFromName("suggestion_label");
+
+ // now put the history results above the suggestions
+ var finalResults = historyResults.concat(results);
+ var finalComments = historyComments.concat(comments);
+
+ // Notify the FE of our new results
+ this.onResultsReady(searchString, finalResults, finalComments,
+ this._formHistoryResult);
+
+ // Reset our state for next time.
+ this._reset();
+ },
+
+ /**
+ * Notifies the front end of new results.
+ * @param searchString the user's query string
+ * @param results an array of results to the search
+ * @param comments an array of metadata corresponding to the results
+ * @private
+ */
+ onResultsReady: function(searchString, results, comments,
+ formHistoryResult) {
+ if (this._listener) {
+ var result = new SuggestAutoCompleteResult(
+ searchString,
+ Ci.nsIAutoCompleteResult.RESULT_SUCCESS,
+ 0,
+ "",
+ results,
+ comments,
+ formHistoryResult);
+
+ this._listener.onSearchResult(this, result);
+
+ // Null out listener to make sure we don't notify it twice, in case our
+ // timer callback still hasn't run.
+ this._listener = null;
+ }
+ },
+
+ /**
+ * Initiates the search result gathering process. Part of
+ * nsIAutoCompleteSearch implementation.
+ *
+ * @param searchString the user's query string
+ * @param searchParam unused, "an extra parameter"; even though
+ * this parameter and the next are unused, pass
+ * them through in case the form history
+ * service wants them
+ * @param previousResult unused, a client-cached store of the previous
+ * generated resultset for faster searching.
+ * @param listener object implementing nsIAutoCompleteObserver which
+ * we notify when results are ready.
+ */
+ startSearch: function(searchString, searchParam, previousResult, listener) {
+ var searchService = Cc["@mozilla.org/browser/search-service;1"].
+ getService(Ci.nsIBrowserSearchService);
+
+ // If there's an existing request, stop it. There is no smart filtering
+ // here as there is when looking through history/form data because the
+ // result set returned by the server is different for every typed value -
+ // "ocean breathes" does not return a subset of the results returned for
+ // "ocean", for example. This does nothing if there is no current request.
+ this.stopSearch();
+
+ this._listener = listener;
+
+ var engine = searchService.currentEngine;
+
+ this._checkForEngineSwitch(engine);
+
+ if (!searchString ||
+ !this._suggestEnabled ||
+ !engine.supportsResponseType(SEARCH_RESPONSE_SUGGESTION_JSON) ||
+ !this._okToRequest()) {
+ // We have an empty search string (user pressed down arrow to see
+ // history), or search suggestions are disabled, or the current engine
+ // has no suggest functionality, or we're in backoff mode; so just use
+ // local history.
+ this._sentSuggestRequest = false;
+ this._startHistorySearch(searchString, searchParam, previousResult);
+ return;
+ }
+
+ // Actually do the search
+ this._request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ var submission = engine.getSubmission(searchString,
+ SEARCH_RESPONSE_SUGGESTION_JSON);
+ this._suggestURI = submission.uri;
+ var method = (submission.postData ? "POST" : "GET");
+ this._request.open(method, this._suggestURI.spec, true);
+ this._request.channel.notificationCallbacks = new SearchSuggestLoadListener();
+
+ var self = this;
+ function onReadyStateChange() {
+ self.onReadyStateChange();
+ }
+ this._request.onreadystatechange = onReadyStateChange;
+ this._request.send(submission.postData);
+
+ if (this._includeFormHistory) {
+ this._sentSuggestRequest = true;
+ this._startHistorySearch(searchString, searchParam, previousResult);
+ }
+ },
+
+ /**
+ * Ends the search result gathering process. Part of nsIAutoCompleteSearch
+ * implementation.
+ */
+ stopSearch: function() {
+ if (this._request) {
+ this._request.abort();
+ this._reset();
+ }
+ },
+
+ /**
+ * nsIObserver
+ */
+ observe: function SAC_observe(aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
+ this._loadSuggestPref();
+ break;
+ case XPCOM_SHUTDOWN_TOPIC:
+ this._removeObservers();
+ break;
+ }
+ },
+
+ _addObservers: function SAC_addObservers() {
+ var prefService2 = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+ prefService2.addObserver(BROWSER_SUGGEST_PREF, this, false);
+
+ var os = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ os.addObserver(this, XPCOM_SHUTDOWN_TOPIC, false);
+ },
+
+ _removeObservers: function SAC_removeObservers() {
+ var prefService2 = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+ prefService2.removeObserver(BROWSER_SUGGEST_PREF, this);
+
+ var os = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ os.removeObserver(this, XPCOM_SHUTDOWN_TOPIC);
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteSearch,
+ Ci.nsIAutoCompleteObserver])
+};
+
+function SearchSuggestLoadListener() {
+}
+SearchSuggestLoadListener.prototype = {
+ // nsIBadCertListener2
+ notifyCertProblem: function SSLL_certProblem(socketInfo, status, targetSite) {
+ return true;
+ },
+
+ // nsISSLErrorListener
+ notifySSLError: function SSLL_SSLError(socketInfo, error, targetSite) {
+ return true;
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function SSLL_getInterface(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIBadCertListener2,
+ Ci.nsISSLErrorListener,
+ Ci.nsIInterfaceRequestor])
+};
+
+/**
+ * SearchSuggestAutoComplete is a service implementation that handles suggest
+ * results specific to web searches.
+ * @constructor
+ */
+function SearchSuggestAutoComplete() {
+ // This calls _init() in the parent class (SuggestAutoComplete) via the
+ // prototype, below.
+ this._init();
+}
+SearchSuggestAutoComplete.prototype = {
+ classDescription: "Remote Search Suggestions",
+ contractID: "@mozilla.org/autocomplete/search;1?name=search-autocomplete",
+ classID: Components.ID("{aa892eb4-ffbf-477d-9f9a-06c995ae9f27}"),
+ __proto__: SuggestAutoComplete.prototype,
+ serviceURL: ""
+};
+
+var component = [SearchSuggestAutoComplete];
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(component);
+}
diff --git a/bundles/XO/components/nsSessionStartup.js b/bundles/XO/components/nsSessionStartup.js
new file mode 100755
index 0000000..78ab3ce
--- /dev/null
+++ b/bundles/XO/components/nsSessionStartup.js
@@ -0,0 +1,262 @@
+/*
+//@line 38 "/builds/moz2_slave/linux_build/build/browser/components/sessionstore/src/nsSessionStartup.js"
+*/
+
+/**
+//@line 65 "/builds/moz2_slave/linux_build/build/browser/components/sessionstore/src/nsSessionStartup.js"
+*/
+
+/* :::::::: Constants and Helpers ::::::::::::::: */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const STATE_RUNNING_STR = "running";
+
+function debug(aMsg) {
+ aMsg = ("SessionStartup: " + aMsg).replace(/\S{80}/g, "$&\n");
+ Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
+ .logStringMessage(aMsg);
+}
+
+/* :::::::: The Service ::::::::::::::: */
+
+function SessionStartup() {
+}
+
+SessionStartup.prototype = {
+
+ // the state to restore at startup
+ _iniString: null,
+ _sessionType: Ci.nsISessionStartup.NO_SESSION,
+
+/* ........ Global Event Handlers .............. */
+
+ /**
+ * Initialize the component
+ */
+ init: function sss_init() {
+ // do not need to initialize anything in auto-started private browsing sessions
+ let pbs = Cc["@mozilla.org/privatebrowsing;1"].
+ getService(Ci.nsIPrivateBrowsingService);
+ if (pbs.autoStarted)
+ return;
+
+ let prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).getBranch("browser.");
+
+ // get file references
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ let sessionFile = dirService.get("ProfD", Ci.nsILocalFile);
+ sessionFile.append("sessionstore.js");
+
+ let doResumeSession = prefBranch.getBoolPref("sessionstore.resume_session_once") ||
+ prefBranch.getIntPref("startup.page") == 3;
+
+ // only read the session file if config allows possibility of restoring
+ var resumeFromCrash = prefBranch.getBoolPref("sessionstore.resume_from_crash");
+ if (!resumeFromCrash && !doResumeSession || !sessionFile.exists())
+ return;
+
+ // get string containing session state
+ this._iniString = this._readStateFile(sessionFile);
+ if (!this._iniString)
+ return;
+
+ try {
+ // parse the session state into JS objects
+ var s = new Components.utils.Sandbox("about:blank");
+ var initialState = Components.utils.evalInSandbox("(" + this._iniString + ")", s);
+ }
+ catch (ex) { debug("The session file is invalid: " + ex); }
+
+ let lastSessionCrashed =
+ initialState && initialState.session && initialState.session.state &&
+ initialState.session.state == STATE_RUNNING_STR;
+
+ // set the startup type
+ if (lastSessionCrashed && resumeFromCrash)
+ this._sessionType = Ci.nsISessionStartup.RECOVER_SESSION;
+ else if (!lastSessionCrashed && doResumeSession)
+ this._sessionType = Ci.nsISessionStartup.RESUME_SESSION;
+ else
+ this._iniString = null; // reset the state string
+
+ if (this._sessionType != Ci.nsISessionStartup.NO_SESSION) {
+ // wait for the first browser window to open
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ observerService.addObserver(this, "domwindowopened", true);
+ observerService.addObserver(this, "browser:purge-session-history", true);
+ }
+ },
+
+ /**
+ * Handle notifications
+ */
+ observe: function sss_observe(aSubject, aTopic, aData) {
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+
+ switch (aTopic) {
+ case "app-startup":
+ observerService.addObserver(this, "final-ui-startup", true);
+ observerService.addObserver(this, "quit-application", true);
+ break;
+ case "final-ui-startup":
+ observerService.removeObserver(this, "final-ui-startup");
+ observerService.removeObserver(this, "quit-application");
+ this.init();
+ break;
+ case "quit-application":
+ // no reason for initializing at this point (cf. bug 409115)
+ observerService.removeObserver(this, "final-ui-startup");
+ observerService.removeObserver(this, "quit-application");
+ break;
+ case "domwindowopened":
+ var window = aSubject;
+ var self = this;
+ window.addEventListener("load", function() {
+ self._onWindowOpened(window);
+ window.removeEventListener("load", arguments.callee, false);
+ }, false);
+ break;
+ case "browser:purge-session-history":
+ // reset all state on sanitization
+ this._iniString = null;
+ this._sessionType = Ci.nsISessionStartup.NO_SESSION;
+ // no need in repeating this, since startup state won't change
+ observerService.removeObserver(this, "browser:purge-session-history");
+ break;
+ }
+ },
+
+ /**
+ * Removes the default arguments from the first browser window
+ * (and removes the "domwindowopened" observer afterwards).
+ */
+ _onWindowOpened: function sss_onWindowOpened(aWindow) {
+ var wType = aWindow.document.documentElement.getAttribute("windowtype");
+ if (wType != "navigator:browser")
+ return;
+
+ /**
+ * Note: this relies on the fact that nsBrowserContentHandler will return
+ * a different value the first time its getter is called after an update,
+ * due to its needHomePageOverride() logic. We don't want to remove the
+ * default arguments in the update case, since they include the "What's
+ * New" page.
+ *
+ * Since we're garanteed to be at least the second caller of defaultArgs
+ * (nsBrowserContentHandler calls it to determine which arguments to pass
+ * at startup), we know that if the window's arguments don't match the
+ * current defaultArguments, we're either in the update case, or we're
+ * launching a non-default browser window, so we shouldn't remove the
+ * window's arguments.
+ */
+ var defaultArgs = Cc["@mozilla.org/browser/clh;1"].
+ getService(Ci.nsIBrowserHandler).defaultArgs;
+ if (aWindow.arguments && aWindow.arguments[0] &&
+ aWindow.arguments[0] == defaultArgs)
+ aWindow.arguments[0] = null;
+
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ observerService.removeObserver(this, "domwindowopened");
+ },
+
+/* ........ Public API ................*/
+
+ /**
+ * Get the session state as a string
+ */
+ get state() {
+ return this._iniString;
+ },
+
+ /**
+ * Determine whether there is a pending session restore.
+ * @returns bool
+ */
+ doRestore: function sss_doRestore() {
+ return this._sessionType != Ci.nsISessionStartup.NO_SESSION;
+ },
+
+ /**
+ * Get the type of pending session store, if any.
+ */
+ get sessionType() {
+ return this._sessionType;
+ },
+
+/* ........ Storage API .............. */
+
+ /**
+ * Reads a session state file into a string and lets
+ * observers modify the state before it's being used
+ *
+ * @param aFile is any nsIFile
+ * @returns a session state string
+ */
+ _readStateFile: function sss_readStateFile(aFile) {
+ var stateString = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ stateString.data = this._readFile(aFile) || "";
+
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ observerService.notifyObservers(stateString, "sessionstore-state-read", "");
+
+ return stateString.data;
+ },
+
+ /**
+ * reads a file into a string
+ * @param aFile
+ * nsIFile
+ * @returns string
+ */
+ _readFile: function sss_readFile(aFile) {
+ try {
+ var stream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ stream.init(aFile, 0x01, 0, 0);
+ var cvstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
+ createInstance(Ci.nsIConverterInputStream);
+ cvstream.init(stream, "UTF-8", 1024, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ var content = "";
+ var data = {};
+ while (cvstream.readString(4096, data)) {
+ content += data.value;
+ }
+ cvstream.close();
+
+ return content.replace(/\r\n?/g, "\n");
+ }
+ catch (ex) { Components.utils.reportError(ex); }
+
+ return null;
+ },
+
+ /* ........ QueryInterface .............. */
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsISupportsWeakReference,
+ Ci.nsISessionStartup]),
+ classDescription: "Browser Session Startup Service",
+ classID: Components.ID("{ec7a6c20-e081-11da-8ad9-0800200c9a66}"),
+ contractID: "@mozilla.org/browser/sessionstartup;1",
+
+ // get this contractID registered for certain categories via XPCOMUtils
+ _xpcom_categories: [
+ // make ourselves a startup observer
+ { category: "app-startup", service: true }
+ ]
+
+};
+
+function NSGetModule(aCompMgr, aFileSpec)
+ XPCOMUtils.generateModule([SessionStartup]);
diff --git a/bundles/XO/components/nsSessionStore.js b/bundles/XO/components/nsSessionStore.js
new file mode 100755
index 0000000..d7446cb
--- /dev/null
+++ b/bundles/XO/components/nsSessionStore.js
@@ -0,0 +1,2918 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the nsSessionStore component.
+ *
+ * The Initial Developer of the Original Code is
+ * Simon BĂĽnzli <zeniko@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dietrich Ayala <dietrich@mozilla.com>
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>
+ * Paul O’Shannessy <paul@oshannessy.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Session Storage and Restoration
+ *
+ * Overview
+ * This service keeps track of a user's session, storing the various bits
+ * required to return the browser to its current state. The relevant data is
+ * stored in memory, and is periodically saved to disk in a file in the
+ * profile directory. The service is started at first window load, in
+ * delayedStartup, and will restore the session from the data received from
+ * the nsSessionStartup service.
+ */
+
+/* :::::::: Constants and Helpers ::::::::::::::: */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+const STATE_STOPPED = 0;
+const STATE_RUNNING = 1;
+const STATE_QUITTING = -1;
+
+const STATE_STOPPED_STR = "stopped";
+const STATE_RUNNING_STR = "running";
+
+const PRIVACY_NONE = 0;
+const PRIVACY_ENCRYPTED = 1;
+const PRIVACY_FULL = 2;
+
+const NOTIFY_WINDOWS_RESTORED = "sessionstore-windows-restored";
+
+const INTERFACES = [Ci.nsISessionStore, Ci.nsIDOMEventListener,
+ Ci.nsIObserver, Ci.nsISupportsWeakReference,
+ Ci.nsISessionStore_MOZILLA_1_9_1, Ci.nsIClassInfo];
+
+// global notifications observed
+const OBSERVING = [
+ "domwindowopened", "domwindowclosed",
+ "quit-application-requested", "quit-application-granted",
+ "quit-application", "browser:purge-session-history",
+ "private-browsing", "browser:purge-domain-data",
+ "private-browsing-change-granted"
+];
+
+/*
+XUL Window properties to (re)store
+Restored in restoreDimensions()
+*/
+const WINDOW_ATTRIBUTES = ["width", "height", "screenX", "screenY", "sizemode"];
+
+/*
+Hideable window features to (re)store
+Restored in restoreWindowFeatures()
+*/
+const WINDOW_HIDEABLE_FEATURES = [
+ "menubar", "toolbar", "locationbar",
+ "personalbar", "statusbar", "scrollbars"
+];
+
+/*
+docShell capabilities to (re)store
+Restored in restoreHistory()
+eg: browser.docShell["allow" + aCapability] = false;
+*/
+const CAPABILITIES = [
+ "Subframes", "Plugins", "Javascript", "MetaRedirects", "Images"
+];
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function debug(aMsg) {
+ aMsg = ("SessionStore: " + aMsg).replace(/\S{80}/g, "$&\n");
+ Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
+ .logStringMessage(aMsg);
+}
+
+/* :::::::: The Service ::::::::::::::: */
+
+function SessionStoreService() {
+}
+
+SessionStoreService.prototype = {
+ classDescription: "Browser Session Store Service",
+ contractID: "@mozilla.org/browser/sessionstore;1",
+ classID: Components.ID("{5280606b-2510-4fe0-97ef-9b5a22eafe6b}"),
+ QueryInterface: XPCOMUtils.generateQI(INTERFACES),
+
+ // extra requirements for nsIClassInfo
+ getInterfaces: function sss_getInterfaces(aCountRef) {
+ aCountRef.value = INTERFACES.length;
+ return INTERFACES;
+ },
+ getHelperForLanguage: function sss_getHelperForLanguage (aLanguage) null,
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ flags: Ci.nsIClassInfo.SINGLETON,
+
+ // xul:tab attributes to (re)store (extensions might want to hook in here);
+ // the favicon is always saved for the about:sessionrestore page
+ xulAttributes: ["image"],
+
+ // set default load state
+ _loadState: STATE_STOPPED,
+
+ // minimal interval between two save operations (in milliseconds)
+ _interval: 10000,
+
+ // when crash recovery is disabled, session data is not written to disk
+ _resume_from_crash: true,
+
+ // During the initial restore tracks the number of windows yet to be restored
+ _restoreCount: 0,
+
+ // time in milliseconds (Date.now()) when the session was last written to file
+ _lastSaveTime: 0,
+
+ // states for all currently opened windows
+ _windows: {},
+
+ // states for all recently closed windows
+ _closedWindows: [],
+
+ // not-"dirty" windows usually don't need to have their data updated
+ _dirtyWindows: {},
+
+ // collection of session states yet to be restored
+ _statesToRestore: {},
+
+ // counts the number of crashes since the last clean start
+ _recentCrashes: 0,
+
+ // whether we are in private browsing mode
+ _inPrivateBrowsing: false,
+
+ // whether we clearing history on shutdown
+ _clearingOnShutdown: false,
+
+/* ........ Global Event Handlers .............. */
+
+ /**
+ * Initialize the component
+ */
+ init: function sss_init(aWindow) {
+ if (!aWindow || this._loadState == STATE_RUNNING) {
+ // make sure that all browser windows which try to initialize
+ // SessionStore are really tracked by it
+ if (aWindow && (!aWindow.__SSi || !this._windows[aWindow.__SSi]))
+ this.onLoad(aWindow);
+ return;
+ }
+
+ this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService).getBranch("browser.");
+ this._prefBranch.QueryInterface(Ci.nsIPrefBranch2);
+
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+
+ OBSERVING.forEach(function(aTopic) {
+ observerService.addObserver(this, aTopic, true);
+ }, this);
+
+ var pbs = Cc["@mozilla.org/privatebrowsing;1"].
+ getService(Ci.nsIPrivateBrowsingService);
+ this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
+
+ // get interval from prefs - used often, so caching/observing instead of fetching on-demand
+ this._interval = this._prefBranch.getIntPref("sessionstore.interval");
+ this._prefBranch.addObserver("sessionstore.interval", this, true);
+
+ // get crash recovery state from prefs and allow for proper reaction to state changes
+ this._resume_from_crash = this._prefBranch.getBoolPref("sessionstore.resume_from_crash");
+ this._prefBranch.addObserver("sessionstore.resume_from_crash", this, true);
+
+ // observe prefs changes so we can modify stored data to match
+ this._prefBranch.addObserver("sessionstore.max_tabs_undo", this, true);
+ this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
+
+ // this pref is only read at startup, so no need to observe it
+ this._sessionhistory_max_entries =
+ this._prefBranch.getIntPref("sessionhistory.max_entries");
+
+ // get file references
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ this._sessionFile = dirService.get("ProfD", Ci.nsILocalFile);
+ this._sessionFileBackup = this._sessionFile.clone();
+ this._sessionFile.append("sessionstore.js");
+ this._sessionFileBackup.append("sessionstore.bak");
+
+ // get string containing session state
+ var iniString;
+ try {
+ var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
+ getService(Ci.nsISessionStartup);
+ if (ss.doRestore())
+ iniString = ss.state;
+ }
+ catch(ex) { dump(ex + "\n"); } // no state to restore, which is ok
+
+ if (iniString) {
+ try {
+ // parse the session state into JS objects
+ this._initialState = this._safeEval("(" + iniString + ")");
+
+ let lastSessionCrashed =
+ this._initialState.session && this._initialState.session.state &&
+ this._initialState.session.state == STATE_RUNNING_STR;
+ if (lastSessionCrashed) {
+ this._recentCrashes = (this._initialState.session &&
+ this._initialState.session.recentCrashes || 0) + 1;
+
+ if (this._needsRestorePage(this._initialState, this._recentCrashes)) {
+ // replace the crashed session with a restore-page-only session
+ let pageData = {
+ url: "about:sessionrestore",
+ formdata: { "#sessionData": iniString }
+ };
+ this._initialState = { windows: [{ tabs: [{ entries: [pageData] }] }] };
+ }
+ }
+
+ // make sure that at least the first window doesn't have anything hidden
+ delete this._initialState.windows[0].hidden;
+ }
+ catch (ex) { debug("The session file is invalid: " + ex); }
+ }
+
+ // remove the session data files if crash recovery is disabled
+ if (!this._resume_from_crash)
+ this._clearDisk();
+ else { // create a backup if the session data file exists
+ try {
+ if (this._sessionFileBackup.exists())
+ this._sessionFileBackup.remove(false);
+ if (this._sessionFile.exists())
+ this._sessionFile.copyTo(null, this._sessionFileBackup.leafName);
+ }
+ catch (ex) { Cu.reportError(ex); } // file was write-locked?
+ }
+
+ // at this point, we've as good as resumed the session, so we can
+ // clear the resume_session_once flag, if it's set
+ if (this._loadState != STATE_QUITTING &&
+ this._prefBranch.getBoolPref("sessionstore.resume_session_once"))
+ this._prefBranch.setBoolPref("sessionstore.resume_session_once", false);
+
+ // As this is called at delayedStartup, restoration must be initiated here
+ this.onLoad(aWindow);
+ },
+
+ /**
+ * Called on application shutdown, after notifications:
+ * quit-application-granted, quit-application
+ */
+ _uninit: function sss_uninit() {
+ if (this._doResumeSession()) { // save all data for session resuming
+ this.saveState(true);
+ }
+ else { // discard all session related data
+ this._clearDisk();
+ }
+ // Make sure to break our cycle with the save timer
+ if (this._saveTimer) {
+ this._saveTimer.cancel();
+ this._saveTimer = null;
+ }
+ },
+
+ /**
+ * Handle notifications
+ */
+ observe: function sss_observe(aSubject, aTopic, aData) {
+ // for event listeners
+ var _this = this;
+
+ switch (aTopic) {
+ case "domwindowopened": // catch new windows
+ aSubject.addEventListener("load", function(aEvent) {
+ aEvent.currentTarget.removeEventListener("load", arguments.callee, false);
+ _this.onLoad(aEvent.currentTarget);
+ }, false);
+ break;
+ case "domwindowclosed": // catch closed windows
+ this.onClose(aSubject);
+ break;
+ case "quit-application-requested":
+ // get a current snapshot of all windows
+ this._forEachBrowserWindow(function(aWindow) {
+ this._collectWindowData(aWindow);
+ });
+ this._dirtyWindows = [];
+ break;
+ case "quit-application-granted":
+ // freeze the data at what we've got (ignoring closing windows)
+ this._loadState = STATE_QUITTING;
+ break;
+ case "quit-application":
+ if (aData == "restart") {
+ this._prefBranch.setBoolPref("sessionstore.resume_session_once", true);
+ this._clearingOnShutdown = false;
+ }
+ this._loadState = STATE_QUITTING; // just to be sure
+ this._uninit();
+ break;
+ case "browser:purge-session-history": // catch sanitization
+ let openWindows = {};
+ this._forEachBrowserWindow(function(aWindow) {
+ Array.forEach(aWindow.getBrowser().browsers, function(aBrowser) {
+ delete aBrowser.parentNode.__SS_data;
+ });
+ openWindows[aWindow.__SSi] = true;
+ });
+ // also clear all data about closed tabs and windows
+ for (let ix in this._windows) {
+ if (ix in openWindows)
+ this._windows[ix]._closedTabs = [];
+ else
+ delete this._windows[ix];
+ }
+ // also clear all data about closed windows
+ this._closedWindows = [];
+ this._clearDisk();
+ // give the tabbrowsers a chance to clear their histories first
+ var win = this._getMostRecentBrowserWindow();
+ if (win)
+ win.setTimeout(function() { _this.saveState(true); }, 0);
+ else if (this._loadState == STATE_RUNNING)
+ this.saveState(true);
+ // Delete the private browsing backed up state, if any
+ if ("_stateBackup" in this)
+ delete this._stateBackup;
+ if (this._loadState == STATE_QUITTING)
+ this._clearingOnShutdown = true;
+ break;
+ case "browser:purge-domain-data":
+ // does a session history entry contain a url for the given domain?
+ function containsDomain(aEntry) {
+ try {
+ if (this._getURIFromString(aEntry.url).host.hasRootDomain(aData))
+ return true;
+ }
+ catch (ex) { /* url had no host at all */ }
+ return aEntry.children && aEntry.children.some(containsDomain, this);
+ }
+ // remove all closed tabs containing a reference to the given domain
+ for (let ix in this._windows) {
+ let closedTabs = this._windows[ix]._closedTabs;
+ for (let i = closedTabs.length - 1; i >= 0; i--) {
+ if (closedTabs[i].state.entries.some(containsDomain, this))
+ closedTabs.splice(i, 1);
+ }
+ }
+ // remove all open & closed tabs containing a reference to the given
+ // domain in closed windows
+ for (let ix = this._closedWindows.length - 1; ix >= 0; ix--) {
+ let closedTabs = this._closedWindows[ix]._closedTabs;
+ let openTabs = this._closedWindows[ix].tabs;
+ let openTabCount = openTabs.length;
+ for (let i = closedTabs.length - 1; i >= 0; i--)
+ if (closedTabs[i].state.entries.some(containsDomain, this))
+ closedTabs.splice(i, 1);
+ for (let j = openTabs.length - 1; j >= 0; j--) {
+ if (openTabs[j].entries.some(containsDomain, this)) {
+ openTabs.splice(j, 1);
+ if (this._closedWindows[ix].selected > j)
+ this._closedWindows[ix].selected--;
+ }
+ }
+ if (openTabs.length == 0) {
+ this._closedWindows.splice(ix, 1);
+ }
+ else if (openTabs.length != openTabCount) {
+ // Adjust the window's title if we removed an open tab
+ let selectedTab = openTabs[this._closedWindows[ix].selected - 1];
+ // some duplication from restoreHistory - make sure we get the correct title
+ let activeIndex = (selectedTab.index || selectedTab.entries.length) - 1;
+ if (activeIndex >= selectedTab.entries.length)
+ activeIndex = selectedTab.entries.length - 1;
+ this._closedWindows[ix].title = selectedTab.entries[activeIndex].title;
+ }
+ }
+ if (this._loadState == STATE_RUNNING)
+ this.saveState(true);
+ break;
+ case "nsPref:changed": // catch pref changes
+ switch (aData) {
+ // if the user decreases the max number of closed tabs they want
+ // preserved update our internal states to match that max
+ case "sessionstore.max_tabs_undo":
+ for (let ix in this._windows) {
+ this._windows[ix]._closedTabs.splice(this._prefBranch.getIntPref("sessionstore.max_tabs_undo"));
+ }
+ break;
+ case "sessionstore.max_windows_undo":
+ this._capClosedWindows();
+ break;
+ case "sessionstore.interval":
+ this._interval = this._prefBranch.getIntPref("sessionstore.interval");
+ // reset timer and save
+ if (this._saveTimer) {
+ this._saveTimer.cancel();
+ this._saveTimer = null;
+ }
+ this.saveStateDelayed(null, -1);
+ break;
+ case "sessionstore.resume_from_crash":
+ this._resume_from_crash = this._prefBranch.getBoolPref("sessionstore.resume_from_crash");
+ // either create the file with crash recovery information or remove it
+ // (when _loadState is not STATE_RUNNING, that file is used for session resuming instead)
+ if (this._resume_from_crash)
+ this.saveState(true);
+ else if (this._loadState == STATE_RUNNING)
+ this._clearDisk();
+ break;
+ }
+ break;
+ case "timer-callback": // timer call back for delayed saving
+ this._saveTimer = null;
+ this.saveState();
+ break;
+ case "private-browsing":
+ switch (aData) {
+ case "enter":
+ this._inPrivateBrowsing = true;
+ break;
+ case "exit":
+ aSubject.QueryInterface(Ci.nsISupportsPRBool);
+ let quitting = aSubject.data;
+ if (quitting) {
+ // save the backed up state with session set to stopped,
+ // otherwise resuming next time would look like a crash
+ if ("_stateBackup" in this) {
+ var oState = this._stateBackup;
+ oState.session = { state: STATE_STOPPED_STR };
+
+ this._saveStateObject(oState);
+ }
+ // make sure to restore the non-private session upon resuming
+ this._prefBranch.setBoolPref("sessionstore.resume_session_once", true);
+ }
+ else
+ this._inPrivateBrowsing = false;
+ delete this._stateBackup;
+ break;
+ }
+ break;
+ case "private-browsing-change-granted":
+ if (aData == "enter") {
+ this.saveState(true);
+ this._stateBackup = this._safeEval(this._getCurrentState(true).toSource());
+ }
+ break;
+ }
+ },
+
+/* ........ Window Event Handlers .............. */
+
+ /**
+ * Implement nsIDOMEventListener for handling various window and tab events
+ */
+ handleEvent: function sss_handleEvent(aEvent) {
+ switch (aEvent.type) {
+ case "load":
+ case "pageshow":
+ this.onTabLoad(aEvent.currentTarget.ownerDocument.defaultView, aEvent.currentTarget, aEvent);
+ break;
+ case "change":
+ case "input":
+ case "DOMAutoComplete":
+ this.onTabInput(aEvent.currentTarget.ownerDocument.defaultView, aEvent.currentTarget);
+ break;
+ case "scroll":
+ this.onTabScroll(aEvent.currentTarget.ownerDocument.defaultView);
+ break;
+ case "TabOpen":
+ case "TabClose":
+ var panelID = aEvent.originalTarget.linkedPanel;
+ var tabpanel = aEvent.originalTarget.ownerDocument.getElementById(panelID);
+ if (aEvent.type == "TabOpen") {
+ this.onTabAdd(aEvent.currentTarget.ownerDocument.defaultView, tabpanel);
+ }
+ else {
+ // aEvent.detail determines if the tab was closed by moving to a different window
+ if (!aEvent.detail)
+ this.onTabClose(aEvent.currentTarget.ownerDocument.defaultView, aEvent.originalTarget);
+ this.onTabRemove(aEvent.currentTarget.ownerDocument.defaultView, tabpanel);
+ }
+ break;
+ case "TabSelect":
+ var tabpanels = aEvent.currentTarget.mPanelContainer;
+ this.onTabSelect(aEvent.currentTarget.ownerDocument.defaultView, tabpanels);
+ break;
+ }
+ },
+
+ /**
+ * If it's the first window load since app start...
+ * - determine if we're reloading after a crash or a forced-restart
+ * - restore window state
+ * - restart downloads
+ * Set up event listeners for this window's tabs
+ * @param aWindow
+ * Window reference
+ */
+ onLoad: function sss_onLoad(aWindow) {
+ // return if window has already been initialized
+ if (aWindow && aWindow.__SSi && this._windows[aWindow.__SSi])
+ return;
+
+ // ignore non-browser windows and windows opened while shutting down
+ if (aWindow.document.documentElement.getAttribute("windowtype") != "navigator:browser" ||
+ this._loadState == STATE_QUITTING)
+ return;
+
+ // assign it a unique identifier (timestamp)
+ aWindow.__SSi = "window" + Date.now();
+
+ // and create its data object
+ this._windows[aWindow.__SSi] = { tabs: [], selected: 0, _closedTabs: [] };
+ if (!aWindow.toolbar.visible)
+ this._windows[aWindow.__SSi].isPopup = true;
+
+ // perform additional initialization when the first window is loading
+ if (this._loadState == STATE_STOPPED) {
+ this._loadState = STATE_RUNNING;
+ this._lastSaveTime = Date.now();
+
+ // restore a crashed session resp. resume the last session if requested
+ if (this._initialState) {
+ // make sure that the restored tabs are first in the window
+ this._initialState._firstTabs = true;
+ this._restoreCount = this._initialState.windows ? this._initialState.windows.length : 0;
+ this.restoreWindow(aWindow, this._initialState, this._isCmdLineEmpty(aWindow));
+ delete this._initialState;
+
+ // mark ourselves as running
+ this.saveState(true);
+ }
+ else {
+ // Nothing to restore, notify observers things are complete.
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ observerService.notifyObservers(null, NOTIFY_WINDOWS_RESTORED, "");
+
+//@line 586 "/builds/moz2_slave/linux_build/build/browser/components/sessionstore/src/nsSessionStore.js"
+ // the next delayed save request should execute immediately
+ this._lastSaveTime -= this._interval;
+//@line 593 "/builds/moz2_slave/linux_build/build/browser/components/sessionstore/src/nsSessionStore.js"
+ }
+ }
+ // this window was opened by _openWindowWithState
+ else if (!this._isWindowLoaded(aWindow)) {
+ let followUp = this._statesToRestore[aWindow.__SS_restoreID].windows.length == 1;
+ this.restoreWindow(aWindow, this._statesToRestore[aWindow.__SS_restoreID], true, followUp);
+ }
+
+ var tabbrowser = aWindow.getBrowser();
+ var tabpanels = tabbrowser.mPanelContainer;
+
+ // add tab change listeners to all already existing tabs
+ for (var i = 0; i < tabpanels.childNodes.length; i++) {
+ this.onTabAdd(aWindow, tabpanels.childNodes[i], true);
+ }
+ // notification of tab add/remove/selection
+ tabbrowser.addEventListener("TabOpen", this, true);
+ tabbrowser.addEventListener("TabClose", this, true);
+ tabbrowser.addEventListener("TabSelect", this, true);
+ },
+
+ /**
+ * On window close...
+ * - remove event listeners from tabs
+ * - save all window data
+ * @param aWindow
+ * Window reference
+ */
+ onClose: function sss_onClose(aWindow) {
+ // this window was about to be restored - conserve its original data, if any
+ let isFullyLoaded = this._isWindowLoaded(aWindow);
+ if (!isFullyLoaded) {
+ if (!aWindow.__SSi)
+ aWindow.__SSi = "window" + Date.now();
+ this._window[aWindow.__SSi] = this._statesToRestore[aWindow.__SS_restoreID];
+ delete this._statesToRestore[aWindow.__SS_restoreID];
+ delete aWindow.__SS_restoreID;
+ }
+
+ // ignore windows not tracked by SessionStore
+ if (!aWindow.__SSi || !this._windows[aWindow.__SSi]) {
+ return;
+ }
+
+ if (this.windowToFocus && this.windowToFocus == aWindow) {
+ delete this.windowToFocus;
+ }
+
+ var tabbrowser = aWindow.getBrowser();
+ var tabpanels = tabbrowser.mPanelContainer;
+
+ tabbrowser.removeEventListener("TabOpen", this, true);
+ tabbrowser.removeEventListener("TabClose", this, true);
+ tabbrowser.removeEventListener("TabSelect", this, true);
+
+ let winData = this._windows[aWindow.__SSi];
+ if (this._loadState == STATE_RUNNING) { // window not closed during a regular shut-down
+ // update all window data for a last time
+ this._collectWindowData(aWindow);
+
+ if (isFullyLoaded) {
+ winData.title = aWindow.content.document.title || tabbrowser.selectedTab.label;
+ winData.title = this._replaceLoadingTitle(winData.title, tabbrowser,
+ tabbrowser.selectedTab);
+ this._updateCookies([winData]);
+ }
+
+ // save the window if it has multiple tabs or a single tab with entries
+ if (winData.tabs.length > 1 ||
+ (winData.tabs.length == 1 && winData.tabs[0].entries.length > 0)) {
+ this._closedWindows.unshift(winData);
+ this._capClosedWindows();
+ }
+
+ // clear this window from the list
+ delete this._windows[aWindow.__SSi];
+
+ // save the state without this window to disk
+ this.saveStateDelayed();
+ }
+
+ for (var i = 0; i < tabpanels.childNodes.length; i++) {
+ this.onTabRemove(aWindow, tabpanels.childNodes[i], true);
+ }
+
+ // cache the window state until the window is completely gone
+ aWindow.__SS_dyingCache = winData;
+
+ delete aWindow.__SSi;
+ },
+
+ /**
+ * set up listeners for a new tab
+ * @param aWindow
+ * Window reference
+ * @param aPanel
+ * TabPanel reference
+ * @param aNoNotification
+ * bool Do not save state if we're updating an existing tab
+ */
+ onTabAdd: function sss_onTabAdd(aWindow, aPanel, aNoNotification) {
+ aPanel.addEventListener("load", this, true);
+ aPanel.addEventListener("pageshow", this, true);
+ aPanel.addEventListener("change", this, true);
+ aPanel.addEventListener("input", this, true);
+ aPanel.addEventListener("DOMAutoComplete", this, true);
+ aPanel.addEventListener("scroll", this, true);
+
+ if (!aNoNotification) {
+ this.saveStateDelayed(aWindow);
+ }
+ },
+
+ /**
+ * remove listeners for a tab
+ * @param aWindow
+ * Window reference
+ * @param aPanel
+ * TabPanel reference
+ * @param aNoNotification
+ * bool Do not save state if we're updating an existing tab
+ */
+ onTabRemove: function sss_onTabRemove(aWindow, aPanel, aNoNotification) {
+ aPanel.removeEventListener("load", this, true);
+ aPanel.removeEventListener("pageshow", this, true);
+ aPanel.removeEventListener("change", this, true);
+ aPanel.removeEventListener("input", this, true);
+ aPanel.removeEventListener("DOMAutoComplete", this, true);
+ aPanel.removeEventListener("scroll", this, true);
+
+ delete aPanel.__SS_data;
+
+ if (!aNoNotification) {
+ this.saveStateDelayed(aWindow);
+ }
+ },
+
+ /**
+ * When a tab closes, collect its properties
+ * @param aWindow
+ * Window reference
+ * @param aTab
+ * TabPanel reference
+ */
+ onTabClose: function sss_onTabClose(aWindow, aTab) {
+ // notify the tabbrowser that the tab state will be retrieved for the last time
+ // (so that extension authors can easily set data on soon-to-be-closed tabs)
+ var event = aWindow.document.createEvent("Events");
+ event.initEvent("SSTabClosing", true, false);
+ aTab.dispatchEvent(event);
+
+ var maxTabsUndo = this._prefBranch.getIntPref("sessionstore.max_tabs_undo");
+ // don't update our internal state if we don't have to
+ if (maxTabsUndo == 0) {
+ return;
+ }
+
+ // make sure that the tab related data is up-to-date
+ var tabState = this._collectTabData(aTab);
+ this._updateTextAndScrollDataForTab(aWindow, aTab.linkedBrowser, tabState);
+
+ // store closed-tab data for undo
+ if (tabState.entries.length > 0) {
+ let tabTitle = aTab.label;
+ let tabbrowser = aWindow.gBrowser;
+ tabTitle = this._replaceLoadingTitle(tabTitle, tabbrowser, aTab);
+
+ this._windows[aWindow.__SSi]._closedTabs.unshift({
+ state: tabState,
+ title: tabTitle,
+ image: aTab.getAttribute("image"),
+ pos: aTab._tPos
+ });
+ var length = this._windows[aWindow.__SSi]._closedTabs.length;
+ if (length > maxTabsUndo)
+ this._windows[aWindow.__SSi]._closedTabs.splice(maxTabsUndo, length - maxTabsUndo);
+ }
+ },
+
+ /**
+ * When a tab loads, save state.
+ * @param aWindow
+ * Window reference
+ * @param aPanel
+ * TabPanel reference
+ * @param aEvent
+ * Event obj
+ */
+ onTabLoad: function sss_onTabLoad(aWindow, aPanel, aEvent) {
+ // react on "load" and solitary "pageshow" events (the first "pageshow"
+ // following "load" is too late for deleting the data caches)
+ if (aEvent.type != "load" && !aEvent.persisted) {
+ return;
+ }
+
+ delete aPanel.__SS_data;
+ this.saveStateDelayed(aWindow);
+
+ // attempt to update the current URL we send in a crash report
+ this._updateCrashReportURL(aWindow);
+ },
+
+ /**
+ * Called when a tabpanel sends the "input" notification
+ * @param aWindow
+ * Window reference
+ * @param aPanel
+ * TabPanel reference
+ */
+ onTabInput: function sss_onTabInput(aWindow, aPanel) {
+ if (aPanel.__SS_data)
+ delete aPanel.__SS_data._formDataSaved;
+
+ this.saveStateDelayed(aWindow, 3000);
+ },
+
+ /**
+ * Called when a tabpanel sends a "scroll" notification
+ * @param aWindow
+ * Window reference
+ */
+ onTabScroll: function sss_onTabScroll(aWindow) {
+ this.saveStateDelayed(aWindow, 3000);
+ },
+
+ /**
+ * When a tab is selected, save session data
+ * @param aWindow
+ * Window reference
+ * @param aPanels
+ * TabPanel reference
+ */
+ onTabSelect: function sss_onTabSelect(aWindow, aPanels) {
+ if (this._loadState == STATE_RUNNING) {
+ this._windows[aWindow.__SSi].selected = aPanels.selectedIndex;
+ this.saveStateDelayed(aWindow);
+
+ // attempt to update the current URL we send in a crash report
+ this._updateCrashReportURL(aWindow);
+ }
+ },
+
+/* ........ nsISessionStore API .............. */
+
+ getBrowserState: function sss_getBrowserState() {
+ return this._toJSONString(this._getCurrentState());
+ },
+
+ setBrowserState: function sss_setBrowserState(aState) {
+ try {
+ var state = this._safeEval("(" + aState + ")");
+ }
+ catch (ex) { /* invalid state object - don't restore anything */ }
+ if (!state || !state.windows)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ var window = this._getMostRecentBrowserWindow();
+ if (!window) {
+ this._openWindowWithState(state);
+ return;
+ }
+
+ // close all other browser windows
+ this._forEachBrowserWindow(function(aWindow) {
+ if (aWindow != window) {
+ aWindow.close();
+ }
+ });
+
+ // make sure closed window data isn't kept
+ this._closedWindows = [];
+
+ // restore to the given state
+ this.restoreWindow(window, state, true);
+ },
+
+ getWindowState: function sss_getWindowState(aWindow) {
+ if (!aWindow.__SSi && !aWindow.__SS_dyingCache)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ if (!aWindow.__SSi)
+ return this._toJSONString({ windows: [aWindow.__SS_dyingCache] });
+ return this._toJSONString(this._getWindowState(aWindow));
+ },
+
+ setWindowState: function sss_setWindowState(aWindow, aState, aOverwrite) {
+ if (!aWindow.__SSi)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ this.restoreWindow(aWindow, "(" + aState + ")", aOverwrite);
+ },
+
+ getTabState: function sss_getTabState(aTab) {
+ if (!aTab.ownerDocument || !aTab.ownerDocument.defaultView.__SSi)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ var tabState = this._collectTabData(aTab);
+
+ var window = aTab.ownerDocument.defaultView;
+ this._updateTextAndScrollDataForTab(window, aTab.linkedBrowser, tabState);
+
+ return this._toJSONString(tabState);
+ },
+
+ setTabState: function sss_setTabState(aTab, aState) {
+ var tabState = this._safeEval("(" + aState + ")");
+ if (!tabState.entries || !aTab.ownerDocument || !aTab.ownerDocument.defaultView.__SSi)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ var window = aTab.ownerDocument.defaultView;
+ this.restoreHistoryPrecursor(window, [aTab], [tabState], 0, 0, 0);
+ },
+
+ duplicateTab: function sss_duplicateTab(aWindow, aTab) {
+ if (!aTab.ownerDocument || !aTab.ownerDocument.defaultView.__SSi ||
+ !aWindow.getBrowser)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ var tabState = this._collectTabData(aTab, true);
+ var sourceWindow = aTab.ownerDocument.defaultView;
+ this._updateTextAndScrollDataForTab(sourceWindow, aTab.linkedBrowser, tabState, true);
+
+ var newTab = aWindow.getBrowser().addTab();
+ this.restoreHistoryPrecursor(aWindow, [newTab], [tabState], 0, 0, 0);
+
+ return newTab;
+ },
+
+ getClosedTabCount: function sss_getClosedTabCount(aWindow) {
+ if (!aWindow.__SSi && aWindow.__SS_dyingCache)
+ return aWindow.__SS_dyingCache._closedTabs.length;
+ if (!aWindow.__SSi)
+ // XXXzeniko shouldn't we throw here?
+ return 0; // not a browser window, or not otherwise tracked by SS.
+
+ return this._windows[aWindow.__SSi]._closedTabs.length;
+ },
+
+ getClosedTabData: function sss_getClosedTabDataAt(aWindow) {
+ if (!aWindow.__SSi && !aWindow.__SS_dyingCache)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ if (!aWindow.__SSi)
+ return this._toJSONString(aWindow.__SS_dyingCache._closedTabs);
+ return this._toJSONString(this._windows[aWindow.__SSi]._closedTabs);
+ },
+
+ undoCloseTab: function sss_undoCloseTab(aWindow, aIndex) {
+ if (!aWindow.__SSi)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ var closedTabs = this._windows[aWindow.__SSi]._closedTabs;
+
+ // default to the most-recently closed tab
+ aIndex = aIndex || 0;
+ if (!(aIndex in closedTabs))
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ // fetch the data of closed tab, while removing it from the array
+ let closedTab = closedTabs.splice(aIndex, 1).shift();
+ let closedTabState = closedTab.state;
+
+ // create a new tab
+ let browser = aWindow.gBrowser;
+ let tab = browser.addTab();
+
+ // restore the tab's position
+ browser.moveTabTo(tab, closedTab.pos);
+
+ // restore tab content
+ this.restoreHistoryPrecursor(aWindow, [tab], [closedTabState], 1, 0, 0);
+
+ // focus the tab's content area
+ let content = browser.getBrowserForTab(tab).contentWindow;
+ aWindow.setTimeout(function() { content.focus(); }, 0);
+
+ return tab;
+ },
+
+ getClosedWindowCount: function sss_getClosedWindowCount() {
+ return this._closedWindows.length;
+ },
+
+ getClosedWindowData: function sss_getClosedWindowData() {
+ return this._toJSONString(this._closedWindows);
+ },
+
+ undoCloseWindow: function sss_undoCloseWindow(aIndex) {
+ // default to the most-recently closed window
+ aIndex = aIndex || 0;
+
+ if (!aIndex in this._closedWindows)
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+
+ // reopen the window
+ let state = { windows: this._closedWindows.splice(aIndex, 1) };
+ let window = this._openWindowWithState(state);
+ this.windowToFocus = window;
+ return window;
+ },
+
+ getWindowValue: function sss_getWindowValue(aWindow, aKey) {
+ if (aWindow.__SSi) {
+ var data = this._windows[aWindow.__SSi].extData || {};
+ return data[aKey] || "";
+ }
+ if (aWindow.__SS_dyingCache) {
+ data = aWindow.__SS_dyingCache.extData || {};
+ return data[aKey] || "";
+ }
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+ },
+
+ setWindowValue: function sss_setWindowValue(aWindow, aKey, aStringValue) {
+ if (aWindow.__SSi) {
+ if (!this._windows[aWindow.__SSi].extData) {
+ this._windows[aWindow.__SSi].extData = {};
+ }
+ this._windows[aWindow.__SSi].extData[aKey] = aStringValue;
+ this.saveStateDelayed(aWindow);
+ }
+ else {
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+ }
+ },
+
+ deleteWindowValue: function sss_deleteWindowValue(aWindow, aKey) {
+ if (aWindow.__SSi && this._windows[aWindow.__SSi].extData &&
+ this._windows[aWindow.__SSi].extData[aKey])
+ delete this._windows[aWindow.__SSi].extData[aKey];
+ else
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+ },
+
+ getTabValue: function sss_getTabValue(aTab, aKey) {
+ var data = aTab.__SS_extdata || {};
+ return data[aKey] || "";
+ },
+
+ setTabValue: function sss_setTabValue(aTab, aKey, aStringValue) {
+ if (!aTab.__SS_extdata) {
+ aTab.__SS_extdata = {};
+ }
+ aTab.__SS_extdata[aKey] = aStringValue;
+ this.saveStateDelayed(aTab.ownerDocument.defaultView);
+ },
+
+ deleteTabValue: function sss_deleteTabValue(aTab, aKey) {
+ if (aTab.__SS_extdata && aTab.__SS_extdata[aKey])
+ delete aTab.__SS_extdata[aKey];
+ else
+ throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
+ },
+
+ persistTabAttribute: function sss_persistTabAttribute(aName) {
+ if (this.xulAttributes.indexOf(aName) != -1)
+ return; // this attribute is already being tracked
+
+ this.xulAttributes.push(aName);
+ this.saveStateDelayed();
+ },
+
+/* ........ Saving Functionality .............. */
+
+ /**
+ * Store all session data for a window
+ * @param aWindow
+ * Window reference
+ */
+ _saveWindowHistory: function sss_saveWindowHistory(aWindow) {
+ var tabbrowser = aWindow.getBrowser();
+ var tabs = tabbrowser.mTabs;
+ var tabsData = this._windows[aWindow.__SSi].tabs = [];
+
+ for (var i = 0; i < tabs.length; i++)
+ tabsData.push(this._collectTabData(tabs[i]));
+
+ this._windows[aWindow.__SSi].selected = tabbrowser.mTabBox.selectedIndex + 1;
+ },
+
+ /**
+ * Collect data related to a single tab
+ * @param aTab
+ * tabbrowser tab
+ * @param aFullData
+ * always return privacy sensitive data (use with care)
+ * @returns object
+ */
+ _collectTabData: function sss_collectTabData(aTab, aFullData) {
+ var tabData = { entries: [] };
+ var browser = aTab.linkedBrowser;
+
+ if (!browser || !browser.currentURI)
+ // can happen when calling this function right after .addTab()
+ return tabData;
+ else if (browser.parentNode.__SS_data && browser.parentNode.__SS_data._tabStillLoading)
+ // use the data to be restored when the tab hasn't been completely loaded
+ return browser.parentNode.__SS_data;
+
+ var history = null;
+ try {
+ history = browser.sessionHistory;
+ }
+ catch (ex) { } // this could happen if we catch a tab during (de)initialization
+
+ // XXXzeniko anchor navigation doesn't reset __SS_data, so we could reuse
+ // data even when we shouldn't (e.g. Back, different anchor)
+ if (history && browser.parentNode.__SS_data &&
+ browser.parentNode.__SS_data.entries[history.index] &&
+ history.index < this._sessionhistory_max_entries - 1 && !aFullData) {
+ tabData = browser.parentNode.__SS_data;
+ tabData.index = history.index + 1;
+ }
+ else if (history && history.count > 0) {
+ for (var j = 0; j < history.count; j++)
+ tabData.entries.push(this._serializeHistoryEntry(history.getEntryAtIndex(j, false),
+ aFullData));
+ tabData.index = history.index + 1;
+
+ // make sure not to cache privacy sensitive data which shouldn't get out
+ if (!aFullData)
+ browser.parentNode.__SS_data = tabData;
+ }
+ else if (browser.currentURI.spec != "about:blank" ||
+ browser.contentDocument.body.hasChildNodes()) {
+ tabData.entries[0] = { url: browser.currentURI.spec };
+ tabData.index = 1;
+ }
+
+ var disallow = [];
+ for (var i = 0; i < CAPABILITIES.length; i++)
+ if (!browser.docShell["allow" + CAPABILITIES[i]])
+ disallow.push(CAPABILITIES[i]);
+ if (disallow.length > 0)
+ tabData.disallow = disallow.join(",");
+ else if (tabData.disallow)
+ delete tabData.disallow;
+
+ if (this.xulAttributes.length > 0) {
+ tabData.attributes = {};
+ Array.forEach(aTab.attributes, function(aAttr) {
+ if (this.xulAttributes.indexOf(aAttr.name) > -1)
+ tabData.attributes[aAttr.name] = aAttr.value;
+ }, this);
+ }
+
+ if (aTab.__SS_extdata)
+ tabData.extData = aTab.__SS_extdata;
+ else if (tabData.extData)
+ delete tabData.extData;
+
+ if (history && browser.docShell instanceof Ci.nsIDocShell)
+ this._serializeSessionStorage(tabData, history, browser.docShell, aFullData);
+
+ return tabData;
+ },
+
+ /**
+ * Get an object that is a serialized representation of a History entry
+ * Used for data storage
+ * @param aEntry
+ * nsISHEntry instance
+ * @param aFullData
+ * always return privacy sensitive data (use with care)
+ * @returns object
+ */
+ _serializeHistoryEntry: function sss_serializeHistoryEntry(aEntry, aFullData) {
+ var entry = { url: aEntry.URI.spec };
+
+ if (aEntry.title && aEntry.title != entry.url) {
+ entry.title = aEntry.title;
+ }
+ if (aEntry.isSubFrame) {
+ entry.subframe = true;
+ }
+ if (!(aEntry instanceof Ci.nsISHEntry)) {
+ return entry;
+ }
+
+ var cacheKey = aEntry.cacheKey;
+ if (cacheKey && cacheKey instanceof Ci.nsISupportsPRUint32 &&
+ cacheKey.data != 0) {
+ // XXXbz would be better to have cache keys implement
+ // nsISerializable or something.
+ entry.cacheKey = cacheKey.data;
+ }
+ entry.ID = aEntry.ID;
+
+ if (aEntry.contentType)
+ entry.contentType = aEntry.contentType;
+
+ var x = {}, y = {};
+ aEntry.getScrollPosition(x, y);
+ if (x.value != 0 || y.value != 0)
+ entry.scroll = x.value + "," + y.value;
+
+ try {
+ var prefPostdata = this._prefBranch.getIntPref("sessionstore.postdata");
+ if (aEntry.postData && (aFullData ||
+ prefPostdata && this._checkPrivacyLevel(aEntry.URI.schemeIs("https")))) {
+ aEntry.postData.QueryInterface(Ci.nsISeekableStream).
+ seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
+ var stream = Cc["@mozilla.org/binaryinputstream;1"].
+ createInstance(Ci.nsIBinaryInputStream);
+ stream.setInputStream(aEntry.postData);
+ var postBytes = stream.readByteArray(stream.available());
+ var postdata = String.fromCharCode.apply(null, postBytes);
+ if (aFullData || prefPostdata == -1 ||
+ postdata.replace(/^(Content-.*\r\n)+(\r\n)*/, "").length <=
+ prefPostdata) {
+ // We can stop doing base64 encoding once our serialization into JSON
+ // is guaranteed to handle all chars in strings, including embedded
+ // nulls.
+ entry.postdata_b64 = btoa(postdata);
+ }
+ }
+ }
+ catch (ex) { debug(ex); } // POSTDATA is tricky - especially since some extensions don't get it right
+
+ if (aEntry.owner) {
+ // Not catching anything specific here, just possible errors
+ // from writeCompoundObject and the like.
+ try {
+ var binaryStream = Cc["@mozilla.org/binaryoutputstream;1"].
+ createInstance(Ci.nsIObjectOutputStream);
+ var pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
+ pipe.init(false, false, 0, 0xffffffff, null);
+ binaryStream.setOutputStream(pipe.outputStream);
+ binaryStream.writeCompoundObject(aEntry.owner, Ci.nsISupports, true);
+ binaryStream.close();
+
+ // Now we want to read the data from the pipe's input end and encode it.
+ var scriptableStream = Cc["@mozilla.org/binaryinputstream;1"].
+ createInstance(Ci.nsIBinaryInputStream);
+ scriptableStream.setInputStream(pipe.inputStream);
+ var ownerBytes =
+ scriptableStream.readByteArray(scriptableStream.available());
+ // We can stop doing base64 encoding once our serialization into JSON
+ // is guaranteed to handle all chars in strings, including embedded
+ // nulls.
+ entry.owner_b64 = btoa(String.fromCharCode.apply(null, ownerBytes));
+ }
+ catch (ex) { debug(ex); }
+ }
+
+ if (!(aEntry instanceof Ci.nsISHContainer)) {
+ return entry;
+ }
+
+ if (aEntry.childCount > 0) {
+ entry.children = [];
+ for (var i = 0; i < aEntry.childCount; i++) {
+ var child = aEntry.GetChildAt(i);
+ if (child) {
+ entry.children.push(this._serializeHistoryEntry(child, aFullData));
+ }
+ else { // to maintain the correct frame order, insert a dummy entry
+ entry.children.push({ url: "about:blank" });
+ }
+ // don't try to restore framesets containing wyciwyg URLs (cf. bug 424689 and bug 450595)
+ if (/^wyciwyg:\/\//.test(entry.children[i].url)) {
+ delete entry.children;
+ break;
+ }
+ }
+ }
+
+ return entry;
+ },
+
+ /**
+ * Updates all sessionStorage "super cookies"
+ * @param aTabData
+ * The data object for a specific tab
+ * @param aHistory
+ * That tab's session history
+ * @param aDocShell
+ * That tab's docshell (containing the sessionStorage)
+ * @param aFullData
+ * always return privacy sensitive data (use with care)
+ */
+ _serializeSessionStorage:
+ function sss_serializeSessionStorage(aTabData, aHistory, aDocShell, aFullData) {
+ let storageData = {};
+ let hasContent = false;
+
+ aDocShell.QueryInterface(Ci.nsIDocShell_MOZILLA_1_9_1_SessionStorage);
+ for (let i = 0; i < aHistory.count; i++) {
+ let uri = aHistory.getEntryAtIndex(i, false).URI;
+ // sessionStorage is saved per origin (cf. nsDocShell::GetSessionStorageForURI)
+ let domain = uri.spec;
+ try {
+ if (uri.host)
+ domain = uri.prePath;
+ }
+ catch (ex) { /* this throws for host-less URIs (such as about: or jar:) */ }
+ if (storageData[domain] || !(aFullData || this._checkPrivacyLevel(uri.schemeIs("https"))))
+ continue;
+
+ let storage, storageItemCount = 0;
+ try {
+ var principal = Cc["@mozilla.org/scriptsecuritymanager;1"].
+ getService(Ci.nsIScriptSecurityManager).
+ getCodebasePrincipal(uri);
+
+ // Using getSessionStorageForPrincipal instead of getSessionStorageForURI
+ // just to be able to pass aCreate = false, that avoids creation of the
+ // sessionStorage object for the page earlier than the page really
+ // requires it. It was causing problems while accessing a storage when
+ // a page later changed its domain.
+ storage = aDocShell.getSessionStorageForPrincipal(principal, false);
+ if (storage)
+ storageItemCount = storage.length;
+ }
+ catch (ex) { /* sessionStorage might throw if it's turned off, see bug 458954 */ }
+ if (storageItemCount == 0)
+ continue;
+
+ let data = storageData[domain] = {};
+ for (let j = 0; j < storageItemCount; j++) {
+ try {
+ let key = storage.key(j);
+ let item = storage.getItem(key);
+ data[key] = item;
+ }
+ catch (ex) { /* XXXzeniko this currently throws for secured items (cf. bug 442048) */ }
+ }
+ hasContent = true;
+ }
+
+ if (hasContent)
+ aTabData.storage = storageData;
+ },
+
+ /**
+ * go through all tabs and store the current scroll positions
+ * and innerHTML content of WYSIWYG editors
+ * @param aWindow
+ * Window reference
+ */
+ _updateTextAndScrollData: function sss_updateTextAndScrollData(aWindow) {
+ var browsers = aWindow.getBrowser().browsers;
+ for (var i = 0; i < browsers.length; i++) {
+ try {
+ var tabData = this._windows[aWindow.__SSi].tabs[i];
+ if (browsers[i].parentNode.__SS_data &&
+ browsers[i].parentNode.__SS_data._tabStillLoading)
+ continue; // ignore incompletely initialized tabs
+ this._updateTextAndScrollDataForTab(aWindow, browsers[i], tabData);
+ }
+ catch (ex) { debug(ex); } // get as much data as possible, ignore failures (might succeed the next time)
+ }
+ },
+
+ /**
+ * go through all frames and store the current scroll positions
+ * and innerHTML content of WYSIWYG editors
+ * @param aWindow
+ * Window reference
+ * @param aBrowser
+ * single browser reference
+ * @param aTabData
+ * tabData object to add the information to
+ * @param aFullData
+ * always return privacy sensitive data (use with care)
+ */
+ _updateTextAndScrollDataForTab:
+ function sss_updateTextAndScrollDataForTab(aWindow, aBrowser, aTabData, aFullData) {
+ var tabIndex = (aTabData.index || aTabData.entries.length) - 1;
+ // entry data needn't exist for tabs just initialized with an incomplete session state
+ if (!aTabData.entries[tabIndex])
+ return;
+
+ let selectedPageStyle = aBrowser.markupDocumentViewer.authorStyleDisabled ? "_nostyle" :
+ this._getSelectedPageStyle(aBrowser.contentWindow);
+ if (selectedPageStyle)
+ aTabData.pageStyle = selectedPageStyle;
+ else if (aTabData.pageStyle)
+ delete aTabData.pageStyle;
+
+ this._updateTextAndScrollDataForFrame(aWindow, aBrowser.contentWindow,
+ aTabData.entries[tabIndex],
+ !aTabData._formDataSaved, aFullData);
+ aTabData._formDataSaved = true;
+ if (aBrowser.currentURI.spec == "about:config")
+ aTabData.entries[tabIndex].formdata = {
+ "#textbox": aBrowser.contentDocument.getElementById("textbox").wrappedJSObject.value
+ };
+ },
+
+ /**
+ * go through all subframes and store all form data, the current
+ * scroll positions and innerHTML content of WYSIWYG editors
+ * @param aWindow
+ * Window reference
+ * @param aContent
+ * frame reference
+ * @param aData
+ * part of a tabData object to add the information to
+ * @param aUpdateFormData
+ * update all form data for this tab
+ * @param aFullData
+ * always return privacy sensitive data (use with care)
+ */
+ _updateTextAndScrollDataForFrame:
+ function sss_updateTextAndScrollDataForFrame(aWindow, aContent, aData,
+ aUpdateFormData, aFullData) {
+ for (var i = 0; i < aContent.frames.length; i++) {
+ if (aData.children && aData.children[i])
+ this._updateTextAndScrollDataForFrame(aWindow, aContent.frames[i],
+ aData.children[i], aUpdateFormData, aFullData);
+ }
+ var isHTTPS = this._getURIFromString((aContent.parent || aContent).
+ document.location.href).schemeIs("https");
+ if (aFullData || this._checkPrivacyLevel(isHTTPS) ||
+ aContent.top.document.location.href == "about:sessionrestore") {
+ if (aFullData || aUpdateFormData) {
+ let formData = this._collectFormDataForFrame(aContent.document);
+ if (formData)
+ aData.formdata = formData;
+ else if (aData.formdata)
+ delete aData.formdata;
+ }
+
+ // designMode is undefined e.g. for XUL documents (as about:config)
+ if ((aContent.document.designMode || "") == "on") {
+ if (aData.innerHTML === undefined && !aFullData) {
+ // we get no "input" events from iframes - listen for keypress here
+ let _this = this;
+ aContent.addEventListener("keypress", function(aEvent) {
+ _this.saveStateDelayed(aWindow, 3000);
+ }, true);
+ }
+ aData.innerHTML = aContent.document.body.innerHTML;
+ }
+ }
+
+ // get scroll position from nsIDOMWindowUtils, since it allows avoiding a
+ // flush of layout
+ let domWindowUtils = aContent.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ let scrollX = {}, scrollY = {};
+ domWindowUtils.getScrollXY(false, scrollX, scrollY);
+ aData.scroll = scrollX.value + "," + scrollY.value;
+ },
+
+ /**
+ * determine the title of the currently enabled style sheet (if any)
+ * and recurse through the frameset if necessary
+ * @param aContent is a frame reference
+ * @returns the title style sheet determined to be enabled (empty string if none)
+ */
+ _getSelectedPageStyle: function sss_getSelectedPageStyle(aContent) {
+ const forScreen = /(?:^|,)\s*(?:all|screen)\s*(?:,|$)/i;
+ for (let i = 0; i < aContent.document.styleSheets.length; i++) {
+ let ss = aContent.document.styleSheets[i];
+ let media = ss.media.mediaText;
+ if (!ss.disabled && ss.title && (!media || forScreen.test(media)))
+ return ss.title
+ }
+ for (let i = 0; i < aContent.frames.length; i++) {
+ let selectedPageStyle = this._getSelectedPageStyle(aContent.frames[i]);
+ if (selectedPageStyle)
+ return selectedPageStyle;
+ }
+ return "";
+ },
+
+ /**
+ * collect the state of all form elements
+ * @param aDocument
+ * document reference
+ */
+ _collectFormDataForFrame: function sss_collectFormDataForFrame(aDocument) {
+ let formNodes = aDocument.evaluate(XPathHelper.restorableFormNodes, aDocument,
+ XPathHelper.resolveNS,
+ Ci.nsIDOMXPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
+ let node = formNodes.iterateNext();
+ if (!node)
+ return null;
+
+ const MAX_GENERATED_XPATHS = 100;
+ let generatedCount = 0;
+
+ let data = {};
+ do {
+ // Only generate a limited number of XPath expressions for perf reasons (cf. bug 477564)
+ if (!node.id && ++generatedCount > MAX_GENERATED_XPATHS)
+ continue;
+
+ let id = node.id ? "#" + node.id : XPathHelper.generate(node);
+ if (node instanceof Ci.nsIDOMHTMLInputElement) {
+ if (node.type != "file")
+ data[id] = node.type == "checkbox" || node.type == "radio" ? node.checked : node.value;
+ else
+ data[id] = { type: "file", value: node.value };
+ }
+ else if (node instanceof Ci.nsIDOMHTMLTextAreaElement)
+ data[id] = node.value;
+ else if (!node.multiple)
+ data[id] = node.selectedIndex;
+ else {
+ let options = Array.map(node.options, function(aOpt, aIx) aOpt.selected ? aIx : -1);
+ data[id] = options.filter(function(aIx) aIx >= 0);
+ }
+ } while ((node = formNodes.iterateNext()));
+
+ return data;
+ },
+
+ /**
+ * store all hosts for a URL
+ * @param aWindow
+ * Window reference
+ */
+ _updateCookieHosts: function sss_updateCookieHosts(aWindow) {
+ var hosts = this._windows[aWindow.__SSi]._hosts = {};
+
+ // get all possible subdomain levels for a given URL
+ var _this = this;
+ function extractHosts(aEntry) {
+ if (/^https?:\/\/(?:[^@\/\s]+@)?([\w.-]+)/.test(aEntry.url) &&
+ !hosts[RegExp.$1] && _this._checkPrivacyLevel(_this._getURIFromString(aEntry.url).schemeIs("https"))) {
+ var host = RegExp.$1;
+ var ix;
+ for (ix = host.indexOf(".") + 1; ix; ix = host.indexOf(".", ix) + 1) {
+ hosts[host.substr(ix)] = true;
+ }
+ hosts[host] = true;
+ }
+ else if (/^file:\/\/([^\/]*)/.test(aEntry.url)) {
+ hosts[RegExp.$1] = true;
+ }
+ if (aEntry.children) {
+ aEntry.children.forEach(extractHosts);
+ }
+ }
+
+ this._windows[aWindow.__SSi].tabs.forEach(function(aTabData) { aTabData.entries.forEach(extractHosts); });
+ },
+
+ /**
+ * Serialize cookie data
+ * @param aWindows
+ * array of Window references
+ */
+ _updateCookies: function sss_updateCookies(aWindows) {
+ var cookiesEnum = Cc["@mozilla.org/cookiemanager;1"].
+ getService(Ci.nsICookieManager).enumerator;
+ // collect the cookies per window
+ for (var i = 0; i < aWindows.length; i++)
+ aWindows[i].cookies = [];
+
+ // MAX_EXPIRY should be 2^63-1, but JavaScript can't handle that precision
+ var MAX_EXPIRY = Math.pow(2, 62);
+ while (cookiesEnum.hasMoreElements()) {
+ var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
+ if (cookie.isSession && this._checkPrivacyLevel(cookie.isSecure)) {
+ var jscookie = null;
+ aWindows.forEach(function(aWindow) {
+ if (aWindow._hosts && aWindow._hosts[cookie.rawHost]) {
+ // serialize the cookie when it's first needed
+ if (!jscookie) {
+ jscookie = { host: cookie.host, value: cookie.value };
+ // only add attributes with non-default values (saving a few bits)
+ if (cookie.path) jscookie.path = cookie.path;
+ if (cookie.name) jscookie.name = cookie.name;
+ if (cookie.isSecure) jscookie.secure = true;
+ if (cookie.isHttpOnly) jscookie.httponly = true;
+ if (cookie.expiry < MAX_EXPIRY) jscookie.expiry = cookie.expiry;
+ }
+ aWindow.cookies.push(jscookie);
+ }
+ });
+ }
+ }
+
+ // don't include empty cookie sections
+ for (i = 0; i < aWindows.length; i++)
+ if (aWindows[i].cookies.length == 0)
+ delete aWindows[i].cookies;
+ },
+
+ /**
+ * Store window dimensions, visibility, sidebar
+ * @param aWindow
+ * Window reference
+ */
+ _updateWindowFeatures: function sss_updateWindowFeatures(aWindow) {
+ var winData = this._windows[aWindow.__SSi];
+
+ WINDOW_ATTRIBUTES.forEach(function(aAttr) {
+ winData[aAttr] = this._getWindowDimension(aWindow, aAttr);
+ }, this);
+
+ var hidden = WINDOW_HIDEABLE_FEATURES.filter(function(aItem) {
+ return aWindow[aItem] && !aWindow[aItem].visible;
+ });
+ if (hidden.length != 0)
+ winData.hidden = hidden.join(",");
+ else if (winData.hidden)
+ delete winData.hidden;
+
+ var sidebar = aWindow.document.getElementById("sidebar-box").getAttribute("sidebarcommand");
+ if (sidebar)
+ winData.sidebar = sidebar;
+ else if (winData.sidebar)
+ delete winData.sidebar;
+ },
+
+ /**
+ * serialize session data as Ini-formatted string
+ * @param aUpdateAll
+ * Bool update all windows
+ * @returns string
+ */
+ _getCurrentState: function sss_getCurrentState(aUpdateAll) {
+ var activeWindow = this._getMostRecentBrowserWindow();
+
+ if (this._loadState == STATE_RUNNING) {
+ // update the data for all windows with activities since the last save operation
+ this._forEachBrowserWindow(function(aWindow) {
+ if (!this._isWindowLoaded(aWindow)) // window data is still in _statesToRestore
+ return;
+ if (aUpdateAll || this._dirtyWindows[aWindow.__SSi] || aWindow == activeWindow) {
+ this._collectWindowData(aWindow);
+ }
+ else { // always update the window features (whose change alone never triggers a save operation)
+ this._updateWindowFeatures(aWindow);
+ }
+ }, this);
+ this._dirtyWindows = [];
+ }
+
+ // collect the data for all windows
+ var total = [], windows = [];
+ var nonPopupCount = 0;
+ var ix;
+ for (ix in this._windows) {
+ total.push(this._windows[ix]);
+ windows.push(ix);
+ if (!this._windows[ix].isPopup)
+ nonPopupCount++;
+ }
+ this._updateCookies(total);
+
+ // collect the data for all windows yet to be restored
+ for (ix in this._statesToRestore) {
+ for each (let winData in this._statesToRestore[ix].windows) {
+ total.push(winData);
+ if (!winData.isPopup)
+ nonPopupCount++;
+ }
+ }
+
+ // shallow copy this._closedWindows to preserve current state
+ let lastClosedWindowsCopy = this._closedWindows.slice();
+
+//@line 1652 "/builds/moz2_slave/linux_build/build/browser/components/sessionstore/src/nsSessionStore.js"
+ // if no non-popup browser window remains open, return the state of the last closed window(s)
+ if (nonPopupCount == 0 && lastClosedWindowsCopy.length > 0) {
+ // prepend the last non-popup browser window, so that if the user loads more tabs
+ // at startup we don't accidentally add them to a popup window
+ do {
+ total.unshift(lastClosedWindowsCopy.shift())
+ } while (total[0].isPopup)
+ }
+//@line 1661 "/builds/moz2_slave/linux_build/build/browser/components/sessionstore/src/nsSessionStore.js"
+
+ if (activeWindow) {
+ this.activeWindowSSiCache = activeWindow.__SSi || "";
+ }
+ ix = this.activeWindowSSiCache ? windows.indexOf(this.activeWindowSSiCache) : -1;
+
+ return { windows: total, selectedWindow: ix + 1, _closedWindows: lastClosedWindowsCopy };
+ },
+
+ /**
+ * serialize session data for a window
+ * @param aWindow
+ * Window reference
+ * @returns string
+ */
+ _getWindowState: function sss_getWindowState(aWindow) {
+ if (!this._isWindowLoaded(aWindow))
+ return this._statesToRestore[aWindow.__SS_restoreID];
+
+ if (this._loadState == STATE_RUNNING) {
+ this._collectWindowData(aWindow);
+ }
+
+ var total = [this._windows[aWindow.__SSi]];
+ this._updateCookies(total);
+
+ return { windows: total };
+ },
+
+ _collectWindowData: function sss_collectWindowData(aWindow) {
+ if (!this._isWindowLoaded(aWindow))
+ return;
+
+ // update the internal state data for this window
+ this._saveWindowHistory(aWindow);
+ this._updateTextAndScrollData(aWindow);
+ this._updateCookieHosts(aWindow);
+ this._updateWindowFeatures(aWindow);
+
+ this._dirtyWindows[aWindow.__SSi] = false;
+ },
+
+/* ........ Restoring Functionality .............. */
+
+ /**
+ * restore features to a single window
+ * @param aWindow
+ * Window reference
+ * @param aState
+ * JS object or its eval'able source
+ * @param aOverwriteTabs
+ * bool overwrite existing tabs w/ new ones
+ * @param aFollowUp
+ * bool this isn't the restoration of the first window
+ */
+ restoreWindow: function sss_restoreWindow(aWindow, aState, aOverwriteTabs, aFollowUp) {
+ if (!aFollowUp) {
+ this.windowToFocus = aWindow;
+ }
+ // initialize window if necessary
+ if (aWindow && (!aWindow.__SSi || !this._windows[aWindow.__SSi]))
+ this.onLoad(aWindow);
+
+ try {
+ var root = typeof aState == "string" ? this._safeEval(aState) : aState;
+ if (!root.windows[0]) {
+ this._notifyIfAllWindowsRestored();
+ return; // nothing to restore
+ }
+ }
+ catch (ex) { // invalid state object - don't restore anything
+ debug(ex);
+ this._notifyIfAllWindowsRestored();
+ return;
+ }
+
+ if (root._closedWindows)
+ this._closedWindows = root._closedWindows;
+
+ var winData;
+ if (!aState.selectedWindow) {
+ aState.selectedWindow = 0;
+ }
+ // open new windows for all further window entries of a multi-window session
+ // (unless they don't contain any tab data)
+ for (var w = 1; w < root.windows.length; w++) {
+ winData = root.windows[w];
+ if (winData && winData.tabs && winData.tabs[0]) {
+ var window = this._openWindowWithState({ windows: [winData] });
+ if (w == aState.selectedWindow - 1) {
+ this.windowToFocus = window;
+ }
+ }
+ }
+ winData = root.windows[0];
+ if (!winData.tabs) {
+ winData.tabs = [];
+ }
+ // don't restore a single blank tab when we've had an external
+ // URL passed in for loading at startup (cf. bug 357419)
+ else if (root._firstTabs && !aOverwriteTabs && winData.tabs.length == 1 &&
+ (!winData.tabs[0].entries || winData.tabs[0].entries.length == 0)) {
+ winData.tabs = [];
+ }
+
+ var tabbrowser = aWindow.gBrowser;
+ var openTabCount = aOverwriteTabs ? tabbrowser.browsers.length : -1;
+ var newTabCount = winData.tabs.length;
+ var tabs = [];
+
+ // disable smooth scrolling while adding, moving, removing and selecting tabs
+ var tabstrip = tabbrowser.tabContainer.mTabstrip;
+ var smoothScroll = tabstrip.smoothScroll;
+ tabstrip.smoothScroll = false;
+
+ // make sure that the selected tab won't be closed in order to
+ // prevent unnecessary flickering
+ if (aOverwriteTabs && tabbrowser.selectedTab._tPos >= newTabCount)
+ tabbrowser.moveTabTo(tabbrowser.selectedTab, newTabCount - 1);
+
+ for (var t = 0; t < newTabCount; t++) {
+ tabs.push(t < openTabCount ? tabbrowser.mTabs[t] : tabbrowser.addTab());
+ // when resuming at startup: add additionally requested pages to the end
+ if (!aOverwriteTabs && root._firstTabs) {
+ tabbrowser.moveTabTo(tabs[t], t);
+ }
+ }
+
+ // when overwriting tabs, remove all superflous ones
+ if (aOverwriteTabs && newTabCount < openTabCount) {
+ Array.slice(tabbrowser.mTabs, newTabCount, openTabCount)
+ .forEach(tabbrowser.removeTab, tabbrowser);
+ }
+
+ if (aOverwriteTabs) {
+ this.restoreWindowFeatures(aWindow, winData);
+ }
+ if (winData.cookies) {
+ this.restoreCookies(winData.cookies);
+ }
+ if (winData.extData) {
+ if (aOverwriteTabs || !this._windows[aWindow.__SSi].extData) {
+ this._windows[aWindow.__SSi].extData = {};
+ }
+ for (var key in winData.extData) {
+ this._windows[aWindow.__SSi].extData[key] = winData.extData[key];
+ }
+ }
+ if (winData._closedTabs && (root._firstTabs || aOverwriteTabs)) {
+ this._windows[aWindow.__SSi]._closedTabs = winData._closedTabs;
+ }
+
+ this.restoreHistoryPrecursor(aWindow, tabs, winData.tabs,
+ (aOverwriteTabs ? (parseInt(winData.selected) || 1) : 0), 0, 0);
+
+ // set smoothScroll back to the original value
+ tabstrip.smoothScroll = smoothScroll;
+
+ this._notifyIfAllWindowsRestored();
+ },
+
+ /**
+ * Manage history restoration for a window
+ * @param aWindow
+ * Window to restore the tabs into
+ * @param aTabs
+ * Array of tab references
+ * @param aTabData
+ * Array of tab data
+ * @param aSelectTab
+ * Index of selected tab
+ * @param aIx
+ * Index of the next tab to check readyness for
+ * @param aCount
+ * Counter for number of times delaying b/c browser or history aren't ready
+ */
+ restoreHistoryPrecursor:
+ function sss_restoreHistoryPrecursor(aWindow, aTabs, aTabData, aSelectTab, aIx, aCount) {
+ var tabbrowser = aWindow.getBrowser();
+
+ // make sure that all browsers and their histories are available
+ // - if one's not, resume this check in 100ms (repeat at most 10 times)
+ for (var t = aIx; t < aTabs.length; t++) {
+ try {
+ if (!tabbrowser.getBrowserForTab(aTabs[t]).webNavigation.sessionHistory) {
+ throw new Error();
+ }
+ }
+ catch (ex) { // in case browser or history aren't ready yet
+ if (aCount < 10) {
+ var restoreHistoryFunc = function(self) {
+ self.restoreHistoryPrecursor(aWindow, aTabs, aTabData, aSelectTab, aIx, aCount + 1);
+ }
+ aWindow.setTimeout(restoreHistoryFunc, 100, this);
+ return;
+ }
+ }
+ }
+
+ // mark the tabs as loading
+ for (t = 0; t < aTabs.length; t++) {
+ var tab = aTabs[t];
+ var browser = tabbrowser.getBrowserForTab(tab);
+
+ aTabData[t]._tabStillLoading = true;
+ if (!aTabData[t].entries || aTabData[t].entries.length == 0) {
+ // make sure to blank out this tab's content
+ // (just purging the tab's history won't be enough)
+ browser.contentDocument.location = "about:blank";
+ continue;
+ }
+
+ browser.stop(); // in case about:blank isn't done yet
+
+ tab.setAttribute("busy", "true");
+ tabbrowser.updateIcon(tab);
+ tabbrowser.setTabTitleLoading(tab);
+
+ // wall-paper fix for bug 439675: make sure that the URL to be loaded
+ // is always visible in the address bar
+ let activeIndex = (aTabData[t].index || aTabData[t].entries.length) - 1;
+ let activePageData = aTabData[t].entries[activeIndex] || null;
+ browser.userTypedValue = activePageData ? activePageData.url || null : null;
+
+ // keep the data around to prevent dataloss in case
+ // a tab gets closed before it's been properly restored
+ browser.parentNode.__SS_data = aTabData[t];
+ }
+
+ if (aTabs.length > 0) {
+ // Determine if we can optimize & load visible tabs first
+ let tabScrollBoxObject = tabbrowser.tabContainer.mTabstrip.scrollBoxObject;
+ let tabBoxObject = aTabs[0].boxObject;
+ let maxVisibleTabs = Math.ceil(tabScrollBoxObject.width / tabBoxObject.width);
+
+ // make sure we restore visible tabs first, if there are enough
+ if (maxVisibleTabs < aTabs.length && aSelectTab > 1) {
+ let firstVisibleTab = 0;
+ if (aTabs.length - maxVisibleTabs > aSelectTab) {
+ // aSelectTab is leftmost since we scroll to it when possible
+ firstVisibleTab = aSelectTab - 1;
+ } else {
+ // aSelectTab is rightmost or no more room to scroll right
+ firstVisibleTab = aTabs.length - maxVisibleTabs;
+ }
+ aTabs = aTabs.splice(firstVisibleTab, maxVisibleTabs).concat(aTabs);
+ aTabData = aTabData.splice(firstVisibleTab, maxVisibleTabs).concat(aTabData);
+ aSelectTab -= firstVisibleTab;
+ }
+
+ // make sure to restore the selected tab first (if any)
+ if (aSelectTab-- && aTabs[aSelectTab]) {
+ aTabs.unshift(aTabs.splice(aSelectTab, 1)[0]);
+ aTabData.unshift(aTabData.splice(aSelectTab, 1)[0]);
+ tabbrowser.selectedTab = aTabs[0];
+ }
+ }
+
+ if (!this._isWindowLoaded(aWindow)) {
+ // from now on, the data will come from the actual window
+ delete this._statesToRestore[aWindow.__SS_restoreID];
+ delete aWindow.__SS_restoreID;
+ }
+
+ // helper hash for ensuring unique frame IDs
+ var idMap = { used: {} };
+ this.restoreHistory(aWindow, aTabs, aTabData, idMap);
+ },
+
+ /**
+ * Restory history for a window
+ * @param aWindow
+ * Window reference
+ * @param aTabs
+ * Array of tab references
+ * @param aTabData
+ * Array of tab data
+ * @param aIdMap
+ * Hash for ensuring unique frame IDs
+ */
+ restoreHistory: function sss_restoreHistory(aWindow, aTabs, aTabData, aIdMap) {
+ var _this = this;
+ while (aTabs.length > 0 && (!aTabData[0]._tabStillLoading || !aTabs[0].parentNode)) {
+ aTabs.shift(); // this tab got removed before being completely restored
+ aTabData.shift();
+ }
+ if (aTabs.length == 0) {
+ return; // no more tabs to restore
+ }
+
+ var tab = aTabs.shift();
+ var tabData = aTabData.shift();
+
+ var browser = aWindow.getBrowser().getBrowserForTab(tab);
+ var history = browser.webNavigation.sessionHistory;
+
+ if (history.count > 0) {
+ history.PurgeHistory(history.count);
+ }
+ history.QueryInterface(Ci.nsISHistoryInternal);
+
+ if (!tabData.entries) {
+ tabData.entries = [];
+ }
+ if (tabData.extData) {
+ tab.__SS_extdata = {};
+ for (let key in tabData.extData)
+ tab.__SS_extdata[key] = tabData.extData[key];
+ }
+ else
+ delete tab.__SS_extdata;
+
+ for (var i = 0; i < tabData.entries.length; i++) {
+ history.addEntry(this._deserializeHistoryEntry(tabData.entries[i], aIdMap), true);
+ }
+
+ // make sure to reset the capabilities and attributes, in case this tab gets reused
+ var disallow = (tabData.disallow)?tabData.disallow.split(","):[];
+ CAPABILITIES.forEach(function(aCapability) {
+ browser.docShell["allow" + aCapability] = disallow.indexOf(aCapability) == -1;
+ });
+ Array.filter(tab.attributes, function(aAttr) {
+ return (_this.xulAttributes.indexOf(aAttr.name) > -1);
+ }).forEach(tab.removeAttribute, tab);
+ if (tabData.xultab) {
+ // restore attributes from the legacy Firefox 2.0/3.0 format
+ tabData.xultab.split(" ").forEach(function(aAttr) {
+ if (/^([^\s=]+)=(.*)/.test(aAttr)) {
+ tab.setAttribute(RegExp.$1, decodeURI(RegExp.$2));
+ }
+ });
+ }
+ for (let name in tabData.attributes)
+ tab.setAttribute(name, tabData.attributes[name]);
+
+ if (tabData.storage && browser.docShell instanceof Ci.nsIDocShell)
+ this._deserializeSessionStorage(tabData.storage, browser.docShell);
+
+ // notify the tabbrowser that the tab chrome has been restored
+ var event = aWindow.document.createEvent("Events");
+ event.initEvent("SSTabRestoring", true, false);
+ tab.dispatchEvent(event);
+
+ let activeIndex = (tabData.index || tabData.entries.length) - 1;
+ if (activeIndex >= tabData.entries.length)
+ activeIndex = tabData.entries.length - 1;
+ try {
+ if (activeIndex >= 0)
+ browser.webNavigation.gotoIndex(activeIndex);
+ }
+ catch (ex) {
+ // ignore page load errors
+ tab.removeAttribute("busy");
+ }
+
+ if (tabData.entries.length > 0) {
+ // restore those aspects of the currently active documents
+ // which are not preserved in the plain history entries
+ // (mainly scroll state and text data)
+ browser.__SS_restore_data = tabData.entries[activeIndex] || {};
+ browser.__SS_restore_text = tabData.text || "";
+ browser.__SS_restore_pageStyle = tabData.pageStyle || "";
+ browser.__SS_restore_tab = tab;
+ browser.__SS_restore = this.restoreDocument_proxy;
+ browser.addEventListener("load", browser.__SS_restore, true);
+ }
+
+ aWindow.setTimeout(function(){ _this.restoreHistory(aWindow, aTabs, aTabData, aIdMap); }, 0);
+ },
+
+ /**
+ * expands serialized history data into a session-history-entry instance
+ * @param aEntry
+ * Object containing serialized history data for a URL
+ * @param aIdMap
+ * Hash for ensuring unique frame IDs
+ * @returns nsISHEntry
+ */
+ _deserializeHistoryEntry: function sss_deserializeHistoryEntry(aEntry, aIdMap) {
+ var shEntry = Cc["@mozilla.org/browser/session-history-entry;1"].
+ createInstance(Ci.nsISHEntry);
+
+ var ioService = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ shEntry.setURI(ioService.newURI(aEntry.url, null, null));
+ shEntry.setTitle(aEntry.title || aEntry.url);
+ if (aEntry.subframe)
+ shEntry.setIsSubFrame(aEntry.subframe || false);
+ shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory;
+ if (aEntry.contentType)
+ shEntry.contentType = aEntry.contentType;
+
+ if (aEntry.cacheKey) {
+ var cacheKey = Cc["@mozilla.org/supports-PRUint32;1"].
+ createInstance(Ci.nsISupportsPRUint32);
+ cacheKey.data = aEntry.cacheKey;
+ shEntry.cacheKey = cacheKey;
+ }
+
+ if (aEntry.ID) {
+ // get a new unique ID for this frame (since the one from the last
+ // start might already be in use)
+ var id = aIdMap[aEntry.ID] || 0;
+ if (!id) {
+ for (id = Date.now(); id in aIdMap.used; id++);
+ aIdMap[aEntry.ID] = id;
+ aIdMap.used[id] = true;
+ }
+ shEntry.ID = id;
+ }
+
+ if (aEntry.scroll) {
+ var scrollPos = (aEntry.scroll || "0,0").split(",");
+ scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
+ shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
+ }
+
+ var postdata;
+ if (aEntry.postdata_b64) { // Firefox 3
+ postdata = atob(aEntry.postdata_b64);
+ } else if (aEntry.postdata) { // Firefox 2
+ postdata = aEntry.postdata;
+ }
+
+ if (postdata) {
+ var stream = Cc["@mozilla.org/io/string-input-stream;1"].
+ createInstance(Ci.nsIStringInputStream);
+ stream.setData(postdata, postdata.length);
+ shEntry.postData = stream;
+ }
+
+ if (aEntry.owner_b64) { // Firefox 3
+ var ownerInput = Cc["@mozilla.org/io/string-input-stream;1"].
+ createInstance(Ci.nsIStringInputStream);
+ var binaryData = atob(aEntry.owner_b64);
+ ownerInput.setData(binaryData, binaryData.length);
+ var binaryStream = Cc["@mozilla.org/binaryinputstream;1"].
+ createInstance(Ci.nsIObjectInputStream);
+ binaryStream.setInputStream(ownerInput);
+ try { // Catch possible deserialization exceptions
+ shEntry.owner = binaryStream.readObject(true);
+ } catch (ex) { debug(ex); }
+ } else if (aEntry.ownerURI) { // Firefox 2
+ var uriObj = ioService.newURI(aEntry.ownerURI, null, null);
+ shEntry.owner = Cc["@mozilla.org/scriptsecuritymanager;1"].
+ getService(Ci.nsIScriptSecurityManager).
+ getCodebasePrincipal(uriObj);
+ }
+
+ if (aEntry.children && shEntry instanceof Ci.nsISHContainer) {
+ for (var i = 0; i < aEntry.children.length; i++) {
+ shEntry.AddChild(this._deserializeHistoryEntry(aEntry.children[i], aIdMap), i);
+ }
+ }
+
+ return shEntry;
+ },
+
+ /**
+ * restores all sessionStorage "super cookies"
+ * @param aStorageData
+ * Storage data to be restored
+ * @param aDocShell
+ * A tab's docshell (containing the sessionStorage)
+ */
+ _deserializeSessionStorage: function sss_deserializeSessionStorage(aStorageData, aDocShell) {
+ let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ for (let url in aStorageData) {
+ let uri = ioService.newURI(url, null, null);
+ let docShell_191 = aDocShell.QueryInterface(Ci.nsIDocShell_MOZILLA_1_9_1_SessionStorage);
+ let storage = docShell_191.getSessionStorageForURI(uri);
+ for (let key in aStorageData[url]) {
+ try {
+ storage.setItem(key, aStorageData[url][key]);
+ }
+ catch (ex) { Cu.reportError(ex); } // throws e.g. for URIs that can't have sessionStorage
+ }
+ }
+ },
+
+ /**
+ * Restore properties to a loaded document
+ */
+ restoreDocument_proxy: function sss_restoreDocument_proxy(aEvent) {
+ // wait for the top frame to be loaded completely
+ if (!aEvent || !aEvent.originalTarget || !aEvent.originalTarget.defaultView || aEvent.originalTarget.defaultView != aEvent.originalTarget.defaultView.top) {
+ return;
+ }
+
+ // always call this before injecting content into a document!
+ function hasExpectedURL(aDocument, aURL)
+ !aURL || aURL.replace(/#.*/, "") == aDocument.location.href.replace(/#.*/, "");
+
+ // restore text data saved by Firefox 2.0/3.0
+ var textArray = this.__SS_restore_text ? this.__SS_restore_text.split(" ") : [];
+ function restoreTextData(aContent, aPrefix, aURL) {
+ textArray.forEach(function(aEntry) {
+ if (/^((?:\d+\|)*)(#?)([^\s=]+)=(.*)$/.test(aEntry) &&
+ RegExp.$1 == aPrefix && hasExpectedURL(aContent.document, aURL)) {
+ var document = aContent.document;
+ var node = RegExp.$2 ? document.getElementById(RegExp.$3) : document.getElementsByName(RegExp.$3)[0] || null;
+ if (node && "value" in node && node.type != "file") {
+ node.value = decodeURI(RegExp.$4);
+
+ var event = document.createEvent("UIEvents");
+ event.initUIEvent("input", true, true, aContent, 0);
+ node.dispatchEvent(event);
+ }
+ }
+ });
+ }
+
+ function restoreFormData(aDocument, aData, aURL) {
+ for (let key in aData) {
+ if (!hasExpectedURL(aDocument, aURL))
+ return;
+
+ let node = key.charAt(0) == "#" ? aDocument.getElementById(key.slice(1)) :
+ XPathHelper.resolve(aDocument, key);
+ if (!node)
+ continue;
+
+ let value = aData[key];
+ if (typeof value == "string" && node.type != "file") {
+ if (node.value == value)
+ continue; // don't dispatch an input event for no change
+
+ node.value = value;
+
+ let event = aDocument.createEvent("UIEvents");
+ event.initUIEvent("input", true, true, aDocument.defaultView, 0);
+ node.dispatchEvent(event);
+ }
+ else if (typeof value == "boolean")
+ node.checked = value;
+ else if (typeof value == "number")
+ try {
+ node.selectedIndex = value;
+ } catch (ex) { /* throws for invalid indices */ }
+ else if (value && value.type && value.type == node.type)
+ node.value = value.value;
+ else if (value && typeof value.indexOf == "function" && node.options) {
+ Array.forEach(node.options, function(aOpt, aIx) {
+ aOpt.selected = value.indexOf(aIx) > -1;
+ });
+ }
+ // NB: dispatching "change" events might have unintended side-effects
+ }
+ }
+
+ let selectedPageStyle = this.__SS_restore_pageStyle;
+ let window = this.ownerDocument.defaultView;
+ function restoreTextDataAndScrolling(aContent, aData, aPrefix) {
+ if (aData.formdata)
+ restoreFormData(aContent.document, aData.formdata, aData.url);
+ else
+ restoreTextData(aContent, aPrefix, aData.url);
+ if (aData.innerHTML) {
+ window.setTimeout(function() {
+ if (aContent.document.designMode == "on" &&
+ hasExpectedURL(aContent.document, aData.url)) {
+ aContent.document.body.innerHTML = aData.innerHTML;
+ }
+ }, 0);
+ }
+ if (aData.scroll && /(\d+),(\d+)/.test(aData.scroll)) {
+ aContent.scrollTo(RegExp.$1, RegExp.$2);
+ }
+ Array.forEach(aContent.document.styleSheets, function(aSS) {
+ aSS.disabled = aSS.title && aSS.title != selectedPageStyle;
+ });
+ for (var i = 0; i < aContent.frames.length; i++) {
+ if (aData.children && aData.children[i] &&
+ hasExpectedURL(aContent.document, aData.url)) {
+ restoreTextDataAndScrolling(aContent.frames[i], aData.children[i], aPrefix + i + "|");
+ }
+ }
+ }
+
+ // don't restore text data and scrolling state if the user has navigated
+ // away before the loading completed (except for in-page navigation)
+ if (hasExpectedURL(aEvent.originalTarget, this.__SS_restore_data.url)) {
+ var content = aEvent.originalTarget.defaultView;
+ if (this.currentURI.spec == "about:config") {
+ // unwrap the document for about:config because otherwise the properties
+ // of the XBL bindings - as the textbox - aren't accessible (see bug 350718)
+ content = content.wrappedJSObject;
+ }
+ restoreTextDataAndScrolling(content, this.__SS_restore_data, "");
+ this.markupDocumentViewer.authorStyleDisabled = selectedPageStyle == "_nostyle";
+
+ // notify the tabbrowser that this document has been completely restored
+ var event = this.ownerDocument.createEvent("Events");
+ event.initEvent("SSTabRestored", true, false);
+ this.__SS_restore_tab.dispatchEvent(event);
+ }
+
+ this.removeEventListener("load", this.__SS_restore, true);
+ delete this.__SS_restore_data;
+ delete this.__SS_restore_text;
+ delete this.__SS_restore_pageStyle;
+ delete this.__SS_restore_tab;
+ delete this.__SS_restore;
+ },
+
+ /**
+ * Restore visibility and dimension features to a window
+ * @param aWindow
+ * Window reference
+ * @param aWinData
+ * Object containing session data for the window
+ */
+ restoreWindowFeatures: function sss_restoreWindowFeatures(aWindow, aWinData) {
+ var hidden = (aWinData.hidden)?aWinData.hidden.split(","):[];
+ WINDOW_HIDEABLE_FEATURES.forEach(function(aItem) {
+ aWindow[aItem].visible = hidden.indexOf(aItem) == -1;
+ });
+
+ if (aWinData.isPopup) {
+ this._windows[aWindow.__SSi].isPopup = true;
+ if (aWindow.gURLBar) {
+ aWindow.gURLBar.readOnly = true;
+ aWindow.gURLBar.setAttribute("enablehistory", "false");
+ }
+ }
+ else {
+ delete this._windows[aWindow.__SSi].isPopup;
+ if (aWindow.gURLBar) {
+ aWindow.gURLBar.readOnly = false;
+ aWindow.gURLBar.setAttribute("enablehistory", "true");
+ }
+ }
+
+ var _this = this;
+ aWindow.setTimeout(function() {
+ _this.restoreDimensions.apply(_this, [aWindow, aWinData.width || 0,
+ aWinData.height || 0, "screenX" in aWinData ? aWinData.screenX : NaN,
+ "screenY" in aWinData ? aWinData.screenY : NaN,
+ aWinData.sizemode || "", aWinData.sidebar || ""]);
+ }, 0);
+ },
+
+ /**
+ * Restore a window's dimensions
+ * @param aWidth
+ * Window width
+ * @param aHeight
+ * Window height
+ * @param aLeft
+ * Window left
+ * @param aTop
+ * Window top
+ * @param aSizeMode
+ * Window size mode (eg: maximized)
+ * @param aSidebar
+ * Sidebar command
+ */
+ restoreDimensions: function sss_restoreDimensions(aWindow, aWidth, aHeight, aLeft, aTop, aSizeMode, aSidebar) {
+ var win = aWindow;
+ var _this = this;
+ function win_(aName) { return _this._getWindowDimension(win, aName); }
+
+ // only modify those aspects which aren't correct yet
+ if (aWidth && aHeight && (aWidth != win_("width") || aHeight != win_("height"))) {
+ aWindow.resizeTo(aWidth, aHeight);
+ }
+ if (!isNaN(aLeft) && !isNaN(aTop) && (aLeft != win_("screenX") || aTop != win_("screenY"))) {
+ aWindow.moveTo(aLeft, aTop);
+ }
+ if (aSizeMode && win_("sizemode") != aSizeMode)
+ {
+ switch (aSizeMode)
+ {
+ case "maximized":
+ aWindow.maximize();
+ break;
+ case "minimized":
+ aWindow.minimize();
+ break;
+ case "normal":
+ aWindow.restore();
+ break;
+ }
+ }
+ var sidebar = aWindow.document.getElementById("sidebar-box");
+ if (sidebar.getAttribute("sidebarcommand") != aSidebar) {
+ aWindow.toggleSidebar(aSidebar);
+ }
+ // since resizing/moving a window brings it to the foreground,
+ // we might want to re-focus the last focused window
+ if (this.windowToFocus) {
+ this.windowToFocus.content.focus();
+ }
+ },
+
+ /**
+ * Restores cookies (accepting both Firefox 2.0 and current format)
+ * @param aCookies
+ * Array of cookie objects
+ */
+ restoreCookies: function sss_restoreCookies(aCookies) {
+ if (aCookies.count && aCookies.domain1) {
+ // convert to the new cookie serialization format
+ var converted = [];
+ for (var i = 1; i <= aCookies.count; i++) {
+ // for simplicity we only accept the format we produced ourselves
+ var parsed = aCookies["value" + i].match(/^([^=;]+)=([^;]*);(?:domain=[^;]+;)?(?:path=([^;]*);)?(secure;)?(httponly;)?/);
+ if (parsed && /^https?:\/\/([^\/]+)/.test(aCookies["domain" + i]))
+ converted.push({
+ host: RegExp.$1, path: parsed[3], name: parsed[1], value: parsed[2],
+ secure: parsed[4], httponly: parsed[5]
+ });
+ }
+ aCookies = converted;
+ }
+
+ var cookieManager = Cc["@mozilla.org/cookiemanager;1"].
+ getService(Ci.nsICookieManager2);
+ // MAX_EXPIRY should be 2^63-1, but JavaScript can't handle that precision
+ var MAX_EXPIRY = Math.pow(2, 62);
+ for (i = 0; i < aCookies.length; i++) {
+ var cookie = aCookies[i];
+ try {
+ cookieManager.add(cookie.host, cookie.path || "", cookie.name || "", cookie.value, !!cookie.secure, !!cookie.httponly, true, "expiry" in cookie ? cookie.expiry : MAX_EXPIRY);
+ }
+ catch (ex) { Cu.reportError(ex); } // don't let a single cookie stop recovering
+ }
+ },
+
+/* ........ Disk Access .............. */
+
+ /**
+ * save state delayed by N ms
+ * marks window as dirty (i.e. data update can't be skipped)
+ * @param aWindow
+ * Window reference
+ * @param aDelay
+ * Milliseconds to delay
+ */
+ saveStateDelayed: function sss_saveStateDelayed(aWindow, aDelay) {
+ if (aWindow) {
+ this._dirtyWindows[aWindow.__SSi] = true;
+ }
+
+ if (!this._saveTimer && this._resume_from_crash &&
+ !this._inPrivateBrowsing) {
+ // interval until the next disk operation is allowed
+ var minimalDelay = this._lastSaveTime + this._interval - Date.now();
+
+ // if we have to wait, set a timer, otherwise saveState directly
+ aDelay = Math.max(minimalDelay, aDelay || 2000);
+ if (aDelay > 0) {
+ this._saveTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._saveTimer.init(this, aDelay, Ci.nsITimer.TYPE_ONE_SHOT);
+ }
+ else {
+ this.saveState();
+ }
+ }
+ },
+
+ /**
+ * save state to disk
+ * @param aUpdateAll
+ * Bool update all windows
+ */
+ saveState: function sss_saveState(aUpdateAll) {
+ // if crash recovery is disabled, only save session resuming information
+ if (!this._resume_from_crash && this._loadState == STATE_RUNNING)
+ return;
+
+ // if we're in private browsing mode, do nothing
+ if (this._inPrivateBrowsing)
+ return;
+
+ var oState = this._getCurrentState(aUpdateAll);
+ oState.session = {
+ state: this._loadState == STATE_RUNNING ? STATE_RUNNING_STR : STATE_STOPPED_STR,
+ lastUpdate: Date.now()
+ };
+ if (this._recentCrashes)
+ oState.session.recentCrashes = this._recentCrashes;
+
+ this._saveStateObject(oState);
+ },
+
+ /**
+ * write a state object to disk
+ */
+ _saveStateObject: function sss_saveStateObject(aStateObj) {
+ var stateString = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ // parentheses are for backwards compatibility with Firefox 2.0 and 3.0
+ stateString.data = "(" + this._toJSONString(aStateObj) + ")";
+
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ observerService.notifyObservers(stateString, "sessionstore-state-write", "");
+
+ // don't touch the file if an observer has deleted all state data
+ if (stateString.data)
+ this._writeFile(this._sessionFile, stateString.data);
+
+ this._lastSaveTime = Date.now();
+ },
+
+ /**
+ * delete session datafile and backup
+ */
+ _clearDisk: function sss_clearDisk() {
+ if (this._sessionFile.exists()) {
+ try {
+ this._sessionFile.remove(false);
+ }
+ catch (ex) { dump(ex + '\n'); } // couldn't remove the file - what now?
+ }
+ if (this._sessionFileBackup.exists()) {
+ try {
+ this._sessionFileBackup.remove(false);
+ }
+ catch (ex) { dump(ex + '\n'); } // couldn't remove the file - what now?
+ }
+ },
+
+/* ........ Auxiliary Functions .............. */
+
+ /**
+ * call a callback for all currently opened browser windows
+ * (might miss the most recent one)
+ * @param aFunc
+ * Callback each window is passed to
+ */
+ _forEachBrowserWindow: function sss_forEachBrowserWindow(aFunc) {
+ var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ var windowsEnum = windowMediator.getEnumerator("navigator:browser");
+
+ while (windowsEnum.hasMoreElements()) {
+ var window = windowsEnum.getNext();
+ if (window.__SSi) {
+ aFunc.call(this, window);
+ }
+ }
+ },
+
+ /**
+ * Returns most recent window
+ * @returns Window reference
+ */
+ _getMostRecentBrowserWindow: function sss_getMostRecentBrowserWindow() {
+ var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ return windowMediator.getMostRecentWindow("navigator:browser");
+ },
+
+ /**
+ * open a new browser window for a given session state
+ * called when restoring a multi-window session
+ * @param aState
+ * Object containing session data
+ */
+ _openWindowWithState: function sss_openWindowWithState(aState) {
+ var argString = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ argString.data = "";
+
+ //XXXzeniko shouldn't it be possible to set the window's dimensions here (as feature)?
+ var window = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher).
+ openWindow(null, this._prefBranch.getCharPref("chromeURL"), "_blank",
+ "chrome,dialog=no,all", argString);
+
+ do {
+ var ID = "window" + Math.random();
+ } while (ID in this._statesToRestore);
+ this._statesToRestore[(window.__SS_restoreID = ID)] = aState;
+
+ return window;
+ },
+
+ /**
+ * Whether or not to resume session, if not recovering from a crash.
+ * @returns bool
+ */
+ _doResumeSession: function sss_doResumeSession() {
+ if (this._clearingOnShutdown)
+ return false;
+
+ return this._prefBranch.getIntPref("startup.page") == 3 ||
+ this._prefBranch.getBoolPref("sessionstore.resume_session_once");
+ },
+
+ /**
+ * whether the user wants to load any other page at startup
+ * (except the homepage) - needed for determining whether to overwrite the current tabs
+ * C.f.: nsBrowserContentHandler's defaultArgs implementation.
+ * @returns bool
+ */
+ _isCmdLineEmpty: function sss_isCmdLineEmpty(aWindow) {
+ var defaultArgs = Cc["@mozilla.org/browser/clh;1"].
+ getService(Ci.nsIBrowserHandler).defaultArgs;
+ if (aWindow.arguments && aWindow.arguments[0] &&
+ aWindow.arguments[0] == defaultArgs)
+ aWindow.arguments[0] = null;
+
+ return !aWindow.arguments || !aWindow.arguments[0];
+ },
+
+ /**
+ * don't save sensitive data if the user doesn't want to
+ * (distinguishes between encrypted and non-encrypted sites)
+ * @param aIsHTTPS
+ * Bool is encrypted
+ * @returns bool
+ */
+ _checkPrivacyLevel: function sss_checkPrivacyLevel(aIsHTTPS) {
+ return this._prefBranch.getIntPref("sessionstore.privacy_level") < (aIsHTTPS ? PRIVACY_ENCRYPTED : PRIVACY_FULL);
+ },
+
+ /**
+ * on popup windows, the XULWindow's attributes seem not to be set correctly
+ * we use thus JSDOMWindow attributes for sizemode and normal window attributes
+ * (and hope for reasonable values when maximized/minimized - since then
+ * outerWidth/outerHeight aren't the dimensions of the restored window)
+ * @param aWindow
+ * Window reference
+ * @param aAttribute
+ * String sizemode | width | height | other window attribute
+ * @returns string
+ */
+ _getWindowDimension: function sss_getWindowDimension(aWindow, aAttribute) {
+ if (aAttribute == "sizemode") {
+ switch (aWindow.windowState) {
+ case aWindow.STATE_MAXIMIZED:
+ return "maximized";
+ case aWindow.STATE_MINIMIZED:
+ return "minimized";
+ default:
+ return "normal";
+ }
+ }
+
+ var dimension;
+ switch (aAttribute) {
+ case "width":
+ dimension = aWindow.outerWidth;
+ break;
+ case "height":
+ dimension = aWindow.outerHeight;
+ break;
+ default:
+ dimension = aAttribute in aWindow ? aWindow[aAttribute] : "";
+ break;
+ }
+
+ if (aWindow.windowState == aWindow.STATE_NORMAL) {
+ return dimension;
+ }
+ return aWindow.document.documentElement.getAttribute(aAttribute) || dimension;
+ },
+
+ /**
+ * Get nsIURI from string
+ * @param string
+ * @returns nsIURI
+ */
+ _getURIFromString: function sss_getURIFromString(aString) {
+ var ioService = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return ioService.newURI(aString, null, null);
+ },
+
+ /**
+ * Annotate a breakpad crash report with the currently selected tab's URL.
+ */
+ _updateCrashReportURL: function sss_updateCrashReportURL(aWindow) {
+ if (!Ci.nsICrashReporter) {
+ // if breakpad isn't built, don't bother next time at all
+ this._updateCrashReportURL = function(aWindow) {};
+ return;
+ }
+ try {
+ var currentURI = aWindow.getBrowser().currentURI.clone();
+ // if the current URI contains a username/password, remove it
+ try {
+ currentURI.userPass = "";
+ }
+ catch (ex) { } // ignore failures on about: URIs
+
+ var cr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsICrashReporter);
+ cr.annotateCrashReport("URL", currentURI.spec);
+ }
+ catch (ex) {
+ // don't make noise when crashreporter is built but not enabled
+ if (ex.result != Components.results.NS_ERROR_NOT_INITIALIZED)
+ debug(ex);
+ }
+ },
+
+ /**
+ * @param aState is a session state
+ * @param aRecentCrashes is the number of consecutive crashes
+ * @returns whether a restore page will be needed for the session state
+ */
+ _needsRestorePage: function sss_needsRestorePage(aState, aRecentCrashes) {
+ const SIX_HOURS_IN_MS = 6 * 60 * 60 * 1000;
+
+ // don't display the page when there's nothing to restore
+ let winData = aState.windows || null;
+ if (!winData || winData.length == 0)
+ return false;
+
+ // don't wrap a single about:sessionrestore page
+ if (winData.length == 1 && winData[0].tabs &&
+ winData[0].tabs.length == 1 && winData[0].tabs[0].entries &&
+ winData[0].tabs[0].entries.length == 1 &&
+ winData[0].tabs[0].entries[0].url == "about:sessionrestore")
+ return false;
+
+ // don't automatically restore in Safe Mode
+ let XRE = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
+ if (XRE.inSafeMode)
+ return true;
+
+ let max_resumed_crashes =
+ this._prefBranch.getIntPref("sessionstore.max_resumed_crashes");
+ let sessionAge = aState.session && aState.session.lastUpdate &&
+ (Date.now() - aState.session.lastUpdate);
+
+ return max_resumed_crashes != -1 &&
+ (aRecentCrashes > max_resumed_crashes ||
+ sessionAge && sessionAge >= SIX_HOURS_IN_MS);
+ },
+
+ /**
+ * safe eval'ing
+ */
+ _safeEval: function sss_safeEval(aStr) {
+ return Cu.evalInSandbox(aStr, new Cu.Sandbox("about:blank"));
+ },
+
+ /**
+ * Converts a JavaScript object into a JSON string
+ * (see http://www.json.org/ for more information).
+ *
+ * The inverse operation consists of JSON.parse(JSON_string).
+ *
+ * @param aJSObject is the object to be converted
+ * @returns the object's JSON representation
+ */
+ _toJSONString: function sss_toJSONString(aJSObject) {
+ // XXXzeniko drop the following keys used only for internal bookkeeping:
+ // _tabStillLoading, _hosts, _formDataSaved
+ let jsonString = JSON.stringify(aJSObject);
+
+ if (/[\u2028\u2029]/.test(jsonString)) {
+ // work-around for bug 485563 until we can use JSON.parse
+ // instead of evalInSandbox everywhere
+ jsonString = jsonString.replace(/[\u2028\u2029]/g,
+ function($0) "\\u" + $0.charCodeAt(0).toString(16));
+ }
+
+ return jsonString;
+ },
+
+ _notifyIfAllWindowsRestored: function sss_notifyIfAllWindowsRestored() {
+ if (this._restoreCount) {
+ this._restoreCount--;
+ if (this._restoreCount == 0) {
+ // This was the last window restored at startup, notify observers.
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ observerService.notifyObservers(null, NOTIFY_WINDOWS_RESTORED, "");
+ }
+ }
+ },
+
+ /**
+ * @param aWindow
+ * Window reference
+ * @returns whether this window's data is still cached in _statesToRestore
+ * because it's not fully loaded yet
+ */
+ _isWindowLoaded: function sss_isWindowLoaded(aWindow) {
+ return !aWindow.__SS_restoreID;
+ },
+
+ /**
+ * Replace "Loading..." with the tab label (with minimal side-effects)
+ * @param aString is the string the title is stored in
+ * @param aTabbrowser is a tabbrowser object, containing aTab
+ * @param aTab is the tab whose title we're updating & using
+ *
+ * @returns aString that has been updated with the new title
+ */
+ _replaceLoadingTitle : function sss_replaceLoadingTitle(aString, aTabbrowser, aTab) {
+ if (aString == aTabbrowser.mStringBundle.getString("tabs.loading")) {
+ aTabbrowser.setTabTitle(aTab);
+ [aString, aTab.label] = [aTab.label, aString];
+ }
+ return aString;
+ },
+
+ /**
+ * Resize this._closedWindows to the value of the pref, except in the case
+ * where we don't have any non-popup windows on Windows and Linux. Then we must
+ * resize such that we have at least one non-popup window.
+ */
+ _capClosedWindows : function sss_capClosedWindows() {
+ let maxWindowsUndo = this._prefBranch.getIntPref("sessionstore.max_windows_undo");
+ if (this._closedWindows.length <= maxWindowsUndo)
+ return;
+ let spliceTo = maxWindowsUndo;
+//@line 2775 "/builds/moz2_slave/linux_build/build/browser/components/sessionstore/src/nsSessionStore.js"
+ let normalWindowIndex = 0;
+ // try to find a non-popup window in this._closedWindows
+ while (normalWindowIndex < this._closedWindows.length &&
+ !!this._closedWindows[normalWindowIndex].isPopup)
+ normalWindowIndex++;
+ if (normalWindowIndex >= maxWindowsUndo)
+ spliceTo = normalWindowIndex + 1;
+//@line 2783 "/builds/moz2_slave/linux_build/build/browser/components/sessionstore/src/nsSessionStore.js"
+ this._closedWindows.splice(spliceTo);
+ },
+
+/* ........ Storage API .............. */
+
+ /**
+ * write file to disk
+ * @param aFile
+ * nsIFile
+ * @param aData
+ * String data
+ */
+ _writeFile: function sss_writeFile(aFile, aData) {
+ // init stream
+ var stream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ stream.init(aFile, 0x02 | 0x08 | 0x20, 0600, 0);
+
+ // convert to UTF-8
+ var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
+ createInstance(Ci.nsIScriptableUnicodeConverter);
+ converter.charset = "UTF-8";
+ var convertedData = converter.ConvertFromUnicode(aData);
+ convertedData += converter.Finish();
+
+ // write and close stream
+ stream.write(convertedData, convertedData.length);
+ if (stream instanceof Ci.nsISafeOutputStream) {
+ stream.finish();
+ } else {
+ stream.close();
+ }
+ }
+};
+
+let XPathHelper = {
+ // these two hashes should be kept in sync
+ namespaceURIs: { "xhtml": "http://www.w3.org/1999/xhtml" },
+ namespacePrefixes: { "http://www.w3.org/1999/xhtml": "xhtml" },
+
+ /**
+ * Generates an approximate XPath query to an (X)HTML node
+ */
+ generate: function sss_xph_generate(aNode) {
+ // have we reached the document node already?
+ if (!aNode.parentNode)
+ return "";
+
+ let prefix = this.namespacePrefixes[aNode.namespaceURI] || null;
+ let tag = (prefix ? prefix + ":" : "") + this.escapeName(aNode.localName);
+
+ // stop once we've found a tag with an ID
+ if (aNode.id)
+ return "//" + tag + "[@id=" + this.quoteArgument(aNode.id) + "]";
+
+ // count the number of previous sibling nodes of the same tag
+ // (and possible also the same name)
+ let count = 0;
+ let nName = aNode.name || null;
+ for (let n = aNode; (n = n.previousSibling); )
+ if (n.localName == aNode.localName && n.namespaceURI == aNode.namespaceURI &&
+ (!nName || n.name == nName))
+ count++;
+
+ // recurse until hitting either the document node or an ID'd node
+ return this.generate(aNode.parentNode) + "/" + tag +
+ (nName ? "[@name=" + this.quoteArgument(nName) + "]" : "") +
+ (count ? "[" + (count + 1) + "]" : "");
+ },
+
+ /**
+ * Resolves an XPath query generated by XPathHelper.generate
+ */
+ resolve: function sss_xph_resolve(aDocument, aQuery) {
+ let xptype = Ci.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE;
+ return aDocument.evaluate(aQuery, aDocument, this.resolveNS, xptype, null).singleNodeValue;
+ },
+
+ /**
+ * Namespace resolver for the above XPath resolver
+ */
+ resolveNS: function sss_xph_resolveNS(aPrefix) {
+ return XPathHelper.namespaceURIs[aPrefix] || null;
+ },
+
+ /**
+ * @returns valid XPath for the given node (usually just the local name itself)
+ */
+ escapeName: function sss_xph_escapeName(aName) {
+ // we can't just use the node's local name, if it contains
+ // special characters (cf. bug 485482)
+ return /^\w+$/.test(aName) ? aName :
+ "*[local-name()=" + this.quoteArgument(aName) + "]";
+ },
+
+ /**
+ * @returns a properly quoted string to insert into an XPath query
+ */
+ quoteArgument: function sss_xph_quoteArgument(aArg) {
+ return !/'/.test(aArg) ? "'" + aArg + "'" :
+ !/"/.test(aArg) ? '"' + aArg + '"' :
+ "concat('" + aArg.replace(/'+/g, "',\"$&\",'") + "')";
+ },
+
+ /**
+ * @returns an XPath query to all savable form field nodes
+ */
+ get restorableFormNodes() {
+ // for a comprehensive list of all available <INPUT> types see
+ // http://mxr.mozilla.org/mozilla-central/search?string=kInputTypeTable
+ let ignoreTypes = ["password", "hidden", "button", "image", "submit", "reset"];
+ // XXXzeniko work-around until lower-case has been implemented (bug 398389)
+ let toLowerCase = '"ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"';
+ let ignore = "not(translate(@type, " + toLowerCase + ")='" +
+ ignoreTypes.join("' or translate(@type, " + toLowerCase + ")='") + "')";
+ let formNodesXPath = "//textarea|//select|//xhtml:textarea|//xhtml:select|" +
+ "//input[" + ignore + "]|//xhtml:input[" + ignore + "]";
+
+ delete this.restorableFormNodes;
+ return (this.restorableFormNodes = formNodesXPath);
+ }
+};
+
+// see nsPrivateBrowsingService.js
+String.prototype.hasRootDomain = function hasRootDomain(aDomain)
+{
+ let index = this.indexOf(aDomain);
+ if (index == -1)
+ return false;
+
+ if (this == aDomain)
+ return true;
+
+ let prevChar = this[index - 1];
+ return (index == (this.length - aDomain.length)) &&
+ (prevChar == "." || prevChar == "/");
+}
+
+function NSGetModule(aComMgr, aFileSpec)
+ XPCOMUtils.generateModule([SessionStoreService]);
diff --git a/bundles/XO/components/nsSetDefaultBrowser.js b/bundles/XO/components/nsSetDefaultBrowser.js
new file mode 100755
index 0000000..e8ddfca
--- /dev/null
+++ b/bundles/XO/components/nsSetDefaultBrowser.js
@@ -0,0 +1,72 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Default Browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Bill Law <law@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * -setDefaultBrowser commandline handler
+ * Makes the current executable the "default browser".
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function nsSetDefaultBrowser() {}
+
+nsSetDefaultBrowser.prototype = {
+ handle: function nsSetDefault_handle(aCmdline) {
+ if (aCmdline.handleFlag("setDefaultBrowser", false)) {
+ var shell = Cc["@mozilla.org/browser/shell-service;1"].
+ getService(Ci.nsIShellService);
+ shell.setDefaultBrowser(true, true);
+ }
+ },
+
+ helpInfo: " -setDefaultBrowser Set this app as the default browser.\n",
+
+ classDescription: "Default Browser Cmdline Handler",
+ contractID: "@mozilla.org/browser/default-browser-clh;1",
+ classID: Components.ID("{F57899D0-4E2C-4ac6-9E29-50C736103B0C}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsICommandLineHandler]),
+ _xpcom_categories: [{
+ category: "command-line-handler",
+ entry: "m-setdefaultbrowser"
+ }]
+}
+
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule([nsSetDefaultBrowser]);
+}
diff --git a/bundles/XO/components/nsSidebar.js b/bundles/XO/components/nsSidebar.js
new file mode 100755
index 0000000..63a76da
--- /dev/null
+++ b/bundles/XO/components/nsSidebar.js
@@ -0,0 +1,333 @@
+//@line 43 "/builds/moz2_slave/linux_build/build/browser/components/sidebar/src/nsSidebar.js"
+
+/*
+ * No magic constructor behaviour, as is de rigeur for XPCOM.
+ * If you must perform some initialization, and it could possibly fail (even
+ * due to an out-of-memory condition), you should use an Init method, which
+ * can convey failure appropriately (thrown exception in JS,
+ * NS_FAILED(nsresult) return in C++).
+ *
+ * In JS, you can actually cheat, because a thrown exception will cause the
+ * CreateInstance call to fail in turn, but not all languages are so lucky.
+ * (Though ANSI C++ provides exceptions, they are verboten in Mozilla code
+ * for portability reasons -- and even when you're building completely
+ * platform-specific code, you can't throw across an XPCOM method boundary.)
+ */
+
+const DEBUG = false; /* set to false to suppress debug messages */
+
+const SIDEBAR_CONTRACTID = "@mozilla.org/sidebar;1";
+const SIDEBAR_CID = Components.ID("{22117140-9c6e-11d3-aaf1-00805f8a4905}");
+const nsISupports = Components.interfaces.nsISupports;
+const nsIFactory = Components.interfaces.nsIFactory;
+const nsISidebar = Components.interfaces.nsISidebar;
+const nsISidebarExternal = Components.interfaces.nsISidebarExternal;
+const nsIClassInfo = Components.interfaces.nsIClassInfo;
+
+// File extension for Sherlock search plugin description files
+const SHERLOCK_FILE_EXT_REGEXP = /\.src$/i;
+
+function nsSidebar()
+{
+ const PROMPTSERVICE_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
+ const nsIPromptService = Components.interfaces.nsIPromptService;
+ this.promptService =
+ Components.classes[PROMPTSERVICE_CONTRACTID].getService(nsIPromptService);
+
+ const SEARCHSERVICE_CONTRACTID = "@mozilla.org/browser/search-service;1";
+ const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
+ this.searchService =
+ Components.classes[SEARCHSERVICE_CONTRACTID].getService(nsIBrowserSearchService);
+}
+
+nsSidebar.prototype.nc = "http://home.netscape.com/NC-rdf#";
+
+function sidebarURLSecurityCheck(url)
+{
+ if (!/^(https?:|ftp:)/i.test(url)) {
+ Components.utils.reportError("Invalid argument passed to window.sidebar.addPanel: Unsupported panel URL." );
+ return false;
+ }
+ return true;
+}
+
+/* decorate prototype to provide ``class'' methods and property accessors */
+nsSidebar.prototype.addPanel =
+function (aTitle, aContentURL, aCustomizeURL)
+{
+ debug("addPanel(" + aTitle + ", " + aContentURL + ", " +
+ aCustomizeURL + ")");
+
+ return this.addPanelInternal(aTitle, aContentURL, aCustomizeURL, false);
+}
+
+nsSidebar.prototype.addPersistentPanel =
+function(aTitle, aContentURL, aCustomizeURL)
+{
+ debug("addPersistentPanel(" + aTitle + ", " + aContentURL + ", " +
+ aCustomizeURL + ")\n");
+
+ return this.addPanelInternal(aTitle, aContentURL, aCustomizeURL, true);
+}
+
+nsSidebar.prototype.addPanelInternal =
+function (aTitle, aContentURL, aCustomizeURL, aPersist)
+{
+ var WINMEDSVC = Components.classes['@mozilla.org/appshell/window-mediator;1']
+ .getService(Components.interfaces.nsIWindowMediator);
+ var win = WINMEDSVC.getMostRecentWindow( "navigator:browser" );
+
+ if (!sidebarURLSecurityCheck(aContentURL))
+ return;
+
+ var uri = null;
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+ try {
+ uri = ioService.newURI(aContentURL, null, null);
+ }
+ catch(ex) { return; }
+
+ win.PlacesUIUtils.showMinimalAddBookmarkUI(uri, aTitle, null, null, true, true);
+}
+
+nsSidebar.prototype.validateSearchEngine =
+function (engineURL, iconURL)
+{
+ try
+ {
+ // Make sure we're using HTTP, HTTPS, or FTP.
+ if (! /^(https?|ftp):\/\//i.test(engineURL))
+ throw "Unsupported search engine URL";
+
+ // Make sure we're using HTTP, HTTPS, or FTP and refering to a
+ // .gif/.jpg/.jpeg/.png/.ico file for the icon.
+ if (iconURL &&
+ ! /^(https?|ftp):\/\/.+\.(gif|jpg|jpeg|png|ico)$/i.test(iconURL))
+ throw "Unsupported search icon URL.";
+ }
+ catch(ex)
+ {
+ debug(ex);
+ Components.utils.reportError("Invalid argument passed to window.sidebar.addSearchEngine: " + ex);
+
+ var searchBundle = srGetStrBundle("chrome://global/locale/search/search.properties");
+ var brandBundle = srGetStrBundle("chrome://branding/locale/brand.properties");
+ var brandName = brandBundle.GetStringFromName("brandShortName");
+ var title = searchBundle.GetStringFromName("error_invalid_engine_title");
+ var msg = searchBundle.formatStringFromName("error_invalid_engine_msg",
+ [brandName], 1);
+ var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Components.interfaces.nsIWindowWatcher);
+ ww.getNewPrompter(null).alert(title, msg);
+ return false;
+ }
+
+ return true;
+}
+
+// The suggestedTitle and suggestedCategory parameters are ignored, but remain
+// for backward compatibility.
+nsSidebar.prototype.addSearchEngine =
+function (engineURL, iconURL, suggestedTitle, suggestedCategory)
+{
+ debug("addSearchEngine(" + engineURL + ", " + iconURL + ", " +
+ suggestedCategory + ", " + suggestedTitle + ")");
+
+ if (!this.validateSearchEngine(engineURL, iconURL))
+ return;
+
+ // OpenSearch files will likely be far more common than Sherlock files, and
+ // have less consistent suffixes, so we assume that ".src" is a Sherlock
+ // (text) file, and anything else is OpenSearch (XML).
+ var dataType;
+ if (SHERLOCK_FILE_EXT_REGEXP.test(engineURL))
+ dataType = Components.interfaces.nsISearchEngine.DATA_TEXT;
+ else
+ dataType = Components.interfaces.nsISearchEngine.DATA_XML;
+
+ this.searchService.addEngine(engineURL, dataType, iconURL, true);
+}
+
+// This function exists largely to implement window.external.AddSearchProvider(),
+// to match other browsers' APIs. The capitalization, although nonstandard here,
+// is therefore important.
+nsSidebar.prototype.AddSearchProvider =
+function (aDescriptionURL)
+{
+ // Get the favicon URL for the current page, or our best guess at the current
+ // page since we don't have easy access to the active document. Most search
+ // engines will override this with an icon specified in the OpenSearch
+ // description anyway.
+ var WINMEDSVC = Components.classes['@mozilla.org/appshell/window-mediator;1']
+ .getService(Components.interfaces.nsIWindowMediator);
+ var win = WINMEDSVC.getMostRecentWindow("navigator:browser");
+ var browser = win.document.getElementById("content");
+ var iconURL = "";
+ // Use documentURIObject in the check for shouldLoadFavIcon so that we
+ // do the right thing with about:-style error pages. Bug 453442
+ if (browser.shouldLoadFavIcon(browser.selectedBrowser
+ .contentDocument
+ .documentURIObject))
+ iconURL = win.gProxyFavIcon.getAttribute("src");
+
+ if (!this.validateSearchEngine(aDescriptionURL, iconURL))
+ return;
+
+ const typeXML = Components.interfaces.nsISearchEngine.DATA_XML;
+ this.searchService.addEngine(aDescriptionURL, typeXML, iconURL, true);
+}
+
+// This function exists to implement window.external.IsSearchProviderInstalled(),
+// for compatibility with other browsers. It will return an integer value
+// indicating whether the given engine is installed for the current user.
+// However, it is currently stubbed out due to security/privacy concerns
+// stemming from difficulties in determining what domain issued the request.
+// See bug 340604 and
+// http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/issearchproviderinstalled.asp .
+// XXX Implement this!
+nsSidebar.prototype.IsSearchProviderInstalled =
+function (aSearchURL)
+{
+ return 0;
+}
+
+nsSidebar.prototype.addMicrosummaryGenerator =
+function (generatorURL)
+{
+ debug("addMicrosummaryGenerator(" + generatorURL + ")");
+
+ if (!/^https?:/i.test(generatorURL))
+ return;
+
+ var stringBundle = srGetStrBundle("chrome://browser/locale/sidebar/sidebar.properties");
+ var titleMessage = stringBundle.GetStringFromName("addMicsumGenConfirmTitle");
+ var dialogMessage = stringBundle.formatStringFromName("addMicsumGenConfirmText", [generatorURL], 1);
+
+ if (!this.promptService.confirm(null, titleMessage, dialogMessage))
+ return;
+
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"].
+ getService(Components.interfaces.nsIIOService);
+ var generatorURI = ioService.newURI(generatorURL, null, null);
+
+ var microsummaryService = Components.classes["@mozilla.org/microsummary/service;1"].
+ getService(Components.interfaces.nsIMicrosummaryService);
+ if (microsummaryService)
+ microsummaryService.addGenerator(generatorURI);
+}
+
+// property of nsIClassInfo
+nsSidebar.prototype.flags = nsIClassInfo.DOM_OBJECT;
+
+// property of nsIClassInfo
+nsSidebar.prototype.classDescription = "Sidebar";
+
+// method of nsIClassInfo
+nsSidebar.prototype.getInterfaces = function(count) {
+ var interfaceList = [nsISidebar, nsISidebarExternal, nsIClassInfo];
+ count.value = interfaceList.length;
+ return interfaceList;
+}
+
+// method of nsIClassInfo
+nsSidebar.prototype.getHelperForLanguage = function(count) {return null;}
+
+nsSidebar.prototype.QueryInterface =
+function (iid) {
+ if (iid.equals(nsISidebar) ||
+ iid.equals(nsISidebarExternal) ||
+ iid.equals(nsIClassInfo) ||
+ iid.equals(nsISupports))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+}
+
+var sidebarModule = new Object();
+
+sidebarModule.registerSelf =
+function (compMgr, fileSpec, location, type)
+{
+ debug("registering (all right -- a JavaScript module!)");
+ compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+
+ compMgr.registerFactoryLocation(SIDEBAR_CID,
+ "Sidebar JS Component",
+ SIDEBAR_CONTRACTID,
+ fileSpec,
+ location,
+ type);
+
+ const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1";
+ const nsICategoryManager = Components.interfaces.nsICategoryManager;
+ var catman = Components.classes[CATMAN_CONTRACTID].
+ getService(nsICategoryManager);
+
+ const JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY = "JavaScript global property";
+ catman.addCategoryEntry(JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY,
+ "sidebar",
+ SIDEBAR_CONTRACTID,
+ true,
+ true);
+
+ catman.addCategoryEntry(JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY,
+ "external",
+ SIDEBAR_CONTRACTID,
+ true,
+ true);
+}
+
+sidebarModule.getClassObject =
+function (compMgr, cid, iid) {
+ if (!cid.equals(SIDEBAR_CID))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+
+ if (!iid.equals(Components.interfaces.nsIFactory))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ return sidebarFactory;
+}
+
+sidebarModule.canUnload =
+function(compMgr)
+{
+ debug("Unloading component.");
+ return true;
+}
+
+/* factory object */
+var sidebarFactory = new Object();
+
+sidebarFactory.createInstance =
+function (outer, iid) {
+ debug("CI: " + iid);
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ return (new nsSidebar()).QueryInterface(iid);
+}
+
+/* entrypoint */
+function NSGetModule(compMgr, fileSpec) {
+ return sidebarModule;
+}
+
+/* static functions */
+if (DEBUG)
+ debug = function (s) { dump("-*- sidebar component: " + s + "\n"); }
+else
+ debug = function (s) {}
+
+// String bundle service
+var gStrBundleService = null;
+
+function srGetStrBundle(path)
+{
+ if (!gStrBundleService)
+ gStrBundleService =
+ Components.classes["@mozilla.org/intl/stringbundle;1"]
+ .getService(Components.interfaces.nsIStringBundleService);
+
+ return gStrBundleService.createBundle(path);
+}
diff --git a/bundles/XO/components/nsTaggingService.js b/bundles/XO/components/nsTaggingService.js
new file mode 100755
index 0000000..1ca96aa
--- /dev/null
+++ b/bundles/XO/components/nsTaggingService.js
@@ -0,0 +1,663 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * The Original Code is the Places Tagging Service.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Asaf Romano <mano@mozilla.com> (Original Author)
+ * Dietrich Ayala <dietrich@mozilla.com>
+ * Marco Bonardo <mak77@bonardo.net>
+ * Drew Willcoxon <adw@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const NH_CONTRACTID = "@mozilla.org/browser/nav-history-service;1";
+const BMS_CONTRACTID = "@mozilla.org/browser/nav-bookmarks-service;1";
+const IO_CONTRACTID = "@mozilla.org/network/io-service;1";
+const ANNO_CONTRACTID = "@mozilla.org/browser/annotation-service;1";
+const FAV_CONTRACTID = "@mozilla.org/browser/favicon-service;1";
+const OBSS_CONTRACTID = "@mozilla.org/observer-service;1";
+
+var gIoService = Cc[IO_CONTRACTID].getService(Ci.nsIIOService);
+
+/**
+ * The Places Tagging Service
+ */
+function TaggingService() {
+ this._bms = Cc[BMS_CONTRACTID].getService(Ci.nsINavBookmarksService);
+ this._bms.addObserver(this, false);
+
+ this._obss = Cc[OBSS_CONTRACTID].getService(Ci.nsIObserverService);
+ this._obss.addObserver(this, "xpcom-shutdown", false);
+}
+
+TaggingService.prototype = {
+ get _history() {
+ if (!this.__history)
+ this.__history = Cc[NH_CONTRACTID].getService(Ci.nsINavHistoryService);
+ return this.__history;
+ },
+
+ get _annos() {
+ if (!this.__annos)
+ this.__annos = Cc[ANNO_CONTRACTID].getService(Ci.nsIAnnotationService);
+ return this.__annos;
+ },
+
+ // Feed XPCOMUtils
+ classDescription: "Places Tagging Service",
+ contractID: "@mozilla.org/browser/tagging-service;1",
+ classID: Components.ID("{bbc23860-2553-479d-8b78-94d9038334f7}"),
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsITaggingService,
+ Ci.nsINavBookmarkObserver_MOZILLA_1_9_1_ADDITIONS,
+ Ci.nsINavBookmarkObserver,
+ Ci.nsIObserver]),
+
+ /**
+ * If there's no tag with the given name or id, null is returned;
+ */
+ _getTagResult: function TS__getTagResult(aTagNameOrId) {
+ if (!aTagNameOrId)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ var tagId = null;
+ if (typeof(aTagNameOrId) == "string")
+ tagId = this._getItemIdForTag(aTagNameOrId);
+ else
+ tagId = aTagNameOrId;
+
+ if (tagId == -1)
+ return null;
+
+ var options = this._history.getNewQueryOptions();
+ var query = this._history.getNewQuery();
+ query.setFolders([tagId], 1);
+ var result = this._history.executeQuery(query, options);
+ return result;
+ },
+
+ /**
+ * Creates a tag container under the tags-root with the given name.
+ *
+ * @param aName
+ * the name for the new container.
+ * @returns the id of the new container.
+ */
+ _createTag: function TS__createTag(aName) {
+ return this._bms.createFolder(this._bms.tagsFolder, aName,
+ this._bms.DEFAULT_INDEX);
+ },
+
+ /**
+ * Checks whether the given uri is tagged with the given tag.
+ *
+ * @param [in] aURI
+ * url to check for
+ * @param [in] aTagName
+ * the tag to check for
+ * @returns the item id if the URI is tagged with the given tag, -1
+ * otherwise.
+ */
+ _getItemIdForTaggedURI: function TS__getItemIdForTaggedURI(aURI, aTagName) {
+ var tagId = this._getItemIdForTag(aTagName);
+ if (tagId == -1)
+ return -1;
+ var bookmarkIds = this._bms.getBookmarkIdsForURI(aURI, {});
+ for (var i=0; i < bookmarkIds.length; i++) {
+ var parent = this._bms.getFolderIdForItem(bookmarkIds[i]);
+ if (parent == tagId)
+ return bookmarkIds[i];
+ }
+ return -1;
+ },
+
+ /**
+ * Returns the folder id for a tag, or -1 if not found.
+ * @param [in] aTag
+ * string tag to search for
+ * @returns integer id for the bookmark folder for the tag
+ */
+ _getItemIdForTag: function TS_getItemIdForTag(aTagName) {
+ for (var i in this._tagFolders) {
+ if (aTagName.toLowerCase() == this._tagFolders[i].toLowerCase())
+ return parseInt(i);
+ }
+ return -1;
+ },
+
+ // nsITaggingService
+ tagURI: function TS_tagURI(aURI, aTags) {
+ if (!aURI || !aTags)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ this._bms.runInBatchMode({
+ _self: this,
+ runBatched: function(aUserData) {
+ for (var i = 0; i < aTags.length; i++) {
+ var tag = aTags[i];
+ var tagId = null;
+ if (typeof(tag) == "number") {
+ // is it a tag folder id?
+ if (this._self._tagFolders[tag]) {
+ tagId = tag;
+ tag = this._self._tagFolders[tagId];
+ }
+ else
+ throw Cr.NS_ERROR_INVALID_ARG;
+ }
+ else {
+ tagId = this._self._getItemIdForTag(tag);
+ if (tagId == -1)
+ tagId = this._self._createTag(tag);
+ }
+
+ var itemId = this._self._getItemIdForTaggedURI(aURI, tag);
+ if (itemId == -1)
+ this._self._bms.insertBookmark(tagId, aURI,
+ this._self._bms.DEFAULT_INDEX, null);
+
+ // Rename the tag container so the Places view would match the
+ // most-recent user-typed values.
+ var currentTagTitle = this._self._bms.getItemTitle(tagId);
+ if (currentTagTitle != tag) {
+ this._self._bms.setItemTitle(tagId, tag);
+ this._self._tagFolders[tagId] = tag;
+ }
+ }
+ }
+ }, null);
+ },
+
+ /**
+ * Removes the tag container from the tags-root if the given tag is empty.
+ *
+ * @param aTagId
+ * the item-id of the tag element under the tags root
+ */
+ _removeTagIfEmpty: function TS__removeTagIfEmpty(aTagId) {
+ var result = this._getTagResult(aTagId);
+ if (!result)
+ return;
+ var node = result.root;
+ node.QueryInterface(Ci.nsINavHistoryContainerResultNode);
+ node.containerOpen = true;
+ var cc = node.childCount;
+ node.containerOpen = false;
+ if (cc == 0)
+ this._bms.removeFolder(node.itemId);
+ },
+
+ // nsITaggingService
+ untagURI: function TS_untagURI(aURI, aTags) {
+ if (!aURI)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ if (!aTags) {
+ // see IDL.
+ // XXXmano: write a perf-sensitive version of this code path...
+ aTags = this.getTagsForURI(aURI, { });
+ }
+
+ this._bms.runInBatchMode({
+ _self: this,
+ runBatched: function(aUserData) {
+ for (var i = 0; i < aTags.length; i++) {
+ var tag = aTags[i];
+ var tagId = null;
+ if (typeof(tag) == "number") {
+ // is it a tag folder id?
+ if (this._self._tagFolders[tag]) {
+ tagId = tag;
+ tag = this._self._tagFolders[tagId];
+ }
+ else
+ throw Cr.NS_ERROR_INVALID_ARG;
+ }
+ else
+ tagId = this._self._getItemIdForTag(tag);
+
+ if (tagId != -1) {
+ var itemId = this._self._getItemIdForTaggedURI(aURI, tag);
+ if (itemId != -1) {
+ this._self._bms.removeItem(itemId);
+ this._self._removeTagIfEmpty(tagId);
+ }
+ }
+ }
+ }
+ }, null);
+ },
+
+ // nsITaggingService
+ getURIsForTag: function TS_getURIsForTag(aTag) {
+ if (!aTag || aTag.length == 0)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ var uris = [];
+ var tagResult = this._getTagResult(aTag);
+ if (tagResult) {
+ var tagNode = tagResult.root;
+ tagNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
+ tagNode.containerOpen = true;
+ var cc = tagNode.childCount;
+ for (var i = 0; i < cc; i++) {
+ try {
+ uris.push(gIoService.newURI(tagNode.getChild(i).uri, null, null));
+ } catch (ex) {
+ // This is an invalid node, tags should only contain valid uri nodes.
+ // continue to next node.
+ }
+ }
+ tagNode.containerOpen = false;
+ }
+ return uris;
+ },
+
+ // nsITaggingService
+ getTagsForURI: function TS_getTagsForURI(aURI, aCount) {
+ if (!aURI)
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ var tags = [];
+ var bookmarkIds = this._bms.getBookmarkIdsForURI(aURI, {});
+ for (var i=0; i < bookmarkIds.length; i++) {
+ var folderId = this._bms.getFolderIdForItem(bookmarkIds[i]);
+ if (this._tagFolders[folderId])
+ tags.push(this._tagFolders[folderId]);
+ }
+
+ // sort the tag list
+ tags.sort(function(a, b) {
+ return a.toLowerCase().localeCompare(b.toLowerCase());
+ });
+ aCount.value = tags.length;
+ return tags;
+ },
+
+ __tagFolders: null,
+ get _tagFolders() {
+ if (!this.__tagFolders) {
+ this.__tagFolders = [];
+ var options = this._history.getNewQueryOptions();
+ var query = this._history.getNewQuery();
+ query.setFolders([this._bms.tagsFolder], 1);
+ var tagsResult = this._history.executeQuery(query, options);
+ var root = tagsResult.root;
+ root.containerOpen = true;
+ var cc = root.childCount;
+ for (var i=0; i < cc; i++) {
+ var child = root.getChild(i);
+ this.__tagFolders[child.itemId] = child.title;
+ }
+ root.containerOpen = false;
+ }
+
+ return this.__tagFolders;
+ },
+
+ // nsITaggingService
+ get allTags() {
+ var allTags = [];
+ for (var i in this._tagFolders)
+ allTags.push(this._tagFolders[i]);
+ // sort the tag list
+ allTags.sort(function(a, b) {
+ return a.toLowerCase().localeCompare(b.toLowerCase());
+ });
+ return allTags;
+ },
+
+ // nsIObserver
+ observe: function TS_observe(aSubject, aTopic, aData) {
+ if (aTopic == "xpcom-shutdown") {
+ this._bms.removeObserver(this);
+ this._obss.removeObserver(this, "xpcom-shutdown");
+ }
+ },
+
+ /**
+ * If the only bookmark items associated with aURI are contained in tag
+ * folders, returns the IDs of those tag folders. This can be the case if
+ * the URI was bookmarked and tagged at some point, but the bookmark was
+ * removed, leaving only the bookmark items in tag folders. Returns null
+ * if the URI is either properly bookmarked or not tagged.
+ *
+ * @param aURI
+ * A URI (string) that may or may not be bookmarked
+ * @returns null or an array of tag IDs
+ */
+ _getTagsIfUnbookmarkedURI: function TS__getTagsIfUnbookmarkedURI(aURI) {
+ var tagIds = [];
+ var isBookmarked = false;
+ var itemIds = this._bms.getBookmarkIdsForURI(aURI, {});
+
+ for (let i = 0; !isBookmarked && i < itemIds.length; i++) {
+ var parentId = this._bms.getFolderIdForItem(itemIds[i]);
+ if (this._tagFolders[parentId])
+ tagIds.push(parentId);
+ else
+ isBookmarked = true;
+ }
+
+ return !isBookmarked && tagIds.length > 0 ? tagIds : null;
+ },
+
+ // boolean to indicate if we're in a batch
+ _inBatch: false,
+
+ // maps the IDs of bookmarks in the process of being removed to their URIs
+ _itemsInRemoval: {},
+
+ // nsINavBookmarkObserver
+ onBeginUpdateBatch: function() {
+ this._inBatch = true;
+ },
+ onEndUpdateBatch: function() {
+ this._inBatch = false;
+ },
+ onItemAdded: function(aItemId, aFolderId, aIndex) {
+ if (aFolderId == this._bms.tagsFolder &&
+ this._bms.getItemType(aItemId) == this._bms.TYPE_FOLDER)
+ this._tagFolders[aItemId] = this._bms.getItemTitle(aItemId);
+ },
+ onBeforeItemRemoved: function(aItemId) {
+ // Remember the bookmark's URI, because it will be gone by the time
+ // onItemRemoved() is called. getBookmarkURI() will throw if the item is
+ // not a bookmark, which is fine.
+ try {
+ this._itemsInRemoval[aItemId] = this._bms.getBookmarkURI(aItemId);
+ }
+ catch (e) {}
+ },
+ onItemRemoved: function(aItemId, aFolderId, aIndex) {
+ var itemURI = this._itemsInRemoval[aItemId];
+ delete this._itemsInRemoval[aItemId];
+
+ // Item is a tag folder.
+ if (aFolderId == this._bms.tagsFolder && this._tagFolders[aItemId])
+ delete this._tagFolders[aItemId];
+
+ // Item is a bookmark that was removed from a non-tag folder.
+ else if (itemURI && !this._tagFolders[aFolderId]) {
+
+ // If the only bookmark items now associated with the bookmark's URI are
+ // contained in tag folders, the URI is no longer properly bookmarked, so
+ // untag it.
+ var tagIds = this._getTagsIfUnbookmarkedURI(itemURI);
+ if (tagIds)
+ this.untagURI(itemURI, tagIds);
+ }
+ },
+ onItemChanged: function(aItemId, aProperty, aIsAnnotationProperty, aValue) {
+ if (this._tagFolders[aItemId])
+ this._tagFolders[aItemId] = this._bms.getItemTitle(aItemId);
+ },
+ onItemVisited: function(aItemId, aVisitID, time) {},
+ onItemMoved: function(aItemId, aOldParent, aOldIndex, aNewParent, aNewIndex) {
+ if (this._tagFolders[aItemId] && this._bms.tagFolder == aOldParent &&
+ this._bms.tagFolder != aNewParent)
+ delete this._tagFolders[aItemId];
+ }
+};
+
+// Implements nsIAutoCompleteResult
+function TagAutoCompleteResult(searchString, searchResult,
+ defaultIndex, errorDescription,
+ results, comments) {
+ this._searchString = searchString;
+ this._searchResult = searchResult;
+ this._defaultIndex = defaultIndex;
+ this._errorDescription = errorDescription;
+ this._results = results;
+ this._comments = comments;
+}
+
+TagAutoCompleteResult.prototype = {
+
+ /**
+ * The original search string
+ */
+ get searchString() {
+ return this._searchString;
+ },
+
+ /**
+ * The result code of this result object, either:
+ * RESULT_IGNORED (invalid searchString)
+ * RESULT_FAILURE (failure)
+ * RESULT_NOMATCH (no matches found)
+ * RESULT_SUCCESS (matches found)
+ */
+ get searchResult() {
+ return this._searchResult;
+ },
+
+ /**
+ * Index of the default item that should be entered if none is selected
+ */
+ get defaultIndex() {
+ return this._defaultIndex;
+ },
+
+ /**
+ * A string describing the cause of a search failure
+ */
+ get errorDescription() {
+ return this._errorDescription;
+ },
+
+ /**
+ * The number of matches
+ */
+ get matchCount() {
+ return this._results.length;
+ },
+
+ /**
+ * Get the value of the result at the given index
+ */
+ getValueAt: function PTACR_getValueAt(index) {
+ return this._results[index];
+ },
+
+ /**
+ * Get the comment of the result at the given index
+ */
+ getCommentAt: function PTACR_getCommentAt(index) {
+ return this._comments[index];
+ },
+
+ /**
+ * Get the style hint for the result at the given index
+ */
+ getStyleAt: function PTACR_getStyleAt(index) {
+ if (!this._comments[index])
+ return null; // not a category label, so no special styling
+
+ if (index == 0)
+ return "suggestfirst"; // category label on first line of results
+
+ return "suggesthint"; // category label on any other line of results
+ },
+
+ /**
+ * Get the image for the result at the given index
+ */
+ getImageAt: function PTACR_getImageAt(index) {
+ return null;
+ },
+
+ /**
+ * Remove the value at the given index from the autocomplete results.
+ * If removeFromDb is set to true, the value should be removed from
+ * persistent storage as well.
+ */
+ removeValueAt: function PTACR_removeValueAt(index, removeFromDb) {
+ this._results.splice(index, 1);
+ this._comments.splice(index, 1);
+ },
+
+ QueryInterface: function(aIID) {
+ if (!aIID.equals(Ci.nsIAutoCompleteResult) && !aIID.equals(Ci.nsISupports))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ return this;
+ }
+};
+
+// Implements nsIAutoCompleteSearch
+function TagAutoCompleteSearch() {
+}
+
+TagAutoCompleteSearch.prototype = {
+ _stopped : false,
+
+ get tagging() {
+ let svc = Cc["@mozilla.org/browser/tagging-service;1"].
+ getService(Ci.nsITaggingService);
+ this.__defineGetter__("tagging", function() svc);
+ return this.tagging;
+ },
+
+ /*
+ * Search for a given string and notify a listener (either synchronously
+ * or asynchronously) of the result
+ *
+ * @param searchString - The string to search for
+ * @param searchParam - An extra parameter
+ * @param previousResult - A previous result to use for faster searching
+ * @param listener - A listener to notify when the search is complete
+ */
+ startSearch: function PTACS_startSearch(searchString, searchParam, result, listener) {
+ var searchResults = this.tagging.allTags;
+ var results = [];
+ var comments = [];
+ this._stopped = false;
+
+ // only search on characters for the last tag
+ var index = Math.max(searchString.lastIndexOf(","),
+ searchString.lastIndexOf(";"));
+ var before = '';
+ if (index != -1) {
+ before = searchString.slice(0, index+1);
+ searchString = searchString.slice(index+1);
+ // skip past whitespace
+ var m = searchString.match(/\s+/);
+ if (m) {
+ before += m[0];
+ searchString = searchString.slice(m[0].length);
+ }
+ }
+
+ if (!searchString.length) {
+ var newResult = new TagAutoCompleteResult(searchString,
+ Ci.nsIAutoCompleteResult.RESULT_NOMATCH, 0, "", results, comments);
+ listener.onSearchResult(self, newResult);
+ return;
+ }
+
+ var self = this;
+ // generator: if yields true, not done
+ function doSearch() {
+ var i = 0;
+ while (i < searchResults.length) {
+ if (self._stopped)
+ yield false;
+ // for each match, prepend what the user has typed so far
+ if (searchResults[i].toLowerCase()
+ .indexOf(searchString.toLowerCase()) == 0 &&
+ comments.indexOf(searchResults[i]) == -1) {
+ results.push(before + searchResults[i]);
+ comments.push(searchResults[i]);
+ }
+
+ ++i;
+
+ /* TODO: bug 481451
+ * For each yield we pass a new result to the autocomplete
+ * listener. The listener appends instead of replacing previous results,
+ * causing invalid matchCount values.
+ *
+ * As a workaround, all tags are searched through in a single batch,
+ * making this synchronous until the above issue is fixed.
+ */
+
+ /*
+ // 100 loops per yield
+ if ((i % 100) == 0) {
+ var newResult = new TagAutoCompleteResult(searchString,
+ Ci.nsIAutoCompleteResult.RESULT_SUCCESS_ONGOING, 0, "", results, comments);
+ listener.onSearchResult(self, newResult);
+ yield true;
+ }
+ */
+ }
+
+ var newResult = new TagAutoCompleteResult(searchString,
+ Ci.nsIAutoCompleteResult.RESULT_SUCCESS, 0, "", results, comments);
+ listener.onSearchResult(self, newResult);
+ yield false;
+ }
+
+ // chunk the search results via the generator
+ var gen = doSearch();
+ while (gen.next());
+ gen.close();
+ },
+
+ /**
+ * Stop an asynchronous search that is in progress
+ */
+ stopSearch: function PTACS_stopSearch() {
+ this._stopped = true;
+ },
+
+ // nsISupports
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteSearch,
+ Ci.nsITimerCallback]),
+
+ classDescription: "Places Tag AutoComplete",
+ contractID: "@mozilla.org/autocomplete/search;1?name=places-tag-autocomplete",
+ classID: Components.ID("{1dcc23b0-d4cb-11dc-9ad6-479d56d89593}")
+};
+
+var component = [TaggingService, TagAutoCompleteSearch];
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(component);
+}
diff --git a/bundles/XO/components/nsTryToClose.js b/bundles/XO/components/nsTryToClose.js
new file mode 100755
index 0000000..f5ad0ee
--- /dev/null
+++ b/bundles/XO/components/nsTryToClose.js
@@ -0,0 +1,80 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the nsTryToClose component.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Michael Wu <flamingice@sourmilk.net> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function TryToClose() {}
+
+TryToClose.prototype = {
+ observe: function (aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "app-startup":
+ var obsService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ obsService.addObserver(this, "quit-application-requested", true);
+ break;
+ case "quit-application-requested":
+ var windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].
+ getService(Ci.nsIWindowMediator);
+ var enumerator = windowMediator.getEnumerator(null);
+ while (enumerator.hasMoreElements()) {
+ var domWindow = enumerator.getNext();
+ if (("tryToClose" in domWindow) && !domWindow.tryToClose()) {
+ aSubject.QueryInterface(Ci.nsISupportsPRBool);
+ aSubject.data = true;
+ break;
+ }
+ }
+ break;
+ }
+ },
+
+ classDescription: "tryToClose Service",
+ contractID: "@mozilla.org/appshell/trytoclose;1",
+ classID: Components.ID("{b69155f4-a8bf-453d-8653-91d1456e1d3d}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsISupportsWeakReference]),
+ _xpcom_categories: [{ category: "app-startup", service: true }]
+};
+
+function NSGetModule(aCompMgr, aFileSpec) {
+ return XPCOMUtils.generateModule([TryToClose]);
+}
diff --git a/bundles/XO/components/nsURLFormatter.js b/bundles/XO/components/nsURLFormatter.js
new file mode 100755
index 0000000..0956dee
--- /dev/null
+++ b/bundles/XO/components/nsURLFormatter.js
@@ -0,0 +1,85 @@
+//@line 37 "/builds/moz2_slave/linux_build/build/toolkit/components/urlformatter/src/nsURLFormatter.js"
+/**
+ * @class nsURLFormatterService
+ *
+ * nsURLFormatterService exposes methods to substitute variables in URL formats.
+ *
+ * Mozilla Applications linking to Mozilla websites are strongly encouraged to use
+ * URLs of the following format:
+ *
+ * http[s]://%LOCALE%.%SERVICE%.mozilla.[com|org]/%LOCALE%/
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function nsURLFormatterService() {}
+nsURLFormatterService.prototype = {
+ classDescription: "Application URL Formatter Service",
+ contractID: "@mozilla.org/toolkit/URLFormatterService;1",
+ classID: Components.ID("{e6156350-2be8-11db-a98b-0800200c9a66}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIURLFormatter]),
+
+ _defaults: {
+ get appInfo() {
+ if (!this._appInfo)
+ this._appInfo = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo).
+ QueryInterface(Ci.nsIXULRuntime);
+ return this._appInfo;
+ },
+
+ LOCALE: function() Cc["@mozilla.org/chrome/chrome-registry;1"].
+ getService(Ci.nsIXULChromeRegistry).getSelectedLocale('global'),
+ VENDOR: function() this.appInfo.vendor,
+ NAME: function() this.appInfo.name,
+ ID: function() this.appInfo.ID,
+ VERSION: function() this.appInfo.version,
+ APPBUILDID: function() this.appInfo.appBuildID,
+ PLATFORMVERSION: function() this.appInfo.platformVersion,
+ PLATFORMBUILDID: function() this.appInfo.platformBuildID,
+ APP: function() this.appInfo.name.toLowerCase().replace(/ /, ""),
+ OS: function() this.appInfo.OS,
+ XPCOMABI: function() this.appInfo.XPCOMABI
+ },
+
+ formatURL: function uf_formatURL(aFormat) {
+ var _this = this;
+ var replacementCallback = function(aMatch, aKey) {
+ if (aKey in _this._defaults) // supported defaults
+ return _this._defaults[aKey]();
+ Cu.reportError("formatURL: Couldn't find value for key: " + aKey);
+ return aMatch;
+ }
+ return aFormat.replace(/%([A-Z]+)%/g, replacementCallback);
+ },
+
+ formatURLPref: function uf_formatURLPref(aPref) {
+ var format = null;
+ var PS = Cc['@mozilla.org/preferences-service;1'].
+ getService(Ci.nsIPrefBranch);
+
+ try {
+ format = PS.getComplexValue(aPref, Ci.nsISupportsString).data;
+ } catch(ex) {
+ Cu.reportError("formatURLPref: Couldn't get pref: " + aPref);
+ return "about:blank";
+ }
+
+ if (!PS.prefHasUserValue(aPref) &&
+ /^(data:text\/plain,.+=.+|chrome:\/\/.+\/locale\/.+\.properties)$/.test(format)) {
+ // This looks as if it might be a localised preference
+ try {
+ format = PS.getComplexValue(aPref, Ci.nsIPrefLocalizedString).data;
+ } catch(ex) {}
+ }
+
+ return this.formatURL(format);
+ }
+};
+
+function NSGetModule(aCompMgr, aFileSpec)
+ XPCOMUtils.generateModule([nsURLFormatterService]);
diff --git a/bundles/XO/components/nsUpdateService.js b/bundles/XO/components/nsUpdateService.js
new file mode 100755
index 0000000..7b1d28e
--- /dev/null
+++ b/bundles/XO/components/nsUpdateService.js
@@ -0,0 +1,3118 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+//@line 44 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+*/
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
+const PREF_APP_UPDATE_AUTO = "app.update.auto";
+const PREF_APP_UPDATE_MODE = "app.update.mode";
+const PREF_APP_UPDATE_SILENT = "app.update.silent";
+const PREF_APP_UPDATE_INTERVAL = "app.update.interval";
+const PREF_APP_UPDATE_TIMER = "app.update.timer";
+const PREF_APP_UPDATE_IDLETIME = "app.update.idletime";
+const PREF_APP_UPDATE_PROMPTWAITTIME = "app.update.promptWaitTime";
+const PREF_APP_UPDATE_LOG_BRANCH = "app.update.log.";
+const PREF_APP_UPDATE_URL = "app.update.url";
+const PREF_APP_UPDATE_URL_OVERRIDE = "app.update.url.override";
+const PREF_APP_UPDATE_URL_DETAILS = "app.update.url.details";
+const PREF_APP_UPDATE_CHANNEL = "app.update.channel";
+const PREF_APP_UPDATE_SHOW_INSTALLED_UI = "app.update.showInstalledUI";
+const PREF_APP_UPDATE_LASTUPDATETIME_FMT = "app.update.lastUpdateTime.%ID%";
+const PREF_APP_UPDATE_INCOMPATIBLE_MODE = "app.update.incompatible.mode";
+const PREF_UPDATE_NEVER_BRANCH = "app.update.never.";
+const PREF_PARTNER_BRANCH = "app.partner.";
+const PREF_APP_DISTRIBUTION = "distribution.id";
+const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
+
+const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
+const URI_UPDATE_HISTORY_DIALOG = "chrome://mozapps/content/update/history.xul";
+const URI_BRAND_PROPERTIES = "chrome://branding/locale/brand.properties";
+const URI_UPDATES_PROPERTIES = "chrome://mozapps/locale/update/updates.properties";
+const URI_UPDATE_NS = "http://www.mozilla.org/2005/app-update";
+
+const KEY_APPDIR = "XCurProcD";
+const KEY_GRED = "GreD";
+//@line 85 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+
+const DIR_UPDATES = "updates";
+const FILE_UPDATE_STATUS = "update.status";
+const FILE_UPDATE_VERSION = "update.version";
+const FILE_UPDATE_ARCHIVE = "update.mar";
+const FILE_UPDATE_LOG = "update.log"
+const FILE_UPDATES_DB = "updates.xml";
+const FILE_UPDATE_ACTIVE = "active-update.xml";
+const FILE_PERMS_TEST = "update.test";
+const FILE_LAST_LOG = "last-update.log";
+const FILE_UPDATE_LOCALE = "update.locale";
+
+const MODE_RDONLY = 0x01;
+const MODE_WRONLY = 0x02;
+const MODE_CREATE = 0x08;
+const MODE_APPEND = 0x10;
+const MODE_TRUNCATE = 0x20;
+
+const PERMS_FILE = 0644;
+const PERMS_DIRECTORY = 0755;
+
+const STATE_NONE = "null";
+const STATE_DOWNLOADING = "downloading";
+const STATE_PENDING = "pending";
+const STATE_APPLYING = "applying";
+const STATE_SUCCEEDED = "succeeded";
+const STATE_DOWNLOAD_FAILED = "download-failed";
+const STATE_FAILED = "failed";
+
+// From updater/errors.h:
+const WRITE_ERROR = 7;
+
+const DOWNLOAD_CHUNK_SIZE = 300000; // bytes
+const DOWNLOAD_BACKGROUND_INTERVAL = 600; // seconds
+const DOWNLOAD_FOREGROUND_INTERVAL = 0;
+
+const UPDATE_WINDOW_NAME = "Update:Wizard";
+const TOOLKIT_ID = "toolkit@mozilla.org";
+
+const POST_UPDATE_CONTRACTID = "@mozilla.org/updates/post-update;1";
+
+var gApp = null;
+var gPref = null;
+var gABI = null;
+var gOSVersion = null;
+var gLocale = null;
+var gConsole = null;
+var gCanUpdate = null;
+var gLogEnabled = { };
+
+// shared code for suppressing bad cert dialogs
+//@line 41 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/shared/src/badCertHandler.js"
+
+/**
+ * Only allow built-in certs for HTTPS connections. See bug 340198.
+ */
+function checkCert(channel) {
+ if (!channel.originalURI.schemeIs("https")) // bypass
+ return;
+
+ const Ci = Components.interfaces;
+ var cert =
+ channel.securityInfo.QueryInterface(Ci.nsISSLStatusProvider).
+ SSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
+
+ var issuer = cert.issuer;
+ while (issuer && !cert.equals(issuer)) {
+ cert = issuer;
+ issuer = cert.issuer;
+ }
+
+ var errorstring = "cert issuer is not built-in";
+ if (!issuer)
+ throw errorstring;
+
+ issuer = issuer.QueryInterface(Ci.nsIX509Cert3);
+ var tokenNames = issuer.getAllTokenNames({});
+
+ if (!tokenNames.some(isBuiltinToken))
+ throw errorstring;
+}
+
+function isBuiltinToken(tokenName) {
+ return tokenName == "Builtin Object Token";
+}
+
+/**
+ * This class implements nsIBadCertListener. Its job is to prevent "bad cert"
+ * security dialogs from being shown to the user. It is better to simply fail
+ * if the certificate is bad. See bug 304286.
+ */
+function BadCertHandler() {
+}
+BadCertHandler.prototype = {
+
+ // nsIChannelEventSink
+ onChannelRedirect: function(oldChannel, newChannel, flags) {
+ // make sure the certificate of the old channel checks out before we follow
+ // a redirect from it. See bug 340198.
+ checkCert(oldChannel);
+ },
+
+ // Suppress any certificate errors
+ notifyCertProblem: function(socketInfo, status, targetSite) {
+ return true;
+ },
+
+ // Suppress any ssl errors
+ notifySSLError: function(socketInfo, error, targetSite) {
+ return true;
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ // nsISupports
+ QueryInterface: function(iid) {
+ if (!iid.equals(Components.interfaces.nsIChannelEventSink) &&
+ !iid.equals(Components.interfaces.nsIBadCertListener2) &&
+ !iid.equals(Components.interfaces.nsISSLErrorListener) &&
+ !iid.equals(Components.interfaces.nsIInterfaceRequestor) &&
+ !iid.equals(Components.interfaces.nsISupports))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ return this;
+ }
+};
+//@line 137 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+
+/**
+ * Logs a string to the error console.
+ * @param string
+ * The string to write to the error console..
+ */
+function LOG(module, string) {
+ if (module in gLogEnabled || "all" in gLogEnabled) {
+ dump("*** AUS:SVC " + module + ":" + string + "\n");
+ // On startup gConsole may not be initialized
+ if (gConsole)
+ gConsole.logStringMessage("AUS:SVC " + module + ":" + string);
+ }
+}
+
+/**
+ * Convert a string containing binary values to hex.
+ */
+function binaryToHex(input) {
+ var result = "";
+ for (var i = 0; i < input.length; ++i) {
+ var hex = input.charCodeAt(i).toString(16);
+ if (hex.length == 1)
+ hex = "0" + hex;
+ result += hex;
+ }
+ return result;
+}
+
+/**
+ * Gets a File URL spec for a nsIFile
+ * @param file
+ * The file to get a file URL spec to
+ * @returns The file URL spec to the file
+ */
+function getURLSpecFromFile(file) {
+ var ioServ = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var fph = ioServ.getProtocolHandler("file").
+ QueryInterface(Ci.nsIFileProtocolHandler);
+ return fph.getURLSpecFromFile(file);
+}
+
+/**
+ * Gets the specified directory at the specified hierarchy under a
+ * Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|
+ * @return nsIFile object for the location specified. If the directory
+ * requested does not exist, it is created, along with any
+ * parent directories that need to be created.
+ */
+function getDir(key, pathArray) {
+ return getDirInternal(key, pathArray, true, false);
+}
+
+/**
+ * Gets the specified directory at the specified hierarchy under a
+ * Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|
+ * @return nsIFile object for the location specified. If the directory
+ * requested does not exist, it is NOT created.
+ */
+function getDirNoCreate(key, pathArray) {
+ return getDirInternal(key, pathArray, false, false);
+}
+
+/**
+ * Gets the specified directory at the specified hierarchy under the
+ * update root directory.
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|
+ * @return nsIFile object for the location specified. If the directory
+ * requested does not exist, it is created, along with any
+ * parent directories that need to be created.
+ */
+function getUpdateDir(pathArray) {
+ return getDirInternal(KEY_APPDIR, pathArray, true, true);
+}
+
+/**
+ * Gets the specified directory at the specified hierarchy under a
+ * Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|
+ * @param shouldCreate
+ * true if the directory hierarchy specified in |pathArray|
+ * should be created if it does not exist,
+ * false otherwise.
+ * @param update
+ * true if finding the update directory,
+ * false otherwise.
+ * @return nsIFile object for the location specified.
+ */
+function getDirInternal(key, pathArray, shouldCreate, update) {
+ var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ var dir = fileLocator.get(key, Ci.nsIFile);
+//@line 254 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ for (var i = 0; i < pathArray.length; ++i) {
+ dir.append(pathArray[i]);
+ if (shouldCreate && !dir.exists())
+ dir.create(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ }
+ return dir;
+}
+
+/**
+ * Gets the file at the specified hierarchy under a Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|. The last item in this array must be the
+ * leaf name of a file.
+ * @return nsIFile object for the file specified. The file is NOT created
+ * if it does not exist, however all required directories along
+ * the way are.
+ */
+function getFile(key, pathArray) {
+ var file = getDir(key, pathArray.slice(0, -1));
+ file.append(pathArray[pathArray.length - 1]);
+ return file;
+}
+
+/**
+ * Gets the file at the specified hierarchy under the update root directory.
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|. The last item in this array must be the
+ * leaf name of a file.
+ * @return nsIFile object for the file specified. The file is NOT created
+ * if it does not exist, however all required directories along
+ * the way are.
+ */
+function getUpdateFile(pathArray) {
+ var file = getUpdateDir(pathArray.slice(0, -1));
+ file.append(pathArray[pathArray.length - 1]);
+ return file;
+}
+
+/**
+ * Closes a Safe Output Stream
+ * @param fos
+ * The Safe Output Stream to close
+ */
+function closeSafeOutputStream(fos) {
+ if (fos instanceof Ci.nsISafeOutputStream) {
+ try {
+ fos.finish();
+ }
+ catch (e) {
+ fos.close();
+ }
+ }
+ else
+ fos.close();
+}
+
+/**
+ * Returns human readable status text from the updates.properties bundle
+ * based on an error code
+ * @param code
+ * The error code to look up human readable status text for
+ * @param defaultCode
+ * The default code to look up should human readable status text
+ * not exist for |code|
+ * @returns A human readable status text string
+ */
+function getStatusTextFromCode(code, defaultCode) {
+ const updateBundle = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).
+ createBundle(URI_UPDATES_PROPERTIES);
+ var reason;
+ try {
+ reason = updateBundle.GetStringFromName("check_error-" + code);
+ LOG("General", "getStatusTextFromCode - transfer error: " + reason +
+ ", code: " + code);
+ }
+ catch (e) {
+ // Use the default reason
+ reason = updateBundle.GetStringFromName("check_error-" + defaultCode);
+ LOG("General", "getStatusTextFromCode - transfer error: " + reason +
+ ", default code: " + defaultCode);
+ }
+ return reason;
+}
+
+/**
+ * Get the Active Updates directory
+ * @param key
+ * The Directory Service Key (optional).
+ * If used, don't search local appdata on Win32 and don't create dir.
+ * @returns The active updates directory, as a nsIFile object
+ */
+function getUpdatesDir(key) {
+ // Right now, we only support downloading one patch at a time, so we always
+ // use the same target directory.
+ var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ var updateDir;
+ if (key)
+ updateDir = fileLocator.get(key, Ci.nsIFile);
+ else {
+ updateDir = fileLocator.get(KEY_APPDIR, Ci.nsIFile);
+//@line 366 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ }
+ updateDir.append(DIR_UPDATES);
+ updateDir.append("0");
+ if (!updateDir.exists() && !key) {
+ LOG("General", "getUpdatesDir - update directory " + updateDir.path +
+ " doesn't exist, creating...");
+ updateDir.create(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ }
+ return updateDir;
+}
+
+/**
+ * Reads the update state from the update.status file in the specified
+ * directory.
+ * @param dir
+ * The dir to look for an update.status file in
+ * @returns The status value of the update.
+ */
+function readStatusFile(dir) {
+ var statusFile = dir.clone();
+ statusFile.append(FILE_UPDATE_STATUS);
+ var status = readStringFromFile(statusFile) || STATE_NONE;
+ LOG("General", "readStatusFile - status: " + status + ", path: " +
+ statusFile.path);
+ return status;
+}
+
+/**
+ * Writes the current update operation/state to a file in the patch
+ * directory, indicating to the patching system that operations need
+ * to be performed.
+ * @param dir
+ * The patch directory where the update.status file should be
+ * written.
+ * @param state
+ * The state value to write.
+ */
+function writeStatusFile(dir, state) {
+ var statusFile = dir.clone();
+ statusFile.append(FILE_UPDATE_STATUS);
+ writeStringToFile(statusFile, state);
+}
+
+/**
+//@line 424 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ */
+function writeVersionFile(dir, version) {
+ var versionFile = dir.clone();
+ versionFile.append(FILE_UPDATE_VERSION);
+ writeStringToFile(versionFile, version);
+}
+
+/**
+ * Removes the Updates Directory
+ * @param key
+ * The Directory Service Key under which update directory resides
+ * (optional).
+ */
+function cleanUpUpdatesDir(key) {
+ // Bail out if we don't have appropriate permissions
+ var updateDir;
+ try {
+ updateDir = getUpdatesDir(key);
+ }
+ catch (e) {
+ return;
+ }
+
+ var e = updateDir.directoryEntries;
+ while (e.hasMoreElements()) {
+ var f = e.getNext().QueryInterface(Ci.nsIFile);
+ // Preserve the last update log file for debugging purposes
+ if (f.leafName == FILE_UPDATE_LOG) {
+ try {
+ var dir = f.parent.parent;
+ var logFile = dir.clone();
+ logFile.append(FILE_LAST_LOG);
+ if (logFile.exists())
+ logFile.remove(false);
+ f.copyTo(dir, FILE_LAST_LOG);
+ }
+ catch (e) {
+ LOG("General", "cleanUpUpdatesDir - failed to copy file: " + f.path);
+ }
+ }
+ // Now, recursively remove this file. The recusive removal is really
+ // only needed on Mac OSX because this directory will contain a copy of
+ // updater.app, which is itself a directory.
+ try {
+ f.remove(true);
+ }
+ catch (e) {
+ LOG("General", "cleanUpUpdatesDir - failed to remove file: " + f.path);
+ }
+ }
+ try {
+ updateDir.remove(false);
+ } catch (e) {
+ LOG("General", "cleanUpUpdatesDir - failed to remove update directory: " +
+ updateDir.path + " - This is almost always bad. Exception = " + e);
+ throw e;
+ }
+ LOG("General", "cleanUpUpdatesDir - successfully removed update directory: " +
+ updateDir.path);
+}
+
+/**
+ * Clean up updates list and the updates directory.
+ * @param key
+ * The Directory Service Key under which update directory resides
+ * (optional).
+ */
+function cleanupActiveUpdate(key) {
+ // Move the update from the Active Update list into the Past Updates list.
+ var um = Cc["@mozilla.org/updates/update-manager;1"].
+ getService(Ci.nsIUpdateManager);
+ um.activeUpdate = null;
+ um.saveUpdates();
+
+ // Now trash the updates directory, since we're done with it
+ cleanUpUpdatesDir(key);
+}
+
+/**
+ * Gets a preference value, handling the case where there is no default.
+ * @param func
+ * The name of the preference function to call, on nsIPrefBranch
+ * @param preference
+ * The name of the preference
+ * @param defaultValue
+ * The default value to return in the event the preference has
+ * no setting
+ * @returns The value of the preference, or undefined if there was no
+ * user or default value.
+ */
+function getPref(func, preference, defaultValue) {
+ try {
+ return gPref[func](preference);
+ }
+ catch (e) {
+ }
+ return defaultValue;
+}
+
+/**
+ * Gets the locale from the update.locale file for replacing %LOCALE% in the
+ * update url. The update.locale file can be located in the application
+ * directory or the GRE directory with preference given to it being located in
+ * the application directory.
+ */
+function getLocale() {
+ if (gLocale)
+ return gLocale;
+
+ var localeFile = getFile(KEY_APPDIR, [FILE_UPDATE_LOCALE]);
+ if (!localeFile.exists())
+ localeFile = getFile(KEY_GRED, [FILE_UPDATE_LOCALE]);
+
+ if (!localeFile.exists())
+ throw Components.Exception(FILE_UPDATE_LOCALE + " file doesn't exist in " +
+ "either the " + KEY_APPDIR + " or " + KEY_GRED +
+ " directories", Cr.NS_ERROR_FILE_NOT_FOUND);
+
+ gLocale = readStringFromFile(localeFile);
+ LOG("General", "getLocale - getting locale from file: " + localeFile.path +
+ ", locale: " + gLocale);
+ return gLocale;
+}
+
+/**
+ * Read the update channel from defaults only. We do this to ensure that
+ * the channel is tightly coupled with the application and does not apply
+ * to other instances of the application that may use the same profile.
+ */
+function getUpdateChannel() {
+ var channel = "default";
+ var prefName;
+ var prefValue;
+
+ try {
+ channel = getDefaultPrefBranch().getCharPref(PREF_APP_UPDATE_CHANNEL);
+ } catch (e) {
+ // use default when pref not found
+ }
+
+ try {
+ var partners = gPref.getChildList(PREF_PARTNER_BRANCH, { });
+ if (partners.length) {
+ channel += "-cck";
+ partners.sort();
+
+ for each (prefName in partners) {
+ prefValue = gPref.getCharPref(prefName);
+ channel += "-" + prefValue;
+ }
+ }
+ }
+ catch (e) {
+ Components.utils.reportError(e);
+ }
+
+ return channel;
+}
+
+/* Get the distribution pref values, from defaults only */
+function getDistributionPrefValue(aPrefName) {
+ var prefValue = "default";
+
+ try {
+ prefValue = getDefaultPrefBranch().getCharPref(aPrefName);
+ } catch (e) {
+ // use default when pref not found
+ }
+
+ return prefValue;
+}
+
+/**
+ * An enumeration of items in a JS array.
+ * @constructor
+ */
+function ArrayEnumerator(aItems) {
+ this._index = 0;
+ if (aItems) {
+ for (var i = 0; i < aItems.length; ++i) {
+ if (!aItems[i])
+ aItems.splice(i, 1);
+ }
+ }
+ this._contents = aItems;
+}
+
+ArrayEnumerator.prototype = {
+ _index: 0,
+ _contents: [],
+
+ hasMoreElements: function ArrayEnumerator_hasMoreElements() {
+ return this._index < this._contents.length;
+ },
+
+ getNext: function ArrayEnumerator_getNext() {
+ return this._contents[this._index++];
+ }
+};
+
+/**
+ * Trims a prefix from a string.
+ * @param string
+ * The source string
+ * @param prefix
+ * The prefix to remove.
+ * @returns The suffix (string - prefix)
+ */
+function stripPrefix(string, prefix) {
+ return string.substr(prefix.length);
+}
+
+/**
+ * Writes a string of text to a file. A newline will be appended to the data
+ * written to the file. This function only works with ASCII text.
+ */
+function writeStringToFile(file, text) {
+ var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ var modeFlags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
+ if (!file.exists())
+ file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ fos.init(file, modeFlags, PERMS_FILE, 0);
+ text += "\n";
+ fos.write(text, text.length);
+ closeSafeOutputStream(fos);
+}
+
+/**
+ * Reads a string of text from a file. A trailing newline will be removed
+ * before the result is returned. This function only works with ASCII text.
+ */
+function readStringFromFile(file) {
+ var fis = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ var modeFlags = MODE_RDONLY;
+ if (!file.exists()) {
+ LOG("General", "readStringFromFile - file doesn't exist: " + file.path);
+ return null;
+ }
+ fis.init(file, modeFlags, PERMS_FILE, 0);
+ var sis = Cc["@mozilla.org/scriptableinputstream;1"].
+ createInstance(Ci.nsIScriptableInputStream);
+ sis.init(fis);
+ var text = sis.read(sis.available());
+ sis.close();
+ if (text[text.length - 1] == "\n")
+ text = text.slice(0, -1);
+ return text;
+}
+
+function getObserverService()
+{
+ return Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+}
+
+function getDefaultPrefBranch()
+{
+ return gPref.QueryInterface(Ci.nsIPrefService).getDefaultBranch(null);
+}
+/**
+ * Update Patch
+ * @param patch
+ * A <patch> element to initialize this object with
+ * @throws if patch has a size of 0
+ * @constructor
+ */
+function UpdatePatch(patch) {
+ this._properties = {};
+ for (var i = 0; i < patch.attributes.length; ++i) {
+ var attr = patch.attributes.item(i);
+ attr.QueryInterface(Ci.nsIDOMAttr);
+ switch (attr.name) {
+ case "selected":
+ this.selected = attr.value == "true";
+ break;
+ case "size":
+ if (0 == parseInt(attr.value)) {
+ LOG("UpdatePatch", "init - 0-sized patch!");
+ throw Cr.NS_ERROR_ILLEGAL_VALUE;
+ }
+ // fall through
+ default:
+ this[attr.name] = attr.value;
+ break;
+ };
+ }
+}
+UpdatePatch.prototype = {
+ /**
+ * See nsIUpdateService.idl
+ */
+ serialize: function UpdatePatch_serialize(updates) {
+ var patch = updates.createElementNS(URI_UPDATE_NS, "patch");
+ patch.setAttribute("type", this.type);
+ patch.setAttribute("URL", this.URL);
+ patch.setAttribute("hashFunction", this.hashFunction);
+ patch.setAttribute("hashValue", this.hashValue);
+ patch.setAttribute("size", this.size);
+ patch.setAttribute("selected", this.selected);
+ patch.setAttribute("state", this.state);
+
+ for (var p in this._properties) {
+ if (this._properties[p].present)
+ patch.setAttribute(p, this._properties[p].data);
+ }
+
+ return patch;
+ },
+
+ /**
+ * A hash of custom properties
+ */
+ _properties: null,
+
+ /**
+ * See nsIWritablePropertyBag.idl
+ */
+ setProperty: function UpdatePatch_setProperty(name, value) {
+ this._properties[name] = { data: value, present: true };
+ },
+
+ /**
+ * See nsIWritablePropertyBag.idl
+ */
+ deleteProperty: function UpdatePatch_deleteProperty(name) {
+ if (name in this._properties)
+ this._properties[name].present = false;
+ else
+ throw Cr.NS_ERROR_FAILURE;
+ },
+
+ /**
+ * See nsIPropertyBag.idl
+ */
+ get enumerator() {
+ var properties = [];
+ for (var p in this._properties)
+ properties.push(this._properties[p].data);
+ return new ArrayEnumerator(properties);
+ },
+
+ /**
+ * See nsIPropertyBag.idl
+ */
+ getProperty: function UpdatePatch_getProperty(name) {
+ if (name in this._properties &&
+ this._properties[name].present)
+ return this._properties[name].data;
+ throw Cr.NS_ERROR_FAILURE;
+ },
+
+ /**
+ * Returns whether or not the update.status file for this patch exists at the
+ * appropriate location.
+ */
+ get statusFileExists() {
+ var statusFile = getUpdatesDir();
+ statusFile.append(FILE_UPDATE_STATUS);
+ return statusFile.exists();
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get state() {
+ if (this._properties.state)
+ return this._properties.state;
+ return STATE_NONE;
+ },
+ set state(val) {
+ this._properties.state = val;
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePatch,
+ Ci.nsIPropertyBag,
+ Ci.nsIWritablePropertyBag])
+};
+
+/**
+ * Update
+ * Implements nsIUpdate
+ * @param update
+ * An <update> element to initialize this object with
+ * @throws if the update contains no patches
+ * @constructor
+ */
+function Update(update) {
+ this._properties = {};
+ this._patches = [];
+ this.installDate = 0;
+ this.isCompleteUpdate = false;
+ this.channel = "default"
+
+ // Null <update>, assume this is a message container and do no
+ // further initialization
+ if (!update)
+ return;
+
+ const ELEMENT_NODE = Ci.nsIDOMNode.ELEMENT_NODE;
+ for (var i = 0; i < update.childNodes.length; ++i) {
+ var patchElement = update.childNodes.item(i);
+ if (patchElement.nodeType != ELEMENT_NODE ||
+ patchElement.localName != "patch")
+ continue;
+
+ patchElement.QueryInterface(Ci.nsIDOMElement);
+ try {
+ var patch = new UpdatePatch(patchElement);
+ } catch (e) {
+ continue;
+ }
+ this._patches.push(patch);
+ }
+
+ if (0 == this._patches.length)
+ throw Cr.NS_ERROR_ILLEGAL_VALUE;
+
+ for (var i = 0; i < update.attributes.length; ++i) {
+ var attr = update.attributes.item(i);
+ attr.QueryInterface(Ci.nsIDOMAttr);
+ if (attr.name == "installDate" && attr.value)
+ this.installDate = parseInt(attr.value);
+ else if (attr.name == "isCompleteUpdate")
+ this.isCompleteUpdate = attr.value == "true";
+ else if (attr.name == "isSecurityUpdate")
+ this.isSecurityUpdate = attr.value == "true";
+ else if (attr.name == "detailsURL")
+ this._detailsURL = attr.value;
+ else if (attr.name == "channel")
+ this.channel = attr.value;
+ else
+ this[attr.name] = attr.value;
+ }
+
+ // The Update Name is either the string provided by the <update> element, or
+ // the string: "<App Name> <Update App Version>"
+ var name = "";
+ if (update.hasAttribute("name"))
+ name = update.getAttribute("name");
+ else {
+ var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ var brandBundle = sbs.createBundle(URI_BRAND_PROPERTIES);
+ var updateBundle = sbs.createBundle(URI_UPDATES_PROPERTIES);
+ var appName = brandBundle.GetStringFromName("brandShortName");
+ name = updateBundle.formatStringFromName("updateName",
+ [appName, this.version], 2);
+ }
+ this.name = name;
+}
+Update.prototype = {
+ /**
+ * See nsIUpdateService.idl
+ */
+ get patchCount() {
+ return this._patches.length;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ getPatchAt: function Update_getPatchAt(index) {
+ return this._patches[index];
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ *
+ * We use a copy of the state cached on this object in |_state| only when
+ * there is no selected patch, i.e. in the case when we could not load
+ * |.activeUpdate| from the update manager for some reason but still have
+ * the update.status file to work with.
+ */
+ _state: "",
+ set state(state) {
+ if (this.selectedPatch)
+ this.selectedPatch.state = state;
+ this._state = state;
+ return state;
+ },
+ get state() {
+ if (this.selectedPatch)
+ return this.selectedPatch.state;
+ return this._state;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ errorCode: 0,
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get selectedPatch() {
+ for (var i = 0; i < this.patchCount; ++i) {
+ if (this._patches[i].selected)
+ return this._patches[i];
+ }
+ return null;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get detailsURL() {
+ if (!this._detailsURL) {
+ try {
+ // Try using a default details URL supplied by the distribution
+ // if the update XML does not supply one.
+ var formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].
+ getService(Ci.nsIURLFormatter);
+ return formatter.formatURLPref(PREF_APP_UPDATE_URL_DETAILS);
+ }
+ catch (e) {
+ }
+ }
+ return this._detailsURL || "";
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ serialize: function Update_serialize(updates) {
+ var update = updates.createElementNS(URI_UPDATE_NS, "update");
+ update.setAttribute("type", this.type);
+ update.setAttribute("name", this.name);
+ update.setAttribute("version", this.version);
+ update.setAttribute("platformVersion", this.platformVersion);
+ update.setAttribute("extensionVersion", this.extensionVersion);
+ update.setAttribute("detailsURL", this.detailsURL);
+ update.setAttribute("licenseURL", this.licenseURL);
+ update.setAttribute("serviceURL", this.serviceURL);
+ update.setAttribute("installDate", this.installDate);
+ update.setAttribute("statusText", this.statusText);
+ update.setAttribute("buildID", this.buildID);
+ update.setAttribute("isCompleteUpdate", this.isCompleteUpdate);
+ update.setAttribute("channel", this.channel);
+ updates.documentElement.appendChild(update);
+
+ for (var p in this._properties) {
+ if (this._properties[p].present)
+ update.setAttribute(p, this._properties[p].data);
+ }
+
+ for (var i = 0; i < this.patchCount; ++i)
+ update.appendChild(this.getPatchAt(i).serialize(updates));
+
+ return update;
+ },
+
+ /**
+ * A hash of custom properties
+ */
+ _properties: null,
+
+ /**
+ * See nsIWritablePropertyBag.idl
+ */
+ setProperty: function Update_setProperty(name, value) {
+ this._properties[name] = { data: value, present: true };
+ },
+
+ /**
+ * See nsIWritablePropertyBag.idl
+ */
+ deleteProperty: function Update_deleteProperty(name) {
+ if (name in this._properties)
+ this._properties[name].present = false;
+ else
+ throw Cr.NS_ERROR_FAILURE;
+ },
+
+ /**
+ * See nsIPropertyBag.idl
+ */
+ get enumerator() {
+ var properties = [];
+ for (var p in this._properties)
+ properties.push(this._properties[p].data);
+ return new ArrayEnumerator(properties);
+ },
+
+ /**
+ * See nsIPropertyBag.idl
+ */
+ getProperty: function Update_getProperty(name) {
+ if (name in this._properties &&
+ this._properties[name].present)
+ return this._properties[name].data;
+ throw Cr.NS_ERROR_FAILURE;
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdate,
+ Ci.nsIPropertyBag,
+ Ci.nsIWritablePropertyBag])
+};
+
+const UpdateServiceFactory = {
+ _instance: null,
+ createInstance: function (outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+ return this._instance == null ? this._instance = new UpdateService() :
+ this._instance;
+ }
+};
+
+/**
+ * UpdateService
+ * A Service for managing the discovery and installation of software updates.
+ * @constructor
+ */
+function UpdateService() {
+ gApp = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).
+ QueryInterface(Ci.nsIXULRuntime);
+ gPref = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+ gConsole = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+
+ // Not all builds have a known ABI
+ try {
+ gABI = gApp.XPCOMABI;
+ }
+ catch (e) {
+ LOG("UpdateService", "init - XPCOM ABI unknown: updates are not possible.");
+ }
+
+ var osVersion;
+ var sysInfo = Cc["@mozilla.org/system-info;1"].
+ getService(Ci.nsIPropertyBag2);
+ try {
+ osVersion = sysInfo.getProperty("name") + " " + sysInfo.getProperty("version");
+ }
+ catch (e) {
+ LOG("UpdateService", "init - OS Version unknown: updates are not possible.");
+ }
+
+ if (osVersion) {
+ try {
+ osVersion += " (" + sysInfo.getProperty("secondaryLibrary") + ")";
+ }
+ catch (e) {
+ // Not all platforms have a secondary widget library, so an error is nothing to worry about.
+ }
+ gOSVersion = encodeURIComponent(osVersion);
+ }
+
+//@line 1084 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+
+ // Start the update timer only after a profile has been selected so that the
+ // appropriate values for the update check are read from the user's profile.
+ var os = getObserverService();
+
+ os.addObserver(this, "profile-after-change", false);
+
+ // Observe xpcom-shutdown to unhook pref branch observers above to avoid
+ // shutdown leaks.
+ os.addObserver(this, "xpcom-shutdown", false);
+}
+
+UpdateService.prototype = {
+ /**
+ * The downloader we are using to download updates. There is only ever one of
+ * these.
+ */
+ _downloader: null,
+
+ /**
+ * Incompatible add-on count.
+ */
+ _incompatAddonsCount: 0,
+
+ /**
+ * Handle Observer Service notifications
+ * @param subject
+ * The subject of the notification
+ * @param topic
+ * The notification name
+ * @param data
+ * Additional data
+ */
+ observe: function AUS_observe(subject, topic, data) {
+ var os = getObserverService();
+
+ switch (topic) {
+ case "profile-after-change":
+ os.removeObserver(this, "profile-after-change");
+ os.addObserver(this, "final-ui-startup", false);
+ this._start();
+ break;
+ case "final-ui-startup":
+ os.removeObserver(this, "final-ui-startup");
+ this._final_ui_start();
+ break;
+ case "xpcom-shutdown":
+ os.removeObserver(this, "xpcom-shutdown");
+
+ // Prevent leaking the downloader (bug 454964)
+ this._downloader = null;
+
+ // Release Services
+ gApp = null;
+ gPref = null;
+ gConsole = null;
+ break;
+ }
+ },
+
+ /**
+ * Start the Update Service
+ */
+ _start: function AUS__start() {
+ // Start logging
+ this._initLoggingPrefs();
+
+ // Register a background update check timer
+ var tm = Cc["@mozilla.org/updates/timer-manager;1"].
+ getService(Ci.nsIUpdateTimerManager);
+ var interval = getPref("getIntPref", PREF_APP_UPDATE_INTERVAL, 86400);
+ tm.registerTimer("background-update-timer", this, interval);
+ },
+
+ /**
+ * The following needs to be performed after final-ui-startup (bug 497578)
+ * 1. post update processing
+ * 2. resume of a download that was in progress during a previous session
+ * 3. start of a complete update download after the failure to apply a partial
+ * update
+ */
+ _final_ui_start: function AUS__delayed_start() {
+ // Clean up any extant updates
+ this._postUpdateProcessing();
+
+ // Resume fetching...
+ var um = Cc["@mozilla.org/updates/update-manager;1"].
+ getService(Ci.nsIUpdateManager);
+ var activeUpdate = um.activeUpdate;
+ if (activeUpdate && activeUpdate.state != STATE_SUCCEEDED) {
+ var status = this.downloadUpdate(activeUpdate, true);
+ if (status == STATE_NONE)
+ cleanupActiveUpdate();
+ }
+ },
+
+ /**
+ * Perform post-processing on updates lingering in the updates directory
+ * from a previous browser session - either report install failures (and
+ * optionally attempt to fetch a different version if appropriate) or
+ * notify the user of install success.
+ */
+ _postUpdateProcessing: function AUS__postUpdateProcessing() {
+ // Detect installation failures and notify
+
+ // Bail out if we don't have appropriate permissions
+ if (!this.canUpdate)
+ return;
+
+ var status = readStatusFile(getUpdatesDir());
+
+ // Make sure to cleanup after an update that failed for an unknown reason
+ if (status == "null")
+ status = null;
+
+ var updRootKey = null;
+//@line 1222 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+
+ if (status == STATE_DOWNLOADING) {
+ LOG("UpdateService", "_postUpdateProcessing - patch found in " +
+ "downloading state");
+ }
+ else if (status != null) {
+ // null status means the update.status file is not present, because either:
+ // 1) no update was performed, and so there's no UI to show
+ // 2) an update was attempted but failed during checking, transfer or
+ // verification, and was cleaned up at that point, and UI notifying of
+ // that error was shown at that stage.
+ var um = Cc["@mozilla.org/updates/update-manager;1"].
+ getService(Ci.nsIUpdateManager);
+ var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
+ createInstance(Ci.nsIUpdatePrompt);
+
+ var update = um.activeUpdate;
+ if (!update) {
+ update = new Update(null);
+ }
+ update.state = status;
+ var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ var bundle = sbs.createBundle(URI_UPDATES_PROPERTIES);
+ if (status == STATE_SUCCEEDED) {
+ update.statusText = bundle.GetStringFromName("installSuccess");
+
+ // Update the patch's metadata.
+ um.activeUpdate = update;
+
+ prompter.showUpdateInstalled();
+//@line 1257 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ // Perform platform-specific post-update processing.
+ if (POST_UPDATE_CONTRACTID in Cc) {
+ Cc[POST_UPDATE_CONTRACTID].createInstance(Ci.nsIRunnable).run();
+ }
+//@line 1262 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ // Done with this update. Clean it up.
+ cleanupActiveUpdate(updRootKey);
+ }
+ else {
+ // If we hit an error, then the error code will be included in the
+ // status string following a colon. If we had an I/O error, then we
+ // assume that the patch is not invalid, and we restage the patch so
+ // that it can be attempted again the next time we restart.
+ var ary = status.split(": ");
+ update.state = ary[0];
+ if (update.state == STATE_FAILED && ary[1]) {
+ update.errorCode = ary[1];
+ if (update.errorCode == WRITE_ERROR) {
+ prompter.showUpdateError(update);
+ writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING);
+ writeVersionFile(getUpdatesDir(), update.extensionVersion);
+ return;
+ }
+ }
+
+ // Something went wrong with the patch application process.
+ cleanupActiveUpdate();
+
+ update.statusText = bundle.GetStringFromName("patchApplyFailure");
+ var oldType = update.selectedPatch ? update.selectedPatch.type
+ : "complete";
+ if (update.selectedPatch && oldType == "partial") {
+ // Partial patch application failed, try downloading the complete
+ // update in the background instead.
+ LOG("UpdateService", "_postUpdateProcessing - install of partial " +
+ "patch failed, downloading complete patch");
+ var status = this.downloadUpdate(update, true);
+ if (status == STATE_NONE)
+ cleanupActiveUpdate();
+ }
+ else {
+ LOG("UpdateService", "_postUpdateProcessing - install of complete or " +
+ "only one patch offered failed... showing error.");
+ }
+ update.QueryInterface(Ci.nsIWritablePropertyBag);
+ update.setProperty("patchingFailed", oldType);
+ prompter.showUpdateError(update);
+ }
+ }
+ else {
+ LOG("UpdateService", "_postUpdateProcessing - no status, no update");
+ }
+ },
+
+ /**
+ * Initialize Logging preferences, formatted like so:
+ * app.update.log.<moduleName> = <true|false>
+ */
+ _initLoggingPrefs: function AUS__initLoggingPrefs() {
+ try {
+ var ps = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ var logBranch = ps.getBranch(PREF_APP_UPDATE_LOG_BRANCH);
+ var modules = logBranch.getChildList("", { value: 0 });
+
+ for (var i = 0; i < modules.length; ++i) {
+ if (logBranch.prefHasUserValue(modules[i]))
+ gLogEnabled[modules[i]] = logBranch.getBoolPref(modules[i]);
+ }
+ }
+ catch (e) {
+ }
+ },
+
+ /**
+ * Notified when a timer fires
+ * @param timer
+ * The timer that fired
+ */
+ notify: function AUS_notify(timer) {
+ // If a download is in progress or the patch has been staged do nothing.
+ if (this.isDownloading || this._downloader && this._downloader.patchIsStaged)
+ return;
+
+ var self = this;
+ var listener = {
+ /**
+ * See nsIUpdateService.idl
+ */
+ onProgress: function AUS_notify_onProgress(request, position, totalSize) {
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ onCheckComplete: function AUS_notify_onCheckComplete(request, updates,
+ updateCount) {
+ self._selectAndInstallUpdate(updates);
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ onError: function AUS_notify_onError(request, update) {
+ LOG("UpdateService", "notify:listener - error during background " +
+ "update: " + update.statusText);
+ },
+ }
+ this.backgroundChecker.checkForUpdates(listener, false);
+ },
+
+ /**
+ * Determine which of the specified updates should be installed.
+ * @param updates
+ * An array of available updates
+ */
+ selectUpdate: function AUS_selectUpdate(updates) {
+ if (updates.length == 0)
+ return null;
+
+ // Choose the newest of the available minor and major updates.
+ var majorUpdate = null, minorUpdate = null;
+ var newestMinor = updates[0], newestMajor = updates[0];
+
+ var vc = Cc["@mozilla.org/xpcom/version-comparator;1"].
+ getService(Ci.nsIVersionComparator);
+ for (var i = 0; i < updates.length; ++i) {
+ // Ignore updates for older versions of the application
+ if (vc.compare(updates[i].extensionVersion, gApp.version) < 0)
+ continue;
+ if (updates[i].type == "major" &&
+ vc.compare(newestMajor.version, updates[i].version) <= 0)
+ majorUpdate = newestMajor = updates[i];
+ if (updates[i].type == "minor" &&
+ vc.compare(newestMinor.version, updates[i].version) <= 0)
+ minorUpdate = newestMinor = updates[i];
+ }
+
+ // IMPORTANT
+ // If there's a minor update, always try and fetch that one first,
+ // otherwise use the newest major update.
+ // selectUpdate() only returns one update.
+ // if major were to trump minor, and we said "never" to the major
+ // we'd never get the minor update, since selectUpdate()
+ // would return the major update that the user said "never" to
+ // (shadowing the important minor update with security fixes)
+ return minorUpdate || majorUpdate;
+ },
+
+ /**
+ * Reference to the currently selected update for when add-on compatibility
+ * is checked.
+ */
+ _update: null,
+
+ /**
+ * Determine which of the specified updates should be installed and begin the
+ * download/installation process or notify the user about the update.
+ * @param updates
+ * An array of available updates
+ */
+ _selectAndInstallUpdate: function AUS__selectAndInstallUpdate(updates) {
+ // Return early if there's an active update. The user is already aware and
+ // is downloading or performed some user action to prevent notification.
+ var um = Cc["@mozilla.org/updates/update-manager;1"].
+ getService(Ci.nsIUpdateManager);
+ if (um.activeUpdate)
+ return;
+
+ var update = this.selectUpdate(updates, updates.length);
+ if (!update)
+ return;
+
+ var updateEnabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true);
+ if (!updateEnabled) {
+ LOG("Checker", "_selectAndInstallUpdate - not prompting because update " +
+ "is disabled");
+ return;
+ }
+
+ /**
+//@line 1450 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ */
+
+ // Encode version since it could be a non-ascii string (bug 359093)
+ var neverPrefName = PREF_UPDATE_NEVER_BRANCH +
+ encodeURIComponent(update.version);
+ if (update.type == "major" &&
+ getPref("getBoolPref", neverPrefName, false)) {
+ LOG("Checker", "_selectAndInstallUpdate - not prompting because this " +
+ "is a major update and the preference " + neverPrefName + " is true");
+ return;
+ }
+
+ /**
+//@line 1479 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ */
+ if (update.type == "major") {
+ LOG("Checker", "_selectAndInstallUpdate - prompting because it is a " +
+ "major update");
+ this._showPrompt(update);
+ return;
+ }
+
+ if (!getPref("getBoolPref", PREF_APP_UPDATE_AUTO, true)) {
+ LOG("Checker", "_selectAndInstallUpdate - prompting because silent " +
+ "install is disabled");
+ this._showPrompt(update);
+ return;
+ }
+
+ if (getPref("getIntPref", PREF_APP_UPDATE_MODE, 1) == 0) {
+ // Do not prompt regardless of add-on incompatibilities
+ LOG("UpdateService", "_selectAndInstallUpdate - no need to show " +
+ "prompt, just download the update");
+ var status = this.downloadUpdate(update, true);
+ if (status == STATE_NONE)
+ cleanupActiveUpdate();
+ return;
+ }
+
+ var ai = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo);
+ var vc = Cc["@mozilla.org/xpcom/version-comparator;1"].
+ getService(Ci.nsIVersionComparator);
+ if (update.extensionVersion &&
+ vc.compare(update.extensionVersion, ai.version) != 0) {
+ this._update = update;
+ this._checkAddonCompatibility();
+ }
+ else {
+ LOG("UpdateService", "_selectAndInstallUpdate - no need to show " +
+ "prompt, just download the update");
+ var status = this.downloadUpdate(update, true);
+ if (status == STATE_NONE)
+ cleanupActiveUpdate();
+ }
+ },
+
+ _showPrompt: function AUS__showPrompt(update) {
+ var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
+ createInstance(Ci.nsIUpdatePrompt);
+ prompter.showUpdateAvailable(update);
+ },
+
+ _checkAddonCompatibility: function AUS__checkAddonCompatibility() {
+ var em = Cc["@mozilla.org/extensions/manager;1"].
+ getService(Ci.nsIExtensionManager);
+ // Get the add-ons that are incompatible with the update's application
+ // version and toolkit version.
+ var currentAddons = em.getIncompatibleItemList("", this._update.extensionVersion,
+ this._update.platformVersion,
+ Ci.nsIUpdateItem.TYPE_ANY,
+ false, { });
+ if (currentAddons.length > 0) {
+ // Get the add-ons that are incompatible with the current application
+ // version and toolkit version.
+ var previousAddons = em.getIncompatibleItemList("", null, null,
+ Ci.nsIUpdateItem.TYPE_ANY,
+ false, { });
+ // Don't include add-ons that are already incompatible with the current
+ // application version and toolkit version.
+ for (var i = 0; i < previousAddons.length; ++i) {
+ for (var j = 0; j < currentAddons.length; ++j) {
+ if (previousAddons[i].id === currentAddons[j].id) {
+ currentAddons.splice(j, 1);
+ break;
+ }
+ }
+ }
+ }
+
+ if (currentAddons.length > 0) {
+ /**
+//@line 1575 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ */
+ this._incompatAddonsCount = currentAddons.length;
+ LOG("UpdateService", "_checkAddonCompatibility - checking for " +
+ "incompatible add-ons");
+ var updateIncompatMode = getPref("getIntPref", PREF_APP_UPDATE_INCOMPATIBLE_MODE, 0);
+ var mode = (updateIncompatMode == 1) ? Ci.nsIExtensionManager.UPDATE_CHECK_COMPATIBILITY :
+ Ci.nsIExtensionManager.UPDATE_NOTIFY_NEWVERSION;
+ em.update(currentAddons, currentAddons.length, mode, this,
+ this._update.extensionVersion, this._update.platformVersion);
+ }
+ else {
+ LOG("UpdateService", "_checkAddonCompatibility - no need to show " +
+ "prompt, just download the update");
+ var status = this.downloadUpdate(this._update, true);
+ if (status == STATE_NONE)
+ cleanupActiveUpdate();
+ this._update = null;
+ }
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onUpdateStarted: function AUS_onUpdateStarted() {
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onUpdateEnded: function AUS_onUpdateEnded() {
+ if (this._incompatAddonsCount > 0) {
+ LOG("Checker", "onUpdateEnded - prompting because there are " +
+ "incompatible add-ons");
+ this._showPrompt(this._update);
+ }
+ else {
+ LOG("UpdateService", "onUpdateEnded - no need to show prompt, just " +
+ "download the update");
+ var status = this.downloadUpdate(this._update, true);
+ if (status == STATE_NONE)
+ cleanupActiveUpdate();
+ }
+ this._update = null;
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onAddonUpdateStarted: function AUS_onAddonUpdateStarted(addon) {
+ },
+
+ /**
+ * See nsIExtensionManager.idl
+ */
+ onAddonUpdateEnded: function AUS_onAddonUpdateEnded(addon, status) {
+ if (status != Ci.nsIAddonUpdateCheckListener.STATUS_UPDATE &&
+ status != Ci.nsIAddonUpdateCheckListener.STATUS_VERSIONINFO)
+ return;
+
+ LOG("UpdateService", "onAddonUpdateEnded - found update for add-on ID: " +
+ addon.id);
+ --this._incompatAddonsCount;
+ },
+
+ /**
+ * The Checker used for background update checks.
+ */
+ _backgroundChecker: null,
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get backgroundChecker() {
+ if (!this._backgroundChecker)
+ this._backgroundChecker = new Checker();
+ return this._backgroundChecker;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get canUpdate() {
+ if (gCanUpdate !== null)
+ return gCanUpdate;
+
+ try {
+ var appDirFile = getUpdateFile([FILE_PERMS_TEST]);
+ LOG("UpdateService", "canUpdate - testing " + appDirFile.path);
+ if (!appDirFile.exists()) {
+ appDirFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ appDirFile.remove(false);
+ }
+ var updateDir = getUpdatesDir();
+ var upDirFile = updateDir.clone();
+ upDirFile.append(FILE_PERMS_TEST);
+ LOG("UpdateService", "canUpdate - testing " + upDirFile.path);
+ if (!upDirFile.exists()) {
+ upDirFile.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ upDirFile.remove(false);
+ }
+//@line 1751 "/builds/moz2_slave/linux_build/build/toolkit/mozapps/update/src/nsUpdateService.js.in"
+ }
+ catch (e) {
+ LOG("UpdateService", "canUpdate - unable to update. Exception: " + e);
+ // No write privileges to install directory
+ return gCanUpdate = false;
+ }
+ // If the administrator has locked the app update functionality
+ // OFF - this is not just a user setting, so disable the manual
+ // UI too.
+ var enabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true);
+ if (!enabled && gPref.prefIsLocked(PREF_APP_UPDATE_ENABLED)) {
+ LOG("UpdateService", "canUpdate - unable to update, disabled by pref");
+ return gCanUpdate = false;
+ }
+
+ // If we don't know the binary platform we're updating, we can't update.
+ if (!gABI) {
+ LOG("UpdateService", "canUpdate - unable tp update, unknown ABI");
+ return gCanUpdate = false;
+ }
+
+ // If we don't know the OS version we're updating, we can't update.
+ if (!gOSVersion) {
+ LOG("UpdateService", "canUpdate unable to update, unknown OS version");
+ return gCanUpdate = false;
+ }
+
+ LOG("UpdateService", "canUpdate - able to update");
+ return gCanUpdate = true;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ addDownloadListener: function AUS_addDownloadListener(listener) {
+ if (!this._downloader) {
+ LOG("UpdateService", "addDownloadListener - no downloader!");
+ return;
+ }
+ this._downloader.addDownloadListener(listener);
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ removeDownloadListener: function AUS_removeDownloadListener(listener) {
+ if (!this._downloader) {
+ LOG("UpdateService", "removeDownloadListener - no downloader!");
+ return;
+ }
+ this._downloader.removeDownloadListener(listener);
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ downloadUpdate: function AUS_downloadUpdate(update, background) {
+ if (!update)
+ throw Cr.NS_ERROR_NULL_POINTER;
+
+ let ai = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo);
+ let vc = Cc["@mozilla.org/xpcom/version-comparator;1"].
+ getService(Ci.nsIVersionComparator);
+ // Don't download the update if the update's version is less than the
+ // current application's version.
+ if (update.extensionVersion && vc.compare(update.extensionVersion, ai.version) < 0) {
+ LOG("UpdateService", "downloadUpdate - removing update for previous " +
+ "application version " + update.extensionVersion);
+ cleanupActiveUpdate();
+ return STATE_NONE;
+ }
+
+ if (this.isDownloading) {
+ if (update.isCompleteUpdate == this._downloader.isCompleteUpdate &&
+ background == this._downloader.background) {
+ LOG("UpdateService", "downloadUpdate - no support for downloading " +
+ "more than one update at a time");
+ return readStatusFile(getUpdatesDir());
+ }
+ this._downloader.cancel();
+ }
+ this._downloader = new Downloader(background);
+ return this._downloader.downloadUpdate(update);
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ pauseDownload: function AUS_pauseDownload() {
+ if (this.isDownloading)
+ this._downloader.cancel();
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get isDownloading() {
+ return this._downloader && this._downloader.isBusy;
+ },
+
+ // nsIClassInfo
+ flags: Ci.nsIClassInfo.SINGLETON,
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ getHelperForLanguage: function(language) null,
+ getInterfaces: function AUS_getInterfaces(count) {
+ var interfaces = [Ci.nsIApplicationUpdateService, Ci.nsITimerCallback,
+ Ci.nsIObserver];
+ count.value = interfaces.length;
+ return interfaces;
+ },
+
+ classDescription: "Update Service",
+ contractID: "@mozilla.org/updates/update-service;1",
+ classID: Components.ID("{B3C290A6-3943-4B89-8BBE-C01EB7B3B311}"),
+ _xpcom_categories: [{ category: "app-startup", service: true }],
+ _xpcom_factory: UpdateServiceFactory,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIApplicationUpdateService,
+ Ci.nsIAddonUpdateCheckListener,
+ Ci.nsITimerCallback,
+ Ci.nsIObserver])
+};
+
+/**
+ * A service to manage active and past updates.
+ * @constructor
+ */
+function UpdateManager() {
+ // Ensure the Active Update file is loaded
+ var updates = this._loadXMLFileIntoArray(getUpdateFile([FILE_UPDATE_ACTIVE]));
+ if (updates.length > 0)
+ this._activeUpdate = updates[0];
+}
+UpdateManager.prototype = {
+ /**
+ * All previously downloaded and installed updates, as an array of nsIUpdate
+ * objects.
+ */
+ _updates: null,
+
+ /**
+ * The current actively downloading/installing update, as a nsIUpdate object.
+ */
+ _activeUpdate: null,
+
+ /**
+ * Loads an updates.xml formatted file into an array of nsIUpdate items.
+ * @param file
+ * A nsIFile for the updates.xml file
+ * @returns The array of nsIUpdate items held in the file.
+ */
+ _loadXMLFileIntoArray: function UM__loadXMLFileIntoArray(file) {
+ if (!file.exists()) {
+ LOG("UpdateManager", "_loadXMLFileIntoArray: XML file does not exist");
+ return [];
+ }
+
+ var result = [];
+ var fileStream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ fileStream.init(file, MODE_RDONLY, PERMS_FILE, 0);
+ try {
+ var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
+ createInstance(Ci.nsIDOMParser);
+ var doc = parser.parseFromStream(fileStream, "UTF-8",
+ fileStream.available(), "text/xml");
+
+ const ELEMENT_NODE = Ci.nsIDOMNode.ELEMENT_NODE;
+ var updateCount = doc.documentElement.childNodes.length;
+ for (var i = 0; i < updateCount; ++i) {
+ var updateElement = doc.documentElement.childNodes.item(i);
+ if (updateElement.nodeType != ELEMENT_NODE ||
+ updateElement.localName != "update")
+ continue;
+
+ updateElement.QueryInterface(Ci.nsIDOMElement);
+ try {
+ var update = new Update(updateElement);
+ } catch (e) {
+ LOG("UpdateManager", "_loadXMLFileIntoArray - invalid update");
+ continue;
+ }
+ result.push(update);
+ }
+ }
+ catch (e) {
+ LOG("UpdateManager", "_loadXMLFileIntoArray - error constructing " +
+ "update list. Exception: " + e);
+ }
+ fileStream.close();
+ return result;
+ },
+
+ /**
+ * Load the update manager, initializing state from state files.
+ */
+ _ensureUpdates: function UM__ensureUpdates() {
+ if (!this._updates) {
+ this._updates = this._loadXMLFileIntoArray(getUpdateFile(
+ [FILE_UPDATES_DB]));
+
+ var activeUpdates = this._loadXMLFileIntoArray(getUpdateFile(
+ [FILE_UPDATE_ACTIVE]));
+ if (activeUpdates.length > 0)
+ this._activeUpdate = activeUpdates[0];
+ }
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ getUpdateAt: function UM_getUpdateAt(index) {
+ this._ensureUpdates();
+ return this._updates[index];
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get updateCount() {
+ this._ensureUpdates();
+ return this._updates.length;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ get activeUpdate() {
+ if (this._activeUpdate &&
+ this._activeUpdate.channel != getUpdateChannel()) {
+ // User switched channels, clear out any old active updates and remove
+ // partial downloads
+ this._activeUpdate = null;
+
+ // Destroy the updates directory, since we're done with it.
+ cleanUpUpdatesDir();
+ }
+ return this._activeUpdate;
+ },
+ set activeUpdate(activeUpdate) {
+ this._addUpdate(activeUpdate);
+ this._activeUpdate = activeUpdate;
+ if (!activeUpdate) {
+ // If |activeUpdate| is null, we have updated both lists - the active list
+ // and the history list, so we want to write both files.
+ this.saveUpdates();
+ }
+ else
+ this._writeUpdatesToXMLFile([this._activeUpdate],
+ getUpdateFile([FILE_UPDATE_ACTIVE]));
+ return activeUpdate;
+ },
+
+ /**
+ * Add an update to the Updates list. If the item already exists in the list,
+ * replace the existing value with the new value.
+ * @param update
+ * The nsIUpdate object to add.
+ */
+ _addUpdate: function UM__addUpdate(update) {
+ if (!update)
+ return;
+ this._ensureUpdates();
+ if (this._updates) {
+ for (var i = 0; i < this._updates.length; ++i) {
+ if (this._updates[i] &&
+ this._updates[i].version == update.version &&
+ this._updates[i].buildID == update.buildID) {
+ // Replace the existing entry with the new value, updating
+ // all metadata.
+ this._updates[i] = update;
+ return;
+ }
+ }
+ }
+ // Otherwise add it to the front of the list.
+ this._updates.unshift(update);
+ },
+
+ /**
+ * Serializes an array of updates to an XML file
+ * @param updates
+ * An array of nsIUpdate objects
+ * @param file
+ * The nsIFile object to serialize to
+ */
+ _writeUpdatesToXMLFile: function UM__writeUpdatesToXMLFile(updates, file) {
+ var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ var modeFlags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
+ if (!file.exists())
+ file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ fos.init(file, modeFlags, PERMS_FILE, 0);
+
+ try {
+ var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
+ createInstance(Ci.nsIDOMParser);
+ const EMPTY_UPDATES_DOCUMENT = "<?xml version=\"1.0\"?><updates xmlns=\"http://www.mozilla.org/2005/app-update\"></updates>";
+ var doc = parser.parseFromString(EMPTY_UPDATES_DOCUMENT, "text/xml");
+
+ for (var i = 0; i < updates.length; ++i) {
+ if (updates[i])
+ doc.documentElement.appendChild(updates[i].serialize(doc));
+ }
+
+ var serializer = Cc["@mozilla.org/xmlextras/xmlserializer;1"].
+ createInstance(Ci.nsIDOMSerializer);
+ serializer.serializeToStream(doc.documentElement, fos, null);
+ }
+ catch (e) {
+ }
+
+ closeSafeOutputStream(fos);
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ saveUpdates: function UM_saveUpdates() {
+ this._writeUpdatesToXMLFile([this._activeUpdate],
+ getUpdateFile([FILE_UPDATE_ACTIVE]));
+ if (this._activeUpdate)
+ this._addUpdate(this._activeUpdate);
+
+ // Don't write updates that have a temporary state to the updates.xml file.
+ if (this._updates) {
+ let updates = this._updates.slice();
+ for (let i = updates.length - 1; i >= 0; --i) {
+ let state = updates[i].state;
+ if (state == STATE_NONE || state == STATE_DOWNLOADING ||
+ state == STATE_PENDING) {
+ updates.splice(i, 1);
+ }
+ }
+
+ this._writeUpdatesToXMLFile(updates.slice(0, 10),
+ getUpdateFile([FILE_UPDATES_DB]));
+ }
+ },
+
+ classDescription: "Update Manager",
+ contractID: "@mozilla.org/updates/update-manager;1",
+ classID: Components.ID("{093C2356-4843-4C65-8709-D7DBCBBE7DFB}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateManager])
+};
+
+
+/**
+ * Checker
+ * Checks for new Updates
+ * @constructor
+ */
+function Checker() {
+}
+Checker.prototype = {
+ /**
+ * The XMLHttpRequest object that performs the connection.
+ */
+ _request : null,
+
+ /**
+ * The nsIUpdateCheckListener callback
+ */
+ _callback : null,
+
+ /**
+ * The URL of the update service XML file to connect to that contains details
+ * about available updates.
+ */
+ getUpdateURL: function UC_getUpdateURL(force) {
+ this._forced = force;
+
+ // Use the override URL if specified.
+ var url = getPref("getCharPref", PREF_APP_UPDATE_URL_OVERRIDE, null);
+
+ // Otherwise, construct the update URL from component parts.
+ if (!url) {
+ try {
+ url = getDefaultPrefBranch().getCharPref(PREF_APP_UPDATE_URL);
+ } catch (e) {
+ }
+ }
+
+ if (!url || url == "") {
+ LOG("Checker", "getUpdateURL - update URL not defined");
+ return null;
+ }
+
+ url = url.replace(/%PRODUCT%/g, gApp.name);
+ url = url.replace(/%VERSION%/g, gApp.version);
+ url = url.replace(/%BUILD_ID%/g, gApp.appBuildID);
+ url = url.replace(/%BUILD_TARGET%/g, gApp.OS + "_" + gABI);
+ url = url.replace(/%OS_VERSION%/g, gOSVersion);
+ if (/%LOCALE%/.test(url))
+ url = url.replace(/%LOCALE%/g, getLocale());
+ url = url.replace(/%CHANNEL%/g, getUpdateChannel());
+ url = url.replace(/%PLATFORM_VERSION%/g, gApp.platformVersion);
+ url = url.replace(/%DISTRIBUTION%/g,
+ getDistributionPrefValue(PREF_APP_DISTRIBUTION));
+ url = url.replace(/%DISTRIBUTION_VERSION%/g,
+ getDistributionPrefValue(PREF_APP_DISTRIBUTION_VERSION));
+ url = url.replace(/\+/g, "%2B");
+
+ if (force)
+ url += (url.indexOf("?") != -1 ? "&" : "?") + "force=1";
+
+ LOG("Checker", "getUpdateURL - update URL: " + url);
+ return url;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ checkForUpdates: function UC_checkForUpdates(listener, force) {
+ if (!listener)
+ throw Cr.NS_ERROR_NULL_POINTER;
+
+ var url = this.getUpdateURL(force);
+ if (!url || (!this.enabled && !force))
+ return;
+
+ this._request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ this._request.open("GET", url, true);
+ this._request.channel.notificationCallbacks = new BadCertHandler();
+ this._request.overrideMimeType("text/xml");
+ this._request.setRequestHeader("Cache-Control", "no-cache");
+
+ var self = this;
+ this._request.onerror = function(event) { self.onError(event); };
+ this._request.onload = function(event) { self.onLoad(event); };
+ this._request.onprogress = function(event) { self.onProgress(event); };
+
+ LOG("Checker", "checkForUpdates - sending request to: " + url);
+ this._request.send(null);
+
+ this._callback = listener;
+ },
+
+ /**
+ * When progress associated with the XMLHttpRequest is received.
+ * @param event
+ * The nsIDOMLSProgressEvent for the load.
+ */
+ onProgress: function UC_onProgress(event) {
+ LOG("Checker", "onProgress - " + event.position + "/" + event.totalSize);
+ this._callback.onProgress(event.target, event.position, event.totalSize);
+ },
+
+ /**
+ * Returns an array of nsIUpdate objects discovered by the update check.
+ */
+ get _updates() {
+ var updatesElement = this._request.responseXML.documentElement;
+ if (!updatesElement) {
+ LOG("Checker", "get_updates - empty updates document?!");
+ return [];
+ }
+
+ if (updatesElement.nodeName != "updates") {
+ LOG("Checker", "get_updates - unexpected node name!");
+ throw "";
+ }
+
+ const ELEMENT_NODE = Ci.nsIDOMNode.ELEMENT_NODE;
+ var updates = [];
+ for (var i = 0; i < updatesElement.childNodes.length; ++i) {
+ var updateElement = updatesElement.childNodes.item(i);
+ if (updateElement.nodeType != ELEMENT_NODE ||
+ updateElement.localName != "update")
+ continue;
+
+ updateElement.QueryInterface(Ci.nsIDOMElement);
+ try {
+ var update = new Update(updateElement);
+ } catch (e) {
+ LOG("Checker", "get_updates - invalid <update/>, ignoring...");
+ continue;
+ }
+ update.serviceURL = this.getUpdateURL(this._forced);
+ update.channel = getUpdateChannel();
+ updates.push(update);
+ }
+
+ return updates;
+ },
+
+ /**
+ * Returns the status code for the XMLHttpRequest
+ */
+ _getChannelStatus: function UC__getChannelStatus(request) {
+ var status = 0;
+ try {
+ status = request.status;
+ }
+ catch (e) {
+ }
+
+ if (status == 0)
+ status = request.channel.QueryInterface(Ci.nsIRequest).status;
+ return status;
+ },
+
+ /**
+ * The XMLHttpRequest succeeded and the document was loaded.
+ * @param event
+ * The nsIDOMEvent for the load
+ */
+ onLoad: function UC_onLoad(event) {
+ LOG("Checker", "onLoad - request completed downloading document");
+
+ try {
+ checkCert(this._request.channel);
+ // Analyze the resulting DOM and determine the set of updates to install
+ var updates = this._updates;
+
+ LOG("Checker", "onLoad - number of updates available: " + updates.length);
+
+ // ... and tell the Update Service about what we discovered.
+ this._callback.onCheckComplete(event.target, updates, updates.length);
+ }
+ catch (e) {
+ LOG("Checker", "onLoad - there was a problem with the update service " +
+ "URL specified, either the XML file was malformed or it does not " +
+ "exist at the location specified. Exception: " + e);
+ var request = event.target;
+ var status = this._getChannelStatus(request);
+ LOG("Checker", "onLoad - request.status: " + status);
+ var update = new Update(null);
+ update.statusText = getStatusTextFromCode(status, 404);
+ this._callback.onError(request, update);
+ }
+
+ this._request = null;
+ },
+
+ /**
+ * There was an error of some kind during the XMLHttpRequest
+ * @param event
+ * The nsIDOMEvent for the load
+ */
+ onError: function UC_onError(event) {
+ var request = event.target;
+ var status = this._getChannelStatus(request);
+ LOG("Checker", "onError - request.status: " + status);
+
+ // If we can't find an error string specific to this status code,
+ // just use the 200 message from above, which means everything
+ // "looks" fine but there was probably an XML error or a bogus file.
+ var update = new Update(null);
+ update.statusText = getStatusTextFromCode(status, 200);
+ this._callback.onError(request, update);
+
+ this._request = null;
+ },
+
+ /**
+ * Whether or not we are allowed to do update checking.
+ */
+ _enabled: true,
+ get enabled() {
+ var aus = Cc["@mozilla.org/updates/update-service;1"].
+ getService(Ci.nsIApplicationUpdateService);
+ var enabled = getPref("getBoolPref", PREF_APP_UPDATE_ENABLED, true) &&
+ aus.canUpdate && this._enabled;
+ return enabled;
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ stopChecking: function UC_stopChecking(duration) {
+ // Always stop the current check
+ if (this._request)
+ this._request.abort();
+
+ switch (duration) {
+ case Ci.nsIUpdateChecker.CURRENT_SESSION:
+ this._enabled = false;
+ break;
+ case Ci.nsIUpdateChecker.ANY_CHECKS:
+ this._enabled = false;
+ gPref.setBoolPref(PREF_APP_UPDATE_ENABLED, this._enabled);
+ break;
+ }
+ },
+
+ classDescription: "Update Checker",
+ contractID: "@mozilla.org/updates/update-checker;1",
+ classID: Components.ID("{898CDC9B-E43F-422F-9CC4-2F6291B415A3}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateChecker])
+};
+
+/**
+ * Manages the download of updates
+ * @param background
+ * Whether or not this downloader is operating in background
+ * update mode.
+ * @constructor
+ */
+function Downloader(background) {
+ this.background = background;
+}
+Downloader.prototype = {
+ /**
+ * The nsIUpdatePatch that we are downloading
+ */
+ _patch: null,
+
+ /**
+ * The nsIUpdate that we are downloading
+ */
+ _update: null,
+
+ /**
+ * The nsIIncrementalDownload object handling the download
+ */
+ _request: null,
+
+ /**
+ * Whether or not the update being downloaded is a complete replacement of
+ * the user's existing installation or a patch representing the difference
+ * between the new version and the previous version.
+ */
+ isCompleteUpdate: null,
+
+ /**
+ * Cancels the active download.
+ */
+ cancel: function Downloader_cancel() {
+ if (this._request && this._request instanceof Ci.nsIRequest) {
+ const NS_BINDING_ABORTED = 0x804b0002;
+ this._request.cancel(NS_BINDING_ABORTED);
+ }
+ },
+
+ /**
+ * Whether or not a patch has been downloaded and staged for installation.
+ */
+ get patchIsStaged() {
+ return readStatusFile(getUpdatesDir()) == STATE_PENDING;
+ },
+
+ /**
+ * Verify the downloaded file. We assume that the download is complete at
+ * this point.
+ */
+ _verifyDownload: function Downloader__verifyDownload() {
+ if (!this._request)
+ return false;
+
+ var destination = this._request.destination;
+
+ // Ensure that the file size matches the expected file size.
+ if (destination.fileSize != this._patch.size)
+ return false;
+
+ var fileStream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ fileStream.init(destination, MODE_RDONLY, PERMS_FILE, 0);
+
+ try {
+ var hash = Cc["@mozilla.org/security/hash;1"].
+ createInstance(Ci.nsICryptoHash);
+ var hashFunction = Ci.nsICryptoHash[this._patch.hashFunction.toUpperCase()];
+ if (hashFunction == undefined)
+ throw Cr.NS_ERROR_UNEXPECTED;
+ hash.init(hashFunction);
+ hash.updateFromStream(fileStream, -1);
+ // NOTE: For now, we assume that the format of _patch.hashValue is hex
+ // encoded binary (such as what is typically output by programs like
+ // sha1sum). In the future, this may change to base64 depending on how
+ // we choose to compute these hashes.
+ digest = binaryToHex(hash.finish(false));
+ } catch (e) {
+ LOG("Downloader", "_verifyDownload - failed to compute hash of " +
+ "downloaded update archive");
+ digest = "";
+ }
+
+ fileStream.close();
+
+ return digest == this._patch.hashValue.toLowerCase();
+ },
+
+ /**
+ * Select the patch to use given the current state of updateDir and the given
+ * set of update patches.
+ * @param update
+ * A nsIUpdate object to select a patch from
+ * @param updateDir
+ * A nsIFile representing the update directory
+ * @returns A nsIUpdatePatch object to download
+ */
+ _selectPatch: function Downloader__selectPatch(update, updateDir) {
+ // Given an update to download, we will always try to download the patch
+ // for a partial update over the patch for a full update.
+
+ /**
+ * Return the first UpdatePatch with the given type.
+ * @param type
+ * The type of the patch ("complete" or "partial")
+ * @returns A nsIUpdatePatch object matching the type specified
+ */
+ function getPatchOfType(type) {
+ for (var i = 0; i < update.patchCount; ++i) {
+ var patch = update.getPatchAt(i);
+ if (patch && patch.type == type)
+ return patch;
+ }
+ return null;
+ }
+
+ // Look to see if any of the patches in the Update object has been
+ // pre-selected for download, otherwise we must figure out which one
+ // to select ourselves.
+ var selectedPatch = update.selectedPatch;
+
+ var state = readStatusFile(updateDir);
+
+ // If this is a patch that we know about, then select it. If it is a patch
+ // that we do not know about, then remove it and use our default logic.
+ var useComplete = false;
+ if (selectedPatch) {
+ LOG("Downloader", "_selectPatch - found existing patch with state: " + state);
+ switch (state) {
+ case STATE_DOWNLOADING:
+ LOG("Downloader", "_selectPatch - resuming download");
+ return selectedPatch;
+ case STATE_PENDING:
+ LOG("Downloader", "_selectPatch - already downloaded and staged");
+ return null;
+ default:
+ // Something went wrong when we tried to apply the previous patch.
+ // Try the complete patch next time.
+ if (update && selectedPatch.type == "partial") {
+ useComplete = true;
+ } else {
+ // This is a pretty fatal error. Just bail.
+ LOG("Downloader", "_selectPatch - failed to apply complete patch!");
+ writeStatusFile(updateDir, STATE_NONE);
+ writeVersionFile(getUpdatesDir(), null);
+ return null;
+ }
+ }
+
+ selectedPatch = null;
+ }
+
+ // If we were not able to discover an update from a previous download, we
+ // select the best patch from the given set.
+ var partialPatch = getPatchOfType("partial");
+ if (!useComplete)
+ selectedPatch = partialPatch;
+ if (!selectedPatch) {
+ if (partialPatch)
+ partialPatch.selected = false;
+ selectedPatch = getPatchOfType("complete");
+ }
+
+ // Restore the updateDir since we may have deleted it.
+ updateDir = getUpdatesDir();
+
+ // if update only contains a partial patch, selectedPatch == null here if
+ // the partial patch has been attempted and fails and we're trying to get a
+ // complete patch
+ if (selectedPatch)
+ selectedPatch.selected = true;
+
+ update.isCompleteUpdate = useComplete;
+
+ // Reset the Active Update object on the Update Manager and flush the
+ // Active Update DB.
+ var um = Cc["@mozilla.org/updates/update-manager;1"].
+ getService(Ci.nsIUpdateManager);
+ um.activeUpdate = update;
+
+ return selectedPatch;
+ },
+
+ /**
+ * Whether or not we are currently downloading something.
+ */
+ get isBusy() {
+ return this._request != null;
+ },
+
+ /**
+ * Download and stage the given update.
+ * @param update
+ * A nsIUpdate object to download a patch for. Cannot be null.
+ */
+ downloadUpdate: function Downloader_downloadUpdate(update) {
+ if (!update)
+ throw Cr.NS_ERROR_NULL_POINTER;
+
+ var updateDir = getUpdatesDir();
+
+ this._update = update;
+
+ // This function may return null, which indicates that there are no patches
+ // to download.
+ this._patch = this._selectPatch(update, updateDir);
+ if (!this._patch) {
+ LOG("Downloader", "downloadUpdate - no patch to download");
+ return readStatusFile(updateDir);
+ }
+ this.isCompleteUpdate = this._patch.type == "complete";
+
+ var patchFile = updateDir.clone();
+ patchFile.append(FILE_UPDATE_ARCHIVE);
+
+ var ios = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var uri = ios.newURI(this._patch.URL, null, null);
+
+ this._request = Cc["@mozilla.org/network/incremental-download;1"].
+ createInstance(Ci.nsIIncrementalDownload);
+
+ LOG("Downloader", "downloadUpdate - downloading from " + uri.spec + " to " +
+ patchFile.path);
+
+ var interval = this.background ? DOWNLOAD_BACKGROUND_INTERVAL
+ : DOWNLOAD_FOREGROUND_INTERVAL;
+ this._request.init(uri, patchFile, DOWNLOAD_CHUNK_SIZE, interval);
+ this._request.start(this, null);
+
+ writeStatusFile(updateDir, STATE_DOWNLOADING);
+ this._patch.QueryInterface(Ci.nsIWritablePropertyBag);
+ this._patch.state = STATE_DOWNLOADING;
+ var um = Cc["@mozilla.org/updates/update-manager;1"].
+ getService(Ci.nsIUpdateManager);
+ um.saveUpdates();
+ return STATE_DOWNLOADING;
+ },
+
+ /**
+ * An array of download listeners to notify when we receive
+ * nsIRequestObserver or nsIProgressEventSink method calls.
+ */
+ _listeners: [],
+
+ /**
+ * Adds a listener to the download process
+ * @param listener
+ * A download listener, implementing nsIRequestObserver and
+ * nsIProgressEventSink
+ */
+ addDownloadListener: function Downloader_addDownloadListener(listener) {
+ for (var i = 0; i < this._listeners.length; ++i) {
+ if (this._listeners[i] == listener)
+ return;
+ }
+ this._listeners.push(listener);
+ },
+
+ /**
+ * Removes a download listener
+ * @param listener
+ * The listener to remove.
+ */
+ removeDownloadListener: function Downloader_removeDownloadListener(listener) {
+ for (var i = 0; i < this._listeners.length; ++i) {
+ if (this._listeners[i] == listener) {
+ this._listeners.splice(i, 1);
+ return;
+ }
+ }
+ },
+
+ /**
+ * When the async request begins
+ * @param request
+ * The nsIRequest object for the transfer
+ * @param context
+ * Additional data
+ */
+ onStartRequest: function Downloader_onStartRequest(request, context) {
+ if (request instanceof Ci.nsIIncrementalDownload)
+ LOG("Downloader", "onStartRequest - spec: " + request.URI.spec);
+
+ var listenerCount = this._listeners.length;
+ for (var i = 0; i < listenerCount; ++i)
+ this._listeners[i].onStartRequest(request, context);
+ },
+
+ /**
+ * When new data has been downloaded
+ * @param request
+ * The nsIRequest object for the transfer
+ * @param context
+ * Additional data
+ * @param progress
+ * The current number of bytes transferred
+ * @param maxProgress
+ * The total number of bytes that must be transferred
+ */
+ onProgress: function Downloader_onProgress(request, context, progress,
+ maxProgress) {
+ LOG("Downloader.onProgress", "onProgress - progress: " + progress + "/" +
+ maxProgress);
+
+ var listenerCount = this._listeners.length;
+ for (var i = 0; i < listenerCount; ++i) {
+ var listener = this._listeners[i];
+ if (listener instanceof Ci.nsIProgressEventSink)
+ listener.onProgress(request, context, progress, maxProgress);
+ }
+ },
+
+ /**
+ * When we have new status text
+ * @param request
+ * The nsIRequest object for the transfer
+ * @param context
+ * Additional data
+ * @param status
+ * A status code
+ * @param statusText
+ * Human readable version of |status|
+ */
+ onStatus: function Downloader_onStatus(request, context, status, statusText) {
+ LOG("Downloader", "onStatus - status: " + status + ", statusText: " +
+ statusText);
+
+ var listenerCount = this._listeners.length;
+ for (var i = 0; i < listenerCount; ++i) {
+ var listener = this._listeners[i];
+ if (listener instanceof Ci.nsIProgressEventSink)
+ listener.onStatus(request, context, status, statusText);
+ }
+ },
+
+ /**
+ * When data transfer ceases
+ * @param request
+ * The nsIRequest object for the transfer
+ * @param context
+ * Additional data
+ * @param status
+ * Status code containing the reason for the cessation.
+ */
+ onStopRequest: function Downloader_onStopRequest(request, context, status) {
+ if (request instanceof Ci.nsIIncrementalDownload)
+ LOG("Downloader", "onStopRequest - spec: " + request.URI.spec +
+ ", status: " + status);
+
+ var state = this._patch.state;
+ var shouldShowPrompt = false;
+ var deleteActiveUpdate = false;
+ const NS_BINDING_ABORTED = 0x804b0002;
+ const NS_ERROR_ABORT = 0x80004004;
+ if (Components.isSuccessCode(status)) {
+ var sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ var updateStrings = sbs.createBundle(URI_UPDATES_PROPERTIES);
+ if (this._verifyDownload()) {
+ state = STATE_PENDING;
+
+ // We only need to explicitly show the prompt if this is a backround
+ // download, since otherwise some kind of UI is already visible and
+ // that UI will notify.
+ if (this.background)
+ shouldShowPrompt = true;
+
+ // Tell the updater.exe we're ready to apply.
+ writeStatusFile(getUpdatesDir(), state);
+ writeVersionFile(getUpdatesDir(), this._update.extensionVersion);
+ this._update.installDate = (new Date()).getTime();
+ this._update.statusText = updateStrings.GetStringFromName("installPending");
+ }
+ else {
+ LOG("Downloader", "onStopRequest - download verification failed");
+ state = STATE_DOWNLOAD_FAILED;
+
+ // TODO: use more informative error code here
+ status = Cr.NS_ERROR_UNEXPECTED;
+
+ // Yes, this code is a string.
+ const vfCode = "verification_failed";
+ var message = getStatusTextFromCode(vfCode, vfCode);
+ this._update.statusText = message;
+
+ if (this._update.isCompleteUpdate)
+ deleteActiveUpdate = true;
+
+ // Destroy the updates directory, since we're done with it.
+ cleanUpUpdatesDir();
+ }
+ }
+ else if (status != NS_BINDING_ABORTED &&
+ status != NS_ERROR_ABORT) {
+ LOG("Downloader", "onStopRequest - non-verification failure");
+ // Some sort of other failure, log this in the |statusText| property
+ state = STATE_DOWNLOAD_FAILED;
+
+ // XXXben - if |request| (The Incremental Download) provided a means
+ // for accessing the http channel we could do more here.
+
+ const NS_BINDING_FAILED = 2152398849;
+ this._update.statusText = getStatusTextFromCode(status,
+ NS_BINDING_FAILED);
+
+ // Destroy the updates directory, since we're done with it.
+ cleanUpUpdatesDir();
+
+ deleteActiveUpdate = true;
+ }
+ LOG("Downloader", "onStopRequest - setting state to: " + state);
+ this._patch.state = state;
+ var um = Cc["@mozilla.org/updates/update-manager;1"].
+ getService(Ci.nsIUpdateManager);
+ if (deleteActiveUpdate) {
+ this._update.installDate = (new Date()).getTime();
+ um.activeUpdate = null;
+ }
+ else {
+ if (um.activeUpdate)
+ um.activeUpdate.state = state;
+ }
+ um.saveUpdates();
+
+ var listenerCount = this._listeners.length;
+ for (var i = 0; i < listenerCount; ++i)
+ this._listeners[i].onStopRequest(request, context, status);
+
+ this._request = null;
+
+ if (state == STATE_DOWNLOAD_FAILED) {
+ if (!this._update.isCompleteUpdate) {
+ var allFailed = true;
+
+ // If we were downloading a patch and the patch verification phase
+ // failed, log this and then commence downloading the complete update.
+ LOG("Downloader", "onStopRequest - verification of patch failed, " +
+ "downloading complete update");
+ this._update.isCompleteUpdate = true;
+ var status = this.downloadUpdate(this._update);
+
+ if (status == STATE_NONE) {
+ cleanupActiveUpdate();
+ } else {
+ allFailed = false;
+ }
+ // This will reset the |.state| property on this._update if a new
+ // download initiates.
+ }
+
+ // if we still fail after trying a complete download, give up completely
+ if (allFailed) {
+ // In all other failure cases, i.e. we're S.O.L. - no more failing over
+ // ...
+
+ // If this was ever a foreground download, and now there is no UI active
+ // (e.g. because the user closed the download window) and there was an
+ // error, we must notify now. Otherwise we can keep the failure to
+ // ourselves since the user won't be expecting it.
+ try {
+ this._update.QueryInterface(Ci.nsIWritablePropertyBag);
+ var fgdl = this._update.getProperty("foregroundDownload");
+ }
+ catch (e) {
+ }
+
+ if (fgdl == "true") {
+ var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
+ createInstance(Ci.nsIUpdatePrompt);
+ this._update.QueryInterface(Ci.nsIWritablePropertyBag);
+ this._update.setProperty("downloadFailed", "true");
+ prompter.showUpdateError(this._update);
+ }
+ }
+
+ // Prevent leaking the update object (bug 454964)
+ this._update = null;
+ // the complete download succeeded or total failure was handled, so exit
+ return;
+ }
+
+ // Do this after *everything* else, since it will likely cause the app
+ // to shut down.
+ if (shouldShowPrompt) {
+ // Notify the user that an update has been downloaded and is ready for
+ // installation (i.e. that they should restart the application). We do
+ // not notify on failed update attempts.
+ var prompter = Cc["@mozilla.org/updates/update-prompt;1"].
+ createInstance(Ci.nsIUpdatePrompt);
+ prompter.showUpdateDownloaded(this._update, true);
+ }
+ // Prevent leaking the update object (bug 454964)
+ this._update = null;
+ },
+
+ /**
+ * See nsIInterfaceRequestor.idl
+ */
+ getInterface: function Downloader_getInterface(iid) {
+ // The network request may require proxy authentication, so provide the
+ // default nsIAuthPrompt if requested.
+ if (iid.equals(Ci.nsIAuthPrompt)) {
+ var prompt = Cc["@mozilla.org/network/default-auth-prompt;1"].
+ createInstance();
+ return prompt.QueryInterface(iid);
+ }
+ throw Components.results.NS_NOINTERFACE;
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIRequestObserver,
+ Ci.nsIProgressEventSink,
+ Ci.nsIInterfaceRequestor])
+};
+
+/**
+ * A manager for update check timers. Manages timers that fire over long
+ * periods of time (e.g. days, weeks).
+ * @constructor
+ */
+function TimerManager() {
+ getObserverService().addObserver(this, "xpcom-shutdown", false);
+
+ this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ var timerInterval = getPref("getIntPref", PREF_APP_UPDATE_TIMER, 600000);
+ this._timer.initWithCallback(this, timerInterval,
+ Ci.nsITimer.TYPE_REPEATING_SLACK);
+}
+TimerManager.prototype = {
+ /**
+ * See nsIObserver.idl
+ */
+ observe: function TM_observe(subject, topic, data) {
+ if (topic == "xpcom-shutdown") {
+ getObserverService().removeObserver(this, "xpcom-shutdown");
+
+ // Release everything we hold onto.
+ for (var timerID in this._timers)
+ delete this._timers[timerID];
+ this._timer = null;
+ this._timers = null;
+ }
+ },
+
+ /**
+ * The Checker Timer
+ */
+ _timer: null,
+
+ /**
+ * The set of registered timers.
+ */
+ _timers: { },
+
+ /**
+ * Called when the checking timer fires.
+ * @param timer
+ * The checking timer that fired.
+ */
+ notify: function TM_notify(timer) {
+ for (var timerID in this._timers) {
+ var timerData = this._timers[timerID];
+ var lastUpdateTime = timerData.lastUpdateTime;
+ var now = Math.round(Date.now() / 1000);
+
+ // Fudge the lastUpdateTime by some random increment of the update
+ // check interval (e.g. some random slice of 10 minutes) so that when
+ // the time comes to check, we offset each client request by a random
+ // amount so they don't all hit at once. app.update.timer is in milliseconds,
+ // whereas app.update.lastUpdateTime is in seconds
+ var timerInterval = getPref("getIntPref", PREF_APP_UPDATE_TIMER, 600000);
+ lastUpdateTime += Math.round(Math.random() * timerInterval / 1000);
+
+ if ((now - lastUpdateTime) > timerData.interval &&
+ timerData.callback instanceof Ci.nsITimerCallback) {
+ timerData.callback.notify(timer);
+ timerData.lastUpdateTime = now;
+ var preference = PREF_APP_UPDATE_LASTUPDATETIME_FMT.replace(/%ID%/, timerID);
+ gPref.setIntPref(preference, now);
+ }
+ }
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ registerTimer: function TM_registerTimer(id, callback, interval) {
+ var preference = PREF_APP_UPDATE_LASTUPDATETIME_FMT.replace(/%ID%/, id);
+ var now = Math.round(Date.now() / 1000);
+ var lastUpdateTime = null;
+ if (gPref.prefHasUserValue(preference)) {
+ lastUpdateTime = gPref.getIntPref(preference);
+ } else {
+ gPref.setIntPref(preference, now);
+ lastUpdateTime = now;
+ }
+ this._timers[id] = { callback : callback,
+ interval : interval,
+ lastUpdateTime : lastUpdateTime };
+ },
+
+ classDescription: "Timer Manager",
+ contractID: "@mozilla.org/updates/timer-manager;1",
+ classID: Components.ID("{B322A5C0-A419-484E-96BA-D7182163899F}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateTimerManager,
+ Ci.nsITimerCallback,
+ Ci.nsIObserver])
+};
+
+/**
+ * UpdatePrompt
+ * An object which can prompt the user with information about updates, request
+ * action, etc. Embedding clients can override this component with one that
+ * invokes a native front end.
+ * @constructor
+ */
+function UpdatePrompt() {
+}
+UpdatePrompt.prototype = {
+ /**
+ * See nsIUpdateService.idl
+ */
+ checkForUpdates: function UP_checkForUpdates() {
+ this._showUI(null, URI_UPDATE_PROMPT_DIALOG, null, UPDATE_WINDOW_NAME,
+ null, null);
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ showUpdateAvailable: function UP_showUpdateAvailable(update) {
+ if (!this._enabled || this._getUpdateWindow())
+ return;
+
+ var bundle = this._updateBundle;
+ var stringsPrefix = "updateAvailable_" + update.type + ".";
+ var title = bundle.formatStringFromName(stringsPrefix + "title",
+ [update.name], 1);
+ var text = bundle.GetStringFromName(stringsPrefix + "text");
+ var imageUrl = "";
+ this._showUnobtrusiveUI(null, URI_UPDATE_PROMPT_DIALOG, null,
+ UPDATE_WINDOW_NAME, "updatesavailable", update,
+ title, text, imageUrl);
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ showUpdateDownloaded: function UP_showUpdateDownloaded(update, background) {
+ if (background) {
+ if (!this._enabled)
+ return;
+
+ var bundle = this._updateBundle;
+ var stringsPrefix = "updateDownloaded_" + update.type + ".";
+ var title = bundle.formatStringFromName(stringsPrefix + "title",
+ [update.name], 1);
+ var text = bundle.GetStringFromName(stringsPrefix + "text");
+ var imageUrl = "";
+ this._showUnobtrusiveUI(null, URI_UPDATE_PROMPT_DIALOG, null,
+ UPDATE_WINDOW_NAME, "finishedBackground", update,
+ title, text, imageUrl);
+ } else {
+ this._showUI(null, URI_UPDATE_PROMPT_DIALOG, null,
+ UPDATE_WINDOW_NAME, "finishedBackground", update);
+ }
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ showUpdateInstalled: function UP_showUpdateInstalled() {
+ if (!this._enabled || this._getUpdateWindow() ||
+ !getPref("getBoolPref", PREF_APP_UPDATE_SHOW_INSTALLED_UI, true))
+ return;
+
+ var page = "installed";
+ var win = this._getUpdateWindow();
+ if (win) {
+ if (page && "setCurrentPage" in win)
+ win.setCurrentPage(page);
+ win.focus();
+ }
+ else {
+ var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ var arg = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ arg.data = page;
+ ww.openWindow(null, URI_UPDATE_PROMPT_DIALOG, null, openFeatures, arg);
+ }
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ showUpdateError: function UP_showUpdateError(update) {
+ if (!this._enabled)
+ return;
+
+ // In some cases, we want to just show a simple alert dialog:
+ if (update.state == STATE_FAILED && update.errorCode == WRITE_ERROR) {
+ var updateBundle = this._updateBundle;
+ var title = updateBundle.GetStringFromName("updaterIOErrorTitle");
+ var text = updateBundle.formatStringFromName("updaterIOErrorMsg",
+ [gApp.name, gApp.name], 2);
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.getNewPrompter(null).alert(title, text);
+ } else {
+ this._showUI(null, URI_UPDATE_PROMPT_DIALOG, null, UPDATE_WINDOW_NAME,
+ "errors", update);
+ }
+ },
+
+ /**
+ * See nsIUpdateService.idl
+ */
+ showUpdateHistory: function UP_showUpdateHistory(parent) {
+ this._showUI(parent, URI_UPDATE_HISTORY_DIALOG, "modal,dialog=yes",
+ "Update:History", null, null);
+ },
+
+ /**
+ * Whether or not we are enabled (i.e. not in Silent mode)
+ */
+ get _enabled() {
+ return !getPref("getBoolPref", PREF_APP_UPDATE_SILENT, false);
+ },
+
+ get _updateBundle() {
+ return Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).
+ createBundle(URI_UPDATES_PROPERTIES);
+ },
+
+ /**
+ * Returns the update window if present.
+ */
+ _getUpdateWindow: function UP__getUpdateWindow() {
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+ return wm.getMostRecentWindow(UPDATE_WINDOW_NAME);
+ },
+
+ /**
+ * Initiate a less obtrusive UI, starting with a non-modal notification alert
+ * @param parent
+ * A parent window, can be null
+ * @param uri
+ * The URI string of the dialog to show
+ * @param name
+ * The Window Name of the dialog to show, in case it is already open
+ * and can merely be focused
+ * @param page
+ * The page of the wizard to be displayed, if one is already open.
+ * @param update
+ * An update to pass to the UI in the window arguments.
+ * Can be null
+ * @param title
+ * The title for the notification alert.
+ * @param text
+ * The contents of the notification alert.
+ * @param imageUrl
+ * A URL identifying the image to put in the notification alert.
+ */
+ _showUnobtrusiveUI: function UP__showUnobUI(parent, uri, features, name, page,
+ update, title, text, imageUrl) {
+ var observer = {
+ updatePrompt: this,
+ service: null,
+ timer: null,
+ notify: function () {
+ // the user hasn't restarted yet => prompt when idle
+ this.service.removeObserver(this, "quit-application");
+ // If the update window is already open skip showing the UI
+ if (this.updatePrompt._getUpdateWindow())
+ return;
+ this.updatePrompt._showUIWhenIdle(parent, uri, features, name, page, update);
+ },
+ observe: function (aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "alertclickcallback":
+ this.updatePrompt._showUI(parent, uri, features, name, page, update);
+ // fall thru
+ case "quit-application":
+ this.timer.cancel();
+ this.service.removeObserver(this, "quit-application");
+ break;
+ }
+ }
+ };
+
+ try {
+ var notifier = Cc["@mozilla.org/alerts-service;1"].
+ getService(Ci.nsIAlertsService);
+ notifier.showAlertNotification(imageUrl, title, text, true, "", observer);
+ }
+ catch (e) {
+ // Failed to retrieve alerts service, platform unsupported
+ this._showUIWhenIdle(parent, uri, features, name, page, update);
+ return;
+ }
+
+ observer.service = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ observer.service.addObserver(observer, "quit-application", false);
+
+ // Give the user x seconds to react before showing the big UI
+ var promptWaitTime = getPref("getIntPref", PREF_APP_UPDATE_PROMPTWAITTIME, 43200);
+ observer.timer = Cc["@mozilla.org/timer;1"].
+ createInstance(Ci.nsITimer);
+ observer.timer.initWithCallback(observer, promptWaitTime * 1000,
+ observer.timer.TYPE_ONE_SHOT);
+ },
+
+ /**
+ * Show the UI when the user was idle
+ * @param parent
+ * A parent window, can be null
+ * @param uri
+ * The URI string of the dialog to show
+ * @param name
+ * The Window Name of the dialog to show, in case it is already open
+ * and can merely be focused
+ * @param page
+ * The page of the wizard to be displayed, if one is already open.
+ * @param update
+ * An update to pass to the UI in the window arguments.
+ * Can be null
+ */
+ _showUIWhenIdle: function UP__showUIWhenIdle(parent, uri, features, name,
+ page, update) {
+ var idleService = Cc["@mozilla.org/widget/idleservice;1"].
+ getService(Ci.nsIIdleService);
+
+ const IDLE_TIME = getPref("getIntPref", PREF_APP_UPDATE_IDLETIME, 60);
+ if (idleService.idleTime / 1000 >= IDLE_TIME) {
+ this._showUI(parent, uri, features, name, page, update);
+ } else {
+ var observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ var observer = {
+ updatePrompt: this,
+ observe: function (aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "idle":
+ // If the update window is already open skip showing the UI
+ if (!this.updatePrompt._getUpdateWindow())
+ this.updatePrompt._showUI(parent, uri, features, name, page, update);
+ // fall thru
+ case "quit-application":
+ idleService.removeIdleObserver(this, IDLE_TIME);
+ observerService.removeObserver(this, "quit-application");
+ break;
+ }
+ }
+ };
+ idleService.addIdleObserver(observer, IDLE_TIME);
+ observerService.addObserver(observer, "quit-application", false);
+ }
+ },
+
+ /**
+ * Show the Update Checking UI
+ * @param parent
+ * A parent window, can be null
+ * @param uri
+ * The URI string of the dialog to show
+ * @param name
+ * The Window Name of the dialog to show, in case it is already open
+ * and can merely be focused
+ * @param page
+ * The page of the wizard to be displayed, if one is already open.
+ * @param update
+ * An update to pass to the UI in the window arguments.
+ * Can be null
+ */
+ _showUI: function UP__showUI(parent, uri, features, name, page, update) {
+ var ary = null;
+ if (update) {
+ ary = Cc["@mozilla.org/supports-array;1"].
+ createInstance(Ci.nsISupportsArray);
+ ary.AppendElement(update);
+ }
+
+ var win = this._getUpdateWindow();
+ if (win) {
+ if (page && "setCurrentPage" in win)
+ win.setCurrentPage(page);
+ win.focus();
+ }
+ else {
+ var openFeatures = "chrome,centerscreen,dialog=no,resizable=no,titlebar,toolbar=no";
+ if (features)
+ openFeatures += "," + features;
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(parent, uri, "", openFeatures, ary);
+ }
+ },
+
+ classDescription: "Update Prompt",
+ contractID: "@mozilla.org/updates/update-prompt;1",
+ classID: Components.ID("{27ABA825-35B5-4018-9FDD-F99250A0E722}"),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdatePrompt])
+};
+
+function NSGetModule(compMgr, fileSpec)
+ XPCOMUtils.generateModule([UpdateService, Checker, UpdatePrompt, TimerManager, UpdateManager]);
+
diff --git a/bundles/XO/components/nsUrlClassifierLib.js b/bundles/XO/components/nsUrlClassifierLib.js
new file mode 100755
index 0000000..ff8bad6
--- /dev/null
+++ b/bundles/XO/components/nsUrlClassifierLib.js
@@ -0,0 +1,1595 @@
+//@line 37 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/src/nsUrlClassifierLib.js"
+
+// We wastefully reload the same JS files across components. This puts all
+// the common JS files used by safebrowsing and url-classifier into a
+// single component.
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const G_GDEBUG = false;
+
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/lang.js"
+
+
+/**
+ * lang.js - Some missing JavaScript language features
+ */
+
+/**
+ * Partially applies a function to a particular "this object" and zero or
+ * more arguments. The result is a new function with some arguments of the first
+ * function pre-filled and the value of |this| "pre-specified".
+ *
+ * Remaining arguments specified at call-time are appended to the pre-
+ * specified ones.
+ *
+ * Usage:
+ * var barMethBound = BindToObject(myFunction, myObj, "arg1", "arg2");
+ * barMethBound("arg3", "arg4");
+ *
+ * @param fn {string} Reference to the function to be bound
+ *
+ * @param self {object} Specifies the object which |this| should point to
+ * when the function is run. If the value is null or undefined, it will default
+ * to the global object.
+ *
+ * @returns {function} A partially-applied form of the speficied function.
+ */
+function BindToObject(fn, self, opt_args) {
+ var boundargs = fn.boundArgs_ || [];
+ boundargs = boundargs.concat(Array.slice(arguments, 2, arguments.length));
+
+ if (fn.boundSelf_)
+ self = fn.boundSelf_;
+ if (fn.boundFn_)
+ fn = fn.boundFn_;
+
+ var newfn = function() {
+ // Combine the static args and the new args into one big array
+ var args = boundargs.concat(Array.slice(arguments));
+ return fn.apply(self, args);
+ }
+
+ newfn.boundArgs_ = boundargs;
+ newfn.boundSelf_ = self;
+ newfn.boundFn_ = fn;
+
+ return newfn;
+}
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ *
+ * Usage:
+ *
+ * function ParentClass(a, b) { }
+ * ParentClass.prototype.foo = function(a) { }
+ *
+ * function ChildClass(a, b, c) {
+ * ParentClass.call(this, a, b);
+ * }
+ *
+ * ChildClass.inherits(ParentClass);
+ *
+ * var child = new ChildClass("a", "b", "see");
+ * child.foo(); // works
+ *
+ * In addition, a superclass' implementation of a method can be invoked
+ * as follows:
+ *
+ * ChildClass.prototype.foo = function(a) {
+ * ChildClass.superClass_.foo.call(this, a);
+ * // other code
+ * };
+ */
+Function.prototype.inherits = function(parentCtor) {
+ var tempCtor = function(){};
+ tempCtor.prototype = parentCtor.prototype;
+ this.superClass_ = parentCtor.prototype;
+ this.prototype = new tempCtor();
+}
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/preferences.js"
+
+
+// Class for manipulating preferences. Aside from wrapping the pref
+// service, useful functionality includes:
+//
+// - abstracting prefobserving so that you can observe preferences
+// without implementing nsIObserver
+//
+// - getters that return a default value when the pref doesn't exist
+// (instead of throwing)
+//
+// - get-and-set getters
+//
+// Example:
+//
+// var p = new PROT_Preferences();
+// dump(p.getPref("some-true-pref")); // shows true
+// dump(p.getPref("no-such-pref", true)); // shows true
+// dump(p.getPref("no-such-pref", null)); // shows null
+//
+// function observe(prefThatChanged) {
+// dump("Pref changed: " + prefThatChanged);
+// };
+//
+// p.addObserver("somepref", observe);
+// p.setPref("somepref", true); // dumps
+// p.removeObserver("somepref", observe);
+//
+// TODO: should probably have the prefobserver pass in the new and old
+// values
+
+// TODO(tc): Maybe remove this class and just call natively since we're no
+// longer an extension.
+
+/**
+ * A class that wraps the preferences service.
+ *
+ * @param opt_startPoint A starting point on the prefs tree to resolve
+ * names passed to setPref and getPref.
+ *
+ * @param opt_useDefaultPranch Set to true to work against the default
+ * preferences tree instead of the profile one.
+ *
+ * @constructor
+ */
+function G_Preferences(opt_startPoint, opt_getDefaultBranch) {
+ this.debugZone = "prefs";
+ this.observers_ = {};
+ this.getDefaultBranch_ = !!opt_getDefaultBranch;
+
+ this.startPoint_ = opt_startPoint || null;
+}
+
+G_Preferences.setterMap_ = { "string": "setCharPref",
+ "boolean": "setBoolPref",
+ "number": "setIntPref" };
+
+G_Preferences.getterMap_ = {};
+G_Preferences.getterMap_[Ci.nsIPrefBranch.PREF_STRING] = "getCharPref";
+G_Preferences.getterMap_[Ci.nsIPrefBranch.PREF_BOOL] = "getBoolPref";
+G_Preferences.getterMap_[Ci.nsIPrefBranch.PREF_INT] = "getIntPref";
+
+G_Preferences.prototype.__defineGetter__('prefs_', function() {
+ var prefs;
+ var prefSvc = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefService);
+
+ if (this.getDefaultBranch_) {
+ prefs = prefSvc.getDefaultBranch(this.startPoint_);
+ } else {
+ prefs = prefSvc.getBranch(this.startPoint_);
+ }
+
+ // QI to prefs in case we want to add observers
+ prefs.QueryInterface(Ci.nsIPrefBranchInternal);
+ return prefs;
+});
+
+/**
+ * Stores a key/value in a user preference. Valid types for val are string,
+ * boolean, and number. Complex values are not yet supported (but feel free to
+ * add them!).
+ */
+G_Preferences.prototype.setPref = function(key, val) {
+ var datatype = typeof(val);
+
+ if (datatype == "number" && (val % 1 != 0)) {
+ throw new Error("Cannot store non-integer numbers in preferences.");
+ }
+
+ var meth = G_Preferences.setterMap_[datatype];
+
+ if (!meth) {
+ throw new Error("Pref datatype {" + datatype + "} not supported.");
+ }
+
+ return this.prefs_[meth](key, val);
+}
+
+/**
+ * Retrieves a user preference. Valid types for the value are the same as for
+ * setPref. If the preference is not found, opt_default will be returned
+ * instead.
+ */
+G_Preferences.prototype.getPref = function(key, opt_default) {
+ var type = this.prefs_.getPrefType(key);
+
+ // zero means that the specified pref didn't exist
+ if (type == Ci.nsIPrefBranch.PREF_INVALID) {
+ return opt_default;
+ }
+
+ var meth = G_Preferences.getterMap_[type];
+
+ if (!meth) {
+ throw new Error("Pref datatype {" + type + "} not supported.");
+ }
+
+ // If a pref has been cleared, it will have a valid type but won't
+ // be gettable, so this will throw.
+ try {
+ return this.prefs_[meth](key);
+ } catch(e) {
+ return opt_default;
+ }
+}
+
+/**
+ * Delete a preference.
+ *
+ * @param which Name of preference to obliterate
+ */
+G_Preferences.prototype.clearPref = function(which) {
+ try {
+ // This throws if the pref doesn't exist, which is fine because a
+ // non-existent pref is cleared
+ this.prefs_.clearUserPref(which);
+ } catch(e) {}
+}
+
+/**
+ * Add an observer for a given pref.
+ *
+ * @param which String containing the pref to listen to
+ * @param callback Function to be called when the pref changes. This
+ * function will receive a single argument, a string
+ * holding the preference name that changed
+ */
+G_Preferences.prototype.addObserver = function(which, callback) {
+ // Need to store the observer we create so we can eventually unregister it
+ if (!this.observers_[which])
+ this.observers_[which] = { callbacks: [], observers: [] };
+
+ /* only add an observer if the callback hasn't been registered yet */
+ if (this.observers_[which].callbacks.indexOf(callback) == -1) {
+ var observer = new G_PreferenceObserver(callback);
+ this.observers_[which].callbacks.push(callback);
+ this.observers_[which].observers.push(observer);
+ this.prefs_.addObserver(which, observer, false /* strong reference */);
+ }
+}
+
+/**
+ * Remove an observer for a given pref.
+ *
+ * @param which String containing the pref to stop listening to
+ * @param callback Function to remove as an observer
+ */
+G_Preferences.prototype.removeObserver = function(which, callback) {
+ var ix = this.observers_[which].callbacks.indexOf(callback);
+ G_Assert(this, ix != -1, "Tried to unregister a nonexistant observer");
+ this.observers_[which].callbacks.splice(ix, 1);
+ var observer = this.observers_[which].observers.splice(ix, 1)[0];
+ this.prefs_.removeObserver(which, observer);
+}
+
+/**
+ * Remove all preference observers registered through this object.
+ */
+G_Preferences.prototype.removeAllObservers = function() {
+ for (var which in this.observers_) {
+ for each (var observer in this.observers_[which].observers) {
+ this.prefs_.removeObserver(which, observer);
+ }
+ }
+ this.observers_ = {};
+}
+
+/**
+ * Helper class that knows how to observe preference changes and
+ * invoke a callback when they do
+ *
+ * @constructor
+ * @param callback Function to call when the preference changes
+ */
+function G_PreferenceObserver(callback) {
+ this.debugZone = "prefobserver";
+ this.callback_ = callback;
+}
+
+/**
+ * Invoked by the pref system when a preference changes. Passes the
+ * message along to the callback.
+ *
+ * @param subject The nsIPrefBranch that changed
+ * @param topic String "nsPref:changed" (aka
+ * NS_PREFBRANCH_PREFCHANGE_OBSERVER_ID -- but where does it
+ * live???)
+ * @param data Name of the pref that changed
+ */
+G_PreferenceObserver.prototype.observe = function(subject, topic, data) {
+ G_Debug(this, "Observed pref change: " + data);
+ this.callback_(data);
+}
+
+/**
+ * XPCOM cruft
+ *
+ * @param iid Interface id of the interface the caller wants
+ */
+G_PreferenceObserver.prototype.QueryInterface = function(iid) {
+ if (iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsIObserver) ||
+ iid.equals(Ci.nsISupportsWeakReference))
+ return this;
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+}
+
+//@line 38 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/debug.js"
+
+//@line 868 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/debug.js"
+
+// Stubs for the debugging aids scattered through this component.
+// They will be expanded if you compile yourself a debug build.
+
+function G_Debug(who, msg) { }
+function G_Assert(who, condition, msg) { }
+function G_Error(who, msg) { }
+var G_debugService = { __noSuchMethod__: function() { } };
+
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/alarm.js"
+
+
+// An Alarm fires a callback after a certain amount of time, or at
+// regular intervals. It's a convenient replacement for
+// setTimeout/Interval when you don't want to bind to a specific
+// window.
+//
+// The ConditionalAlarm is an Alarm that cancels itself if its callback
+// returns a value that type-converts to true.
+//
+// Example:
+//
+// function foo() { dump('hi'); };
+// new G_Alarm(foo, 10*1000); // Fire foo in 10 seconds
+// new G_Alarm(foo, 10*1000, true /*repeat*/); // Fire foo every 10 seconds
+// new G_Alarm(foo, 10*1000, true, 7); // Fire foo every 10 seconds
+// // seven times
+// new G_ConditionalAlarm(foo, 1000, true); // Fire every sec until foo()==true
+//
+// // Fire foo every 10 seconds until foo returns true or until it fires seven
+// // times, whichever happens first.
+// new G_ConditionalAlarm(foo, 10*1000, true /*repeating*/, 7);
+//
+// TODO: maybe pass an isFinal flag to the callback if they opted to
+// set maxTimes and this is the last iteration?
+
+
+/**
+ * Set an alarm to fire after a given amount of time, or at specific
+ * intervals.
+ *
+ * @param callback Function to call when the alarm fires
+ * @param delayMS Number indicating the length of the alarm period in ms
+ * @param opt_repeating Boolean indicating whether this should fire
+ * periodically
+ * @param opt_maxTimes Number indicating a maximum number of times to
+ * repeat (obviously only useful when opt_repeating==true)
+ */
+function G_Alarm(callback, delayMS, opt_repeating, opt_maxTimes) {
+ this.debugZone = "alarm";
+ this.callback_ = callback;
+ this.repeating_ = !!opt_repeating;
+ this.timer_ = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ var type = opt_repeating ?
+ this.timer_.TYPE_REPEATING_SLACK :
+ this.timer_.TYPE_ONE_SHOT;
+ this.maxTimes_ = opt_maxTimes ? opt_maxTimes : null;
+ this.nTimes_ = 0;
+
+ this.observerServiceObserver_ = new G_ObserverServiceObserver(
+ 'xpcom-shutdown',
+ BindToObject(this.cancel, this));
+
+ // Ask the timer to use nsITimerCallback (.notify()) when ready
+ this.timer_.initWithCallback(this, delayMS, type);
+}
+
+/**
+ * Cancel this timer
+ */
+G_Alarm.prototype.cancel = function() {
+ if (!this.timer_) {
+ return;
+ }
+
+ this.timer_.cancel();
+ // Break circular reference created between this.timer_ and the G_Alarm
+ // instance (this)
+ this.timer_ = null;
+ this.callback_ = null;
+
+ // We don't need the shutdown observer anymore
+ this.observerServiceObserver_.unregister();
+}
+
+/**
+ * Invoked by the timer when it fires
+ *
+ * @param timer Reference to the nsITimer which fired (not currently
+ * passed along)
+ */
+G_Alarm.prototype.notify = function(timer) {
+ // fire callback and save results
+ var ret = this.callback_();
+
+ // If they've given us a max number of times to fire, enforce it
+ this.nTimes_++;
+ if (this.repeating_ &&
+ typeof this.maxTimes_ == "number"
+ && this.nTimes_ >= this.maxTimes_) {
+ this.cancel();
+ } else if (!this.repeating_) {
+ // Clear out the callback closure for TYPE_ONE_SHOT timers
+ this.cancel();
+ }
+ // We don't cancel/cleanup timers that repeat forever until either
+ // xpcom-shutdown occurs or cancel() is called explicitly.
+
+ return ret;
+}
+
+G_Alarm.prototype.setDelay = function(delay) {
+ this.timer_.delay = delay;
+}
+
+/**
+ * XPCOM cruft
+ */
+G_Alarm.prototype.QueryInterface = function(iid) {
+ if (iid.equals(Components.interfaces.nsISupports) ||
+ iid.equals(Components.interfaces.nsITimerCallback))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+}
+
+
+/**
+ * An alarm with the additional property that it cancels itself if its
+ * callback returns true.
+ *
+ * For parameter documentation, see G_Alarm
+ */
+function G_ConditionalAlarm(callback, delayMS, opt_repeating, opt_maxTimes) {
+ G_Alarm.call(this, callback, delayMS, opt_repeating, opt_maxTimes);
+ this.debugZone = "conditionalalarm";
+}
+
+G_ConditionalAlarm.inherits(G_Alarm);
+
+/**
+ * Invoked by the timer when it fires
+ *
+ * @param timer Reference to the nsITimer which fired (not currently
+ * passed along)
+ */
+G_ConditionalAlarm.prototype.notify = function(timer) {
+ // Call G_Alarm::notify
+ var rv = G_Alarm.prototype.notify.call(this, timer);
+
+ if (this.repeating_ && rv) {
+ G_Debug(this, "Callback of a repeating alarm returned true; cancelling.");
+ this.cancel();
+ }
+}
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/cryptohasher.js"
+
+
+// A very thin wrapper around nsICryptoHash. It's not strictly
+// necessary, but makes the code a bit cleaner and gives us the
+// opportunity to verify that our implementations give the results that
+// we expect, for example if we have to interoperate with a server.
+//
+// The digest* methods reset the state of the hasher, so it's
+// necessary to call init() explicitly after them.
+//
+// Works only in Firefox 1.5+.
+//
+// IMPORTANT NOTE: Due to https://bugzilla.mozilla.org/show_bug.cgi?id=321024
+// you cannot use the cryptohasher before app-startup. The symptom of doing
+// so is a segfault in NSS.
+
+/**
+ * Instantiate a new hasher. You must explicitly call init() before use!
+ */
+function G_CryptoHasher() {
+ this.debugZone = "cryptohasher";
+ this.hasher_ = null;
+}
+
+G_CryptoHasher.algorithms = {
+ MD2: Ci.nsICryptoHash.MD2,
+ MD5: Ci.nsICryptoHash.MD5,
+ SHA1: Ci.nsICryptoHash.SHA1,
+ SHA256: Ci.nsICryptoHash.SHA256,
+ SHA384: Ci.nsICryptoHash.SHA384,
+ SHA512: Ci.nsICryptoHash.SHA512,
+};
+
+/**
+ * Initialize the hasher. This function must be called after every call
+ * to one of the digest* methods.
+ *
+ * @param algorithm Constant from G_CryptoHasher.algorithms specifying the
+ * algorithm this hasher will use
+ */
+G_CryptoHasher.prototype.init = function(algorithm) {
+ var validAlgorithm = false;
+ for (var alg in G_CryptoHasher.algorithms)
+ if (algorithm == G_CryptoHasher.algorithms[alg])
+ validAlgorithm = true;
+
+ if (!validAlgorithm)
+ throw new Error("Invalid algorithm: " + algorithm);
+
+ this.hasher_ = Cc["@mozilla.org/security/hash;1"]
+ .createInstance(Ci.nsICryptoHash);
+ this.hasher_.init(algorithm);
+}
+
+/**
+ * Update the hash's internal state with input given in a string. Can be
+ * called multiple times for incrementeal hash updates.
+ *
+ * @param input String containing data to hash.
+ */
+G_CryptoHasher.prototype.updateFromString = function(input) {
+ if (!this.hasher_)
+ throw new Error("You must initialize the hasher first!");
+
+ var stream = Cc['@mozilla.org/io/string-input-stream;1']
+ .createInstance(Ci.nsIStringInputStream);
+ stream.setData(input, input.length);
+ this.updateFromStream(stream);
+}
+
+/**
+ * Update the hash's internal state with input given in an array. Can be
+ * called multiple times for incremental hash updates.
+ *
+ * @param input Array containing data to hash.
+ */
+G_CryptoHasher.prototype.updateFromArray = function(input) {
+ if (!this.hasher_)
+ throw new Error("You must initialize the hasher first!");
+
+ this.hasher_.update(input, input.length);
+}
+
+/**
+ * Update the hash's internal state with input given in a stream. Can be
+ * called multiple times from incremental hash updates.
+ */
+G_CryptoHasher.prototype.updateFromStream = function(stream) {
+ if (!this.hasher_)
+ throw new Error("You must initialize the hasher first!");
+
+ if (stream.available())
+ this.hasher_.updateFromStream(stream, stream.available());
+}
+
+/**
+ * @returns The hash value as a string (sequence of 8-bit values)
+ */
+G_CryptoHasher.prototype.digestRaw = function() {
+ var digest = this.hasher_.finish(false /* not b64 encoded */);
+ this.hasher_ = null;
+ return digest;
+}
+
+/**
+ * @returns The hash value as a base64-encoded string
+ */
+G_CryptoHasher.prototype.digestBase64 = function() {
+ var digest = this.hasher_.finish(true /* b64 encoded */);
+ this.hasher_ = null;
+ return digest;
+}
+
+/**
+ * @returns The hash value as a hex-encoded string
+ */
+G_CryptoHasher.prototype.digestHex = function() {
+ var raw = this.digestRaw();
+ return this.toHex_(raw);
+}
+
+/**
+ * Converts a sequence of values to a hex-encoded string. The input is a
+ * a string, so you can stick 16-bit values in each character.
+ *
+ * @param str String to conver to hex. (Often this is just a sequence of
+ * 16-bit values)
+ *
+ * @returns String containing the hex representation of the input
+ */
+G_CryptoHasher.prototype.toHex_ = function(str) {
+ var hexchars = '0123456789ABCDEF';
+ var hexrep = new Array(str.length * 2);
+
+ for (var i = 0; i < str.length; ++i) {
+ hexrep[i * 2] = hexchars.charAt((str.charCodeAt(i) >> 4) & 15);
+ hexrep[i * 2 + 1] = hexchars.charAt(str.charCodeAt(i) & 15);
+ }
+ return hexrep.join('');
+}
+
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/observer.js"
+
+
+// A couple of classes to simplify creating observers.
+//
+// // Example1:
+//
+// function doSomething() { ... }
+// var observer = new G_ObserverWrapper(topic, doSomething);
+// someObj.addObserver(topic, observer);
+//
+// // Example2:
+//
+// function doSomething() { ... }
+// new G_ObserverServiceObserver("profile-after-change",
+// doSomething,
+// true /* run only once */);
+
+
+/**
+ * This class abstracts the admittedly simple boilerplate required of
+ * an nsIObserver. It saves you the trouble of implementing the
+ * indirection of your own observe() function.
+ *
+ * @param topic String containing the topic the observer will filter for
+ *
+ * @param observeFunction Reference to the function to call when the
+ * observer fires
+ *
+ * @constructor
+ */
+function G_ObserverWrapper(topic, observeFunction) {
+ this.debugZone = "observer";
+ this.topic_ = topic;
+ this.observeFunction_ = observeFunction;
+}
+
+/**
+ * XPCOM
+ */
+G_ObserverWrapper.prototype.QueryInterface = function(iid) {
+ if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsIObserver))
+ return this;
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+}
+
+/**
+ * Invoked by the thingy being observed
+ */
+G_ObserverWrapper.prototype.observe = function(subject, topic, data) {
+ if (topic == this.topic_)
+ this.observeFunction_(subject, topic, data);
+}
+
+
+/**
+ * This class abstracts the admittedly simple boilerplate required of
+ * observing an observerservice topic. It implements the indirection
+ * required, and automatically registers to hear the topic.
+ *
+ * @param topic String containing the topic the observer will filter for
+ *
+ * @param observeFunction Reference to the function to call when the
+ * observer fires
+ *
+ * @param opt_onlyOnce Boolean indicating if the observer should unregister
+ * after it has fired
+ *
+ * @constructor
+ */
+function G_ObserverServiceObserver(topic, observeFunction, opt_onlyOnce) {
+ this.debugZone = "observerserviceobserver";
+ this.topic_ = topic;
+ this.observeFunction_ = observeFunction;
+ this.onlyOnce_ = !!opt_onlyOnce;
+
+ this.observer_ = new G_ObserverWrapper(this.topic_,
+ BindToObject(this.observe_, this));
+ this.observerService_ = Cc["@mozilla.org/observer-service;1"]
+ .getService(Ci.nsIObserverService);
+ this.observerService_.addObserver(this.observer_, this.topic_, false);
+}
+
+/**
+ * Unregister the observer from the observerservice
+ */
+G_ObserverServiceObserver.prototype.unregister = function() {
+ this.observerService_.removeObserver(this.observer_, this.topic_);
+ this.observerService_ = null;
+}
+
+/**
+ * Invoked by the observerservice
+ */
+G_ObserverServiceObserver.prototype.observe_ = function(subject, topic, data) {
+ this.observeFunction_(subject, topic, data);
+ if (this.onlyOnce_)
+ this.unregister();
+}
+
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/moz/protocol4.js"
+
+
+// A helper class that knows how to parse from and serialize to
+// protocol4. This is a simple, historical format used by some Google
+// interfaces, for example the Toolbar (i.e., ancient services).
+//
+// Protocol4 consists of a newline-separated sequence of name/value
+// pairs (strings). Each line consists of the name, the value length,
+// and the value itself, all separated by colons. Example:
+//
+// foo:6:barbaz\n
+// fritz:33:issickofdynamicallytypedlanguages\n
+
+
+/**
+ * This class knows how to serialize/deserialize maps to/from their
+ * protocol4 representation.
+ *
+ * @constructor
+ */
+function G_Protocol4Parser() {
+ this.debugZone = "protocol4";
+
+ this.protocol4RegExp_ = new RegExp("([^:]+):\\d+:(.*)$");
+ this.newlineRegExp_ = new RegExp("(\\r)?\\n");
+}
+
+/**
+ * Create a map from a protocol4 string. Silently skips invalid lines.
+ *
+ * @param text String holding the protocol4 representation
+ *
+ * @returns Object as an associative array with keys and values
+ * given in text. The empty object is returned if none
+ * are parsed.
+ */
+G_Protocol4Parser.prototype.parse = function(text) {
+
+ var response = {};
+ if (!text)
+ return response;
+
+ // Responses are protocol4: (repeated) name:numcontentbytes:content\n
+ var lines = text.split(this.newlineRegExp_);
+ for (var i = 0; i < lines.length; i++)
+ if (this.protocol4RegExp_.exec(lines[i]))
+ response[RegExp.$1] = RegExp.$2;
+
+ return response;
+}
+
+/**
+ * Create a protocol4 string from a map (object). Throws an error on
+ * an invalid input.
+ *
+ * @param map Object as an associative array with keys and values
+ * given as strings.
+ *
+ * @returns text String holding the protocol4 representation
+ */
+G_Protocol4Parser.prototype.serialize = function(map) {
+ if (typeof map != "object")
+ throw new Error("map must be an object");
+
+ var text = "";
+ for (var key in map) {
+ if (typeof map[key] != "string")
+ throw new Error("Keys and values must be strings");
+
+ text += key + ":" + map[key].length + ":" + map[key] + "\n";
+ }
+
+ return text;
+}
+
+//@line 53 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/src/nsUrlClassifierLib.js"
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Google Safe Browsing.
+ *
+ * The Initial Developer of the Original Code is Google Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Tony Chang <tc@google.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This implements logic for stopping requests if the server starts to return
+// too many errors. If we get MAX_ERRORS errors in ERROR_PERIOD minutes, we
+// back off for TIMEOUT_INCREMENT minutes. If we get another error
+// immediately after we restart, we double the timeout and add
+// TIMEOUT_INCREMENT minutes, etc.
+//
+// This is similar to the logic used by the search suggestion service.
+
+// HTTP responses that count as an error. We also include any 5xx response
+// as an error.
+const HTTP_FOUND = 302;
+const HTTP_SEE_OTHER = 303;
+const HTTP_TEMPORARY_REDIRECT = 307;
+
+/**
+ * @param maxErrors Number of times to request before backing off.
+ * @param retryIncrement Time (ms) for each retry before backing off.
+ * @param maxRequests Number the number of requests needed to trigger backoff
+ * @param requestPeriod Number time (ms) in which maxRequests have to occur to
+ * trigger the backoff behavior
+ * @param timeoutIncrement Number time (ms) the starting timeout period
+ * we double this time for consecutive errors
+ * @param maxTimeout Number time (ms) maximum timeout period
+ */
+function RequestBackoff(maxErrors, retryIncrement,
+ maxRequests, requestPeriod,
+ timeoutIncrement, maxTimeout) {
+ this.MAX_ERRORS_ = maxErrors;
+ this.RETRY_INCREMENT_ = retryIncrement;
+ this.MAX_REQUESTS_ = maxRequests;
+ this.REQUEST_PERIOD_ = requestPeriod;
+ this.TIMEOUT_INCREMENT_ = timeoutIncrement;
+ this.MAX_TIMEOUT_ = maxTimeout;
+
+ // Queue of ints keeping the time of all requests
+ this.requestTimes_ = [];
+
+ this.numErrors_ = 0;
+ this.errorTimeout_ = 0;
+ this.nextRequestTime_ = 0;
+}
+
+/**
+ * Reset the object for reuse.
+ */
+RequestBackoff.prototype.reset = function() {
+ this.numErrors_ = 0;
+ this.errorTimeout_ = 0;
+ this.nextRequestTime_ = 0;
+}
+
+/**
+ * Check to see if we can make a request.
+ */
+RequestBackoff.prototype.canMakeRequest = function() {
+ var now = Date.now();
+ if (now < this.nextRequestTime_) {
+ return false;
+ }
+
+ return (this.requestTimes_.length < this.MAX_REQUESTS_ ||
+ (now - this.requestTimes_[0]) > this.REQUEST_PERIOD_);
+}
+
+RequestBackoff.prototype.noteRequest = function() {
+ var now = Date.now();
+ this.requestTimes_.push(now);
+
+ // We only care about keeping track of MAX_REQUESTS
+ if (this.requestTimes_.length > this.MAX_REQUESTS_)
+ this.requestTimes_.shift();
+}
+
+RequestBackoff.prototype.nextRequestDelay = function() {
+ return Math.max(0, this.nextRequestTime_ - Date.now());
+}
+
+/**
+ * Notify this object of the last server response. If it's an error,
+ */
+RequestBackoff.prototype.noteServerResponse = function(status) {
+ if (this.isErrorStatus(status)) {
+ this.numErrors_++;
+
+ if (this.numErrors_ < this.MAX_ERRORS_)
+ this.errorTimeout_ = this.RETRY_INCREMENT_;
+ else if (this.numErrors_ == this.MAX_ERRORS_)
+ this.errorTimeout_ = this.TIMEOUT_INCREMENT_;
+ else
+ this.errorTimeout_ *= 2;
+
+ this.errorTimeout_ = Math.min(this.errorTimeout_, this.MAX_TIMEOUT_);
+ this.nextRequestTime_ = Date.now() + this.errorTimeout_;
+ } else {
+ // Reset error timeout, allow requests to go through.
+ this.reset();
+ }
+}
+
+/**
+ * We consider 302, 303, 307, 4xx, and 5xx http responses to be errors.
+ * @param status Number http status
+ * @return Boolean true if we consider this http status an error
+ */
+RequestBackoff.prototype.isErrorStatus = function(status) {
+ return ((400 <= status && status <= 599) ||
+ HTTP_FOUND == status ||
+ HTTP_SEE_OTHER == status ||
+ HTTP_TEMPORARY_REDIRECT == status);
+}
+
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/url-crypto-key-manager.js"
+
+
+// This file implements the tricky business of managing the keys for our
+// URL encryption. The protocol is:
+//
+// - Server generates secret key K_S
+// - Client starts up and requests a new key K_C from the server via HTTPS
+// - Server generates K_C and WrappedKey, which is K_C encrypted with K_S
+// - Server resonse with K_C and WrappedKey
+// - When client wants to encrypt a URL, it encrypts it with K_C and sends
+// the encrypted URL along with WrappedKey
+// - Server decrypts WrappedKey with K_S to get K_C, and the URL with K_C
+//
+// This is, however, trickier than it sounds for two reasons. First,
+// we want to keep the number of HTTPS requests to an aboslute minimum
+// (like 1 or 2 per browser session). Second, the HTTPS request at
+// startup might fail, for example the user might be offline or a URL
+// fetch might need to be issued before the HTTPS request has
+// completed.
+//
+// We implement the following policy:
+//
+// - Firefox will issue at most two HTTPS getkey requests per session
+// - Firefox will issue one HTTPS getkey request at startup if more than 24
+// hours has passed since the last getkey request.
+// - Firefox will serialize to disk any key it gets
+// - Firefox will fall back on this serialized key until it has a
+// fresh key
+// - The front-end can respond with a flag in a lookup request that tells
+// the client to re-key. Firefox will issue a new HTTPS getkey request
+// at this time if it has only issued one before
+
+// We store the user key in this file. The key can be used to verify signed
+// server updates.
+const kKeyFilename = "urlclassifierkey3.txt";
+
+/**
+ * A key manager for UrlCrypto. There should be exactly one of these
+ * per appplication, and all UrlCrypto's should share it. This is
+ * currently implemented by having the manager attach itself to the
+ * UrlCrypto's prototype at startup. We could've opted for a global
+ * instead, but I like this better, even though it is spooky action
+ * at a distance.
+ * XXX: Should be an XPCOM service
+ *
+ * @param opt_keyFilename String containing the name of the
+ * file we should serialize keys to/from. Used
+ * mostly for testing.
+ *
+ * @param opt_testing Boolean indicating whether we are testing. If we
+ * are, then we skip trying to read the old key from
+ * file and automatically trying to rekey; presumably
+ * the tester will drive these manually.
+ *
+ * @constructor
+ */
+function PROT_UrlCryptoKeyManager(opt_keyFilename, opt_testing) {
+ this.debugZone = "urlcryptokeymanager";
+ this.testing_ = !!opt_testing;
+ this.clientKey_ = null; // Base64-encoded, as fetched from server
+ this.clientKeyArray_ = null; // Base64-decoded into an array of numbers
+ this.wrappedKey_ = null; // Opaque websafe base64-encoded server key
+ this.rekeyTries_ = 0;
+ this.updating_ = false;
+
+ // Don't do anything until keyUrl_ is set.
+ this.keyUrl_ = null;
+
+ this.keyFilename_ = opt_keyFilename ?
+ opt_keyFilename : kKeyFilename;
+
+ this.onNewKey_ = null;
+
+ // Convenience properties
+ this.MAX_REKEY_TRIES = PROT_UrlCryptoKeyManager.MAX_REKEY_TRIES;
+ this.CLIENT_KEY_NAME = PROT_UrlCryptoKeyManager.CLIENT_KEY_NAME;
+ this.WRAPPED_KEY_NAME = PROT_UrlCryptoKeyManager.WRAPPED_KEY_NAME;
+
+ if (!this.testing_) {
+ this.maybeLoadOldKey();
+ }
+}
+
+// Do ***** NOT ***** set this higher; HTTPS is expensive
+PROT_UrlCryptoKeyManager.MAX_REKEY_TRIES = 2;
+
+// Base pref for keeping track of when we updated our key.
+// We store the time as seconds since the epoch.
+PROT_UrlCryptoKeyManager.NEXT_REKEY_PREF = "urlclassifier.keyupdatetime.";
+
+// Once every 30 days (interval in seconds)
+PROT_UrlCryptoKeyManager.KEY_MIN_UPDATE_TIME = 30 * 24 * 60 * 60;
+
+// These are the names the server will respond with in protocol4 format
+PROT_UrlCryptoKeyManager.CLIENT_KEY_NAME = "clientkey";
+PROT_UrlCryptoKeyManager.WRAPPED_KEY_NAME = "wrappedkey";
+
+/**
+ * Called to get ClientKey
+ * @returns urlsafe-base64-encoded client key or null if we haven't gotten one.
+ */
+PROT_UrlCryptoKeyManager.prototype.getClientKey = function() {
+ return this.clientKey_;
+}
+
+/**
+ * Called by a UrlCrypto to get the current K_C
+ *
+ * @returns Array of numbers making up the client key or null if we
+ * have no key
+ */
+PROT_UrlCryptoKeyManager.prototype.getClientKeyArray = function() {
+ return this.clientKeyArray_;
+}
+
+/**
+ * Called by a UrlCrypto to get WrappedKey
+ *
+ * @returns Opaque base64-encoded WrappedKey or null if we haven't
+ * gotten one
+ */
+PROT_UrlCryptoKeyManager.prototype.getWrappedKey = function() {
+ return this.wrappedKey_;
+}
+
+/**
+ * Change the key url. When we do this, we go ahead and rekey.
+ * @param keyUrl String
+ */
+PROT_UrlCryptoKeyManager.prototype.setKeyUrl = function(keyUrl) {
+ // If it's the same key url, do nothing.
+ if (keyUrl == this.keyUrl_)
+ return;
+
+ this.keyUrl_ = keyUrl;
+ this.rekeyTries_ = 0;
+
+ // Check to see if we should make a new getkey request.
+ var prefs = new G_Preferences(PROT_UrlCryptoKeyManager.NEXT_REKEY_PREF);
+ var nextRekey = prefs.getPref(this.getPrefName_(this.keyUrl_), 0);
+ if (nextRekey < parseInt(Date.now() / 1000, 10)) {
+ this.reKey();
+ }
+}
+
+/**
+ * Given a url, return the pref value to use (pref contains last update time).
+ * We basically use the url up until query parameters. This avoids duplicate
+ * pref entries as version number changes over time.
+ * @param url String getkey URL
+ */
+PROT_UrlCryptoKeyManager.prototype.getPrefName_ = function(url) {
+ var queryParam = url.indexOf("?");
+ if (queryParam != -1) {
+ return url.substring(0, queryParam);
+ }
+ return url;
+}
+
+/**
+ * Tell the manager to re-key. For safety, this method still obeys the
+ * max-tries limit. Clients should generally use maybeReKey() if they
+ * want to try a re-keying: it's an error to call reKey() after we've
+ * hit max-tries, but not an error to call maybeReKey().
+ */
+PROT_UrlCryptoKeyManager.prototype.reKey = function() {
+ if (this.updating_) {
+ G_Debug(this, "Already re-keying, ignoring this request");
+ return true;
+ }
+
+ if (this.rekeyTries_ > this.MAX_REKEY_TRIES)
+ throw new Error("Have already rekeyed " + this.rekeyTries_ + " times");
+
+ this.rekeyTries_++;
+
+ G_Debug(this, "Attempting to re-key");
+ // If the keyUrl isn't set, we don't do anything.
+ if (!this.testing_ && this.keyUrl_) {
+ this.fetcher_ = new PROT_XMLFetcher();
+ this.fetcher_.get(this.keyUrl_, BindToObject(this.onGetKeyResponse, this));
+ this.updating_ = true;
+
+ // Calculate the next time we're allowed to re-key.
+ var prefs = new G_Preferences(PROT_UrlCryptoKeyManager.NEXT_REKEY_PREF);
+ var nextRekey = parseInt(Date.now() / 1000, 10)
+ + PROT_UrlCryptoKeyManager.KEY_MIN_UPDATE_TIME;
+ prefs.setPref(this.getPrefName_(this.keyUrl_), nextRekey);
+ }
+}
+
+/**
+ * Try to re-key if we haven't already hit our limit. It's OK to call
+ * this method multiple times, even if we've already tried to rekey
+ * more than the max. It will simply refuse to do so.
+ *
+ * @returns Boolean indicating if it actually issued a rekey request (that
+ * is, if we haven' already hit the max)
+ */
+PROT_UrlCryptoKeyManager.prototype.maybeReKey = function() {
+ if (this.rekeyTries_ > this.MAX_REKEY_TRIES) {
+ G_Debug(this, "Not re-keying; already at max");
+ return false;
+ }
+
+ this.reKey();
+ return true;
+}
+
+/**
+ * Drop the existing set of keys. Resets the rekeyTries variable to
+ * allow a rekey to succeed.
+ */
+PROT_UrlCryptoKeyManager.prototype.dropKey = function() {
+ this.rekeyTries_ = 0;
+ this.replaceKey_(null, null);
+}
+
+/**
+ * @returns Boolean indicating if we have a key we can use
+ */
+PROT_UrlCryptoKeyManager.prototype.hasKey = function() {
+ return this.clientKey_ != null && this.wrappedKey_ != null;
+}
+
+PROT_UrlCryptoKeyManager.prototype.unUrlSafe = function(key)
+{
+ return key ? key.replace("-", "+").replace("_", "/") : "";
+}
+
+/**
+ * Set a new key and serialize it to disk.
+ *
+ * @param clientKey String containing the base64-encoded client key
+ * we wish to use
+ *
+ * @param wrappedKey String containing the opaque base64-encoded WrappedKey
+ * the server gave us (i.e., K_C encrypted with K_S)
+ */
+PROT_UrlCryptoKeyManager.prototype.replaceKey_ = function(clientKey,
+ wrappedKey) {
+ if (this.clientKey_)
+ G_Debug(this, "Replacing " + this.clientKey_ + " with " + clientKey);
+
+ this.clientKey_ = clientKey;
+ this.clientKeyArray_ = Array.map(atob(this.unUrlSafe(clientKey)),
+ function(c) { return c.charCodeAt(0); });
+ this.wrappedKey_ = wrappedKey;
+
+ this.serializeKey_(this.clientKey_, this.wrappedKey_);
+
+ if (this.onNewKey_) {
+ this.onNewKey_();
+ }
+}
+
+/**
+ * Try to write the key to disk so we can fall back on it. Fail
+ * silently if we cannot. The keys are serialized in protocol4 format.
+ *
+ * @returns Boolean indicating whether we succeeded in serializing
+ */
+PROT_UrlCryptoKeyManager.prototype.serializeKey_ = function() {
+
+ var map = {};
+ map[this.CLIENT_KEY_NAME] = this.clientKey_;
+ map[this.WRAPPED_KEY_NAME] = this.wrappedKey_;
+
+ try {
+
+ var keyfile = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties)
+ .get("ProfD", Ci.nsILocalFile); /* profile directory */
+ keyfile.append(this.keyFilename_);
+
+ if (!this.clientKey_ || !this.wrappedKey_) {
+ keyfile.remove(true);
+ return;
+ }
+
+ var data = (new G_Protocol4Parser()).serialize(map);
+
+ try {
+ var stream = Cc["@mozilla.org/network/file-output-stream;1"]
+ .createInstance(Ci.nsIFileOutputStream);
+ stream.init(keyfile,
+ 0x02 | 0x08 | 0x20 /* PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE */,
+ -1 /* default perms */, 0 /* no special behavior */);
+ stream.write(data, data.length);
+ } finally {
+ stream.close();
+ }
+ return true;
+
+ } catch(e) {
+
+ G_Error(this, "Failed to serialize new key: " + e);
+ return false;
+
+ }
+}
+
+/**
+ * Invoked when we've received a protocol4 response to our getkey
+ * request. Try to parse it and set this key as the new one if we can.
+ *
+ * @param responseText String containing the protocol4 getkey response
+ */
+PROT_UrlCryptoKeyManager.prototype.onGetKeyResponse = function(responseText) {
+
+ var response = (new G_Protocol4Parser).parse(responseText);
+ var clientKey = response[this.CLIENT_KEY_NAME];
+ var wrappedKey = response[this.WRAPPED_KEY_NAME];
+
+ this.updating_ = false;
+ this.fetcher_ = null;
+
+ if (response && clientKey && wrappedKey) {
+ G_Debug(this, "Got new key from: " + responseText);
+ this.replaceKey_(clientKey, wrappedKey);
+ } else {
+ G_Debug(this, "Not a valid response for /newkey");
+ }
+}
+
+/**
+ * Set the callback to be called whenever we get a new key.
+ *
+ * @param callback The callback.
+ */
+PROT_UrlCryptoKeyManager.prototype.onNewKey = function(callback)
+{
+ this.onNewKey_ = callback;
+}
+
+/**
+ * Attempt to read a key we've previously serialized from disk, so
+ * that we can fall back on it in case we can't get one from the
+ * server. If we get a key, only use it if we don't already have one
+ * (i.e., if our startup HTTPS request died or hasn't yet completed).
+ *
+ * This method should be invoked early, like when the user's profile
+ * becomes available.
+ */
+PROT_UrlCryptoKeyManager.prototype.maybeLoadOldKey = function() {
+
+ var oldKey = null;
+ try {
+ var keyfile = Cc["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties)
+ .get("ProfD", Ci.nsILocalFile); /* profile directory */
+ keyfile.append(this.keyFilename_);
+ if (keyfile.exists()) {
+ try {
+ var fis = Cc["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Ci.nsIFileInputStream);
+ fis.init(keyfile, 0x01 /* PR_RDONLY */, 0444, 0);
+ var stream = Cc["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Ci.nsIScriptableInputStream);
+ stream.init(fis);
+ oldKey = stream.read(stream.available());
+ } finally {
+ if (stream)
+ stream.close();
+ }
+ }
+ } catch(e) {
+ G_Debug(this, "Caught " + e + " trying to read keyfile");
+ return;
+ }
+
+ if (!oldKey) {
+ G_Debug(this, "Couldn't find old key.");
+ return;
+ }
+
+ oldKey = (new G_Protocol4Parser).parse(oldKey);
+ var clientKey = oldKey[this.CLIENT_KEY_NAME];
+ var wrappedKey = oldKey[this.WRAPPED_KEY_NAME];
+
+ if (oldKey && clientKey && wrappedKey && !this.hasKey()) {
+ G_Debug(this, "Read old key from disk.");
+ this.replaceKey_(clientKey, wrappedKey);
+ }
+}
+
+PROT_UrlCryptoKeyManager.prototype.shutdown = function() {
+ if (this.fetcher_) {
+ this.fetcher_.cancel();
+ this.fetcher_ = null;
+ }
+}
+
+
+//@line 36 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/xml-fetcher.js"
+
+// A simple class that encapsulates a request. You'll notice the
+// style here is different from the rest of the extension; that's
+// because this was re-used from really old code we had. At some
+// point it might be nice to replace this with something better
+// (e.g., something that has explicit onerror handler, ability
+// to set headers, and so on).
+//
+// The only interesting thing here is its ability to strip cookies
+// from the request.
+
+/**
+ * Because we might be in a component, we can't just assume that
+ * XMLHttpRequest exists. So we use this tiny factory function to wrap the
+ * XPCOM version.
+ *
+ * @return XMLHttpRequest object
+ */
+function PROT_NewXMLHttpRequest() {
+ var Cc = Components.classes;
+ var Ci = Components.interfaces;
+ var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
+ .createInstance(Ci.nsIXMLHttpRequest);
+ // Need the following so we get onerror/load/progresschange
+ request.QueryInterface(Ci.nsIJSXMLHttpRequest);
+ return request;
+}
+
+/**
+ * A helper class that does HTTP GETs and calls back a function with
+ * the content it receives. Asynchronous, so uses a closure for the
+ * callback.
+ *
+ * @param opt_stripCookies Boolean indicating whether we should strip
+ * cookies from this request
+ *
+ * @constructor
+ */
+function PROT_XMLFetcher(opt_stripCookies) {
+ this.debugZone = "xmlfetcher";
+ this._request = PROT_NewXMLHttpRequest();
+ this._stripCookies = !!opt_stripCookies;
+}
+
+PROT_XMLFetcher.prototype = {
+ /**
+ * Function that will be called back upon fetch completion.
+ */
+ _callback: null,
+
+
+ /**
+ * Fetches some content.
+ *
+ * @param page URL to fetch
+ * @param callback Function to call back when complete.
+ */
+ get: function(page, callback) {
+ this._request.abort(); // abort() is asynchronous, so
+ this._request = PROT_NewXMLHttpRequest();
+ this._callback = callback;
+ var asynchronous = true;
+ this._request.open("GET", page, asynchronous);
+ this._request.channel.notificationCallbacks = this;
+
+ if (this._stripCookies)
+ new PROT_CookieStripper(this._request.channel);
+
+ // Create a closure
+ var self = this;
+ this._request.onreadystatechange = function() {
+ self.readyStateChange(self);
+ }
+
+ this._request.send(null);
+ },
+
+ cancel: function() {
+ this._request.onreadystatechange = null;
+ this._request.abort();
+ this._request = null;
+ },
+
+ /**
+ * Called periodically by the request to indicate some state change. 4
+ * means content has been received.
+ */
+ readyStateChange: function(fetcher) {
+ if (fetcher._request.readyState != 4)
+ return;
+
+ // If the request fails, on trunk we get status set to
+ // NS_ERROR_NOT_AVAILABLE. On 1.8.1 branch we get an exception
+ // forwarded from nsIHttpChannel::GetResponseStatus. To be consistent
+ // between branch and trunk, we send back NS_ERROR_NOT_AVAILABLE for
+ // http failures.
+ var responseText = null;
+ var status = Components.results.NS_ERROR_NOT_AVAILABLE;
+ try {
+ G_Debug(this, "xml fetch status code: \"" +
+ fetcher._request.status + "\"");
+ status = fetcher._request.status;
+ responseText = fetcher._request.responseText;
+ } catch(e) {
+ G_Debug(this, "Caught exception trying to read xmlhttprequest " +
+ "status/response.");
+ G_Debug(this, e);
+ }
+ if (fetcher._callback)
+ fetcher._callback(responseText, status);
+ },
+
+ // Suppress any certificate errors
+ notifyCertProblem: function(socketInfo, status, targetSite) {
+ return true;
+ },
+
+ // Suppress any ssl errors
+ notifySSLError: function(socketInfo, error, targetSite) {
+ return true;
+ },
+
+ // nsIInterfaceRequestor
+ getInterface: function(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ QueryInterface: function(iid) {
+ if (!iid.equals(Components.interfaces.nsIBadCertListener2) &&
+ !iid.equals(Components.interfaces.nsISSLErrorListener) &&
+ !iid.equals(Components.interfaces.nsIInterfaceRequestor) &&
+ !iid.equals(Components.interfaces.nsISupports))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ return this;
+ }
+};
+
+
+/**
+ * This class knows how to strip cookies from an HTTP request. It
+ * listens for http-on-modify-request, and modifies the request
+ * accordingly. We can't do this using xmlhttprequest.setHeader() or
+ * nsIChannel.setRequestHeader() before send()ing because the cookie
+ * service is called after send().
+ *
+ * @param channel nsIChannel in which the request is happening
+ * @constructor
+ */
+function PROT_CookieStripper(channel) {
+ this.debugZone = "cookiestripper";
+ this.topic_ = "http-on-modify-request";
+ this.channel_ = channel;
+
+ var Cc = Components.classes;
+ var Ci = Components.interfaces;
+ this.observerService_ = Cc["@mozilla.org/observer-service;1"]
+ .getService(Ci.nsIObserverService);
+ this.observerService_.addObserver(this, this.topic_, false);
+
+ // If the request doesn't issue, don't hang around forever
+ var twentySeconds = 20 * 1000;
+ this.alarm_ = new G_Alarm(BindToObject(this.stopObserving, this),
+ twentySeconds);
+}
+
+/**
+ * Invoked by the observerservice. See nsIObserve.
+ */
+PROT_CookieStripper.prototype.observe = function(subject, topic, data) {
+ if (topic != this.topic_ || subject != this.channel_)
+ return;
+
+ G_Debug(this, "Stripping cookies for channel.");
+
+ this.channel_.QueryInterface(Components.interfaces.nsIHttpChannel);
+ this.channel_.setRequestHeader("Cookie", "", false /* replace, not add */);
+ this.alarm_.cancel();
+ this.stopObserving();
+}
+
+/**
+ * Remove us from the observerservice
+ */
+PROT_CookieStripper.prototype.stopObserving = function() {
+ G_Debug(this, "Removing observer");
+ this.observerService_.removeObserver(this, this.topic_);
+ this.channel_ = this.alarm_ = this.observerService_ = null;
+}
+
+/**
+ * XPCOM cruft
+ */
+PROT_CookieStripper.prototype.QueryInterface = function(iid) {
+ var Ci = Components.interfaces;
+ if (iid.equals(Ci.nsISupports) || iid.equals(Ci.nsIObserve))
+ return this;
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+}
+
+//@line 57 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/src/nsUrlClassifierLib.js"
+
+// Expose this whole component.
+var lib = this;
+
+function UrlClassifierLib() {
+ this.wrappedJSObject = lib;
+}
+
+// Module object
+function UrlClassifierLibMod() {
+ this.firstTime = true;
+ this.cid = Components.ID("{26a4a019-2827-4a89-a85c-5931a678823a}");
+ this.progid = "@mozilla.org/url-classifier/jslib;1";
+}
+
+UrlClassifierLibMod.prototype.registerSelf = function(compMgr, fileSpec, loc, type) {
+ if (this.firstTime) {
+ this.firstTime = false;
+ throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
+ }
+ compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ compMgr.registerFactoryLocation(this.cid,
+ "UrlClassifier JS Lib",
+ this.progid,
+ fileSpec,
+ loc,
+ type);
+};
+
+UrlClassifierLibMod.prototype.getClassObject = function(compMgr, cid, iid) {
+ if (!cid.equals(this.cid))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ if (!iid.equals(Ci.nsIFactory))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ return this.factory;
+}
+
+UrlClassifierLibMod.prototype.canUnload = function(compMgr) {
+ return true;
+}
+
+UrlClassifierLibMod.prototype.factory = {
+ createInstance: function(outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+ return new UrlClassifierLib();
+ }
+};
+
+var LibModInst = new UrlClassifierLibMod();
+
+function NSGetModule(compMgr, fileSpec) {
+ return LibModInst;
+}
diff --git a/bundles/XO/components/nsUrlClassifierListManager.js b/bundles/XO/components/nsUrlClassifierListManager.js
new file mode 100755
index 0000000..76eb350
--- /dev/null
+++ b/bundles/XO/components/nsUrlClassifierListManager.js
@@ -0,0 +1,615 @@
+//@line 37 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/src/nsUrlClassifierListManager.js"
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+//@line 37 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/content/listmanager.js"
+
+
+// A class that manages lists, namely white and black lists for
+// phishing or malware protection. The ListManager knows how to fetch,
+// update, and store lists.
+//
+// There is a single listmanager for the whole application.
+//
+// TODO more comprehensive update tests, for example add unittest check
+// that the listmanagers tables are properly written on updates
+
+// How frequently we check for updates (30 minutes)
+const kUpdateInterval = 30 * 60 * 1000;
+
+function QueryAdapter(callback) {
+ this.callback_ = callback;
+};
+
+QueryAdapter.prototype.handleResponse = function(value) {
+ this.callback_.handleEvent(value);
+}
+
+/**
+ * A ListManager keeps track of black and white lists and knows
+ * how to update them.
+ *
+ * @constructor
+ */
+function PROT_ListManager() {
+ this.debugZone = "listmanager";
+ G_debugService.enableZone(this.debugZone);
+
+ this.currentUpdateChecker_ = null; // set when we toggle updates
+ this.prefs_ = new G_Preferences();
+
+ this.updateserverURL_ = null;
+ this.gethashURL_ = null;
+
+ this.isTesting_ = false;
+
+ this.tablesData = {};
+
+ this.observerServiceObserver_ = new G_ObserverServiceObserver(
+ 'quit-application',
+ BindToObject(this.shutdown_, this),
+ true /*only once*/);
+
+ // Lazily create the key manager (to avoid fetching keys when they
+ // aren't needed).
+ this.keyManager_ = null;
+
+ this.rekeyObserver_ = new G_ObserverServiceObserver(
+ 'url-classifier-rekey-requested',
+ BindToObject(this.rekey_, this),
+ false);
+ this.updateWaitingForKey_ = false;
+
+ this.cookieObserver_ = new G_ObserverServiceObserver(
+ 'cookie-changed',
+ BindToObject(this.cookieChanged_, this),
+ false);
+
+ /* Backoff interval should be between 30 and 60 minutes. */
+ var backoffInterval = 30 * 60 * 1000;
+ backoffInterval += Math.floor(Math.random() * (30 * 60 * 1000));
+
+ this.requestBackoff_ = new RequestBackoff(2 /* max errors */,
+ 60*1000 /* retry interval, 1 min */,
+ 4 /* num requests */,
+ 60*60*1000 /* request time, 60 min */,
+ backoffInterval /* backoff interval, 60 min */,
+ 8*60*60*1000 /* max backoff, 8hr */);
+
+ this.dbService_ = Cc["@mozilla.org/url-classifier/dbservice;1"]
+ .getService(Ci.nsIUrlClassifierDBService);
+
+ this.hashCompleter_ = Cc["@mozilla.org/url-classifier/hashcompleter;1"]
+ .getService(Ci.nsIUrlClassifierHashCompleter);
+}
+
+/**
+ * xpcom-shutdown callback
+ * Delete all of our data tables which seem to leak otherwise.
+ */
+PROT_ListManager.prototype.shutdown_ = function() {
+ if (this.keyManager_) {
+ this.keyManager_.shutdown();
+ }
+
+ for (var name in this.tablesData) {
+ delete this.tablesData[name];
+ }
+}
+
+/**
+ * Set the url we check for updates. If the new url is valid and different,
+ * update our table list.
+ *
+ * After setting the update url, the caller is responsible for registering
+ * tables and then toggling update checking. All the code for this logic is
+ * currently in browser/components/safebrowsing. Maybe it should be part of
+ * the listmanger?
+ */
+PROT_ListManager.prototype.setUpdateUrl = function(url) {
+ G_Debug(this, "Set update url: " + url);
+ if (url != this.updateserverURL_) {
+ this.updateserverURL_ = url;
+ this.requestBackoff_.reset();
+
+ // Remove old tables which probably aren't valid for the new provider.
+ for (var name in this.tablesData) {
+ delete this.tablesData[name];
+ }
+ }
+}
+
+/**
+ * Set the gethash url.
+ */
+PROT_ListManager.prototype.setGethashUrl = function(url) {
+ G_Debug(this, "Set gethash url: " + url);
+ if (url != this.gethashURL_) {
+ this.gethashURL_ = url;
+ this.hashCompleter_.gethashUrl = url;
+ }
+}
+
+/**
+ * Set the crypto key url.
+ * @param url String
+ */
+PROT_ListManager.prototype.setKeyUrl = function(url) {
+ G_Debug(this, "Set key url: " + url);
+ if (!this.keyManager_) {
+ this.keyManager_ = new PROT_UrlCryptoKeyManager();
+ this.keyManager_.onNewKey(BindToObject(this.newKey_, this));
+
+ this.hashCompleter_.setKeys(this.keyManager_.getClientKey(),
+ this.keyManager_.getWrappedKey());
+ }
+
+ this.keyManager_.setKeyUrl(url);
+}
+
+/**
+ * Register a new table table
+ * @param tableName - the name of the table
+ * @param opt_requireMac true if a mac is required on update, false otherwise
+ * @returns true if the table could be created; false otherwise
+ */
+PROT_ListManager.prototype.registerTable = function(tableName,
+ opt_requireMac) {
+ this.tablesData[tableName] = {};
+ this.tablesData[tableName].needsUpdate = false;
+
+ return true;
+}
+
+/**
+ * Enable updates for some tables
+ * @param tables - an array of table names that need updating
+ */
+PROT_ListManager.prototype.enableUpdate = function(tableName) {
+ var changed = false;
+ var table = this.tablesData[tableName];
+ if (table) {
+ G_Debug(this, "Enabling table updates for " + tableName);
+ table.needsUpdate = true;
+ changed = true;
+ }
+
+ if (changed === true)
+ this.maybeToggleUpdateChecking();
+}
+
+/**
+ * Disables updates for some tables
+ * @param tables - an array of table names that no longer need updating
+ */
+PROT_ListManager.prototype.disableUpdate = function(tableName) {
+ var changed = false;
+ var table = this.tablesData[tableName];
+ if (table) {
+ G_Debug(this, "Disabling table updates for " + tableName);
+ table.needsUpdate = false;
+ changed = true;
+ }
+
+ if (changed === true)
+ this.maybeToggleUpdateChecking();
+}
+
+/**
+ * Determine if we have some tables that need updating.
+ */
+PROT_ListManager.prototype.requireTableUpdates = function() {
+ for (var type in this.tablesData) {
+ // Tables that need updating even if other tables dont require it
+ if (this.tablesData[type].needsUpdate)
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Start managing the lists we know about. We don't do this automatically
+ * when the listmanager is instantiated because their profile directory
+ * (where we store the lists) might not be available.
+ */
+PROT_ListManager.prototype.maybeStartManagingUpdates = function() {
+ if (this.isTesting_)
+ return;
+
+ // We might have been told about tables already, so see if we should be
+ // actually updating.
+ this.maybeToggleUpdateChecking();
+}
+
+PROT_ListManager.prototype.kickoffUpdate_ = function (tableData)
+{
+ this.startingUpdate_ = false;
+ // If the user has never downloaded tables, do the check now.
+ // If the user has tables, add a fuzz of a few minutes.
+ var initialUpdateDelay = 3000;
+ if (tableData != "") {
+ // Add a fuzz of 0-5 minutes.
+ initialUpdateDelay += Math.floor(Math.random() * (5 * 60 * 1000));
+ }
+
+ this.currentUpdateChecker_ =
+ new G_Alarm(BindToObject(this.checkForUpdates, this),
+ initialUpdateDelay);
+}
+
+/**
+ * Determine if we have any tables that require updating. Different
+ * Wardens may call us with new tables that need to be updated.
+ */
+PROT_ListManager.prototype.maybeToggleUpdateChecking = function() {
+ // If we are testing or dont have an application directory yet, we should
+ // not start reading tables from disk or schedule remote updates
+ if (this.isTesting_)
+ return;
+
+ // We update tables if we have some tables that want updates. If there
+ // are no tables that want to be updated - we dont need to check anything.
+ if (this.requireTableUpdates() === true) {
+ G_Debug(this, "Starting managing lists");
+ this.startUpdateChecker();
+
+ // Multiple warden can ask us to reenable updates at the same time, but we
+ // really just need to schedule a single update.
+ if (!this.currentUpdateChecker && !this.startingUpdate_) {
+ this.startingUpdate_ = true;
+ // check the current state of tables in the database
+ this.dbService_.getTables(BindToObject(this.kickoffUpdate_, this));
+ }
+ } else {
+ G_Debug(this, "Stopping managing lists (if currently active)");
+ this.stopUpdateChecker(); // Cancel pending updates
+ }
+}
+
+/**
+ * Start periodic checks for updates. Idempotent.
+ * We want to distribute update checks evenly across the update period (an
+ * hour). To do this, we pick a random number of time between 0 and 30
+ * minutes. The client first checks at 15 + rand, then every 30 minutes after
+ * that.
+ */
+PROT_ListManager.prototype.startUpdateChecker = function() {
+ this.stopUpdateChecker();
+
+ // Schedule the first check for between 15 and 45 minutes.
+ var repeatingUpdateDelay = kUpdateInterval / 2;
+ repeatingUpdateDelay += Math.floor(Math.random() * kUpdateInterval);
+ this.updateChecker_ = new G_Alarm(BindToObject(this.initialUpdateCheck_,
+ this),
+ repeatingUpdateDelay);
+}
+
+/**
+ * Callback for the first update check.
+ * We go ahead and check for table updates, then start a regular timer (once
+ * every 30 minutes).
+ */
+PROT_ListManager.prototype.initialUpdateCheck_ = function() {
+ this.checkForUpdates();
+ this.updateChecker_ = new G_Alarm(BindToObject(this.checkForUpdates, this),
+ kUpdateInterval, true /* repeat */);
+}
+
+/**
+ * Stop checking for updates. Idempotent.
+ */
+PROT_ListManager.prototype.stopUpdateChecker = function() {
+ if (this.updateChecker_) {
+ this.updateChecker_.cancel();
+ this.updateChecker_ = null;
+ }
+ // Cancel the oneoff check from maybeToggleUpdateChecking.
+ if (this.currentUpdateChecker_) {
+ this.currentUpdateChecker_.cancel();
+ this.currentUpdateChecker_ = null;
+ }
+}
+
+/**
+ * Provides an exception free way to look up the data in a table. We
+ * use this because at certain points our tables might not be loaded,
+ * and querying them could throw.
+ *
+ * @param table String Name of the table that we want to consult
+ * @param key String Key for table lookup
+ * @param callback nsIUrlListManagerCallback (ie., Function) given false or the
+ * value in the table corresponding to key. If the table name does not
+ * exist, we return false, too.
+ */
+PROT_ListManager.prototype.safeLookup = function(key, callback) {
+ try {
+ G_Debug(this, "safeLookup: " + key);
+ var cb = new QueryAdapter(callback);
+ this.dbService_.lookup(key,
+ BindToObject(cb.handleResponse, cb),
+ true);
+ } catch(e) {
+ G_Debug(this, "safeLookup masked failure for key " + key + ": " + e);
+ callback.handleEvent("");
+ }
+}
+
+/**
+ * Updates our internal tables from the update server
+ *
+ * @returns true when a new request was scheduled, false if an old request
+ * was still pending.
+ */
+PROT_ListManager.prototype.checkForUpdates = function() {
+ // Allow new updates to be scheduled from maybeToggleUpdateChecking()
+ this.currentUpdateChecker_ = null;
+
+ if (!this.updateserverURL_) {
+ G_Debug(this, 'checkForUpdates: no update server url');
+ return false;
+ }
+
+ // See if we've triggered the request backoff logic.
+ if (!this.requestBackoff_.canMakeRequest())
+ return false;
+
+ // Grab the current state of the tables from the database
+ this.dbService_.getTables(BindToObject(this.makeUpdateRequest_, this));
+ return true;
+}
+
+/**
+ * Method that fires the actual HTTP update request.
+ * First we reset any tables that have disappeared.
+ * @param tableData List of table data already in the database, in the form
+ * tablename;<chunk ranges>\n
+ */
+PROT_ListManager.prototype.makeUpdateRequest_ = function(tableData) {
+ if (!this.keyManager_)
+ return;
+
+ if (!this.keyManager_.hasKey()) {
+ // We don't have a client key yet. Schedule a rekey, and rerequest
+ // when we have one.
+
+ // If there's already an update waiting for a new key, don't bother.
+ if (this.updateWaitingForKey_)
+ return;
+
+ // If maybeReKey() returns false we have asked for too many keys,
+ // and won't be getting a new one. Since we don't want to do
+ // updates without a client key, we'll skip this update if maybeReKey()
+ // fails.
+ if (this.keyManager_.maybeReKey())
+ this.updateWaitingForKey_ = true;
+
+ return;
+ }
+
+ var tableList;
+ var tableNames = {};
+ for (var tableName in this.tablesData) {
+ if (this.tablesData[tableName].needsUpdate)
+ tableNames[tableName] = true;
+ if (!tableList) {
+ tableList = tableName;
+ } else {
+ tableList += "," + tableName;
+ }
+ }
+
+ var request = "";
+
+ // For each table already in the database, include the chunk data from
+ // the database
+ var lines = tableData.split("\n");
+ for (var i = 0; i < lines.length; i++) {
+ var fields = lines[i].split(";");
+ if (tableNames[fields[0]]) {
+ request += lines[i] + ":mac\n";
+ delete tableNames[fields[0]];
+ }
+ }
+
+ // For each requested table that didn't have chunk data in the database,
+ // request it fresh
+ for (var tableName in tableNames) {
+ request += tableName + ";mac\n";
+ }
+
+ G_Debug(this, 'checkForUpdates: scheduling request..');
+ var streamer = Cc["@mozilla.org/url-classifier/streamupdater;1"]
+ .getService(Ci.nsIUrlClassifierStreamUpdater);
+ try {
+ streamer.updateUrl = this.updateserverURL_ +
+ "&wrkey=" + this.keyManager_.getWrappedKey();
+ } catch (e) {
+ G_Debug(this, 'invalid url');
+ return;
+ }
+
+ this.requestBackoff_.noteRequest();
+
+ if (!streamer.downloadUpdates(tableList,
+ request,
+ this.keyManager_.getClientKey(),
+ BindToObject(this.updateSuccess_, this),
+ BindToObject(this.updateError_, this),
+ BindToObject(this.downloadError_, this))) {
+ G_Debug(this, "pending update, wait until later");
+ }
+}
+
+/**
+ * Callback function if the update request succeeded.
+ * @param waitForUpdate String The number of seconds that the client should
+ * wait before requesting again.
+ */
+PROT_ListManager.prototype.updateSuccess_ = function(waitForUpdate) {
+ G_Debug(this, "update success: " + waitForUpdate);
+ if (waitForUpdate) {
+ var delay = parseInt(waitForUpdate, 10);
+ // As long as the delay is something sane (5 minutes or more), update
+ // our delay time for requesting updates
+ if (delay >= (5 * 60) && this.updateChecker_)
+ this.updateChecker_.setDelay(delay * 1000);
+ }
+
+ // Let the backoff object know that we completed successfully.
+ this.requestBackoff_.noteServerResponse(200);
+}
+
+/**
+ * Callback function if the update request succeeded.
+ * @param result String The error code of the failure
+ */
+PROT_ListManager.prototype.updateError_ = function(result) {
+ G_Debug(this, "update error: " + result);
+ // XXX: there was some trouble applying the updates.
+}
+
+/**
+ * Callback function when the download failed
+ * @param status String http status or an empty string if connection refused.
+ */
+PROT_ListManager.prototype.downloadError_ = function(status) {
+ G_Debug(this, "download error: " + status);
+ // If status is empty, then we assume that we got an NS_CONNECTION_REFUSED
+ // error. In this case, we treat this is a http 500 error.
+ if (!status) {
+ status = 500;
+ }
+ status = parseInt(status, 10);
+ this.requestBackoff_.noteServerResponse(status);
+
+ if (this.requestBackoff_.isErrorStatus(status)) {
+ // Schedule an update for when our backoff is complete
+ this.currentUpdateChecker_ =
+ new G_Alarm(BindToObject(this.checkForUpdates, this),
+ this.requestBackoff_.nextRequestDelay());
+ }
+}
+
+/**
+ * Called when either the update process or a gethash request signals
+ * that the server requested a rekey.
+ */
+PROT_ListManager.prototype.rekey_ = function() {
+ G_Debug(this, "rekey requested");
+
+ // The current key is no good anymore.
+ this.keyManager_.dropKey();
+ this.keyManager_.maybeReKey();
+}
+
+/**
+ * Called when cookies are cleared - clears the current MAC keys.
+ */
+PROT_ListManager.prototype.cookieChanged_ = function(subject, topic, data) {
+ if (data != "cleared")
+ return;
+
+ G_Debug(this, "cookies cleared");
+ this.keyManager_.dropKey();
+}
+
+/**
+ * Called when we've received a new key from the server.
+ */
+PROT_ListManager.prototype.newKey_ = function() {
+ G_Debug(this, "got a new MAC key");
+
+ this.hashCompleter_.setKeys(this.keyManager_.getClientKey(),
+ this.keyManager_.getWrappedKey());
+
+ if (this.keyManager_.hasKey()) {
+ if (this.updateWaitingForKey_) {
+ this.updateWaitingForKey_ = false;
+ this.checkForUpdates();
+ }
+ }
+}
+
+PROT_ListManager.prototype.QueryInterface = function(iid) {
+ if (iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsIUrlListManager) ||
+ iid.equals(Ci.nsITimerCallback))
+ return this;
+
+ Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
+ return null;
+}
+//@line 42 "/builds/moz2_slave/linux_build/build/toolkit/components/url-classifier/src/nsUrlClassifierListManager.js"
+
+var modScope = this;
+function Init() {
+ // Pull the library in.
+ var jslib = Cc["@mozilla.org/url-classifier/jslib;1"]
+ .getService().wrappedJSObject;
+ Function.prototype.inherits = jslib.Function.prototype.inherits;
+ modScope.G_Preferences = jslib.G_Preferences;
+ modScope.G_PreferenceObserver = jslib.G_PreferenceObserver;
+ modScope.G_ObserverServiceObserver = jslib.G_ObserverServiceObserver;
+ modScope.G_Debug = jslib.G_Debug;
+ modScope.G_Assert = jslib.G_Assert;
+ modScope.G_debugService = jslib.G_debugService;
+ modScope.G_Alarm = jslib.G_Alarm;
+ modScope.BindToObject = jslib.BindToObject;
+ modScope.PROT_XMLFetcher = jslib.PROT_XMLFetcher;
+ modScope.PROT_UrlCryptoKeyManager = jslib.PROT_UrlCryptoKeyManager;
+ modScope.RequestBackoff = jslib.RequestBackoff;
+
+ // We only need to call Init once.
+ modScope.Init = function() {};
+}
+
+// Module object
+function UrlClassifierListManagerMod() {
+ this.firstTime = true;
+ this.cid = Components.ID("{ca168834-cc00-48f9-b83c-fd018e58cae3}");
+ this.progid = "@mozilla.org/url-classifier/listmanager;1";
+}
+
+UrlClassifierListManagerMod.prototype.registerSelf = function(compMgr, fileSpec, loc, type) {
+ if (this.firstTime) {
+ this.firstTime = false;
+ throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
+ }
+ compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ compMgr.registerFactoryLocation(this.cid,
+ "UrlClassifier List Manager Module",
+ this.progid,
+ fileSpec,
+ loc,
+ type);
+};
+
+UrlClassifierListManagerMod.prototype.getClassObject = function(compMgr, cid, iid) {
+ if (!cid.equals(this.cid))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ if (!iid.equals(Ci.nsIFactory))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ return this.factory;
+}
+
+UrlClassifierListManagerMod.prototype.canUnload = function(compMgr) {
+ return true;
+}
+
+UrlClassifierListManagerMod.prototype.factory = {
+ createInstance: function(outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+ Init();
+ return (new PROT_ListManager()).QueryInterface(iid);
+ }
+};
+
+var ListManagerModInst = new UrlClassifierListManagerMod();
+
+function NSGetModule(compMgr, fileSpec) {
+ return ListManagerModInst;
+}
diff --git a/bundles/XO/components/nsWebHandlerApp.js b/bundles/XO/components/nsWebHandlerApp.js
new file mode 100755
index 0000000..d704401
--- /dev/null
+++ b/bundles/XO/components/nsWebHandlerApp.js
@@ -0,0 +1,184 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com>
+ * Myk Melez <myk@mozilla.org>
+ * Dan Mosedale <dmose@mozilla.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cc = Components.classes;
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsWebHandler class
+
+function nsWebHandlerApp() {}
+
+nsWebHandlerApp.prototype = {
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsWebHandler
+
+ classDescription: "A web handler for protocols and content",
+ classID: Components.ID("8b1ae382-51a9-4972-b930-56977a57919d"),
+ contractID: "@mozilla.org/uriloader/web-handler-app;1",
+
+ _name: null,
+ _uriTemplate: null,
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsIHandlerApp
+
+ get name() {
+ return this._name;
+ },
+
+ set name(aName) {
+ this._name = aName;
+ },
+
+ equals: function(aHandlerApp) {
+ if (!aHandlerApp)
+ throw Cr.NS_ERROR_NULL_POINTER;
+
+ if (aHandlerApp instanceof Ci.nsIWebHandlerApp &&
+ aHandlerApp.uriTemplate &&
+ this.uriTemplate &&
+ aHandlerApp.uriTemplate == this.uriTemplate)
+ return true;
+
+ return false;
+ },
+
+ launchWithURI: function nWHA__launchWithURI(aURI, aWindowContext) {
+
+ // XXX need to strip passwd & username from URI to handle, as per the
+ // WhatWG HTML5 draft. nsSimpleURL, which is what we're going to get,
+ // can't do this directly. Ideally, we'd fix nsStandardURL to make it
+ // possible to turn off all of its quirks handling, and use that...
+
+ // encode the URI to be handled
+ var escapedUriSpecToHandle = encodeURIComponent(aURI.spec);
+
+ // insert the encoded URI and create the object version
+ var uriSpecToSend = this.uriTemplate.replace("%s", escapedUriSpecToHandle);
+ var ioService = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ var uriToSend = ioService.newURI(uriSpecToSend, null, null);
+
+ // if we have a window context, use the URI loader to load there
+ if (aWindowContext) {
+
+ // create a channel from this URI
+ var channel = ioService.newChannelFromURI(uriToSend);
+ channel.loadFlags = Ci.nsIChannel.LOAD_DOCUMENT_URI;
+
+ // load the channel
+ var uriLoader = Cc["@mozilla.org/uriloader;1"].
+ getService(Ci.nsIURILoader);
+ // XXX ideally, aIsContentPreferred (the second param) should really be
+ // passed in from above. Practically, true is probably a reasonable
+ // default since browsers don't care much, and link click is likely to be
+ // the more interesting case for non-browser apps. See
+ // <https://bugzilla.mozilla.org/show_bug.cgi?id=392957#c9> for details.
+ uriLoader.openURI(channel, true, aWindowContext);
+ return;
+ }
+
+ // since we don't have a window context, hand it off to a browser
+ var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator);
+
+ // get browser dom window
+ var browserDOMWin = windowMediator.getMostRecentWindow("navigator:browser")
+ .QueryInterface(Ci.nsIDOMChromeWindow)
+ .browserDOMWindow;
+
+ // if we got an exception, there are several possible reasons why:
+ // a) this gecko embedding doesn't provide an nsIBrowserDOMWindow
+ // implementation (i.e. doesn't support browser-style functionality),
+ // so we need to kick the URL out to the OS default browser. This is
+ // the subject of bug 394479.
+ // b) this embedding does provide an nsIBrowserDOMWindow impl, but
+ // there doesn't happen to be a browser window open at the moment; one
+ // should be opened. It's not clear whether this situation will really
+ // ever occur in real life. If it does, the only API that I can find
+ // that seems reasonably likely to work for most embedders is the
+ // command line handler.
+ // c) something else went wrong
+ //
+ // it's not clear how one would differentiate between the three cases
+ // above, so for now we don't catch the exception
+
+ // openURI
+ browserDOMWin.openURI(uriToSend,
+ null, // no window.opener
+ Ci.nsIBrowserDOMWindow.OPEN_DEFAULT_WINDOW,
+ Ci.nsIBrowserDOMWindow.OPEN_NEW);
+
+ return;
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsIWebHandlerApp
+
+ get uriTemplate() {
+ return this._uriTemplate;
+ },
+
+ set uriTemplate(aURITemplate) {
+ this._uriTemplate = aURITemplate;
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsISupports
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebHandlerApp, Ci.nsIHandlerApp])
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// Module
+
+let components = [nsWebHandlerApp];
+
+function NSGetModule(compMgr, fileSpec)
+{
+ return XPCOMUtils.generateModule(components);
+}
+
diff --git a/bundles/XO/components/pluginGlue.js b/bundles/XO/components/pluginGlue.js
new file mode 100755
index 0000000..8a43a50
--- /dev/null
+++ b/bundles/XO/components/pluginGlue.js
@@ -0,0 +1,78 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla pluginfinder style sheet registration code.
+ *
+ * The Initial Developer of the Original Code is
+ * Christian Biesinger <cbiesinger@web.de>.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * @file
+ * This file contains the agent style sheet registration code for the
+ * pluginfinder XBL binding. It's not a real module, it only exists so that we
+ * can call addCategoryEntry / deleteCategoryEntry.
+ */
+
+var module = {
+ categoryEntry: "pluginfinder xbl binding",
+ categoryValue: "chrome://mozapps/content/plugins/missingPluginBinding.css",
+
+ // registerSelf: Register this component.
+ registerSelf: function (compMgr, fileSpec, location, type) {
+ var catman = Components.classes['@mozilla.org/categorymanager;1']
+ .getService(Components.interfaces.nsICategoryManager);
+ catman.addCategoryEntry("agent-style-sheets", this.categoryEntry,
+ this.categoryValue, true, true);
+
+ },
+
+ // unregisterSelf: Unregister this component.
+ unregisterSelf: function (aCompMgr, aLocation, aLoaderStr) {
+ catman.deleteCategoryEntry("agent-style-sheets", this.categoryEntry,
+ true);
+ },
+
+ // getClassObject: Return this component's factory object.
+ getClassObject: function (compMgr, cid, iid) {
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ // canUnload: n/a (returns true)
+ canUnload: function(compMgr) {
+ return true;
+ }
+};
+
+// NSGetModule: Return the nsIModule object.
+function NSGetModule(compMgr, fileSpec) {
+ return module;
+}
+
diff --git a/bundles/XO/components/storage-Legacy.js b/bundles/XO/components/storage-Legacy.js
new file mode 100755
index 0000000..0d70f99
--- /dev/null
+++ b/bundles/XO/components/storage-Legacy.js
@@ -0,0 +1,1478 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Justin Dolske <dolske@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function LoginManagerStorage_legacy() { };
+
+LoginManagerStorage_legacy.prototype = {
+
+ classDescription : "LoginManagerStorage_legacy",
+ contractID : "@mozilla.org/login-manager/storage/legacy;1",
+ classID : Components.ID("{e09e4ca6-276b-4bb4-8b71-0635a3a2a007}"),
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsILoginManagerStorage,
+ Ci.nsILoginManagerIEMigrationHelper]),
+
+ __logService : null, // Console logging service, used for debugging.
+ get _logService() {
+ if (!this.__logService)
+ this.__logService = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ return this.__logService;
+ },
+
+ __ioService: null, // IO service for string -> nsIURI conversion
+ get _ioService() {
+ if (!this.__ioService)
+ this.__ioService = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__ioService;
+ },
+
+ __decoderRing : null, // nsSecretDecoderRing service
+ get _decoderRing() {
+ if (!this.__decoderRing)
+ this.__decoderRing = Cc["@mozilla.org/security/sdr;1"].
+ getService(Ci.nsISecretDecoderRing);
+ return this.__decoderRing;
+ },
+
+ __utfConverter : null, // UCS2 <--> UTF8 string conversion
+ get _utfConverter() {
+ if (!this.__utfConverter) {
+ this.__utfConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
+ createInstance(Ci.nsIScriptableUnicodeConverter);
+ this.__utfConverter.charset = "UTF-8";
+ }
+ return this.__utfConverter;
+ },
+
+ _utfConverterReset : function() {
+ this.__utfConverter = null;
+ },
+
+ __profileDir: null, // nsIFile for the user's profile dir
+ get _profileDir() {
+ if (!this.__profileDir) {
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ this.__profileDir = dirService.get("ProfD", Ci.nsIFile);
+ }
+ return this.__profileDir;
+ },
+
+ __nsLoginInfo: null, // Constructor for nsILoginInfo implementation
+ get _nsLoginInfo() {
+ if (!this.__nsLoginInfo)
+ this.__nsLoginInfo = new Components.Constructor(
+ "@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo);
+ return this.__nsLoginInfo;
+ },
+
+ _prefBranch : null, // Preferences service
+
+ _signonsFile : null, // nsIFile for "signons3.txt" (or whatever pref is)
+ _debug : false, // mirrors signon.debug
+
+ /*
+ * A list of prefs that have been used to specify the filename for storing
+ * logins. (We've used a number over time due to compatibility issues.)
+ * This list is also used by _removeOldSignonsFile() to clean up old files.
+ */
+ _filenamePrefs : ["SignonFileName3", "SignonFileName2", "SignonFileName"],
+
+ /*
+ * Core datastructures
+ *
+ * EG: _logins["http://site.com"][0].password
+ * EG: _disabledHosts["never.site.com"]
+ */
+ _logins : null,
+ _disabledHosts : null,
+
+
+ /*
+ * log
+ *
+ * Internal function for logging debug messages to the Error Console.
+ */
+ log : function (message) {
+ if (!this._debug)
+ return;
+ dump("PwMgr Storage: " + message + "\n");
+ this._logService.logStringMessage("PwMgr Storage: " + message);
+ },
+
+
+
+
+ /* ==================== Public Methods ==================== */
+
+
+
+
+ initWithFile : function(aInputFile, aOutputFile) {
+ this._signonsFile = aInputFile;
+
+ this.init();
+
+ if (aOutputFile) {
+ this._signonsFile = aOutputFile;
+ this._writeFile();
+ }
+ },
+
+ /*
+ * init
+ *
+ * Initialize this storage component and load stored passwords from disk.
+ */
+ init : function () {
+ this._logins = {};
+ this._disabledHosts = {};
+
+ // Connect to the correct preferences branch.
+ this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ this._prefBranch = this._prefBranch.getBranch("signon.");
+ this._prefBranch.QueryInterface(Ci.nsIPrefBranch2);
+
+ this._debug = this._prefBranch.getBoolPref("debug");
+
+ // Check to see if the internal PKCS#11 token has been initialized.
+ // If not, set a blank password.
+ var tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].
+ getService(Ci.nsIPK11TokenDB);
+
+ var token = tokenDB.getInternalKeyToken();
+ if (token.needsUserInit) {
+ this.log("Initializing key3.db with default blank password.");
+ token.initPassword("");
+ }
+
+ var importFile = null;
+ // If initWithFile is calling us, _signonsFile is already set.
+ if (!this._signonsFile)
+ [this._signonsFile, importFile] = this._getSignonsFile();
+
+ // If we have an import file, do a switcharoo before reading it.
+ if (importFile) {
+ this.log("Importing " + importFile.path);
+
+ var tmp = this._signonsFile;
+ this._signonsFile = importFile;
+ }
+
+ // Read in the stored login data.
+ this._readFile();
+
+ // If we were importing, write back to the normal file.
+ if (importFile) {
+ this._signonsFile = tmp;
+ this._writeFile();
+ }
+ },
+
+
+ /*
+ * addLogin
+ *
+ */
+ addLogin : function (login) {
+ // Throws if there are bogus values.
+ this._checkLoginValues(login);
+
+ // Clone the input. This ensures changes made by the caller to the
+ // login (after calling addLogin) do no change the login we have.
+ // Also, we rely on using login.wrappedJSObject, but can't rely on the
+ // thing provided by the caller to support that.
+ var clone = new this._nsLoginInfo();
+ clone.init(login.hostname, login.formSubmitURL, login.httpRealm,
+ login.username, login.password,
+ login.usernameField, login.passwordField);
+ login = clone;
+
+ var key = login.hostname;
+
+ // If first entry for key, create an Array to hold its logins.
+ var rollback;
+ if (!this._logins[key]) {
+ this._logins[key] = [];
+ rollback = null;
+ } else {
+ rollback = this._logins[key].concat(); // clone array
+ }
+
+ this._logins[key].push(login);
+
+ var ok = this._writeFile();
+
+ // If we failed, don't keep the added login in memory.
+ if (!ok) {
+ if (rollback)
+ this._logins[key] = rollback;
+ else
+ delete this._logins[key];
+
+ throw "Couldn't write to file, login not added.";
+ }
+ },
+
+
+ /*
+ * removeLogin
+ *
+ */
+ removeLogin : function (login) {
+ var key = login.hostname;
+ var logins = this._logins[key];
+
+ if (!logins)
+ throw "No logins found for hostname (" + key + ")";
+
+ var rollback = this._logins[key].concat(); // clone array
+
+ // The specified login isn't encrypted, so we need to ensure
+ // the logins we're comparing with are decrypted. We decrypt one entry
+ // at a time, lest _decryptLogins return fewer entries and screw up
+ // indices between the two.
+ for (var i = 0; i < logins.length; i++) {
+
+ var [[decryptedLogin], userCanceled] =
+ this._decryptLogins([logins[i]]);
+
+ if (userCanceled)
+ throw "User canceled master password entry, login not removed.";
+
+ if (!decryptedLogin)
+ continue;
+
+ if (decryptedLogin.equals(login)) {
+ logins.splice(i, 1); // delete that login from array.
+ break;
+ // Note that if there are duplicate entries, they'll
+ // have to be deleted one-by-one.
+ }
+ }
+
+ // Did we delete the last login for this host?
+ if (logins.length == 0)
+ delete this._logins[key];
+
+ var ok = this._writeFile();
+
+ // If we failed, don't actually remove the login.
+ if (!ok) {
+ this._logins[key] = rollback;
+ throw "Couldn't write to file, login not removed.";
+ }
+ },
+
+
+ /*
+ * modifyLogin
+ *
+ */
+ modifyLogin : function (oldLogin, newLogin) {
+ if (newLogin instanceof Ci.nsIPropertyBag)
+ throw "legacy modifyLogin with propertybag not implemented.";
+ newLogin.QueryInterface(Ci.nsILoginInfo);
+ // Throws if there are bogus values.
+ this._checkLoginValues(newLogin);
+
+ this.removeLogin(oldLogin);
+ this.addLogin(newLogin);
+ },
+
+
+ /*
+ * getAllLogins
+ *
+ * Returns an array of nsAccountInfo.
+ */
+ getAllLogins : function (count) {
+ var result = [], userCanceled;
+
+ // Each entry is an array -- append the array entries to |result|.
+ for each (var hostLogins in this._logins) {
+ result = result.concat(hostLogins);
+ }
+
+ // decrypt entries for caller.
+ [result, userCanceled] = this._decryptLogins(result);
+
+ if (userCanceled)
+ throw "User canceled Master Password entry";
+
+ count.value = result.length; // needed for XPCOM
+ return result;
+ },
+
+
+ /*
+ * getAllEncryptedLogins
+ *
+ * Returns an array of nsAccountInfo, each in the encrypted state.
+ */
+ getAllEncryptedLogins : function (count) {
+ var result = [];
+
+ // Each entry is an array -- append the array entries to |result|.
+ for each (var hostLogins in this._logins) {
+ // Return copies to the caller. Prevents callers from modifying
+ // our internal storage
+ for each (var login in hostLogins) {
+ var clone = new this._nsLoginInfo();
+ clone.init(login.hostname, login.formSubmitURL, login.httpRealm,
+ login.wrappedJSObject.encryptedUsername,
+ login.wrappedJSObject.encryptedPassword,
+ login.usernameField, login.passwordField);
+ result.push(clone);
+ }
+ }
+
+ count.value = result.length; // needed for XPCOM
+ return result;
+ },
+
+
+ /*
+ * searchLogins
+ *
+ * Not implemented. This interface was added to perform arbitrary searches.
+ * Since the legacy storage module is no longer used, there is no need to
+ * implement it here.
+ */
+ searchLogins : function (count, matchData) {
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+
+ /*
+ * removeAllLogins
+ *
+ * Removes all logins from storage.
+ */
+ removeAllLogins : function () {
+ // Delete any old, unused files.
+ this._removeOldSignonsFiles();
+
+ // Disabled hosts kept, as one presumably doesn't want to erase those.
+ this._logins = {};
+ this._writeFile();
+ },
+
+
+ /*
+ * getAllDisabledHosts
+ *
+ */
+ getAllDisabledHosts : function (count) {
+ var result = [];
+
+ for (var hostname in this._disabledHosts) {
+ result.push(hostname);
+ }
+
+ count.value = result.length; // needed for XPCOM
+ return result;
+ },
+
+
+ /*
+ * getLoginSavingEnabled
+ *
+ */
+ getLoginSavingEnabled : function (hostname) {
+ return !this._disabledHosts[hostname];
+ },
+
+
+ /*
+ * setLoginSavingEnabled
+ *
+ */
+ setLoginSavingEnabled : function (hostname, enabled) {
+ // File format prohibits certain values. Also, nulls
+ // won't round-trip with getAllDisabledHosts().
+ if (hostname == "." ||
+ hostname.indexOf("\r") != -1 ||
+ hostname.indexOf("\n") != -1 ||
+ hostname.indexOf("\0") != -1)
+ throw "Invalid hostname";
+
+ if (enabled)
+ delete this._disabledHosts[hostname];
+ else
+ this._disabledHosts[hostname] = true;
+
+ this._writeFile();
+ },
+
+
+ /*
+ * findLogins
+ *
+ */
+ findLogins : function (count, hostname, formSubmitURL, httpRealm) {
+ var userCanceled;
+
+ var logins = this._searchLogins(hostname, formSubmitURL, httpRealm);
+
+ // Decrypt entries found for the caller.
+ [logins, userCanceled] = this._decryptLogins(logins);
+
+ // We want to throw in this case, so that the Login Manager
+ // knows to stop processing forms on the page so the user isn't
+ // prompted multiple times.
+ if (userCanceled)
+ throw "User canceled Master Password entry";
+
+ count.value = logins.length; // needed for XPCOM
+ return logins;
+ },
+
+
+ /*
+ * countLogins
+ *
+ */
+ countLogins : function (aHostname, aFormSubmitURL, aHttpRealm) {
+ var logins;
+
+ // Normal case: return direct results for the specified host.
+ if (aHostname) {
+ logins = this._searchLogins(aHostname, aFormSubmitURL, aHttpRealm);
+ return logins.length
+ }
+
+ // For consistency with how aFormSubmitURL and aHttpRealm work
+ if (aHostname == null)
+ return 0;
+
+ // aHostname == "", so loop through each known host to match with each.
+ var count = 0;
+ for (var hostname in this._logins) {
+ logins = this._searchLogins(hostname, aFormSubmitURL, aHttpRealm);
+ count += logins.length;
+ }
+
+ return count;
+ },
+
+
+
+
+ /* ==================== Internal Methods ==================== */
+
+
+
+
+ /*
+ * _searchLogins
+ *
+ */
+ _searchLogins : function (hostname, formSubmitURL, httpRealm) {
+ var hostLogins = this._logins[hostname];
+ if (hostLogins == null)
+ return [];
+
+ var result = [], userCanceled;
+
+ for each (var login in hostLogins) {
+
+ // If search arg is null, skip login unless it doesn't specify a
+ // httpRealm (ie, it's also null). If the search arg is an empty
+ // string, always match.
+ if (httpRealm == null) {
+ if (login.httpRealm != null)
+ continue;
+ } else if (httpRealm != "") {
+ // Make sure the realms match. If search arg is null,
+ // only match if login doesn't specify a realm (is null)
+ if (httpRealm != login.httpRealm)
+ continue;
+ }
+
+ // If search arg is null, skip login unless it doesn't specify a
+ // action URL (ie, it's also null). If the search arg is an empty
+ // string, always match.
+ if (formSubmitURL == null) {
+ if (login.formSubmitURL != null)
+ continue;
+ } else if (formSubmitURL != "") {
+ // If the stored login is blank (not null), that means the
+ // login was stored before we started keeping the action
+ // URL, so always match. Unless the search g
+ if (login.formSubmitURL != "" &&
+ formSubmitURL != login.formSubmitURL)
+ continue;
+ }
+
+ result.push(login);
+ }
+
+ return result;
+ },
+
+
+ /*
+ * _checkLoginValues
+ *
+ * Due to the way the signons2.txt file is formatted, we need to make
+ * sure certain field values or characters do not cause the file to
+ * be parse incorrectly. Reject logins that we can't store correctly.
+ */
+ _checkLoginValues : function (aLogin) {
+ function badCharacterPresent(l, c) {
+ return ((l.formSubmitURL && l.formSubmitURL.indexOf(c) != -1) ||
+ (l.httpRealm && l.httpRealm.indexOf(c) != -1) ||
+ l.hostname.indexOf(c) != -1 ||
+ l.usernameField.indexOf(c) != -1 ||
+ l.passwordField.indexOf(c) != -1);
+ }
+
+ // Nulls are invalid, as they don't round-trip well.
+ // Mostly not a formatting problem, although ".\0" can be quirky.
+ if (badCharacterPresent(aLogin, "\0"))
+ throw "login values can't contain nulls";
+
+ // In theory these nulls should just be rolled up into the encrypted
+ // values, but nsISecretDecoderRing doesn't use nsStrings, so the
+ // nulls cause truncation. Check for them here just to avoid
+ // unexpected round-trip surprises.
+ if (aLogin.username.indexOf("\0") != -1 ||
+ aLogin.password.indexOf("\0") != -1)
+ throw "login values can't contain nulls";
+
+ // Newlines are invalid for any field stored as plaintext.
+ if (badCharacterPresent(aLogin, "\r") ||
+ badCharacterPresent(aLogin, "\n"))
+ throw "login values can't contain newlines";
+
+ // A line with just a "." can have special meaning.
+ if (aLogin.usernameField == "." ||
+ aLogin.formSubmitURL == ".")
+ throw "login values can't be periods";
+
+ // A hostname with "\ \(" won't roundtrip.
+ // eg host="foo (", realm="bar" --> "foo ( (bar)"
+ // vs host="foo", realm=" (bar" --> "foo ( (bar)"
+ if (aLogin.hostname.indexOf(" (") != -1)
+ throw "bad parens in hostname";
+ },
+
+
+ /*
+ * _getSignonsFile
+ *
+ * Determines what file to use based on prefs. Returns it as a
+ * nsILocalFile, along with a file to import from first (if needed)
+ *
+ */
+ _getSignonsFile : function() {
+ var destFile = null, importFile = null;
+
+ // We've used a number of prefs over time due to compatibility issues.
+ // Use the filename specified in the newest pref, but import from
+ // older files if needed.
+ for (var i = 0; i < this._filenamePrefs.length; i++) {
+ var prefname = this._filenamePrefs[i];
+ var filename = this._prefBranch.getCharPref(prefname);
+ var file = this._profileDir.clone();
+ file.append(filename);
+
+ this.log("Checking file " + filename + " (" + prefname + ")");
+
+ // First loop through, save the preferred filename.
+ if (!destFile)
+ destFile = file;
+ else
+ importFile = file;
+
+ if (file.exists())
+ return [destFile, importFile];
+ }
+
+ // If we can't find any existing file, use the preferred file.
+ return [destFile, null];
+ },
+
+
+ /*
+ * _removeOldSignonsFiles
+ *
+ * Deletes any storage files that we're not using any more.
+ */
+ _removeOldSignonsFiles : function() {
+ // We've used a number of prefs over time due to compatibility issues.
+ // Skip the first entry (the newest) and delete the others.
+ for (var i = 1; i < this._filenamePrefs.length; i++) {
+ var prefname = this._filenamePrefs[i];
+ var filename = this._prefBranch.getCharPref(prefname);
+ var file = this._profileDir.clone();
+ file.append(filename);
+
+ if (file.exists()) {
+ this.log("Deleting old " + filename + " (" + prefname + ")");
+ try {
+ file.remove(false);
+ } catch (e) {
+ this.log("NOTICE: Couldn't delete " + filename + ": " + e);
+ }
+ }
+ }
+ },
+
+
+ /*
+ * _upgrade_entry_to_2E
+ *
+ * Updates the format of an entry from 2D to 2E. Returns an array of
+ * logins (1 or 2), as sometimes updating an entry requires creating an
+ * extra login.
+ */
+ _upgrade_entry_to_2E : function (aLogin) {
+ var upgradedLogins = [aLogin];
+
+ /*
+ * For logins stored from HTTP channels
+ * - scheme needs to be derived and prepended
+ * - blank or missing realm becomes same as hostname.
+ *
+ * "site.com:80" --> "http://site.com"
+ * "site.com:443" --> "https://site.com"
+ * "site.com:123" --> Who knows! (So add both)
+ *
+ * Note: For HTTP logins, the hostname never contained a username
+ * or password. EG "user@site.com:80" shouldn't ever happen.
+ *
+ * Note: Proxy logins are also stored in this format.
+ */
+ if (aLogin.hostname.indexOf("://") == -1) {
+ var oldHost = aLogin.hostname;
+
+ // Check for a trailing port number, EG "site.com:80". If there's
+ // no port, it wasn't saved by the browser and is probably some
+ // arbitrary string picked by an extension.
+ if (!/:\d+$/.test(aLogin.hostname)) {
+ this.log("2E upgrade: no port, skipping " + aLogin.hostname);
+ return upgradedLogins;
+ }
+
+ // Parse out "host:port".
+ try {
+ // Small hack: Need a scheme for nsIURI, so just prepend http.
+ // We'll check for a port == -1 in case nsIURI ever starts
+ // noticing that "http://foo:80" is using the default port.
+ var uri = this._ioService.newURI("http://" + aLogin.hostname,
+ null, null);
+ var host = uri.host;
+ var port = uri.port;
+ } catch (e) {
+ this.log("2E upgrade: Can't parse hostname " + aLogin.hostname);
+ return upgradedLogins;
+ }
+
+ if (port == 80 || port == -1)
+ aLogin.hostname = "http://" + host;
+ else if (port == 443)
+ aLogin.hostname = "https://" + host;
+ else {
+ // Not a standard port! Could be either http or https!
+ // (Or maybe it's a proxy login!) To try and avoid
+ // breaking logins, we'll add *both* http and https
+ // versions.
+ this.log("2E upgrade: Cloning login for " + aLogin.hostname);
+
+ aLogin.hostname = "http://" + host + ":" + port;
+
+ var extraLogin = new this._nsLoginInfo();
+ extraLogin.init("https://" + host + ":" + port,
+ null, aLogin.httpRealm,
+ aLogin.username, aLogin.password, "", "");
+ // We don't have decrypted values, unless we're importing from IE,
+ // so clone the encrypted bits into the new entry.
+ extraLogin.wrappedJSObject.encryptedPassword =
+ aLogin.wrappedJSObject.encryptedPassword;
+ extraLogin.wrappedJSObject.encryptedUsername =
+ aLogin.wrappedJSObject.encryptedUsername;
+
+ if (extraLogin.httpRealm == "")
+ extraLogin.httpRealm = extraLogin.hostname;
+
+ upgradedLogins.push(extraLogin);
+ }
+
+ // If the server didn't send a realm (or it was blank), we
+ // previously didn't store anything.
+ if (aLogin.httpRealm == "")
+ aLogin.httpRealm = aLogin.hostname;
+
+ this.log("2E upgrade: " + oldHost + " ---> " + aLogin.hostname);
+
+ return upgradedLogins;
+ }
+
+
+ /*
+ * For form logins and non-HTTP channel logins (both were stored in
+ * the same format):
+ *
+ * Standardize URLs (.hostname and .actionURL)
+ * - remove default port numbers, if specified
+ * "http://site.com:80" --> "http://site.com"
+ * - remove usernames from URL (may move into aLogin.username)
+ * "ftp://user@site.com" --> "ftp://site.com"
+ *
+ * Note: Passwords in the URL ("foo://user:pass@site.com") were not
+ * stored in FF2, so no need to try to move the value into
+ * aLogin.password.
+ */
+
+ // closures in cleanupURL
+ var ioService = this._ioService;
+ var log = this.log;
+
+ function cleanupURL(aURL, allowJS) {
+ var newURL, username = null, pathname = "";
+
+ try {
+ var uri = ioService.newURI(aURL, null, null);
+ var scheme = uri.scheme;
+
+ if (allowJS && scheme == "javascript")
+ return ["javascript:", null, ""];
+
+ newURL = scheme + "://" + uri.host;
+
+ // If the URL explicitly specified a port, only include it when
+ // it's not the default. (We never want "http://foo.com:80")
+ port = uri.port;
+ if (port != -1) {
+ var handler = ioService.getProtocolHandler(scheme);
+ if (port != handler.defaultPort)
+ newURL += ":" + port;
+ }
+
+ // Could be a channel login with a username.
+ if (scheme != "http" && scheme != "https" && uri.username)
+ username = uri.username;
+
+ if (uri.path != "/")
+ pathname = uri.path;
+
+ } catch (e) {
+ log("Can't cleanup URL: " + aURL + " e: " + e);
+ newURL = aURL;
+ }
+
+ if (newURL != aURL)
+ log("2E upgrade: " + aURL + " ---> " + newURL);
+
+ return [newURL, username, pathname];
+ }
+
+ const isMailNews = /^(ldaps?|smtp|imap|news|mailbox):\/\//;
+
+ // Old mailnews logins were protocol logins with a username/password
+ // field name set.
+ var isFormLogin = (aLogin.formSubmitURL ||
+ aLogin.usernameField ||
+ aLogin.passwordField) &&
+ !isMailNews.test(aLogin.hostname);
+
+ var [hostname, username, pathname] = cleanupURL(aLogin.hostname);
+ aLogin.hostname = hostname;
+
+ // If a non-HTTP URL contained a username, it wasn't stored in the
+ // encrypted username field (which contains an encrypted empty value)
+ // (Don't do this if it's a form login, though.)
+ if (username && !isFormLogin) {
+ if (isMailNews.test(aLogin.hostname))
+ username = decodeURIComponent(username);
+
+ var [encUsername, userCanceled] = this._encrypt(username);
+ if (!userCanceled)
+ aLogin.wrappedJSObject.encryptedUsername = encUsername;
+ }
+
+
+ if (aLogin.formSubmitURL) {
+ [hostname, username, pathname] = cleanupURL(aLogin.formSubmitURL,
+ true);
+ aLogin.formSubmitURL = hostname;
+ // username, if any, ignored.
+ }
+
+
+ /*
+ * For logins stored from non-HTTP channels
+ * - Set httpRealm so they don't look like form logins
+ * "ftp://site.com" --> "ftp://site.com (ftp://site.com)"
+ *
+ * Tricky: Form logins and non-HTTP channel logins are stored in the
+ * same format, and we don't want to add a realm to a form login.
+ * Form logins have field names, so only update the realm if there are
+ * no field names set. [Any login with a http[s]:// hostname is always
+ * a form login, so explicitly ignore those just to be safe.]
+ */
+ const isHTTP = /^https?:\/\//;
+ const isLDAP = /^ldaps?:\/\//;
+ const isNews = /^news?:\/\//;
+ if (!isHTTP.test(aLogin.hostname) && !isFormLogin) {
+ // LDAP and News logins need to keep the path.
+ if (isLDAP.test(aLogin.hostname) ||
+ isNews.test(aLogin.hostname))
+ aLogin.httpRealm = aLogin.hostname + pathname;
+ else
+ aLogin.httpRealm = aLogin.hostname;
+
+ aLogin.formSubmitURL = null;
+
+ // Null out the form items because mailnews will no longer treat
+ // or expect these as form logins
+ if (isMailNews.test(aLogin.hostname)) {
+ aLogin.usernameField = "";
+ aLogin.passwordField = "";
+ }
+
+ this.log("2E upgrade: set empty realm to " + aLogin.httpRealm);
+ }
+
+ return upgradedLogins;
+ },
+
+
+ /*
+ * _readFile
+ *
+ */
+ _readFile : function () {
+ var formatVersion;
+
+ this.log("Reading passwords from " + this._signonsFile.path);
+
+ // If it doesn't exist, just bail out.
+ if (!this._signonsFile.exists()) {
+ this.log("No existing signons file found.");
+ return;
+ }
+
+ var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ // init the stream as RD_ONLY, -1 == default permissions.
+ inputStream.init(this._signonsFile, 0x01, -1, null);
+ var lineStream = inputStream.QueryInterface(Ci.nsILineInputStream);
+ var line = { value: "" };
+
+ const STATE = { HEADER : 0, REJECT : 1, REALM : 2,
+ USERFIELD : 3, USERVALUE : 4,
+ PASSFIELD : 5, PASSVALUE : 6, ACTIONURL : 7,
+ FILLER : 8 };
+ var parseState = STATE.HEADER;
+
+ var processEntry = false;
+ var discardEntry = false;
+
+ do {
+ var hasMore = lineStream.readLine(line);
+ try {
+ line.value = this._utfConverter.ConvertToUnicode(line.value);
+ } catch (e) {
+ this.log("Bad UTF8 conversion: " + line.value);
+ this._utfConverterReset();
+ }
+
+ switch (parseState) {
+ // Check file header
+ case STATE.HEADER:
+ if (line.value == "#2c") {
+ formatVersion = 0x2c;
+ } else if (line.value == "#2d") {
+ formatVersion = 0x2d;
+ } else if (line.value == "#2e") {
+ formatVersion = 0x2e;
+ } else {
+ this.log("invalid file header (" + line.value + ")");
+ throw "invalid file header in signons file";
+ // We could disable later writing to file, so we
+ // don't clobber whatever it is. ...however, that
+ // would mean corrupt files are not self-healing.
+ return;
+ }
+ parseState++;
+ break;
+
+ // Line is a hostname for which passwords should never be saved.
+ case STATE.REJECT:
+ if (line.value == ".") {
+ parseState++;
+ break;
+ }
+
+ this._disabledHosts[line.value] = true;
+
+ break;
+
+ // Line is a hostname, saved login(s) will follow
+ case STATE.REALM:
+ var hostrealm = line.value;
+
+ // Format is "http://site.com", with "(some realm)"
+ // appended if it's a HTTP-Auth login.
+ const realmFormat = /^(.+?)( \(.*\))?$/;
+ var matches = realmFormat.exec(hostrealm);
+ var hostname, httpRealm;
+ if (matches && matches.length == 3) {
+ hostname = matches[1];
+ httpRealm = matches[2] ?
+ matches[2].slice(2, -1) : null;
+ } else {
+ if (hostrealm != "") {
+ // Uhoh. This shouldn't happen, but try to deal.
+ this.log("Error parsing host/realm: " + hostrealm);
+ }
+ hostname = hostrealm;
+ httpRealm = null;
+ }
+
+ parseState++;
+ break;
+
+ // Line is the HTML 'name' attribute for the username field
+ // (or "." to indicate end of hostrealm)
+ case STATE.USERFIELD:
+ if (line.value == ".") {
+ discardEntry = false;
+ parseState = STATE.REALM;
+ break;
+ }
+
+ // If we're discarding the entry, keep looping in this
+ // state until we hit the "." marking the end of the entry.
+ if (discardEntry)
+ break;
+
+ var entry = new this._nsLoginInfo();
+ entry.hostname = hostname;
+ entry.httpRealm = httpRealm;
+
+ entry.usernameField = line.value;
+ parseState++;
+ break;
+
+ // Line is a username
+ case STATE.USERVALUE:
+ entry.wrappedJSObject.encryptedUsername = line.value;
+ parseState++;
+ break;
+
+ // Line is the HTML 'name' attribute for the password field,
+ // with a leading '*' character
+ case STATE.PASSFIELD:
+ if (line.value.charAt(0) != '*') {
+ discardEntry = true;
+ entry = null;
+ parseState = STATE.USERFIELD;
+ break;
+ }
+ entry.passwordField = line.value.substr(1);
+ parseState++;
+ break;
+
+ // Line is a password
+ case STATE.PASSVALUE:
+ entry.wrappedJSObject.encryptedPassword = line.value;
+
+ // Version 2C doesn't have an ACTIONURL line, so
+ // process entry now.
+ if (formatVersion < 0x2d)
+ processEntry = true;
+
+ parseState++;
+ break;
+
+ // Line is the action URL
+ case STATE.ACTIONURL:
+ var formSubmitURL = line.value;
+ if (!formSubmitURL && entry.httpRealm != null)
+ entry.formSubmitURL = null;
+ else
+ entry.formSubmitURL = formSubmitURL;
+
+ // Version 2D doesn't have a FILLER line, so
+ // process entry now.
+ if (formatVersion < 0x2e)
+ processEntry = true;
+
+ parseState++;
+ break;
+
+ // Line is unused filler for future use
+ case STATE.FILLER:
+ // Save the line's value (so we can dump it back out when
+ // we save the file next time) for forwards compatability.
+ entry.wrappedJSObject.filler = line.value;
+ processEntry = true;
+
+ parseState++;
+ break;
+ }
+
+ // If we've read all the lines for the current entry,
+ // process it and reset the parse state for the next entry.
+ if (processEntry) {
+ if (formatVersion < 0x2d) {
+ // A blank, non-null value is handled as a wildcard.
+ if (entry.httpRealm != null)
+ entry.formSubmitURL = null;
+ else
+ entry.formSubmitURL = "";
+ }
+
+ // Upgrading an entry to 2E can sometimes result in the need
+ // to create an extra login.
+ var entries = [entry];
+ if (formatVersion < 0x2e)
+ entries = this._upgrade_entry_to_2E(entry);
+
+
+ for each (var e in entries) {
+ if (!this._logins[e.hostname])
+ this._logins[e.hostname] = [];
+ this._logins[e.hostname].push(e);
+ }
+
+ entry = null;
+ processEntry = false;
+ parseState = STATE.USERFIELD;
+ }
+ } while (hasMore);
+
+ lineStream.close();
+
+ return;
+ },
+
+
+ /*
+ * _writeFile
+ *
+ * Returns true if the operation was successfully completed, or false
+ * if there was an error (probably the user refusing to enter a
+ * master password if prompted).
+ */
+ _writeFile : function () {
+ var converter = this._utfConverter;
+ function writeLine(data) {
+ data = converter.ConvertFromUnicode(data);
+ data += converter.Finish();
+ data += "\r\n";
+ outputStream.write(data, data.length);
+ }
+
+ this.log("Writing passwords to " + this._signonsFile.path);
+
+ var safeStream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ // WR_ONLY|CREAT|TRUNC
+ safeStream.init(this._signonsFile, 0x02 | 0x08 | 0x20, 0600, null);
+
+ var outputStream = Cc["@mozilla.org/network/buffered-output-stream;1"].
+ createInstance(Ci.nsIBufferedOutputStream);
+ outputStream.init(safeStream, 8192);
+ outputStream.QueryInterface(Ci.nsISafeOutputStream); // for .finish()
+
+
+ // write file version header
+ writeLine("#2e");
+
+ // write disabled logins list
+ for (var hostname in this._disabledHosts) {
+ writeLine(hostname);
+ }
+
+ // write end-of-reject-list marker
+ writeLine(".");
+
+ for (var hostname in this._logins) {
+ function sortByRealm(a,b) {
+ a = a.httpRealm;
+ b = b.httpRealm;
+
+ if (!a && !b)
+ return 0;
+
+ if (!a || a < b)
+ return -1;
+
+ if (!b || b > a)
+ return 1;
+
+ return 0; // a==b, neither is null
+ }
+
+ // Sort logins by httpRealm. This allows us to group multiple
+ // logins for the same realm together.
+ this._logins[hostname].sort(sortByRealm);
+
+
+ // write each login known for the host
+ var lastRealm = null;
+ var firstEntry = true;
+ var userCanceled = false;
+ for each (var login in this._logins[hostname]) {
+
+ // If this login is for a new realm, start a new entry.
+ if (login.httpRealm != lastRealm || firstEntry) {
+ // end previous entry, if needed.
+ if (!firstEntry)
+ writeLine(".");
+
+ var hostrealm = login.hostname;
+ if (login.httpRealm)
+ hostrealm += " (" + login.httpRealm + ")";
+
+ writeLine(hostrealm);
+ }
+
+ firstEntry = false;
+
+ // Get the encrypted value of the username. Newly added
+ // logins will need the plaintext value encrypted.
+ var encUsername = login.wrappedJSObject.encryptedUsername;
+ if (!encUsername) {
+ [encUsername, userCanceled] = this._encrypt(login.username);
+ login.wrappedJSObject.encryptedUsername = encUsername;
+ }
+
+ if (userCanceled)
+ break;
+
+ // Get the encrypted value of the password. Newly added
+ // logins will need the plaintext value encrypted.
+ var encPassword = login.wrappedJSObject.encryptedPassword;
+ if (!encPassword) {
+ [encPassword, userCanceled] = this._encrypt(login.password);
+ login.wrappedJSObject.encryptedPassword = encPassword;
+ }
+
+ if (userCanceled)
+ break;
+
+
+ writeLine((login.usernameField ? login.usernameField : ""));
+ writeLine(encUsername);
+ writeLine("*" +
+ (login.passwordField ? login.passwordField : ""));
+ writeLine(encPassword);
+ writeLine((login.formSubmitURL ? login.formSubmitURL : ""));
+ if (login.wrappedJSObject.filler)
+ writeLine(login.wrappedJSObject.filler);
+ else
+ writeLine("---");
+
+ lastRealm = login.httpRealm;
+ }
+
+ if (userCanceled) {
+ this.log("User canceled Master Password, aborting write.");
+ // .close will cause an abort w/o modifying original file
+ outputStream.close();
+ return false;
+ }
+
+ // write end-of-host marker
+ writeLine(".");
+ }
+
+ // [if there were no hosts, no end-of-host marker (".") needed]
+
+ outputStream.finish();
+ return true;
+ },
+
+
+ /*
+ * _decryptLogins
+ *
+ * Decrypts username and password fields in the provided array of
+ * logins. This is deferred from the _readFile() code, so that
+ * the user is not prompted for a master password (if set) until
+ * the entries are actually used.
+ *
+ * The entries specified by the array will be decrypted, if possible.
+ * An array of successfully decrypted logins will be returned. The return
+ * value should be given to external callers (since still-encrypted
+ * entries are useless), whereas internal callers generally don't want
+ * to lose unencrypted entries (eg, because the user clicked Cancel
+ * instead of entering their master password)
+ */
+ _decryptLogins : function (logins) {
+ var result = [], userCanceled = false;
+
+ for each (var login in logins) {
+ var decryptedUsername, decryptedPassword;
+
+ [decryptedUsername, userCanceled] =
+ this._decrypt(login.wrappedJSObject.encryptedUsername);
+
+ if (userCanceled)
+ break;
+
+ [decryptedPassword, userCanceled] =
+ this._decrypt(login.wrappedJSObject.encryptedPassword);
+
+ // Probably can't hit this case, but for completeness...
+ if (userCanceled)
+ break;
+
+ // If decryption failed (corrupt entry?) skip it. Note that we
+ // allow password-only logins, so decryptedUsername can be "".
+ if (decryptedUsername == null || !decryptedPassword)
+ continue;
+
+ // Return copies to the caller. Prevents callers from modifying
+ // our internal stoage, and helps avoid keeping decrypted data in
+ // memory (although this is fuzzy, because of GC issues).
+ var clone = new this._nsLoginInfo();
+ clone.init(login.hostname, login.formSubmitURL, login.httpRealm,
+ decryptedUsername, decryptedPassword,
+ login.usernameField, login.passwordField);
+
+ // Old mime64-obscured entries should be opportunistically
+ // reencrypted in the new format.
+ var recrypted;
+ if (login.wrappedJSObject.encryptedUsername &&
+ login.wrappedJSObject.encryptedUsername.charAt(0) == '~') {
+ [recrypted, userCanceled] = this._encrypt(decryptedUsername);
+
+ if (userCanceled)
+ break;
+
+ login.wrappedJSObject.encryptedUsername = recrypted;
+ }
+
+ if (login.wrappedJSObject.encryptedPassword &&
+ login.wrappedJSObject.encryptedPassword.charAt(0) == '~') {
+ [recrypted, userCanceled] = this._encrypt(decryptedPassword);
+
+ if (userCanceled)
+ break;
+
+ login.wrappedJSObject.encryptedPassword = recrypted;
+ }
+
+ result.push(clone);
+ }
+
+ return [result, userCanceled];
+ },
+
+
+ /*
+ * _encrypt
+ *
+ * Encrypts the specified string, using the SecretDecoderRing.
+ *
+ * Returns [cipherText, userCanceled] where:
+ * cipherText -- the encrypted string, or null if it failed.
+ * userCanceled -- if the encryption failed, this is true if the
+ * user selected Cancel when prompted to enter their
+ * Master Password. The caller should bail out, and not
+ * not request that more things be encrypted (which
+ * results in prompting the user for a Master Password
+ * over and over.)
+ */
+ _encrypt : function (plainText) {
+ var cipherText = null, userCanceled = false;
+
+ try {
+ var plainOctet = this._utfConverter.ConvertFromUnicode(plainText);
+ plainOctet += this._utfConverter.Finish();
+ cipherText = this._decoderRing.encryptString(plainOctet);
+ } catch (e) {
+ this.log("Failed to encrypt string. (" + e.name + ")");
+ // If the user clicks Cancel, we get NS_ERROR_FAILURE.
+ // (unlike decrypting, which gets NS_ERROR_NOT_AVAILABLE).
+ if (e.result == Components.results.NS_ERROR_FAILURE)
+ userCanceled = true;
+ }
+
+ return [cipherText, userCanceled];
+ },
+
+
+ /*
+ * _decrypt
+ *
+ * Decrypts the specified string, using the SecretDecoderRing.
+ *
+ * Returns [plainText, userCanceled] where:
+ * plainText -- the decrypted string, or null if it failed.
+ * userCanceled -- if the decryption failed, this is true if the
+ * user selected Cancel when prompted to enter their
+ * Master Password. The caller should bail out, and not
+ * not request that more things be decrypted (which
+ * results in prompting the user for a Master Password
+ * over and over.)
+ */
+ _decrypt : function (cipherText) {
+ var plainText = null, userCanceled = false;
+
+ try {
+ var plainOctet;
+ if (cipherText.charAt(0) == '~') {
+ // The older file format obscured entries by
+ // base64-encoding them. These entries are signaled by a
+ // leading '~' character.
+ plainOctet = atob(cipherText.substring(1));
+ } else {
+ plainOctet = this._decoderRing.decryptString(cipherText);
+ }
+ plainText = this._utfConverter.ConvertToUnicode(plainOctet);
+ } catch (e) {
+ this.log("Failed to decrypt string: " + cipherText +
+ " (" + e.name + ")");
+
+ // In the unlikely event the converter threw, reset it.
+ this._utfConverterReset();
+
+ // If the user clicks Cancel, we get NS_ERROR_NOT_AVAILABLE.
+ // If the cipherText is bad / wrong key, we get NS_ERROR_FAILURE
+ // Wrong passwords are handled by the decoderRing reprompting;
+ // we get no notification.
+ if (e.result == Components.results.NS_ERROR_NOT_AVAILABLE)
+ userCanceled = true;
+ }
+
+ return [plainText, userCanceled];
+ },
+
+
+
+
+ /* ================== nsILoginManagerIEMigratorHelper ================== */
+
+
+
+
+ _migrationLoginManager : null,
+
+ /*
+ * migrateAndAddLogin
+ *
+ * Given a login with IE6-formatted fields, migrates it to the new format
+ * and adds it to the login manager.
+ *
+ * Experimentally derived format of IE6 logins, see:
+ * https://bugzilla.mozilla.org/attachment.cgi?id=319346
+ *
+ * HTTP AUTH:
+ * - hostname is always "example.com:123"
+ * * "example.com", "http://example.com", "http://example.com:80" all
+ * end up as just "example.com:80"
+ * * Entering "example.com:80" in the URL bar isn't recognized as a
+ * valid URL by IE6.
+ * * "https://example.com" is saved as "example.com:443"
+ * * "https://example.com:666" is saved as "example.com:666". Thus, for
+ * non-standard ports we don't know the right scheme, so create both.
+ *
+ * - an empty or missing "realm" in the WWW-Authenticate reply is stored
+ * as just an empty string by IE6.
+ *
+ * - IE6 will store logins where one or both (!) of the username/password
+ * is left blank. We don't support logins without a password, so these
+ * logins won't be added [addLogin() will throw].
+ *
+ * - IE6 won't recognize a URL with and embedded username/password (eg
+ * http://user@example.com, http://user:pass@example.com), so these
+ * shouldn't be encountered.
+ *
+ * - Our migration code doesn't extract non-HTTP logins (eg, FTP). So
+ * they shouldn't be encountered here. (Verified by saving FTP logins
+ * in IE and then importing in Firefox.)
+ *
+ *
+ * FORM LOGINS:
+ * - hostname is "http://site.com" or "https://site.com".
+ * * scheme always included
+ * * default port not included
+ * - port numbers, even for non-standard posts, are never present!
+ * unfortunately, this means logins will only work on the default
+ * port, because we don't know what the original was (or even that
+ * it wasn't originally stored for the original port).
+ * - Logins are stored without a field name by IE, but we look one up
+ * in the migrator for the username. The password field name will
+ * always be empty-string.
+ */
+ migrateAndAddLogin : function (aLogin) {
+ // Initialize outself on the first call
+ if (!this._migrationLoginManager) {
+ // Connect to the correct preferences branch.
+ this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ this._prefBranch = this._prefBranch.getBranch("signon.");
+ this._prefBranch.QueryInterface(Ci.nsIPrefBranch2);
+
+ this._debug = this._prefBranch.getBoolPref("debug");
+
+ this._migrationLoginManager = Cc["@mozilla.org/login-manager;1"].
+ getService(Ci.nsILoginManager);
+ }
+
+ this.log("Migrating login for " + aLogin.hostname);
+
+ // The IE login is in the same format as the old password
+ // manager entries, so just reuse that code.
+ var logins = this._upgrade_entry_to_2E(aLogin);
+
+ // Add logins via the login manager (and not this.addLogin),
+ // lest an alternative storage module be in use.
+ for each (var login in logins)
+ this._migrationLoginManager.addLogin(login);
+ }
+}; // end of nsLoginManagerStorage_legacy implementation
+
+var component = [LoginManagerStorage_legacy];
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(component);
+}
diff --git a/bundles/XO/components/storage-mozStorage.js b/bundles/XO/components/storage-mozStorage.js
new file mode 100755
index 0000000..f9e528c
--- /dev/null
+++ b/bundles/XO/components/storage-mozStorage.js
@@ -0,0 +1,1588 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Paul O'Shannessy <poshannessy@mozilla.com> (primary author)
+ * Mrinal Kant <mrinal.kant@gmail.com> (original sqlite related changes)
+ * Justin Dolske <dolske@mozilla.com> (encryption/decryption functions are
+ * a lift from Justin's storage-Legacy.js)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const DB_VERSION = 3; // The database schema version
+
+const ENCTYPE_BASE64 = 0;
+const ENCTYPE_SDR = 1;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function LoginManagerStorage_mozStorage() { };
+
+LoginManagerStorage_mozStorage.prototype = {
+
+ classDescription : "LoginManagerStorage_mozStorage",
+ contractID : "@mozilla.org/login-manager/storage/mozStorage;1",
+ classID : Components.ID("{8c2023b9-175c-477e-9761-44ae7b549756}"),
+ QueryInterface : XPCOMUtils.generateQI([Ci.nsILoginManagerStorage]),
+
+ __logService : null, // Console logging service, used for debugging.
+ get _logService() {
+ if (!this.__logService)
+ this.__logService = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+ return this.__logService;
+ },
+
+ __decoderRing : null, // nsSecretDecoderRing service
+ get _decoderRing() {
+ if (!this.__decoderRing)
+ this.__decoderRing = Cc["@mozilla.org/security/sdr;1"].
+ getService(Ci.nsISecretDecoderRing);
+ return this.__decoderRing;
+ },
+
+ __utfConverter : null, // UCS2 <--> UTF8 string conversion
+ get _utfConverter() {
+ if (!this.__utfConverter) {
+ this.__utfConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
+ createInstance(Ci.nsIScriptableUnicodeConverter);
+ this.__utfConverter.charset = "UTF-8";
+ }
+ return this.__utfConverter;
+ },
+
+ _utfConverterReset : function() {
+ this.__utfConverter = null;
+ },
+
+ __profileDir: null, // nsIFile for the user's profile dir
+ get _profileDir() {
+ if (!this.__profileDir)
+ this.__profileDir = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties).
+ get("ProfD", Ci.nsIFile);
+ return this.__profileDir;
+ },
+
+ __storageService: null, // Storage service for using mozStorage
+ get _storageService() {
+ if (!this.__storageService)
+ this.__storageService = Cc["@mozilla.org/storage/service;1"].
+ getService(Ci.mozIStorageService);
+ return this.__storageService;
+ },
+
+ __uuidService: null,
+ get _uuidService() {
+ if (!this.__uuidService)
+ this.__uuidService = Cc["@mozilla.org/uuid-generator;1"].
+ getService(Ci.nsIUUIDGenerator);
+ return this.__uuidService;
+ },
+
+ __observerService : null,
+ get _observerService() {
+ if (!this.__observerService)
+ this.__observerService = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ return this.__observerService;
+ },
+
+
+ // The current database schema.
+ _dbSchema: {
+ tables: {
+ moz_logins: "id INTEGER PRIMARY KEY," +
+ "hostname TEXT NOT NULL," +
+ "httpRealm TEXT," +
+ "formSubmitURL TEXT," +
+ "usernameField TEXT NOT NULL," +
+ "passwordField TEXT NOT NULL," +
+ "encryptedUsername TEXT NOT NULL," +
+ "encryptedPassword TEXT NOT NULL," +
+ "guid TEXT," +
+ "encType INTEGER",
+ // Changes must be reflected in this._dbAreExpectedColumnsPresent
+ // and this._searchLogins
+ moz_disabledHosts: "id INTEGER PRIMARY KEY," +
+ "hostname TEXT UNIQUE ON CONFLICT REPLACE",
+ },
+ indices: {
+ moz_logins_hostname_index: {
+ table: "moz_logins",
+ columns: ["hostname"]
+ },
+ moz_logins_hostname_formSubmitURL_index: {
+ table: "moz_logins",
+ columns: ["hostname", "formSubmitURL"]
+ },
+ moz_logins_hostname_httpRealm_index: {
+ table: "moz_logins",
+ columns: ["hostname", "httpRealm"]
+ },
+ moz_logins_guid_index: {
+ table: "moz_logins",
+ columns: ["guid"]
+ },
+ moz_logins_encType_index: {
+ table: "moz_logins",
+ columns: ["encType"]
+ }
+ }
+ },
+ _dbConnection : null, // The database connection
+ _dbStmts : null, // Database statements for memoization
+
+ _prefBranch : null, // Preferences service
+ _signonsFile : null, // nsIFile for "signons.sqlite"
+ _importFile : null, // nsIFile for import from legacy
+ _debug : false, // mirrors signon.debug
+ _base64checked : false,
+
+
+ /*
+ * log
+ *
+ * Internal function for logging debug messages to the Error Console.
+ */
+ log : function (message) {
+ if (!this._debug)
+ return;
+ dump("PwMgr mozStorage: " + message + "\n");
+ this._logService.logStringMessage("PwMgr mozStorage: " + message);
+ },
+
+
+ /*
+ * initWithFile
+ *
+ * Initialize the component, but override the default filename locations.
+ * This is primarily used to the unit tests and profile migration.
+ * aImportFile is legacy storage file, aDBFile is a sqlite/mozStorage file.
+ */
+ initWithFile : function(aImportFile, aDBFile) {
+ if (aImportFile)
+ this._importFile = aImportFile;
+ if (aDBFile)
+ this._signonsFile = aDBFile;
+
+ this.init();
+ },
+
+
+ /*
+ * init
+ *
+ * Initialize this storage component; import from legacy files, if
+ * necessary. Most of the work is done in _deferredInit.
+ */
+ init : function () {
+ this._dbStmts = [];
+
+ // Connect to the correct preferences branch.
+ this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ this._prefBranch = this._prefBranch.getBranch("signon.");
+ this._prefBranch.QueryInterface(Ci.nsIPrefBranch2);
+
+ this._debug = this._prefBranch.getBoolPref("debug");
+
+ // Check to see if the internal PKCS#11 token has been initialized.
+ // If not, set a blank password.
+ let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].
+ getService(Ci.nsIPK11TokenDB);
+
+ let token = tokenDB.getInternalKeyToken();
+ if (token.needsUserInit) {
+ this.log("Initializing key3.db with default blank password.");
+ token.initPassword("");
+ }
+
+ let isFirstRun;
+ try {
+ // If initWithFile is calling us, _signonsFile may already be set.
+ if (!this._signonsFile) {
+ // Initialize signons.sqlite
+ this._signonsFile = this._profileDir.clone();
+ this._signonsFile.append("signons.sqlite");
+ }
+ this.log("Opening database at " + this._signonsFile.path);
+
+ // Initialize the database (create, migrate as necessary)
+ isFirstRun = this._dbInit();
+
+ // On first run we want to import the default legacy storage files.
+ // Otherwise if passed a file, import from that.
+ if (isFirstRun && !this._importFile)
+ this._importLegacySignons();
+ else if (this._importFile)
+ this._importLegacySignons(this._importFile);
+
+ this._initialized = true;
+ } catch (e) {
+ this.log("Initialization failed: " + e);
+ // If the import fails on first run, we want to delete the db
+ if (isFirstRun && e == "Import failed")
+ this._dbCleanup(false);
+ throw "Initialization failed";
+ }
+ },
+
+
+ /*
+ * addLogin
+ *
+ */
+ addLogin : function (login) {
+ this._addLogin(login, false);
+ },
+
+
+ /*
+ * _addLogin
+ *
+ * Private function wrapping core addLogin functionality.
+ */
+ _addLogin : function (login, isEncrypted) {
+ let userCanceled, encUsername, encPassword;
+
+ // Throws if there are bogus values.
+ this._checkLoginValues(login);
+
+ if (isEncrypted) {
+ [encUsername, encPassword] = [login.username, login.password];
+ } else {
+ // Get the encrypted value of the username and password.
+ [encUsername, encPassword, userCanceled] = this._encryptLogin(login);
+ if (userCanceled)
+ throw "User canceled master password entry, login not added.";
+ }
+
+ // Clone the login, so we don't modify the caller's object.
+ let loginClone = login.clone();
+
+ // Initialize the nsILoginMetaInfo fields, unless the caller gave us values
+ loginClone.QueryInterface(Ci.nsILoginMetaInfo);
+ if (loginClone.guid) {
+ if (!this._isGuidUnique(loginClone.guid))
+ throw "specified GUID already exists";
+ } else {
+ loginClone.guid = this._uuidService.generateUUID().toString();
+ }
+
+ // Determine encryption type
+ let encType = ENCTYPE_SDR;
+ if (isEncrypted &&
+ (encUsername.charAt(0) == '~' || encPassword.charAt(0) == '~'))
+ encType = ENCTYPE_BASE64;
+
+ let query =
+ "INSERT INTO moz_logins " +
+ "(hostname, httpRealm, formSubmitURL, usernameField, " +
+ "passwordField, encryptedUsername, encryptedPassword, " +
+ "guid, encType) " +
+ "VALUES (:hostname, :httpRealm, :formSubmitURL, :usernameField, " +
+ ":passwordField, :encryptedUsername, :encryptedPassword, " +
+ ":guid, :encType)";
+
+ let params = {
+ hostname: loginClone.hostname,
+ httpRealm: loginClone.httpRealm,
+ formSubmitURL: loginClone.formSubmitURL,
+ usernameField: loginClone.usernameField,
+ passwordField: loginClone.passwordField,
+ encryptedUsername: encUsername,
+ encryptedPassword: encPassword,
+ guid: loginClone.guid,
+ encType: encType
+ };
+
+ let stmt;
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ stmt.execute();
+ } catch (e) {
+ this.log("_addLogin failed: " + e.name + " : " + e.message);
+ throw "Couldn't write to database, login not added.";
+ } finally {
+ stmt.reset();
+ }
+
+ // Send a notification that a login was added.
+ if (!isEncrypted)
+ this._sendNotification("addLogin", loginClone);
+ },
+
+
+ /*
+ * removeLogin
+ *
+ */
+ removeLogin : function (login) {
+ let [idToDelete, storedLogin] = this._getIdForLogin(login);
+ if (!idToDelete)
+ throw "No matching logins";
+
+ // Execute the statement & remove from DB
+ let query = "DELETE FROM moz_logins WHERE id = :id";
+ let params = { id: idToDelete };
+ let stmt;
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ stmt.execute();
+ } catch (e) {
+ this.log("_removeLogin failed: " + e.name + " : " + e.message);
+ throw "Couldn't write to database, login not removed.";
+ } finally {
+ stmt.reset();
+ }
+
+ this._sendNotification("removeLogin", storedLogin);
+ },
+
+
+ /*
+ * modifyLogin
+ *
+ */
+ modifyLogin : function (oldLogin, newLoginData) {
+ let [idToModify, oldStoredLogin] = this._getIdForLogin(oldLogin);
+ if (!idToModify)
+ throw "No matching logins";
+ oldStoredLogin.QueryInterface(Ci.nsILoginMetaInfo);
+
+ let newLogin;
+ if (newLoginData instanceof Ci.nsILoginInfo) {
+ // Clone the existing login to get its nsILoginMetaInfo, then init it
+ // with the replacement nsILoginInfo data from the new login.
+ newLogin = oldStoredLogin.clone();
+ newLogin.init(newLoginData.hostname,
+ newLoginData.formSubmitURL, newLoginData.httpRealm,
+ newLoginData.username, newLoginData.password,
+ newLoginData.usernameField, newLoginData.passwordField);
+ newLogin.QueryInterface(Ci.nsILoginMetaInfo);
+ } else if (newLoginData instanceof Ci.nsIPropertyBag) {
+ // Clone the existing login, along with all its properties.
+ newLogin = oldStoredLogin.clone();
+ newLogin.QueryInterface(Ci.nsILoginMetaInfo);
+
+ let propEnum = newLoginData.enumerator;
+ while (propEnum.hasMoreElements()) {
+ let prop = propEnum.getNext().QueryInterface(Ci.nsIProperty);
+ switch (prop.name) {
+ // nsILoginInfo properties...
+ case "hostname":
+ case "httpRealm":
+ case "formSubmitURL":
+ case "username":
+ case "password":
+ case "usernameField":
+ case "passwordField":
+ newLogin[prop.name] = prop.value;
+ break;
+
+ // nsILoginMetaInfo properties...
+ case "guid":
+ newLogin.guid = prop.value;
+ if (!this._isGuidUnique(newLogin.guid))
+ throw "specified GUID already exists";
+ break;
+
+ // Fail if caller requests setting an unknown property.
+ default:
+ throw "Unexpected propertybag item: " + prop.name;
+ }
+ }
+ } else {
+ throw "newLoginData needs an expected interface!";
+ }
+
+ // Throws if there are bogus values.
+ this._checkLoginValues(newLogin);
+
+ // Get the encrypted value of the username and password.
+ let [encUsername, encPassword, userCanceled] = this._encryptLogin(newLogin);
+ if (userCanceled)
+ throw "User canceled master password entry, login not modified.";
+
+ let query =
+ "UPDATE moz_logins " +
+ "SET hostname = :hostname, " +
+ "httpRealm = :httpRealm, " +
+ "formSubmitURL = :formSubmitURL, " +
+ "usernameField = :usernameField, " +
+ "passwordField = :passwordField, " +
+ "encryptedUsername = :encryptedUsername, " +
+ "encryptedPassword = :encryptedPassword, " +
+ "guid = :guid, " +
+ "encType = :encType " +
+ "WHERE id = :id";
+
+ let params = {
+ id: idToModify,
+ hostname: newLogin.hostname,
+ httpRealm: newLogin.httpRealm,
+ formSubmitURL: newLogin.formSubmitURL,
+ usernameField: newLogin.usernameField,
+ passwordField: newLogin.passwordField,
+ encryptedUsername: encUsername,
+ encryptedPassword: encPassword,
+ guid: newLogin.guid,
+ encType: ENCTYPE_SDR
+ };
+
+ let stmt;
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ stmt.execute();
+ } catch (e) {
+ this.log("modifyLogin failed: " + e.name + " : " + e.message);
+ throw "Couldn't write to database, login not modified.";
+ } finally {
+ stmt.reset();
+ }
+
+ this._sendNotification("modifyLogin", [oldStoredLogin, newLogin]);
+ },
+
+
+ /*
+ * getAllLogins
+ *
+ * Returns an array of nsILoginInfo.
+ */
+ getAllLogins : function (count) {
+ let userCanceled;
+ let [logins, ids] = this._searchLogins({});
+
+ // decrypt entries for caller.
+ [logins, userCanceled] = this._decryptLogins(logins);
+
+ if (userCanceled)
+ throw "User canceled Master Password entry";
+
+ this.log("_getAllLogins: returning " + logins.length + " logins.");
+ count.value = logins.length; // needed for XPCOM
+ return logins;
+ },
+
+
+ /*
+ * getAllEncryptedLogins
+ *
+ * Not implemented. This interface was added to extract logins from the
+ * legacy storage module without decrypting them. Now that logins are in
+ * mozStorage, if the encrypted data is really needed it can be easily
+ * obtained with SQL and the mozStorage APIs.
+ */
+ getAllEncryptedLogins : function (count) {
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+
+ /*
+ * searchLogins
+ *
+ * Public wrapper around _searchLogins to convert the nsIPropertyBag to a
+ * JavaScript object and decrypt the results.
+ *
+ * Returns an array of decrypted nsILoginInfo.
+ */
+ searchLogins : function(count, matchData) {
+ let realMatchData = {};
+ // Convert nsIPropertyBag to normal JS object
+ let propEnum = matchData.enumerator;
+ while (propEnum.hasMoreElements()) {
+ let prop = propEnum.getNext().QueryInterface(Ci.nsIProperty);
+ realMatchData[prop.name] = prop.value;
+ }
+
+ let [logins, ids] = this._searchLogins(realMatchData);
+
+ let userCanceled;
+ // Decrypt entries found for the caller.
+ [logins, userCanceled] = this._decryptLogins(logins);
+
+ if (userCanceled)
+ throw "User canceled Master Password entry";
+
+ count.value = logins.length; // needed for XPCOM
+ return logins;
+ },
+
+
+ /*
+ * _searchLogins
+ *
+ * Private method to perform arbitrary searches on any field. Decryption is
+ * left to the caller.
+ *
+ * Returns [logins, ids] for logins that match the arguments, where logins
+ * is an array of encrypted nsLoginInfo and ids is an array of associated
+ * ids in the database.
+ */
+ _searchLogins : function (matchData) {
+ let conditions = [], params = {};
+
+ for (field in matchData) {
+ let value = matchData[field];
+ switch (field) {
+ // Historical compatibility requires this special case
+ case "formSubmitURL":
+ if (value != null) {
+ conditions.push("formSubmitURL = :formSubmitURL OR formSubmitURL = ''");
+ params["formSubmitURL"] = value;
+ break;
+ }
+ // Normal cases.
+ case "hostname":
+ case "httpRealm":
+ case "id":
+ case "usernameField":
+ case "passwordField":
+ case "encryptedUsername":
+ case "encryptedPassword":
+ case "guid":
+ case "encType":
+ if (value == null) {
+ conditions.push(field + " isnull");
+ } else {
+ conditions.push(field + " = :" + field);
+ params[field] = value;
+ }
+ break;
+ // Fail if caller requests an unknown property.
+ default:
+ throw "Unexpected field: " + field;
+ }
+ }
+
+ // Build query
+ let query = "SELECT * FROM moz_logins";
+ if (conditions.length) {
+ conditions = conditions.map(function(c) "(" + c + ")");
+ query += " WHERE " + conditions.join(" AND ");
+ }
+
+ let stmt;
+ let logins = [], ids = [];
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ // We can't execute as usual here, since we're iterating over rows
+ while (stmt.step()) {
+ // Create the new nsLoginInfo object, push to array
+ let login = Cc["@mozilla.org/login-manager/loginInfo;1"].
+ createInstance(Ci.nsILoginInfo);
+ login.init(stmt.row.hostname, stmt.row.formSubmitURL,
+ stmt.row.httpRealm, stmt.row.encryptedUsername,
+ stmt.row.encryptedPassword, stmt.row.usernameField,
+ stmt.row.passwordField);
+ // set nsILoginMetaInfo values
+ login.QueryInterface(Ci.nsILoginMetaInfo);
+ login.guid = stmt.row.guid;
+ logins.push(login);
+ ids.push(stmt.row.id);
+ }
+ } catch (e) {
+ this.log("_searchLogins failed: " + e.name + " : " + e.message);
+ } finally {
+ stmt.reset();
+ }
+
+ this.log("_searchLogins: returning " + logins.length + " logins");
+ return [logins, ids];
+ },
+
+
+ /*
+ * removeAllLogins
+ *
+ * Removes all logins from storage.
+ */
+ removeAllLogins : function () {
+ this.log("Removing all logins");
+ // Delete any old, unused files.
+ this._removeOldSignonsFiles();
+
+ // Disabled hosts kept, as one presumably doesn't want to erase those.
+ let query = "DELETE FROM moz_logins";
+ let stmt;
+ try {
+ stmt = this._dbCreateStatement(query);
+ stmt.execute();
+ } catch (e) {
+ this.log("_removeAllLogins failed: " + e.name + " : " + e.message);
+ throw "Couldn't write to database";
+ } finally {
+ stmt.reset();
+ }
+
+ this._sendNotification("removeAllLogins", null);
+ },
+
+
+ /*
+ * getAllDisabledHosts
+ *
+ */
+ getAllDisabledHosts : function (count) {
+ let disabledHosts = this._queryDisabledHosts(null);
+
+ this.log("_getAllDisabledHosts: returning " + disabledHosts.length + " disabled hosts.");
+ count.value = disabledHosts.length; // needed for XPCOM
+ return disabledHosts;
+ },
+
+
+ /*
+ * getLoginSavingEnabled
+ *
+ */
+ getLoginSavingEnabled : function (hostname) {
+ this.log("Getting login saving is enabled for " + hostname);
+ return this._queryDisabledHosts(hostname).length == 0
+ },
+
+
+ /*
+ * setLoginSavingEnabled
+ *
+ */
+ setLoginSavingEnabled : function (hostname, enabled) {
+ // Throws if there are bogus values.
+ this._checkHostnameValue(hostname);
+
+ this.log("Setting login saving enabled for " + hostname + " to " + enabled);
+ let query;
+ if (enabled)
+ query = "DELETE FROM moz_disabledHosts " +
+ "WHERE hostname = :hostname";
+ else
+ query = "INSERT INTO moz_disabledHosts " +
+ "(hostname) VALUES (:hostname)";
+ let params = { hostname: hostname };
+
+ let stmt
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ stmt.execute();
+ } catch (e) {
+ this.log("setLoginSavingEnabled failed: " + e.name + " : " + e.message);
+ throw "Couldn't write to database"
+ } finally {
+ stmt.reset();
+ }
+
+ this._sendNotification(enabled ? "hostSavingEnabled" : "hostSavingDisabled", hostname);
+ },
+
+
+ /*
+ * findLogins
+ *
+ */
+ findLogins : function (count, hostname, formSubmitURL, httpRealm) {
+ let userCanceled;
+ let loginData = {
+ hostname: hostname,
+ formSubmitURL: formSubmitURL,
+ httpRealm: httpRealm
+ };
+ let matchData = { };
+ for each (field in ["hostname", "formSubmitURL", "httpRealm"])
+ if (loginData[field] != '')
+ matchData[field] = loginData[field];
+ let [logins, ids] = this._searchLogins(matchData);
+
+ // Decrypt entries found for the caller.
+ [logins, userCanceled] = this._decryptLogins(logins);
+
+ // We want to throw in this case, so that the Login Manager
+ // knows to stop processing forms on the page so the user isn't
+ // prompted multiple times.
+ if (userCanceled)
+ throw "User canceled Master Password entry";
+
+ this.log("_findLogins: returning " + logins.length + " logins");
+ count.value = logins.length; // needed for XPCOM
+ return logins;
+ },
+
+
+ /*
+ * countLogins
+ *
+ */
+ countLogins : function (hostname, formSubmitURL, httpRealm) {
+ // Do checks for null and empty strings, adjust conditions and params
+ let [conditions, params] =
+ this._buildConditionsAndParams(hostname, formSubmitURL, httpRealm);
+
+ let query = "SELECT COUNT(1) AS numLogins FROM moz_logins";
+ if (conditions.length) {
+ conditions = conditions.map(function(c) "(" + c + ")");
+ query += " WHERE " + conditions.join(" AND ");
+ }
+
+ let stmt, numLogins;
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ stmt.step();
+ numLogins = stmt.row.numLogins;
+ } catch (e) {
+ this.log("_countLogins failed: " + e.name + " : " + e.message);
+ } finally {
+ stmt.reset();
+ }
+
+ this.log("_countLogins: counted logins: " + numLogins);
+ return numLogins;
+ },
+
+
+ /*
+ * _sendNotification
+ *
+ * Send a notification when stored data is changed.
+ */
+ _sendNotification : function (changeType, data) {
+ let dataObject = data;
+ // Can't pass a raw JS string or array though notifyObservers(). :-(
+ if (data instanceof Array) {
+ dataObject = Cc["@mozilla.org/array;1"].
+ createInstance(Ci.nsIMutableArray);
+ for (let i = 0; i < data.length; i++)
+ dataObject.appendElement(data[i], false);
+ } else if (typeof(data) == "string") {
+ dataObject = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ dataObject.data = data;
+ }
+ this._observerService.notifyObservers(dataObject, "passwordmgr-storage-changed", changeType);
+ },
+
+
+ /*
+ * _getIdForLogin
+ *
+ * Returns an array with two items: [id, login]. If the login was not
+ * found, both items will be null. The returned login contains the actual
+ * stored login (useful for looking at the actual nsILoginMetaInfo values).
+ */
+ _getIdForLogin : function (login) {
+ let matchData = { };
+ for each (field in ["hostname", "formSubmitURL", "httpRealm"])
+ if (login[field] != '')
+ matchData[field] = login[field];
+ let [logins, ids] = this._searchLogins(matchData);
+
+ let id = null;
+ let foundLogin = null;
+
+ // The specified login isn't encrypted, so we need to ensure
+ // the logins we're comparing with are decrypted. We decrypt one entry
+ // at a time, lest _decryptLogins return fewer entries and screw up
+ // indices between the two.
+ for (let i = 0; i < logins.length; i++) {
+ let [[decryptedLogin], userCanceled] =
+ this._decryptLogins([logins[i]]);
+
+ if (userCanceled)
+ throw "User canceled master password entry.";
+
+ if (!decryptedLogin || !decryptedLogin.equals(login))
+ continue;
+
+ // We've found a match, set id and break
+ foundLogin = decryptedLogin;
+ id = ids[i];
+ break;
+ }
+
+ return [id, foundLogin];
+ },
+
+
+ /*
+ * _queryDisabledHosts
+ *
+ * Returns an array of hostnames from the database according to the
+ * criteria given in the argument. If the argument hostname is null, the
+ * result array contains all hostnames
+ */
+ _queryDisabledHosts : function (hostname) {
+ let disabledHosts = [];
+
+ let query = "SELECT hostname FROM moz_disabledHosts";
+ let params = {};
+ if (hostname) {
+ query += " WHERE hostname = :hostname";
+ params = { hostname: hostname };
+ }
+
+ let stmt;
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ while (stmt.step())
+ disabledHosts.push(stmt.row.hostname);
+ } catch (e) {
+ this.log("_queryDisabledHosts failed: " + e.name + " : " + e.message);
+ } finally {
+ stmt.reset();
+ }
+
+ return disabledHosts;
+ },
+
+
+ /*
+ * _buildConditionsAndParams
+ *
+ * Adjusts the WHERE conditions and parameters for statements prior to the
+ * statement being created. This fixes the cases where nulls are involved
+ * and the empty string is supposed to be a wildcard match
+ */
+ _buildConditionsAndParams : function (hostname, formSubmitURL, httpRealm) {
+ let conditions = [], params = {};
+
+ if (hostname == null) {
+ conditions.push("hostname isnull");
+ } else if (hostname != '') {
+ conditions.push("hostname = :hostname");
+ params["hostname"] = hostname;
+ }
+
+ if (formSubmitURL == null) {
+ conditions.push("formSubmitURL isnull");
+ } else if (formSubmitURL != '') {
+ conditions.push("formSubmitURL = :formSubmitURL OR formSubmitURL = ''");
+ params["formSubmitURL"] = formSubmitURL;
+ }
+
+ if (httpRealm == null) {
+ conditions.push("httpRealm isnull");
+ } else if (httpRealm != '') {
+ conditions.push("httpRealm = :httpRealm");
+ params["httpRealm"] = httpRealm;
+ }
+
+ return [conditions, params];
+ },
+
+
+ /*
+ * _checkLoginValues
+ *
+ * Due to the way the signons2.txt file is formatted, we need to make
+ * sure certain field values or characters do not cause the file to
+ * be parse incorrectly. Reject logins that we can't store correctly.
+ */
+ _checkLoginValues : function (aLogin) {
+ function badCharacterPresent(l, c) {
+ return ((l.formSubmitURL && l.formSubmitURL.indexOf(c) != -1) ||
+ (l.httpRealm && l.httpRealm.indexOf(c) != -1) ||
+ l.hostname.indexOf(c) != -1 ||
+ l.usernameField.indexOf(c) != -1 ||
+ l.passwordField.indexOf(c) != -1);
+ }
+
+ // Nulls are invalid, as they don't round-trip well.
+ // Mostly not a formatting problem, although ".\0" can be quirky.
+ if (badCharacterPresent(aLogin, "\0"))
+ throw "login values can't contain nulls";
+
+ // In theory these nulls should just be rolled up into the encrypted
+ // values, but nsISecretDecoderRing doesn't use nsStrings, so the
+ // nulls cause truncation. Check for them here just to avoid
+ // unexpected round-trip surprises.
+ if (aLogin.username.indexOf("\0") != -1 ||
+ aLogin.password.indexOf("\0") != -1)
+ throw "login values can't contain nulls";
+
+ // Newlines are invalid for any field stored as plaintext.
+ if (badCharacterPresent(aLogin, "\r") ||
+ badCharacterPresent(aLogin, "\n"))
+ throw "login values can't contain newlines";
+
+ // A line with just a "." can have special meaning.
+ if (aLogin.usernameField == "." ||
+ aLogin.formSubmitURL == ".")
+ throw "login values can't be periods";
+
+ // A hostname with "\ \(" won't roundtrip.
+ // eg host="foo (", realm="bar" --> "foo ( (bar)"
+ // vs host="foo", realm=" (bar" --> "foo ( (bar)"
+ if (aLogin.hostname.indexOf(" (") != -1)
+ throw "bad parens in hostname";
+ },
+
+
+ /*
+ * _checkHostnameValue
+ *
+ * Legacy storage prohibited newlines and nulls in hostnames, so we'll keep
+ * that standard here. Throws on illegal format.
+ */
+ _checkHostnameValue : function (hostname) {
+ // File format prohibits certain values. Also, nulls
+ // won't round-trip with getAllDisabledHosts().
+ if (hostname == "." ||
+ hostname.indexOf("\r") != -1 ||
+ hostname.indexOf("\n") != -1 ||
+ hostname.indexOf("\0") != -1)
+ throw "Invalid hostname";
+ },
+
+
+ /*
+ * _isGuidUnique
+ *
+ * Checks to see if the specified GUID already exists.
+ */
+ _isGuidUnique : function (guid) {
+ let query = "SELECT COUNT(1) AS numLogins FROM moz_logins WHERE guid = :guid";
+ let params = { guid: guid };
+
+ let stmt, numLogins;
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ stmt.step();
+ numLogins = stmt.row.numLogins;
+ } catch (e) {
+ this.log("_isGuidUnique failed: " + e.name + " : " + e.message);
+ } finally {
+ stmt.reset();
+ }
+
+ return (numLogins == 0);
+ },
+
+
+ /*
+ * _importLegacySignons
+ *
+ * Imports a file that uses Legacy storage. Will use importFile if provided
+ * else it will attempt to initialize the Legacy storage normally.
+ *
+ */
+ _importLegacySignons : function (importFile) {
+ this.log("Importing " + (importFile ? importFile.path : "legacy storage"));
+
+ let legacy = Cc["@mozilla.org/login-manager/storage/legacy;1"].
+ createInstance(Ci.nsILoginManagerStorage);
+
+ // Import all logins and disabled hosts
+ try {
+ if (importFile)
+ legacy.initWithFile(importFile, null);
+ else
+ legacy.init();
+
+ // Import logins and disabledHosts
+ let logins = legacy.getAllEncryptedLogins({});
+
+ // Wrap in a transaction for better performance.
+ this._dbConnection.beginTransaction();
+ for each (let login in logins) {
+ try {
+ this._addLogin(login, true);
+ } catch (e) {
+ this.log("_importLegacySignons failed to add login: " + e);
+ }
+ }
+ let disabledHosts = legacy.getAllDisabledHosts({});
+ for each (let hostname in disabledHosts)
+ this.setLoginSavingEnabled(hostname, false);
+ this._dbConnection.commitTransaction();
+ } catch (e) {
+ this.log("_importLegacySignons failed: " + e.name + " : " + e.message);
+ throw "Import failed";
+ }
+ },
+
+
+ /*
+ * _removeOldSignonsFiles
+ *
+ * Deletes any storage files that we're not using any more.
+ */
+ _removeOldSignonsFiles : function () {
+ // We've used a number of prefs over time due to compatibility issues.
+ // We want to delete all files referenced in prefs, which are only for
+ // importing and clearing logins from storage-Legacy.js.
+ filenamePrefs = ["SignonFileName3", "SignonFileName2", "SignonFileName"];
+ for each (let prefname in filenamePrefs) {
+ let filename = this._prefBranch.getCharPref(prefname);
+ let file = this._profileDir.clone();
+ file.append(filename);
+
+ if (file.exists()) {
+ this.log("Deleting old " + filename + " (" + prefname + ")");
+ try {
+ file.remove(false);
+ } catch (e) {
+ this.log("NOTICE: Couldn't delete " + filename + ": " + e);
+ }
+ }
+ }
+ },
+
+
+ /*
+ * _encryptLogin
+ *
+ * Returns the encrypted username and password for the specified login,
+ * and a boolean indicating if the user canceled the master password entry
+ * (in which case no encrypted values are returned).
+ */
+ _encryptLogin : function (login) {
+ let encUsername, encPassword, userCanceled;
+ [encUsername, userCanceled] = this._encrypt(login.username);
+ if (userCanceled)
+ return [null, null, true];
+
+ [encPassword, userCanceled] = this._encrypt(login.password);
+ // Probably can't hit this case, but for completeness...
+ if (userCanceled)
+ return [null, null, true];
+
+ if (!this._base64checked)
+ this._reencryptBase64Logins();
+
+ return [encUsername, encPassword, false];
+ },
+
+
+ /*
+ * _decryptLogins
+ *
+ * Decrypts username and password fields in the provided array of
+ * logins.
+ *
+ * The entries specified by the array will be decrypted, if possible.
+ * An array of successfully decrypted logins will be returned. The return
+ * value should be given to external callers (since still-encrypted
+ * entries are useless), whereas internal callers generally don't want
+ * to lose unencrypted entries (eg, because the user clicked Cancel
+ * instead of entering their master password)
+ */
+ _decryptLogins : function (logins) {
+ let result = [], userCanceled = false;
+
+ for each (let login in logins) {
+ let decryptedUsername, decryptedPassword;
+
+ [decryptedUsername, userCanceled] = this._decrypt(login.username);
+
+ if (userCanceled)
+ break;
+
+ [decryptedPassword, userCanceled] = this._decrypt(login.password);
+
+ // Probably can't hit this case, but for completeness...
+ if (userCanceled)
+ break;
+
+ // If decryption failed (corrupt entry?) skip it.
+ // Note that we allow password-only logins, so username can be "".
+ if (decryptedUsername == null || !decryptedPassword)
+ continue;
+
+ login.username = decryptedUsername;
+ login.password = decryptedPassword;
+
+ result.push(login);
+ }
+
+ if (!this._base64checked && !userCanceled)
+ this._reencryptBase64Logins();
+
+ return [result, userCanceled];
+ },
+
+
+ /*
+ * _reencryptBase64Logins
+ *
+ * Checks the signons DB for any logins using the old wallet-style base64
+ * obscuring of the username/password, instead of proper encryption. We're
+ * called once per session, after the user has successfully encrypted or
+ * decrypted some login (this helps ensure the user doesn't get mysterious
+ * prompts for a master password, when set).
+ */
+ _reencryptBase64Logins : function () {
+ this._base64checked = true;
+ // Ignore failures, will try again next session...
+
+ try {
+ let [logins, ids] = this._searchLogins({ encType: 0 });
+
+ if (!logins.length)
+ return;
+
+ let userCancelled;
+ [logins, userCanceled] = this._decryptLogins(logins);
+ if (userCanceled)
+ return;
+
+ for each (let login in logins)
+ this.modifyLogin(login, login);
+ } catch (e) {
+ this.log("_reencryptBase64Logins caught error: " + e);
+ }
+ },
+
+
+ /*
+ * _encrypt
+ *
+ * Encrypts the specified string, using the SecretDecoderRing.
+ *
+ * Returns [cipherText, userCanceled] where:
+ * cipherText -- the encrypted string, or null if it failed.
+ * userCanceled -- if the encryption failed, this is true if the
+ * user selected Cancel when prompted to enter their
+ * Master Password. The caller should bail out, and not
+ * not request that more things be encrypted (which
+ * results in prompting the user for a Master Password
+ * over and over.)
+ */
+ _encrypt : function (plainText) {
+ let cipherText = null, userCanceled = false;
+
+ try {
+ let plainOctet = this._utfConverter.ConvertFromUnicode(plainText);
+ plainOctet += this._utfConverter.Finish();
+ cipherText = this._decoderRing.encryptString(plainOctet);
+ } catch (e) {
+ this.log("Failed to encrypt string. (" + e.name + ")");
+ // If the user clicks Cancel, we get NS_ERROR_FAILURE.
+ // (unlike decrypting, which gets NS_ERROR_NOT_AVAILABLE).
+ if (e.result == Components.results.NS_ERROR_FAILURE)
+ userCanceled = true;
+ }
+
+ return [cipherText, userCanceled];
+ },
+
+
+ /*
+ * _decrypt
+ *
+ * Decrypts the specified string, using the SecretDecoderRing.
+ *
+ * Returns [plainText, userCanceled] where:
+ * plainText -- the decrypted string, or null if it failed.
+ * userCanceled -- if the decryption failed, this is true if the
+ * user selected Cancel when prompted to enter their
+ * Master Password. The caller should bail out, and not
+ * not request that more things be decrypted (which
+ * results in prompting the user for a Master Password
+ * over and over.)
+ */
+ _decrypt : function (cipherText) {
+ let plainText = null, userCanceled = false;
+
+ try {
+ let plainOctet;
+ if (cipherText.charAt(0) == '~') {
+ // The old Wallet file format obscured entries by
+ // base64-encoding them. These entries are signaled by a
+ // leading '~' character.
+ plainOctet = atob(cipherText.substring(1));
+ } else {
+ plainOctet = this._decoderRing.decryptString(cipherText);
+ }
+ plainText = this._utfConverter.ConvertToUnicode(plainOctet);
+ } catch (e) {
+ this.log("Failed to decrypt string: " + cipherText +
+ " (" + e.name + ")");
+
+ // In the unlikely event the converter threw, reset it.
+ this._utfConverterReset();
+
+ // If the user clicks Cancel, we get NS_ERROR_NOT_AVAILABLE.
+ // If the cipherText is bad / wrong key, we get NS_ERROR_FAILURE
+ // Wrong passwords are handled by the decoderRing reprompting;
+ // we get no notification.
+ if (e.result == Components.results.NS_ERROR_NOT_AVAILABLE)
+ userCanceled = true;
+ }
+
+ return [plainText, userCanceled];
+ },
+
+
+ //**************************************************************************//
+ // Database Creation & Access
+
+ /*
+ * _dbCreateStatement
+ *
+ * Creates a statement, wraps it, and then does parameter replacement
+ * Returns the wrapped statement for execution. Will use memoization
+ * so that statements can be reused.
+ */
+ _dbCreateStatement : function (query, params) {
+ let wrappedStmt = this._dbStmts[query];
+ // Memoize the statements
+ if (!wrappedStmt) {
+ this.log("Creating new statement for query: " + query);
+ let stmt = this._dbConnection.createStatement(query);
+
+ wrappedStmt = Cc["@mozilla.org/storage/statement-wrapper;1"].
+ createInstance(Ci.mozIStorageStatementWrapper);
+ wrappedStmt.initialize(stmt);
+ this._dbStmts[query] = wrappedStmt;
+ }
+ // Replace parameters, must be done 1 at a time
+ if (params)
+ for (let i in params)
+ wrappedStmt.params[i] = params[i];
+ return wrappedStmt;
+ },
+
+
+ /*
+ * _dbInit
+ *
+ * Attempts to initialize the database. This creates the file if it doesn't
+ * exist, performs any migrations, etc. When database is first created, we
+ * attempt to import legacy signons. Return if this is the first run.
+ */
+ _dbInit : function () {
+ this.log("Initializing Database");
+ let isFirstRun = false;
+ try {
+ this._dbConnection = this._storageService.openDatabase(this._signonsFile);
+ // Get the version of the schema in the file. It will be 0 if the
+ // database has not been created yet.
+ let version = this._dbConnection.schemaVersion;
+ if (version == 0) {
+ this._dbCreate();
+ isFirstRun = true;
+ } else if (version != DB_VERSION) {
+ this._dbMigrate(version);
+ }
+ } catch (e if e.result == Components.results.NS_ERROR_FILE_CORRUPTED) {
+ // Database is corrupted, so we backup the database, then throw
+ // causing initialization to fail and a new db to be created next use
+ this._dbCleanup(true);
+ throw e;
+ }
+ return isFirstRun;
+ },
+
+
+ _dbCreate: function () {
+ this.log("Creating Database");
+ this._dbCreateSchema();
+ this._dbConnection.schemaVersion = DB_VERSION;
+ },
+
+
+ _dbCreateSchema : function () {
+ this._dbCreateTables();
+ this._dbCreateIndices();
+ },
+
+
+ _dbCreateTables : function () {
+ this.log("Creating Tables");
+ for (let name in this._dbSchema.tables)
+ this._dbConnection.createTable(name, this._dbSchema.tables[name]);
+ },
+
+
+ _dbCreateIndices : function () {
+ this.log("Creating Indices");
+ for (let name in this._dbSchema.indices) {
+ let index = this._dbSchema.indices[name];
+ let statement = "CREATE INDEX IF NOT EXISTS " + name + " ON " + index.table +
+ "(" + index.columns.join(", ") + ")";
+ this._dbConnection.executeSimpleSQL(statement);
+ }
+ },
+
+
+ _dbMigrate : function (oldVersion) {
+ this.log("Attempting to migrate from version " + oldVersion);
+
+ if (oldVersion > DB_VERSION) {
+ this.log("Downgrading to version " + DB_VERSION);
+ // User's DB is newer. Sanity check that our expected columns are
+ // present, and if so mark the lower version and merrily continue
+ // on. If the columns are borked, something is wrong so blow away
+ // the DB and start from scratch. [Future incompatible upgrades
+ // should swtich to a different table or file.]
+
+ if (!this._dbAreExpectedColumnsPresent())
+ throw Components.Exception("DB is missing expected columns",
+ Components.results.NS_ERROR_FILE_CORRUPTED);
+
+ // Change the stored version to the current version. If the user
+ // runs the newer code again, it will see the lower version number
+ // and re-upgrade (to fixup any entries the old code added).
+ this._dbConnection.schemaVersion = DB_VERSION;
+ return;
+ }
+
+ // Upgrade to newer version...
+
+ this._dbConnection.beginTransaction();
+
+ try {
+ for (let v = oldVersion + 1; v <= DB_VERSION; v++) {
+ this.log("Upgrading to version " + v + "...");
+ let migrateFunction = "_dbMigrateToVersion" + v;
+ this[migrateFunction]();
+ }
+ } catch (e) {
+ this.log("Migration failed: " + e);
+ this._dbConnection.rollbackTransaction();
+ throw e;
+ }
+
+ this._dbConnection.schemaVersion = DB_VERSION;
+ this._dbConnection.commitTransaction();
+ this.log("DB migration completed.");
+ },
+
+
+ /*
+ * _dbMigrateToVersion2
+ *
+ * Version 2 adds a GUID column. Existing logins are assigned a random GUID.
+ */
+ _dbMigrateToVersion2 : function () {
+ // Check to see if GUID column already exists.
+ let exists = true;
+ try {
+ let stmt = this._dbConnection.createStatement(
+ "SELECT guid FROM moz_logins");
+ // (no need to execute statement, if it compiled we're good)
+ stmt.finalize();
+ } catch (e) {
+ exists = false;
+ }
+
+ // Add the new column and index only if needed.
+ if (!exists) {
+ this._dbConnection.executeSimpleSQL(
+ "ALTER TABLE moz_logins ADD COLUMN guid TEXT");
+
+ this._dbConnection.executeSimpleSQL(
+ "CREATE INDEX IF NOT EXISTS " +
+ "moz_logins_guid_index ON moz_logins (guid)");
+ }
+
+ // Get a list of IDs for existing logins
+ let ids = [];
+ let query = "SELECT id FROM moz_logins WHERE guid isnull";
+ let stmt;
+ try {
+ stmt = this._dbCreateStatement(query);
+ while (stmt.step())
+ ids.push(stmt.row.id);
+ } catch (e) {
+ this.log("Failed getting IDs: " + e);
+ throw e;
+ } finally {
+ stmt.reset();
+ }
+
+ // Generate a GUID for each login and update the DB.
+ query = "UPDATE moz_logins SET guid = :guid WHERE id = :id";
+ for each (let id in ids) {
+ let params = {
+ id: id,
+ guid: this._uuidService.generateUUID().toString()
+ };
+
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ stmt.execute();
+ } catch (e) {
+ this.log("Failed setting GUID: " + e);
+ throw e;
+ } finally {
+ stmt.reset();
+ }
+ }
+ },
+
+
+ /*
+ * _dbMigrateToVersion3
+ *
+ * Version 3 adds a encType column.
+ */
+ _dbMigrateToVersion3 : function () {
+ // Check to see if encType column already exists.
+ let exists = true;
+ let query = "SELECT encType FROM moz_logins";
+ let stmt;
+ try {
+ stmt = this._dbConnection.createStatement(query);
+ // (no need to execute statement, if it compiled we're good)
+ stmt.finalize();
+ } catch (e) {
+ exists = false;
+ }
+
+ // Add the new column and index only if needed.
+ if (!exists) {
+ query = "ALTER TABLE moz_logins ADD COLUMN encType INTEGER";
+ this._dbConnection.executeSimpleSQL(query);
+
+ query = "CREATE INDEX IF NOT EXISTS " +
+ "moz_logins_encType_index ON moz_logins (encType)";
+ this._dbConnection.executeSimpleSQL(query);
+ }
+
+ // Get a list of existing logins
+ let logins = [];
+ query = "SELECT id, encryptedUsername, encryptedPassword " +
+ "FROM moz_logins WHERE encType isnull";
+ try {
+ stmt = this._dbCreateStatement(query);
+ while (stmt.step()) {
+ let params = { id: stmt.row.id };
+ if (stmt.row.encryptedUsername.charAt(0) == '~' ||
+ stmt.row.encryptedPassword.charAt(0) == '~')
+ params.encType = ENCTYPE_BASE64;
+ else
+ params.encType = ENCTYPE_SDR;
+ logins.push(params);
+ }
+ } catch (e) {
+ this.log("Failed getting logins: " + e);
+ throw e;
+ } finally {
+ stmt.reset();
+ }
+
+ // Determine encryption type for each login and update the DB.
+ query = "UPDATE moz_logins SET encType = :encType WHERE id = :id";
+ for each (params in logins) {
+ try {
+ stmt = this._dbCreateStatement(query, params);
+ stmt.execute();
+ } catch (e) {
+ this.log("Failed setting encType: " + e);
+ throw e;
+ } finally {
+ stmt.reset();
+ }
+ }
+
+ },
+
+
+ /*
+ * _dbAreExpectedColumnsPresent
+ *
+ * Sanity check to ensure that the columns this version of the code expects
+ * are present in the DB we're using.
+ */
+ _dbAreExpectedColumnsPresent : function () {
+ let query = "SELECT " +
+ "id, " +
+ "hostname, " +
+ "httpRealm, " +
+ "formSubmitURL, " +
+ "usernameField, " +
+ "passwordField, " +
+ "encryptedUsername, " +
+ "encryptedPassword, " +
+ "guid, " +
+ "encType " +
+ "FROM moz_logins";
+ try {
+ let stmt = this._dbConnection.createStatement(query);
+ // (no need to execute statement, if it compiled we're good)
+ stmt.finalize();
+ } catch (e) {
+ return false;
+ }
+
+ query = "SELECT " +
+ "id, " +
+ "hostname " +
+ "FROM moz_disabledHosts";
+ try {
+ let stmt = this._dbConnection.createStatement(query);
+ // (no need to execute statement, if it compiled we're good)
+ stmt.finalize();
+ } catch (e) {
+ return false;
+ }
+
+ this.log("verified that expected columns are present in DB.");
+ return true;
+ },
+
+
+ /*
+ * _dbCleanup
+ *
+ * Called when database creation fails. Finalizes database statements,
+ * closes the database connection, deletes the database file.
+ */
+ _dbCleanup : function (backup) {
+ this.log("Cleaning up DB file - close & remove & backup=" + backup)
+
+ // Create backup file
+ if (backup) {
+ let backupFile = this._signonsFile.leafName + ".corrupt";
+ this._storageService.backupDatabaseFile(this._signonsFile, backupFile);
+ }
+
+ // Finalize all statements to free memory, avoid errors later
+ for (let i = 0; i < this._dbStmts.length; i++)
+ this._dbStmts[i].statement.finalize();
+ this._dbStmts = [];
+
+ // Close the connection, ignore 'already closed' error
+ try { this._dbConnection.close() } catch(e) {}
+ this._signonsFile.remove(false);
+ }
+
+}; // end of nsLoginManagerStorage_mozStorage implementation
+
+let component = [LoginManagerStorage_mozStorage];
+function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(component);
+}
diff --git a/bundles/XO/components/txEXSLTRegExFunctions.js b/bundles/XO/components/txEXSLTRegExFunctions.js
new file mode 100755
index 0000000..2d7f235
--- /dev/null
+++ b/bundles/XO/components/txEXSLTRegExFunctions.js
@@ -0,0 +1,188 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Peter Van der Beken.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Peter Van der Beken <peterv@propagandism.org>
+ *
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const EXSLT_REGEXP_CONTRACTID = "@mozilla.org/exslt/regexp;1";
+const EXSLT_REGEXP_CID = Components.ID("{18a03189-067b-4978-b4f1-bafe35292ed6}");
+const EXSLT_REGEXP_NS = "http://exslt.org/regular-expressions";
+const EXSLT_REGEXP_DESC = "EXSLT RegExp extension functions"
+
+const XSLT_EXTENSIONS_CAT = "XSLT extension functions";
+
+const CATMAN_CONTRACTID = "@mozilla.org/categorymanager;1";
+const NODESET_CONTRACTID = "@mozilla.org/transformiix-nodeset;1";
+
+const Ci = Components.interfaces;
+
+function txEXSLTRegExFunctions()
+{
+}
+
+txEXSLTRegExFunctions.prototype = {
+ QueryInterface: function(iid) {
+ if (iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.txIEXSLTRegExFunctions))
+ return this;
+
+ if (iid.equals(Ci.nsIClassInfo))
+ return txEXSLTRegExModule.factory
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ match: function(context, str, regex, flags) {
+ var nodeset = Components.classes[NODESET_CONTRACTID]
+ .createInstance(Ci.txINodeSet);
+
+ var re = new RegExp(regex, flags);
+ var matches = str.match(re);
+ if (matches != null && matches.length > 0) {
+ var contextNode = context.contextNode;
+ var doc = contextNode.nodeType == Ci.nsIDOMNode.DOCUMENT_NODE ?
+ contextNode : contextNode.ownerDocument;
+ var docFrag = doc.createDocumentFragment();
+
+ for (var i = 0; i < matches.length; ++i) {
+ var match = matches[i];
+ var elem = doc.createElementNS(null, "match");
+ var text = doc.createTextNode(match ? match : '');
+ elem.appendChild(text);
+ docFrag.appendChild(elem);
+ nodeset.add(elem);
+ }
+ }
+
+ return nodeset;
+ },
+
+ replace: function(str, regex, flags, replace) {
+ var re = new RegExp(regex, flags);
+
+ return str.replace(re, replace);
+ },
+
+ test: function(str, regex, flags) {
+ var re = new RegExp(regex, flags);
+
+ return re.test(str);
+ }
+}
+
+var SingletonInstance = null;
+
+var txEXSLTRegExModule = {
+ registerSelf: function(compMgr, fileSpec, location, type) {
+ compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ compMgr.registerFactoryLocation(EXSLT_REGEXP_CID, EXSLT_REGEXP_DESC,
+ EXSLT_REGEXP_CONTRACTID, fileSpec,
+ location, type);
+
+ var catman = Components.classes[CATMAN_CONTRACTID]
+ .getService(Ci.nsICategoryManager);
+ catman.addCategoryEntry(XSLT_EXTENSIONS_CAT, EXSLT_REGEXP_NS,
+ EXSLT_REGEXP_CONTRACTID, true, true);
+ },
+
+ unregisterSelf: function(compMgr, location, loaderStr) {
+ compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ compMgr.unregisterFactoryLocation(EXSLT_REGEXP_CID, location);
+
+ var catman = Components.classes[CATMAN_CONTRACTID]
+ .getService(Ci.nsICategoryManager);
+ catman.deleteCategoryEntry(XSLT_EXTENSIONS_CAT, EXSLT_REGEXP_NS, true);
+ },
+
+ getClassObject: function(compMgr, cid, iid) {
+ if (!cid.equals(EXSLT_REGEXP_CID))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ if (!iid.equals(Ci.nsIFactory) &&
+ !iid.equals(Ci.nsIClassInfo))
+ throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+ return this.factory;
+ },
+
+ factory: {
+ QueryInterface: function(iid) {
+ if (iid.equals(Ci.nsISupports) ||
+ iid.equals(Ci.nsIFactory) ||
+ iid.equals(Ci.nsIClassInfo))
+ return this;
+
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+ createInstance: function(outer, iid) {
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ if (SingletonInstance == null)
+ SingletonInstance = new txEXSLTRegExFunctions();
+
+ return SingletonInstance.QueryInterface(iid);
+ },
+
+ getInterfaces: function(countRef) {
+ var interfaces = [
+ Ci.txIEXSLTRegExFunctions
+ ];
+ countRef.value = interfaces.length;
+
+ return interfaces;
+ },
+
+ getHelperForLanguage: function(language) {
+ return null;
+ },
+
+ contractID: EXSLT_REGEXP_CONTRACTID,
+ classDescription: EXSLT_REGEXP_DESC,
+ classID: EXSLT_REGEXP_CID,
+ implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
+ flags: Ci.nsIClassInfo.SINGLETON
+ },
+
+ canUnload: function(compMgr) {
+ return true;
+ }
+};
+
+function NSGetModule(compMgr, fileSpec) {
+ return txEXSLTRegExModule;
+}
diff --git a/bundles/XO/components/xpti.dat b/bundles/XO/components/xpti.dat
new file mode 100755
index 0000000..55abd5c
--- /dev/null
+++ b/bundles/XO/components/xpti.dat
@@ -0,0 +1,1449 @@
+# Generated file. ** DO NOT EDIT! **
+
+[Header,2]
+0,Version,2,0
+1,AppDir,/home/olpc/Activities/Firefox.activity
+
+[Directories,4]
+0,/home/olpc/Activities/Firefox.activity/components
+1,/home/olpc/.mozilla/plugins
+2,/home/olpc/Activities/Firefox.activity/plugins
+3,/usr/lib/mozilla/plugins
+
+[Files,1]
+0,browser.xpt,0,361500,1253014816000
+
+[ArchiveItems,0]
+
+[Interfaces,1431]
+0,nsIDOMStyleSheet,{a6cf9080-15b3-11d2-932e-00805f8add32},0,-1,1
+1,nsIAddonSearchResultsCallback,{a6f70917-dd30-4eb6-8b3d-453204f96f33},0,-1,1
+2,txIXPathObject,{67706346-dece-4c9b-9fc2-57cf19071014},0,-1,1
+3,nsIContentSniffer,{a5772d1b-fc63-495e-a169-96e8d3311af0},0,-1,1
+4,extIPreferenceBranch,{ce697d40-aa5a-11db-abbd-0800200c9a66},0,-1,1
+5,nsIDOMMediaList,{9b0c2ed7-111c-4824-adf9-ef0da6dad371},0,-1,1
+6,nsISHContainer,{65281ba2-988a-11d3-bdc7-0050040a9b44},0,-1,1
+7,nsITimer,{193fc37a-8aa4-4d29-aa57-1acd87c26b66},0,-1,1
+8,nsIBrowserSearchService,{8307b8f2-08ea-45b8-96bf-b1dc7688fe3b},0,-1,1
+9,nsIDOMHTMLAudioElement,{5ecd8913-a738-41be-8597-7f3a4ffba017},0,-1,1
+10,nsIDOMNSXBLFormControl,{1c28ed66-1dd2-11b2-95af-e2cf10931adb},0,-1,1
+11,nsIThreadPool,{d628159b-1a03-4985-aa77-43122eb23bfc},0,-1,1
+12,nsIScrollBoxObject,{56e2ada8-4631-11d4-ba11-001083023c1e},0,-1,1
+13,nsICachingChannel,{830d4bcb-3e46-4011-9bda-51a5d1af891f},0,-1,1
+14,nsIClipboardDragDropHooks,{e03e6c5e-0d84-4c0b-8739-e6b8d51922de},0,-1,1
+15,nsIDragDropHandler,{4f418f58-f834-4736-a755-e0395bedca9d},0,-1,1
+16,nsIDOMSVGAnimatedInteger,{7b196db6-955e-4a9f-8f42-645ebc2ce938},0,-1,1
+17,nsIJARURI,{b0922a89-f87b-4cb5-8612-305a285fcca7},0,-1,1
+18,nsITableEditor,{4805e684-49b9-11d3-9ce4-ed60bd6cb5bc},0,-1,1
+19,nsIClassicPluginFactory,{07bfa284-1dd2-11b2-90f8-fef5608e8a56},0,-1,0
+20,nsISignatureVerifier,{dea87f65-e91e-4119-aa13-aaa2be80cac2},0,-1,0
+21,nsIPropertyBag2,{625cfd1e-da1e-4417-9ee9-dbc8e0b3fd79},0,-1,1
+22,nsILocalFile,{aa610f20-a889-11d3-8c81-000064657374},0,-1,1
+23,nsIURIFixup,{773081ac-9f81-4bdb-9e7a-5e87b4361f09},0,-1,1
+24,nsIDOMStorageItem,{0cc37c78-4c5f-48e1-adfc-7480b8fe9dc4},0,-1,1
+25,nsIDOMCSSRuleList,{a6cf90c0-15b3-11d2-932e-00805f8add32},0,-1,1
+26,nsIStorageStream,{604ad9d0-753e-11d3-90ca-34278643278f},0,-1,1
+27,nsIDOMSVGFEFuncBElement,{8b139fe7-5d21-4af3-beda-414aa089b3fb},0,-1,1
+28,nsITreeSelection,{ab6fe746-300b-4ab4-abb9-1c0e3977874c},0,-1,1
+29,nsINonBlockingAlertService,{e800ef97-ae37-46b7-a46c-31fbe79657ea},0,-1,1
+30,nsIDownloadObserver,{44b3153e-a54e-4077-a527-b0325e40924e},0,-1,1
+31,nsIUnicharStreamLoaderObserver,{6bb3e55b-69c0-4fc9-87e5-bed780d997ce},0,-1,1
+32,nsIFile,{c8c0a080-0868-11d3-915f-d9d889d48e3c},0,-1,1
+33,nsIDocumentLoader,{bbe961ee-59e9-42bb-be50-0331979bb79f},0,-1,1
+34,nsIDOMHTMLTableCellElement,{a6cf90b7-15b3-11d2-932e-00805f8add32},0,-1,1
+35,nsIException,{f3a8d3b4-c424-4edc-8bf6-8974c983ba78},0,-1,1
+36,nsIContentPrefObserver,{746c7a02-f6c1-4869-b434-7c8b86e60e61},0,-1,1
+37,nsICommandParams,{83f892cf-7ed3-490e-967a-62640f3158e1},0,-1,1
+38,nsIUrlClassifierDBService,{7aae3f3a-527d-488b-a448-45dca6db0e80},0,-1,1
+39,nsIRDFDataSource,{0f78da58-8321-11d2-8eac-00805f29f370},0,-1,1
+40,nsIContentPrefService,{5047e359-dfda-4858-abec-d145c7463250},0,-1,1
+41,nsIDOMNotifyPaintEvent,{dec5582e-5cea-412f-bf98-6b27480fb46a},0,-1,1
+42,nsIDOMSVGFEMergeElement,{b860512c-2547-4d1f-bb43-b57b54d39014},0,-1,1
+43,nsIDOMCRMFObject,{16da46c0-208d-11d4-8a7c-006008c844c3},0,-1,1
+44,nsIInterfaceInfoManager,{8b161900-be2b-11d2-9831-006008962422},0,-1,0
+45,nsITextServicesFilter,{5bec321f-59ac-413a-a4ad-8a8d7c50a0d0},0,-1,1
+46,nsIJAR,{04501db2-0409-11d3-bcf8-00805f0e1353},0,-1,0
+47,nsIClientAuthUserDecision,{95c4373e-bdd4-4a63-b431-f5b000367721},0,-1,1
+48,nsILoginManagerPrompter,{68b3cb59-51b8-4c57-bd7f-b2ce955a593d},0,-1,1
+49,nsILoginMetaInfo,{867407d5-10e0-43a0-bc81-a324740534ca},0,-1,1
+50,nsIDirectoryServiceProvider,{bbf8cab0-d43a-11d3-8cc2-00609792278c},0,-1,1
+51,nsIX509Cert,{f0980f60-ee3d-11d4-998b-00b0d02354a0},0,-1,1
+52,jsdIContextEnumerator,{912e342a-1dd2-11b2-b09f-cf3af38c15f0},0,-1,1
+53,nsIRDFNode,{0f78da50-8321-11d2-8eac-00805f29f370},0,-1,1
+54,nsIDOMSVGDescElement,{56f539b7-0b3d-4bac-b60d-9efe220216ea},0,-1,1
+55,nsIDOMCSSRule,{a6cf90c1-15b3-11d2-932e-00805f8add32},0,-1,1
+56,nsIProxyInfo,{3fe9308b-1608-4fa0-933c-c5ec2c6175fd},0,-1,1
+57,nsIDOMHTMLLinkElement,{a6cf9088-15b3-11d2-932e-00805f8add32},0,-1,1
+58,nsISupportsPRUint32,{e01dc470-4a1c-11d3-9890-006008962422},0,-1,1
+59,nsIDOMXMLDocument,{8816d003-e7c8-4065-8827-829b8d07b6e0},0,-1,1
+60,nsIDOMSVGImageElement,{43ae4efe-2610-4cce-8242-279e556a78fa},0,-1,1
+61,nsIUrlClassifierDBServiceWorker,{2af84c09-269e-4fc2-b28f-af56717db118},0,-1,1
+62,nsIXSLTProcessorObsolete,{3fbff728-2d20-11d3-aef3-00108300ff91},0,-1,1
+63,nsIWebBrowserSetup,{f15398a0-8018-11d3-af70-00a024ffc08c},0,-1,1
+64,nsIDOMHTMLParagraphElement,{a6cf90a1-15b3-11d2-932e-00805f8add32},0,-1,1
+65,nsIAssociatedContentSecurity,{8db92dde-799f-4d33-80f7-459cac800dc9},0,-1,1
+66,nsIRunnable,{4a2abaf0-6886-11d3-9382-00104ba0fd40},0,-1,1
+67,nsIDirectoryService,{57a66a60-d43a-11d3-8cc2-00609792278c},0,-1,1
+68,extIExtension,{10cee02c-f6e0-4d61-ab27-c16572b18c46},0,-1,1
+69,nsIDNSListener,{41466a9f-f027-487d-a96c-af39e629b8d2},0,-1,1
+70,nsIPK11TokenDB,{4ee28c82-1dd2-11b2-aabf-bb4017abe395},0,-1,1
+71,nsIAccessibleText,{0f4633b1-550c-4b50-8c04-0eb1005eef2f},0,-1,1
+72,nsICommandLineValidator,{5ecaa593-7660-4a3a-957a-92d5770671c7},0,-1,1
+73,nsICookieManager,{aaab6710-0f2c-11d5-a53b-0010a401eb10},0,-1,1
+74,nsPIDNSService,{a26c5b45-7707-4412-bbc1-2462b890848d},0,-1,1
+75,nsIMIMEHeaderParam,{ddbbdfb8-a1c0-4dd5-a31b-5d2a7a3bb6ec},0,-1,1
+76,xpcIJSWeakReference,{5b776cd4-952b-45a2-b363-84e99e8fe608},0,-1,1
+77,mozIPersonalDictionary,{7ef52eaf-b7e1-462b-87e2-5d1dbaca9048},0,-1,1
+78,nsIInstallLocation,{32a74707-ec7c-af19-f4d8-d0cd8cb6a948},0,-1,1
+79,nsISerializable,{91cca981-c26d-44a8-bebe-d9ed4891503a},0,-1,1
+80,imgIContainerObserver,{53102f15-0f53-4939-957e-aea353ad2700},0,-1,1
+81,nsIStringEnumerator,{50d3ef6c-9380-4f06-9fb2-95488f7d141c},0,-1,1
+82,nsICipherInfoService,{766d47cb-6d8c-4e71-b6b7-336917629a69},0,-1,1
+83,nsIDOMSerializer,{9fd4ba15-e67c-4c98-b52c-7715f62c9196},0,-1,1
+84,nsICacheMetaDataVisitor,{22f9a49c-3cf8-4c23-8006-54efb11ac562},0,-1,1
+85,nsIDownloadManagerUI,{ca7663d5-69e3-4c4a-b754-f462bd36b05f},0,-1,1
+86,nsIPKCS11Slot,{c2d4f296-ee60-11d4-998b-00b0d02354a0},0,-1,1
+87,nsIGeneratingKeypairInfoDialogs,{11bf5cdc-1dd2-11b2-ba6a-c76afb326fa1},0,-1,1
+88,jsdIEphemeral,{46f1e23e-1dd2-11b2-9ceb-8285f2e95e69},0,-1,1
+89,nsIWorker,{daf945c3-8d29-4724-8939-dd383f7d27a7},0,-1,1
+90,nsIPrompt,{a63f70c0-148b-11d3-9333-00104ba0fd40},0,-1,1
+91,nsIAuthPromptAdapterFactory,{60e46383-bb9a-4860-8962-80d9c5c05ddc},0,-1,1
+92,nsIAlertsService,{e177399e-2e31-4019-aed3-cba63ce9fa99},0,-1,1
+93,nsIUrlClassifierCallback,{4ca27b6b-a674-4b3d-ab30-d21e2da2dffb},0,-1,1
+94,nsIApplicationCacheChannel,{9acfd21c-9c07-459f-8dae-ed2ffba23ddc},0,-1,1
+95,nsISessionStore_MOZILLA_1_9_1,{7f750b1a-35b7-11de-b025-b7deb5eac8bf},0,-1,1
+96,nsIXULBuilderListener,{ac46be8f-c863-4c23-84a2-d0fcc8dfa9f4},0,-1,1
+97,nsIDownloader,{fafe41a9-a531-4d6d-89bc-588a6522fb4e},0,-1,1
+98,fuelIApplication,{fe74cf80-aa2d-11db-abbd-0800200c9a66},0,-1,1
+99,nsIPrefLocalizedString,{ae419e24-1dd1-11b2-b39a-d3e5e7073802},0,-1,1
+100,nsIOutputStream,{0d0acd2a-61b4-11d4-9877-00c04fa0cf4a},0,-1,1
+101,nsIDOMCounter,{31adb439-0055-402d-9b1d-d5ca94f3f55b},0,-1,1
+102,nsIHTTPHeaderListener,{ea51e0b8-871c-4b85-92da-6f400394c5ec},0,-1,1
+103,nsIUnicodeNormalizer,{b43a461f-1bcf-4329-820b-66e48c979e14},0,-1,1
+104,nsIDOMSVGTransformList,{cee0a9d4-8554-4bf6-bf9b-7d0cebb4269d},0,-1,1
+105,nsISecureBrowserUI,{081e31e0-a144-11d3-8c7c-00609792278c},0,-1,1
+106,nsIAuthenticationInfo,{078a1b99-6be2-4a57-a749-378f4a506097},0,-1,0
+107,nsICertPickDialogs,{51d59b08-1dd2-11b2-ad4a-a51b92f8a184},0,-1,1
+108,nsIToolkit,{18032bd0-b265-11d1-aa2a-000000000000},0,-1,0
+109,nsISupportsFloat,{abeaa390-4ac0-11d3-baea-00805f8a5dd7},0,-1,1
+110,nsIDOMHTMLSelectElement,{a6cf9090-15b3-11d2-932e-00805f8add32},0,-1,1
+111,nsIObjectOutputStream,{92c898ac-5fde-4b99-87b3-5d486422094b},0,-1,1
+112,nsIContextMenuInfo,{2f977d56-5485-11d4-87e2-0010a4e75ef2},0,-1,1
+113,nsIMultiPartChannel,{ba78db7b-b88c-4b76-baf9-3c2296a585ae},0,-1,1
+114,nsIUnicharLineInputStream,{67f42475-ba80-40f8-ac0b-649c89230184},0,-1,1
+115,nsIDOMSVGTransformable,{b81f6e37-1842-4534-a546-1ab86e59a3c6},0,-1,1
+116,nsIDOMSVGAnimatedNumberList,{93ebb030-f82d-4f8e-b133-d1b5abb73cf3},0,-1,1
+117,nsITokenDialogs,{a1cbc159-468c-495d-8068-61dd538cbcca},0,-1,1
+118,nsILoginManager,{9c78bfc1-422b-4f4f-ba09-f7eb3c4e72b2},0,-1,1
+119,nsIDOMDocumentCSS,{39f76c23-45b2-428a-9240-a981e5abf148},0,-1,1
+120,nsIAccessibleTreeCache,{1dde5c3b-bede-43d1-aabf-dabc461113bd},0,-1,0
+121,nsITransportSecurityInfo,{0d0a6b62-d4a9-402e-a197-6bc6e358fec9},0,-1,1
+122,nsIIdleService,{cc52f19a-63ae-4a1c-9cc3-e79eace0b471},0,-1,1
+123,nsITextToSubURI,{8b042e24-6f87-11d3-b3c8-00805f8a6670},0,-1,1
+124,nsIDOMHTMLFrameElement,{a6cf90b9-15b3-11d2-932e-00805f8add32},0,-1,1
+125,nsITokenPasswordDialogs,{be26b580-1dd1-11b2-9946-c598d0d07727},0,-1,1
+126,nsIDataSignatureVerifier,{0a84b3d5-6ba9-432d-89da-4fbd0b0f2aec},0,-1,1
+127,jsdIExecutionHook,{9a7b6ad0-1dd1-11b2-a789-fcfae96356a2},0,-1,1
+128,nsINavBookmarkObserver,{f9828ba8-9c70-4d95-b926-60d9e4378d7d},0,-1,1
+129,nsIDOMPopupBlockedEvent,{05be571f-c3ea-4959-a340-c57b1591ae4b},0,-1,1
+130,nsIFeedWriter,{67003393-018c-4e96-af10-c6c51a049fad},0,-1,1
+131,nsIDOMSVGFECompositeElement,{6ff3c539-1a3b-4a3f-8acd-354d349eb7fc},0,-1,1
+132,nsIXPIProgressDialog,{ce8f744e-d5a5-41b3-911f-0fee3008b64e},0,-1,1
+133,nsIDOMStorageWindow_1_9_1,{b5e1b190-5e0d-4a77-a3df-fd7762110e23},0,-1,1
+134,nsISupportsChar,{e2b05e40-4a1c-11d3-9890-006008962422},0,-1,1
+135,nsISelectionPrivate,{b416c692-eeb8-4186-addd-c444e81b68e5},0,-1,1
+136,nsIXPCConstructor,{c814ca20-e0dc-11d3-8f5f-0010a4e73d9a},0,-1,1
+137,nsIDOMSVGZoomEvent,{339a8c7a-552e-4cbc-8d96-8370a3939358},0,-1,1
+138,nsICancelable,{d94ac0a0-bb18-46b8-844e-84159064b0bd},0,-1,1
+139,nsIDOMHTMLCanvasElement,{d87394af-d31a-484e-8b7c-75381045384d},0,-1,1
+140,nsIJARChannel,{6e6cc56d-51eb-4299-a795-dcfd1229ab3d},0,-1,1
+141,nsIFeedProgressListener,{ebfd5de5-713c-40c0-ad7c-f095117fa580},0,-1,1
+142,nsIDOMLSSerializerFilter,{b9b6ec85-f69f-4a5a-a96a-8a7a8f07e2b4},0,-1,1
+143,nsIBinaryOutputStream,{204ee610-8765-11d3-90cf-0040056a906e},0,-1,1
+144,nsIDOMDOMStringList,{0bbae65c-1dde-11d9-8c46-000a95dc234c},0,-1,1
+145,nsIImageLoadingContent,{7744c6d3-5c60-4b7b-a526-4fe9d5ac7e97},0,-1,1
+146,nsIExceptionService,{35a88f54-f267-4414-92a7-191f6454ab52},0,-1,1
+147,nsIDOMNSDataTransfer_MOZILLA_1_9_1,{a3d50078-13cf-4bef-b673-c3f25a41b9ca},0,-1,1
+148,nsIStreamBufferAccess,{ac923b72-ac87-4892-ac7a-ca385d429435},0,-1,0
+149,nsIThreadInternal,{f89b5063-b06d-42f8-bf23-4dfcf2d80d6a},0,-1,1
+150,nsIDOMCSSMediaRule,{a6cf90bc-15b3-11d2-932e-00805f8add32},0,-1,1
+151,imgIDecoder,{9eebf43a-1dd1-11b2-953e-f1782f4cbad3},0,-1,1
+152,nsIRDFInMemoryDataSource,{17c4e0aa-1dd2-11b2-8029-bf6f668de500},0,-1,1
+153,nsIFeed,{3b8aae33-80e2-4efa-99c8-a6c5b99f76ea},0,-1,1
+154,nsIAccessibleProvider,{3f7f9194-c625-4a85-8148-6d92d34897fa},0,-1,1
+155,nsIDOMHTMLPreElement,{a6cf90a4-15b3-11d2-932e-00805f8add32},0,-1,1
+156,nsIDOMMouseScrollEvent,{f172af88-48c3-4989-b814-60449823fc7d},0,-1,1
+157,nsIRDFXMLSink,{eb1a5d31-ab33-11d2-8ec6-00805f29f370},0,-1,1
+158,nsIPluginStreamInfo,{ed7d4ca0-b005-11d2-adaa-00805f6dec49},0,-1,0
+159,gfxIImageFrame,{9c37930b-cadd-453c-89e1-9ed456715b9c},0,-1,1
+160,nsIAccessibleSelectable,{34d268d6-1dd2-11b2-9d63-83a5e0ada290},0,-1,1
+161,nsPICommandUpdater,{b135f602-0bfe-11d5-a73c-f0e420e8293c},0,-1,1
+162,nsIDOMDocumentType,{a6cf9077-15b3-11d2-932e-00805f8add32},0,-1,1
+163,nsIExternalProtocolService,{70f93b7a-3ec6-4bcb-b093-92d9984c9f83},0,-1,1
+164,nsIPrivateBrowsingService,{49d6f133-80c0-48c7-876d-0b70bbfd0289},0,-1,1
+165,nsIPluginInstancePeer2_1_9_1_BRANCH,{79a2d210-55e4-4687-bd87-64b10c2466cc},0,-1,0
+166,nsIUTF8ConverterService,{249f52a3-2599-4b00-ba40-0481364831a2},0,-1,1
+167,nsIPluginInstancePeer,{4b7cea20-019b-11d2-815b-006008119d7a},0,-1,0
+168,nsIDOMDOMException,{a6cf910a-15b3-11d2-932e-00805f8add32},0,-1,1
+169,inIDOMView,{fbb67442-27a3-483c-8eb2-29c3eed7514c},0,-1,1
+170,nsIStreamConverter,{0b6e2c69-5cf5-48b0-9dfd-c95950e2cc7b},0,-1,1
+171,nsIContentViewerContainer,{ea2ce7a0-5c3d-11d4-90c2-0050041caf44},0,-1,1
+172,nsIAppStartup,{6799abed-4721-4f51-9304-d1a2ea1df5d5},0,-1,1
+173,nsICookie2,{8587f4e0-870c-11dd-ad8b-0800200c9a66},0,-1,1
+174,nsIPKCS11ModuleDB,{ff9fbcd7-9517-4334-b97a-ceed78909974},0,-1,1
+175,nsIBrowserInstance,{8af0fa40-598d-11d3-806a-00600811a9c3},0,-1,1
+176,nsIOCSPResponder,{96b2f5ae-4334-11d5-ba27-00108303b117},0,-1,1
+177,nsIAddonUpdateCheckListener,{c946119f-9e7c-41aa-a794-803148045350},0,-1,1
+178,nsIRandomGenerator,{2362d97a-747a-4576-8863-697667309209},0,-1,1
+179,nsIDocShell_MOZILLA_1_9_1,{460ba822-e664-4c38-9b08-98d2736473d7},0,-1,1
+180,nsIDOMCDATASection,{a6cf9071-15b3-11d2-932e-00805f8add32},0,-1,1
+181,nsIXPCScriptable,{5d309b93-e9b4-4374-bcd5-44245c83408f},0,-1,0
+182,nsIJVMConfigManager,{ca29fff1-a677-493c-9d80-3dc60432212b},0,-1,1
+183,nsIDOMXULContainerItemElement,{4650e55f-4777-4271-8b62-9603a7dd4614},0,-1,1
+184,nsISSLSocketControl,{a092097c-8386-4f1b-97b1-90eb70008c2d},0,-1,1
+185,nsISSLErrorListener,{99f8d972-bae4-414c-b39b-47587d3ded68},0,-1,1
+186,nsIContentHandler,{49439df2-b3d2-441c-bf62-866bdaf56fd2},0,-1,1
+187,nsIPKIParamBlock,{b6fe3d78-1dd1-11b2-9058-ced9016984c8},0,-1,1
+188,nsIMutableArray,{af059da0-c85b-40ec-af07-ae4bfdc192cc},0,-1,1
+189,nsIBufEntropyCollector,{485b87a8-5dd7-4b8d-8ea8-dee53201f899},0,-1,0
+190,nsIDOMFile,{4a17d83b-424f-43f3-8a7c-430f406921be},0,-1,1
+191,nsIHTMLEditor,{afc36593-5787-4420-93d9-b2c0ccbf0cad},0,-1,1
+192,nsIDOMSVGPathSegLinetoRel,{7933a81a-72c5-4489-ba64-5635f4c23063},0,-1,1
+193,nsIDownloadProgressListener,{7acb07ea-cac2-4c15-a3ad-23aaa789ed51},0,-1,1
+194,nsIDOMNamedNodeMap,{a6cf907b-15b3-11d2-932e-00805f8add32},0,-1,1
+195,nsISHistoryInternal,{7ca0fd71-437c-48ad-985d-11ce9e2429b4},0,-1,1
+196,nsIGnomeVFSService,{dea20bf0-4e4d-48c5-b932-dc3e116dc64b},0,-1,1
+197,nsITreeContentView,{5ef62896-0c0a-41f1-bb3c-44a60f5dfdab},0,-1,1
+198,nsIDOMSVGPathSegLinetoHorizontalRel,{8693268c-5180-43fd-acc3-5b9c09f43386},0,-1,1
+199,nsIXPIDialogService,{8cdd8baa-1dd2-11b2-909a-f0178da5c5ff},0,-1,1
+200,nsIDOMGeoPositionCallback,{527e8b53-6f29-4b6a-8d04-5c1666a4c4c1},0,-1,1
+201,nsIAutoCompleteSimpleResult,{f9841787-ad26-49e6-a2dd-ba9020ee1c64},0,-1,1
+202,nsIAccessibleEditableText,{52837507-202d-4e72-a482-5f068a1fd720},0,-1,1
+203,nsIWorkerMessagePort,{ab3725b8-3fca-40cc-a42c-92fb154ef01d},0,-1,1
+204,nsIAboutModule,{9575693c-60d9-4332-b6b8-6c29289339cb},0,-1,1
+205,nsIDOMNotation,{a6cf907e-15b3-11d2-932e-00805f8add32},0,-1,1
+206,nsIProxyObjectManager,{ee8ce1e3-0319-4bd9-8f70-7258b21c7733},0,-1,1
+207,nsIFileUtilities,{89a31ce0-019a-11d2-815b-006008119d7a},0,-1,0
+208,nsIAuthInformation,{0d73639c-2a92-4518-9f92-28f71fea5f20},0,-1,1
+209,nsIProfileLock,{50e07b0a-f338-4da3-bcdb-f4bb0db94dbe},0,-1,1
+210,nsIAutoCompleteSimpleResultListener,{004efdc5-1989-4874-8a7a-345bf2fa33af},0,-1,1
+211,nsINavHistoryObserver,{eacb76eb-3eeb-419b-a963-9b3a9d65f356},0,-1,1
+212,nsIFileOutputStream,{e6f68040-c7ec-11d3-8cda-0060b0fc14a3},0,-1,1
+213,nsIFind,{75125d55-37ee-4575-b9b5-f33bfa68c2a1},0,-1,1
+214,nsIXTFPrivate,{13ef3d54-1dd1-4a5c-a8d5-a04a327fb9b6},0,-1,1
+215,nsIPlaintextEditor,{1480e196-0d5c-40cf-8563-ed8a33eabcf2},0,-1,1
+216,nsIDOMNSHTMLSelectElement,{a6cf9105-15b3-11d2-932e-00805f8add32},0,-1,1
+217,nsIDOMHTMLModElement,{a6cf90a9-15b3-11d2-932e-00805f8add32},0,-1,1
+218,nsIDOMSVGPathSegLinetoVerticalAbs,{fd5ffb7b-7279-4c09-abfd-b733dc872e80},0,-1,1
+219,nsIPluginInputStream,{af160530-542a-11d2-8164-006008119d7a},0,-1,0
+220,nsICRLInfo,{c185d920-4a3e-11d5-ba27-00108303b117},0,-1,1
+221,nsIDOMCSSMozDocumentRule,{4eb9adac-afaf-4b8a-8640-7340863c1587},0,-1,1
+222,nsIAccessibleRelation,{f42a1589-70ab-4704-877f-4a9162bbe188},0,-1,1
+223,nsIDOMSVGEllipseElement,{5d1cd1e6-4a14-4056-acc0-2f78c1672898},0,-1,1
+224,jsdIContext,{a2dd25a4-1dd1-11b2-bda6-ed525acd4c35},0,-1,1
+225,nsIDOMDocumentTraversal,{13f236c0-47f8-11d5-b6a3-009027446e84},0,-1,1
+226,nsIFeedProcessor,{8a0b2908-21b0-45d7-b14d-30df0f92afc7},0,-1,1
+227,nsIXTFAttributeHandler,{72152f7f-7e8d-43fd-8477-3f29ae8d240d},0,-1,1
+228,nsISupportsWeakReference,{9188bc86-f92e-11d2-81ef-0060083a0bcf},0,-1,1
+229,nsIDOMSVGElement,{e0be7cbb-81c1-4663-8f95-109d96a60b6b},0,-1,1
+230,nsIDOM3DocumentEvent,{090ecc19-b7cb-4f47-ae47-ed68d4926249},0,-1,1
+231,nsIRDFRemoteDataSource,{1d297320-27f7-11d3-be01-000064657374},0,-1,1
+232,nsIDOMSVGPathSegLinetoHorizontalAbs,{4a54a4d2-edef-4e19-9600-2330311000f4},0,-1,1
+233,nsIAsyncInputStream,{a5f255ab-4801-4161-8816-277ac92f6ad1},0,-1,1
+234,nsIDOMText,{a6cf9082-15b3-11d2-932e-00805f8add32},0,-1,1
+235,nsIDOMRect,{71735f62-ac5c-4236-9a1f-5ffb280d531c},0,-1,1
+236,nsICRLManager,{486755db-627a-4678-a21b-f6a63bb9c56a},0,-1,1
+237,nsIHttpEventSink,{9475a6af-6352-4251-90f9-d65b1cd2ea15},0,-1,1
+238,nsIX509Cert3,{399004d8-b8c7-4eb9-8362-d99f4c0161fd},0,-1,1
+239,nsISearchEngine,{803e510b-4b27-4ba2-a16d-bb5fa953c166},0,-1,1
+240,nsIUrlListManagerCallback,{fa4caf12-d057-4e7e-81e9-ce066ceee90b},0,-1,1
+241,nsIDOMXPathNamespace,{75506f87-b504-11d5-a7f2-ca108ab8b6fc},0,-1,1
+242,nsIDOMHTMLHRElement,{a6cf90a8-15b3-11d2-932e-00805f8add32},0,-1,1
+243,fuelIBookmarkRoots,{c9a80870-eb3c-11dc-95ff-0800200c9a66},0,-1,1
+244,nsIXULTemplateRuleFilter,{819cd1ed-8010-42e1-a8b9-778b726a1ff3},0,-1,1
+245,nsIWebBrowserFocus,{9c5d3c58-1dd1-11b2-a1c9-f3699284657a},0,-1,1
+246,nsISAXErrorHandler,{e02b6693-6cca-11da-be43-001422106990},0,-1,1
+247,nsIHTMLObjectResizer,{8b396020-69d3-451f-80c1-1a96a7da25a9},0,-1,1
+248,nsIXMLContentBuilder,{e9c4cd4f-cd41-43d0-bf3b-48abb9cde90f},0,-1,1
+249,nsIInputStreamCallback,{d1f28e94-3a6e-4050-a5f5-2e81b1fc2a43},0,-1,1
+250,nsIUpdateCheckListener,{8cbceb6e-8e27-46f2-8808-444c6499f836},0,-1,1
+251,nsIClipboard,{38984945-8674-4d04-b786-5c0ca9434457},0,-1,1
+252,nsIEditorMailSupport,{fdf23301-4a94-11d3-9ce4-9960496c41bc},0,-1,1
+253,inIDOMUtils,{78fd16c2-bdfb-4b1d-8738-d536d0a8f430},0,-1,1
+254,nsIToolkitProfileService,{9b434f48-438c-4f85-89de-b7f321a45341},0,-1,1
+255,nsIRandomAccessIterator,{9bd6fdb0-1dd1-11b2-9101-d15375968230},0,-1,1
+256,nsITransactionListener,{58e330c4-7b48-11d2-98b9-00805f297d89},0,-1,1
+257,nsICookiePermission,{4b1a775d-f6d3-4389-be2e-9dfbaf2ab47b},0,-1,1
+258,nsICache,{ec1c0063-197d-44bb-84ba-7525d50fc937},0,-1,1
+259,nsIContentPolicy,{344f9cb0-9a17-44c5-ab96-ee707884266c},0,-1,1
+260,nsIWyciwygChannel,{89b0674a-9e2f-4124-9b59-481444be841d},0,-1,1
+261,nsIHelperAppLauncher,{d9a19faf-497b-408c-b995-777d956b72c0},0,-1,1
+262,nsITransaction,{58e330c1-7b48-11d2-98b9-00805f297d89},0,-1,1
+263,nsIRDFContainerUtils,{d4214e91-fb94-11d2-bdd8-00104bde6048},0,-1,1
+264,nsIRelativeFilePref,{2f977d4e-5485-11d4-87e2-0010a4e75ef2},0,-1,1
+265,nsIDOMClientRect,{b2f824c4-d9d3-499b-8d3b-45c8245497c6},0,-1,1
+266,nsINavHistoryQueryResultNode,{ea17745a-1852-4155-a98f-d1dd1763b3df},0,-1,1
+267,nsIDOMDocumentStyle,{3d9f4973-dd2e-48f5-b5f7-2634e09eadd9},0,-1,1
+268,nsIURIContentListener,{94928ab3-8b63-11d3-989d-001083010e9b},0,-1,1
+269,nsIRDFObserver,{3cc75360-484a-11d2-bc16-00805f912fe7},0,-1,1
+270,nsIDOMNSDocument,{533a8131-8d0c-4ebf-990b-7fad7cd514ee},0,-1,1
+271,nsIWebBrowser,{69e5df00-7b8b-11d3-af61-00a024ffc08c},0,-1,1
+272,nsIRDFXMLSource,{4da56f10-99fe-11d2-8ebb-00805f29f370},0,-1,1
+273,nsIDOMElement,{a6cf9078-15b3-11d2-932e-00805f8add32},0,-1,1
+274,nsIGeolocationRequest,{f2aefde1-8e38-48b3-bbb8-bd6c4ae1ac8a},0,-1,1
+275,nsIDOMSVGTextElement,{6d43b1b4-efb6-426d-9e65-4420c3e24688},0,-1,1
+276,jsdIFilter,{05593438-1b83-4517-864f-3cea3d37a266},0,-1,1
+277,nsIDOMCSSStyleRule,{a6cf90bf-15b3-11d2-932e-00805f8add32},0,-1,1
+278,nsIDOMClientInformation,{f8bbf8c3-c47b-465a-a221-22824449f689},0,-1,1
+279,nsIContentViewer,{05b290ac-d880-4900-bb1f-2211b5f8accc},0,-1,1
+280,nsIDOMJSWindow,{14efb76c-5bd6-449e-b36f-0cbd22981f20},0,-1,1
+281,nsIDOMSVGAnimatedLengthList,{bfa6e42b-bc9d-404d-8688-729fdbfff801},0,-1,1
+282,nsIStreamConverterService,{f2b1ab53-f0bd-4adb-9365-e59b1701a258},0,-1,1
+283,nsIFastLoadReadControl,{652ecec6-d40b-45b6-afef-641d6c63a35b},0,-1,1
+284,nsIWebBrowserChrome2,{2585a7b1-7b47-43c4-bf17-c6bf84e09b7b},0,-1,1
+285,nsIBidiKeyboard,{0d8f8f10-c92d-4a6a-b2bb-e1921f3f4dda},0,-1,1
+286,nsIXPConnectWrappedJS,{bed52030-bca6-11d2-ba79-00805f8a5dd7},0,-1,0
+287,nsIHTMLInlineTableEditor,{eda2e65c-a758-451f-9b05-77cb8de74ed2},0,-1,1
+288,nsIAutoCompleteController,{6f08d134-8536-4b28-b456-d150fbaa66a9},0,-1,1
+289,nsIDOMSVGAnimatedPreserveAspectRatio,{afcd7cd4-d74d-492f-b3b1-d71bfa36874f},0,-1,1
+290,nsIPrefBranch,{56c35506-f14b-11d3-99d3-ddbfac2ccf65},0,-1,1
+291,nsIDOMPlugin,{f6134681-f28b-11d2-8360-c90899049c3c},0,-1,1
+292,nsISelectionListener,{a6cf90e2-15b3-11d2-932e-00805f8add32},0,-1,1
+293,nsIWebHandlerApp,{7521a093-c498-45ce-b462-df7ba0d882f6},0,-1,1
+294,nsICacheService,{98dd0187-aad4-4cab-82c5-1adddef3629d},0,-1,1
+295,jsdIScriptHook,{ae89a7e2-1dd1-11b2-8c2f-af82086291a5},0,-1,1
+296,nsIWindowDataSource,{3722a5b9-5323-4ed0-bb1a-8299f27a4e89},0,-1,1
+297,nsIDOMHTMLByteRanges,{992c540c-4d81-42df-80a6-f71ede2b59d8},0,-1,1
+298,nsIStreamLoaderObserver,{359f7990-d4e9-11d3-a1a5-0050041caf44},0,-1,1
+299,nsIDOMHTMLElement,{a6cf9085-15b3-11d2-932e-00805f8add32},0,-1,1
+300,nsIXTFElementFactory,{27c10dca-2efc-416b-ae36-9794380a661e},0,-1,1
+301,nsIXPCScriptNotify,{b804504d-0025-4d6b-8ced-d94e41102a7f},0,-1,0
+302,nsIDOMHTMLMediaElement,{23fb201a-556d-4054-9885-6437e8910296},0,-1,1
+303,nsICharsetConverterManager,{f5323a76-c8f7-4c65-8d0c-1250e969c7d5},0,-1,1
+304,fuelIBookmarkFolder,{9f42fe20-52de-4a55-8632-a459c7716aa0},0,-1,1
+305,nsIXPointerResult,{d3992637-f474-4b65-83ed-323fe69c60d2},0,-1,1
+306,nsIGeolocationPrompt,{2300c895-1bee-4297-912c-a57082f3e936},0,-1,1
+307,nsIInputStreamTee,{44e8b2c8-1ecb-4a63-8b23-3e3500c34f32},0,-1,1
+308,nsIDOMNodeSelector,{7cebc153-168a-416c-ba5a-56a8c2ddb2ec},0,-1,1
+309,nsIJVMManager,{a1e5ed50-aa4a-11d1-85b2-00805f0e4dfe},0,-1,1
+310,nsIWritableVariant,{5586a590-8c82-11d5-90f3-0010a4e73d9a},0,-1,1
+311,nsIFontEnumerator,{924d98d9-3518-4cb4-8708-c74fe8e3ec3c},0,-1,1
+312,nsISound,{b01adad7-d937-4738-8508-3bd5946bf9c8},0,-1,1
+313,nsIDOMNode,{a6cf907c-15b3-11d2-932e-00805f8add32},0,-1,1
+314,nsIDOMSVGPathSegCurvetoCubicSmoothAbs,{5fa8fea8-bdd1-4315-ac44-a39b3ff347b5},0,-1,1
+315,nsIDOMDOMConfiguration,{cfb5b821-9016-4a79-9d98-87b57c3ea0c7},0,-1,1
+316,nsIPKCS11Module,{8a44bdf9-d1a5-4734-bd5a-34ed7fe564c2},0,-1,1
+317,nsIFormatConverter,{948a0023-e3a7-11d2-96cf-0060b0fb9956},0,-1,1
+318,nsIChannel,{c63a055a-a676-4e71-bf3c-6cfa11082018},0,-1,1
+319,nsIDOMDocumentFragment,{a6cf9076-15b3-11d2-932e-00805f8add32},0,-1,1
+320,nsIProtocolProxyService2,{dbd9565d-29b1-437a-bff5-2fc339e2c5df},0,-1,1
+321,nsIDOMParser,{5677f36e-1842-4c6f-a39c-2e5576ab8b40},0,-1,1
+322,imgILoader,{d2f50c69-1064-4ce3-a92d-01dc5f5b4842},0,-1,1
+323,nsIDOMCSSPageRule,{a6cf90bd-15b3-11d2-932e-00805f8add32},0,-1,1
+324,nsIDOMSVGAnimatedTransformList,{fd54c8c4-2eb4-4849-8df6-79985c2491da},0,-1,1
+325,nsISliderListener,{e5b3074e-ee18-4538-83b9-2487d90a2a34},0,-1,1
+326,nsIWindowCreator2,{f673ec81-a4b0-11d6-964b-eb5a2bf216fc},0,-1,1
+327,nsIBrowserGlue,{781df699-17dc-4237-b3d7-876ddb7085e3},0,-1,1
+328,nsIExternalProtocolHandler,{0e61f3b2-34d7-4c79-bfdc-4860bc7341b7},0,-1,1
+329,nsIXTFElement,{4f144387-796d-4baf-8641-5db45dba1808},0,-1,1
+330,nsIFilePicker,{d24ef0aa-d555-4117-84af-9cbbb7406909},0,-1,1
+331,nsIPropertyElement,{283ee646-1aef-11d4-98b3-00c04fa0ce9a},0,-1,1
+332,nsIDOMGeoPositionErrorCallback,{7d9b09d9-4843-43eb-a7a7-67f7dda6b3c4},0,-1,1
+333,nsIStandardURL,{babd6cca-ebe7-4329-967c-d6b9e33caa81},0,-1,1
+334,nsIRDFPurgeableDataSource,{951700f0-fed0-11d2-bdd9-00104bde6048},0,-1,1
+335,nsIExtendedExpatSink,{0c2dc80f-7aa4-467a-9454-b89dba0e0779},0,-1,1
+336,nsIWorkerMessageEvent,{508f2d49-e9a0-4fe8-bd33-321820173b4a},0,-1,1
+337,nsISeekableStream,{8429d350-1040-4661-8b71-f2a6ba455980},0,-1,1
+338,nsIHandlerService,{53f0ad17-ec62-46a1-adbc-efccc06babcd},0,-1,1
+339,nsIScriptSecurityManager,{f8e350b9-9f31-451a-8c8f-d10fea26b780},0,-1,1
+340,nsIWindowMediator,{0659cb81-faad-11d2-8e19-b206620a657c},0,-1,1
+341,nsIMicrosummary,{6867dc21-077f-4462-937d-cd8b7c680e0c},0,-1,1
+342,nsIDocumentLoaderFactory,{5e7d2967-5a07-444f-95d5-25b533252d38},0,-1,1
+343,nsIProxiedChannel,{6238f134-8c3f-4354-958f-dfd9d54a4446},0,-1,1
+344,nsIStreamListenerTee,{fb683e76-d42b-41a4-8ae6-65a6c2b146e5},0,-1,1
+345,nsIDOMNSCSS2Properties,{e7245a21-3f46-4e67-82bf-a9b326fe74ee},0,-1,1
+346,nsIProcess2,{7d362c71-308e-4724-b1eb-8451fe133026},0,-1,1
+347,nsIFeedGenerator,{0fecd56b-bd92-481b-a486-b8d489cdd385},0,-1,1
+348,nsISyncStreamListener,{7e1aa658-6e3f-4521-9946-9685a169f764},0,-1,1
+349,nsIDOMLSParserFilter,{10e8893d-ddf5-45d1-8872-615d72065fb4},0,-1,1
+350,nsISearchContext,{31aba0f0-2d93-11d3-8069-00600811a9c3},0,-1,1
+351,nsIScriptError,{b0196fc7-1913-441a-882a-453c0d8b89b8},0,-1,1
+352,nsIXPConnectJSObjectHolder,{8916a320-d118-11d3-8f3a-0010a4e73d9a},0,-1,0
+353,nsIXULWindow,{c175a596-ee13-420a-aa74-13ad3a14deb1},0,-1,1
+354,nsIEventTarget,{4e8febe4-6631-49dc-8ac9-308c1cb9b09c},0,-1,1
+355,nsIURLParser,{7281076d-cf37-464a-815e-698235802604},0,-1,1
+356,nsIGeolocationUpdate,{b89d7227-9f04-4236-a582-25a3f2779d72},0,-1,1
+357,nsIX509CertValidity,{e701dfd8-1dd1-11b2-a172-ffa6cc6156ad},0,-1,1
+358,extIExtensions,{de281930-aa5a-11db-abbd-0800200c9a66},0,-1,1
+359,nsIModule,{7392d032-5371-11d3-994e-00805fd26fee},0,-1,1
+360,nsINativeAppSupport,{5fdf8480-1f98-11d4-8077-00600811a9c3},0,-1,1
+361,nsIDOMSVGMetadataElement,{94558064-140c-41a1-9cc9-4e9cdbf5c124},0,-1,1
+362,nsINavHistoryQueryOptions,{a46c132e-35f3-4e1e-bb3d-4e3043657248},0,-1,1
+363,nsIRDFDate,{e13a24e1-c77a-11d2-80be-006097b76b8e},0,-1,1
+364,nsIDOMSVGFEDisplacementMapElement,{80e1ea9c-eff3-490a-8c98-918963d2e7e9},0,-1,1
+365,nsIDocCharset,{9c18bb4e-1dd1-11b2-bf91-9cc82c275823},0,-1,1
+366,nsISocketTransport,{ef3f4993-cfbc-4e5a-9509-16deafe16549},0,-1,1
+367,nsIASN1Object,{ba8bf582-1dd1-11b2-898c-f40246bc9a63},0,-1,1
+368,nsIPrintProgress,{7e46bc35-fb7d-4b45-ab35-82fd61015380},0,-1,1
+369,nsIDOMXULElement,{30a4a815-b42a-4f0b-9c10-1e7f727cd135},0,-1,1
+370,nsIXPCWrappedJSObjectGetter,{254bb2e0-6439-11d4-8fe0-0010a4e73d9a},0,-1,1
+371,nsIDOMMimeType,{f6134682-f28b-11d2-8360-c90899049c3c},0,-1,1
+372,nsIDOMMouseEvent,{ff751edc-8b02-aae7-0010-8301838a3123},0,-1,1
+373,nsIAccessibleEvent,{ba448f0e-a761-48c8-a0f5-1f25e23d4fe4},0,-1,1
+374,nsIDOMXULLabelElement,{c987629e-6370-45f5-86ec-aa765fa861cd},0,-1,1
+375,nsIDOMNSRGBAColor,{742dc816-5134-4214-adfa-cad9dd3377cd},0,-1,1
+376,nsIApplicationUpdateService,{9849c4bf-5197-4d22-baa8-e3b44a1703d2},0,-1,1
+377,nsIInterfaceRequestor,{033a1470-8b2a-11d3-af88-00a024ffc08c},0,-1,1
+378,nsINestedURI,{6de2c874-796c-46bf-b57f-0d7bd7d6cab0},0,-1,1
+379,nsIServiceManager,{8bb35ed9-e332-462d-9155-4a002ab5c958},0,-1,1
+380,nsIDOMHTMLOptGroupElement,{a6cf9091-15b3-11d2-932e-00805f8add32},0,-1,1
+381,nsICommandManager,{080d2001-f91e-11d4-a73c-f9242928207c},0,-1,1
+382,nsIIDNService,{a592a60e-3621-4f19-a318-2bf233cfad3e},0,-1,1
+383,nsIDOMSVGFEOffsetElement,{c080f191-b22c-4fc0-85d5-a79dc3fa7ec8},0,-1,1
+384,nsIDOMHTMLTitleElement,{a6cf9089-15b3-11d2-932e-00805f8add32},0,-1,1
+385,nsINavHistoryObserver_MOZILLA_1_9_1_ADDITIONS,{c1945447-a94f-4134-80c5-7fe48ef00178},0,-1,1
+386,nsIMemoryReporter,{d298b942-3e66-4cd3-9ff5-46abc69147a7},0,-1,1
+387,nsITraceRefcnt,{273dc92f-0fe6-4545-96a9-21be77828039},0,-1,0
+388,nsITimelineService,{93276790-3daf-11d5-b67d-000064657374},0,-1,1
+389,nsIUnicharOutputStream,{2d00b1bb-8b21-4a63-bcc6-7213f513ac2e},0,-1,1
+390,nsIAppShell,{501403e9-a091-4780-ba55-cfd1e21287a1},0,-1,0
+391,nsIDataType,{4d12e540-83d7-11d5-90ed-0010a4e73d9a},0,-1,1
+392,nsIChromeRegistry,{249fb5ad-ae29-4e2c-a728-ba5cf464d188},0,-1,1
+393,nsIJSON,{45464c36-efde-4cb5-8e00-07480533ff35},0,-1,1
+394,nsINavHistoryVisitResultNode,{8e2c5a86-b33d-4fa6-944b-559af7e95fcd},0,-1,1
+395,nsIDOMSVGGradientElement,{988b2de4-137b-4bb8-a15e-fe94038e9cf3},0,-1,1
+396,nsIDOMSVGFEImageElement,{3250f5c9-9c76-4e77-96d8-5f0cc85f41c4},0,-1,1
+397,nsIInputStreamPump,{400f5468-97e7-4d2b-9c65-a82aecc7ae82},0,-1,1
+398,nsIDOMLSParser,{2a31a3a0-be68-40af-9f64-914192f0fba2},0,-1,1
+399,nsIDOMCSSStyleDeclaration,{a6cf90be-15b3-11d2-932e-00805f8add32},0,-1,1
+400,nsIOfflineCacheUpdateService,{6fd2030f-7b00-4102-a0e3-d73078821eb1},0,-1,1
+401,nsIRequest,{ef6bfbd2-fd46-48d8-96b7-9f8f0fd387fe},0,-1,1
+402,nsIJSIID,{e76ec564-a080-4705-8609-384c755ec91e},0,-1,1
+403,nsIProcess,{d573f1f3-fcdd-4dbe-980b-4ba79e6718dc},0,-1,1
+404,nsIDOMHTMLTableSectionElement,{a6cf90b5-15b3-11d2-932e-00805f8add32},0,-1,1
+405,nsIDirectoryEnumerator,{31f7f4ae-6916-4f2d-a81e-926a4e3022ee},0,-1,1
+406,imgICache,{f1b74aae-5661-4753-a21c-66dd644afebc},0,-1,1
+407,nsIDOMSVGZoomAndPan,{18967370-921a-4245-8158-a279b190abca},0,-1,1
+408,nsIContainerBoxObject,{35d4c04b-3bd3-4375-92e2-a818b4b4acb6},0,-1,1
+409,nsILoginManager_MOZILLA_1_9_1,{44ec4942-3678-11de-b4e6-47765a06a143},0,-1,1
+410,nsISupportsPRUint8,{dec2e4e0-4a1c-11d3-9890-006008962422},0,-1,1
+411,nsIDOMSVGStyleElement,{9af0d129-b366-4aa8-b7d8-8dce93148d91},0,-1,1
+412,nsIURILoader,{2f7e8051-f1c9-4bcc-8584-9cfd5849e343},0,-1,1
+413,nsIWindowCreator,{30465632-a777-44cc-90f9-8145475ef999},0,-1,1
+414,nsIEditorLogging,{4805e681-49b9-11d3-9ce4-ed60bd6cb5bc},0,-1,1
+415,nsIIdentityInfo,{e9da87b8-b87c-4bd1-a6bc-5a9a2c7f6d8d},0,-1,1
+416,nsITransferable,{8b5314bc-db01-11d2-96ce-0060b0fb9956},0,-1,1
+417,nsIDOMNSEventTarget,{37ca0054-c715-42df-83c7-35c69e24a632},0,-1,1
+418,nsIEditingSession,{274cd32e-3675-47e1-9d8a-fc6504ded9ce},0,-1,1
+419,nsIAccessibilityService,{8160457f-7b1a-4779-a0ca-cea07d17194d},0,-1,0
+420,nsIDOMHTMLDocument,{a6cf9084-15b3-11d2-932e-00805f8add32},0,-1,1
+421,nsIStyleSheetService,{1f42a6a2-ab0a-45d4-8a96-396f58ea6c6d},0,-1,1
+422,nsIUrlClassifierUtils,{e4f0e59c-b922-48b0-a7b6-1735c1f96fed},0,-1,1
+423,jsdIValue,{b7964304-1dd1-11b2-ba20-cf4205772e9d},0,-1,1
+424,nsIDOMSVGFESpecularLightingElement,{49c38287-a7c2-4895-a630-86d2b45df23c},0,-1,1
+425,nsIUrlListManager,{9c5598ec-9986-40cf-af40-b5e0d817a3a0},0,-1,1
+426,nsIDOMStorageWindow,{b4f572fb-9ba5-480b-9361-c230863323e4},0,-1,1
+427,nsIPluginInstancePeer2,{e7d48c00-e1f1-11d2-8360-fbc8abc4ae7c},0,-1,0
+428,imgIRequest,{a297d3fa-5e0c-4e59-9f30-a01c9d4f3f8b},0,-1,1
+429,nsILocaleService,{c2edc848-4219-4440-abbf-98119882c83f},0,-1,1
+430,nsIPluginDocument,{e4be1d0a-9f24-4d69-bec5-245726ab85fb},0,-1,0
+431,nsIRDFCompositeDataSource,{96343820-307c-11d2-bc15-00805f912fe7},0,-1,1
+432,nsIRequestObserver,{fd91e2e0-1481-11d3-9333-00104ba0fd40},0,-1,1
+433,nsIDOMSVGFEComponentTransferElement,{4de6b44a-f909-4948-bc43-5ee2ca6de55b},0,-1,1
+434,nsIRecyclingAllocator,{d064a04c-9cee-4319-be31-64d565bccba9},0,-1,1
+435,nsISelectionController,{b5c3ffc4-f48a-4f25-86e1-4cf79db1bcbb},0,-1,1
+436,nsIDocShell_MOZILLA_1_9_1_SessionStorage,{b0534fdd-8a6c-4489-8c9e-471d7b2b2596},0,-1,1
+437,nsIDOMHTMLIFrameElement,{a6cf90ba-15b3-11d2-932e-00805f8add32},0,-1,1
+438,nsIHttpAuthManager,{7ce8e9d1-8b4b-4883-a307-66fe12a50153},0,-1,1
+439,nsIXULBrowserWindow,{67a601df-f091-4894-a2e2-2e6cfebb35ea},0,-1,1
+440,nsIDOMSVGPointList,{4c12af24-0fc2-4fe7-b71d-5d6b41d463c1},0,-1,1
+441,nsIUserInfo,{6c1034f0-1dd2-11b2-aa14-e6657ed7bb0b},0,-1,1
+442,nsIDOMHTMLVideoElement,{4e3f05a5-ca9b-4576-af7f-b1d4038e6eb3},0,-1,1
+443,nsICacheEntryDescriptor,{49c1a11d-f5d2-4f09-8262-551e64908ada},0,-1,1
+444,nsIHTMLAbsPosEditor,{91375f52-20e6-4757-9835-eb04fabe5498},0,-1,1
+445,nsIAutoCompleteObserver,{18c36504-9a4c-4ac3-8494-bd05e00ae27f},0,-1,1
+446,nsIFormHistory2,{5d7d84d1-9798-4016-bf61-a32acf09b29d},0,-1,1
+447,nsIAccessibleTextChangeEvent,{50a1e151-8e5f-4bcc-aaaf-a4bed1190e93},0,-1,1
+448,nsISecurityWarningDialogs,{1c399d06-1dd2-11b2-bc58-c87cbcacdb78},0,-1,1
+449,nsIImageDocument,{7b80eebc-c98e-4461-8bdb-6e3b6e828890},0,-1,1
+450,jsdIDebuggerService,{a074fcb4-73d7-4825-a4cd-7cbb1d6800b1},0,-1,1
+451,nsITransport,{d8786c64-eb49-4a0b-b42c-0936a745fbe8},0,-1,1
+452,nsIMutable,{321578d0-03c1-4d95-8821-021ac612d18d},0,-1,1
+453,jsdICallHook,{f102caf6-1dd1-11b2-bd43-c1dbacb95a98},0,-1,1
+454,nsIListBoxObject,{aa9def4e-2e59-412d-a6df-b76f52167795},0,-1,1
+455,nsIAccessibleScrollType,{05cd38b1-94b3-4cdf-8371-3935a9611405},0,-1,1
+456,nsICategoryManager,{3275b2cd-af6d-429a-80d7-f0c5120342ac},0,-1,1
+457,nsIBidirectionalIterator,{948defaa-1dd1-11b2-89f6-8ce81f5ebda9},0,-1,1
+458,nsIErrorService,{e72f94b2-5f85-11d4-9877-00c04fa0cf4a},0,-1,1
+459,nsIURIClassifier,{2de5c563-1203-43dd-a212-f5d56d530b6f},0,-1,1
+460,nsIWindowMediatorListener,{2f276982-0d60-4377-a595-d350ba516395},0,-1,1
+461,nsISHistoryListener,{3b07f591-e8e1-11d4-9882-00c04fa02f40},0,-1,1
+462,nsIEditor,{96b60ba0-634a-41e4-928e-78ab0b3c4b46},0,-1,1
+463,nsIAccessibleTableChangeEvent,{a9485c7b-5861-4695-8441-fab0235b205d},0,-1,1
+464,nsIDOMHistory,{896d1d20-b4c4-11d2-bd93-00805f8ae3f4},0,-1,1
+465,nsIZipEntry,{e1c028bc-c478-11da-95a8-00e08161165f},0,-1,1
+466,nsIWebContentHandlerRegistrar,{e6a75410-c93e-42bf-84ca-a5c3ec34a2f1},0,-1,1
+467,mozIStorageStatementWrapper,{eee6f7c9-5586-4eaf-b35c-dca987c4ffd1},0,-1,1
+468,nsIDOMNodeList,{a6cf907d-15b3-11d2-932e-00805f8add32},0,-1,1
+469,nsIUnicharInputStream,{d5e3bd80-6723-4b92-b0c9-22f6162fd94f},0,-1,1
+470,rdfITripleVisitor,{aafea151-c271-4505-9978-a100d292800c},0,-1,1
+471,nsIDOMDOMImplementationLS,{e2c8b03c-a49a-4923-81b0-ba9a86da0e21},0,-1,1
+472,nsIDOMAbstractView,{f51ebade-8b1a-11d3-aae7-0010830123b4},0,-1,1
+473,nsIPopupBoxObject,{a41af368-9f73-4d73-a058-49dd7e41f9ea},0,-1,1
+474,nsIWorkerErrorEvent,{73d82c1d-05de-49c9-a23b-7121ff09a67a},0,-1,1
+475,nsINavBookmarkObserver_MOZILLA_1_9_1_ADDITIONS,{76440c39-1085-4f2b-9535-5ba4658fcdad},0,-1,1
+476,nsIRDFLiteral,{e0c493d2-9542-11d2-8eb8-00805f29f370},0,-1,1
+477,nsIAccessible,{670fc322-14ec-4f3b-8279-9d62ab8895c0},0,-1,1
+478,nsIDOMCanvasPattern,{21dea65c-5c08-4eb1-ac82-81fe95be77b8},0,-1,1
+479,nsISupportsVoid,{464484f0-568d-11d3-baf8-00805f8a5dd7},0,-1,1
+480,nsIDOMCSSImportRule,{a6cf90cf-15b3-11d2-932e-00805f8add32},0,-1,1
+481,nsISecurityEventSink,{a71aee68-dd38-4736-bd79-035fea1a1ec6},0,-1,1
+482,nsIConsoleMessage,{41bd8784-1dd2-11b2-9553-8606958fffe1},0,-1,1
+483,imgILoad,{e6273acc-1dd1-11b2-a08b-824ad1b1628d},0,-1,1
+484,nsISAXLocator,{7a307c6c-6cc9-11da-be43-001422106990},0,-1,1
+485,nsIDOMHTMLSourceElement,{be281029-7dd9-4268-963e-96f5196acc19},0,-1,1
+486,nsIDOMSVGMaskElement,{fdd7039c-35b6-465a-b7a3-c98a815b583e},0,-1,1
+487,nsICookiePromptService,{72f8bb14-2810-4f38-8d0d-290c5401f54e},0,-1,1
+488,extIApplication,{e53d6610-7468-11dd-ad8b-0800200c9a66},0,-1,1
+489,nsIDOMHTMLCollection,{a6cf9083-15b3-11d2-932e-00805f8add32},0,-1,1
+490,nsIFeedPerson,{29cbd45f-f2d3-4b28-b557-3ab7a61ecde4},0,-1,1
+491,nsIDOMEvent,{a66b7b80-ff46-bd97-0080-5f8ae38add32},0,-1,1
+492,nsINavHistoryService,{437f539b-d541-4a0f-a200-6f9a6d45cce2},0,-1,1
+493,nsIMIMEInfo,{cd7083f8-5fe9-4248-bb09-0b0e2982fde8},0,-1,1
+494,nsIDOMHTMLBRElement,{a6cf90a5-15b3-11d2-932e-00805f8add32},0,-1,1
+495,nsIURIClassifierCallback,{8face46e-0c96-470f-af40-0037dcd797bd},0,-1,1
+496,nsICertificateDialogs,{a03ca940-09be-11d5-ac5d-000064657374},0,-1,1
+497,nsIInputIterator,{85585e12-1dd2-11b2-a930-f6929058269a},0,-1,1
+498,nsIGlobalHistory,{9491c383-e3c4-11d2-bdbe-0050040a9b44},0,-1,1
+499,mozIStorageStatementParams,{e65fe6e2-2643-463c-97e2-27665efe2386},0,-1,1
+500,fuelIWindow,{207edb28-eb5e-424e-a862-b0e97c8de866},0,-1,1
+501,nsIPref,{a22ad7b0-ca86-11d1-a9a4-00805f8a7ac4},0,-1,1
+502,nsIAsyncStreamCopier,{72e515de-a91e-4154-bb78-e5244cbaae74},0,-1,1
+503,nsIDOMSVGPathSegLinetoAbs,{5c7ba7b0-c7c5-4a7b-bc1c-2d784153be77},0,-1,1
+504,nsIDOMSVGAnimatedEnumeration,{73b101bd-797b-470f-9308-c24c64278bcd},0,-1,1
+505,nsIAutoCompleteSearch,{de8db85f-c1de-4d87-94ba-7844890f91fe},0,-1,1
+506,nsIDOMComment,{a6cf9073-15b3-11d2-932e-00805f8add32},0,-1,1
+507,nsISecretDecoderRingConfig,{01d8c0f0-0ccc-11d4-9fdd-000064657374},0,-1,1
+508,nsIXULTreeBuilderObserver,{a5480e0d-ac7c-42e5-aca5-d7f0bbffa207},0,-1,1
+509,nsIXPTLoader,{368a15d9-17a9-4c2b-ac3d-a35b3a22b876},0,-1,1
+510,nsIContentFilter,{c18c49a8-62f0-4045-9884-4aa91e388f14},0,-1,1
+511,nsIASN1Tree,{c727b2f2-1dd1-11b2-95df-f63c15b4cd35},0,-1,1
+512,extISessionStorage,{0787ac44-29b9-4889-b97f-13573aec6971},0,-1,1
+513,nsIComponentManagerObsolete,{8458a740-d5dc-11d2-92fb-00e09805570f},0,-1,1
+514,mozIStorageStatementRow,{02eeaf95-c3db-4182-9340-222c29f68f02},0,-1,1
+515,nsIInterfaceInfo,{215dbe04-94a7-11d2-ba58-00805f8a5dd7},0,-1,0
+516,nsIShellService,{bb477da4-dddf-4106-a562-f06c85c7f9a8},0,-1,1
+517,mozISpellCheckingEngine,{43987f7b-0faa-4019-811e-42becac73fc5},0,-1,1
+518,nsIApplicationCacheContainer,{bbb80700-1f7f-4258-aff4-1743cc5a7d23},0,-1,1
+519,mozIStorageDataSet,{57826606-3c8a-4243-9f2f-cb3fe6e91148},0,-1,1
+520,nsIJSContextStack,{c67d8270-3189-11d3-9885-006008962422},0,-1,0
+521,nsIDOMNSHTMLFrameElement,{d67bd267-f984-4993-b378-95851b71f0a3},0,-1,1
+522,nsIProfile,{02b0625a-e7f3-11d2-9f5a-006008a6efe9},0,-1,1
+523,nsIDOMSVGPathSegMovetoRel,{58ca7e86-661a-473a-96de-89682e7e24d6},0,-1,1
+524,nsISystemProxySettings,{a9f3ae38-b769-4e0b-9317-578388e326c9},0,-1,1
+525,nsIPromptService,{1630c61a-325e-49ca-8759-a31b16c47aa5},0,-1,1
+526,nsIJARProtocolHandler,{92c3b42c-98c4-11d3-8cd9-0060b0fc14a3},0,-1,1
+527,nsIRefreshURI,{cb0ad623-6b46-4c09-a473-c1d6ca63d3c7},0,-1,1
+528,nsIDOMAttr,{a6cf9070-15b3-11d2-932e-00805f8add32},0,-1,1
+529,nsIDOMXPathExpression,{75506f82-b504-11d5-a7f2-ca108ab8b6fc},0,-1,1
+530,nsIJVMPluginInstance,{a0c057d0-01c1-11d2-815b-006008119d7a},0,-1,1
+531,nsIVariant,{6c9eb060-8c6a-11d5-90f3-0010a4e73d9a},0,-1,1
+532,nsIDOMSVGAnimatedBoolean,{7e325385-cc82-4763-bd14-e2c92edd5462},0,-1,1
+533,nsITreeColumn,{ae835ecf-6b32-4660-9b43-8a270df56e02},0,-1,1
+534,nsIAutoCompletePopup,{1b9d7d8a-6dd0-11dc-8314-0800200c9a66},0,-1,1
+535,nsIFullScreen,{9854976e-1dd1-11b2-8350-e6d35099fbce},0,-1,1
+536,nsIAccessibleCaretMoveEvent,{b9076dce-4cd3-4e3d-a7f6-7f33a7f40c31},0,-1,1
+537,mozIStorageFunction,{9ff02465-21cb-49f3-b975-7d5b38ceec73},0,-1,1
+538,nsIDOMPkcs11,{9fd42950-25e7-11d4-8a7d-006008c844c3},0,-1,1
+539,nsIDocumentEncoderNodeFixup,{3c556e41-0f73-4e1d-b724-1474884fe2e3},0,-1,1
+540,nsIToolkitProfile,{7422b090-4a86-4407-972e-75468a625388},0,-1,1
+541,nsIWebBrowserPrint,{9a7ca4b0-fbba-11d4-a869-00105a183419},0,-1,1
+542,nsPIAccessible,{ed61e5cd-283a-42df-9599-765e0e27f4d9},0,-1,0
+543,nsIGlobalHistory2,{cf777d42-1270-4b34-be7b-2931c93feda5},0,-1,1
+544,rdfIDataSource,{ebce86bd-1568-4a34-a808-9ccf9cde8087},0,-1,1
+545,nsIWebBrowserFindInFrames,{e0f5d182-34bc-11d5-be5b-b760676c6ebc},0,-1,1
+546,nsIDynamicContainer,{7e85d97b-4109-4ea7-afd8-bc2cd3840d70},0,-1,1
+547,nsISAXXMLFilter,{77a22cf0-6cdf-11da-be43-001422106990},0,-1,1
+548,nsINavHistoryFullVisitResultNode,{c49fd9d5-56e2-43eb-932c-f933f28cba85},0,-1,1
+549,nsISearchableInputStream,{8c39ef62-f7c9-11d4-98f5-001083010e9b},0,-1,1
+550,nsIDirIndexListener,{fae4e9a8-1dd1-11b2-b53c-8f3aa1bbf8f5},0,-1,1
+551,nsISAXContentHandler,{2a99c757-dfee-4806-bff3-f721440412e0},0,-1,1
+552,nsIExternalHelperAppService,{9e456297-ba3e-42b1-92bd-b7db014268cb},0,-1,1
+553,nsIDOMSVGTitleElement,{524564b0-13a3-459b-bbec-ad66aea9f789},0,-1,1
+554,nsICurrentCharsetListener,{cf9428c1-df50-11d3-9d0c-0050040007b2},0,-1,1
+555,nsISocketProvider,{00b3df92-e830-11d8-d48e-0004e22243f8},0,-1,1
+556,nsIThreadObserver,{81d0b509-f198-4417-8020-08eb4271491f},0,-1,1
+557,nsIStringInputStream,{450cd2d4-f0fd-424d-b365-b1251f80fd53},0,-1,1
+558,nsIPhonetic,{bc6ea726-ab56-46b6-a21a-aa7b76d6818f},0,-1,1
+559,nsIDOMLoadStatus,{2cb53a8a-d2f4-4ddf-874f-3bc2d595c41a},0,-1,1
+560,nsIInterfaceInfoSuperManager,{0ee22850-bc6a-11d5-9134-0010a4e73d9a},0,-1,0
+561,nsIThread,{9c889946-a73a-4af3-ae9a-ea64f7d4e3ca},0,-1,1
+562,nsIDOMCSSValue,{009f7ea5-9e80-41be-b008-db62f10823f2},0,-1,1
+563,nsICookieAcceptDialog,{3f2f0d2c-bdea-4b5a-afc6-fcf18f66b97e},0,-1,1
+564,nsIDOMSVGFEBlendElement,{8f4daf4c-de2d-450f-a373-449ad62e3800},0,-1,1
+565,nsIMenuBoxObject,{f5099746-5049-4e81-a03e-945d5110fee2},0,-1,1
+566,nsIDOMSVGFEFuncRElement,{85719a5d-9688-4c5f-bad5-c21847515200},0,-1,1
+567,nsIDOMNSEvent,{e565d518-4510-407f-a3d9-3b4107549c6d},0,-1,1
+568,nsIAutoCompleteInput,{f5eddd39-f8e0-43b7-bc3d-03623f595e52},0,-1,1
+569,nsIDOMSVGPathSegClosePath,{4970505f-2cc0-4afa-92e6-0cf4bdbf5a53},0,-1,1
+570,nsIDOMLSException,{1cc8e4b3-1dbb-4adc-a913-1527bf67748c},0,-1,1
+571,nsIDOMHTMLTimeRanges,{5c9995a1-9fce-44e8-aa7f-de52ff4c3f46},0,-1,1
+572,nsIDOMSVGFEGaussianBlurElement,{43ff8d42-3380-4dbd-a916-7c2daa3ed7f4},0,-1,1
+573,nsIDOMHTMLFieldSetElement,{a6cf9097-15b3-11d2-932e-00805f8add32},0,-1,1
+574,nsIDOMSVGLinearGradientElement,{7e15fce5-b208-43e1-952a-c570ebad0619},0,-1,1
+575,nsIDOMStorage,{95cc1383-3b62-4b89-aaef-1004a513ef47},0,-1,1
+576,nsIStreamLoader,{8ea7e890-8211-11d9-8bde-f66bad1e3f3a},0,-1,1
+577,nsIDOMWindowCollection,{a6cf906f-15b3-11d2-932e-00805f8add32},0,-1,1
+578,nsIBinaryInputStream,{7b456cb0-8772-11d3-90cf-0040056a906e},0,-1,1
+579,nsIDOMSVGFEConvolveMatrixElement,{42109b58-a8c1-4078-b44c-ec1d5d6b9574},0,-1,1
+580,nsIDocShell_MOZILLA_1_9_1_dns,{6cf71a12-c7d6-404d-b0b5-15ceae321337},0,-1,1
+581,nsISSLStatus,{cfede939-def1-49be-81ed-d401b3a07d1c},0,-1,1
+582,nsITextScroll,{067b28a0-877f-11d3-af7e-00a024ffc08c},0,-1,1
+583,nsIDOMSVGRadialGradientElement,{d0262ae1-31a4-44be-b82e-85e4cfe280fd},0,-1,1
+584,nsIBidirectionalEnumerator,{75f158a0-cadd-11d2-8cca-0060b0fc14a3},0,-1,0
+585,nsIVersionComparator,{e6cd620a-edbb-41d2-9e42-9a2ffc8107f3},0,-1,1
+586,nsIUrlClassifierLookupCallback,{f1dc83c6-ad43-4f0f-a809-fd43de7de8a4},0,-1,0
+587,nsIControllerCommandTable,{d1a47834-6ad4-11d7-bfad-000393636592},0,-1,1
+588,nsIWindowWatcher,{002286a8-494b-43b3-8ddd-49e3fc50622b},0,-1,1
+589,nsIDOMXPathException,{75506f89-b504-11d5-a7f2-ca108ab8b6fc},0,-1,1
+590,nsIDOMXULCommandEvent,{f9fa8205-a988-4828-9228-f3332d5475ac},0,-1,1
+591,nsISHistory,{9883609f-cdd8-4d83-9b55-868ff08ad433},0,-1,1
+592,nsIAutoCompleteBaseResult,{e6396544-921d-4776-aa62-8bf2dc1ae058},0,-1,0
+593,nsIDOMCrypto,{12b6d899-2aed-4ea9-8c02-2223ab7ab592},0,-1,1
+594,nsIDOMSVGFEDiffuseLightingElement,{2e9eb422-2398-4be9-a9b8-b1cc7aa9dd6f},0,-1,1
+595,nsIDOMCryptoDialogs,{1f8fe77e-1dd2-11b2-8dd2-e55f8d3465b8},0,-1,1
+596,nsISimpleUnicharStreamFactory,{8238cd2e-e8e3-43e8-b556-56e21389c766},0,-1,1
+597,nsIDOMMutationEvent,{8e440d86-886a-4e76-9e59-c13b939c9a4b},0,-1,1
+598,nsIDOMSVGTextPositioningElement,{5d052835-8cb0-442c-9754-a8e616db1f89},0,-1,1
+599,nsIDOMNSHTMLAnchorElement,{a6cf911c-15b3-11d2-932e-00805f8add32},0,-1,1
+600,nsILocalHandlerApp,{9812be73-273c-478c-8170-c3e0db08ae7c},0,-1,1
+601,nsIComponentRegistrar,{2417cbfe-65ad-48a6-b4b6-eb84db174392},0,-1,1
+602,nsIFileChannel,{06169120-136d-45a5-b535-498f1f755ab7},0,-1,1
+603,nsIPluginHost,{2af1c32d-38dd-4f72-b0ab-24697d836e61},0,-1,1
+604,nsIDOMSVGPathElement,{2b19e692-3338-440f-a998-3cb1e8474999},0,-1,1
+605,nsIHttpAuthenticator,{0f331436-8bc8-4c68-a124-d0253a19d06f},0,-1,1
+606,nsIPrintSession,{2f977d52-5485-11d4-87e2-0010a4e75ef2},0,-1,0
+607,nsICacheListener,{638c3848-778b-4851-8ff3-9400f65b8773},0,-1,1
+608,mozIStorageResultSet,{18dd7953-076d-4598-8105-3e32ad26ab24},0,-1,1
+609,mozIStorageValueArray,{07b5b93e-113c-4150-863c-d247b003a55d},0,-1,1
+610,nsIStreamCipher,{1d507cd6-1630-4710-af1b-4012dbcc514c},0,-1,1
+611,nsIDOMSVGAnimatedRect,{ca45959e-f1da-46f6-af19-1ecdc322285a},0,-1,1
+612,nsIWindowlessPluginInstancePeer,{57b4e2f0-019b-11d2-815b-006008119d7a},0,-1,0
+613,nsIDOMDocumentEvent,{46b91d66-28e2-11d4-ab1e-0010830123b4},0,-1,1
+614,nsICMSMessageErrors,{f2aec680-60a0-49f0-afe5-6cf1d3f15e0d},0,-1,1
+615,nsICrashReporter,{d9a0f5b2-a7df-4aeb-9775-21b9e01b4c59},0,-1,1
+616,nsIXULAppInfo,{a61ede2a-ef09-11d9-a5ce-001124787b2e},0,-1,1
+617,nsIProxiedProtocolHandler,{0a24fed4-1dd2-11b2-a75c-9f8b9a8f9ba7},0,-1,1
+618,nsISupportsString,{d79dc970-4a1c-11d3-9890-006008962422},0,-1,1
+619,nsIDOMNSFeatureFactory,{dc5ba787-b648-4b01-a8e7-b293ffb044ef},0,-1,1
+620,nsISafeOutputStream,{5f914307-5c34-4e1f-8e32-ec749d25b27a},0,-1,1
+621,inIDeepTreeWalker,{91fca0e9-99d6-406b-9d78-4c96f11e9ee4},0,-1,1
+622,nsIComponentManager,{a88e5a60-205a-4bb1-94e1-2628daf51eae},0,-1,1
+623,nsIDocShellTreeItem,{09b54ec1-d98a-49a9-bc95-3219e8b55089},0,-1,1
+624,nsIDOMCSSFontFaceRule,{a6cf90bb-15b3-11d2-932e-00805f8add32},0,-1,1
+625,nsIPrincipal,{b8268b9a-2403-44ed-81e3-614075c92034},0,-1,1
+626,nsISupportsPRUint64,{e13567c0-4a1c-11d3-9890-006008962422},0,-1,1
+627,nsITaggingService,{e39cea60-7e6d-4c8b-80a3-997af1c2cbcb},0,-1,1
+628,nsIXMLHttpRequestEventTarget,{6ce0a193-b033-4c3d-b748-f851b09261f5},0,-1,1
+629,nsICMSMessage2,{a99a3203-39e3-45e1-909c-175b0e471c2b},0,-1,0
+630,nsIAutoCompleteMdbResult,{f7e7b341-2d5c-4d04-9f51-496cb2ce178c},0,-1,0
+631,nsIPrefBranch2,{74567534-eb94-4b1c-8f45-389643bfc555},0,-1,1
+632,inISearchObserver,{46226d9b-e398-4106-8d9b-225d4d0589f5},0,-1,1
+633,nsIDOMSVGAnimatedLength,{a52f0322-7f4d-418d-af6d-a7b14abd5cdf},0,-1,1
+634,nsIPasswordManager,{173562f0-2173-11d5-a54c-0010a401eb10},0,-1,1
+635,nsISupportsID,{d18290a0-4a1c-11d3-9890-006008962422},0,-1,1
+636,nsIRollupListener,{ee6efe03-77dc-4aac-a6a8-905731a1796e},0,-1,0
+637,nsIResProtocolHandler,{067ca872-e947-4bd6-8946-a479cb6ba5dd},0,-1,1
+638,nsIServerSocketListener,{836d98ec-fee2-4bde-b609-abd5e966eabd},0,-1,1
+639,nsIAccessNode,{71a3b4e7-e83d-45cf-a20e-9ce292bcf19f},0,-1,1
+640,nsIDOMSVGPathSegCurvetoQuadraticAbs,{b7aef0f0-2830-4145-b04f-fe05789ccf8a},0,-1,1
+641,nsIWebNavigation,{f5d9e7b0-d930-11d3-b057-00a024ffc08c},0,-1,1
+642,nsISupportsPRInt64,{e3cb0ff0-4a1c-11d3-9890-006008962422},0,-1,1
+643,nsIXPCComponents_ID,{7994a6e0-e028-11d3-8f5d-0010a4e73d9a},0,-1,1
+644,nsITooltipTextProvider,{b128a1e6-44f3-4331-8fbe-5af360ff21ee},0,-1,1
+645,nsIXPCComponents_Classes,{978ff520-d26c-11d2-9842-006008962422},0,-1,1
+646,nsIFastLoadService,{759e475e-0c23-4dbf-b1b8-78c9369e3072},0,-1,1
+647,jsdIProperty,{b8816e56-1dd1-11b2-81dc-8ba99a833d9e},0,-1,1
+648,nsIWorkerGlobalScope,{d7d7cf59-6c8a-4598-8753-630953ae7409},0,-1,1
+649,nsIDOMHTMLLegendElement,{a6cf9098-15b3-11d2-932e-00805f8add32},0,-1,1
+650,nsIAutoConfig,{80db54ae-13f2-11d5-be44-00108335a220},0,-1,0
+651,nsIDOMNSHTMLAreaElement2,{1859b16a-7c16-4ab7-bdb9-52792ba16cc1},0,-1,1
+652,nsIDOMSVGDefsElement,{a2e86036-f04c-4013-9f74-e7090a0aac0a},0,-1,1
+653,nsIBaseWindow,{046bc8a0-8015-11d3-af70-00a024ffc08c},0,-1,1
+654,nsIFastLoadFileControl,{8a1e2c63-af50-4147-af7e-26289dc180dd},0,-1,1
+655,nsIPrefService,{decb9cc7-c08f-4ea5-be91-a8fc637ce2d2},0,-1,1
+656,nsIDOMLSProgressEvent,{b9a2371f-70e9-4657-b0e8-28e15b40857e},0,-1,1
+657,nsIAccessibleHyperText,{d56bd454-8ff3-4edc-b266-baeada00267b},0,-1,1
+658,nsIMicrosummaryGenerator,{05b48344-d0a7-427e-934e-9a6e0d5ecced},0,-1,1
+659,mozIStorageRow,{62d1b6bd-cbfe-4f9b-aee1-0ead4af4e6dc},0,-1,1
+660,nsIContentURIGrouper,{4bb38cb4-c3cb-4d17-9799-1b3132b39723},0,-1,1
+661,nsIJVMAuthTools,{82274a32-a196-42ee-8e3b-fcb73e339518},0,-1,0
+662,nsIDOMSVGPathSeg,{b9022da7-e26d-4df3-8c94-b45c4aedda7c},0,-1,1
+663,fuelIBrowserTab,{3073ceff-777c-41ce-9ace-ab37268147c1},0,-1,1
+664,nsISSLCertErrorDialog,{0729ce8e-8935-4989-ba72-a2d6307f2365},0,-1,1
+665,nsIThreadJSContextStack,{a1339ae0-05c1-11d4-8f92-0010a4e73d9a},0,-1,0
+666,nsIScriptChannel,{33234b99-9588-4c7d-9da6-86b8b7cba565},0,-1,1
+667,nsIDOMBarProp,{9eb2c150-1d56-11d3-8221-0060083a0bcf},0,-1,1
+668,nsIPluginInstanceOwner,{2e6cc23b-7d4e-4b0a-ad45-f2281c937f5c},0,-1,0
+669,nsIHttpHeaderVisitor,{0cf40717-d7c1-4a94-8c1e-d6c9734101bb},0,-1,1
+670,fuelIAnnotations,{335c9292-91a1-4ca0-ad0b-07d5f63ed6cd},0,-1,1
+671,nsIWindowProvider,{5119ac7f-81dd-4061-96a7-71f2cf5efee4},0,-1,1
+672,nsIPrintSettingsService,{841387c8-72e6-484b-9296-bf6eea80d58a},0,-1,1
+673,nsIDOMSVGFEColorMatrixElement,{0e966878-ebf1-4455-86fd-f4c7b1f24777},0,-1,1
+674,nsIPKCS11,{5743f870-958e-4f02-aef2-c0afeef67f05},0,-1,1
+675,nsIDOMSVGFEFuncAElement,{fa48511c-283a-437f-9507-c309ac6f0f57},0,-1,1
+676,nsIObjectInputStream,{6c248606-4eae-46fa-9df0-ba58502368eb},0,-1,1
+677,nsIDOMSVGFETileElement,{ed042a81-39fc-4c89-9385-75758a2434b5},0,-1,1
+678,nsIDOMGetSVGDocument,{b5d3074c-4f63-4936-bf39-49034efa26a5},0,-1,1
+679,nsIDirIndex,{23bbabd0-1dd2-11b2-86b7-aad68ae7d7e0},0,-1,1
+680,nsIEditorBoxObject,{e3800a23-5b83-49aa-b18c-efa1ac5416e0},0,-1,1
+681,nsIPasswordManagerInternal,{a448531f-dc92-4dc1-9012-da841febcbe0},0,-1,1
+682,nsIDOMNSHTMLHRElement,{19b5879f-c125-447c-aaaf-719de3ef221a},0,-1,1
+683,nsIDOMSVGFEFloodElement,{2743af95-28c5-429d-9812-12b7b017887e},0,-1,1
+684,nsIFormFillController,{07f0a0dc-f6e9-4cdd-a55f-56d770523a4c},0,-1,1
+685,nsIMIMEInputStream,{dcbce63c-1dd1-11b2-b94d-91f6d49a3161},0,-1,1
+686,nsIRecentBadCertsService,{a5ae8b05-a76e-408f-b0ba-02a831265749},0,-1,1
+687,nsICommandHandler,{34a4fcf0-66fc-11d4-9528-0020183bf181},0,-1,1
+688,nsIDOMHTMLObjectElement,{a6cf90ac-15b3-11d2-932e-00805f8add32},0,-1,1
+689,nsIDOMLocation,{a6cf906d-15b3-11d2-932e-00805f8add32},0,-1,1
+690,nsIViewSourceChannel,{8b77d6e2-2ae9-11d5-be57-000064657374},0,-1,0
+691,nsISyncLoadDOMService,{8095998d-ae1c-4cfa-9b43-0973e5d77eb0},0,-1,1
+692,nsIDOMXULDescriptionElement,{c7b0b43c-1dd1-11b2-9e1c-ce5f6a660630},0,-1,1
+693,nsIURL,{d6116970-8034-11d3-9399-00104ba0fd40},0,-1,1
+694,nsIMultiplexInputStream,{a076fd12-1dd1-11b2-b19a-d53b5dffaade},0,-1,1
+695,nsIClipboardCommands,{b8100c90-73be-11d2-92a5-00105a1b0d64},0,-1,1
+696,nsIThreadEventFilter,{a0605c0b-17f5-4681-b8cd-a1cd75d42559},0,-1,1
+697,nsIXPCSecurityManager,{31431440-f1ce-11d2-985a-006008962422},0,-1,0
+698,nsIDOMXULMenuListElement,{3d49950e-04f9-4e35-a9a0-ffd51356a674},0,-1,1
+699,nsIDocShellTreeNode,{37f1ab73-f224-44b1-82f0-d2834ab1cec0},0,-1,1
+700,nsIWebBrowserChrome,{ba434c60-9d52-11d3-afb0-00a024ffc08c},0,-1,1
+701,nsIFastLoadWriteControl,{2ad6e9e6-1379-4e45-a899-a54b27ff915c},0,-1,1
+702,nsIPluginManager2,{d2962dc0-4eb6-11d2-8164-006008119d7a},0,-1,0
+703,nsIByteRangeRequest,{c1b1f426-7e83-4759-9f88-0e1b17f49366},0,-1,1
+704,nsIPrintStatusFeedback,{19855dff-3248-4902-b196-93ee4c477880},0,-1,1
+705,nsIPluginTagInfo2,{6a49c9a0-019b-11d2-815b-006008119d7a},0,-1,0
+706,nsIDOMRange,{a6cf90ce-15b3-11d2-932e-00805f8add32},0,-1,1
+707,nsIAccessibleStates,{7fe1ee90-edaa-43f1-9f3b-071099b51f08},0,-1,1
+708,nsIAtomService,{9c1f50b9-f9eb-42d4-a8cb-2c7600aeb241},0,-1,1
+709,nsIExceptionProvider,{0577744c-c1d2-47f2-8bcc-ce7a9e5a88fc},0,-1,1
+710,nsIDOMJSNavigator,{4b4f8316-1dd2-11b2-b265-9a857376d159},0,-1,1
+711,nsIScriptableDateFormat,{0c89efb0-1aae-11d3-9141-006008a6edf6},0,-1,1
+712,nsIDOM3EventTarget,{3e9c01a7-de97-4c3b-8294-b4bd9d7056d1},0,-1,1
+713,nsIJVMConfig,{3e333e20-b190-42d8-b993-d5fa435e46c4},0,-1,1
+714,nsIDOMXPathNSResolver,{75506f83-b504-11d5-a7f2-ca108ab8b6fc},0,-1,1
+715,nsIFTPChannel,{2315d831-8b40-446a-9138-fe09ebb1b720},0,-1,1
+716,nsIDOMCSSValueList,{8f09fa84-39b9-4dca-9b2f-db0eeb186286},0,-1,1
+717,nsIStackFrame,{91d82105-7c62-4f8b-9779-154277c0ee90},0,-1,1
+718,nsIDOMHTMLFontElement,{a6cf90a7-15b3-11d2-932e-00805f8add32},0,-1,1
+719,nsIEffectiveTLDService,{6852369e-baa9-4c9a-bbcd-5123fc54a297},0,-1,1
+720,imgIEncoder,{ba3a854b-fb8d-4881-8af9-5849df10e5e5},0,-1,1
+721,nsIToolkitChromeRegistry,{94490b3f-f094-418e-b1b9-73878d29bff3},0,-1,1
+722,nsIBrowserHistory,{96602bf3-de2a-42ed-812f-a83b130e6299},0,-1,1
+723,nsIPropertyBag,{bfcd37b0-a49f-11d5-910d-0010a4e73d9a},0,-1,1
+724,nsIFeedElementBase,{5215291e-fa0a-40c2-8ce7-e86cd1a1d3fa},0,-1,1
+725,nsIINIParserFactory,{ccae7ea5-1218-4b51-aecb-c2d8ecd46af9},0,-1,1
+726,nsIFormSigningDialog,{4fe04d6d-4b66-4023-a0bc-b43ce68b3e15},0,-1,1
+727,nsIDOMProgressEvent,{6af7022c-d7f8-414c-a11f-a7918f14052b},0,-1,1
+728,nsIAccessibleImage,{09086623-0f09-4310-ac56-c2cda7c29648},0,-1,1
+729,nsILiveTitleNotificationSubject,{f9e577a8-19d9-4ca0-a140-b9e43f014470},0,-1,1
+730,nsITypeAheadFind,{0749a445-19d3-4eb9-9d66-78eca8c6f604},0,-1,1
+731,nsIAddonSearchResult,{a549a714-2ada-4bb9-8a47-be26e73d49a5},0,-1,1
+732,nsICacheVisitor,{f8c08c4b-d778-49d1-a59b-866fdc500d95},0,-1,1
+733,nsISSLStatusProvider,{8de811f0-1dd2-11b2-8bf1-e9aa324984b2},0,-1,1
+734,nsIProxyAutoConfig,{a42619df-0a1c-46fb-8154-0e9b8f8f1ea8},0,-1,1
+735,nsIDOMStorageManager,{9efc2081-218f-4622-837b-40bdb870a1c8},0,-1,1
+736,nsIAuthPrompt2,{447fc780-1d28-412a-91a1-466d48129c65},0,-1,1
+737,nsIProfileChangeStatus,{2f977d43-5485-11d4-87e2-0010a4e75ef2},0,-1,1
+738,nsIDOMSVGComponentTransferFunctionElement,{cb615c0f-8d4a-4e30-9695-a3dd6f4216ee},0,-1,1
+739,nsISupportsArray,{791eafa0-b9e6-11d1-8031-006008159b5a},0,-1,1
+740,nsIThreadPoolListener,{ef194cab-3f86-4b61-b132-e5e96a79e5d1},0,-1,1
+741,nsIPromptFactory,{2532b748-75db-4732-9173-78d3bf34f694},0,-1,1
+742,nsIMemoryReporterManager,{63fc8fbd-509b-4fdb-93b4-2e6caeeddab1},0,-1,1
+743,nsIWebBrowserPersist,{dd4e0a6a-210f-419a-ad85-40e8543b9465},0,-1,1
+744,nsIDOMCSSStyleSheet,{a6cf90c2-15b3-11d2-932e-00805f8add32},0,-1,1
+745,nsIDOMXULSelectControlElement,{919d9808-8937-4cec-9390-91225eb8864b},0,-1,1
+746,nsIXULTemplateBuilder,{a583b676-5b02-4f9c-a0c9-cb850cb99818},0,-1,1
+747,nsIXPointerSchemeContext,{781f4aa1-ebb3-4667-b1c2-2b35e94c4281},0,-1,0
+748,nsISemanticUnitScanner,{9f620be4-e535-11d6-b254-00039310a47a},0,-1,1
+749,nsIDOMNSUIEvent,{a6cf90c4-15b3-11d2-932e-00805f8add32},0,-1,1
+750,nsIDOMSVGTextPathElement,{5c29a76c-3489-48fe-b9ea-ea0f5b196dff},0,-1,1
+751,nsIClientAuthDialogs,{fa4c7520-1433-11d5-ba24-00108303b117},0,-1,1
+752,nsIDOMBeforeUnloadEvent,{da19e9dc-dea2-4a1d-a958-9be375c9799c},0,-1,1
+753,nsIDOMNSHTMLElement,{7f142f9a-fba7-4949-93d6-cf08a974ac51},0,-1,1
+754,nsIDOMHTMLBodyElement,{a6cf908e-15b3-11d2-932e-00805f8add32},0,-1,1
+755,nsIEnumerator,{ad385286-cbc4-11d2-8cca-0060b0fc14a3},0,-1,1
+756,nsIBufferedInputStream,{616f5b48-da09-11d3-8cda-0060b0fc14a3},0,-1,1
+757,nsIX509CertList,{a539759b-e22d-462f-94ea-2915b11b33e8},0,-1,1
+758,mozIStoragePendingStatement,{fc3c5fdc-9a87-4757-b01f-4ace2670a3a0},0,-1,1
+759,nsICMSDecoder,{65244a06-a342-11d5-ba47-00108303b117},0,-1,0
+760,nsPIPromptService,{d16e906d-bab3-49e0-8688-7f49a6f4293a},0,-1,0
+761,nsPIAccessibleDocument,{fa9cafac-9562-49ad-afcf-911ab1e4e4fb},0,-1,0
+762,nsISMimeVerificationListener,{56310af6-dffc-48b4-abca-85eae4059064},0,-1,0
+763,nsIInputStreamChannel,{274c4d7a-2447-4ceb-a6de-80db1b83f5d2},0,-1,1
+764,nsISecurityInfoProvider,{b8cc9126-9319-4415-afd9-b82220d453ed},0,-1,1
+765,nsIDOMKeyEvent,{028e0e6e-8b01-11d3-aae7-0010838a3123},0,-1,1
+766,nsIGeolocationProvider,{5c819505-8804-496e-9cb2-53089b3dd4ef},0,-1,1
+767,nsIDOMSVGForeignObjectElement,{fd9c9871-23fd-48eb-a65b-3842e9b0acbd},0,-1,1
+768,nsIDOMCSSUnknownRule,{a6cf90d0-15b3-11d2-932e-00805f8add32},0,-1,1
+769,nsICommandController,{ebe55080-c8a9-11d5-a73c-dd620d6e04bc},0,-1,1
+770,nsIIOService2,{d44fe6d4-ee35-4789-886a-eb8f0554d04e},0,-1,1
+771,nsIPluginManager,{da58ad80-4eb6-11d2-8164-006008119d7a},0,-1,1
+772,nsIDOMSVGPolylineElement,{7b6e15cf-9793-41ee-adcc-cc1c206c80e6},0,-1,1
+773,nsIStreamTransportService,{8268d474-efbf-494f-a152-e8a8616f4e52},0,-1,1
+774,nsIDOMSVGFilterElement,{9e81d4ae-190c-4b9d-a076-ebc52a7bf231},0,-1,1
+775,nsIDownloadHistory,{202533cd-a8f1-4ee4-8d20-3a6a0d2c6c51},0,-1,1
+776,nsIDOMHTMLButtonElement,{a6cf9095-15b3-11d2-932e-00805f8add32},0,-1,1
+777,nsIDOMDataContainerEvent,{3600d66c-b9ac-4c22-b39a-d64cce619921},0,-1,1
+778,mozIStorageService,{fe8e95cb-b377-4c8d-bccb-d9198c67542b},0,-1,1
+779,nsIModuleLoader,{9b328e24-4d85-4a9c-9cb7-f25e66f430c3},0,-1,1
+780,nsIDOMNSHTMLInputElement,{df3dc133-d77a-482f-8364-8e40df978a33},0,-1,1
+781,nsIDOMSVGFEDistantLightElement,{02141672-7f2c-412a-a7d7-4caa194842e9},0,-1,1
+782,nsITransfer,{23c51569-e9a1-4a92-adeb-3723db82ef7c},0,-1,1
+783,nsIOfflineCacheUpdateObserver,{a28abeaf-a0b4-4440-b2fe-bc78249710ea},0,-1,1
+784,nsIDOMHTMLTableColElement,{a6cf90b4-15b3-11d2-932e-00805f8add32},0,-1,1
+785,nsIScriptEventManager,{b6427ace-dc77-495b-ab21-43baeb52bc27},0,-1,0
+786,mozIStorageProgressHandler,{a3a6fcd4-bf89-4208-a837-bf2a73afd30c},0,-1,1
+787,nsIDOMSVGPathSegCurvetoQuadraticRel,{c46eb661-9c05-4d46-9b2a-c2ae5b166060},0,-1,1
+788,nsIXMLHttpRequestUpload,{09ff3682-7759-4441-a765-f70e1a1fabcf},0,-1,1
+789,nsIDOMSVGTSpanElement,{4a23cb1f-cf1e-437e-9524-8756f7928b2e},0,-1,1
+790,nsIControllerContext,{47b82b60-a36f-4167-8072-6f421151ed50},0,-1,1
+791,nsIUrlClassifierStreamUpdater,{daf3038a-556c-47d3-a3d2-36caa9a762a0},0,-1,1
+792,nsIDOMSVGClipPathElement,{0c3f45a4-e6d0-44e7-a2f8-d128ecf1db9b},0,-1,1
+793,nsICertTree,{a8cd1c89-a901-4735-831b-7198b7b8b6b1},0,-1,1
+794,nsIUTF8StringEnumerator,{9bdf1010-3695-4907-95ed-83d0410ec307},0,-1,1
+795,nsIExpatSink,{f61c56b5-ea5b-42b4-ad3c-17416e72e238},0,-1,1
+796,nsIDocShell,{dc4daea1-b43d-406f-bd62-c2ee879192ad},0,-1,1
+797,extIEvents,{3a8ec9d0-ab19-11db-abbd-0800200c9a66},0,-1,1
+798,nsIINIParser,{7eb955f6-3e78-4d39-b72f-c1bf12a94bce},0,-1,1
+799,nsIXBLAccessible,{3716eb86-166b-445b-a94a-9b522fee96e6},0,-1,1
+800,nsIDOMEventListener,{df31c120-ded6-11d1-bd85-00805f8ae3f4},0,-1,1
+801,nsPICertNotification,{42cd7162-ea4a-4088-9888-63ea5095869e},0,-1,0
+802,nsIPermission,{28f16d80-157b-11d5-a542-0010a401eb10},0,-1,1
+803,nsIEditorObserver,{a6cf9125-15b3-11d2-932e-00805f8add32},0,-1,1
+804,nsIPrefSecurityCheck,{c73c9a05-92ce-46e1-8f69-90a2a3a36104},0,-1,0
+805,nsICertVerificationListener,{6684bce9-50db-48e1-81b7-98102bf81357},0,-1,1
+806,nsIDOMMessageEvent,{98150805-6a15-4667-815a-1a8c87cb4bbc},0,-1,1
+807,nsIIOService,{bddeda3f-9020-4d12-8c70-984ee9f7935e},0,-1,1
+808,nsIDOMCanvasGradient,{bbb20a59-524e-4662-981e-5e142814b20c},0,-1,1
+809,nsIDOMEventGroup,{33347bee-6620-4841-8152-36091ae80c7e},0,-1,1
+810,nsISidebarExternal,{4350fb73-9305-41df-a669-11d26222d420},0,-1,1
+811,nsITooltipListener,{44b78386-1dd2-11b2-9ad2-e4eee2ca1916},0,-1,1
+812,nsIDOMNSHTMLTextAreaElement,{ca066b44-9ddf-11d3-bccc-0060b0fc76bd},0,-1,1
+813,nsIDOMSVGNumberList,{59364ec4-faf1-460f-bf58-e6a6a2769a3a},0,-1,1
+814,nsIAccessibleTable,{dcc1e5c3-966e-45b2-b30a-839d35432b24},0,-1,1
+815,nsIAccessibleStateChangeEvent,{444db51a-05fd-4576-8a64-32dbb2a83884},0,-1,1
+816,nsIDOMSVGPathSegCurvetoQuadraticSmoothAbs,{ff5bbb58-b49a-450f-b91b-e50585c34b3d},0,-1,1
+817,nsISAXLexicalHandler,{23c26a56-adff-440c-8caf-95c2dc2e399b},0,-1,1
+818,nsISMimeCert,{66710f97-a4dd-49f1-a906-fe0ebc5924c0},0,-1,1
+819,nsIAppShellService,{361facd0-6e9a-4ff1-a0d4-450744cf0023},0,-1,1
+820,nsIDOMSVGPathSegArcRel,{49d0360d-bb66-4ab9-b9b0-f49b93398595},0,-1,1
+821,nsILoginInfo,{c41b7dff-6b9b-42fe-b78d-113051facb05},0,-1,1
+822,nsIDOMHTMLMetaElement,{a6cf908a-15b3-11d2-932e-00805f8add32},0,-1,1
+823,nsINavHistoryResultViewer,{e60f4429-3787-45c8-a8c0-18ef52621bbf},0,-1,1
+824,nsISaveAsCharset,{33b87f70-7a9c-11d3-915c-006008a6edf6},0,-1,1
+825,nsICMSSecureMessage,{14b4394a-1dd2-11b2-b4fd-ba4a194fe97e},0,-1,1
+826,nsIStringBundleService,{d85a17c0-aa7c-11d2-9b8c-00805f8a16d9},0,-1,1
+827,nsIXULOverlayProvider,{1d5b5b94-dc47-4050-93b7-ac092e383cad},0,-1,1
+828,nsIAuthModule,{6e35dbc0-49ef-4e2c-b1ea-b72ec64450a2},0,-1,0
+829,nsPIPlacesDatabase,{8e6d4f8a-4b8e-4026-9fca-517c4494ddb7},0,-1,1
+830,nsINavHistoryResult,{d1562f6f-8d5a-4042-8524-72f747a51b18},0,-1,1
+831,nsIDOMDOMImplementation,{a6cf9074-15b3-11d2-932e-00805f8add32},0,-1,1
+832,nsIFastLoadFileIO,{715577db-d9c5-464a-a32e-0a40c29b22d4},0,-1,1
+833,nsICollation,{b0132cc0-3786-4557-9874-910d7def5f93},0,-1,1
+834,nsIDOMLSOutput,{757e9971-8890-478d-a53a-07f9f6f6e0d3},0,-1,1
+835,nsIGConfService,{5009acae-6973-48c3-b6d6-52c692cc5d9d},0,-1,1
+836,nsIDOMSVGAnimatedNumber,{716e3b11-b03b-49f7-b82d-5383922b0ab3},0,-1,1
+837,nsIProfileStartup,{048e5ca1-0eb7-4bb1-a9a2-a36f7d4e0e3c},0,-1,1
+838,nsIUUIDGenerator,{138ad1b2-c694-41cc-b201-333ce936d8b8},0,-1,1
+839,nsIControllerCommandGroup,{9f82c404-1c7b-11d5-a73c-eca43ca836fc},0,-1,1
+840,nsIXSLTProcessor,{4a91aeb3-4100-43ee-a21e-9866268757c5},0,-1,1
+841,nsIDialogParamBlock,{f76c0901-437a-11d3-b7a0-e35db351b4bc},0,-1,1
+842,nsISessionStore,{91f6d650-898d-11dd-ad8b-0800200c9a66},0,-1,1
+843,nsIRDFBlob,{237f85a2-1dd2-11b2-94af-8122582fc45e},0,-1,1
+844,nsIDOMHTMLHeadElement,{a6cf9087-15b3-11d2-932e-00805f8add32},0,-1,1
+845,nsIXPCComponents_Exception,{5bf039c0-e028-11d3-8f5d-0010a4e73d9a},0,-1,1
+846,nsIASN1PrintableItem,{114e1142-1dd2-11b2-ac26-b6db19d9184a},0,-1,1
+847,nsIDOMNSHTMLButtonElement,{c914d7a4-63b3-4d40-943f-91a3c7ab0d4d},0,-1,1
+848,nsIDOMHTMLMapElement,{a6cf90af-15b3-11d2-932e-00805f8add32},0,-1,1
+849,nsISupportsDouble,{b32523a0-4ac0-11d3-baea-00805f8a5dd7},0,-1,1
+850,nsINSSErrorsService,{3a5c7a0f-f5da-4a8b-a748-d7c5a528f33b},0,-1,1
+851,nsIProtocolProxyCallback,{a9967200-f95e-45c2-beb3-9b060d874bfd},0,-1,1
+852,nsIApplicationCache,{663e2e2e-04a0-47b6-87b3-a122be46cb53},0,-1,1
+853,nsIXULSortService,{f29270c8-3be5-4046-9b57-945a84dff132},0,-1,1
+854,mozIStorageConnection,{ac3c486c-69a1-4cbe-8f25-2ad20880eab3},0,-1,1
+855,nsIDOMNSHTMLOptionCollection,{1181207b-2337-41a7-8ddf-fbe96461256f},0,-1,1
+856,nsIXULTreeBuilder,{06b31b15-ebf5-4e74-a0e2-6bc0a18a3969},0,-1,1
+857,nsIModifyableXPointerResult,{2dc3be2e-642d-4d7e-b3c5-f3dac51afbee},0,-1,0
+858,nsIHistoryEntry,{a41661d4-1417-11d5-9882-00c04fa02f40},0,-1,1
+859,nsIDOMStorage2,{a67ba00f-ccb8-4ffe-bada-f8913caafb20},0,-1,1
+860,nsIDOMXULImageElement,{f73f4d77-a6fb-4ab5-b41e-15045a0cc6ff},0,-1,1
+861,nsICommandLineHandler,{d4b123df-51ee-48b1-a663-002180e60d3b},0,-1,1
+862,nsIFileURL,{d26b2e2e-1dd1-11b2-88f3-8545a7ba7949},0,-1,1
+863,nsIFindService,{5060b801-340e-11d5-be5b-b3e063ec6a3c},0,-1,1
+864,nsIContentDispatchChooser,{456ca3b2-02be-4f97-89a2-08c08d3ad88f},0,-1,1
+865,nsIHandlerInfo,{325e56a7-3762-4312-aec7-f1fcf84b4145},0,-1,1
+866,nsIDOMHTMLOptionsCollection,{bce0213c-f70f-488f-b93f-688acca55d63},0,-1,1
+867,nsIDOMHTMLTableRowElement,{a6cf90b6-15b3-11d2-932e-00805f8add32},0,-1,1
+868,nsIClipboardHelper,{44073a98-1dd2-11b2-8600-d0ae854dbe93},0,-1,1
+869,nsIWebProgressListener,{570f39d1-efd0-11d3-b093-00a024ffc08c},0,-1,1
+870,nsIReadConfig,{ba5bc4c6-1dd1-11b2-bb89-b844c6ec0339},0,-1,0
+871,nsIUrlClassifierHashCompleter,{ade9b72b-3562-44f5-aba6-e63246be53ae},0,-1,1
+872,nsIDragService,{82b58ada-f490-4c3d-b737-1057c4f1d052},0,-1,1
+873,nsISupportsPRInt16,{e30d94b0-4a1c-11d3-9890-006008962422},0,-1,1
+874,nsIDOMSVGException,{64e6f0e1-af99-4bb9-ab25-7e56012f0021},0,-1,1
+875,nsIDOMSVGFEMorphologyElement,{16154319-fb5f-4473-b360-5065b6096d33},0,-1,1
+876,nsILocale,{21035ee0-4556-11d3-91cd-00105aa3f7dc},0,-1,1
+877,nsIUpdateItem,{f559f340-5160-420f-abc8-19b251708e7e},0,-1,1
+878,nsICiter,{a6cf9102-15b3-11d2-932e-00805f8add32},0,-1,1
+879,nsIUrlClassifierUpdateObserver,{bbb33c65-e783-476c-8db0-6ddb91826c07},0,-1,1
+880,nsIXSLTException,{e06dfaea-92d5-47f7-a800-c5f5404d8771},0,-1,1
+881,nsIFormHistoryImporter,{9e811188-6a5b-4d96-a92d-1bac66a41898},0,-1,1
+882,nsISAXDTDHandler,{4d01f225-6cc5-11da-be43-001422106990},0,-1,1
+883,nsILivemarkService,{2c08ab79-7f9b-40f3-8d04-540b5857b211},0,-1,1
+884,nsIDOMSVGDocument,{12d3b664-1dd2-11b2-a7cf-ceee7e90f396},0,-1,1
+885,nsIDOMHTMLLIElement,{a6cf909e-15b3-11d2-932e-00805f8add32},0,-1,1
+886,nsIDOMParserJS,{ba6bcd6c-63d8-49b3-bc8a-1e5e895645bc},0,-1,1
+887,nsIDOMSVGStylable,{ea8a6cb1-9176-45db-989d-d0e89f563d7e},0,-1,1
+888,nsIDOMHTMLUListElement,{a6cf9099-15b3-11d2-932e-00805f8add32},0,-1,1
+889,nsIDOMXULContainerElement,{bc07c626-4294-43ae-9b0a-e726de0adcad},0,-1,1
+890,nsIClipboardOwner,{5a31c7a1-e122-11d2-9a57-000064657374},0,-1,1
+891,nsIDOMSimpleGestureEvent,{cb68e879-f710-415d-a871-9a550860df01},0,-1,1
+892,nsIScriptableInterfaces,{01c78c65-31da-456b-90bf-da39d09fdcbf},0,-1,1
+893,nsIURI,{07a22cc0-0ce5-11d3-9331-00104ba0fd40},0,-1,1
+894,nsIBrowserHistory_MOZILLA_1_9_1_ADDITIONS,{130f2940-6a63-4790-ae8d-89d5a2683090},0,-1,1
+895,nsIChannelClassifier,{1481c5b5-9f6e-4995-8fe3-2aad5c06440d},0,-1,1
+896,nsIDOMHTMLTableElement,{a6cf90b2-15b3-11d2-932e-00805f8add32},0,-1,1
+897,nsIDOMSVGEvent,{13aed1cc-a505-45d5-bbc2-0052c6bf200f},0,-1,1
+898,nsIContextMenuListener2,{7fb719b3-d804-4964-9596-77cf924ee314},0,-1,1
+899,nsISimpleStreamListener,{a9b84f6a-0824-4278-bae6-bfca0570a26e},0,-1,1
+900,nsIDOMWindowUtils,{a2d8d4f8-6082-4653-b91d-f958518b6ada},0,-1,1
+901,nsIDOMXULPopupElement,{c32390a8-2bd8-4d1b-bf9f-1b1d0a944d19},0,-1,1
+902,nsIHandlerApp,{8d298761-0963-4c90-99e2-6ea498825e82},0,-1,1
+903,nsIOSChromeItem,{ddd6790a-1dd1-11b2-a804-b522643903b9},0,-1,1
+904,nsIFileView,{60b320d2-1dd2-11b2-bd73-dc3575f78ddd},0,-1,1
+905,nsIConsoleService,{883472a0-ea9b-11da-8ad9-0800200c9a66},0,-1,1
+906,nsIDocShellTreeOwner,{bc0eb30e-656e-491e-a7ae-7f460b660c8d},0,-1,1
+907,nsIDOMHTMLOListElement,{a6cf909a-15b3-11d2-932e-00805f8add32},0,-1,1
+908,nsIContextMenuListener,{3478b6b0-3875-11d4-94ef-0020183bf181},0,-1,1
+909,nsIExceptionManager,{efc9d00b-231c-4feb-852c-ac017266a415},0,-1,1
+910,nsIDOMSVGViewSpec,{ede34b03-57b6-45bf-a259-3550b5697286},0,-1,1
+911,nsINativeTreeView,{38e0b44d-fa08-458c-83fb-3e10b12aeb45},0,-1,0
+912,nsIPluginTagInfo,{5f1ec1d0-019b-11d2-815b-006008119d7a},0,-1,0
+913,nsIInlineSpellChecker,{074cd6ff-9118-4164-8da7-3c2d4b3ed38b},0,-1,1
+914,nsIAppStartup2,{3012668f-44b6-49b1-89fb-761a912a78c1},0,-1,1
+915,nsIJSRuntimeService,{e7d09265-4c23-4028-b1b0-c99e02aa78f8},0,-1,0
+916,nsIHelperAppLauncherDialog,{f3704fdc-8ae6-4eba-a3c3-f02958ac0649},0,-1,1
+917,xpcIJSModuleLoader,{89da3673-e699-4f26-9ed7-11a528011434},0,-1,1
+918,nsIPluginTag,{13a1b39e-72e5-442d-aa73-5905ffaf837b},0,-1,1
+919,nsIScriptablePlugin,{f1a12bba-1dd1-11b2-a95f-cdc118605e92},0,-1,0
+920,nsIRDFInferDataSource,{2b04860f-4017-40f6-8a57-784a1e35077a},0,-1,1
+921,nsIDOMSVGCircleElement,{0f89f2a4-b168-4602-90f5-1874418c0a6a},0,-1,1
+922,nsIJSContextStackIterator,{c7e6b7aa-fc12-4ca7-b140-98c38b698961},0,-1,0
+923,nsISHEntry,{c16fde76-3108-450e-8c8c-ae8286f286ed},0,-1,1
+924,nsIProperty,{6dcf9030-a49f-11d5-910d-0010a4e73d9a},0,-1,1
+925,nsIDOMStyleSheetList,{a6cf9081-15b3-11d2-932e-00805f8add32},0,-1,1
+926,nsIDNSRecord,{31c9c52e-1100-457d-abac-d2729e43f506},0,-1,1
+927,nsIDOMSVGPathSegCurvetoCubicSmoothRel,{dd5b4b00-edaa-493a-b477-bbc2576b4a98},0,-1,1
+928,nsIDOMCSSCharsetRule,{19fe78cc-65ff-4b1d-a5d7-9ea89692cec6},0,-1,1
+929,nsICookieStorage,{c8c05100-cfdb-11d2-bab8-b088e084e5bc},0,-1,0
+930,nsIProtocolProxyFilter,{f424abd3-32b4-456c-9f45-b7e3376cb0d1},0,-1,1
+931,nsIProtocolProxyService,{e38ab577-786e-4a7f-936b-7ae4c7d877b2},0,-1,1
+932,nsIPrefetchService,{cba513eb-c457-4b93-832c-1a979e66edd1},0,-1,1
+933,nsIDOMNameList,{faaf1b80-1ddd-11d9-8c46-000a95dc234c},0,-1,1
+934,nsIDOMNSDocumentStyle,{26311d10-7e24-4c7b-bb3d-17aad86f4d88},0,-1,1
+935,nsINetworkLinkService,{61618a52-ea91-4277-a4ab-ebe10d7b9a64},0,-1,1
+936,nsIEventHandler,{a447ddf0-1a99-11d2-815f-006008119d7a},0,-1,0
+937,nsIDOMHTMLLabelElement,{a6cf9096-15b3-11d2-932e-00805f8add32},0,-1,1
+938,nsIResumableChannel,{4ad136fa-83af-4a22-a76e-503642c0f4a8},0,-1,1
+939,nsIScriptLoaderObserver,{7b787204-76fb-4764-96f1-fb7a666db4f4},0,-1,1
+940,nsIHttpChannelInternal,{3ce040fb-3933-462a-8d62-80b78fbd0809},0,-1,1
+941,nsICollationFactory,{04971e14-d6b3-4ada-8cbb-c3a13842b349},0,-1,1
+942,nsIScriptableRegion,{82d8f400-5bde-11d3-b033-b27a62766bbc},0,-1,1
+943,nsITXTToHTMLConv,{933355f6-1dd2-11b2-a9b0-d335b9e35983},0,-1,1
+944,nsIPlugin,{df773070-0199-11d2-815b-006008119d7a},0,-1,0
+945,mozIStorageError,{1f350f96-7023-434a-8864-40a1c493aac1},0,-1,1
+946,nsIRequestObserverProxy,{7df8845f-938a-4437-9ea4-b11b850048f1},0,-1,1
+947,nsIWorkerNavigator,{74fb665a-e477-4ce2-b3c6-c58b1b28b6c3},0,-1,1
+948,nsISAXXMLReader,{5556997e-d816-4218-8b54-803d4261206e},0,-1,1
+949,nsIDOMLSResourceResolver,{9e61c7c8-8698-4477-9971-0923513919bd},0,-1,1
+950,nsIDOMCharacterData,{a6cf9072-15b3-11d2-932e-00805f8add32},0,-1,1
+951,nsIDownloadManager,{bacca1ac-1b01-4a6f-9e91-c2ead1f7d2c0},0,-1,1
+952,nsIDOM3Document,{2e0e9ea1-72ab-4d9e-bdeb-ca64e1abeba4},0,-1,1
+953,nsIDOMSVGPathSegCurvetoQuadraticSmoothRel,{ac0b2007-04e4-4e70-a0e0-294f374b29c4},0,-1,1
+954,nsIDOMPageTransitionEvent,{b712418b-376f-4f75-b156-5d9ad99fe51f},0,-1,1
+955,nsIArray,{114744d9-c369-456e-b55a-52fe52880d2d},0,-1,1
+956,nsIDOMDocumentView,{1acdb2ba-1dd2-11b2-95bc-9542495d2569},0,-1,1
+957,nsIOfflineCacheUpdate,{877261bb-b952-4d27-847e-859bdd47c0ec},0,-1,1
+958,nsIJRILiveConnectPluginInstancePeer,{25b63f40-f773-11d1-815b-006008119d7a},0,-1,0
+959,nsIAccessibleRetrieval,{244e4c67-a1d3-44f2-9cab-cdaa31b68046},0,-1,1
+960,nsIDOMMimeTypeArray,{f6134683-f28b-11d2-8360-c90899049c3c},0,-1,1
+961,nsISidebar,{67cf6231-c303-4f7e-b9b1-a0e87772ecfd},0,-1,1
+962,nsPIPluginHost,{673811fb-83d6-4b8f-b1a9-bb3a9033f256},0,-1,0
+963,nsIDOMCSS2Properties,{529b987a-cb21-4d58-99d7-9586e7662801},0,-1,1
+964,nsIHashable,{17e595fa-b57a-4933-bd0f-b1812e8ab188},0,-1,1
+965,nsIDOMHTMLDListElement,{a6cf909b-15b3-11d2-932e-00805f8add32},0,-1,1
+966,fuelIBookmark,{808585b6-7568-4b26-8c62-545221bf2b8c},0,-1,1
+967,nsIDOMSVGMarkerElement,{6a3b7b40-e65a-4e9c-9ee7-ca03ed0a18c7},0,-1,1
+968,nsIDOMDOMConstructor,{0ccbcf19-d1b4-489e-984c-cd8c43672bb9},0,-1,1
+969,nsIDOMUIEvent,{a6cf90c3-15b3-11d2-932e-00805f8add32},0,-1,1
+970,nsIRDFResource,{fb9686a7-719a-49dc-9107-10dea5739341},0,-1,1
+971,nsIDOMFileException,{b52356e1-45c5-4d61-b61a-fb9bd91690e1},0,-1,1
+972,nsIXULTemplateResult,{ebea0230-36fa-41b7-8e31-760806057965},0,-1,1
+973,nsIDOMSVGLength,{2596325c-aed0-487e-96a1-0a6d589b9c6b},0,-1,1
+974,nsIDOMSVGPreserveAspectRatio,{7ae42f27-4799-4e7c-86c6-e1dae6ad5157},0,-1,1
+975,nsIEditorDocShell,{3bdb8f01-f141-11d4-a73c-fba4aba8a3fc},0,-1,1
+976,nsIDocumentCharsetInfo,{2d40b291-01e1-11d4-9d0e-0050040007b2},0,-1,1
+977,nsIConsoleListener,{eaaf61d6-1dd1-11b2-bc6e-8fc96480f20d},0,-1,1
+978,nsIProgrammingLanguage,{ea604e90-40ba-11d5-90bb-0010a4e73d9a},0,-1,1
+979,nsIDOMNSHTMLImageElement,{a6cf90c7-15b3-11d2-932e-00805f8add32},0,-1,1
+980,nsIUnicharStreamLoader,{9037f476-7c08-4729-b690-3e425269802b},0,-1,1
+981,nsIFrameLoaderOwner,{641c2d90-4ada-4367-bdb1-80831614161d},0,-1,1
+982,nsIDOMHTMLAreaElement,{a6cf90b0-15b3-11d2-932e-00805f8add32},0,-1,1
+983,nsIKeyObject,{4b31f4ed-9424-4710-b946-79b7e33cf3a8},0,-1,1
+984,nsIMIMEService,{5b3675a1-02db-4f8f-a560-b34736635f47},0,-1,1
+985,nsIDOMSVGMatrix,{ec2da3ef-5a99-49ed-aaef-b5af916c14ac},0,-1,1
+986,nsIDOMWindow2,{73c5fa35-3add-4c87-a303-a850ccf4d65a},0,-1,1
+987,nsPISocketTransportService,{83123036-81c0-47cb-8d9c-bd85d29a1b3f},0,-1,1
+988,nsIDOMGeoPositionOptions,{453b72de-ea90-4f09-ae16-c2e7ee0dddc4},0,-1,1
+989,nsIURLFormatter,{4ab31d30-372d-11db-a98b-0800200c9a66},0,-1,1
+990,nsICacheEntryInfo,{fab51c92-95c3-4468-b317-7de4d7588254},0,-1,1
+991,imgIContainer,{186e80e1-476c-47f0-b340-424e6b7b6c9c},0,-1,1
+992,nsITransportEventSink,{eda4f520-67f7-484b-a691-8c3226a5b0a6},0,-1,1
+993,nsPIWindowWatcher,{8624594a-28d7-4bc3-8d12-b1c2b9eefd90},0,-1,0
+994,nsIFeedResult,{7a180b78-0f46-4569-8c22-f3d720ea1c57},0,-1,1
+995,nsIDOMSVGSVGElement,{83b04425-9509-49f5-af75-1ae1f8f3e871},0,-1,1
+996,nsIFormSubmitObserver,{0787d64a-44bf-4273-8438-61ff13ebec0c},0,-1,1
+997,nsIDOMUserDataHandler,{91afebdd-a201-4db0-b728-9d59580f0cfd},0,-1,1
+998,nsIDOMXULTreeElement,{1f8111b2-d44d-4d11-845a-a70ae06b7d04},0,-1,1
+999,nsIDOMSVGTextContentElement,{87ad94bc-07c9-412b-b2d8-de245a2e84a5},0,-1,1
+1000,nsIDOM3Node,{29fb2a18-1dd2-11b2-8dd9-a6fd5d5ad12f},0,-1,1
+1001,nsIDirectoryServiceProvider2,{2f977d4b-5485-11d4-87e2-0010a4e75ef2},0,-1,1
+1002,nsIWebPageDescriptor,{6f30b676-3710-4c2c-80b1-0395fb26516e},0,-1,1
+1003,nsINetUtil,{57322c6f-f4ec-4e46-8253-b74be220de16},0,-1,1
+1004,nsIDOMHTMLParamElement,{a6cf90ad-15b3-11d2-932e-00805f8add32},0,-1,1
+1005,nsIServerSocket,{a5b64be0-d563-46bb-ae95-132e46fcd42f},0,-1,1
+1006,nsIDOMSVGFESpotLightElement,{5515dd05-3d9d-4d6c-8460-a04aaf5afe15},0,-1,1
+1007,jsdIObject,{d500e8b8-1dd1-11b2-89a1-cdf55d91cbbd},0,-1,1
+1008,jsdIScript,{a38f65ca-1dd1-11b2-95d5-ff2947e9c920},0,-1,1
+1009,nsIDOMNSEditableElement,{b33eb56c-3120-418c-892b-774b00c7dde8},0,-1,1
+1010,nsIClassInfo,{986c11d0-f340-11d4-9075-0010a4e73d9a},0,-1,1
+1011,nsIRDFService,{bfd05261-834c-11d2-8eac-00805f29f370},0,-1,1
+1012,nsISOCKSSocketInfo,{8f755c44-1dd2-11b2-a613-91117453fa95},0,-1,1
+1013,nsISupportsPriority,{aa578b44-abd5-4c19-8b14-36d4de6fdc36},0,-1,1
+1014,nsIKeyObjectFactory,{264eb54d-e20d-49a0-890c-1a5986ea81c4},0,-1,1
+1015,nsIWifiListener,{bcd4bede-f4a5-4a62-9071-d7a60174e376},0,-1,1
+1016,nsIInputStream,{fa9c7f6c-61b3-11d4-9877-00c04fa0cf4a},0,-1,1
+1017,nsISecurityCheckedComponent,{0dad9e8c-a12d-4dcb-9a6f-7d09839356e1},0,-1,1
+1018,nsIDOMSVGAnimatedPoints,{ebf334b3-86ef-4bf3-8a92-d775c72defa4},0,-1,1
+1019,nsIDOMHTMLFormElement,{a6cf908f-15b3-11d2-932e-00805f8add32},0,-1,1
+1020,nsIAnnotationObserver,{63fe98e0-6889-4c2c-ac9f-703e4bc25027},0,-1,1
+1021,nsIScriptableInterfacesByID,{c99cffac-5aed-4267-ad2f-f4a4c9d4a081},0,-1,1
+1022,nsIConverterOutputStream,{4b71113a-cb0d-479f-8ed5-01daeba2e8d4},0,-1,1
+1023,nsIDOMViewCSS,{0b9341f3-95d4-4fa4-adcd-e119e0db2889},0,-1,1
+1024,nsIEnvironment,{101d5941-d820-4e85-a266-9a3469940807},0,-1,1
+1025,nsIUpdatePatch,{56863a67-bd69-42de-9f40-583e625b457d},0,-1,1
+1026,nsITreeColumns,{f8a8d6b4-6788-438d-9009-7142798767ab},0,-1,1
+1027,nsIDOMHTMLHtmlElement,{a6cf9086-15b3-11d2-932e-00805f8add32},0,-1,1
+1028,nsIHttpProtocolHandler,{122c91c0-2485-40ba-89c9-b895934921bc},0,-1,1
+1029,nsIDOMSVGUnitTypes,{154b572f-3d0b-49c0-8b5d-8864d05bd3d1},0,-1,1
+1030,nsIRDFXMLSerializer,{8ae1fbf8-1dd2-11b2-bd21-d728069cca92},0,-1,1
+1031,nsICookie,{e9fcb9a4-d376-458f-b720-e65e7df593bc},0,-1,1
+1032,nsICMSEncoder,{a15789aa-8903-462b-81e9-4aa2cff4d5cb},0,-1,0
+1033,nsISelectElement,{35bd8ed5-5f34-4126-8c4f-38ba01681836},0,-1,1
+1034,nsIAddonRepository,{c4d2ac29-6edc-43cd-8dc8-e4cf213aa1be},0,-1,1
+1035,extIEventListener,{2dfe3a50-ab2f-11db-abbd-0800200c9a66},0,-1,1
+1036,nsIRDFContainer,{d4214e90-fb94-11d2-bdd8-00104bde6048},0,-1,1
+1037,nsIXPIInstallInfo,{5a4a775c-e452-4cf2-8ff8-d327ae24aec6},0,-1,1
+1038,nsINavBookmarksService,{3b6ff5c5-0ab4-4aab-b1be-d569763a6ce0},0,-1,1
+1039,nsIThreadManager,{056216f5-8803-46b4-9199-d95bc1f0446f},0,-1,1
+1040,nsIDOMLinkStyle,{24d89a65-f598-481e-a297-23cc02599bbd},0,-1,1
+1041,nsIDOMSVGPoint,{45f18f8f-1315-4447-a7d5-8aeca77bdcaf},0,-1,1
+1042,nsIXMLHttpRequest,{ad78bf21-2227-447e-8ed5-824a017c265f},0,-1,1
+1043,nsISupportsCString,{d65ff270-4a1c-11d3-9890-006008962422},0,-1,1
+1044,nsIDebug,{3bf0c3d7-3bd9-4cf2-a971-33572c503e1e},0,-1,1
+1045,IDispatch,{00020400-0000-0000-c000-000000000046},0,-1,1
+1046,nsIXPInstallManager,{83fdd52f-2d34-4e22-981d-cf3c4ae76faa},0,-1,1
+1047,nsIFeedResultListener,{4d2ebe88-36eb-4e20-bcd1-997b3c1f24ce},0,-1,1
+1048,nsIDOMTreeWalker,{400af3ca-1dd2-11b2-a50a-887ecca2e63a},0,-1,1
+1049,inICSSValueSearch,{e0d39e48-1dd1-11b2-81bd-9a0c117f0736},0,-1,1
+1050,nsIClipboardDragDropHookList,{876a2015-6b66-11d7-8f18-0003938a9d96},0,-1,1
+1051,nsIDOMSVGAnimatedString,{36f18f12-61a9-4529-8fa9-30050bd6ac00},0,-1,1
+1052,nsITreeView,{637276b5-58c0-4eff-89ea-c7f3c5bf0b54},0,-1,1
+1053,nsIDOMDocumentXBL,{1a38762b-4da5-4f61-80fb-9317e198cb92},0,-1,1
+1054,nsIObserverService,{d07f5192-e3d1-11d2-8acd-00105a1b8860},0,-1,1
+1055,nsIApplicationCacheService,{611161c8-37d0-450f-a4fe-457c47bbaf64},0,-1,1
+1056,nsIDBusHandlerApp,{1ffc274b-4cbf-4bb5-a635-05ad2cbb6534},0,-1,1
+1057,nsIDOMHTMLFrameSetElement,{a6cf90b8-15b3-11d2-932e-00805f8add32},0,-1,1
+1058,nsICertOverrideService,{31738d2a-77d3-4359-84c9-4be2f38fb8c5},0,-1,1
+1059,nsIPipe,{f4211abc-61b3-11d4-9877-00c04fa0cf4a},0,-1,1
+1060,nsINavHistoryBatchCallback,{5143f2bb-be0a-4faf-9acb-b0ed3f82952c},0,-1,1
+1061,nsIFactory,{00000001-0000-0000-c000-000000000046},0,-1,1
+1062,nsILoadContext,{314d8a54-1caf-4721-94d7-f6c82d9b82ed},0,-1,1
+1063,nsIProtectedAuthThread,{4bb27cb7-8984-4cee-8ce7-9b014c3d091b},0,-1,1
+1064,nsIFIXptrEvaluator,{50d28211-8fb8-4323-b93d-08a6e80e559e},0,-1,0
+1065,nsISupportsPRTime,{e2563630-4a1c-11d3-9890-006008962422},0,-1,1
+1066,nsIDOM3Text,{bcca052e-46f4-4b8e-8859-a86776c2f1d7},0,-1,1
+1067,nsIDOMSVGStopElement,{93169940-7663-4eab-af23-94a8a08c2654},0,-1,1
+1068,nsIJRILiveConnectPlugin,{c94058e0-f772-11d1-815b-006008119d7a},0,-1,0
+1069,inISearchProcess,{d5fa765b-2448-4686-b7c1-5ff13acb0fc9},0,-1,1
+1070,nsIDOMSVGRect,{5b912111-c10e-498f-a44c-c713c1843007},0,-1,1
+1071,nsISecurityPref,{94afd973-8045-4c6c-89e6-75bdced4209e},0,-1,0
+1072,nsIFeedTextConstruct,{fc97a2a9-d649-4494-931e-db81a156c873},0,-1,1
+1073,nsIIncrementalDownload,{6687823f-56c4-461d-93a1-7f6cb7dfbfba},0,-1,1
+1074,nsIDocShellHistory,{89caa9f0-8b1c-47fb-b0d3-f0aef0bff749},0,-1,1
+1075,nsICacheSession,{ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e},0,-1,1
+1076,txIFunctionEvaluationContext,{0ecbb00c-6a78-11d9-9791-000a95dc234c},0,-1,1
+1077,nsIDOMHTMLEmbedElement,{123f90ab-15b3-11d2-456e-00805f8add32},0,-1,1
+1078,nsIDOMHTMLAnchorElement,{a6cf90aa-15b3-11d2-932e-00805f8add32},0,-1,1
+1079,nsIApplicationCacheNamespace,{96e4c264-2065-4ce9-93bb-43734c62c4eb},0,-1,1
+1080,nsIProfileMigrator,{24ce8b9d-b7ff-4279-aef4-26e158f03e34},0,-1,1
+1081,nsIRDFPropagatableDataSource,{5a9b4770-9fcb-4307-a12e-4b6708e78b97},0,-1,1
+1082,mozISpellI18NUtil,{b075d5dc-1df1-441a-bebf-680d8caaa19c},0,-1,1
+1083,nsIGlobalHistory3,{24306852-c60e-49c3-a455-90f6747118ba},0,-1,1
+1084,nsIScriptEventHandler,{375f787f-8d3a-4344-b540-293d5645c22c},0,-1,0
+1085,nsIDOMChromeWindow,{77a20f5a-68ad-41d3-97ac-6ff721512908},0,-1,1
+1086,nsISupports,{00000000-0000-0000-c000-000000000046},0,-1,1
+1087,nsIFileProtocolHandler,{255602ea-c31f-4d29-8f35-905ead3f76f4},0,-1,1
+1088,nsILoginManagerIEMigrationHelper,{8a59ea3d-b8d0-48af-a3e2-63e27a02cde7},0,-1,1
+1089,nsIMicrosummarySet,{7111e88d-fecd-4b17-b7a9-1fa74e23153f},0,-1,1
+1090,nsIFeedEntry,{31bfd5b4-8ff5-4bfd-a8cb-b3dfbd4f0a5b},0,-1,1
+1091,nsIDOMSVGAnimatedAngle,{c6ab8b9e-32db-464a-ae33-8691d44bc60a},0,-1,1
+1092,nsIDOMGeoPositionError,{1b493214-4e58-4a40-aa4c-1ab70c6ddbec},0,-1,1
+1093,nsIXPCComponents_Constructor,{88655640-e028-11d3-8f5d-0010a4e73d9a},0,-1,1
+1094,nsIXPCException,{b2a34010-3983-11d3-9888-006008962422},0,-1,1
+1095,nsIRDFXMLSinkObserver,{eb1a5d30-ab33-11d2-8ec6-00805f29f370},0,-1,1
+1096,nsIDOMLSSerializer,{96ea4792-d362-4c28-a8c2-0337790d648a},0,-1,1
+1097,nsIUpdateChecker,{877ace25-8bc5-452a-8586-9c1cf2871994},0,-1,1
+1098,nsIOutputIterator,{7330650e-1dd2-11b2-a0c2-9ff86ee97bed},0,-1,1
+1099,nsIDOM3Attr,{a2216ddc-1bcd-4ec2-a292-371e09a6c377},0,-1,1
+1100,nsIDOMHTMLQuoteElement,{a6cf90a3-15b3-11d2-932e-00805f8add32},0,-1,1
+1101,nsIPlacesTransactionsService,{32eee5da-2bc7-4d18-8a54-a8ff0dec4d2a},0,-1,1
+1102,nsIX509Cert2,{5b62c61c-f898-4dab-8ace-51109bb459b4},0,-1,1
+1103,nsIFeedResultService,{950a829e-c20e-4dc3-b447-f8b753ae54da},0,-1,1
+1104,nsIMarkupDocumentViewer,{40b2282a-a882-4483-a634-dec468d88377},0,-1,1
+1105,txINodeSet,{15d424c0-6b47-11d9-9791-000a95dc234c},0,-1,1
+1106,nsIDOMSVGFEMergeNodeElement,{540c3447-4b07-4bd3-84df-30f66b68df14},0,-1,1
+1107,nsIEntropyCollector,{6f883680-ab9d-11d4-9978-00b0d02354a0},0,-1,0
+1108,nsIDOMSVGPathSegMovetoAbs,{30cf7749-bf1f-4f9c-9558-8ee24da3a22c},0,-1,1
+1109,nsIScriptableInputStream,{a2a32f90-9b90-11d3-a189-0050041caf44},0,-1,1
+1110,nsIDOMLSInput,{165e7f61-5048-4c2c-b4bf-6b44bb617ee4},0,-1,1
+1111,nsIWritablePropertyBag,{96fc4671-eeb4-4823-9421-e50fb70ad353},0,-1,1
+1112,nsIAutoCompleteResult,{d2fcba9a-3f5c-40fc-a9fc-4adc87dc61ef},0,-1,1
+1113,nsIScriptableUnicodeConverter,{1ea19c6c-c59f-4fd7-9fc7-151e946baca0},0,-1,1
+1114,nsIEditorIMESupport,{57032dcb-e8c7-4eb6-8ec6-a0f8e300809d},0,-1,1
+1115,nsISelection2,{5d21d5fe-3691-4716-a334-4691eea54d29},0,-1,1
+1116,nsIDOMHTMLHeadingElement,{a6cf90a2-15b3-11d2-932e-00805f8add32},0,-1,1
+1117,nsIWebNavigationInfo,{62a93afb-93a1-465c-84c8-0432264229de},0,-1,1
+1118,nsIAccessibleDocument,{b7ae45bd-21e9-4ed5-a67e-86448b25d56b},0,-1,1
+1119,nsIDOMCanvasRenderingContext2D,{66e6d87c-759c-43a7-b3d3-3348180b35df},0,-1,1
+1120,nsIStreamListener,{1a637020-1482-11d3-9333-00104ba0fd40},0,-1,1
+1121,nsIOutputStreamCallback,{40dbcdff-9053-42c5-a57c-3ec910d0f148},0,-1,1
+1122,jsdIScriptEnumerator,{4c2f706e-1dd2-11b2-9ebc-85a06e948830},0,-1,1
+1123,nsPIPluginInstancePeer,{4a708562-8a37-400b-8c08-20037d1adad3},0,-1,0
+1124,nsIBoxObject,{ce572460-b0f2-4650-a9e7-c53a99d3b6ad},0,-1,1
+1125,nsIXULChromeRegistry,{2860e205-490e-4b06-90b6-87160d35a5a7},0,-1,1
+1126,nsIScreenManager,{e224bd44-252b-4b66-b869-99738250904a},0,-1,1
+1127,nsIUpdateTimerManager,{0765c92c-6145-4253-9db4-594d8023087e},0,-1,1
+1128,nsIJSCID,{26b2a374-6eaf-46d4-acaf-1c6be152d36b},0,-1,1
+1129,nsIDOMNSElement,{f0aef489-18c5-4de6-99d5-58b3758b098c},0,-1,1
+1130,nsIHttpChannel,{9277fe09-f0cc-4cd9-bbce-581dd94b0260},0,-1,1
+1131,txIEXSLTRegExFunctions,{c180e993-aced-4839-95a0-ecd5ff138be9},0,-1,1
+1132,nsIPrinterEnumerator,{5e738fff-404c-4c94-9189-e8f2cce93e94},0,-1,1
+1133,mozISpellI18NManager,{aeb8936f-219c-4d3c-8385-d9382daa551a},0,-1,1
+1134,nsIPluginInstance,{ebe00f40-0199-11d2-815b-006008119d7a},0,-1,0
+1135,nsIDownload,{c891111e-92a6-47b8-bc46-874ebb61ac9d},0,-1,1
+1136,nsIObjectLoadingContent,{90ab443e-3e99-405e-88c9-9c42adaa3217},0,-1,1
+1137,nsIBrowserDOMWindow,{f9691a49-7fb3-4b54-bb11-a4f2e0b6eddb},0,-1,1
+1138,nsIAuthPromptProvider,{bd9dc0fa-68ce-47d0-8859-6418c2ae8576},0,-1,1
+1139,nsISelection,{b2c7ed59-8634-4352-9e37-5484c8b6e4e1},0,-1,1
+1140,nsIAccessibleRole,{8c0f68f8-164a-4078-a9ee-36a7d180f0e4},0,-1,1
+1141,nsIRDFInt,{e13a24e3-c77a-11d2-80be-006097b76b8e},0,-1,1
+1142,nsIXPointerSchemeProcessor,{093d3559-b56b-44d0-8764-c25815715080},0,-1,0
+1143,nsIDOMSVGLengthList,{a8760fcd-3de5-446a-a009-5cf877e7a4df},0,-1,1
+1144,nsIRDFDelegateFactory,{a1b89470-a124-11d3-be59-0020a6361667},0,-1,1
+1145,nsIWebContentConverterService,{de7cc06e-e778-45cb-b7db-7a114e1e75b1},0,-1,1
+1146,nsIUrlClassifierHashCompleterCallback,{bbd6c954-7cb4-4447-bc55-8cefd1ceed89},0,-1,1
+1147,nsIX509CertDB2,{e0df4784-6560-45bf-b1b7-86076a0e8381},0,-1,1
+1148,nsIDOMTextMetrics,{2d01715c-ec7d-424a-ab85-e0fd70c8665c},0,-1,1
+1149,nsILoadGroup,{3de0a31c-feaf-400f-9f1e-4ef71f8b20cc},0,-1,1
+1150,nsIExtensionManager,{7fbb049a-00e6-4ce2-82fc-854c52788df9},0,-1,1
+1151,nsICharsetResolver,{d143a084-b626-4614-845f-41f3ca43a674},0,-1,1
+1152,nsIEditActionListener,{b22907b1-ee93-11d2-8d50-000064657374},0,-1,1
+1153,nsICookieManager2,{5047cab4-9cb2-4927-a4ab-77422bc3bc67},0,-1,1
+1154,nsIUserCertPicker,{06d018e0-d41b-4629-a4fc-daaa6029888e},0,-1,1
+1155,nsICommandHandlerInit,{731c6c50-67d6-11d4-9529-0020183bf181},0,-1,1
+1156,nsIDOMSVGAElement,{35d3365a-3e6f-4cdf-983d-fdaed1564478},0,-1,1
+1157,nsIDOMSVGTransform,{29cc2e14-6d18-4710-bda9-a88d9d3bc8dc},0,-1,1
+1158,nsICommandLineRunner,{c1f4cfbf-a41f-4628-aa6c-9fb914478af8},0,-1,0
+1159,nsIPromptService2,{cf86d196-dbee-4482-9dfa-3477aa128319},0,-1,1
+1160,nsIDOMDocument,{a6cf9075-15b3-11d2-932e-00805f8add32},0,-1,1
+1161,nsIPluginStreamListener,{df055770-5448-11d2-8164-006008119d7a},0,-1,0
+1162,mozIStorageAggregateFunction,{763217b7-3123-11da-918d-000347412e16},0,-1,1
+1163,nsPIExternalAppLauncher,{d0b5d7d3-9565-403d-9fb5-e5089c4567c6},0,-1,1
+1164,nsIDOMProcessingInstruction,{a6cf907f-15b3-11d2-932e-00805f8add32},0,-1,1
+1165,nsITreeBoxObject,{64ba5199-c4f4-4498-bbdc-f8e4c369086c},0,-1,1
+1166,nsIDOMNSRange,{59188642-23b4-41d6-bde1-302c3906d1f0},0,-1,1
+1167,nsIDOMSVGAngle,{58b6190e-37b3-412a-ba02-1d5ad6c6ea7c},0,-1,1
+1168,nsIDOMXPathEvaluator,{75506f8a-b504-11d5-a7f2-ca108ab8b6fc},0,-1,1
+1169,nsIXPointerEvaluator,{addd0fe5-8555-45b7-b763-97d5898ce268},0,-1,0
+1170,nsISecretDecoderRing,{0ec80360-075c-11d4-9fd4-00c04f1b83d8},0,-1,1
+1171,nsIAutoCompleteMdbResult2,{148c9dc5-0fbb-408b-80fe-544f6a85b433},0,-1,0
+1172,nsIPrintOptions,{92597c2b-109b-40bb-8f93-9b9acfa31de8},0,-1,1
+1173,nsIHttpActivityObserver,{412880c8-6c36-48d8-bf8f-84f91f892503},0,-1,1
+1174,nsITraceableChannel,{68167b0b-ef34-4d79-a09a-8045f7c5140e},0,-1,1
+1175,nsIBrowserBoxObject,{db436f2f-c656-4754-b0fa-99bc353bd63f},0,-1,1
+1176,nsIAddonInstallListener,{2333b04c-f371-4dea-a2f1-d8fdb0c82866},0,-1,1
+1177,nsIDOMGeoPositionCoords,{b31702d0-6dac-4fa0-b93b-f043e71c8f9a},0,-1,1
+1178,nsIDOMElementCSSInlineStyle,{99715845-95fc-4a56-aa53-214b65c26e22},0,-1,1
+1179,nsIDOMSVGNumber,{98575762-a936-4ecf-a226-b74c3a2981b4},0,-1,1
+1180,nsICommandLine,{bc3173bd-aa46-46a0-9d25-d9867a9659b6},0,-1,1
+1181,nsIDOMModalContentWindow,{51aebd45-b979-4ec6-9d11-3a3fd3d5d59e},0,-1,1
+1182,nsIRDFXMLParser,{1831dd2e-1dd2-11b2-bdb3-86b7b50b70b5},0,-1,1
+1183,nsICryptoHash,{1e5b7c43-4688-45ce-92e1-77ed931e3bbe},0,-1,1
+1184,nsIAnnotationService,{ba249b58-346f-42a9-a393-203ae34ec6c4},0,-1,1
+1185,nsIDOMHTMLStyleElement,{a6cf908d-15b3-11d2-932e-00805f8add32},0,-1,1
+1186,nsIDOMNSHTMLFormElement,{a6cf90c6-15b3-11d2-932e-00805f8add32},0,-1,1
+1187,nsIAuthPromptWrapper,{6228d644-17fe-11d4-8cee-0060b0fc14a3},0,-1,1
+1188,nsICollection,{83b6019c-cbc4-11d2-8cca-0060b0fc14a3},0,-1,1
+1189,nsIStringBundleOverride,{965eb278-5678-456b-82a7-20a0c86a803c},0,-1,1
+1190,nsIAuthPromptCallback,{bdc387d7-2d29-4cac-92f1-dd75d786631d},0,-1,1
+1191,nsIJSXMLHttpRequest,{423fdd3d-41c9-4149-8fe5-b14a1d3912a0},0,-1,1
+1192,nsIDOMSVGFEFuncGElement,{28555e78-c6c2-4a98-af53-bfc2c6944295},0,-1,1
+1193,nsIProgressEventSink,{d974c99e-4148-4df9-8d98-de834a2f6462},0,-1,1
+1194,nsIDOMSVGFETurbulenceElement,{77bc4d70-0d49-4c81-b7a7-7432f0fe3e04},0,-1,1
+1195,nsIDOMXULControlElement,{007b8358-1dd2-11b2-8924-d209efc3f124},0,-1,1
+1196,nsICacheDeviceInfo,{31d1c294-1dd2-11b2-be3a-c79230dca297},0,-1,1
+1197,imgITools,{c395d8f1-c616-4a1b-adfd-747b4b1b2cbe},0,-1,1
+1198,nsIContentViewerFile,{6317f32c-9bc7-11d3-bccc-0060b0fc76bd},0,-1,1
+1199,nsIDOMSVGPatternElement,{bc435244-b748-4e14-9e4c-219d5d3cb218},0,-1,1
+1200,nsIAccessibleCoordinateType,{c9fbdf10-619e-436f-bf4b-8566686f1577},0,-1,1
+1201,nsIConverterInputStream,{fc66ffb6-5404-4908-a4a3-27f92fa0579d},0,-1,1
+1202,nsIScreen,{f728830e-1dd1-11b2-9598-fb9f414f2465},0,-1,1
+1203,nsIDOMCSSPrimitiveValue,{e249031f-8df9-4e7a-b644-18946dce0019},0,-1,1
+1204,nsIDOMXULTextBoxElement,{71135b6c-294e-4634-a8e4-a72398f1e72a},0,-1,1
+1205,nsIDirIndexParser,{38e3066c-1dd2-11b2-9b59-8be515c1ee3f},0,-1,1
+1206,nsIDOMRGBColor,{6aff3102-320d-4986-9790-12316bb87cf9},0,-1,1
+1207,nsIDOMHTMLTableCaptionElement,{a6cf90b3-15b3-11d2-932e-00805f8add32},0,-1,1
+1208,nsIIFrameBoxObject,{30114c44-d398-44a5-9e01-b48b711291cd},0,-1,1
+1209,nsIFaviconService,{fafe10e0-194f-4e89-aab9-a5849e97287c},0,-1,1
+1210,nsIPopupWindowManager,{3210a6aa-b464-4f57-9335-b22815567cf1},0,-1,1
+1211,extIEventItem,{05281820-ab62-11db-abbd-0800200c9a66},0,-1,1
+1212,nsIDOM3TypeInfo,{2a1088c7-499a-49a7-9d3b-1970d21532ab},0,-1,1
+1213,nsIStringBundle,{d85a17c2-aa7c-11d2-9b8c-00805f8a16d9},0,-1,1
+1214,nsIDOMFileList,{3bfef9fa-8ad3-4e49-bd62-d6cd75b29298},0,-1,1
+1215,nsIZipReader,{5cce7f53-23b3-47f8-be05-122c0ba703fd},0,-1,1
+1216,nsIWebContentHandlerInfo,{eb361098-5158-4b21-8f98-50b445f1f0b2},0,-1,1
+1217,nsIDOMNSHTMLFormControlList,{a6cf911a-15b3-11d2-932e-00805f8add32},0,-1,1
+1218,nsINavHistoryResultTreeViewer,{fa77e4e9-9fc8-45d2-9507-0fe4f0602505},0,-1,1
+1219,nsIXPCComponents_ClassesByID,{336a9590-4d19-11d3-9893-006008962422},0,-1,1
+1220,nsILoginManagerStorage,{e66c97cd-3bcf-4eee-9937-38f650372d77},0,-1,1
+1221,nsIPrintingPromptService,{75d1553d-63bf-4b5d-a8f7-e4e4cac21ba4},0,-1,1
+1222,nsIDOMNSXPathExpression,{ce600ca8-e98a-4419-ad61-2f6d0cb0ecc8},0,-1,1
+1223,nsINavHistoryResultNode,{47cf89e3-4777-46bf-9677-21793870ce62},0,-1,1
+1224,nsIDragSession,{15860d52-fe2c-4ddd-ac50-9c23e24916c4},0,-1,1
+1225,nsITransactionList,{97f863f3-f886-11d4-9d39-0060b0f8baff},0,-1,1
+1226,nsIDOMSVGPathSegCurvetoCubicRel,{0e661233-0c4f-4e0d-94d3-fbc460ad1f88},0,-1,1
+1227,nsIScrollable,{919e792a-6490-40b8-bba5-f9e9ad5640c8},0,-1,1
+1228,gfxIFormats,{96d086e6-1dd1-11b2-b6b2-b77b59390247},0,-1,1
+1229,nsISupportsPRBool,{ddc3b490-4a1c-11d3-9890-006008962422},0,-1,1
+1230,nsIDOMNodeFilter,{e4723748-1dd1-11b2-8ee6-866a532a6237},0,-1,1
+1231,nsISocketTransportService,{185b3a5d-8729-436d-9693-7bdccb9c2216},0,-1,1
+1232,nsIDOMNavigatorGeolocation,{9f218d6a-42ec-4b8a-aee9-e29ca96a4eae},0,-1,1
+1233,nsISelectionDisplay,{0ddf9e1c-1dd2-11b2-a183-908a08aa75ae},0,-1,1
+1234,nsIObserver,{db242e01-e4d9-11d2-9dde-000064657374},0,-1,1
+1235,nsIJSID,{baedc96a-9cee-4b6b-9160-90d257b3c8ef},0,-1,1
+1236,nsIGnomeVFSMimeApp,{66009894-9877-405b-9321-bf30420e34e6},0,-1,1
+1237,nsIPrintProgressParams,{ca89b55b-6faf-4051-9645-1c03ef5108f8},0,-1,1
+1238,nsIDOMDragEvent,{18feefd7-a461-4865-bcf1-4dc8a2f30584},0,-1,1
+1239,nsIProtocolHandler,{15fd6940-8ea7-11d3-93ad-00104ba0fd40},0,-1,1
+1240,nsIHTMLObjectResizeListener,{27b00295-349c-429f-ad0c-87b859e77130},0,-1,1
+1241,nsIKeygenThread,{8712a243-5539-447c-9f47-8653f40c3a09},0,-1,1
+1242,nsIPersistentProperties,{1a180f60-93b2-11d2-9b8b-00805f8a16d9},0,-1,1
+1243,nsIXPCComponents_utils_Sandbox,{4f8ae0dc-d266-4a32-875b-6a9de71a8ce9},0,-1,1
+1244,nsIScriptableUnescapeHTML,{3ab244a9-f09d-44da-9e3f-ee4d67367f2d},0,-1,1
+1245,nsITransactionManager,{58e330c2-7b48-11d2-98b9-00805f297d89},0,-1,1
+1246,nsIURIRefObject,{2226927e-1dd2-11b2-b57f-faab47288563},0,-1,1
+1247,nsIDOMNSHTMLOptionElement,{e2dfc89c-7ae0-4651-8aee-7f5edc2aa626},0,-1,1
+1248,imgIDecoderObserver,{876f14ee-f27c-41cd-b6fb-9efda3ebc7b5},0,-1,1
+1249,nsICookieService,{2aaa897a-293c-4d2b-a657-8c9b7136996d},0,-1,1
+1250,nsIDOMEventTarget,{1c773b30-d1cf-11d2-bd95-00805f8ae3f4},0,-1,1
+1251,nsIWorkerScope,{d30a2f61-86e2-434e-837f-4f1985efa865},0,-1,1
+1252,nsIDOMSVGScriptElement,{bbe0d0ee-e9ed-4f84-a6e4-e58f66530caa},0,-1,1
+1253,nsIFTPEventSink,{455d4234-0330-43d2-bbfb-99afbecbfeb0},0,-1,1
+1254,nsIPermissionManager,{00708302-684c-42d6-a5a3-995d51b1d17c},0,-1,1
+1255,nsIXPCComponents,{155809f1-71f1-47c5-be97-d812ba560405},0,-1,1
+1256,nsIBlocklistService,{8439f9c0-da03-4260-8b21-dc635eed28fb},0,-1,1
+1257,nsIDOMEntity,{a6cf9079-15b3-11d2-932e-00805f8add32},0,-1,1
+1258,nsIWifiMonitor,{f289701e-d9af-4685-bc2f-e4226ff7c018},0,-1,1
+1259,nsIDOMHTMLBaseElement,{a6cf908b-15b3-11d2-932e-00805f8add32},0,-1,1
+1260,nsIController,{d5b61b82-1da4-11d3-bf87-00105a1b0627},0,-1,1
+1261,nsIFileInputStream,{e3d56a20-c7ec-11d3-8cda-0060b0fc14a3},0,-1,1
+1262,nsIDOMHTMLMenuElement,{a6cf909d-15b3-11d2-932e-00805f8add32},0,-1,1
+1263,nsIDOMHTMLDivElement,{a6cf90a0-15b3-11d2-932e-00805f8add32},0,-1,1
+1264,nsIUpdate,{9d6a388b-2e0c-4d0e-9a60-5c9739a7ada5},0,-1,1
+1265,nsIPlacesImportExportService,{21c00314-fa63-11db-8314-0800200c9a66},0,-1,1
+1266,nsIDOMXULLabeledControlElement,{a457ea70-1dd1-11b2-9089-8fd894122084},0,-1,1
+1267,nsIZipWriter,{6d4ef074-206c-4649-9884-57bc355864d6},0,-1,1
+1268,nsIDOMSVGLineElement,{4ea07ef3-ed66-4b41-8119-4afc6d0ed5af},0,-1,1
+1269,nsIWifiAccessPoint,{e28e614f-8f86-44ff-bcf5-5f18225834a0},0,-1,1
+1270,nsISAXMutableAttributes,{8b1de83d-cebb-49fa-8245-c0fe319eb7b6},0,-1,1
+1271,nsIDOMXULSelectControlItemElement,{6aaaa30d-54ab-434a-8ae8-6d29a566d870},0,-1,1
+1272,nsIPrefBranchInternal,{d1d412d9-15d6-4a6a-9533-b949dc175ff5},0,-1,1
+1273,nsIDOMSVGPathSegList,{94a6db98-3f34-4529-a35f-89ef49713795},0,-1,1
+1274,nsISupportsPRUint16,{dfacb090-4a1c-11d3-9890-006008962422},0,-1,1
+1275,mozIStorageStatement,{4a712295-d076-4007-9c78-8c0e15373b9f},0,-1,1
+1276,nsIProperties,{78650582-4e93-4b60-8e85-26ebd3eb14ca},0,-1,1
+1277,nsIDOMLSLoadEvent,{6c16a810-a37d-4859-b557-337341631aee},0,-1,1
+1278,nsIDOMNavigator,{777bd8a1-38c1-4b12-ba8f-ff6c2eb8c56b},0,-1,1
+1279,nsIDOMHTMLVoidCallback,{4a17c0e2-fdd5-4855-a71c-b4c509dffa13},0,-1,1
+1280,nsPIEditorTransaction,{4f18ada2-0ddc-11d5-9d3a-0060b0f8baff},0,-1,1
+1281,nsISearchSubmission,{58e4f602-a7c8-4cd1-9dca-716705e826ef},0,-1,1
+1282,nsIDOMWindowInternal,{3414ebc7-731f-4697-9f43-aca6f5050875},0,-1,1
+1283,nsIDOMSVGFilterPrimitiveStandardAttributes,{ab68567a-b830-4c46-9f2f-a28513a9e980},0,-1,1
+1284,nsIDOMOfflineResourceList,{f394a721-66e9-46fc-bb24-b980bb732dd0},0,-1,1
+1285,nsIPrintSettings,{5af07661-6477-4235-8814-4a45215855b8},0,-1,1
+1286,nsISupportsInterfacePointer,{995ea724-1dd1-11b2-9211-c21bdd3e7ed0},0,-1,1
+1287,nsIFlavorDataProvider,{7e225e5f-711c-11d7-9fae-000393636592},0,-1,1
+1288,nsIDOMSVGSymbolElement,{86092181-a5db-4a89-be03-07dcc14d426e},0,-1,1
+1289,nsIUnicharStreamListener,{4a7e9b62-fef8-400d-9865-d6820f630b4c},0,-1,1
+1290,jsdIStackFrame,{b6d50784-1dd1-11b2-a932-882246c6fe45},0,-1,1
+1291,nsIDOMNSDataTransfer,{53c854fc-33f9-4647-b045-46d7ab06a6f1},0,-1,1
+1292,nsIDOMXULDocument,{9816241b-2a20-44ff-903b-575f40c0ecc5},0,-1,1
+1293,nsIEditorSpellCheck,{90c93610-c116-44ab-9793-62dccb9f43ce},0,-1,1
+1294,nsIDOMHTMLScriptElement,{a6cf90b1-15b3-11d2-932e-00805f8add32},0,-1,1
+1295,nsIWebBrowserChromeFocus,{d2206418-1dd1-11b2-8e55-acddcd2bcfb8},0,-1,1
+1296,nsIEntityConverter,{d14c7111-55e0-11d3-91d9-00105aa3f7dc},0,-1,1
+1297,nsISimpleEnumerator,{d1899240-f9d2-11d2-bdd6-000064657374},0,-1,1
+1298,nsIEmbeddingSiteWindow2,{e932bf55-0a64-4beb-923a-1f32d3661044},0,-1,1
+1299,nsIBufferedOutputStream,{6476378a-da09-11d3-8cda-0060b0fc14a3},0,-1,1
+1300,nsIDocumentEncoder,{f85c5a20-258d-11db-a98b-0800200c9a66},0,-1,1
+1301,nsIChannelEventSink,{6757d790-2916-498e-aaca-6b668a956875},0,-1,1
+1302,nsIXPCComponents_Utils,{da2267f2-d4cc-448f-9d70-1c7fe134d2fe},0,-1,1
+1303,nsINavHistoryContainerResultNode,{f9c8e1c1-e701-44ad-893c-8504c3956929},0,-1,1
+1304,nsIPrintingPrompt,{44e314ca-75b1-4f3d-9553-9b3507912108},0,-1,1
+1305,nsIDOMHTMLOptionElement,{a6cf9092-15b3-11d2-932e-00805f8add32},0,-1,1
+1306,nsISupportsPRInt32,{e36c5250-4a1c-11d3-9890-006008962422},0,-1,1
+1307,nsIDOMSVGPathSegArcAbs,{c9e222e5-31fd-4083-ae1f-fcf013681340},0,-1,1
+1308,nsIFrameLoader,{d675c531-6bdc-417c-b176-635060105f07},0,-1,1
+1309,nsIDOMSVGPathSegLinetoVerticalRel,{d3ef2128-8de3-4aac-a6b4-13c7563119a6},0,-1,1
+1310,nsIDOMXULCommandDispatcher,{f3c50361-14fe-11d3-bf87-00105a1b0627},0,-1,1
+1311,nsIDOMGeoGeolocation,{37687daf-b85f-4e4d-8881-85a0ad24cf78},0,-1,1
+1312,nsIX509CertDB,{da48b3c0-1284-11d5-ac67-000064657374},0,-1,1
+1313,nsIDOMRangeException,{0f807301-39d2-11d6-a7f2-8f504ff870dc},0,-1,1
+1314,extIPreference,{2c7462e2-72c2-4473-9007-0e6ae71e23ca},0,-1,1
+1315,nsICryptoHMAC,{8feb4c7c-1641-4a7b-bc6d-1964e2099497},0,-1,1
+1316,nsILineInputStream,{c97b466c-1e6e-4773-a4ab-2b2b3190a7a6},0,-1,1
+1317,nsIWeakReference,{9188bc85-f92e-11d2-81ef-0060083a0bcf},0,-1,1
+1318,nsIAccessibleHyperLink,{38c60bfa-6040-4bfe-93f2-acd6a909bb60},0,-1,1
+1319,nsIWebProgress,{570f39d0-efd0-11d3-b093-00a024ffc08c},0,-1,1
+1320,nsIForwardIterator,{8da01646-1dd2-11b2-98a7-c7009045be7e},0,-1,1
+1321,inIFlasher,{7b4a099f-6f6e-4565-977b-fb622adbff49},0,-1,1
+1322,nsIBadCertListener2,{2c3d268c-ad82-49f3-99aa-e9ffddd7a0dc},0,-1,1
+1323,nsIDOMClientRectList,{917da19d-62f5-441d-b47e-9e35f05639c9},0,-1,1
+1324,nsIDOMSmartCardEvent,{52bdc7ca-a934-4a40-a2e2-ac83a70b4019},0,-1,1
+1325,nsIXULRuntime,{2848ab92-d912-11d9-89f7-001124787b2e},0,-1,1
+1326,nsIRemoteService,{a2240f6a-f1e4-4548-9e1a-6f3bc9b2426c},0,-1,1
+1327,nsIDOMXPathResult,{75506f84-b504-11d5-a7f2-ca108ab8b6fc},0,-1,1
+1328,nsIDOMSVGLocatable,{9cf4fc9c-90b2-4d66-88f5-35049b558aee},0,-1,1
+1329,nsIWebBrowserFind,{2f977d44-5485-11d4-87e2-0010a4e75ef2},0,-1,1
+1330,nsICryptoFIPSInfo,{99e81922-7318-4431-b3aa-78b3cb4119bb},0,-1,1
+1331,nsIDOMSVGUseElement,{d49a3ac7-e779-46c8-ae92-214420aa1b71},0,-1,1
+1332,nsICertVerificationResult,{2fd0a785-9f2d-4327-8871-8c3e0783891d},0,-1,1
+1333,nsIDOMXULMultiSelectControlElement,{82c72eca-9886-473e-94cd-9de5694b3f88},0,-1,1
+1334,nsIMicrosummaryService,{d58143a2-74fa-4b13-94ed-113af8936d80},0,-1,1
+1335,nsIControllers,{f36e3ec1-9197-4ad8-8d4c-d3b1927fd6df},0,-1,1
+1336,jsdIErrorHook,{b7dd3c1c-1dd1-11b2-83eb-8a857d199e0f},0,-1,1
+1337,nsIDOMHTMLInputElement,{a6cf9093-15b3-11d2-932e-00805f8add32},0,-1,1
+1338,mozIStorageStatementCallback,{29383d00-d8c4-4ddd-9f8b-c2feb0f2fcfa},0,-1,1
+1339,nsIDOMSVGGElement,{0bd57cbd-a090-44aa-a61b-2fb876841194},0,-1,1
+1340,nsPIAccessibleTreeItem,{b71532f9-53b2-4647-a5b2-1c5f57e9aed6},0,-1,0
+1341,nsICipherInfo,{028e2b2a-1f0b-43a4-a1a7-365d2d7f35d0},0,-1,1
+1342,nsIDOMGeoPosition,{76888eb0-5eab-4be6-bfe0-489ec4095358},0,-1,1
+1343,nsIDOMHTMLBaseFontElement,{a6cf90a6-15b3-11d2-932e-00805f8add32},0,-1,1
+1344,nsIDOMXULCheckboxElement,{5afaba88-1dd2-11b2-9249-dd65a129d0e4},0,-1,1
+1345,nsIDOMHTMLMediaError,{7bd8c29f-8a76-453f-9373-79f820f2dc01},0,-1,1
+1346,nsIDOMWindow,{a6cf906b-15b3-11d2-932e-00805f8add32},0,-1,1
+1347,nsIDOMHTMLDirectoryElement,{a6cf909c-15b3-11d2-932e-00805f8add32},0,-1,1
+1348,nsIBrowserProfileMigrator,{f8365b4a-da55-4e47-be7a-230142360f62},0,-1,1
+1349,nsIDOMSVGSwitchElement,{7676f306-22c9-427e-bd71-2b1315851c93},0,-1,1
+1350,nsIBrowserHandler,{8d3f5a9d-118d-4548-a137-cf7718679069},0,-1,1
+1351,nsIURIChecker,{4660c1a1-be2d-4c78-9baf-c22984176c28},0,-1,1
+1352,nsIDOMNSHTMLAreaElement,{3dce9071-f3b9-4280-a6ee-776cdfe3dd9e},0,-1,1
+1353,nsIDOMDataTransfer,{b5947dd0-8e86-4b9c-aa65-c86303efcf94},0,-1,1
+1354,nsIDOMHTMLImageElement,{a6cf90ab-15b3-11d2-932e-00805f8add32},0,-1,1
+1355,nsILocalFileWin,{def38371-73b0-4dfd-85cd-0a7c91afbec6},0,-1,1
+1356,nsIDOMHTMLTextAreaElement,{a6cf9094-15b3-11d2-932e-00805f8add32},0,-1,1
+1357,nsIDOMCommandEvent,{37fb1798-0f76-4870-af6f-0135b4d973c8},0,-1,1
+1358,nsIFeedContainer,{577a1b4c-b3d4-4c76-9cf8-753e6606114f},0,-1,1
+1359,nsIDOMXULButtonElement,{6852d9a6-1dd2-11b2-a29d-cd7977a91b1b},0,-1,1
+1360,nsIXULTemplateQueryProcessor,{970f1c36-5d2e-4cbc-a1cf-e3327b50df71},0,-1,1
+1361,nsIEmbeddingSiteWindow,{3e5432cd-9568-4bd1-8cbe-d50aba110743},0,-1,1
+1362,nsIDOMSVGFEPointLightElement,{557f128a-026b-4fa8-a44c-605df7bfd62e},0,-1,1
+1363,nsIDOMSVGFitToViewBox,{089410f3-9777-44f1-a882-ab4225696434},0,-1,1
+1364,jsdIFilterEnumerator,{54382875-ed12-4f90-9a63-1f0498d0a3f2},0,-1,1
+1365,nsINavHistoryQuery,{53b51afe-9de8-40ad-9c81-f2cc1701f1ff},0,-1,1
+1366,nsIXPConnectWrappedNative,{7021d99d-6344-4cc0-96e7-943ed58792b8},0,-1,0
+1367,nsIDNSService,{c1a56a45-8fa3-44e6-9f01-38c91c858cf9},0,-1,1
+1368,nsIPK11Token,{51191434-1dd2-11b2-a17c-e49c4e99a4e3},0,-1,1
+1369,nsIControllerCommand,{0eae9a46-1dd2-11b2-aca0-9176f05fe9db},0,-1,1
+1370,nsIXSLTProcessorPrivate,{b8d727f7-67f4-4dc1-a318-ec0c87280816},0,-1,1
+1371,nsISessionStartup,{c0b185e7-0d21-46ac-8eee-7b5065ee7ecd},0,-1,1
+1372,nsIDOMNSHTMLAnchorElement2,{d7627eda-6ec0-4326-87c4-c3067fe6e324},0,-1,1
+1373,nsIWebBrowserStream,{86d02f0e-219b-4cfc-9c88-bd98d2cce0b8},0,-1,1
+1374,nsITimerCallback,{a796816d-7d47-4348-9ab8-c7aeb3216a7d},0,-1,1
+1375,nsINSSCertCache,{1b75bdae-1757-4322-9d1e-cfcaa18cb710},0,-1,1
+1376,nsISocketProviderService,{8f8a23d0-5472-11d3-bbc8-0000861d1237},0,-1,1
+1377,nsIZipReaderCache,{52c45d86-0cc3-11d4-986e-00c04fa0cf4a},0,-1,1
+1378,nsIWebProgressListener2,{dde39de0-e4e0-11da-8ad9-0800200c9a66},0,-1,1
+1379,nsIAuthPrompt,{358089f9-ee4b-4711-82fd-bcd07fc62061},0,-1,1
+1380,jsdINestCallback,{88bea60f-9b5d-4b39-b08b-1c3a278782c6},0,-1,1
+1381,nsIHTTPIndex,{6f2bdbd0-58c3-11d3-be36-00104bde6048},0,-1,1
+1382,nsIDOMDocumentRange,{7b9badc6-c9bc-447a-8670-dbd195aed24b},0,-1,1
+1383,nsICMSMessage,{a4557478-ae16-11d5-ba4b-00108303b117},0,-1,0
+1384,nsIProfileUnlocker,{08923af1-e7a3-4fae-ba02-128502193994},0,-1,1
+1385,nsIDOMNodeIterator,{5af83f50-c8d5-4824-be29-1aa9d640bacb},0,-1,1
+1386,nsIDOMSVGAnimatedPathData,{6ef2b400-dbf4-4c12-8787-fe15caac5648},0,-1,1
+1387,nsIEncodedChannel,{30d7ec3a-f376-4652-9276-3092ec57abb6},0,-1,1
+1388,nsIXPTLoaderSink,{6e48c500-8682-4730-add6-7db693b9e7ba},0,-1,1
+1389,nsIDOMNSHTMLDocument,{79beb289-3644-4b54-9432-9fb993945629},0,-1,1
+1390,nsIAccessibleValue,{42a1e1dc-58cf-419d-bff0-ed3314c70016},0,-1,1
+1391,nsIAtom,{3d1b15b0-93b4-11d1-895b-006008911b81},0,-1,1
+1392,nsIAsyncOutputStream,{beb632d3-d77a-4e90-9134-f9ece69e8200},0,-1,1
+1393,nsIDOMEntityReference,{a6cf907a-15b3-11d2-932e-00805f8add32},0,-1,1
+1394,nsIXTFElementWrapper,{0ad87068-c6fd-4122-a515-ffe8c4773b10},0,-1,1
+1395,nsIUpdatePrompt,{599fd3c6-ec68-4499-ada5-2997739c97a6},0,-1,1
+1396,nsIDOMSVGRectElement,{1695ca39-e40d-44dc-81db-a51b6fd234fa},0,-1,1
+1397,mozITXTToHTMLConv,{77c0e42a-1dd2-11b2-8ebf-edc6606f2f4b},0,-1,1
+1398,nsIMicrosummaryObserver,{560b0980-be95-47e9-81cc-4428c073127c},0,-1,1
+1399,mozIJSSubScriptLoader,{8792d77e-1dd2-11b2-ac7f-9bc9be4f2916},0,-1,1
+1400,nsIDocShellLoadInfo,{92a0a637-373e-4647-9476-ead11e005c75},0,-1,1
+1401,nsIXPCComponents_Results,{2fc229a0-5860-11d3-9899-006008962422},0,-1,1
+1402,nsIDOMLoadStatusEvent,{f14431b1-efb6-436c-a272-312f087b1459},0,-1,1
+1403,nsIMemory,{59e7e77a-38e4-11d4-8cf5-0060b0fc14a3},0,-1,1
+1404,nsIContentViewerEdit,{1691a02f-53b2-4cb8-8769-48e7efc908b8},0,-1,1
+1405,nsISupportsPrimitive,{d0d4b136-1dd1-11b2-9371-f0727ef827c0},0,-1,1
+1406,nsIEditorStyleSheets,{4805e682-49b9-11d3-9ce4-ed60bd6cb5bc},0,-1,1
+1407,rdfISerializer,{f0edfcdd-8bca-4d32-9226-7421001396a4},0,-1,1
+1408,nsIDOMSVGPolygonElement,{9de04775-77c5-48b5-9f4a-8996a936bfb2},0,-1,1
+1409,nsIDOMStorageList,{f2166929-91b6-4372-8d5f-c366f47a5f54},0,-1,1
+1410,nsIWritablePropertyBag2,{9cfd1587-360e-4957-a58f-4c2b1c5e7ed9},0,-1,1
+1411,nsIDocumentStateListener,{050cdc00-3b8e-11d3-9ce4-a458f454fcbc},0,-1,1
+1412,nsISHTransaction,{2edf705f-d252-4971-9f09-71dd0f760dc6},0,-1,1
+1413,nsIDOMHTMLIsIndexElement,{a6cf908c-15b3-11d2-932e-00805f8add32},0,-1,1
+1414,nsIASN1Sequence,{b6b957e6-1dd1-11b2-89d7-e30624f50b00},0,-1,1
+1415,nsIDOMHTMLAppletElement,{a6cf90ae-15b3-11d2-932e-00805f8add32},0,-1,1
+1416,nsIDOMToString,{2a72e20f-e337-4822-8994-2e35b5550d03},0,-1,1
+1417,nsIUpdateManager,{fede66a9-9f96-4507-a22a-775ee885577e},0,-1,1
+1418,nsIDOMScreen,{77947960-b4af-11d2-bd93-00805f8ae3f4},0,-1,1
+1419,nsICertTreeItem,{d0180863-606e-49e6-8324-cf45ed4dd891},0,-1,1
+1420,extIConsole,{ae8482e0-aa5a-11db-abbd-0800200c9a66},0,-1,1
+1421,nsISAXAttributes,{e347005e-6cd0-11da-be43-001422106990},0,-1,1
+1422,nsIXPConnect,{b2ddc328-194b-45d6-95c6-52e487438096},0,-1,0
+1423,nsIDOMSVGPathSegCurvetoCubicAbs,{380afecd-f884-4da7-a0d7-5ffc4531b70b},0,-1,1
+1424,nsIUploadChannel,{ddf633d8-e9a4-439d-ad88-de636fd9bb75},0,-1,1
+1425,nsIScreenManager_MOZILLA_1_9_1_BRANCH,{ee561ea4-7409-46f9-b79c-9f98f7f21aec},0,-1,1
+1426,nsIXPCFunctionThisTranslator,{039ef260-2a0d-11d5-90a7-0010a4e73d9a},0,-1,0
+1427,nsIAbstractWorker,{b90b7561-b5e2-4545-84b0-280dbaaa94ea},0,-1,1
+1428,nsIDOMSVGURIReference,{8092b5f3-dc8a-459c-94f1-92f8011f2438},0,-1,1
+1429,nsIDOMPluginArray,{f6134680-f28b-11d2-8360-c90899049c3c},0,-1,1
+1430,nsIDOMStorageEvent,{fc540c28-8edd-4b7a-9c30-8638289b7a7d},0,-1,1
diff --git a/bundles/XO/crashreporter b/bundles/XO/crashreporter
new file mode 100755
index 0000000..5a437fa
--- /dev/null
+++ b/bundles/XO/crashreporter
Binary files differ
diff --git a/bundles/XO/crashreporter-override.ini b/bundles/XO/crashreporter-override.ini
new file mode 100755
index 0000000..12fb902
--- /dev/null
+++ b/bundles/XO/crashreporter-override.ini
@@ -0,0 +1,5 @@
+# This file is in the UTF-8 encoding
+[Strings]
+# LOCALIZATION NOTE (CrashReporterProductErrorText2): The %s is replaced with a string containing detailed information.
+CrashReporterProductErrorText2=Firefox had a problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nUnfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
+CrashReporterDescriptionText2=Firefox had a problem and crashed. We'll try to restore your tabs and windows when it restarts.\n\nTo help us diagnose and fix the problem, you can send us a crash report.
diff --git a/bundles/XO/crashreporter.ini b/bundles/XO/crashreporter.ini
new file mode 100755
index 0000000..dee34b5
--- /dev/null
+++ b/bundles/XO/crashreporter.ini
@@ -0,0 +1,56 @@
+# This file is in the UTF-8 encoding
+[Strings]
+# LOCALIZATION NOTE (isRTL):
+# Leave this entry empty unless your language requires right-to-left layout,
+# for example like Arabic, Hebrew, Persian. If your language needs RTL, please
+# use the untranslated English word "yes" as value
+isRTL=
+CrashReporterTitle=Crash Reporter
+# LOCALIZATION NOTE (CrashReporterVendorTitle): %s is replaced with the vendor name. (i.e. "Mozilla")
+CrashReporterVendorTitle=%s Crash Reporter
+# LOCALIZATION NOTE (CrashReporterErrorText): %s is replaced with another string containing detailed information.
+CrashReporterErrorText=The application had problem and crashed.\n\nUnfortunately the crash reporter is unable to submit a report for this crash.\n\nDetails: %s
+# LOCALIZATION NOTE (CrashReporterProductErrorText2): The first %s is replaced with the product name (i.e. "Firefox"), the second is replaced with another string containing detailed information. These two substitutions can not be reordered!
+CrashReporterProductErrorText2=%s had a problem and crashed.\n\nUnfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
+CrashReporterSorry=We're Sorry
+# LOCALIZATION NOTE (CrashReporterDescriptionText2): The %s is replaced with the product name.
+CrashReporterDescriptionText2=%s had a problem and crashed.\n\nTo help us diagnose and fix the problem, you can send us a crash report.
+CrashReporterDefault=This application is run after a crash to report the problem to the application vendor. It should not be run directly.
+Details=Details…
+ViewReportTitle=Report Contents
+CommentGrayText=Add a comment (comments are publicly visible)
+ExtraReportInfo=This report also contains technical information about the state of the application when it crashed.
+# LOCALIZATION NOTE (CheckSendReport): The %s is replaced with the vendor name.
+CheckSendReport=Tell %s about this crash so they can fix it
+CheckIncludeURL=Include the address of the page I was on
+CheckSendEmail=Email me when more information is available
+EmailGrayText=Enter your email address here
+ReportPreSubmit2=Your crash report will be submitted before you quit or restart.
+ReportDuringSubmit2=Submitting your report…
+ReportSubmitSuccess=Report submitted successfully!
+ReportSubmitFailed=There was a problem submitting your report.
+ReportResubmit=Resending reports that previously failed to send…
+# LOCALIZATION NOTE (Quit2): The %s is replaced with the product name.
+Quit2=Quit %s
+# LOCALIZATION NOTE (Restart): The %s is replaced with the product name.
+Restart=Restart %s
+Ok=OK
+Close=Close
+
+# LOCALIZATION NOTE (CrashID): The %s is replaced with the Crash ID from the server, which is a string like abc12345-6789-0abc-def1-23456abcdef1
+CrashID=Crash ID: %s
+# LOCALIZATION NOTE (CrashDetailsURL): The %s is replaced with a URL that the user can visit to view the crash details.
+CrashDetailsURL=You can view details of this crash at %s
+ErrorBadArguments=The application passed an invalid argument.
+ErrorExtraFileExists=The application didn't leave an application data file.
+ErrorExtraFileRead=Couldn't read the application data file.
+ErrorExtraFileMove=Couldn't move application data file.
+ErrorDumpFileExists=The application did not leave a crash dump file.
+ErrorDumpFileMove=Couldn't move crash dump.
+ErrorNoProductName=The application did not identify itself.
+ErrorNoServerURL=The application did not specify a crash reporting server.
+ErrorNoSettingsPath=Couldn't find the crash reporter's settings.
+ErrorCreateDumpDir=Couldn't create pending dump directory.
+# LOCALIZATION NOTE (ErrorEndOfLife): The %s is replaced with the product name.
+ErrorEndOfLife=The version of %s you are using is no longer supported. Crash reports are no longer being accepted for this version. Please consider upgrading to a supported version.
+
diff --git a/bundles/XO/defaults/autoconfig/platform.js b/bundles/XO/defaults/autoconfig/platform.js
new file mode 100755
index 0000000..8cc65b4
--- /dev/null
+++ b/bundles/XO/defaults/autoconfig/platform.js
@@ -0,0 +1,2 @@
+// Unix specific auto configuration preference defaults
+platform.value = "unix";
diff --git a/bundles/XO/defaults/autoconfig/prefcalls.js b/bundles/XO/defaults/autoconfig/prefcalls.js
new file mode 100755
index 0000000..ba65aeb
--- /dev/null
+++ b/bundles/XO/defaults/autoconfig/prefcalls.js
@@ -0,0 +1,240 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mitesh Shah <mitesh@netscape.com>
+ * Brian Nesse <bnesse@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const nsILDAPURL = Components.interfaces.nsILDAPURL;
+const LDAPURLContractID = "@mozilla.org/network/ldap-url;1";
+const nsILDAPSyncQuery = Components.interfaces.nsILDAPSyncQuery;
+const LDAPSyncQueryContractID = "@mozilla.org/ldapsyncquery;1";
+const nsIPrefService = Components.interfaces.nsIPrefService;
+const PrefServiceContractID = "@mozilla.org/preferences-service;1";
+
+// set on a platform specific basis in platform.js
+platform = { value: "" };
+
+var gVersion;
+
+function getPrefBranch() {
+
+ var prefService = Components.classes[PrefServiceContractID]
+ .getService(nsIPrefService);
+ return prefService.getBranch(null);
+}
+
+function pref(prefName, value) {
+
+ try {
+ var prefBranch = getPrefBranch();
+
+ if (typeof value == "string") {
+ prefBranch.setCharPref(prefName, value);
+ }
+ else if (typeof value == "number") {
+ prefBranch.setIntPref(prefName, value);
+ }
+ else if (typeof value == "boolean") {
+ prefBranch.setBoolPref(prefName, value);
+ }
+ }
+ catch(e) {
+ displayError("pref", e);
+ }
+}
+
+function defaultPref(prefName, value) {
+
+ try {
+ var prefService = Components.classes[PrefServiceContractID]
+ .getService(nsIPrefService);
+ var prefBranch = prefService.getDefaultBranch(null);
+ if (typeof value == "string") {
+ prefBranch.setCharPref(prefName, value);
+ }
+ else if (typeof value == "number") {
+ prefBranch.setIntPref(prefName, value);
+ }
+ else if (typeof value == "boolean") {
+ prefBranch.setBoolPref(prefName, value);
+ }
+ }
+ catch(e) {
+ displayError("defaultPref", e);
+ }
+}
+
+function lockPref(prefName, value) {
+
+ try {
+ var prefBranch = getPrefBranch();
+
+ if (prefBranch.prefIsLocked(prefName))
+ prefBranch.unlockPref(prefName);
+
+ defaultPref(prefName, value);
+
+ prefBranch.lockPref(prefName);
+ }
+ catch(e) {
+ displayError("lockPref", e);
+ }
+}
+
+function unlockPref(prefName) {
+
+ try {
+
+ var prefBranch = getPrefBranch();
+ prefBranch.unlockPref(prefName);
+ }
+ catch(e) {
+ displayError("unlockPref", e);
+ }
+}
+
+function getPref(prefName) {
+
+ try {
+ var prefBranch = getPrefBranch();
+
+ switch (prefBranch.getPrefType(prefName)) {
+
+ case prefBranch.PREF_STRING:
+ return prefBranch.getCharPref(prefName);
+
+ case prefBranch.PREF_INT:
+ return prefBranch.getIntPref(prefName);
+
+ case prefBranch.PREF_BOOL:
+ return prefBranch.getBoolPref(prefName);
+ default:
+ return null;
+ }
+ }
+ catch(e) {
+ displayError("getPref", e);
+ }
+}
+
+function clearPref(prefName) {
+
+ try {
+ var prefBranch = getPrefBranch();
+ prefBranch.clearUserPref(prefName);
+ }
+ catch(e) {
+ }
+
+}
+
+function setLDAPVersion(version) {
+ gVersion = version;
+}
+
+
+function getLDAPAttributes(host, base, filter, attribs) {
+
+ try {
+ var url = Components.classes[LDAPURLContractID].createInstance(nsILDAPURL);
+
+ url.spec = "ldap://" + host + "/" + base + "?" + attribs
+ + "?sub?" + filter;
+ var ldapquery = Components.classes[LDAPSyncQueryContractID]
+ .createInstance(nsILDAPSyncQuery);
+ // default to LDAP v3
+ if (!gVersion)
+ gVersion = Components.interfaces.nsILDAPConnection.VERSION3
+ // user supplied method
+ processLDAPValues(ldapquery.getQueryResults(url, gVersion));
+ }
+ catch(e) {
+ displayError("getLDAPAttibutes", e);
+ }
+}
+
+function getLDAPValue(str, key) {
+
+ try {
+ if (str == null || key == null)
+ return null;
+
+ var search_key = "\n" + key + "=";
+
+ var start_pos = str.indexOf(search_key);
+ if (start_pos == -1)
+ return null;
+
+ start_pos += search_key.length;
+
+ var end_pos = str.indexOf("\n", start_pos);
+ if (end_pos == -1)
+ end_pos = str.length;
+
+ return str.substring(start_pos, end_pos);
+ }
+ catch(e) {
+ displayError("getLDAPValue", e);
+ }
+}
+
+function displayError(funcname, message) {
+
+ try {
+ var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+ var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
+ .getService(Components.interfaces.nsIStringBundleService)
+ .createBundle("chrome://autoconfig/locale/autoconfig.properties");
+
+ var title = bundle.GetStringFromName("autoConfigTitle");
+ var msg = bundle.formatStringFromName("autoConfigMsg", [funcname], 1);
+ promptService.alert(null, title, msg + " " + message);
+ }
+ catch(e) { }
+}
+
+function getenv(name) {
+ try {
+ var environment = Components.classes["@mozilla.org/process/environment;1"].
+ getService(Components.interfaces.nsIEnvironment);
+ return environment.get(name);
+ }
+ catch(e) {
+ displayError("getEnvironment", e);
+ }
+}
+
diff --git a/bundles/XO/defaults/pref/channel-prefs.js b/bundles/XO/defaults/pref/channel-prefs.js
new file mode 100755
index 0000000..b20751c
--- /dev/null
+++ b/bundles/XO/defaults/pref/channel-prefs.js
@@ -0,0 +1,2 @@
+//@line 2 "/builds/moz2_slave/linux_build/build/browser/app/profile/channel-prefs.js"
+pref("app.update.channel", "release");
diff --git a/bundles/XO/defaults/pref/firefox-branding.js b/bundles/XO/defaults/pref/firefox-branding.js
new file mode 100755
index 0000000..2997435
--- /dev/null
+++ b/bundles/XO/defaults/pref/firefox-branding.js
@@ -0,0 +1,17 @@
+pref("startup.homepage_override_url","http://%LOCALE%.www.mozilla.com/%LOCALE%/%APP%/%VERSION%/whatsnew/");
+pref("startup.homepage_welcome_url","http://%LOCALE%.www.mozilla.com/%LOCALE%/%APP%/%VERSION%/firstrun/");
+// Interval: Time between checks for a new version (in seconds)
+// nightly=6 hours, official=24 hours
+pref("app.update.interval", 86400);
+// URL user can browse to manually if for some reason all update installation
+// attempts fail.
+pref("app.update.url.manual", "http://%LOCALE%.www.mozilla.com/%LOCALE%/%APP%/");
+// A default value for the "More information about this update" link
+// supplied in the "An update is available" page of the update wizard.
+pref("app.update.url.details", "http://%LOCALE%.www.mozilla.com/%LOCALE%/%APP%/releases/");
+
+// Release notes URL
+pref("app.releaseNotesURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/%APP%/%VERSION%/releasenotes/");
+
+pref("browser.search.param.yahoo-fr", "moz35");
+pref("browser.search.param.yahoo-fr-cjkt", "moz35");
diff --git a/bundles/XO/defaults/pref/firefox-l10n.js b/bundles/XO/defaults/pref/firefox-l10n.js
new file mode 100755
index 0000000..3ad1045
--- /dev/null
+++ b/bundles/XO/defaults/pref/firefox-l10n.js
@@ -0,0 +1,5 @@
+//@line 36 "/builds/moz2_slave/linux_build/build/browser/locales/en-US/firefox-l10n.js"
+
+//@line 38 "/builds/moz2_slave/linux_build/build/browser/locales/en-US/firefox-l10n.js"
+
+pref("general.useragent.locale", "en-US");
diff --git a/bundles/XO/defaults/pref/firefox.js b/bundles/XO/defaults/pref/firefox.js
new file mode 100755
index 0000000..77d5b1f
--- /dev/null
+++ b/bundles/XO/defaults/pref/firefox.js
@@ -0,0 +1,764 @@
+//@line 37 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+// XXX Toolkit-specific preferences should be moved into toolkit.js
+
+//@line 41 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+//@line 44 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+//@line 50 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+pref("general.startup.browser", true);
+
+pref("browser.chromeURL","chrome://browser/content/");
+pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
+pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
+pref("xpinstall.dialog.progress.skin", "chrome://mozapps/content/extensions/extensions.xul");
+pref("xpinstall.dialog.progress.chrome", "chrome://mozapps/content/extensions/extensions.xul");
+pref("xpinstall.dialog.progress.type.skin", "Extension:Manager");
+pref("xpinstall.dialog.progress.type.chrome", "Extension:Manager");
+
+// Developers can set this to |true| if they are constantly changing files in their
+// extensions directory so that the extension system does not constantly think that
+// their extensions are being updated and thus reregistered every time the app is
+// started.
+pref("extensions.ignoreMTimeChanges", false);
+// Enables some extra Extension System Logging (can reduce performance)
+pref("extensions.logging.enabled", false);
+// Hides the install button in the add-ons mgr
+pref("extensions.hideInstallButton", true);
+
+// Preferences for the Get Add-ons pane
+pref("extensions.getAddons.showPane", true);
+pref("extensions.getAddons.browseAddons", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%");
+pref("extensions.getAddons.maxResults", 5);
+pref("extensions.getAddons.recommended.browseURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/recommended");
+pref("extensions.getAddons.recommended.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/list/featured/all/10/%OS%/%VERSION%");
+pref("extensions.getAddons.search.browseURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/search?q=%TERMS%");
+pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/10/%OS%/%VERSION%");
+
+// Blocklist preferences
+pref("extensions.blocklist.enabled", true);
+pref("extensions.blocklist.interval", 86400);
+// Controls what level the blocklist switches from warning about items to forcibly
+// blocking them.
+pref("extensions.blocklist.level", 2);
+pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
+pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
+
+// Dictionary download preference
+pref("browser.dictionaries.download.url", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/firefox/%VERSION%/dictionaries/");
+
+// App-specific update preferences
+
+// Whether or not app updates are enabled
+pref("app.update.enabled", true);
+
+// This preference turns on app.update.mode and allows automatic download and
+// install to take place. We use a separate boolean toggle for this to make
+// the UI easier to construct.
+pref("app.update.auto", true);
+
+// Defines how the Application Update Service notifies the user about updates:
+//
+// AUM Set to: Minor Releases: Major Releases:
+// 0 download no prompt download no prompt
+// 1 download no prompt download no prompt if no incompatibilities
+// 2 download no prompt prompt
+//
+// See chart in nsUpdateService.js.in for more details
+//
+pref("app.update.mode", 1);
+
+// If set to true, the Update Service will present no UI for any event.
+pref("app.update.silent", false);
+
+// Update service URL:
+pref("app.update.url", "https://aus2.mozilla.org/update/3/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/update.xml");
+// app.update.url.manual is in branding section
+// app.update.url.details is in branding section
+
+// User-settable override to app.update.url for testing purposes.
+//pref("app.update.url.override", "");
+
+// app.update.interval is in branding section
+
+// Interval: Time before prompting the user again to restart to install the
+// latest download (in seconds) default=1 day
+pref("app.update.nagTimer.restart", 86400);
+
+// Interval: When all registered timers should be checked (in milliseconds)
+// default=10 minutes
+pref("app.update.timer", 600000);
+// Give the user x seconds to react before showing the big UI. default=12 hours
+pref("app.update.promptWaitTime", 43200);
+// Show the Update Checking/Ready UI when the user was idle for x seconds
+pref("app.update.idletime", 60);
+
+// Whether or not we show a dialog box informing the user that the update was
+// successfully applied. This is off in Firefox by default since we show a
+// upgrade start page instead! Other apps may wish to show this UI, and supply
+// a whatsNewURL field in their brand.properties that contains a link to a page
+// which tells users what's new in this new update.
+pref("app.update.showInstalledUI", false);
+
+// 0 = suppress prompting for incompatibilities if there are updates available
+// to newer versions of installed addons that resolve them.
+// 1 = suppress prompting for incompatibilities only if there are VersionInfo
+// updates available to installed addons that resolve them, not newer
+// versions.
+pref("app.update.incompatible.mode", 0);
+
+// Symmetric (can be overridden by individual extensions) update preferences.
+// e.g.
+// extensions.{GUID}.update.enabled
+// extensions.{GUID}.update.url
+// extensions.{GUID}.update.interval
+// .. etc ..
+//
+pref("extensions.update.enabled", true);
+pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%");
+pref("extensions.update.interval", 86400); // Check for updates to Extensions and
+ // Themes every day
+// Non-symmetric (not shared by extensions) extension-specific [update] preferences
+pref("extensions.getMoreExtensionsURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/%VERSION%/extensions/");
+pref("extensions.getMoreThemesURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/%VERSION%/themes/");
+pref("extensions.getMorePluginsURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/%VERSION%/plugins/");
+pref("extensions.dss.enabled", false); // Dynamic Skin Switching
+pref("extensions.dss.switchPending", false); // Non-dynamic switch pending after next
+ // restart.
+
+pref("xpinstall.whitelist.add", "update.mozilla.org");
+pref("xpinstall.whitelist.add.103", "addons.mozilla.org");
+
+pref("keyword.enabled", true);
+pref("keyword.URL", "chrome://browser-region/locale/region.properties");
+
+pref("general.useragent.locale", "en-US");
+pref("general.skins.selectedSkin", "classic/1.0");
+pref("general.useragent.extra.firefox", "Firefox/3.5.3");
+
+pref("general.smoothScroll", false);
+//@line 183 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("general.autoScroll", false);
+//@line 187 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+// Whether or not the application should check at startup each time if it
+// is the default browser.
+pref("browser.shell.checkDefaultBrowser", true);
+
+// 0 = blank, 1 = home (browser.startup.homepage), 2 = last visited page, 3 = resume previous browser session
+// The behavior of option 3 is detailed at: http://wiki.mozilla.org/Session_Restore
+pref("browser.startup.page", 1);
+pref("browser.startup.homepage", "resource:/browserconfig.properties");
+
+pref("browser.enable_automatic_image_resizing", true);
+pref("browser.chrome.site_icons", true);
+pref("browser.chrome.favicons", true);
+pref("browser.formfill.enable", true);
+pref("browser.warnOnQuit", true);
+pref("browser.warnOnRestart", true);
+pref("browser.fullscreen.autohide", true);
+pref("browser.fullscreen.animateUp", 1);
+
+//@line 207 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("browser.urlbar.clickSelectsAll", false);
+//@line 212 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("browser.urlbar.doubleClickSelectsAll", true);
+//@line 216 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("browser.urlbar.autoFill", false);
+// 0: Match anywhere (e.g., middle of words)
+// 1: Match on word boundaries and then try matching anywhere
+// 2: Match only on word boundaries (e.g., after / or .)
+// 3: Match at the beginning of the url or title
+pref("browser.urlbar.matchBehavior", 1);
+pref("browser.urlbar.filter.javascript", true);
+
+// the maximum number of results to show in autocomplete when doing richResults
+pref("browser.urlbar.maxRichResults", 12);
+// Size of "chunks" affects the number of places to process between each search
+// timeout (ms). Too big and the UI will be unresponsive; too small and we'll
+// be waiting on the timeout too often without many results.
+pref("browser.urlbar.search.chunkSize", 1000);
+pref("browser.urlbar.search.timeout", 100);
+
+// The special characters below can be typed into the urlbar to either restrict
+// the search to visited history, bookmarked, tagged pages; or force a match on
+// just the title text or url.
+pref("browser.urlbar.restrict.history", "^");
+pref("browser.urlbar.restrict.bookmark", "*");
+pref("browser.urlbar.restrict.tag", "+");
+pref("browser.urlbar.restrict.typed", "~");
+pref("browser.urlbar.match.title", "#");
+pref("browser.urlbar.match.url", "@");
+
+// The default behavior for the urlbar can be configured to use any combination
+// of the restrict or match filters with each additional filter restricting
+// more (intersection). Add the following values to set the behavior as the
+// default: 1: history, 2: bookmark, 4: tag, 8: title, 16: url, 32: typed
+// E.g., 0 = show all results (no filtering), 1 = only visited pages in history,
+// 2 = only bookmarks, 3 = visited bookmarks, 1+16 = history matching in the url
+pref("browser.urlbar.default.behavior", 0);
+
+// Number of milliseconds to wait for the http headers (and thus
+// the Content-Disposition filename) before giving up and falling back to
+// picking a filename without that info in hand so that the user sees some
+// feedback from their action.
+pref("browser.download.saveLinkAsFilenameTimeout", 1000);
+
+pref("browser.download.useDownloadDir", true);
+pref("browser.download.folderList", 1);
+pref("browser.download.manager.showAlertOnComplete", true);
+pref("browser.download.manager.showAlertInterval", 2000);
+pref("browser.download.manager.retention", 2);
+pref("browser.download.manager.showWhenStarting", true);
+pref("browser.download.manager.closeWhenDone", false);
+pref("browser.download.manager.focusWhenStarting", false);
+pref("browser.download.manager.flashCount", 2);
+pref("browser.download.manager.addToRecentDocs", true);
+pref("browser.download.manager.quitBehavior", 0);
+pref("browser.download.manager.scanWhenDone", true);
+pref("browser.download.manager.resumeOnWakeDelay", 10000);
+
+// search engines URL
+pref("browser.search.searchEnginesURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/firefox/%VERSION%/search-engines/");
+
+// pointer to the default engine name
+pref("browser.search.defaultenginename", "chrome://browser-region/locale/region.properties");
+
+// disable logging for the search service by default
+pref("browser.search.log", false);
+
+// Ordering of Search Engines in the Engine list.
+pref("browser.search.order.1", "chrome://browser-region/locale/region.properties");
+pref("browser.search.order.2", "chrome://browser-region/locale/region.properties");
+
+// search bar results always open in a new tab
+pref("browser.search.openintab", false);
+
+// send ping to the server to update
+pref("browser.search.update", true);
+
+// disable logging for the search service update system by default
+pref("browser.search.update.log", false);
+
+// Check whether we need to perform engine updates every 6 hours
+pref("browser.search.updateinterval", 6);
+
+// Whether or not microsummary and generator updates are enabled
+pref("browser.microsummary.enabled", true);
+pref("browser.microsummary.updateGenerators", true);
+
+// enable search suggestions by default
+pref("browser.search.suggest.enabled", true);
+
+pref("browser.history.grouping", "day");
+pref("browser.history.showSessions", false);
+pref("browser.sessionhistory.max_entries", 50);
+pref("browser.history_expire_days", 180);
+pref("browser.history_expire_days_min", 90);
+pref("browser.history_expire_sites", 40000);
+
+// handle links targeting new windows
+// 0=default window, 1=current window/tab, 2=new window, 3=new tab in most recent window
+pref("browser.link.open_newwindow", 3);
+
+// 0: no restrictions - divert everything
+// 1: don't divert window.open at all
+// 2: don't divert window.open with features
+pref("browser.link.open_newwindow.restriction", 2);
+
+// Tabbed browser
+pref("browser.tabs.autoHide", false);
+pref("browser.tabs.closeWindowWithLastTab", true);
+pref("browser.tabs.warnOnClose", true);
+pref("browser.tabs.warnOnOpen", true);
+pref("browser.tabs.maxOpenBeforeWarn", 15);
+pref("browser.tabs.loadInBackground", true);
+pref("browser.tabs.loadFolderAndReplace", true);
+pref("browser.tabs.opentabfor.middleclick", true);
+pref("browser.tabs.loadDivertedInBackground", false);
+pref("browser.tabs.loadBookmarksInBackground", false);
+pref("browser.tabs.tabMinWidth", 100);
+pref("browser.tabs.tabMaxWidth", 250);
+pref("browser.tabs.tabClipWidth", 140);
+
+// Where to show tab close buttons:
+// 0 on active tab only
+// 1 on all tabs until tabClipWidth is reached, then active tab only
+// 2 no close buttons at all
+// 3 at the end of the tabstrip
+pref("browser.tabs.closeButtons", 1);
+
+// When tabs opened by links in other tabs via a combination of
+// browser.link.open_newwindow being set to 3 and target="_blank" etc are
+// closed:
+// true return to the tab that opened this tab (its owner)
+// false return to the adjacent tab (old default)
+pref("browser.tabs.selectOwnerOnClose", true);
+
+pref("browser.ctrlTab.previews", true);
+pref("browser.ctrlTab.recentlyUsedLimit", 7);
+
+// Default bookmark sorting
+pref("browser.bookmarks.sort.direction", "descending");
+pref("browser.bookmarks.sort.resource", "rdf:http://home.netscape.com/NC-rdf#Name");
+
+// By default, do not export HTML at shutdown.
+// If true, at shutdown the bookmarks in your menu and toolbar will
+// be exported as HTML to the bookmarks.html file.
+pref("browser.bookmarks.autoExportHTML", false);
+
+// The maximum number of daily bookmark backups to
+// keep in {PROFILEDIR}/bookmarkbackups. Special values:
+// -1: unlimited
+// 0: no backups created (and deletes all existing backups)
+pref("browser.bookmarks.max_backups", 5);
+
+// Scripts & Windows prefs
+pref("dom.disable_open_during_load", true);
+//@line 371 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("javascript.options.showInConsole", false);
+//@line 373 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+// Make the status bar reliably present and unaffected by pages
+pref("dom.disable_window_open_feature.status", true);
+// This is the pref to control the location bar, change this to true to
+// force this instead of or in addition to the status bar - this makes
+// the origin of popup windows more obvious to avoid spoofing. We would
+// rather not do it by default because it affects UE for web applications, but
+// without it there isn't a really good way to prevent chrome spoofing, see bug 337344
+pref("dom.disable_window_open_feature.location", true);
+pref("dom.disable_window_status_change", true);
+// allow JS to move and resize existing windows
+pref("dom.disable_window_move_resize", false);
+// prevent JS from monkeying with window focus, etc
+pref("dom.disable_window_flip", true);
+
+// popups.policy 1=allow,2=reject
+pref("privacy.popups.policy", 1);
+pref("privacy.popups.usecustom", true);
+pref("privacy.popups.firstTime", true);
+pref("privacy.popups.showBrowserMessage", true);
+
+pref("privacy.item.cookies", false);
+
+pref("privacy.clearOnShutdown.history", true);
+pref("privacy.clearOnShutdown.formdata", true);
+pref("privacy.clearOnShutdown.passwords", false);
+pref("privacy.clearOnShutdown.downloads", true);
+pref("privacy.clearOnShutdown.cookies", true);
+pref("privacy.clearOnShutdown.cache", true);
+pref("privacy.clearOnShutdown.sessions", true);
+pref("privacy.clearOnShutdown.offlineApps", false);
+pref("privacy.clearOnShutdown.siteSettings", false);
+
+pref("privacy.cpd.history", true);
+pref("privacy.cpd.formdata", true);
+pref("privacy.cpd.passwords", false);
+pref("privacy.cpd.downloads", true);
+pref("privacy.cpd.cookies", true);
+pref("privacy.cpd.cache", true);
+pref("privacy.cpd.sessions", true);
+pref("privacy.cpd.offlineApps", false);
+pref("privacy.cpd.siteSettings", false);
+
+// What default should we use for the time span in the sanitizer:
+// 0 - Clear everything
+// 1 - Last Hour
+// 2 - Last 2 Hours
+// 3 - Last 4 Hours
+// 4 - Today
+pref("privacy.sanitize.timeSpan", 1);
+pref("privacy.sanitize.sanitizeOnShutdown", false);
+
+pref("privacy.sanitize.migrateFx3Prefs", false);
+
+pref("network.proxy.share_proxy_settings", false); // use the same proxy settings for all protocols
+
+pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
+
+// l12n and i18n
+pref("intl.accept_languages", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.static", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more1", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more2", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more3", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more4", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more5", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.unicode", "chrome://global/locale/intl.properties");
+pref("intl.charset.detector", "chrome://global/locale/intl.properties");
+pref("intl.charset.default", "chrome://global-platform/locale/intl.properties");
+pref("font.language.group", "chrome://global/locale/intl.properties");
+pref("intl.menuitems.alwaysappendaccesskeys","chrome://global/locale/intl.properties");
+pref("intl.menuitems.insertseparatorbeforeaccesskeys","chrome://global/locale/intl.properties");
+
+// simple gestures support
+pref("browser.gesture.swipe.left", "Browser:BackOrBackDuplicate");
+pref("browser.gesture.swipe.right", "Browser:ForwardOrForwardDuplicate");
+pref("browser.gesture.swipe.up", "cmd_scrollTop");
+pref("browser.gesture.swipe.down", "cmd_scrollBottom");
+//@line 455 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("browser.gesture.pinch.latched", false);
+pref("browser.gesture.pinch.threshold", 25);
+//@line 458 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("browser.gesture.pinch.out", "cmd_fullZoomEnlarge");
+pref("browser.gesture.pinch.in", "cmd_fullZoomReduce");
+pref("browser.gesture.pinch.out.shift", "cmd_fullZoomReset");
+pref("browser.gesture.pinch.in.shift", "cmd_fullZoomReset");
+pref("browser.gesture.twist.latched", false);
+pref("browser.gesture.twist.threshold", 25);
+pref("browser.gesture.twist.right", "");
+pref("browser.gesture.twist.left", "");
+pref("browser.gesture.tap", "cmd_fullZoomReset");
+
+// 0=lines, 1=pages, 2=history , 3=text size
+//@line 483 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("mousewheel.withshiftkey.action",2);
+pref("mousewheel.withshiftkey.sysnumlines",false);
+pref("mousewheel.withshiftkey.numlines",1);
+pref("mousewheel.withaltkey.action",0);
+pref("mousewheel.withaltkey.sysnumlines",false);
+pref("mousewheel.withaltkey.numlines",1);
+pref("mousewheel.withmetakey.action",0);
+pref("mousewheel.withmetakey.sysnumlines",true);
+pref("mousewheel.withmetakey.numlines",1);
+//@line 493 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("mousewheel.withcontrolkey.action",3);
+pref("mousewheel.withcontrolkey.sysnumlines",false);
+pref("mousewheel.withcontrolkey.numlines",1);
+
+pref("profile.allow_automigration", false); // setting to false bypasses automigration in the profile code
+
+// Customizable toolbar stuff
+pref("custtoolbar.personal_toolbar_folder", "");
+
+// pref to control the alert notification
+pref("alerts.slideIncrement", 1);
+pref("alerts.slideIncrementTime", 10);
+pref("alerts.totalOpenTime", 4000);
+
+pref("browser.xul.error_pages.enabled", true);
+pref("browser.xul.error_pages.expert_bad_cert", false);
+
+// We want to make sure mail URLs are handled externally...
+pref("network.protocol-handler.external.mailto", true); // for mail
+pref("network.protocol-handler.external.news", true); // for news
+pref("network.protocol-handler.external.snews", true); // for secure news
+pref("network.protocol-handler.external.nntp", true); // also news
+// ...without warning dialogs
+pref("network.protocol-handler.warn-external.mailto", false);
+pref("network.protocol-handler.warn-external.news", false);
+pref("network.protocol-handler.warn-external.snews", false);
+pref("network.protocol-handler.warn-external.nntp", false);
+
+// By default, all protocol handlers are exposed. This means that
+// the browser will respond to openURL commands for all URL types.
+// It will also try to open link clicks inside the browser before
+// failing over to the system handlers.
+pref("network.protocol-handler.expose-all", true);
+pref("network.protocol-handler.expose.mailto", false);
+pref("network.protocol-handler.expose.news", false);
+pref("network.protocol-handler.expose.snews", false);
+pref("network.protocol-handler.expose.nntp", false);
+
+// Default security warning dialogs to show once.
+pref("security.warn_entering_secure.show_once", false);
+pref("security.warn_entering_weak.show_once", true);
+pref("security.warn_leaving_secure.show_once", false);
+pref("security.warn_viewing_mixed.show_once", true);
+pref("security.warn_submit_insecure.show_once", false);
+
+pref("accessibility.typeaheadfind", false);
+pref("accessibility.typeaheadfind.timeout", 5000);
+pref("accessibility.typeaheadfind.linksonly", false);
+pref("accessibility.typeaheadfind.flashBar", 1);
+
+// Disable the default plugin for firefox
+pref("plugin.default_plugin_disabled", true);
+
+// plugin finder service url
+pref("pfs.datasource.url", "https://pfs.mozilla.org/plugins/PluginFinderService.php?mimetype=%PLUGIN_MIMETYPE%&appID=%APP_ID%&appVersion=%APP_VERSION%&clientOS=%CLIENT_OS%&chromeLocale=%CHROME_LOCALE%&appRelease=%APP_RELEASE%");
+
+// by default we show an infobar message when pages require plugins the user has not installed
+pref("plugins.hide_infobar_for_missing_plugin", false);
+
+//@line 555 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("browser.preferences.instantApply", true);
+//@line 560 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("browser.preferences.animateFadeIn", false);
+//@line 562 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+pref("browser.download.show_plugins_in_list", true);
+pref("browser.download.hide_plugins_without_extensions", true);
+
+// Backspace and Shift+Backspace behavior
+// 0 goes Back/Forward
+// 1 act like PgUp/PgDown
+// 2 and other values, nothing
+//@line 571 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("browser.backspace_action", 2);
+//@line 575 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+// this will automatically enable inline spellchecking (if it is available) for
+// editable elements in HTML
+// 0 = spellcheck nothing
+// 1 = check multi-line controls [default]
+// 2 = check multi/single line controls
+pref("layout.spellcheckDefault", 1);
+
+pref("browser.send_pings", false);
+
+/* initial web feed readers list */
+pref("browser.contentHandlers.types.0.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.0.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.0.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.1.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.1.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.1.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.2.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.2.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.2.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.3.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.3.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.3.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.4.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.4.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.4.type", "application/vnd.mozilla.maybe.feed");
+pref("browser.contentHandlers.types.5.title", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.5.uri", "chrome://browser-region/locale/region.properties");
+pref("browser.contentHandlers.types.5.type", "application/vnd.mozilla.maybe.feed");
+
+pref("browser.feeds.handler", "ask");
+pref("browser.videoFeeds.handler", "ask");
+pref("browser.audioFeeds.handler", "ask");
+
+// At startup, if the handler service notices that the version number in the
+// region.properties file is newer than the version number in the handler
+// service datastore, it will add any new handlers it finds in the prefs (as
+// seeded by this file) to its datastore.
+pref("gecko.handlerService.defaultHandlersVersion", "chrome://browser-region/locale/region.properties");
+
+// The default set of web-based protocol handlers shown in the application
+// selection dialog for webcal: ; I've arbitrarily picked 4 default handlers
+// per protocol, but if some locale wants more than that (or defaults for some
+// protocol not currently listed here), we should go ahead and add those.
+
+// webcal
+pref("gecko.handlerService.schemes.webcal.0.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.0.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.1.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.1.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.2.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.2.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.3.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.webcal.3.uriTemplate", "chrome://browser-region/locale/region.properties");
+
+// mailto
+pref("gecko.handlerService.schemes.mailto.0.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.0.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.1.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.1.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.2.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.2.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.3.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.mailto.3.uriTemplate", "chrome://browser-region/locale/region.properties");
+
+// irc
+pref("gecko.handlerService.schemes.irc.0.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.0.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.1.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.1.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.2.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.2.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.3.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.irc.3.uriTemplate", "chrome://browser-region/locale/region.properties");
+
+// ircs
+pref("gecko.handlerService.schemes.ircs.0.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.0.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.1.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.1.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.2.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.2.uriTemplate", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.3.name", "chrome://browser-region/locale/region.properties");
+pref("gecko.handlerService.schemes.ircs.3.uriTemplate", "chrome://browser-region/locale/region.properties");
+
+// By default, we don't want protocol/content handlers to be registered from a different host, see bug 402287
+pref("gecko.handlerService.allowRegisterFromDifferentHost", false);
+
+//@line 664 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+// Safe browsing does nothing unless this pref is set
+pref("browser.safebrowsing.enabled", true);
+
+// Prevent loading of pages identified as malware
+pref("browser.safebrowsing.malware.enabled", true);
+
+// Non-enhanced mode (local url lists) URL list to check for updates
+pref("browser.safebrowsing.provider.0.updateURL", "http://safebrowsing.clients.google.com/safebrowsing/downloads?client={moz:client}&appver={moz:version}&pver=2.2");
+
+pref("browser.safebrowsing.dataProvider", 0);
+
+// Does the provider name need to be localizable?
+pref("browser.safebrowsing.provider.0.name", "Google");
+pref("browser.safebrowsing.provider.0.lookupURL", "http://safebrowsing.clients.google.com/safebrowsing/lookup?sourceid=firefox-antiphish&features=TrustRank&client={moz:client}&appver={moz:version}&");
+pref("browser.safebrowsing.provider.0.keyURL", "https://sb-ssl.google.com/safebrowsing/newkey?client={moz:client}&appver={moz:version}&pver=2.2");
+pref("browser.safebrowsing.provider.0.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/report?");
+pref("browser.safebrowsing.provider.0.gethashURL", "http://safebrowsing.clients.google.com/safebrowsing/gethash?client={moz:client}&appver={moz:version}&pver=2.2");
+
+// HTML report pages
+pref("browser.safebrowsing.provider.0.reportGenericURL", "http://{moz:locale}.phish-generic.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportErrorURL", "http://{moz:locale}.phish-error.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportPhishURL", "http://{moz:locale}.phish-report.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportMalwareURL", "http://{moz:locale}.malware-report.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportMalwareErrorURL", "http://{moz:locale}.malware-error.mozilla.com/?hl={moz:locale}");
+
+// FAQ URLs
+pref("browser.safebrowsing.warning.infoURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/firefox/phishing-protection/");
+pref("browser.geolocation.warning.infoURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/firefox/geolocation/");
+
+// Name of the about: page contributed by safebrowsing to handle display of error
+// pages on phishing/malware hits. (bug 399233)
+pref("urlclassifier.alternate_error_page", "blocked");
+
+// The number of random entries to send with a gethash request.
+pref("urlclassifier.gethashnoise", 4);
+
+// The list of tables that use the gethash request to confirm partial results.
+pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
+
+// If an urlclassifier table has not been updated in this number of seconds,
+// a gethash request will be forced to check that the result is still in
+// the database.
+pref("urlclassifier.confirm-age", 2700);
+
+//@line 714 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+// Maximum size of the sqlite3 cache during an update, in bytes
+//@line 717 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+pref("urlclassifier.updatecachemax", 104857600);
+//@line 721 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+// URL for checking the reason for a malware warning.
+pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
+
+//@line 726 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+pref("browser.EULA.version", 3);
+pref("browser.rights.version", 3);
+pref("browser.rights.3.shown", false);
+
+//@line 735 "/builds/moz2_slave/linux_build/build/browser/app/profile/firefox.js"
+
+pref("browser.sessionstore.resume_from_crash", true);
+pref("browser.sessionstore.resume_session_once", false);
+
+// minimal interval between two save operations in milliseconds
+pref("browser.sessionstore.interval", 10000);
+// maximum amount of POSTDATA to be saved in bytes per history entry (-1 = all of it)
+// (NB: POSTDATA will be saved either entirely or not at all)
+pref("browser.sessionstore.postdata", 0);
+// on which sites to save text data, POSTDATA and cookies
+// 0 = everywhere, 1 = unencrypted sites, 2 = nowhere
+pref("browser.sessionstore.privacy_level", 1);
+// how many tabs can be reopened (per window)
+pref("browser.sessionstore.max_tabs_undo", 10);
+// how many windows can be reopened (per session) - on non-OS X platforms this
+// pref may be ignored when dealing with pop-up windows to ensure proper startup
+pref("browser.sessionstore.max_windows_undo", 3);
+// number of crashes that can occur before the about:sessionrestore page is displayed
+// (this pref has no effect if more than 6 hours have passed since the last crash)
+pref("browser.sessionstore.max_resumed_crashes", 1);
+
+// allow META refresh by default
+pref("accessibility.blockautorefresh", false);
+
+// the (maximum) number of the recent visits to sample
+// when calculating frecency
+pref("places.frecency.numVisits", 10);
+
+// Number of records to update frecency for when idle.
+pref("places.frecency.numCalcOnIdle", 50);
+
+// Number of records to update frecency for when migrating from
+// a pre-frecency build.
+pref("places.frecency.numCalcOnMigrate", 50);
+
+// Perform frecency recalculation after this amount of idle, repeating.
+// A value of zero disables updating of frecency on idle.
+// Default is 1 minute (60000ms).
+pref("places.frecency.updateIdleTime", 60000);
+
+// buckets (in days) for frecency calculation
+pref("places.frecency.firstBucketCutoff", 4);
+pref("places.frecency.secondBucketCutoff", 14);
+pref("places.frecency.thirdBucketCutoff", 31);
+pref("places.frecency.fourthBucketCutoff", 90);
+
+// weights for buckets for frecency calculations
+pref("places.frecency.firstBucketWeight", 100);
+pref("places.frecency.secondBucketWeight", 70);
+pref("places.frecency.thirdBucketWeight", 50);
+pref("places.frecency.fourthBucketWeight", 30);
+pref("places.frecency.defaultBucketWeight", 10);
+
+// bonus (in percent) for visit transition types for frecency calculations
+pref("places.frecency.embedVisitBonus", 0);
+pref("places.frecency.linkVisitBonus", 100);
+pref("places.frecency.typedVisitBonus", 2000);
+pref("places.frecency.bookmarkVisitBonus", 75);
+pref("places.frecency.downloadVisitBonus", 0);
+pref("places.frecency.permRedirectVisitBonus", 0);
+pref("places.frecency.tempRedirectVisitBonus", 0);
+pref("places.frecency.defaultVisitBonus", 0);
+
+// bonus (in percent) for place types for frecency calculations
+pref("places.frecency.unvisitedBookmarkBonus", 140);
+pref("places.frecency.unvisitedTypedBonus", 200);
+
+// Controls behavior of the "Add Exception" dialog launched from SSL error pages
+// 0 - don't pre-populate anything
+// 1 - pre-populate site URL, but don't fetch certificate
+// 2 - pre-populate site URL and pre-fetch certificate
+pref("browser.ssl_override_behavior", 2);
+
+// Controls the display of domain in the identity box for SSL connections.
+// 0 - do not show domain
+// 1 - show effectiveTLD + 1 (e.g. mozilla.org)
+// 2 - show full domain (e.g. bugzilla.mozilla.org)
+pref("browser.identity.ssl_domain_display", 1);
+
+// True if the user should be prompted when a web application supports
+// offline apps.
+pref("browser.offline-apps.notify", true);
+
+// if true, use full page zoom instead of text zoom
+pref("browser.zoom.full", true);
+
+// Whether or not to save and restore zoom levels on a per-site basis.
+pref("browser.zoom.siteSpecific", true);
+
+// Whether or not to update background tabs to the current zoom level.
+pref("browser.zoom.updateBackgroundTabs", true);
+
+// replace newlines with spaces when pasting into <input type="text"> fields
+pref("editor.singleLine.pasteNewlines", 2);
+
+// The breakpad report server to link to in about:crashes
+pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
+
+// base URL for web-based support pages
+pref("app.support.baseURL", "http://support.mozilla.com/1/%APP%/%VERSION%/%OS%/%LOCALE%/");
+
+// Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
+pref("security.alternate_certificate_error_page", "certerror");
+
+// Whether to start the private browsing mode at application startup
+pref("browser.privatebrowsing.autostart", false);
+
+// Whether we should skip prompting before starting the private browsing mode
+pref("browser.privatebrowsing.dont_prompt_on_enter", false);
+
+// base url for the wifi geolocation network provider
+pref("geo.wifi.uri", "https://www.google.com/loc/json");
+
diff --git a/bundles/XO/defaults/pref/reporter.js b/bundles/XO/defaults/pref/reporter.js
new file mode 100755
index 0000000..f11a0de
--- /dev/null
+++ b/bundles/XO/defaults/pref/reporter.js
@@ -0,0 +1,3 @@
+// Make sure there are trailing slashes!
+pref("extensions.reporter.privacyURL", "http://reporter.mozilla.org/privacy/");
+pref("extensions.reporter.serviceURL", "http://reporter.mozilla.org/service/0.3/");
diff --git a/bundles/XO/defaults/profile/bookmarks.html b/bundles/XO/defaults/profile/bookmarks.html
new file mode 100755
index 0000000..9098a60
--- /dev/null
+++ b/bundles/XO/defaults/profile/bookmarks.html
@@ -0,0 +1,26 @@
+<!DOCTYPE NETSCAPE-Bookmark-file-1>
+<!-- This is an automatically generated file.
+ It will be read and overwritten.
+ DO NOT EDIT! -->
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
+<TITLE>Bookmarks</TITLE>
+<H1>Bookmarks</H1>
+
+<DL><p>
+ <DT><A HREF="https://addons.mozilla.org/en-US/firefox/bookmarks/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M%2F3AAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAPkSURBVHjaYmAAgrjyOnOGiKxqxT9%2F%2FvwHCCCGuNJKLpAo49KTL%2F5%2F%2F8PMABBADJFZFWwXnn%2F%2FDxJYeOLNf0aQ9AIg48%2Ff%2Fwwfvv1hAAggZpBAYlWdnrqJLcPVE4e%2Bsuy7%2FfH%2F%2B88%2FGdjY2Bj%2BcCqHMey6%2Ben%2F379%2F%2F%2F8B6unZ9ew%2Fy54jV249f6%2Bm9uXnX4Y9qyaoAAQAhAB7%2FwEAAAAAY3h%2BG1RdbeMMCgkB9%2Fr%2BAPL2%2FAC3vsyi5NG6YQFcbnwdZ3F44uru9gAAAQAAUjEVALPT7wDu9v4A5erz%2FgL19vr16PD6AAUHBgDu9PwA%2F%2F8AAO%2F2%2FgD0%2BP0A7e7x8QPYzsX38vj9g%2BPk6hkLFiAxy%2BP4AeHj5%2FXFtp9GonxaagII7AawXyprpf%2F%2FZ5L5%2Fe%2Fv9%2B%2Fff91ZN7nrG0icJSqrkknJxHm1h5Nl0J8%2F%2Fxg%2B%2FwDa%2Febzv39%2FWKQ2TG97ycIvq%2Bvn52oVxMHGxHDj8RcGQT4uEGZyCct98e3LL3YmJ2enNYxAi%2B48%2B8QQaizGIMLFBLaSlYWZgYWDWZaJhY2V%2BcvPfwz%2BeiIMf%2F%2F%2BY9CV4GAQ42Zh%2BPPvP8O%2Fv%2F%2BZmG7cff7u49c%2FDNtufGZgYmJiOHLvG8Pt1z8Yfv3%2Bz%2FDn19%2B3TCd2LNV7%2F%2FU3w7vPvxkWnHzDcOPFd4ZvQBPv3L79aM%2BS3nfMN88d%2BfyXkW0Lq6BiGAs7J8fHT9%2F%2FXTy%2BY82Lp0cdb5889hcgQJNU85JYFMXP%2B5aHqRmmZJ9kKMGAEBgtDCYYY6BFa%2BlrPc6yRf0LYYtZzG4YaNGibUNJVLuIcBNUTLMQM8ZoppdiaXnf9Xlf5z4ounDu4p57f%2Ff8Pt50SH9ZEfUuLehy93yMRBNroVAg6PV2yBbO9c94tK5v7suF3%2FlMs1o8oU27ltvIMic7fJv7uuqLJGa2UpPxlCILICBtGz1pYWooakeoDaTFgBtNWm04zl%2Fkbs53FnZ%2FZO%2BldGbFP5aaP50cj41pigi8XFjF2zp8ivpgsFMFHp0GgrQZL4DuYGCE6f3pzoBnUwRB8sYi4QGKHf7b5d8HiHWpMBsPvLKDeFiHmVEPBN0yMJyMIUhfb6gXbMkr4xtq1J6Z36eLpmiDH508LNShbDzB4kTIATguNsBqA1CHElJDhGdCGWsDkYY%2FTJh3lUelu384yTlzrtgDWVaggvG8qhDnYcEwwWi0wET%2FTNTh9Gh%2FvVn7v%2B2I%2BHlpWXS59ORgfOr7UGRkVNMUAWPtCMnHdbjjATFNKJeKpdLZYQY0crDzLUvfbHxdqfllj6a7p2VVjUqyGhYwPpZFqxYlf6hZ%2F7X3c736%2Fv4LV1blv94gEvsAAAAASUVORK5CYII%3D" ID="rdf:#$CnoJ1">Get Bookmark Add-ons</A>
+ <HR>
+ <DT><H3 PERSONAL_TOOLBAR_FOLDER="true" ID="rdf:#$FvPhC3">Bookmarks Toolbar Folder</H3>
+<DD>Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar
+ <DL><p>
+ <DT><A HREF="http://www.mozilla.com/en-US/firefox/central/" ID="rdf:#$GvPhC3">Getting Started</A>
+ <DT><A HREF="http://fxfeeds.mozilla.com/en-US/firefox/livebookmarks/" FEEDURL="http://fxfeeds.mozilla.com/en-US/firefox/headlines.xml" ID="rdf:#$HvPhC3">Latest Headlines</A>
+ </DL><p>
+ <HR>
+ <DT><H3 ID="rdf:#$ZvPhC3">Mozilla Firefox</H3>
+ <DL><p>
+ <DT><A HREF="http://www.mozilla.com/en-US/firefox/help/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$22iCK1">Help and Tutorials</A>
+ <DT><A HREF="http://www.mozilla.com/en-US/firefox/customize/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$32iCK1">Customize Firefox</A>
+ <DT><A HREF="http://www.mozilla.com/en-US/firefox/community/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$42iCK1">Get Involved</A>
+ <DT><A HREF="http://www.mozilla.com/en-US/firefox/about/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$52iCK1">About Us</A>
+ </DL><p>
+</DL><p>
diff --git a/bundles/XO/defaults/profile/chrome/userChrome-example.css b/bundles/XO/defaults/profile/chrome/userChrome-example.css
new file mode 100755
index 0000000..0fadb00
--- /dev/null
+++ b/bundles/XO/defaults/profile/chrome/userChrome-example.css
@@ -0,0 +1,46 @@
+/*
+ * Edit this file and copy it as userChrome.css into your
+ * profile-directory/chrome/
+ */
+
+/*
+ * This file can be used to customize the look of Mozilla's user interface
+ * You should consider using !important on rules which you want to
+ * override default settings.
+ */
+
+/*
+ * Do not remove the @namespace line -- it's required for correct functioning
+ */
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* set default namespace to XUL */
+
+
+/*
+ * Some possible accessibility enhancements:
+ */
+/*
+ * Make all the default font sizes 20 pt:
+ *
+ * * {
+ * font-size: 20pt !important
+ * }
+ */
+/*
+ * Make menu items in particular 15 pt instead of the default size:
+ *
+ * menupopup > * {
+ * font-size: 15pt !important
+ * }
+ */
+/*
+ * Give the Location (URL) Bar a fixed-width font
+ *
+ * #urlbar {
+ * font-family: monospace !important;
+ * }
+ */
+
+/*
+ * For more examples see http://www.mozilla.org/unix/customizing.html
+ */
+
diff --git a/bundles/XO/defaults/profile/chrome/userContent-example.css b/bundles/XO/defaults/profile/chrome/userContent-example.css
new file mode 100755
index 0000000..bd79691
--- /dev/null
+++ b/bundles/XO/defaults/profile/chrome/userContent-example.css
@@ -0,0 +1,35 @@
+/*
+ * Edit this file and copy it as userContent.css into your
+ * profile-directory/chrome/
+ */
+
+/*
+ * This file can be used to apply a style to all web pages you view
+ * Rules without !important are overruled by author rules if the
+ * author sets any. Rules with !important overrule author rules.
+ */
+
+/*
+ * example: turn off "blink" element blinking
+ *
+ * blink { text-decoration: none ! important; }
+ *
+ */
+
+/*
+ * example: give all tables a 2px border
+ *
+ * table { border: 2px solid; }
+ */
+
+/*
+ * example: turn off "marquee" element
+ *
+ * marquee { -moz-binding: none; }
+ *
+ */
+
+/*
+ * For more examples see http://www.mozilla.org/unix/customizing.html
+ */
+
diff --git a/bundles/XO/defaults/profile/localstore.rdf b/bundles/XO/defaults/profile/localstore.rdf
new file mode 100755
index 0000000..aa5d4d9
--- /dev/null
+++ b/bundles/XO/defaults/profile/localstore.rdf
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<RDF:RDF
+ xmlns:NC="http://home.netscape.com/NC-rdf#"
+ xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+</RDF:RDF>
diff --git a/bundles/XO/defaults/profile/mimeTypes.rdf b/bundles/XO/defaults/profile/mimeTypes.rdf
new file mode 100755
index 0000000..9665f4e
--- /dev/null
+++ b/bundles/XO/defaults/profile/mimeTypes.rdf
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:NC="http://home.netscape.com/NC-rdf#"
+ xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+
+ <Description about="urn:mimetypes">
+ <NC:MIME-types>
+ <Seq about="urn:mimetypes:root">
+ </Seq>
+ </NC:MIME-types>
+ </Description>
+</RDF>
diff --git a/bundles/XO/defaults/profile/prefs.js b/bundles/XO/defaults/profile/prefs.js
new file mode 100755
index 0000000..cff73a4
--- /dev/null
+++ b/bundles/XO/defaults/profile/prefs.js
@@ -0,0 +1,10 @@
+# Mozilla User Preferences
+
+/* Do not edit this file.
+ *
+ * If you make changes to this file while the browser is running,
+ * the changes will be overwritten when the browser exits.
+ *
+ * To make a manual change to preferences, you can visit the URL about:config
+ * For more information, see http://www.mozilla.org/unix/customizing.html#prefs
+ */
diff --git a/bundles/XO/dictionaries/en-US.aff b/bundles/XO/dictionaries/en-US.aff
new file mode 100755
index 0000000..9d5e076
--- /dev/null
+++ b/bundles/XO/dictionaries/en-US.aff
@@ -0,0 +1,206 @@
+SET ISO8859-1
+TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
+NOSUGGEST !
+
+# ordinal numbers
+COMPOUNDMIN 1
+# only in compounds: 1th, 2th, 3th
+ONLYINCOMPOUND c
+# compound rules:
+# 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.)
+# 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.)
+COMPOUNDRULE 2
+COMPOUNDRULE n*1t
+COMPOUNDRULE n*mp
+WORDCHARS 0123456789
+
+PFX A Y 1
+PFX A 0 re .
+
+PFX I Y 1
+PFX I 0 in .
+
+PFX U Y 1
+PFX U 0 un .
+
+PFX C Y 1
+PFX C 0 de .
+
+PFX E Y 1
+PFX E 0 dis .
+
+PFX F Y 1
+PFX F 0 con .
+
+PFX K Y 1
+PFX K 0 pro .
+
+SFX V N 2
+SFX V e ive e
+SFX V 0 ive [^e]
+
+SFX N Y 3
+SFX N e ion e
+SFX N y ication y
+SFX N 0 en [^ey]
+
+SFX X Y 3
+SFX X e ions e
+SFX X y ications y
+SFX X 0 ens [^ey]
+
+SFX H N 2
+SFX H y ieth y
+SFX H 0 th [^y]
+
+SFX Y Y 1
+SFX Y 0 ly .
+
+SFX G Y 2
+SFX G e ing e
+SFX G 0 ing [^e]
+
+SFX J Y 2
+SFX J e ings e
+SFX J 0 ings [^e]
+
+SFX D Y 4
+SFX D 0 d e
+SFX D y ied [^aeiou]y
+SFX D 0 ed [^ey]
+SFX D 0 ed [aeiou]y
+
+SFX T N 4
+SFX T 0 st e
+SFX T y iest [^aeiou]y
+SFX T 0 est [aeiou]y
+SFX T 0 est [^ey]
+
+SFX R Y 4
+SFX R 0 r e
+SFX R y ier [^aeiou]y
+SFX R 0 er [aeiou]y
+SFX R 0 er [^ey]
+
+SFX Z Y 4
+SFX Z 0 rs e
+SFX Z y iers [^aeiou]y
+SFX Z 0 ers [aeiou]y
+SFX Z 0 ers [^ey]
+
+SFX S Y 4
+SFX S y ies [^aeiou]y
+SFX S 0 s [aeiou]y
+SFX S 0 es [sxzh]
+SFX S 0 s [^sxzhy]
+
+SFX P Y 3
+SFX P y iness [^aeiou]y
+SFX P 0 ness [aeiou]y
+SFX P 0 ness [^y]
+
+SFX M Y 1
+SFX M 0 's .
+
+SFX B Y 3
+SFX B 0 able [^aeiou]
+SFX B 0 able ee
+SFX B e able [^aeiou]e
+
+SFX L Y 1
+SFX L 0 ment .
+
+SFX i N 1
+SFX i us i us
+
+REP 90
+REP a ei
+REP ei a
+REP a ey
+REP ey a
+REP ai ie
+REP ie ai
+REP alot a_lot
+REP are air
+REP are ear
+REP are eir
+REP air are
+REP air ere
+REP ere air
+REP ere ear
+REP ere eir
+REP ear are
+REP ear air
+REP ear ere
+REP eir are
+REP eir ere
+REP ch te
+REP te ch
+REP ch ti
+REP ti ch
+REP ch tu
+REP tu ch
+REP ch s
+REP s ch
+REP ch k
+REP k ch
+REP f ph
+REP ph f
+REP gh f
+REP f gh
+REP i igh
+REP igh i
+REP i uy
+REP uy i
+REP i ee
+REP ee i
+REP j di
+REP di j
+REP j gg
+REP gg j
+REP j ge
+REP ge j
+REP s ti
+REP ti s
+REP s ci
+REP ci s
+REP k cc
+REP cc k
+REP k qu
+REP qu k
+REP kw qu
+REP o eau
+REP eau o
+REP o ew
+REP ew o
+REP oo ew
+REP ew oo
+REP ew ui
+REP ui ew
+REP oo ui
+REP ui oo
+REP ew u
+REP u ew
+REP oo u
+REP u oo
+REP u oe
+REP oe u
+REP u ieu
+REP ieu u
+REP ue ew
+REP ew ue
+REP uff ough
+REP oo ieu
+REP ieu oo
+REP ier ear
+REP ear ier
+REP ear air
+REP air ear
+REP w qu
+REP qu w
+REP z ss
+REP ss z
+REP shun tion
+REP shun sion
+REP shun cion
+REP sitted sat
diff --git a/bundles/XO/dictionaries/en-US.dic b/bundles/XO/dictionaries/en-US.dic
new file mode 100755
index 0000000..d844a28
--- /dev/null
+++ b/bundles/XO/dictionaries/en-US.dic
@@ -0,0 +1,56053 @@
+56029
+0/nm
+0th/pt
+1/n1
+1st/p
+1th/tc
+2/nm
+2nd/p
+2th/tc
+3/nm
+3rd/p
+3th/tc
+4/nm
+4th/pt
+5/nm
+5th/pt
+6/nm
+6th/pt
+7/nm
+7th/pt
+8/nm
+8th/pt
+9/nm
+9th/pt
+A/SM
+AA/M
+AAA
+AB/M
+ABA
+ABC/M
+ABM/SM
+ABS
+AC/M
+ACLU
+ACT
+ACTH/M
+AD/M
+ADC
+ADD
+ADP/M
+AF
+AFAIK/S
+AFB
+AFC
+AFDC
+AFN
+AFT
+AI/SM
+AIDS/M
+AIDSes
+AK
+AL
+AM/M
+AMA
+ANSI/S
+ANZUS
+AOL/M
+AP
+APB
+APO
+APR
+AR
+ARC
+ASAP
+ASCII/SM
+ASL/M
+ASPCA
+ATM/M
+ATP/M
+ATV
+AV
+AWACS
+AWOL/M
+AZ/M
+AZT/M
+Aachen
+Aaliyah/M
+Aaren/M
+Aarika/M
+Aaron
+Ab/M
+Abagael/M
+Abagail/M
+Abba/S
+Abbasid
+Abbe/M
+Abbey/M
+Abbi/M
+Abbie/M
+Abbot/M
+Abbott/M
+Abby/M
+Abbye/M
+Abdel/M
+Abdul/M
+Abe/M
+Abel/M
+Abelard
+Abelson/M
+Aberdeen/M
+Abernathy/M
+Abeu/M
+Abey/M
+Abidjan/M
+Abie/M
+Abigael/M
+Abigail
+Abigale/M
+Abilene
+Abner/M
+Aborigine/MS
+Abra/M
+Abraham/M
+Abrahan/M
+Abram/MS
+Abramo/M
+Abran/M
+Absalom
+Abuja
+Abyssinia/M
+Abyssinian/M
+Ac/M
+Acadia/M
+Acapulco/M
+Accra/M
+Acevedo/M
+Achaean/M
+Achebe/M
+Achernar
+Acheson/M
+Achilles/M
+Aconcagua/M
+Acosta/M
+Acropolis
+Acrux/M
+Actaeon
+Acton
+Acts
+Acuff/M
+Ad/MN
+Ada/SM
+Adah/M
+Adair/M
+Adaline/M
+Adam/SM
+Adamo/M
+Adan/M
+Adana
+Adar/M
+Adara/M
+Adda/M
+Addams
+Adderley/M
+Addi/M
+Addia/M
+Addie/M
+Addison
+Addy/M
+Ade/M
+Adel/M
+Adela/M
+Adelaida/M
+Adelaide/M
+Adelbert/M
+Adele/M
+Adelheid/M
+Adelice/M
+Adelina/M
+Adelind/M
+Adeline/M
+Adella/M
+Adelle/M
+Aden/M
+Adena/M
+Adenauer
+Adey/M
+Adham/M
+Adhara/M
+Adi/M
+Adiana/M
+Adidas/M
+Adina/M
+Adirondack/MS
+Adirondacks/M
+Adkins/M
+Adlai/M
+Adler
+Adm
+Admiralty
+Ado/M
+Adolf/M
+Adolfo/M
+Adolph/M
+Adolphe/M
+Adolpho/M
+Adolphus/M
+Adonis/MS
+Adora/M
+Adore/M
+Adoree/M
+Adorne/M
+Adrea/M
+Adrenalin/MS
+Adria/MX
+Adrian
+Adriana/M
+Adriane/M
+Adrianna/M
+Adrianne/M
+Adriano/M
+Adriatic/M
+Adrien/M
+Adriena/M
+Adrienne/M
+Advent/MS
+Adventist/MS
+Advil/M
+Aegean/M
+Aelfric/M
+Aeneas/M
+Aeneid/M
+Aeolus/M
+Aeriel/M
+Aeriela/M
+Aeriell/M
+Aeroflot/M
+Aeschylus/M
+Aesculapius/M
+Aesop/M
+Afghan/SM
+Afghanistan/M
+Afr
+Africa/M
+African/SM
+Afrikaans/M
+Afrikaner/SM
+Afro/SM
+Afrocentric
+Afrocentrism
+Afton/M
+Ag/M
+Agace/M
+Agamemnon/M
+Agana
+Agassi/M
+Agassiz/M
+Agata/M
+Agatha/M
+Agathe/M
+Aggi/M
+Aggie
+Aggy/M
+Aglaia
+Agna/M
+Agnella/M
+Agnes
+Agnese/M
+Agnesse/M
+Agneta/M
+Agnew/M
+Agni/M
+Agnola/M
+Agosto/M
+Agra
+Agretha/M
+Agricola
+Agrippa/M
+Agrippina/M
+Aguascalientes
+Aguie/M
+Aguilar/M
+Aguinaldo/M
+Aguirre/M
+Aguistin/M
+Aguste/M
+Agustin/M
+Ahab/M
+Aharon/M
+Ahmad/M
+Ahmadabad
+Ahmed/M
+Ahriman/M
+Aida/M
+Aidan/M
+Aigneis/M
+Aiken
+Aila/M
+Ailbert/M
+Aile/M
+Ailee/M
+Aileen/M
+Ailene/M
+Ailey/M
+Aili/SM
+Ailina/M
+Ailsun/M
+Ailyn/M
+Aime/M
+Aimee/M
+Aimil/M
+Aindrea/M
+Ainslee/M
+Ainsley/M
+Ainslie/M
+Ainu
+Airedale/MS
+Aisha
+Ajax/M
+Ajay/M
+Akbar
+Akhmatova/M
+Akihito
+Akim/M
+Akita
+Akkad
+Akron/M
+Aksel/M
+Al/MY
+Ala/S
+Alabama/M
+Alabaman/MS
+Alabamian/SM
+Aladdin/M
+Alain/M
+Alaine/M
+Alair/M
+Alameda/M
+Alamo/M
+Alamogordo/M
+Alan/M
+Alana/M
+Alanah/M
+Aland/M
+Alane/M
+Alanna/M
+Alano/M
+Alanson/M
+Alar/M
+Alard/M
+Alaric
+Alasdair/M
+Alaska/M
+Alaskan/MS
+Alastair/M
+Alasteir/M
+Alaster/M
+Alayne/M
+Alba
+Albania/M
+Albanian/MS
+Albany/M
+Albee
+Alberik/M
+Alberio/M
+Albert
+Alberta/M
+Albertan
+Albertina/M
+Albertine/M
+Alberto/M
+Albie/M
+Albigensian
+Albina/M
+Albion
+Albireo/M
+Albrecht/M
+Albuquerque/M
+Alcatraz
+Alcestis
+Alcibiades
+Alcmena/M
+Alcoa/M
+Alcott
+Alcuin
+Alcyone
+Aldan
+Aldebaran/M
+Alden
+Alderamin/M
+Aldin/M
+Aldis/M
+Aldo/M
+Aldon/M
+Aldous/M
+Aldric/M
+Aldrich/M
+Aldridge/M
+Aldrin/M
+Aldus/M
+Aldwin/M
+Alec/M
+Alecia/M
+Aleda/M
+Aleece/M
+Aleen/M
+Aleichem/M
+Alejandra/M
+Alejandrina/M
+Alejandro/M
+Alejoa/M
+Aleksandr/M
+Alembert/M
+Alena/M
+Alene/M
+Aleppo/M
+Alessandra/M
+Alessandro/M
+Aleta/M
+Alethea/M
+Aleut/MS
+Aleutian/SM
+Alex/M
+Alexa/M
+Alexander/MS
+Alexandr/M
+Alexandra
+Alexandre/M
+Alexandria/M
+Alexandrian
+Alexandrina/M
+Alexandro/MS
+Alexei/M
+Alexi/MS
+Alexia/M
+Alexina/M
+Alexine/M
+Alexio/M
+Alf/M
+Alfi/M
+Alfie/M
+Alfons/M
+Alfonse/M
+Alfonso/M
+Alfonzo/M
+Alford/M
+Alfred
+Alfreda/M
+Alfredo
+Alfy/M
+Algenib/M
+Alger
+Algeria/M
+Algerian/SM
+Algernon/M
+Algieba/M
+Algiers/M
+Algol/M
+Algonquian/SM
+Algonquin/MS
+Alhambra
+Alhena/M
+Ali/S
+Alia/M
+Alic/M
+Alica/M
+Alice/M
+Alicea/M
+Alicia/M
+Alick/M
+Alida/M
+Alidia/M
+Alie/M
+Alighieri/M
+Alika/M
+Alikee/M
+Alina/M
+Aline/M
+Alioth/M
+Alisa/M
+Alisander/M
+Alisha/M
+Alison/M
+Alissa/M
+Alistair/M
+Alister/M
+Alisun/M
+Alix/M
+Aliza/M
+Alkaid/M
+Alla/M
+Allah/M
+Allahabad
+Allan/M
+Allard/M
+Allayne/M
+Alleen/M
+Alleghenies/M
+Allegheny/S
+Allegra/M
+Allen
+Allende/M
+Allene/M
+Allentown
+Alley/M
+Alleyn/M
+Allhallows/M
+Alli/SM
+Allianora/M
+Allie/M
+Allin/M
+Allina/M
+Allison/M
+Allissa/M
+Allister/M
+Allistir/M
+Allix/M
+Allstate/M
+Allsun/M
+Allx/M
+Ally/SM
+Allyce/M
+Allyn/M
+Allys
+Allyson/M
+Alma/M
+Almach/M
+Almaty/M
+Almeda/M
+Almeria/M
+Almeta/M
+Almighty/M
+Almira/M
+Almire/M
+Almohad/M
+Almoravid/M
+Alnilam/M
+Alnitak/M
+Aloin/M
+Aloise/M
+Aloisia/M
+Alon/M
+Alonso/M
+Alonzo/M
+Aloysia/M
+Aloysius/M
+Alpert/M
+Alphard/M
+Alphecca/M
+Alpheratz/M
+Alphonse/M
+Alphonso/M
+Alpine
+Alpo/M
+Alps/M
+Alric/M
+Alsace/M
+Alsatian/SM
+Alsop/M
+Alston/M
+Alta
+Altai/M
+Altaic/M
+Altair
+Altamira
+Althea/M
+Altiplano/M
+Altman/M
+Altoids/M
+Alton/M
+Aludra/M
+Aluin/M
+Aluino/M
+Alva
+Alvan/M
+Alvarado/M
+Alvarez/M
+Alvaro/M
+Alvera/M
+Alverta/M
+Alvie/M
+Alvin/M
+Alvina/M
+Alvinia/M
+Alvira/M
+Alvis/M
+Alvy/M
+Alwin/M
+Alwyn/M
+Alyce/M
+Alyda/M
+Alyosha/M
+Alys/M
+Alysa/M
+Alyse/M
+Alysia/M
+Alyson/M
+Alyss
+Alyssa/M
+Alzheimer/M
+Am/MNR
+Amabel/M
+Amabelle/M
+Amadeus/M
+Amado/M
+Amalea/M
+Amalee/M
+Amaleta/M
+Amalia/M
+Amalie/M
+Amalita/M
+Amalle/M
+Amanda/M
+Amandi/M
+Amandie/M
+Amandy/M
+Amara/M
+Amargo/M
+Amarillo
+Amaru/M
+Amata/M
+Amaterasu/M
+Amati
+Amazon/SM
+Amazonian
+Amber/MY
+Amberly/M
+Amble/M
+Ambros/M
+Ambrose
+Ambrosi/M
+Ambrosio/M
+Ambrosius/M
+Ambur/M
+Amby/M
+Ame/M
+Amelia/M
+Amelie/M
+Amelina/M
+Ameline/M
+Amelita/M
+Amen/M
+Amenhotep/M
+Amerasian
+America/SM
+American/MS
+Americana/M
+Americanism/SM
+Americanization/SM
+Americanize/DSG
+Amerigo/M
+Amerind/SM
+Amerindian/SM
+Amery/M
+Ameslan/M
+Amharic/M
+Amherst
+Ami/M
+Amie/M
+Amiga/M
+Amii/M
+Amil/M
+Amish/M
+Amitie/M
+Amity/M
+Ammamaria/M
+Amman/M
+Amoco/M
+Amory/M
+Amos
+Amparo/M
+Ampere/M
+Amritsar
+Amsterdam/M
+Amtrak
+Amundsen
+Amur/M
+Amway/M
+Amy/M
+Amye/M
+Ana/M
+Anabal/M
+Anabaptist/M
+Anabel/M
+Anabella/M
+Anabelle/M
+Anacin/M
+Anacreon
+Anaheim
+Analects/M
+Analiese/M
+Analise/M
+Anallese/M
+Anallise/M
+Ananias/M
+Anasazi
+Anastasia
+Anastasie/M
+Anastassia/M
+Anatol/M
+Anatola/M
+Anatole/M
+Anatolia/M
+Anatolian/M
+Anatollo/M
+Anaxagoras
+Ancell/M
+Anchorage/M
+Andalusia/M
+Andalusian
+Andaman
+Andean
+Andee/M
+Andeee/M
+Anderea/M
+Anders/N
+Andersen/M
+Anderson
+Andes/M
+Andi/M
+Andie/M
+Andonis/M
+Andorra/M
+Andorran/SM
+Andra/MS
+Andre/MS
+Andrea/SM
+Andreana/M
+Andree/M
+Andrei/M
+Andrej/M
+Andrew/SM
+Andrey/M
+Andria/M
+Andriana/M
+Andrianampoinimerina/M
+Andriette/M
+Andris
+Andromache
+Andromeda/M
+Andropov
+Andros
+Andrus/M
+Andy/M
+Anestassia/M
+Anet/M
+Anett/M
+Anetta/M
+Anette/M
+Angara
+Ange/M
+Angel/M
+Angela/M
+Angele/M
+Angeli/M
+Angelia/M
+Angelica
+Angelico
+Angelika/M
+Angelina/M
+Angeline/M
+Angelique/M
+Angelita/M
+Angelle/M
+Angelo/M
+Angelou
+Angevin/M
+Angie/M
+Angil/M
+Angkor
+Angle/MS
+Anglia
+Anglican/SM
+Anglicanism/MS
+Anglicism/MS
+Anglicization
+Anglicize
+Anglo
+Anglophile
+Anglophobe
+Angola/M
+Angolan/MS
+Angora/SM
+Angstrom
+Anguilla/M
+Angus/M
+Angy/M
+Ania/M
+Aniakchak/M
+Anibal/M
+Anica/M
+Anissa/M
+Anita/M
+Anitra/M
+Anjanette/M
+Anjela/M
+Ankara/M
+Ann/M
+Anna
+Annabal/M
+Annabel/M
+Annabela/M
+Annabell/M
+Annabella/M
+Annabelle/M
+Annadiana/M
+Annadiane/M
+Annalee/M
+Annaliese/M
+Annalise/M
+Annam/M
+Annamaria/M
+Annamarie/M
+Annapolis/M
+Annapurna/M
+Anne
+Annecorinne/M
+Anneliese/M
+Annelise/M
+Annemarie/M
+Annetta/M
+Annette/M
+Anni/SM
+Annice/M
+Annie/M
+Annissa/M
+Annmaria/M
+Annmarie/M
+Annnora/M
+Annora/M
+Annunciation/MS
+Anny/M
+Anouilh
+Ansel/M
+Ansell/M
+Anselm
+Anselma/M
+Anselmo/M
+Anshan/M
+Ansley/M
+Anson/M
+Anstice/M
+Antaeus
+Antananarivo/M
+Antarctic/M
+Antarctica/M
+Antares/M
+Anthe/M
+Anthea/M
+Anthia/M
+Anthiathia/M
+Anthony
+Antichrist/MS
+Antietam
+Antigone/M
+Antigua/M
+Antillean
+Antilles/M
+Antin/M
+Antioch
+Antipas/M
+Antipodes
+Antofagasta/M
+Antoine/M
+Antoinette
+Anton/MS
+Antone/M
+Antonella/M
+Antonetta/M
+Antoni/M
+Antonia/M
+Antonie/M
+Antonietta/M
+Antonin/M
+Antonina/M
+Antonino/M
+Antoninus
+Antonio/M
+Antonius
+Antony/M
+Antwan/M
+Antwerp/M
+Anubis/M
+Any/M
+Anya/M
+Anzac
+Apache/SM
+Apalachicola/M
+Apennines
+Aphrodite/M
+Apia
+Apocalypse/M
+Apocrypha/M
+Apollinaire
+Apollo/SM
+Apollonian
+Appalachia/M
+Appalachian/S
+Appaloosa/SM
+Apple/M
+Appleseed
+Appleton
+Appolonia/M
+Appomattox
+Apr/M
+April/MS
+Aprilette/M
+Apuleius
+Aquafresh/M
+Aquarius/MS
+Aquila
+Aquinas/M
+Aquino/M
+Aquitaine/M
+Ar/MY
+Ara/M
+Arab/SM
+Arabel/M
+Arabela/M
+Arabele/M
+Arabella/M
+Arabelle/M
+Arabia/M
+Arabian/MS
+Arabic/M
+Arabist/MS
+Araby
+Araceli/M
+Arafat/M
+Araguaya/M
+Aral/M
+Araldo/M
+Aramaic/M
+Aramco/M
+Arapaho/MS
+Arapahoes
+Ararat/M
+Araucanian
+Arawak/M
+Arawakan/M
+Arbitron/M
+Arcadia/M
+Arcadian/M
+Arch/R
+Archaimbaud/M
+Archambault/M
+Archean
+Archibald/M
+Archibaldo/M
+Archibold/M
+Archie/M
+Archimedes
+Archy/M
+Arctic/M
+Arcturus/M
+Arda/MH
+Ardabil
+Ardath/M
+Ardeen/M
+Ardelia/M
+Ardelis/M
+Ardella/M
+Ardelle/M
+Arden
+Ardene/M
+Ardenia/M
+Ardine/M
+Ardis/M
+Ardisj/M
+Ardith/M
+Ardra/M
+Ardyce/M
+Ardys
+Ardyth/M
+Arel/M
+Arequipa
+Ares
+Aretha/M
+Argentina/M
+Argentine
+Argentinean
+Argentinian/MS
+Argo/S
+Argonaut/MS
+Argonne/M
+Argus/M
+Ari/M
+Ariadne/M
+Ariana/M
+Arianism/M
+Aridatha/M
+Arie/SM
+Ariel
+Ariela/M
+Ariella/M
+Arielle/M
+Aries/MS
+Arin/M
+Ario/M
+Ariosto
+Aristarchus/M
+Aristides
+Aristophanes/M
+Aristotelian/M
+Aristotle/M
+Arius/M
+Ariz
+Arizona/M
+Arizonan/SM
+Arizonian/MS
+Arjuna
+Ark
+Arkansan/MS
+Arkansas/M
+Arkhangelsk
+Arkwright
+Arlan/M
+Arlana/M
+Arlee/M
+Arleen/M
+Arlen/M
+Arlena/M
+Arlene/M
+Arleta/M
+Arlette/M
+Arley/M
+Arleyne/M
+Arlie/M
+Arliene/M
+Arlin/M
+Arlina/M
+Arlinda/M
+Arline/M
+Arlington
+Arluene/M
+Arly/M
+Arlyn/M
+Arlyne/M
+Armageddon/SM
+Armagnac/M
+Arman/M
+Armand/M
+Armando/M
+Armani/M
+Armenia/M
+Armenian/SM
+Armin/M
+Arminius/M
+Armonk/M
+Armour/M
+Armstrong/M
+Arnaldo/M
+Arne
+Arneb/M
+Arney/M
+Arnhem
+Arni/M
+Arnie/M
+Arno/M
+Arnold
+Arnoldo/M
+Arnuad/M
+Arnulfo/M
+Arny/M
+Aron/M
+Arrhenius
+Arri/M
+Arron/M
+Art/M
+Artair/M
+Artaxerxes/M
+Arte/M
+Artemas
+Artemis/M
+Artemus/M
+Arther/M
+Arthur/M
+Arthurian
+Artie/M
+Artur/M
+Arturo/M
+Artus/M
+Arty/M
+Aruba/M
+Arv/M
+Arvie/M
+Arvin/M
+Arvy/M
+Aryan/MS
+Aryn/M
+Asa/M
+Asama/M
+Ascella/M
+Ascension/M
+Ase/M
+Asgard
+Ash/MRY
+Ashanti
+Ashbey/M
+Ashby/M
+Ashcroft
+Ashe/Y
+Ashely/M
+Ashgabat
+Ashia/M
+Ashien/M
+Ashikaga/M
+Ashil/M
+Ashkenazim
+Ashkhabad/M
+Ashla/M
+Ashlan/M
+Ashlee/M
+Ashleigh/M
+Ashlen/M
+Ashley/M
+Ashli/M
+Ashlie/M
+Ashlin/M
+Ashly/M
+Ashmolean/M
+Ashton
+Ashurbanipal
+Asia/M
+Asian/MS
+Asiatic/SM
+Asimov
+Asmara
+Asoka
+Aspell/M
+Aspen/M
+Aspidiske/M
+Asquith
+Assad/M
+Assam/M
+Assamese/M
+Assembly
+Assisi
+Assyria/M
+Assyrian/SM
+Astaire
+Astana/M
+Astarte/M
+Aston
+Astor
+Astoria
+Astra/M
+Astrakhan
+Astrid/M
+Astrix/M
+AstroTurf
+Asturias
+Asuncion/M
+Aswan/M
+At/SM
+Atacama/M
+Atahualpa
+Atalanta
+Atari/M
+Ataturk/M
+Athabasca/M
+Athabaskan/MS
+Athena/M
+Athene/M
+Athenian/SM
+Athens/M
+Atkins/M
+Atkinson
+Atlanta/M
+Atlante/SM
+Atlantic/M
+Atlantis/M
+Atlas/MS
+Atman
+Atreus
+Atria/M
+Atropos/M
+Attic/M
+Attica/M
+Attila/M
+Attlee
+Attn
+Attucks
+Atwood/M
+Au/M
+Aube
+Auberon/M
+Aubert/M
+Auberta/M
+Aubine/M
+Aubree/M
+Aubrette/M
+Aubrey
+Aubrie/M
+Aubry/M
+Auckland
+Auden/M
+Audi/M
+Audie/M
+Audion/M
+Audra/M
+Audre/M
+Audrey/M
+Audrie/M
+Audry/M
+Audrye/M
+Audubon
+Audy/M
+Aug/M
+Augean
+Augie/M
+Augsburg
+August/MS
+Augusta/M
+Augustan
+Auguste/M
+Augustin/M
+Augustina/M
+Augustine/M
+Augustinian/MS
+Augusto/M
+Augustus/M
+Augy/M
+Aundrea/M
+Aura/M
+Aurangzeb
+Aurea/M
+Aurel/M
+Aurelea/M
+Aurelia/M
+Aurelie/M
+Aurelio/M
+Aurelius
+Aureomycin/M
+Auria/M
+Aurie/M
+Auriga/M
+Aurilia/M
+Aurlie/M
+Auroora/M
+Aurora/M
+Aurore/M
+Aurthur/M
+Auschwitz
+Aussie/MS
+Austen
+Austerlitz/M
+Austin/MS
+Austina/M
+Austine/M
+Australasia/M
+Australasian
+Australia/M
+Australian/MS
+Australoid
+Australopithecus/M
+Austria/M
+Austrian/SM
+Austronesian/M
+Autumn/M
+Av/M
+Ava/M
+Avalon
+Ave
+Aveline/M
+Aventine
+Averell/M
+Averil/M
+Averill/M
+Avernus
+Averroes
+Avery/M
+Averyl/M
+Avesta/M
+Avicenna
+Avictor/M
+Avie/M
+Avigdor/M
+Avignon
+Avila/M
+Avior/M
+Avis
+Aviva/M
+Avivah/M
+Avogadro
+Avon
+Avram/M
+Avril/M
+Avrit/M
+Avrom/M
+Ax/M
+Axe/M
+Axel
+Axis
+Axum
+Ayala/M
+Ayers
+Aylmar/M
+Aylmer/M
+Aymara
+Aymer/M
+Ayn/M
+Ayrshire/M
+Ayurveda
+Ayyubid/M
+Azana/M
+Azania/M
+Azazel
+Azerbaijan/M
+Azerbaijani/MS
+Azores/M
+Azov
+Aztec/SM
+Aztecan/M
+Aztlan/M
+B/MNRTG
+BA/M
+BASIC/SM
+BB/M
+BBB
+BBC
+BBQ
+BBS
+BBSes
+BC/M
+BIA
+BIOS
+BITNET/S
+BLT/SM
+BM/M
+BMW/M
+BO
+BPOE
+BR
+BS/M
+BSA
+BSD/S
+BTU
+BTW
+BYOB
+Ba/M
+Baal/SM
+Bab/SM
+Babara/M
+Babb/M
+Babbage
+Babbette/M
+Babbie/M
+Babbitt
+Babel/MS
+Babette/M
+Babita/M
+Babylon/MS
+Babylonia/M
+Babylonian/SM
+Bacall/M
+Bacardi
+Bacchanalia/M
+Bacchic
+Bacchus/M
+Bach/M
+Backus/M
+Bacon/M
+Bactria
+Baden
+Badlands/M
+Baedeker/MS
+Baez
+Baffin/M
+Baggies
+Baghdad/M
+Baguio
+Baha'i
+Baha'ullah
+Bahama/SM
+Bahamanian
+Bahamas/M
+Bahamian/MS
+Bahia
+Bahrain/M
+Baikal
+Bail/M
+Bailey/M
+Bailie/M
+Baillie/M
+Baily/M
+Baird
+Bakelite/M
+Baker
+Bakersfield
+Baku/M
+Bakunin
+Balanchine
+Balaton
+Balboa
+Bald/MR
+Balder/M
+Balduin/M
+Baldwin/SM
+Bale/M
+Balearic/M
+Balfour
+Bali/M
+Balinese/M
+Balkan/S
+Balkhash
+Ball
+Ballard/M
+Balthazar
+Baltic/M
+Baltimore/M
+Baluchistan
+Balzac/M
+Bamako/M
+Bambi/M
+Bambie/M
+Bamby/M
+Ban/M
+Banach/M
+Bancroft/M
+Bandung/M
+Bangalore
+Bangkok/M
+Bangladesh/M
+Bangladeshi/MS
+Bangor
+Bangui/M
+Banjarmasin/M
+Banjul
+Bank/SM
+Banky/M
+Banneker/M
+Bannister
+Banting
+Bantu/MS
+Baotou/M
+Baptist/SM
+Baptiste/M
+Bar/H
+Barabbas
+Barb/MR
+Barbabas/M
+Barbabra/M
+Barbadian/SM
+Barbados/M
+Barbara/M
+Barbaraanne/M
+Barbarella/M
+Barbarossa/M
+Barbary/M
+Barbe/M
+Barbee/M
+Barbette/M
+Barbey/M
+Barbi/M
+Barbie
+Barbour/M
+Barbra/M
+Barbuda/M
+Barby/M
+Barcelona/M
+Barclay/M
+Bard/M
+Barde/M
+Bardeen/M
+Barents/M
+Bari/M
+Barker/M
+Barkley/M
+Barlow/M
+Barn/M
+Barnabas
+Barnabe/M
+Barnaby/M
+Barnard
+Barnaul
+Barnebas/M
+Barnes
+Barnett/M
+Barney/M
+Barnie/M
+Barnum
+Barny/M
+Baroda
+Baron/M
+Barquisimeto
+Barr/M
+Barranquilla
+Barrera/M
+Barret/M
+Barrett/M
+Barri/MS
+Barrie/M
+Barron/M
+Barry
+Barrymore
+Bart
+Bartel/M
+Barth/S
+Barthel/M
+Bartholdi/M
+Bartholemy/M
+Bartholomeo/M
+Bartholomeus/M
+Bartholomew
+Bartie/M
+Bartlet/M
+Bartlett
+Bartok
+Bartolemo/M
+Bartolomeo/M
+Barton
+Bartram/M
+Barty/M
+Baruch
+Bary/M
+Baryram/M
+Baryshnikov
+Base/M
+Basel/M
+Basho/M
+Basia/M
+Basie
+Basil
+Basile/M
+Basilio/M
+Basilius/M
+Basque/MS
+Basra
+Bass/M
+Basseterre/M
+Bastian/M
+Bastien/M
+Bastille/M
+Basutoland/M
+Bat/M
+Bataan/M
+Bates
+Batholomew/M
+Bathsheba
+Batista
+Batman/M
+Batsheva/M
+Battle/M
+Batu/M
+Baudelaire/M
+Baudoin/M
+Baudouin/M
+Bauer
+Bauhaus/M
+Baum
+Bavaria/M
+Bavarian
+Bax
+Baxie/M
+Baxter/M
+Baxy/M
+Bay/MR
+Bayamon
+Bayard
+Bayer/M
+Bayes
+Bayesian
+Bayeux/M
+Baylor/M
+Bayonne/M
+Bayreuth
+Baywatch/M
+Be/MH
+Bea/M
+Beach/M
+Beadle
+Beale/M
+Bealle/M
+Bean/M
+Bear/M
+Beard/M
+Beardmore/M
+Beardsley
+Bearnaise/M
+Bearnard/M
+Beasley/M
+Beatlemania/M
+Beatles/M
+Beatrice/M
+Beatrisa/M
+Beatrix/M
+Beatriz/M
+Beau/M
+Beaufort
+Beaujolais/M
+Beaumarchais
+Beaumont
+Beauregard/M
+Beauvoir
+Bebe/M
+Becca/M
+Bechtel/M
+Beck/MR
+Becka/M
+Becker/M
+Becket/M
+Beckett/M
+Becki/M
+Beckie/M
+Becky/M
+Becquerel
+Bede
+Bedouin/SM
+Bee/M
+Beebe/M
+Beecher
+Beefaroni/M
+Beelzebub/M
+Beerbohm
+Beethoven/M
+Beeton/M
+Begin
+Behan
+Behring
+Beiderbecke
+Beijing/M
+Beilul/M
+Beirut/M
+Beitris/M
+Bekesy/M
+Bekki/M
+Bel/M
+Bela/M
+Belarus/M
+Belau/M
+Belem/M
+Belfast/M
+Belg
+Belgian/SM
+Belgium/M
+Belgrade/M
+Belia/M
+Belicia/M
+Belinda/M
+Belita/M
+Belize/M
+Bell/M
+Bella/M
+Bellamy/M
+Bellanca/M
+Bellatrix/M
+Belle/M
+Bellina/M
+Bellini
+Bellow
+Belmont/M
+Belmopan
+Belorussian/MS
+Belshazzar/M
+Beltane
+Beltran/M
+Belushi/M
+Belva/M
+Belvia/M
+Ben/M
+Benacerraf/M
+Benchley/M
+Bender/M
+Bendick/M
+Bendicty/M
+Bendite/M
+Bendix/M
+Benedetta/M
+Benedetto/M
+Benedick/M
+Benedict/M
+Benedicta/M
+Benedictine/SM
+Benedicto/M
+Benedikt/M
+Benedikta/M
+Benelux/M
+Benet
+Benetta/M
+Benetton/M
+Bengal/SM
+Bengali/M
+Benghazi/M
+Bengt/M
+Beniamino/M
+Benin/M
+Beninese/M
+Benita/M
+Benito/M
+Benjamen/M
+Benjamin
+Benji/M
+Benjie/M
+Benjy/M
+Benn/M
+Bennett
+Benni/M
+Bennie/M
+Benny/M
+Benoit/M
+Benoite/M
+Benson/M
+Bent/M
+Bentham
+Bentlee/M
+Bentley
+Benton
+Benyamin/M
+Benz
+Benzedrine/M
+Beowulf
+Ber/MG
+Berber/SM
+Berenice/M
+Beret
+Beretta/M
+Berg/NR
+Bergen/M
+Berger/M
+Bergerac
+Berget/M
+Bergman
+Bergson
+Beria
+Berk/MY
+Berke/M
+Berkeley/M
+Berkie/M
+Berkley/M
+Berkly/M
+Berkshire/SM
+Berky/M
+Berle/M
+Berlin/SZMR
+Berliner/M
+Berlioz
+Berlitz/M
+Bermuda/SM
+Bermudan/SM
+Bermudian/SM
+Bern/M
+Berna/M
+Bernadene/M
+Bernadette
+Bernadina/M
+Bernadine/M
+Bernard
+Bernardina/M
+Bernardine
+Bernardo/M
+Bernarr/M
+Bernays/M
+Bernbach/M
+Bernelle/M
+Bernese
+Bernete/M
+Bernetta/M
+Bernette/M
+Bernhard/M
+Bernhardt
+Berni/M
+Bernice/M
+Bernie/M
+Bernini
+Bernita/M
+Bernoulli
+Bernstein
+Berny/M
+Berra/M
+Berri/M
+Berrie/M
+Berry
+Bert/M
+Berta/M
+Berte/M
+Bertelsmann/M
+Bertha/M
+Berthe/M
+Berti/M
+Bertie/M
+Bertillon/M
+Bertina/M
+Bertine/M
+Berton/M
+Bertram/M
+Bertrand/M
+Bertrando/M
+Berty/M
+Beryl/M
+Beryle/M
+Berzelius
+Bess
+Bessel
+Bessemer/M
+Bessie
+Bessy/M
+Best/M
+Betelgeuse/M
+Beth/M
+Bethanne/M
+Bethany
+Bethe
+Bethena/M
+Bethesda
+Bethina/M
+Bethlehem
+Bethune
+Betsey/M
+Betsy/M
+Betta/M
+Bette/M
+Betteann/M
+Betteanne/M
+Betti
+Bettie/M
+Bettina/M
+Bettine/M
+Betty/M
+Bettye/M
+Beulah
+Bevan
+Beverie/M
+Beverlee/M
+Beverley/M
+Beverlie/M
+Beverly/M
+Bevin
+Bevon/M
+Bevvy/M
+Beyer
+Bhopal
+Bhutan/M
+Bhutanese/M
+Bhutto/M
+Bi/M
+Bialystok
+Bianca/M
+Bianka/M
+Bib
+Bibbie/M
+Bibby/M
+Bibbye/M
+Bibi/M
+Bible/MS
+Bic/M
+Biddie/M
+Biddle
+Biddy/M
+Bidget/M
+Bierce
+Bigfoot/M
+Biggles/M
+Biko/M
+Bil/MY
+Bilbao
+Bilbo/M
+Bili/M
+Bill/MJ
+Billi/M
+Billie/M
+Billings/M
+Billy/M
+Billye/M
+Bimini/M
+Bink/M
+Binky/M
+Binni/M
+Binnie/M
+Binny/M
+Bioko/M
+Birch/M
+Bird
+Birdie/M
+Birdseye/M
+Birgit/M
+Birgitta/M
+Birk/M
+Birkenstock
+Birmingham/M
+Biro/M
+Biron/M
+Biscay
+Biscayne/M
+Bishkek
+Bishop/M
+Bismarck/M
+Bismark/M
+Bisquick/M
+Bissau/M
+Bizet
+Bjorn/M
+Bk/M
+Blackbeard/M
+Blackburn/M
+Blackfeet
+Blackfoot/M
+Blackpool/M
+Blackshirt/M
+Blackstone
+Blackwell
+Blaine/M
+Blair/M
+Blaire/M
+Blake
+Blakelee/M
+Blakeley/M
+Blanca/M
+Blanch/M
+Blancha/M
+Blanchard/M
+Blanche/M
+Blane/M
+Blankenship/M
+Blantyre/M
+Blatz/M
+Blavatsky
+Blayne/M
+Blenheim/M
+Blevins/M
+Bligh/M
+Blinni/M
+Blinnie/M
+Blinny/M
+Bliss
+Blisse/M
+Blithe/M
+Bloch
+Blockbuster/M
+Bloemfontein/M
+Blondel/M
+Blondell/M
+Blondelle/M
+Blondie/M
+Blondy/M
+Bloom/MR
+Bloomfield
+Bloomingdale/M
+Bloomsbury
+Blucher/M
+Bluebeard/M
+Blvd
+Blythe/M
+Bo/MRZ
+Boadicea
+Boas/M
+Bob/M
+Bobbe/M
+Bobbee/M
+Bobbette/M
+Bobbi/M
+Bobbie/M
+Bobbitt/M
+Bobby/M
+Bobbye/M
+Bobette/M
+Bobina/M
+Bobine/M
+Bobinette/M
+Boccaccio
+Bodhidharma/M
+Bodhisattva/M
+Boeing/M
+Boeotia/M
+Boeotian
+Boer/M
+Boethius
+Bogart/M
+Bogey/M
+Bogota/M
+Bohemia
+Bohemian/SM
+Bohr
+Boigie/M
+Boise/M
+Bojangles/M
+Boleyn/M
+Bolivar/M
+Bolivia/M
+Bolivian/MS
+Bologna/M
+Bolshevik/SM
+Bolshevism
+Bolshevist
+Bolshoi/M
+Bolton
+Boltzmann
+Bombay/M
+Bonaparte
+Bonaventure
+Bond/M
+Bondie/M
+Bondon/M
+Bondy/M
+Bone/M
+Bonhoeffer/M
+Boniface
+Bonita/M
+Bonn/MR
+Bonnee/M
+Bonner/M
+Bonneville/M
+Bonni/M
+Bonnibelle/M
+Bonnie/M
+Bonny
+Booker/M
+Boole/M
+Boolean
+Boone/M
+Boonie/M
+Boony/M
+Boot/M
+Boote/MS
+Bootes/M
+Booth
+Boothe/M
+Bord/MN
+Bordeaux/M
+Borden/M
+Bordie/M
+Bordon/M
+Bordy/M
+Boreas/M
+Borg/SM
+Borges
+Borgia
+Borglum
+Boris
+Bork/M
+Borlaug/M
+Born
+Borneo/M
+Borobudur/M
+Borodin
+Boru/M
+Bosch
+Bose
+Bosnia/M
+Bosnian
+Bosporus/M
+Boston/MS
+Bostonian
+Boswell
+Botswana/M
+Botticelli
+Boulder
+Boulez/M
+Bourbaki/M
+Bourbon/SM
+Bourke/M
+Bournemouth
+Bovary/M
+Bowditch/M
+Bowell/M
+Bowen/M
+Bowers
+Bowery/M
+Bowie
+Bowman/M
+Boy/MR
+Boyce/M
+Boycey/M
+Boycie/M
+Boyd
+Boyer/M
+Boyle
+Br/MNT
+Brad/MNY
+Bradan/M
+Bradbury
+Braddock/M
+Brade/M
+Braden/M
+Bradford
+Bradley
+Bradly/M
+Bradney/M
+Bradshaw/M
+Bradstreet/M
+Brady
+Bragg/M
+Brahe
+Brahma/MS
+Brahmagupta/M
+Brahman/MS
+Brahmani
+Brahmanism/SM
+Brahmaputra/M
+Brahms/M
+Braille/MS
+Brain/M
+Bram/M
+Brampton/M
+Bran/M
+Brana/M
+Branch/M
+Brand/MNR
+Brandais/M
+Brande/M
+Brandea/M
+Brandeis
+Branden/M
+Brandenburg
+Brander/M
+Brandi/M
+Brandice/M
+Brandie/M
+Brandise/M
+Brando
+Brandon/M
+Brandt
+Brandtr/M
+Brandy/M
+Brandyn/M
+Brannon/M
+Brant/M
+Brantley/M
+Braque
+Brasilia/M
+Bratislava
+Brattain/M
+Bray/M
+Brazil/M
+Brazilian/MS
+Brazos/M
+Brazzaville/M
+Breanne/M
+Brear/M
+Breathalyzer
+Brecht
+Breckenridge/M
+Bree/M
+Breena/M
+Bremen
+Bren/M
+Brena/M
+Brenda/M
+Brendan/M
+Brenden/M
+Brendin/M
+Brendis/M
+Brendon/M
+Brenn/MNR
+Brenna/M
+Brennan/M
+Brennen/M
+Brenner/M
+Brent/M
+Brenton/M
+Bret/M
+Breton/M
+Brett/M
+Brew/MR
+Brewer/M
+Brewster
+Brezhnev
+Bria/M
+Brian/M
+Briana/M
+Brianna/M
+Brianne/M
+Briano/M
+Briant/M
+Brice/M
+Bridalveil/M
+Bride/M
+Bridgeport/M
+Bridger/M
+Bridges
+Bridget/M
+Bridgetown
+Bridgett/M
+Bridgette/M
+Bridgman
+Bridie/M
+Brie/RSM
+Brien/M
+Brier/M
+Brietta/M
+Brig
+Brigadoon
+Brigg/MS
+Brigham/M
+Bright
+Brighton/M
+Brigid/M
+Brigida/M
+Brigit/M
+Brigitta/M
+Brigitte/M
+Brillo
+Brina/M
+Briney/M
+Brinkley/M
+Brinn/M
+Brinna/M
+Briny/M
+Brion/M
+Brisbane/M
+Bristol/M
+Brit/SM
+Brita/M
+Britain/M
+Britannia
+Britannic
+Britannica/M
+Briticism/SM
+British/MRZ
+Britisher/M
+Britney/M
+Britni/M
+Briton/MS
+Britt/MN
+Britta/M
+Brittan/M
+Brittaney/M
+Brittani/M
+Brittany/SM
+Britte/M
+Britteny/M
+Brittne/M
+Brittney/M
+Brittni/M
+Brnaba/M
+Brnaby/M
+Brno
+Broadway/SM
+Brobdingnag/M
+Brobdingnagian
+Brock/M
+Brockie/M
+Brocky/M
+Brod/M
+Broddie/M
+Broddy/M
+Broderic/M
+Broderick/M
+Brodie/M
+Brody/M
+Brok/M
+Brokaw/M
+Bron/M
+Bronnie/M
+Bronny/M
+Bronson/M
+Bronte
+Bronx/M
+Brook/MS
+Brooke
+Brooklyn/M
+Bros
+Brose/M
+Brown/G
+Browne
+Brownian/M
+Brownie/S
+Brownshirt
+Brownsville
+Brubeck
+Bruce/M
+Brucie/M
+Bruckner
+Bruegel
+Bruis/M
+Brummel/M
+Brunei/M
+Bruneian/MS
+Brunelleschi
+Brunhilda/M
+Brunhilde/M
+Bruno
+Brunswick/M
+Brussels/M
+Brut/M
+Brutus/M
+Bryan
+Bryana/M
+Bryant
+Bryanty/M
+Bryce/M
+Bryn/M
+Bryna/M
+Brynn/MR
+Brynna/M
+Brynne/M
+Brynner/M
+Bryon/M
+Brzezinski/M
+Btu/M
+Buber
+Buchanan/M
+Bucharest/M
+Buchenwald
+Buchwald/M
+Buck
+Buckie/M
+Buckingham
+Buckley/M
+Buckner/M
+Bucky/M
+Bud/M
+Budapest/M
+Budd/M
+Buddha/SM
+Buddhism/SM
+Buddhist/SM
+Buddie/M
+Buddy/M
+Budweiser/M
+Buffalo/M
+Buffy/M
+Buford/M
+Bugatti/M
+Bugzilla/M
+Buick/M
+Buiron/M
+Bujumbura/M
+Bukhara
+Bukharin
+Bulawayo
+Bulfinch
+Bulganin
+Bulgar
+Bulgaria/M
+Bulgarian/SM
+Bullock/M
+Bullwinkle/M
+Bultmann/M
+Bumppo/M
+Bunche
+Bundestag
+Bunin
+Bunker/M
+Bunni/M
+Bunnie/M
+Bunny/M
+Bunsen
+Bunuel/M
+Bunyan/M
+Burbank
+Burch/M
+Burg/MR
+Burger/M
+Burgess
+Burgoyne/M
+Burgundian
+Burgundy/SM
+Burk/SM
+Burke
+Burl/M
+Burlie/M
+Burlington/M
+Burma/M
+Burmese/M
+Burnaby/M
+Burnard/M
+Burnett
+Burns
+Burnside
+Burr
+Burris/M
+Burroughs
+Bursa
+Burt/M
+Burtie/M
+Burton/M
+Burty/M
+Burundi/M
+Burundian/MS
+Busch/M
+Bush/M
+Bushido
+Bushnell/M
+Butch/M
+Butler
+Butterfingers/M
+Buxtehude
+Byblos/M
+Byers/M
+Byram/M
+Byran/M
+Byrann/M
+Byrd
+Byrle/M
+Byrom/M
+Byron
+Byronic
+Byzantine/MS
+Byzantium/M
+C/SMDY
+CA
+CAD/M
+CAI
+CAM
+CAP
+CARE
+CATV
+CB
+CBC/M
+CBS
+CCTV
+CCU
+CD/M
+CDC
+CDT
+CEO/M
+CF
+CFC/M
+CFO
+CIA/M
+CID
+CNN
+CNS/M
+CO/M
+COBOL/SM
+COD
+COL
+COLA
+CPA/M
+CPI/M
+CPO
+CPR/M
+CPU/M
+CRT/SM
+CST/M
+CT/M
+CV
+CZ
+Ca/M
+Cabernet/M
+Cabot
+Cabral
+Cabrera/M
+Cabrini
+Cacilia/M
+Cacilie/M
+Cad/M
+Caddric/M
+Cadette
+Cadillac
+Cadiz/M
+Caedmon/M
+Caerphilly
+Caesar/SM
+Cage
+Cagney/M
+Cahokia/M
+Cahra/M
+Caiaphas
+Cain/SM
+Cairistiona/M
+Cairo/M
+Caitlin/M
+Caitrin/M
+Cajun/MS
+Cal/Y
+Calais
+Calcutta/M
+Calder
+Calderon/M
+Caldwell
+Cale/M
+Caleb/M
+Caledonia
+Calgary/M
+Calhoun
+Cali
+Caliban
+Calida/M
+Calif
+California/M
+Californian/MS
+Caligula
+Calla/MS
+Callaghan
+Callahan/M
+Callao
+Callean/M
+Calley/M
+Calli/M
+Callida/M
+Callie/M
+Calliope/M
+Callisto/M
+Cally/M
+Caloocan/M
+Calv/M
+Calvary/M
+Calvert
+Calvin/M
+Calvinism/MS
+Calvinist/MS
+Calvinistic
+Calypso
+Cam
+Camacho/M
+Camala/M
+Cambodia/M
+Cambodian/SM
+Cambrian/SM
+Cambridge/M
+Camden/M
+Camel/M
+Camella/M
+Camellia/M
+Camelopardalis
+Camelot/MS
+Camembert/MS
+Cameron/M
+Cameroon/SM
+Cameroonian/SM
+Camey/M
+Cami/M
+Camila/M
+Camile/M
+Camilla/M
+Camille/M
+Camino/M
+Cammi/M
+Cammie/M
+Cammy/M
+Camoens/M
+Campbell
+Campinas
+Campos
+Camry/M
+Camus
+Can
+Canaan/M
+Canaanite/MS
+Canad
+Canada/M
+Canadian/SM
+Canadianism
+Canaletto
+Canaries/M
+Canaveral
+Canberra/M
+Cancer/SM
+Cancun/M
+Candace/M
+Candi/MS
+Candice/M
+Candida/M
+Candide/M
+Candie/M
+Candra/M
+Candy/M
+Cannes/M
+Cannon/M
+Canon/M
+Canopus
+Cantabrigian/M
+Canterbury
+Canton/M
+Cantonese/M
+Cantor/M
+Cantrell/M
+Cantu/M
+Canute
+Capek/M
+Capella/M
+Capet
+Capetian
+Capetown/M
+Caph/M
+Capistrano/M
+Capitol/SM
+Capitoline
+Capone
+Capote
+Capra/M
+Capri/M
+Caprice/M
+Capricorn/MS
+Capt
+Capulet/M
+Car/MNY
+Cara/M
+Caracalla
+Caracas/M
+Caralie/M
+Caravaggio
+Carboloy/M
+Carboniferous/M
+Carborundum
+Carce/M
+Cardenas/M
+Cardiff/M
+Cardin/M
+Cardozo/M
+Care/M
+Caren/M
+Carena/M
+Caresa/M
+Caressa/M
+Caresse/M
+Carey
+Cari/M
+Caria
+Carib/MS
+Caribbean/MS
+Carie/M
+Caril/M
+Carilyn/M
+Carin/M
+Carina
+Carine/M
+Cariotta/M
+Carissa/M
+Carita/M
+Caritta/M
+Carl/GMN
+Carla/M
+Carlee/M
+Carleen/M
+Carlen/M
+Carlene/M
+Carleton/M
+Carley/M
+Carlie/M
+Carlin/M
+Carlina/M
+Carline/M
+Carling/M
+Carlita/M
+Carlo/MS
+Carlota
+Carlotta/M
+Carlsbad
+Carlson/M
+Carlton
+Carly/M
+Carlye/M
+Carlyle
+Carlyn/M
+Carlynn/M
+Carlynne/M
+Carma/M
+Carmel
+Carmela/M
+Carmelia/M
+Carmelina/M
+Carmelita/M
+Carmella/M
+Carmelle/M
+Carmelo/M
+Carmen/M
+Carmencita/M
+Carmichael/M
+Carmina/M
+Carmine/M
+Carmita/M
+Carmon/M
+Carnap
+Carnation/M
+Carnegie/M
+Carney/M
+Carnot
+Carny/M
+Caro/M
+Carol/M
+Carola/M
+Carolan/M
+Carolann/M
+Carole/M
+Carolee/M
+Carolin/M
+Carolina
+Caroline
+Carolingian
+Carolinian/M
+Caroljean/M
+Carolus/M
+Carolyn/M
+Carolyne/M
+Carolynn/M
+Caron/M
+Carpathian/MS
+Carpenter
+Carr/M
+Carranza/M
+Carree/M
+Carri/MR
+Carrie/M
+Carrier/M
+Carrillo/M
+Carrissa/M
+Carrol/M
+Carroll/M
+Carry/M
+Carson
+Cart/MR
+Carter/M
+Cartesian
+Carthage/M
+Carthaginian/MS
+Cartier
+Cartwright
+Caruso
+Carver
+Cary
+Caryl/M
+Caryn/M
+Casablanca/M
+Casals
+Casandra/M
+Casanova/SM
+Casar/M
+Cascades/M
+Case/M
+Casey/M
+Cash
+Casi/M
+Casie/M
+Casio/M
+Caspar
+Casper/M
+Caspian
+Cass/M
+Cassandra/SM
+Cassandre/M
+Cassandry/M
+Cassatt
+Cassaundra/M
+Cassey/M
+Cassi/M
+Cassie/M
+Cassiopeia/M
+Cassius/M
+Cassondra/M
+Cassy/M
+Castaneda/M
+Castillo/M
+Castlereagh
+Castor/M
+Castries/M
+Castro
+Catalan/SM
+Catalina/M
+Catalonia/M
+Catarina/M
+Catawba/M
+Cate/M
+Caterina/M
+Caterpillar/M
+Catha/M
+Catharina/M
+Catharine/M
+Cathay/M
+Cathe/MR
+Cathee/M
+Catherin/M
+Catherina/M
+Catherine/M
+Cathi/M
+Cathie/M
+Cathleen/M
+Cathlene/M
+Catholic/MS
+Catholicism/SM
+Cathrin/M
+Cathrine/M
+Cathryn/M
+Cathy/M
+Cathyleen/M
+Cati/M
+Catie/M
+Catiline
+Catina/M
+Catlaina/M
+Catlee/M
+Catlin/M
+Cato
+Catrina/M
+Catriona/M
+Catskill/SM
+Catskills/M
+Catt
+Catullus
+Caty/M
+Caucasian/MS
+Caucasoid
+Caucasus/M
+Cauchy
+Cavendish
+Cavour
+Caxton
+Caye/M
+Cayenne
+Cayla/M
+Cayman/M
+Cayuga/SM
+Cayuse
+Caz/M
+Cazzie/M
+Cb
+Cchaddie/M
+Cd/M
+Ce/M
+Ceausescu/M
+Cebu/M
+Cebuano/M
+Cece/M
+Cecelia/M
+Cecil
+Cecile/M
+Ceciley/M
+Cecilia
+Cecilio/M
+Cecilius/M
+Cecilla/M
+Cecily/M
+Ced/M
+Cedric/M
+Ceil/M
+Cele/M
+Celene/M
+Celesta/M
+Celeste/M
+Celestia/M
+Celestina/M
+Celestine/M
+Celestyn/M
+Celestyna/M
+Celia/M
+Celie/M
+Celina/M
+Celinda/M
+Celine/M
+Celinka/M
+Celisse/M
+Celka/M
+Celle/M
+Cellini
+Cello/M
+Celsius
+Celt/SM
+Celtic/SM
+Cenozoic/M
+Centaurus/M
+Centigrade
+Central
+Cepheid
+Cepheus/M
+Cerberus/M
+Cerenkov
+Ceres/M
+Cerf/M
+Cervantes/M
+Cesar/M
+Cesare/M
+Cesarean
+Cesaro/M
+Cessna/M
+Cesya/M
+Cetus
+Ceylon/M
+Ceylonese
+Cezanne
+Cf/M
+Ch'in
+Ch/NRS
+Chablis/M
+Chad/M
+Chadd/M
+Chaddie/M
+Chaddy/M
+Chadian/MS
+Chadwick
+Chagall
+Chaim/M
+Chaitanya/M
+Chaitin/M
+Chaldea
+Chaldean
+Challenger/M
+Chalmers
+Chamberlain
+Chambers
+Champlain
+Champollion
+Chan/M
+Chance/M
+Chancellorsville/M
+Chancey/M
+Chanda/M
+Chandal/M
+Chandigarh
+Chandler
+Chandra/M
+Chandragupta
+Chandrasekhar/M
+Chane/M
+Chanel
+Chaney/M
+Chang/M
+Changchun
+Changsha
+Channa/M
+Chantal/M
+Chantalle/M
+Chantilly
+Chaplin
+Chapman
+Chappaquiddick/M
+Chapultepec/M
+Chara
+Charbray/M
+Chardonnay/M
+Charil/M
+Charin/M
+Chariot/M
+Charis
+Charissa/M
+Charisse/M
+Charita/M
+Charity/M
+Charla/M
+Charlean/M
+Charleen/M
+Charlemagne/M
+Charlena/M
+Charlene/M
+Charles/M
+Charleston/MS
+Charley
+Charlie
+Charline/M
+Charlot/M
+Charlotta/M
+Charlotte/M
+Charlottetown/M
+Charlton
+Charmain/M
+Charmaine/M
+Charmane/M
+Charmian/M
+Charmin/M
+Charmine/M
+Charmion/M
+Charo/M
+Charolais/M
+Charon/M
+Chartism/M
+Chartres
+Charybdis/M
+Charyl/M
+Chas
+Chase
+Chasity/M
+Chastity/M
+Chateaubriand/M
+Chattahoochee/M
+Chattanooga/M
+Chatterley/M
+Chatterton
+ChatZilla/M
+Chaucer/M
+Chaunce/M
+Chauncey/M
+Chautauqua
+Chavez/M
+Chayefsky/M
+Che/M
+Chechen
+Chechnya/M
+Cheddar
+Cheer/M
+Cheerios/M
+Cheetos/M
+Cheever
+Chekhov/M
+Chekhovian
+Chelsae/M
+Chelsea
+Chelsey/M
+Chelsie/M
+Chelsy/M
+Chelyabinsk/M
+Chen/M
+Cheney/M
+Chengdu
+Chennai/M
+Cheops
+Chere/M
+Cherey/M
+Cheri/M
+Cherianne/M
+Cherice/M
+Cherida/M
+Cherie/M
+Cherilyn/M
+Cherilynn/M
+Cherin/M
+Cherise/M
+Cherish/M
+Cherlyn/M
+Chernenko/M
+Chernobyl/M
+Chernomyrdin/M
+Cherokee/MS
+Cherri/M
+Cherrita/M
+Cherry/M
+Chery/M
+Cherye/M
+Cheryl/M
+Chesapeake
+Cheshire
+Cheslie/M
+Chester/M
+Chesterfield
+Chesterton
+Cheston/M
+Chet/M
+Chev/M
+Chevalier
+Cheviot/M
+Chevrolet/M
+Chevron/M
+Chevy/M
+Cheyenne/SM
+Chi/M
+Chianti/MS
+Chiarra/M
+Chiba
+Chibcha
+Chic/M
+Chicago/M
+Chicagoan
+Chicana
+Chicano
+Chick/M
+Chickasaw/MS
+Chickie/M
+Chicky/M
+Chiclets/M
+Chico/M
+Chihuahua/MS
+Chile/M
+Chilean/MS
+Chilton/M
+Chimborazo/M
+Chimera/MS
+Chimu/M
+Chin/M
+China/M
+Chinatown
+Chinese/M
+Chinook/MS
+Chip/M
+Chipewyan/M
+Chippendale/M
+Chippewa/SM
+Chiquia/M
+Chiquita/M
+Chirico
+Chisholm/M
+Chisinau/M
+Chittagong
+Chivas/M
+Chlo/M
+Chloe
+Chloette/M
+Chloris/M
+Choctaw/SM
+Chomsky
+Chongqing
+Chopin/M
+Chopra/M
+Chou
+Chretien/M
+Chris/M
+Chrisse/M
+Chrissie/M
+Chrissy/M
+Christ/MNS
+Christa/M
+Christabel/M
+Christabella/M
+Christal/M
+Christalle/M
+Christan/M
+Christchurch
+Christean/M
+Christel/M
+Christen/M
+Christendom/SM
+Christensen/M
+Christi/M
+Christian/SM
+Christiana/M
+Christiane/M
+Christianity/SM
+Christianize
+Christiano/M
+Christie
+Christin/M
+Christina
+Christine/M
+Christlike
+Christmas/MS
+Christmastide/MS
+Christmastime/MS
+Christoffer/M
+Christoforo/M
+Christoper/M
+Christoph/MR
+Christophe
+Christopher/M
+Christophorus/M
+Christos/M
+Christye/M
+Christyna/M
+Chrisy/M
+Chronicles
+Chrotoem/M
+Chrysa/M
+Chrysler/M
+Chrysostom
+Chrystal/M
+Chryste/M
+Chrystel/M
+Chucho/M
+Chuck/M
+Chukchi
+Chumash
+Chung/M
+Church
+Churchill/M
+Churriguera/M
+Chuvash/M
+Ci
+Cicely/M
+Cicero/M
+Cicily/M
+Cid
+Ciel/M
+Cilka/M
+Cimabue/M
+Cincinnati
+Cinda/M
+Cindee/M
+Cindelyn/M
+Cinderella/MS
+Cindi/M
+Cindie/M
+Cindra/M
+Cindy/M
+CinemaScope/M
+Cinerama
+Cinnamon/M
+Cipro/M
+Circe/M
+Cirillo/M
+Cirilo/M
+Ciro/M
+Cissiee/M
+Cissy/M
+Citibank/M
+Citroen/M
+Cl/MV
+Claiborn/M
+Claiborne/M
+Clair/M
+Claire/M
+Clairol/M
+Clancy/M
+Clapeyron/M
+Clapton/M
+Clara/M
+Clarabelle/M
+Clarance/M
+Clare
+Clarence/M
+Clarendon
+Claresta/M
+Clareta/M
+Claretta/M
+Clarette/M
+Clarey/M
+Clari/M
+Claribel/M
+Clarice/M
+Clarie/M
+Clarinda/M
+Clarine/M
+Clarissa/M
+Clarisse/M
+Clarita/M
+Clark
+Clarke/M
+Clary/M
+Claude/M
+Claudell/M
+Claudelle/M
+Claudetta/M
+Claudette/M
+Claudia/M
+Claudian/M
+Claudianus/M
+Claudie/M
+Claudina/M
+Claudine/M
+Claudio/M
+Claudius/M
+Claus/M
+Clausewitz
+Clausius
+Clay
+Clayborn/M
+Clayborne/M
+Claybourne/M
+Clayson/M
+Clayton/M
+Clea/M
+Clearasil/M
+Cleavland/M
+Clem/XM
+Clemence/M
+Clemenceau
+Clement/MS
+Clemente/M
+Clementia/M
+Clementina/M
+Clementine/M
+Clementius/M
+Clemmie/M
+Clemmy/M
+Clemons
+Clemson/M
+Cleo/M
+Cleon
+Cleopatra/M
+Clerc/M
+Clerissa/M
+Cletis
+Cletus/M
+Cleve/M
+Cleveland/M
+Clevey/M
+Clevie/M
+Cliburn/M
+Cliff/M
+Clifford
+Clifton/M
+Clim/M
+Cline/M
+Clint/M
+Clinton/M
+Clio/M
+Clo/M
+Cloe/M
+Clorets/M
+Cloris/M
+Clorox/M
+Clotho/M
+Clotilda/M
+Clouseau/M
+Clovis/M
+Cly/M
+Clyde
+Clydesdale/M
+Clytemnestra
+Clyve/M
+Clywd/M
+Cm/M
+Cmdr
+Co/SM
+Cob/M
+Cobain/M
+Cobb
+Cobbie/M
+Cobby/M
+Cochabamba
+Cochin
+Cochise
+Cochran/M
+Cockney/M
+Cocteau
+Cod
+Codee/M
+Codi/M
+Codie/M
+Cody
+Coffey/M
+Cognac/M
+Cohan
+Cohen
+Coimbatore
+Cointon/M
+Cointreau
+Coke/SM
+Col
+Colan/M
+Colas
+Colbert/M
+Colby
+Cole
+Coleen/M
+Coleman/M
+Colene/M
+Coleridge/M
+Colet
+Coletta/M
+Colette
+Colfax/M
+Colgate/M
+Colin/M
+Colleen/M
+Collen/M
+Collete/M
+Collette/M
+Collie/M
+Collier/M
+Collin/SM
+Colline/M
+Colly/RM
+Colman/M
+Colo
+Cologne/M
+Colombia/M
+Colombian/MS
+Colombo/M
+Colon/M
+Coloradan/SM
+Colorado/M
+Coloradoan
+Colosseum
+Colt/M
+Coltrane
+Columbia/M
+Columbine
+Columbus/M
+Colver/M
+Com
+Comanche/MS
+Combs/M
+Comdr
+Comintern
+Commons
+Commonwealth
+Communion/SM
+Communism
+Communist/SM
+Como
+Comoran
+Comoros/M
+Compaq/M
+Compton
+CompuServe/M
+Comte
+Con
+Conakry/M
+Conan/M
+Conant/M
+Concepcion
+Concetta/M
+Concettina/M
+Conchita/M
+Concord/SM
+Concorde
+Concordia/M
+Condillac
+Condorcet
+Conestoga/M
+Confederacy/M
+Confederate/MS
+Confucian/SM
+Confucianism/MS
+Confucius/M
+Cong
+Congo/M
+Congolese/M
+Congregational
+Congregationalist/MS
+Congress/MS
+Congressional
+Congreve
+Conley/M
+Conn/R
+Connecticut/M
+Connemara
+Conner/M
+Connery/M
+Conney/M
+Conni/M
+Connie/M
+Connolly/M
+Connor/SM
+Conny/M
+Conrad
+Conrade/M
+Conrado/M
+Conrail/M
+Conroy/M
+Consalve/M
+Conservative
+Consolata/M
+Constable
+Constance
+Constancia/M
+Constancy/M
+Constanta/M
+Constantia
+Constantin/M
+Constantina/M
+Constantine
+Constantino/M
+Constantinople/M
+Constitution
+Consuela/M
+Consuelo/M
+Continent/M
+Continental
+Contreras/M
+Conway
+Cook
+Cooke/M
+Cookie/M
+Cooley/M
+Coolidge/M
+Coop/MR
+Cooperstown/M
+Coors/M
+Copacabana/M
+Copeland/M
+Copenhagen/M
+Copernican
+Copernicus/M
+Copland
+Copley
+Copperfield/M
+Coppertone/M
+Coppola/M
+Coptic/M
+Cora/M
+Corabel/M
+Corabella/M
+Corabelle/M
+Coral/M
+Coralie/M
+Coraline/M
+Coralyn/M
+Corbet/M
+Corbett/M
+Corbie/M
+Corbin/M
+Corby
+Cord/M
+Cordelia/M
+Cordelie/M
+Cordell/M
+Cordey/M
+Cordi/M
+Cordie/M
+Cordilleras
+Cordoba/M
+Cordula/M
+Cordy/M
+Coreen/M
+Corella/M
+Corenda/M
+Corene/M
+Coretta/M
+Corette/M
+Corey/M
+Corfu
+Cori/M
+Corie/M
+Corilla/M
+Corina/M
+Corine/M
+Corinna/M
+Corinne/M
+Corinth/M
+Corinthian/SM
+Coriolanus
+Coriolis/M
+Coriss/M
+Corissa/M
+Cork
+Corleone/M
+Corliss/M
+Corly/M
+Cormack/M
+Cornall/M
+Corneille
+Cornela/M
+Cornelia/M
+Cornelius/M
+Cornell/M
+Cornelle/M
+Corney/M
+Cornie/M
+Corning/M
+Cornish/MS
+Cornwall/M
+Cornwallis
+Corny/M
+Coronado
+Corot
+Corp
+Correggio
+Correna/M
+Correy/M
+Corri/M
+Corrianne/M
+Corrie/M
+Corrina/M
+Corrine/M
+Corrinne/M
+Corry/M
+Corsica/M
+Corsican
+Cort/M
+Cortes/MS
+Cortie/M
+Cortland/M
+Cortney/M
+Corty/M
+Corvallis/M
+Corvette/M
+Corvus/M
+Cory/M
+Cosby/M
+Cosetta/M
+Cosette/M
+Cosimo/M
+Cosme/M
+Cosmo/M
+Cossack
+Costa/M
+Costanza/M
+Costco/M
+Costello/M
+Costner/M
+Cote/M
+Cotonou
+Cotopaxi/M
+Cotswold/M
+Cotton/M
+Coulomb
+Couperin
+Courbet
+Court/M
+Courtenay/M
+Courtnay/M
+Courtney/M
+Cousteau
+Coventry/SM
+Coward
+Cowley
+Cowper
+Cox
+Coy/M
+Cozmo/M
+Cozumel/M
+Cpl
+Cr/MT
+Crabbe
+Craft/M
+Craggie/M
+Craggy/M
+Craig
+Cranach
+Crane
+Cranmer
+Crater/M
+Crawford/M
+Cray/M
+Crayola/M
+Creation/M
+Creator/M
+Crecy/M
+Cree/DSM
+Creek/SM
+Creigh/M
+Creight/M
+Creighton/M
+Creole/SM
+Creon
+Crest/M
+Cretaceous/M
+Cretan/SM
+Crete/M
+Crichton
+Crick
+Crimea/M
+Crimean
+Crin/M
+Criollo
+Cris/M
+Crisco/M
+Crissie/M
+Crissy/M
+Crista/M
+Cristabel/M
+Cristal/M
+Cristen/M
+Cristi/M
+Cristian/M
+Cristiano/M
+Cristie/M
+Cristin/M
+Cristina/M
+Cristine/M
+Cristionna/M
+Cristobal/M
+Cristy/M
+Croat/SM
+Croatia/M
+Croatian/MS
+Croce
+Crockett
+Croesus
+Cromwell/M
+Cromwellian
+Cronin/M
+Cronkite/M
+Cronus/M
+Crookes
+Crosby
+Cross
+Crow/SM
+Crowley/M
+Crucifixion/MS
+Cruikshank
+Cruise/M
+Crusoe/M
+Crux/M
+Cruz/M
+Cryptozoic/M
+Crysta/M
+Crystal/M
+Crystie/M
+Csonka/M
+Ct
+Ctesiphon
+Cthrine/M
+Cu/M
+Cuba/M
+Cuban/SM
+Cuchulain/M
+Cuisinart
+Culbertson
+Cull/MN
+Cullan/M
+Cullen/M
+Culley/M
+Cullie/M
+Cullin/M
+Cully/M
+Culver/M
+Cumberland/M
+Cummings
+Cunard/M
+Cunningham/M
+Cupid/M
+Curacao/M
+Curcio/M
+Curie
+Curitiba
+Curr/M
+Curran/M
+Currey/M
+Currie/MR
+Currier/M
+Curry
+Curt/M
+Curtice/M
+Curtis/M
+Custer
+Cuvier/M
+Cuzco
+Cy
+Cyb/M
+Cybele/M
+Cybil/M
+Cybill/M
+Cyclades/M
+Cyclopes/M
+Cyclops/M
+Cygnus/M
+Cymbre/M
+Cynde/M
+Cyndi/M
+Cyndia/M
+Cyndie/M
+Cyndy/M
+Cynthea/M
+Cynthia/M
+Cynthie/M
+Cynthy/M
+Cyprian/M
+Cypriot/MS
+Cyprus/M
+Cyrano/M
+Cyril
+Cyrill/M
+Cyrille/M
+Cyrillic/M
+Cyrillus/M
+Cyrus
+Czech/M
+Czechoslovak
+Czechoslovakia/M
+Czechoslovakian/MS
+Czechs
+Czerny
+D'Arcy
+D/MN
+DA/M
+DAR
+DAT/M
+DBMS/M
+DC/M
+DD/M
+DDS/M
+DDT/S
+DE
+DEA
+DEC/SDG
+DH
+DI
+DJ
+DMD/M
+DMZ
+DNA/M
+DOA
+DOB
+DOD
+DOE
+DOS/M
+DOT
+DP/SM
+DPT
+DST
+DTP
+DUI
+DVD
+DWI
+Dacey/M
+Dachau/M
+Dacia
+Dacie/M
+Dacron/SM
+Dacy/M
+Dada/M
+Dadaism/M
+Daedalus/M
+Dael/M
+Daffi/M
+Daffie/M
+Daffy/M
+Dag/M
+Dagmar/M
+Dagny/M
+Daguerre
+Dagwood
+Dahlia/M
+Dahomey/M
+Daile/M
+Daimler/M
+Daisey/M
+Daisi/M
+Daisie/M
+Daisy
+Dakar/M
+Dakota/SM
+Dakotan
+Dal/M
+Dale
+Dalenna/M
+Daley/M
+Dali/S
+Dalia/M
+Dalian/M
+Dalila/M
+Dall/M
+Dallas/M
+Dalli/MS
+Dallon/M
+Dalmatia/M
+Dalmatian/SM
+Daloris/M
+Dalston/M
+Dalt/M
+Dalton/M
+Damara/M
+Damaris/M
+Damascus/M
+Dame/N
+Damian/M
+Damiano/M
+Damien
+Damion/M
+Damita/M
+Damocles
+Damon/M
+Dan
+Dana/M
+Danae
+Dane/SM
+Danelaw
+Danell/M
+Danella/M
+Danette/M
+Dangerfield/M
+Dani/M
+Dania/M
+Danial/M
+Danica/M
+Danice/M
+Danie/M
+Daniel/SM
+Daniela/M
+Daniele/M
+Daniella/M
+Danielle/M
+Danika/M
+Danila/M
+Danish/M
+Danit/M
+Danita/M
+Danna/M
+Dannel/M
+Danni/M
+Dannie/M
+Danny/M
+Dannye/M
+Dante/M
+Danton
+Danube/M
+Danubian
+Danya/M
+Danyelle/M
+Danyette/M
+Daphene/M
+Daphna/M
+Daphne/M
+Dar/MNH
+Dara/M
+Darb/M
+Darbee/M
+Darbie/M
+Darby/M
+Darcee/M
+Darcey/M
+Darci/M
+Darcie/M
+Darcy/M
+Darda/M
+Dardanelles/M
+Dare
+Dareen/M
+Darell/M
+Darelle/M
+Daren/M
+Dari/M
+Daria/M
+Darice/M
+Darill/M
+Darin/M
+Dario/M
+Darius
+Darjeeling
+Darla/M
+Darleen/M
+Darlene/M
+Darline/M
+Darling/M
+Darlleen/M
+Darn/M
+Darnall/M
+Darnell/M
+Daron/M
+Darrel/M
+Darrell/M
+Darrelle/M
+Darren/M
+Darrick/M
+Darrin/M
+Darrow
+Darryl/M
+Darsey/M
+Darsie/M
+Darth/M
+Dartmoor
+Dartmouth
+Darvon/M
+Darwin/M
+Darwinian
+Darwinism/SM
+Darwinist
+Darya/M
+Daryl/M
+Daryle/M
+Daryn/M
+Dasha/M
+Dasi/M
+Dasie/M
+Dasya/M
+Datamation/S
+Datha/M
+Daugherty/M
+Daumier
+Daune/M
+Dav/MN
+Davao
+Dave/M
+Daveen/M
+Daven/M
+Davenport
+Daveta/M
+Davey/M
+David/MS
+Davida/M
+Davidde/M
+Davide/M
+Davidson/M
+Davie/MS
+Davin/M
+Davina/M
+Davine/M
+Davis
+Davita/M
+Davon/M
+Davy
+Dawes
+Dawn/M
+Dawna/M
+Dawson
+Day
+Dayan
+Dayle/M
+Dayna/M
+Dayton
+Ddene/M
+De/RSMN
+DeGeneres/M
+Deadhead/M
+Dean
+Deana/M
+Deandre/M
+Deane/M
+Deann/M
+Deanna/M
+Deanne/M
+Deb/SM
+Debbi/M
+Debbie/M
+Debby/M
+Debee/M
+Debera/M
+Debi/M
+Debian/M
+Debor/M
+Debora/M
+Deborah
+Debouillet/M
+Debra/M
+Debussy
+Dec/M
+Decalogue/M
+Decatur
+Decca/M
+Deccan
+December/SM
+Deck/MR
+Dede/M
+Dedekind/M
+Dedie/M
+Dedra/M
+Dee
+Deeann/M
+Deeanne/M
+Deedee/M
+Deena/M
+Deerdre/M
+Deere/M
+Deeyn/M
+Defoe
+Degas
+Dehlia/M
+Deidre/M
+Deimos
+Deina/M
+Deirdre
+Deity
+Dejesus/M
+Del/Y
+Dela/M
+Delacroix
+Delacruz/M
+Delainey/M
+Delaney/M
+Delano/M
+Delaware/MS
+Delawarean/MS
+Delbert/M
+Delcina/M
+Delcine/M
+Deleon/M
+Delgado
+Delhi/M
+Delia/M
+Delibes
+Delicious/M
+Delila/M
+Delilah/M
+Delilahs
+Delinda/M
+Delius
+Dell/M
+Della/M
+Delly/M
+Delmar/M
+Delmarva/M
+Delmer/M
+Delmonico
+Delmor/M
+Delmore/M
+Delora/M
+Delores/M
+Deloria/M
+Deloris/M
+Delphi/M
+Delphic
+Delphine/M
+Delphinia/M
+Delphinus/M
+Delta
+Dem/G
+Demavend/M
+Demerol/M
+Demeter/M
+Demetra/M
+Demetre/M
+Demetri/SM
+Demetria/M
+Demetrius/M
+Deming/M
+Democrat/SM
+Democratic
+Democritus
+Demosthenes/M
+Demott/M
+Dempsey
+Dena/M
+Denali
+Dene
+Deneb
+Denebola/M
+Deng/M
+Deni/SM
+Denice/M
+Denise/M
+Denmark/M
+Denna/M
+Dennet/M
+Denney/M
+Denni/MS
+Dennie/M
+Dennison/M
+Denny/M
+Denver/M
+Deny/M
+Denys
+Denyse/M
+Deon/M
+Deonne/M
+Der/M
+Derby
+Derek/M
+Derick/M
+Derk/M
+Dermot/M
+Derrek/M
+Derrick/M
+Derrida/M
+Derrik/M
+Derril/M
+Derron/M
+Derry
+Derward/M
+Derwin/M
+Descartes/M
+Desdemona/M
+Desi/M
+Desirae/M
+Desiree/M
+Desiri/M
+Desmond/M
+Desmund/M
+Detroit/M
+Deuteronomy/M
+Dev/M
+Deva/M
+Devan/M
+Devanagari/M
+Devi/M
+Devin/M
+Devina/M
+Devinne/M
+Devland/M
+Devlen/M
+Devlin/M
+Devon/M
+Devondra/M
+Devonian/M
+Devonna/M
+Devonne/M
+Devora/M
+Devy/M
+Dew/M
+Dewain/M
+Dewar/M
+Dewayne/M
+Dewey/M
+Dewie/M
+Dewitt/M
+Dex/M
+Dexedrine/M
+Dexter
+Dhaka/M
+Dhaulagiri/M
+Di/S
+DiCaprio/M
+DiMaggio
+Diaghilev
+Diahann/M
+Dial/M
+Dian/M
+Diana/M
+Diandra/M
+Diane/M
+Dianemarie/M
+Diann/M
+Dianna/M
+Dianne/M
+Diannne/M
+Diarmid/M
+Dias
+Diaspora/MS
+Dick/X
+Dickensian
+Dickerson/M
+Dickie/M
+Dickinson
+Dickson/M
+Dicky/M
+Dictaphone/SM
+Diderot
+Didi/M
+Dido/M
+Didrikson/M
+Diefenbaker
+Diego/M
+Diem/M
+Diena/M
+Dierdre/M
+Dieter/M
+Dietrich
+Dijkstra/M
+Dijon
+Dilan/M
+Dilbert/MS
+Dill/M
+Dillard/M
+Dillie/M
+Dillinger/M
+Dillon/M
+Dilly/M
+Dimitri/M
+Dimitry/M
+Dina/M
+Dinah
+Dinnie/M
+Dinny/M
+Dino/M
+Diocletian
+Diogenes
+Dion/M
+Dione
+Dionis/M
+Dionisio/M
+Dionne/M
+Dionysian
+Dionysus/M
+Diophantine/M
+Dior
+Dipper/M
+Dir
+Dirac
+Dirichlet
+Dirk/M
+Dis/M
+Disney
+Disneyland
+Disraeli
+Dita/M
+Divine/M
+Diwali/M
+Dix
+Dixie/M
+Dixiecrat
+Dixieland/SM
+Dixon/M
+Djibouti/M
+Dmitri/M
+Dnepropetrovsk
+Dniester
+Dniren/M
+Dobbin/M
+Doberman/M
+Dobro
+Doctor
+Doctorow/M
+Dode/M
+Dodge/M
+Dodgson/M
+Dodi/M
+Dodie/M
+Dodoma/M
+Dodson/M
+Dody/M
+Doe
+Doha/M
+Dolby
+Dole/M
+Dolf/M
+Doll/M
+Dolley/M
+Dolli/M
+Dollie/M
+Dolly/M
+Dolores/M
+Dolorita/SM
+Dolph/M
+Dom
+Domenic/M
+Domenico/M
+Domeniga/M
+Domesday/M
+Dominga/M
+Domingo/M
+Dominguez/M
+Domini/M
+Dominic
+Dominica/M
+Dominican/MS
+Dominick/M
+Dominik/M
+Dominion
+Dominique/M
+Domitian
+Don/SM
+Dona
+Donahue/M
+Donal/M
+Donald/M
+Donaldson/M
+Donall/M
+Donalt/M
+Donatello
+Donaugh/M
+Donavon/M
+Donella/M
+Donelle/M
+Donetsk/M
+Donetta/M
+Donia/M
+Donica/M
+Donielle/M
+Donizetti/M
+Donn/MR
+Donna
+Donnamarie/M
+Donne/M
+Donnell/M
+Donner/M
+Donni/M
+Donnie/M
+Donny/M
+Donovan/M
+Dooley/M
+Doolittle
+Doonesbury/M
+Doppler
+Dora/M
+Doralia/M
+Doralin/M
+Doralyn/M
+Doralynn/M
+Doralynne/M
+Dorcas
+Dore/M
+Doreen/M
+Dorelia/M
+Dorella/M
+Dorelle/M
+Dorena/M
+Dorene/M
+Doretta/M
+Dorette/M
+Dorey/M
+Dori/SM
+Doria/M
+Dorian/M
+Doric/M
+Dorice/M
+Dorie/M
+Dorine/M
+Doris/M
+Dorisa/M
+Dorise/M
+Dorita/M
+Doritos/M
+Doro/M
+Dorolice/M
+Dorolisa/M
+Dorotea/M
+Doroteya/M
+Dorothea/M
+Dorothee/M
+Dorothy/M
+Dorree/M
+Dorri/SM
+Dorrie/M
+Dorry/M
+Dorset
+Dorsey/M
+Dorthea/M
+Dorthy/M
+Dortmund
+Dory/M
+Dosi/M
+Dostoevsky/M
+Dot/M
+Doti/M
+Dotson/M
+Dotti/M
+Dottie/M
+Dotty/M
+Douala/M
+Douay/M
+Doubleday/M
+Doug/M
+Dougie/M
+Douglas
+Douglass
+Dougy/M
+Douro
+Dov/MR
+Dover/M
+Dow
+Downs
+Downy/M
+Doy/M
+Doyle
+Dr
+Draco/M
+Draconian
+Dracula/M
+Drake
+Dramamine/SM
+Drambuie
+Drano/M
+Dravidian/M
+Dre/M
+Dreddy/M
+Dredi/M
+Dreiser
+Dresden/M
+Drew/M
+Dreyfus/M
+Dristan/M
+Drona/M
+Dru/M
+Druci/M
+Drucie/M
+Drucill/M
+Drucy/M
+Drud/M
+Drugi/M
+Drusi/M
+Drusie/M
+Drusilla/M
+Drusy/M
+Dryden
+Dshubba/M
+Du
+DuPont
+Duane/M
+Dubai
+Dubcek/M
+Dubhe/M
+Dublin/M
+Dubrovnik/M
+Duchamp
+Dud/M
+Dudley
+Duff/M
+Duffie/M
+Duffy/M
+Dugald/M
+Duisburg
+Duke/M
+Dukey/M
+Dukie/M
+Duky/M
+Dulce/M
+Dulcea/M
+Dulci/M
+Dulcia/M
+Dulciana/M
+Dulcie/M
+Dulcine/M
+Dulcinea/M
+Dulcy/M
+Dulles
+Dulsea/M
+Duluth
+Dumas
+Dumbo/M
+Dumpster
+Dun/M
+Dunant
+Dunbar
+Dunc/M
+Duncan
+Dundee
+Dunedin
+Dunkirk/M
+Dunlap/M
+Dunn/M
+Dunne/M
+Dunstan
+Dur/R
+Duracell/M
+Duran/M
+Durand/M
+Durant
+Durante/M
+Durban
+Durex/M
+Durham/MS
+Durkheim
+Duroc
+Durocher/M
+Durward/M
+Duse/M
+Dushanbe/M
+Dusseldorf/M
+Dustbuster/M
+Dustin/M
+Dusty/M
+Dutch/M
+Dutchman/M
+Dutchmen
+Dutchwoman
+Duvalier
+Dvina
+Dvorak
+Dwain/M
+Dwayne/M
+Dwight/M
+Dy/M
+Dyan/M
+Dyana/M
+Dyane/M
+Dyann/M
+Dyanna/M
+Dyanne/M
+Dyer/M
+Dylan/M
+Dyna/M
+Dynah/M
+Dyson/M
+Dzerzhinsky/M
+Dzungaria
+E/SMY
+EC
+ECG/M
+EDP/M
+EDT
+EEC/M
+EEG/M
+EEO
+EEOC
+EFL
+EFT
+EKG/M
+ELF/M
+EM
+EMT
+ENE/M
+EOE
+EPA/M
+ER
+ERA
+ESE/M
+ESL
+ESP/M
+ESPN
+EST/M
+ET
+ETA
+ETD
+EU
+Eachelle/M
+Eada/M
+Eadie/M
+Eadith/M
+Eadmund/M
+Eakins
+Eal/M
+Ealasaid/M
+Eamon/M
+Earhart
+Earl/M
+Earle/M
+Earlene/M
+Earlie/M
+Earline/M
+Early/M
+Earnest/M
+Earnestine/M
+Earnhardt/M
+Earp/M
+Eartha/M
+Earvin/M
+East/SZMR
+Easter/M
+Eastern/R
+Eastman
+Eastwood/M
+Eaton/M
+Eb/MN
+Eba/M
+Ebba/M
+Eben/M
+Ebeneezer/M
+Ebeneser/M
+Ebenezer/M
+Eberhard/M
+Ebert
+Eberto/M
+Ebola
+Ebonee/M
+Ebonics/M
+Ebony/M
+Ebro/M
+Ecclesiastes
+Eco/M
+Ecstasy
+Ecuador/M
+Ecuadoran/SM
+Ecuadorean
+Ecuadorian/MS
+Ed/MNX
+Eda/M
+Edam/SM
+Edan/M
+Edd/M
+Edda
+Eddi/M
+Eddie/M
+Eddington/M
+Eddy/M
+Ede
+Edee/M
+Edeline/M
+Eden/M
+Edgar
+Edgard/M
+Edgardo/M
+Edi/MH
+Edie/M
+Edik/M
+Edin/M
+Edinburgh/M
+Edison/M
+Edita/M
+Edith/M
+Editha/M
+Edithe/M
+Ediva/M
+Edlin/M
+Edmon/M
+Edmond/M
+Edmonton/M
+Edmund/M
+Edna/M
+Edouard/M
+Edsel
+Eduard/M
+Eduardo/M
+Eduino/M
+Edvard/M
+Edward/SM
+Edwardian/M
+Edwardo/M
+Edwin
+Edwina/M
+Edy/M
+Edyth/M
+Edythe/M
+Eeyore/M
+Effie/M
+Efrain/M
+Efrem/M
+Efren/M
+Egan/M
+Egbert
+Eggo/M
+Egon/M
+Egor/M
+Egypt/M
+Egyptian/MS
+Egyptology/M
+Ehrenberg/M
+Ehrlich
+Eichmann
+Eiffel
+Eileen/M
+Eilis/M
+Eimile/M
+Einstein/MS
+Eire/M
+Eirena/M
+Eisenhower/M
+Eisenstein
+Eisner/M
+Ekaterina/M
+El/Y
+Elaina/M
+Elaine
+Elam
+Elana/M
+Elane/M
+Elanor/M
+Elayne/M
+Elba
+Elbe/M
+Elbert
+Elberta/M
+Elbertina/M
+Elbertine/M
+Elbrus
+Elden/M
+Eldin/M
+Eldon/M
+Eldredge/M
+Eldridge/M
+Eleanor/M
+Eleanora/M
+Eleanore/M
+Eleazar/M
+Electra/M
+Eleen/M
+Elena/M
+Elene/M
+Eleni/M
+Elenore/M
+Eleonora/M
+Eleonore/M
+Elfie/M
+Elfreda/M
+Elfrida/M
+Elfrieda/M
+Elga/M
+Elgar
+Eli
+Elia/S
+Elianora/M
+Elianore/M
+Elicia/M
+Elie/M
+Elihu/M
+Elijah/M
+Elinor/M
+Elinore/M
+Eliot
+Elisa/M
+Elisabet/M
+Elisabeth
+Elisabetta/M
+Elise/M
+Eliseo/M
+Elisha
+Elissa/M
+Elita/M
+Eliza/M
+Elizabet/M
+Elizabeth/M
+Elizabethan/MS
+Elka/M
+Elke/M
+Ella/M
+Elladine/M
+Ellary/M
+Elle/M
+Ellen/M
+Ellene/M
+Ellerey/M
+Ellery/M
+Ellesmere/M
+Ellette/M
+Elli/SM
+Ellie/M
+Ellington
+Elliot/M
+Elliott/M
+Ellison/M
+Ellissa/M
+Ellswerth/M
+Ellsworth/M
+Ellwood/M
+Elly/M
+Ellyn/M
+Ellynn/M
+Elma/M
+Elmer/M
+Elmira/M
+Elmo/M
+Elmore/M
+Elna/MH
+Elnar/M
+Elnath/M
+Elnora/M
+Elnore/M
+Elohim
+Eloisa/M
+Eloise/M
+Elonore/M
+Elora/M
+Eloy/M
+Elroy/M
+Elsa/M
+Elsbeth/M
+Else/M
+Elset/M
+Elsey/M
+Elsi/M
+Elsie/M
+Elsinore
+Elspeth/M
+Elston/M
+Elsworth/M
+Elsy/M
+Eltanin/M
+Elton/M
+Elul/M
+Elva/M
+Elvera/M
+Elvia/M
+Elvin/M
+Elvina/M
+Elvira/M
+Elvis/M
+Elvyn/M
+Elwin/M
+Elwira/M
+Elwood/M
+Elwyn/M
+Elyn/M
+Elyse/M
+Elysee/M
+Elysha/M
+Elysia
+Elysian
+Elysium/SM
+Elyssa/M
+Em/M
+Ema/M
+Emacs/M
+Emalee/M
+Emalia/M
+Emanuel/M
+Emanuele/M
+Emelda/M
+Emelen/M
+Emelia/M
+Emelina/M
+Emeline/M
+Emelita/M
+Emelyne/M
+Emera/M
+Emerson
+Emery/M
+Emil/M
+Emile/M
+Emilee/M
+Emili/M
+Emilia/M
+Emilie/M
+Emiline/M
+Emilio/M
+Emily/M
+Eminence
+Emlen/M
+Emlyn/M
+Emlynn/M
+Emlynne/M
+Emma/M
+Emmalee/M
+Emmaline/M
+Emmalyn/M
+Emmalynn/M
+Emmalynne/M
+Emmanuel
+Emmeline/M
+Emmerich/M
+Emmery/M
+Emmet/M
+Emmett/M
+Emmey/M
+Emmi/M
+Emmie/M
+Emmit/M
+Emmott/M
+Emmy
+Emmye/M
+Emogene/M
+Emory/M
+Emyle/M
+Emylee/M
+Encarta/M
+Endymion
+Eng
+Engelbert/M
+Engels/M
+England/M
+Englebert/M
+English/MRS
+Englishman/M
+Englishmen
+Englishwoman/M
+Englishwomen
+Engracia/M
+Enid
+Enif/M
+Eniwetok/M
+Enkidu/M
+Ennis
+Enoch
+Enos
+Enrica/M
+Enrichetta/M
+Enrico/M
+Enrika/M
+Enrique/M
+Enriqueta/M
+Enron/M
+Enterprise/M
+Eocene/M
+Eolanda/M
+Eolande/M
+Epcot/M
+Ephesian/S
+Ephesus
+Ephraim
+Ephrayim/M
+Ephrem/M
+Epictetus
+Epicurean
+Epicurus/M
+Epimethius/M
+Epiphany/SM
+Episcopal
+Episcopalian/MS
+Epistle
+Epsom
+Epstein
+Equuleus
+Er/M
+Eran/M
+Erasmus/M
+Erastus/M
+Erato/M
+Eratosthenes/M
+Erda/M
+Erebus/M
+Erector
+Erek/M
+Erena/M
+Erhard
+Erhart/M
+Eric/M
+Erica/M
+Erich/M
+Ericha/M
+Erick/M
+Ericka/M
+Erickson/M
+Eridanus
+Erie
+Erik/M
+Erika/M
+Erin
+Erina/M
+Erinn/M
+Erinna/M
+Eris/MS
+Eritrea/M
+Eritrean/SM
+Erl/M
+Erlenmeyer/M
+Erma/M
+Ermanno/M
+Ermengarde/M
+Ermentrude/M
+Ermin/M
+Ermina/M
+Erminia/M
+Erminie/M
+Erna/M
+Ernaline/M
+Ernest/M
+Ernesta/M
+Ernestine/M
+Ernesto/M
+Ernestus/M
+Ernie/M
+Ernst
+Erny/M
+Eros/MS
+Errick/M
+Errol/M
+Erroll/M
+Erse/M
+Erskine
+Ertha/M
+Erv/M
+ErvIn/M
+Erwin/M
+Eryn/M
+Esau/M
+Escher/M
+Escherichia/M
+Escondido
+Esdras
+Eskimo/MS
+Esma/M
+Esmaria/M
+Esme/M
+Esmeralda/M
+Esperanto/M
+Esperanza/M
+Espinoza/M
+Esq/M
+Esquire/MS
+Esra/M
+Essa/M
+Essen/M
+Essene
+Essequibo
+Essex
+Essie/M
+Essy/M
+Esta/M
+Establishment
+Esteban/M
+Estel/M
+Estela/M
+Estele/M
+Estell/M
+Estella/M
+Estelle/M
+Ester/M
+Esterhazy/M
+Estes
+Estevan/M
+Esther/M
+Estonia/M
+Estonian/SM
+Estrada/M
+Estrella/M
+Estrellita/M
+Etan/M
+Ethan/M
+Ethe/M
+Ethel/M
+Ethelbert
+Ethelda/M
+Ethelin/M
+Ethelind/M
+Etheline/M
+Ethelred/M
+Ethelyn/M
+Ethernet
+Ethiopia/M
+Ethiopian/SM
+Ethyl/M
+Etienne/M
+Etna/M
+Eton
+Etruria
+Etruscan
+Etta/M
+Etti/M
+Ettie/M
+Ettore/M
+Etty/M
+Eu/M
+Eucharist/MS
+Eucharistic
+Euclid/M
+Eudora/M
+Euell/M
+Eugen/M
+Eugene
+Eugenia/M
+Eugenie/M
+Eugenio/M
+Eugenius/M
+Eugine/M
+Eula/M
+Eulalie/M
+Euler
+Eumenides/M
+Eunice/M
+Euphemia/M
+Euphrates/M
+Eur
+Eurasia/M
+Eurasian/MS
+Euripides
+Eurodollar/MS
+Europa/M
+Europe/M
+European/MS
+Eurydice/M
+Eustace/M
+Eustachian/M
+Eustacia/M
+Euterpe/M
+Ev/MN
+Eva/M
+Evaleen/M
+Evan/SM
+Evangelia/M
+Evangelical
+Evangelin/M
+Evangelina/M
+Evangeline/M
+Evangelist
+Evania/M
+Evanne/M
+Evansville
+Eve/M
+Eveleen/M
+Evelin/M
+Evelina/M
+Eveline/M
+Evelyn
+Even/M
+Evenki/M
+EverReady/M
+Everard/M
+Evered/M
+Everest/M
+Everett/M
+Everette/M
+Everglades/M
+Evert/M
+Evey/M
+Evian/M
+Evie/M
+Evin/M
+Evita/M
+Evonne/M
+Evvie/M
+Evvy/M
+Evy/M
+Evyn/M
+Ewan/M
+Eward/M
+Ewart/M
+Ewell/M
+Ewen/M
+Ewing/M
+Excalibur/M
+Excedrin/M
+Excellency/SM
+Exchequer
+Exercycle
+Exocet/M
+Exodus/M
+Exxon/M
+Eyck/M
+Eyde/M
+Eydie/M
+Eyre
+Eysenck/M
+Ezechiel/M
+Ezekiel
+Ezequiel/M
+Eziechiele/M
+Ezmeralda/M
+Ezra
+Ezri/M
+F/MD
+FAA
+FAQ/SM
+FBI/M
+FCC
+FD
+FDA
+FDIC/M
+FDR/M
+FHA/M
+FICA/M
+FIFO
+FL
+FM/SM
+FNMA/M
+FOFL
+FORTRAN/M
+FPO
+FSLIC
+FTC
+FUD/S
+FWD
+FY
+FYI
+Fabe/RM
+Faber/M
+Faberge
+Fabian/MS
+Fabiano/M
+Fabien/M
+Fabio/M
+Fae/M
+Faeroe/M
+Fafnir
+Fagin/M
+Fahd/M
+Fahrenheit
+Faina/M
+Fair/M
+Fairbanks
+Fairfax
+Fairleigh/M
+Fairlie/M
+Faisal/M
+Faisalabad
+Faith
+Falasha
+Falito/M
+Falkland/SM
+Falkner
+Fallon/M
+Fallopian/M
+Falstaff/M
+Falwell/M
+Fan
+Fanchette/M
+Fanchon/M
+Fancie/M
+Fancy/M
+Fanechka/M
+Fania/M
+Fanni/M
+Fannie/M
+Fanny/M
+Fanya/M
+Far/MY
+Fara/M
+Faraday/M
+Farah/M
+Farand/M
+Fargo/M
+Farica/M
+Farlay/M
+Farlee/M
+Farleigh/M
+Farley/M
+Farlie/M
+Farly/M
+Farmer
+Farr/M
+Farra/M
+Farragut
+Farrah/M
+Farrakhan/M
+Farrand/M
+Farrel/M
+Farrell/M
+Farris/M
+Farrow/M
+Farsi/M
+Fassbinder/M
+Fatah/M
+Fates
+Father/SM
+Fatima
+Fatimid
+Faulkner/M
+Faulknerian
+Faun/M
+Faunie/M
+Fauntleroy/M
+Faust/M
+Faustian
+Faustina/M
+Faustine/M
+Faustino/M
+Faustus/M
+Fawkes
+Fawn/M
+Fawne/M
+Fawnia/M
+Fax/M
+Fay/M
+Faydra/M
+Faye/M
+Fayette/M
+Fayina/M
+Fayre/M
+Fayth/M
+Faythe/M
+Fe/M
+Feb/M
+February/SM
+Fed/SM
+FedEx
+Federal/MS
+Federalist/M
+Federica/M
+Federico/M
+Fedora/M
+Fee/M
+Felecia/M
+Felic/M
+Felicdad/M
+Felice/M
+Felicia/M
+Felicio/M
+Felicity/M
+Felicle/M
+Felike/M
+Feliks/M
+Felipa/M
+Felipe/M
+Felisha/M
+Felita/M
+Felix/M
+Feliza/M
+Felizio/M
+Fellini
+Fenelia/M
+Fenian
+Feodor/M
+Feodora/M
+Ferber/M
+Ferd/M
+Ferdie/M
+Ferdinand
+Ferdinanda/M
+Ferdinande/M
+Ferdy/M
+Fergus
+Ferguson/M
+Ferlinghetti/M
+Fermat/M
+Fermi
+Fern/M
+Fernanda/M
+Fernande/M
+Fernandez/M
+Fernandina/M
+Fernando/M
+Ferne/M
+Ferrari/M
+Ferraro/M
+Ferrel/M
+Ferrell/M
+Ferris
+Fey/M
+Feynman/M
+Fez
+Fiann/M
+Fianna
+Fiat/M
+Fiberglas
+Fibonacci/M
+Fichte
+Fidel/M
+Fidela/M
+Fidelia/M
+Fidelio/M
+Fidelity/M
+Fido/M
+Fidole/M
+Field/GS
+Fifi/M
+Fifine/M
+Figaro/M
+Figueroa/M
+Fiji/M
+Fijian/MS
+Filbert/M
+Filberte/M
+Filberto/M
+Filia/M
+Filide/M
+Filip/M
+Filipino/MS
+Filippa/M
+Filippo/M
+Fillmore/M
+Filmer/M
+Filmore/M
+Filofax
+Fin
+Fina/M
+Finch/M
+Findlay/M
+Findley/M
+Finland/M
+Finlay/M
+Finley/M
+Finn/SM
+Finnbogadottir/M
+Finnegan/M
+Finnish/M
+Fiona/M
+Fionna/M
+Fionnula/M
+Fiorenze/M
+Firefox/M
+Firestone/M
+Fischer
+Fisher
+Fisk/M
+Fitch/M
+Fitz/M
+Fitzgerald
+Fitzpatrick/M
+Fitzroy/M
+Fizeau/M
+Fla
+Flanagan/M
+Flanders/M
+Flathead
+Flatt/M
+Flaubert
+Fleischer/M
+Flem/G
+Flemish/M
+Flemming/M
+Fletch/MR
+Fleur/M
+Fleurette/M
+Flin/M
+Flinn/M
+Flint
+Flintstones
+Flo/M
+Flor/M
+Flora
+Florance/M
+Flore/SM
+Florella/M
+Florence/M
+Florencia/M
+Florentia/M
+Florentine
+Florenza/M
+Florette/M
+Flori/SM
+Floria/M
+Florian/M
+Florida/M
+Floridan
+Floridian/SM
+Florie/M
+Florina/M
+Florinda/M
+Florine/M
+Florri/M
+Florrie/M
+Florry/M
+Florsheim/M
+Flory/M
+Flossi/M
+Flossie/M
+Flossy/M
+Flowers
+Floyd
+Flss/M
+Flynn/M
+Fm/M
+Foch
+Fokker
+Foley
+Folgers
+Folsom
+Fomalhaut
+Fonda
+Fons
+Fonsie/M
+Fonz/M
+Fonzie/M
+Foosball/M
+Forbes
+Ford/M
+Foreman/M
+Forest/MR
+Formica/MS
+Formosa/M
+Formosan/M
+Forrest/R
+Forrester/M
+Forster
+Fortaleza
+Foss/M
+Foster
+Fotomat/M
+Foucault
+Fourier
+Fourneyron/M
+Fourth
+Fowler
+Fox/MS
+Fr/MD
+Fragonard
+Fran/SM
+France/SM
+Francene/M
+Francesca
+Francesco/M
+Franchot/M
+Francine/M
+Francis
+Francisca/M
+Franciscan/SM
+Francisco/M
+Franciska/M
+Franciskus/M
+Franck
+Francklin/M
+Francklyn/M
+Franco
+Francois/M
+Francoise/M
+Francyne/M
+Franglais
+Frank/SM
+Frankel/M
+Frankenstein
+Frankfort/M
+Frankfurt/MR
+Frankie/M
+Frankish
+Franklin
+Franklyn/M
+Franky/M
+Franni/M
+Frannie/M
+Franny/M
+Fransisco/M
+Frants/M
+Franz/MN
+Franzen/M
+Frasco/M
+Fraser
+Frasier/M
+Frasquito/M
+Frau/MN
+Fraulein
+Frayda/M
+Fraze/RM
+Frazier/M
+Fred/M
+Freda/M
+Freddi/M
+Freddie/M
+Freddy/M
+Fredek/M
+Fredelia/M
+Frederic/M
+Frederica/M
+Frederich/M
+Frederick
+Fredericka/M
+Frederico/M
+Fredericton/M
+Frederigo/M
+Frederik/M
+Frederique/M
+Fredi/M
+Fredia/M
+Fredra/M
+Fredric/M
+Fredrick/M
+Fredrika/M
+Free/M
+Freedman/M
+Freeland/M
+Freeman/M
+Freemason/SM
+Freemasonry/SM
+Freemon/M
+Freetown/M
+Freida/M
+Fremont
+French/MS
+Frenchman/M
+Frenchmen
+Frenchwoman/M
+Frenchwomen
+Freon
+Fresnel/M
+Fresno/M
+Freud/M
+Freudian
+Frey/M
+Freya/M
+Fri/M
+Friday/SM
+Frieda/M
+Friedan
+Friederike/M
+Friedman
+Friedrich
+Friedrick/M
+Friend/SM
+Frigga/M
+Frigidaire
+Frisbee
+Frisco
+Frisian/MS
+Frito/M
+Fritz/M
+Frobisher
+Froissart
+Fromm
+Fronde
+Frontenac/M
+Frost/M
+Frostbelt
+Frunze/M
+Fry
+Frye/M
+Fuchs/M
+Fuentes
+Fugger
+Fuji/M
+Fujitsu/M
+Fujiwara/M
+Fujiyama/M
+Fukuoka/M
+Fulani/M
+Fulbright
+Fuller
+Fullerton
+Fulton/M
+Fulvia/M
+Funafuti
+Fundy
+Furies/M
+Furtwangler/M
+Fushun
+Fuzhou/M
+Fuzzbuster
+G/MNRB
+GA
+GAO
+GATT/M
+GB/M
+GDP/M
+GE/M
+GED
+GHQ/M
+GI
+GIGO
+GM
+GMAT
+GMT/M
+GNP/M
+GOP/M
+GP/M
+GPA
+GPO
+GSA
+GTE/M
+GU
+GUI/M
+Ga/M
+Gabbey/M
+Gabbi/M
+Gabbie/M
+Gabby/M
+Gabe/M
+Gabey/M
+Gabi/M
+Gabie/M
+Gabon/M
+Gabonese/M
+Gaborone/M
+Gabriel
+Gabriela/M
+Gabriele/M
+Gabriell/M
+Gabriella/M
+Gabrielle/M
+Gabriellia/M
+Gabriello/M
+Gabrila/M
+Gaby/M
+Gacrux/M
+Gadsden/M
+Gae/M
+Gaea/M
+Gael/SM
+Gaelan/M
+Gaelic/M
+Gagarin
+Gage
+Gail/M
+Gaile/M
+Gaines/M
+Gainsborough/M
+Gal/N
+Galahad/SM
+Galapagos/M
+Galatea
+Galatia
+Galatians
+Galaxy
+Galbraith
+Gale/M
+Galibi
+Galilean/SM
+Galilee
+Galileo/M
+Galina/M
+Gall/M
+Gallagher/M
+Gallard/M
+Gallegos/M
+Gallic
+Gallicism/SM
+Gallo/M
+Galloway/M
+Gallup
+Galois/M
+Galsworthy
+Galvan/M
+Galvani
+Galven/M
+Galveston/M
+Galvin/M
+Gama
+Gamaliel/M
+Gamay
+Gambia/M
+Gambian/SM
+Gamble/M
+Gamow/M
+Gan/M
+Gandhi/M
+Gandhian
+Ganesha/M
+Ganges/M
+Gangtok/M
+Gannie/M
+Gannon/M
+Ganny/M
+Gantry/M
+Ganymede/M
+Gap/M
+Gar/MH
+Garald/M
+Garbo
+Garcia/M
+Gard
+Gardener/M
+Gardie/M
+Gardiner
+Gardner/M
+Gardy/M
+Gare/MH
+Garek/M
+Gareth/M
+Garey/M
+Garfield/M
+Garfunkel/M
+Gargantua
+Garibaldi/M
+Garik/M
+Garland
+Garner
+Garnet/M
+Garnette/M
+Garold/M
+Garrard/M
+Garrek/M
+Garret/M
+Garreth/M
+Garrett/M
+Garrick
+Garrik/M
+Garrison
+Garrot/M
+Garrott/M
+Garry/M
+Garth/M
+Garv/M
+Garvey
+Garvin/M
+Garvy/M
+Garwin/M
+Garwood/M
+Gary
+Garza/M
+Gascony/M
+Gaspar
+Gaspard/M
+Gasparo/M
+Gasper/M
+Gasser
+Gaston/M
+Gates
+Gatling/M
+Gatorade/M
+Gatsby/M
+Gatun/M
+Gauguin/M
+Gaul/SM
+Gaulish
+Gaultiero/M
+Gauss/M
+Gaussian
+Gautama/M
+Gauthier/M
+Gautier
+Gav/MN
+Gavan/M
+Gaven/M
+Gavin/M
+Gavra/M
+Gavrielle/M
+Gawain/M
+Gawen/M
+Gay
+Gaye/M
+Gayel/M
+Gayelord/M
+Gayla/M
+Gayle/RM
+Gayleen/M
+Gaylene/M
+Gayler/M
+Gaylor/M
+Gaylord/M
+Gaynor/M
+Gaza
+Gaziantep
+Gd/M
+Gdansk/M
+Ge/M
+Gearalt/M
+Gearard/M
+Geffen/M
+Gehenna/M
+Gehrig
+Geiger/M
+Gelbvieh/M
+Geller/M
+Gelya/M
+Gemini/MS
+Gena/M
+Genaro/M
+Gene/M
+Genesis/M
+Genet/M
+Geneva/M
+Genevieve/M
+Genevra/M
+Genghis/M
+Genia/M
+Genna/M
+Genni/M
+Gennie/M
+Gennifer/M
+Genny/M
+Geno/M
+Genoa/SM
+Genovera/M
+Gentoo
+Gentry/M
+Genvieve/M
+Geo/M
+Geoff/M
+Geoffrey/M
+Geoffry/M
+Georas/M
+Geordie
+Georg/M
+George/MS
+Georgeanna/M
+Georgeanne/M
+Georgena/M
+Georgeta/M
+Georgetown/M
+Georgetta/M
+Georgette
+Georgi/M
+Georgia/M
+Georgian/MS
+Georgiana/M
+Georgianna/M
+Georgianne/M
+Georgie/M
+Georgina/M
+Georgine/M
+Georgy/M
+Gerald/M
+Geralda/M
+Geraldine/M
+Gerard/M
+Gerardo/M
+Gerber/M
+Gerda/M
+Gerek/M
+Gerhard/M
+Gerhardine/M
+Gerhardt/M
+Geri/M
+Gerianna/M
+Gerianne/M
+Gerick/M
+Gerik/M
+Geritol/M
+Gerladina/M
+Germain/M
+Germaine/M
+German/MS
+Germana/M
+Germanic/M
+Germany/M
+Germayne/M
+Gerome/M
+Geronimo
+Gerrard/M
+Gerri/M
+Gerrie/M
+Gerrilee/M
+Gerry/M
+Gershwin
+Gert/M
+Gerta/M
+Gerti/M
+Gertie/M
+Gertrud/M
+Gertruda/M
+Gertrude/M
+Gertrudis/M
+Gerty/M
+Gery/M
+Gestapo/SM
+Gethsemane
+Getty
+Gettysburg/M
+Gewurztraminer
+Ghana/M
+Ghanaian
+Ghats
+Ghazvanid/M
+Ghent
+Gherardo/M
+Ghibelline
+Giacinta/M
+Giacobo/M
+Giacometti
+Giacomo/M
+Giacopo/M
+Gian/M
+Giana/M
+Gianina/M
+Gianna/M
+Gianni/M
+Giannini/M
+Giauque/M
+Giavani/M
+Gib/M
+Gibb/SM
+Gibbie/M
+Gibbon
+Gibby/M
+Gibraltar/MS
+Gibson
+Gide
+Gideon
+Gielgud
+Gienah/M
+Giff/MR
+Giffard/M
+Giffer/M
+Giffie/M
+Gifford/M
+Giffy/M
+Gigi/M
+Gil/MY
+Gila/M
+Gilbert/M
+Gilberta/M
+Gilberte/M
+Gilbertina/M
+Gilbertine
+Gilberto/M
+Gilburt/M
+Gilchrist/M
+Gilda/M
+Gilead
+Gilemette/M
+Giles
+Gilgamesh
+Gill
+Gillan/M
+Gilles
+Gillespie
+Gillette/M
+Gilli/M
+Gilliam/M
+Gillian/M
+Gillie/M
+Gilligan/M
+Gilly/M
+Gilmore/M
+Gina/M
+Ginelle/M
+Ginevra/M
+Ginger/M
+Gingrich/M
+Ginni/M
+Ginnie/M
+Ginnifer/M
+Ginny/M
+Gino/M
+Ginsberg
+Ginsburg/M
+Ginsu/M
+Giordano/M
+Giorgi/M
+Giorgia/M
+Giorgio/M
+Giorgione
+Giotto
+Giovanna/M
+Giovanni/M
+Giralda/M
+Giraldo/M
+Giraud
+Giraudoux
+Gisela/M
+Giselbert/M
+Gisele/M
+Gisella/M
+Giselle/M
+Gish
+Giuditta/M
+Giulia/M
+Giuliani/M
+Giulietta/M
+Giulio/M
+Giuseppe/M
+Giustina/M
+Giustino/M
+Giusto/M
+Giza/M
+Gizela/M
+Gk
+Glad/M
+Gladi/M
+Gladstone/MS
+Gladys
+Glaser
+Glasgow/M
+Glass/M
+Glastonbury/M
+Glaswegian/SM
+Glaxo/M
+Gleason/M
+Gleda/M
+Glen/M
+Glenda/M
+Glendale
+Glenden/M
+Glendon/M
+Glenine/M
+Glenlivet/M
+Glenn/M
+Glenna/M
+Glennie/M
+Glennis/M
+Glori/M
+Gloria
+Gloriana/M
+Gloriane/M
+Glory/M
+Gloucester
+Glover/M
+Glyn/M
+Glynda/M
+Glynis/M
+Glynn/M
+Glynnis/M
+Gnni/M
+Gnostic
+Gnosticism/M
+Goa
+Gobi/M
+God/M
+Godard
+Godart/M
+Goddard
+Goddart/M
+Godel/M
+Godfree/M
+Godfrey/M
+Godfry/M
+Godhead/M
+Godiva/M
+Godot/M
+Godspeed/SM
+Godthaab
+Godunov
+Godwin
+Godzilla/M
+Goebbels
+Goering
+Goethals/M
+Goethe/M
+Goff/M
+Gog
+Gogol
+Goiania/M
+Golan/M
+Golconda
+Golda/M
+Goldarina/M
+Goldberg/M
+Golden/M
+Goldi/M
+Goldia/M
+Goldie/M
+Goldilocks/M
+Goldina/M
+Golding
+Goldman/M
+Goldsmith
+Goldwater/M
+Goldwyn
+Goldy/M
+Golgi
+Golgotha/M
+Goliath
+Gomez/M
+Gomorrah/M
+Gompers
+Gomulka
+Gondwanaland/M
+Gonzales
+Gonzalez/M
+Gonzalo/M
+Goober/M
+Good/M
+Goodall/M
+Goodman
+Goodrich/M
+Goodwill/M
+Goodwin/M
+Goodyear
+Google/M
+Gopher
+Goran/M
+Goraud/M
+Gorbachev
+Gordan/M
+Gorden/M
+Gordian/M
+Gordie/M
+Gordimer
+Gordon
+Gordy/M
+Gore
+Goren/M
+Gorey/M
+Gorgas
+Gorgon/M
+Gorgonzola
+Gorky/M
+Gospel/MS
+Goteborg/M
+Goth/M
+Gotham
+Gothart/M
+Gothic/MS
+Goths
+Gottfried/M
+Gouda/SM
+Gould
+Gounod
+Governor
+Goya
+Gr
+Gracchus
+Grace
+Graceland/M
+Gracia/M
+Gracie/M
+Graciela/M
+Gradeigh/M
+Gradey/M
+Grady/M
+Graehme/M
+Graeme/M
+Graffias/M
+Grafton/M
+Graham
+Grahame
+Graig/M
+Grail
+Gram/M
+Grammy
+Grampians
+Gran/M
+Granada/M
+Grange/R
+Grannie/M
+Granny/M
+Grant/M
+Grantham/M
+Granthem/M
+Grantley/M
+Granville/M
+Grass
+Grata/M
+Gratia/M
+Gratiana/M
+Graves
+Gray
+Grayce/M
+Grazia/M
+Grecian
+Greece/M
+Greek/SM
+Greeley
+Green/SM
+Greene
+Greenland/M
+Greenlandic
+Greenpeace/M
+Greensboro/M
+Greensleeves/M
+Greenspan/M
+Greenwich/M
+Greer/M
+Greg/M
+Gregg/M
+Greggory/M
+Gregoire/M
+Gregoor/M
+Gregor/M
+Gregorian
+Gregorio/M
+Gregorius/M
+Gregory/M
+Grenada/M
+Grenadian/MS
+Grenadines
+Grendel
+Grenoble
+Grenville
+Gresham
+Greta/M
+Gretal/M
+Gretchen/M
+Grete/M
+Gretel/M
+Grethel/M
+Gretna/M
+Gretta/M
+Gretzky/M
+Grey
+Grieg
+Grier/M
+Griff/M
+Griffie/M
+Griffin/M
+Griffith
+Griffy/M
+Grimes
+Grimm/M
+Grinch/M
+Gris
+Griselda
+Grissel/M
+Griswold/M
+Griz/M
+Gromyko
+Gropius/M
+Gross
+Grosz
+Grotius
+Grove/RM
+Grover/M
+Grozny
+Grumman/M
+Grundy
+Grunewald/M
+Grus/M
+Gruyere/SM
+Guadalajara/M
+Guadalcanal/M
+Guadalquivir
+Guadalupe/M
+Guadeloupe/M
+Guallatiri/M
+Gualterio/M
+Guam/M
+Guamanian
+Guangzhou/M
+Guantanamo/M
+Guarani/M
+Guarnieri/M
+Guatemala/M
+Guatemalan/SM
+Guayaquil/M
+Gucci/M
+Guelph
+Guendolen/M
+Guenevere/M
+Guenna/M
+Guernsey/MS
+Guerra/M
+Guerrero
+Guevara
+Guggenheim
+Guglielma/M
+Guglielmo/M
+Gui/M
+Guiana/M
+Guido/M
+Guilbert/M
+Guillaume/M
+Guillema/M
+Guillemette/M
+Guillermo/M
+Guinea/M
+Guinean/MS
+Guinevere/M
+Guinna/M
+Guinness/M
+Guiyang
+Guizot
+Gujarat/M
+Gujarati/M
+Gujranwala
+Gullah
+Gulliver/M
+Gumbel/M
+Gun/M
+Gunar/M
+Gunilla/M
+Gunner/M
+Guntar/M
+Gunter
+Gunther
+Guofeng/M
+Gupta/M
+Gurkha/M
+Gus/M
+Gusella/M
+Guss
+Gussi/M
+Gussie/M
+Gussy/M
+Gusta/M
+Gustaf/M
+Gustav/M
+Gustave/M
+Gustavo/M
+Gustavus/M
+Gusti/M
+Gustie/M
+Gusty/M
+Gutenberg
+Guthrey/M
+Guthrie
+Guthry/M
+Gutierrez/M
+Guy/M
+Guyana/M
+Guyanese/M
+Guzman/M
+Gwalior
+Gwen/M
+Gwendolen/M
+Gwendolin/M
+Gwendoline/M
+Gwendolyn/M
+Gweneth/M
+Gwenette/M
+Gwenneth/M
+Gwenni/M
+Gwennie/M
+Gwenny/M
+Gwenora/M
+Gwenore/M
+Gwyn/M
+Gwyneth/M
+Gwynne/M
+Gypsy/SM
+H/M
+HBO
+HDTV
+HF/M
+HHS
+HI
+HIV/M
+HM
+HMO/M
+HMS
+HOV
+HP/M
+HQ/M
+HR
+HRH
+HS
+HST
+HT
+HTML/M
+HTTP
+HTTPS
+HUD/M
+Ha
+Haas/M
+Habakkuk
+Haber/M
+Had/M
+Hadar/M
+Hades/M
+Hadlee/M
+Hadleigh/M
+Hadley/M
+Hadria/M
+Hadrian
+Hafiz/M
+Hagan/M
+Hagar
+Hagen
+Haggai
+Hagiographa/M
+Hague
+Hahn
+Haida/SM
+Haifa/M
+Hailee/M
+Hailey/M
+Haily/M
+Haiphong
+Haiti/M
+Haitian/MS
+Hakeem/M
+Hakim/M
+Hakka/M
+Hakluyt
+Hal/SMY
+Haldane
+Hale
+Haleakala
+Haleigh/M
+Halette/M
+Haley/M
+Hali/M
+Halie/M
+Halifax/M
+Halimeda/M
+Hall
+Halley
+Halli/M
+Hallie/M
+Hallmark/M
+Halloween/MS
+Hallstatt
+Hallsy/M
+Hally/M
+Halon/M
+Halsey
+Halsy/M
+Ham/M
+Haman/M
+Hamburg/MS
+Hamel/M
+Hamhung
+Hamid/M
+Hamil/M
+Hamilcar/M
+Hamill/M
+Hamilton/M
+Hamiltonian
+Hamish/M
+Hamitic/M
+Hamlen/M
+Hamlet
+Hamlin/M
+Hammad/M
+Hammarskjold
+Hammerstein
+Hammett/M
+Hammond
+Hammurabi
+Hamnet/M
+Hampshire/M
+Hampton
+Hamsun
+Han/S
+Hana/M
+Hanan/M
+Hancock
+Handel/M
+Handy
+Haney/M
+Hangul/M
+Hangzhou/M
+Hank/M
+Hanna/M
+Hannah/M
+Hanni/SM
+Hannibal/M
+Hannie/M
+Hanny/M
+Hanoi/M
+Hanover/M
+Hanoverian/M
+Hansel/M
+Hansen/M
+Hansiain/M
+Hanson/M
+Hanuka
+Hanukkah/M
+Hanukkahs
+Happy/M
+Hapsburg/M
+Harald/M
+Harare/M
+Harbert/M
+Harbin
+Harcourt/M
+Hardin/M
+Harding/M
+Hardy
+Hargreaves
+Harlan/M
+Harland/M
+Harlem/M
+Harlen/M
+Harlene/M
+Harlequin
+Harley
+Harli/M
+Harlie/M
+Harlin/M
+Harlow
+Harman/M
+Harmon/M
+Harmonia/M
+Harmonie/M
+Harmony/M
+Harold/M
+Haroun/M
+Harp/MR
+Harper/M
+Harpy/SM
+Harrell/M
+Harri/SM
+Harrie/M
+Harriet/M
+Harriett/M
+Harrietta/M
+Harriette/M
+Harrington/M
+Harriot/M
+Harriott/M
+Harrisburg/M
+Harrison/M
+Harrods
+Harry/M
+Hart
+Harte
+Hartford/M
+Hartley
+Hartline/M
+Hartman/M
+Hartwell/M
+Harv/M
+Harvard/M
+Harvey
+Harwell/M
+Harwilll/M
+Hasbro/M
+Hasheem/M
+Hashim/M
+Hasidim
+Haskel/M
+Haskell/M
+Haslett/M
+Hastie/M
+Hastings/M
+Hasty/M
+Hatfield
+Hathaway
+Hatsheput/M
+Hatteras
+Hatti/M
+Hattie/M
+Hatty/M
+Hauptmann
+Hausa/M
+Hausdorff/M
+Havana/MS
+Havarti
+Havel
+Haven/M
+Havoline/M
+Haw
+Hawaii/M
+Hawaiian/SM
+Hawking
+Hawkins
+Hawks
+Hawthorne
+Hay/SM
+Hayden/M
+Haydn/M
+Haydon/M
+Hayes/M
+Hayley/M
+Haynes
+Hayward
+Haywood/M
+Hayyim/M
+Haze/M
+Hazel/M
+Hazlett/M
+Hazlitt
+He/M
+Head/M
+Heall/M
+Hearst
+Heath/R
+Heather/M
+Heaviside
+Heb
+Hebe
+Hebert/M
+Hebraic
+Hebraism/SM
+Hebrew/MS
+Hebrides/M
+Hecate
+Hector/M
+Hecuba
+Heda/M
+Hedda/M
+Heddi/M
+Heddie/M
+Hedi/M
+Hedvig/M
+Hedvige/M
+Hedwig/M
+Hedwiga/M
+Hedy/M
+Heep/M
+Hefner/M
+Hegel/M
+Hegelian
+Hegira
+Heida/M
+Heidegger
+Heidelberg
+Heidi/M
+Heidie/M
+Heifetz
+Heimlich/M
+Heindrick/M
+Heine
+Heineken/M
+Heinlein/M
+Heinrich/M
+Heinrick/M
+Heinrik/M
+Heinz
+Heisenberg
+Heisman/M
+Helaina/M
+Helaine/M
+Helen/M
+Helena/M
+Helene/M
+Helenka/M
+Helga/M
+Helge/M
+Helicon
+Heliopolis
+Helios/M
+Hellene/SM
+Hellenic/M
+Hellenism/MS
+Hellenist
+Hellenistic
+Hellenization
+Hellenize
+Heller
+Hellespont/M
+Helli/M
+Hellman
+Helmholtz/M
+Heloise/M
+Helsa/M
+Helsinki/M
+Helvetian
+Helvetius/M
+Helyn/M
+Hemingway/M
+Hench/M
+Henderson/M
+Hendrick/MS
+Hendrik/M
+Hendrika/M
+Hendrix
+Henka/M
+Henley
+Henri/M
+Henrie/M
+Henrieta/M
+Henrietta/M
+Henriette/M
+Henrik/M
+Henry/M
+Henryetta/M
+Hensley/M
+Henson/M
+Hepburn
+Hephaestus/M
+Hephzibah/M
+Hepplewhite
+Hera/M
+Heracles/M
+Heraclitus
+Herakles/M
+Herb/M
+Herbart
+Herbert
+Herbie/M
+Herby/M
+Herc/M
+Herculaneum/M
+Hercule/MS
+Herculean
+Hercules/M
+Herculie/M
+Herder
+Hereford/SM
+Herero
+Heriberto/M
+Herman/M
+Hermann/M
+Hermaphroditus
+Hermes/M
+Hermia/M
+Hermie/M
+Hermina/M
+Hermine/M
+Herminia/M
+Hermione/M
+Hermitage
+Hermite/M
+Hermon
+Hermosillo/M
+Hermy/M
+Hernandez/M
+Hernando/M
+Herod/M
+Herodotus/M
+Herold/M
+Herr/MG
+Herrera/M
+Herrick
+Herring/M
+Hersch/M
+Herschel
+Hersey/M
+Hersh/M
+Hershel/M
+Hershey/M
+Herta/M
+Hertha/M
+Hertz/M
+Hertzsprung/M
+Herve/M
+Hervey/M
+Herzegovina
+Herzl
+Heshvan/M
+Hesiod
+Hesperus
+Hess
+Hesse
+Hessian
+Hester/M
+Hesther/M
+Hestia/M
+Heston/M
+Hetti/M
+Hettie/M
+Hetty/M
+Hew/M
+Hewe/M
+Hewet/M
+Hewett/M
+Hewie/M
+Hewitt/M
+Hewlett/M
+Heyerdahl
+Heywood
+Hezbollah/M
+Hezekiah
+Hf/M
+Hg/M
+Hi/M
+Hialeah
+Hiawatha/M
+Hibernia/M
+Hibernian
+Hickman/M
+Hickok
+Hicks/M
+Hieronymus
+Higashiosaka
+Higgins/M
+Highlander/MS
+Highlands
+Highness/M
+Hilario/M
+Hilarius/M
+Hilary/M
+Hilbert
+Hilda/M
+Hildagard/M
+Hildagarde/M
+Hilde/M
+Hildebrand
+Hildegaard/M
+Hildegarde/M
+Hildy/M
+Hilfiger/M
+Hill
+Hillard/M
+Hillary
+Hillel
+Hillery/M
+Hilliard
+Hilliary/M
+Hillie/M
+Hillier/M
+Hilly/RM
+Hillyer/M
+Hilton
+Himalaya/SM
+Himalayan
+Himmler
+Hinayana/M
+Hinda/M
+Hindemith
+Hindenburg
+Hindi
+Hindu/SM
+Hinduism/SM
+Hindustan/M
+Hindustani/SM
+Hines
+Hinton/M
+Hinze/M
+Hipparchus
+Hippocrates/M
+Hippocratic
+Hiram
+Hirobumi/M
+Hirohito
+Hiroshima/M
+Hirsch/M
+Hispanic/SM
+Hispaniola/M
+Hiss/M
+Hitachi/M
+Hitchcock
+Hitler/MS
+Hittite/SM
+Hmong
+Ho/M
+Hobard/M
+Hobart/M
+Hobbes
+Hobbs
+Hobey/M
+Hobie/M
+Hockney/M
+Hodge/SM
+Hodgkin
+Hoebart/M
+Hoff/M
+Hoffa/M
+Hoffman/M
+Hofstadter/M
+Hogan/M
+Hogarth
+Hogwarts/M
+Hohenlohe
+Hohenstaufen
+Hohenzollern/M
+Hohhot/M
+Hohokam
+Hokkaido/M
+Hokusai
+Holbein
+Holcomb/M
+Holden/M
+Holder/M
+Holiday
+Holiness
+Holland/ZSMR
+Hollander/M
+Hollerith/M
+Holley/M
+Holli/SM
+Hollie/M
+Holloway/M
+Holly
+Hollyanne/M
+Hollywood/M
+Holman/M
+Holmes/M
+Holocaust
+Holocene/M
+Holst
+Holstein/SM
+Holt
+Homer/M
+Homere/M
+Homeric
+Homerus/M
+Hon
+Honda/M
+Honduran/MS
+Honduras/M
+Honecker/M
+Honey/M
+Honeywell/M
+Honiara
+Honolulu/M
+Honor/B
+Honoria/M
+Honshu/M
+Hood
+Hooke/R
+Hooper/M
+Hoosier/MS
+Hooters/M
+Hoover/MS
+Hope
+Hopewell/M
+Hopi/SM
+Hopkins
+Hopper
+Horace
+Horacio/M
+Horatia/M
+Horatio/M
+Horatius/M
+Hormel/M
+Hormuz
+Horn
+Hornblower/M
+Horne/M
+Horowitz
+Horst/M
+Hort/MN
+Horten/M
+Hortense
+Hortensia/M
+Horthy
+Horton/M
+Horus/M
+Hosea/M
+Host/SM
+Hotpoint/M
+Hottentot/SM
+Houdini
+House
+Housman
+Houston/M
+Houyhnhnm/M
+Howard
+Howe
+Howell/MS
+Howey/M
+Howie/M
+Howrah
+Hoyle
+Hoyt/M
+Hrothgar/M
+Hts
+Huang
+Hubbard
+Hubble/M
+Hube/RM
+Huber/M
+Hubert/M
+Huberto/M
+Hubey/M
+Hubie/M
+Huck/M
+Huddersfield
+Hudson/M
+Huerta/M
+Huey/M
+Huff/M
+Huffman/M
+Huggins
+Hugh/MS
+Hughie
+Hugibert/M
+Hugo/M
+Huguenot/MS
+Hugues/M
+Hui
+Huitzilopitchli/M
+Hulda/M
+Hull/M
+Humbert/M
+Humberto/M
+Humboldt
+Hume
+Humfrey/M
+Humfrid/M
+Humfried/M
+Humphrey
+Humvee
+Hun/SM
+Hunfredo/M
+Hung
+Hungarian/SM
+Hungary/M
+Hunspell/M
+Hunt/R
+Hunter/M
+Huntington/M
+Huntlee/M
+Huntley/M
+Huntsville
+Hurlee/M
+Hurleigh/M
+Hurley/M
+Huron
+Hurst/M
+Hus
+Husein/M
+Hussein
+Husserl
+Hussite
+Huston
+Hutchinson
+Hutton/M
+Hutu
+Huxley/M
+Huygens
+Hy/M
+Hyacinth/M
+Hyacintha/M
+Hyacinthe/M
+Hyacinthia/M
+Hyacinthie/M
+Hyades/M
+Hyatt/M
+Hyde
+Hyderabad
+Hydra/M
+Hyman/M
+Hymen/M
+Hymie
+Hynda/M
+Hyperion/M
+Hyundai/M
+Hz/M
+I'd
+I'll
+I'm
+I've
+I/M
+IA
+IBM/M
+ICBM/SM
+ICC
+ICU
+ID/SM
+IE
+IL
+IMF/M
+IMHO
+IMNSHO
+IMO
+IN
+INRI
+INS
+IOU/M
+IPA
+IQ/M
+IRA/SM
+IRS/M
+ISBN
+ISO
+IT
+IUD
+IV/SM
+Ia
+Iaccoca/M
+Iago/M
+Iain/M
+Ian/M
+Ianthe/M
+Iapetus/M
+Ibadan
+Ibbie/M
+Ibby/M
+Iberia/M
+Iberian
+Ibiza
+Iblis/M
+Ibo
+Ibrahim/M
+Ibsen/M
+Icahn/M
+Icarus/M
+Ice
+Iceland/MRZ
+Icelander/M
+Icelandic/M
+Ichabod/M
+Ida
+Idaho/SM
+Idahoan/MS
+Idahoes
+Idalia/M
+Idalina/M
+Idaline/M
+Idell/M
+Idelle/M
+Idette/M
+Ieyasu
+Iggie/M
+Iggy/M
+Ignace/M
+Ignacio/M
+Ignacius/M
+Ignatius
+Ignaz/M
+Ignazio/M
+Igor/M
+Iguassu/M
+Ijsselmeer/M
+Ike/M
+Ikey/M
+Ikhnaton
+Ila
+Ilaire/M
+Ilario/M
+Ileana/M
+Ileane/M
+Ilene/M
+Iliad/SM
+Ilise/M
+Ilka/M
+Ill
+Illa/M
+Illinois/M
+Illinoisan/MS
+Illuminati
+Ilsa/M
+Ilse/M
+Ilysa/M
+Ilyse/M
+Ilyssa/M
+Ilyushin/M
+Imelda/M
+Immanuel
+Imodium/M
+Imogen/M
+Imogene/M
+Imojean/M
+Imus/M
+In/MP
+Ina/M
+Inc
+Inca/SM
+Inchon/M
+Incorporated
+Ind
+Independence/M
+India/M
+Indian/MS
+Indiana/M
+Indianan/SM
+Indianapolis/M
+Indianian
+Indira/M
+Indochina/M
+Indochinese
+Indonesia/M
+Indonesian/MS
+Indore
+Indra/M
+Indus/M
+Indy/SM
+Ines
+Inesita/M
+Inessa/M
+Inez/M
+Inga/M
+Ingaberg/M
+Ingaborg/M
+Ingamar/M
+Ingar/M
+Inge/R
+Ingeberg/M
+Ingeborg/M
+Ingelbert/M
+Ingemar/M
+Inger/M
+Inglebert/M
+Inglewood
+Inglis/M
+Ingmar/M
+Ingra/M
+Ingram/M
+Ingres
+Ingrid/M
+Ingrim/M
+Ingunna/M
+Inigo/M
+Inna/M
+Inness/M
+Innis/M
+Innocent/M
+Innsbruck
+Inonu/M
+Inquisition
+Inst
+Instamatic/M
+Intel/M
+Intelsat
+Internationale/M
+Internet/S
+Interpol
+Inuit/MS
+Inuktitut/M
+Invar/M
+Io/M
+Iolande/M
+Iolanthe/M
+Iona
+Ionesco
+Ionian/MS
+Ionic/SM
+Iorgo/MS
+Iormina/M
+Iosep/M
+Iowa/SM
+Iowan/MS
+Iphigenia
+Ipswich
+Iqaluit/M
+Iqbal
+Iquitos
+Ir/M
+Ira/M
+Iran/M
+Iranian/SM
+Iraq/M
+Iraqi/MS
+Ireland/M
+Irena/M
+Irene
+Irina/M
+Iris
+Irish/MR
+Irishman/M
+Irishmen
+Irishwoman/M
+Irishwomen
+Irita/M
+Irkutsk
+Irma/M
+Iroquoian/SM
+Iroquois/M
+Irrawaddy
+Irtish/M
+Irv/MG
+Irvin/M
+Irvine
+Irwin/M
+Irwinn/M
+Isa
+Isaac/M
+Isaak/M
+Isabel/M
+Isabelita/M
+Isabella
+Isabelle/M
+Isac/M
+Isacco/M
+Isador/M
+Isadora/M
+Isadore/M
+Isahella/M
+Isaiah
+Isak/M
+Iscariot
+Iseabal/M
+Isfahan
+Isherwood
+Ishim/M
+Ishmael
+Ishtar/M
+Isiah/M
+Isiahi/M
+Isidor/M
+Isidora/M
+Isidore/M
+Isidoro/M
+Isidro/M
+Isis/M
+Islam/MS
+Islamabad/M
+Islamic
+Ismael/M
+Ismail/M
+Isobel/M
+Isolde
+Ispell/M
+Israel/SM
+Israeli/SM
+Israelite
+Issac/M
+Issachar
+Issi/M
+Issiah/M
+Issie/M
+Issy/M
+Istanbul/M
+Isuzu/M
+It
+Itaipu/M
+Ital
+Italian/SM
+Italianate
+Italy/M
+Itasca/M
+Itch/M
+Ithaca
+Ithacan
+Ito
+Iva/M
+Ivan
+Ivanhoe/M
+Ivar/M
+Ive/RSM
+Iver/M
+Ivett/M
+Ivette/M
+Ivie/M
+Ivonne/M
+Ivor/M
+Ivorian
+Ivory/M
+Ivy
+Iyar/M
+Izaak/M
+Izabel/M
+Izak/M
+Izanagi/M
+Izanami/M
+Izhevsk
+Izmir
+Izod/M
+Izvestia/M
+Izzy/M
+J/MDNX
+JCS
+JD
+JFK/M
+JP
+JV
+Jabez/M
+Jacenta/M
+Jacinda/M
+Jacinta/M
+Jacintha/M
+Jacinthe/M
+Jack
+Jackelyn/M
+Jacki/M
+Jackie/M
+Jacklin/M
+Jacklyn/M
+Jackquelin/M
+Jackqueline/M
+Jackson/M
+Jacksonian
+Jacksonville/M
+Jacky/M
+Jaclin/M
+Jaclyn/M
+Jacob/SM
+Jacobean/M
+Jacobi
+Jacobin/M
+Jacobite/M
+Jacobo/M
+Jacobson/M
+Jacquard
+Jacquelin/M
+Jacqueline/M
+Jacquelyn/M
+Jacquelynn/M
+Jacquenetta/M
+Jacquenette/M
+Jacques
+Jacquetta/M
+Jacquette/M
+Jacqui/M
+Jacquie/M
+Jacuzzi
+Jacynth/M
+Jada/M
+Jade/M
+Jae/M
+Jagger/M
+Jagiellon/M
+Jaguar/M
+Jahangir/M
+Jaime/M
+Jaimie/M
+Jain
+Jaine/M
+Jainism/M
+Jaipur
+Jakarta/M
+Jake/M
+Jakie/M
+Jakob/M
+Jamaal/M
+Jamaica/M
+Jamaican/SM
+Jamal/M
+Jamar/M
+Jame/SM
+Jamel/M
+James
+Jameson
+Jamestown
+Jamesy/M
+Jamey/M
+Jami/M
+Jamie/M
+Jamil/M
+Jamill/M
+Jamima/M
+Jamison/M
+Jammal/M
+Jammie/M
+Jan/M
+Jana/M
+Janacek/M
+Janaya/M
+Janaye/M
+Jandy/M
+Jane/M
+Janean/M
+Janeczka/M
+Janeen/M
+Janek/M
+Janel/M
+Janela/M
+Janell/M
+Janella/M
+Janelle/M
+Janene/M
+Janenna/M
+Janessa/M
+Janet/M
+Janeta/M
+Janetta/M
+Janette/M
+Janeva/M
+Janey/M
+Jania/M
+Janice/M
+Janie/M
+Janifer/M
+Janina
+Janine/M
+Janis/M
+Janissary/M
+Janith/M
+Janka/M
+Janna/M
+Jannel/M
+Jannelle/M
+Jannie/M
+Janos/M
+Janot/M
+Jansen/M
+Jansenist/M
+January/SM
+Janus/M
+Jany/M
+Japan/M
+Japanese/MS
+Japura/M
+Jaquelin/M
+Jaquelyn/M
+Jaquenetta/M
+Jaquenette/M
+Jaquith/M
+Jarad/M
+Jard/M
+Jareb/M
+Jared/M
+Jarib/M
+Jarid/M
+Jarlsberg
+Jarrad/M
+Jarred/M
+Jarret/M
+Jarrett/M
+Jarrid/M
+Jarrod/M
+Jarvis/M
+Jase/M
+Jasen/M
+Jasmin/M
+Jasmina/M
+Jasmine/M
+Jason/M
+Jasper/M
+Jasun/M
+Jataka
+Java/SM
+JavaScript/M
+Javanese/M
+Javier/M
+Jaxartes
+Jay
+Jayapura/M
+Jayawardene/M
+Jaycee/S
+Jaye/M
+Jayme/M
+Jaymee/M
+Jaymie/M
+Jayne/M
+Jaynell/M
+Jayson/M
+Jazmin/M
+Jdavie/M
+Jean/M
+Jeana/M
+Jeane/M
+Jeanelle/M
+Jeanette/M
+Jeanie/M
+Jeanine/M
+Jeanna/M
+Jeanne/M
+Jeannette/M
+Jeannie/M
+Jeannine/M
+Jecho/M
+Jed/M
+Jedd/M
+Jeddy/M
+Jedediah/M
+Jedi/M
+Jedidiah/M
+Jeep
+Jeeves/M
+Jeff/M
+Jefferey/M
+Jefferson/M
+Jeffersonian
+Jeffery/M
+Jeffie/M
+Jeffrey
+Jeffry/M
+Jeffy/M
+Jehanna/M
+Jehoshaphat
+Jehovah/M
+Jehu
+Jekyll/M
+Jelene/M
+Jemie/M
+Jemima/M
+Jemimah/M
+Jemmie/M
+Jemmy/M
+Jen/M
+Jena/M
+Jenda/M
+Jenelle/M
+Jeni/M
+Jenica/M
+Jeniece/M
+Jenifer/M
+Jeniffer/M
+Jenilee/M
+Jenine/M
+Jenkins
+Jenn/MRJ
+Jenna/M
+Jennee/M
+Jennette/M
+Jenni/M
+Jennica/M
+Jennie/M
+Jennifer/M
+Jennilee/M
+Jennine/M
+Jennings/M
+Jenny/M
+Jeno/M
+Jensen/M
+Jephthah
+Jerad/M
+Jerald/M
+Jeralee/M
+Jeramey/M
+Jeramie/M
+Jere/M
+Jereme/M
+Jeremiah/M
+Jeremiahs
+Jeremias/M
+Jeremie/M
+Jeremy/M
+Jeri/M
+Jericho/M
+Jermain/M
+Jermaine/M
+Jermayne/M
+Jeroboam
+Jerold/M
+Jerome
+Jeromy/M
+Jerri/M
+Jerrie/M
+Jerrilee/M
+Jerrilyn/M
+Jerrine/M
+Jerrod/M
+Jerrold/M
+Jerrome/M
+Jerry/M
+Jerrylee/M
+Jersey/MS
+Jerusalem/M
+Jervis/M
+Jess/M
+Jessa/M
+Jessalin/M
+Jessalyn/M
+Jessamine/M
+Jessamyn/M
+Jesse
+Jessee/M
+Jesselyn/M
+Jessey/M
+Jessi/M
+Jessica/M
+Jessie/M
+Jessika/M
+Jessy/M
+Jesuit/MS
+Jesus
+Jeth/M
+Jethro
+Jetway
+Jew/SM
+Jewel/M
+Jewell/M
+Jewelle/M
+Jewess/MS
+Jewish/P
+Jewry
+Jezebel/SM
+Jidda
+Jilin
+Jill
+Jillana/M
+Jillane/M
+Jillayne/M
+Jilleen/M
+Jillene/M
+Jilli/M
+Jillian/M
+Jillie/M
+Jilly/M
+Jim/M
+Jimenez/M
+Jimmie/M
+Jimmy/M
+Jinan
+Jinnah
+Jinny/M
+Jivaro
+Jo/MY
+Joachim
+Joan
+Joana/M
+Joane/M
+Joanie/M
+Joann/M
+Joanna/M
+Joanne/SM
+Joaquin/M
+Job/SM
+Jobey/M
+Jobi/M
+Jobie/M
+Jobina/M
+Joby/M
+Jobye/M
+Jobyna/M
+Jocasta
+Jocelin/M
+Joceline/M
+Jocelyn/M
+Jocelyne/M
+Jock
+Jockey
+Jocko/M
+Jodee/M
+Jodi/M
+Jodie/M
+Jody/M
+Joe
+Joeann/M
+Joel/Y
+Joela/M
+Joelie/M
+Joell/MN
+Joella/M
+Joelle/M
+Joellen/M
+Joelly/M
+Joellyn/M
+Joelynn/M
+Joesph/M
+Joete/M
+Joey/M
+Jogjakarta/M
+Johan/M
+Johann/M
+Johanna/M
+Johannah/M
+Johannes
+Johannesburg/M
+John/SM
+Johna/MH
+Johnath/M
+Johnathan/M
+Johnathon/M
+Johnette/M
+Johnie/M
+Johnna/M
+Johnnie
+Johnny/M
+Johnson/M
+Johnston/M
+Johny/M
+Joice/M
+Jojo/M
+Jolee/M
+Joleen/M
+Jolene/M
+Joletta/M
+Joli/M
+Jolie/M
+Joline/M
+Jolson
+Joly/M
+Jolyn/M
+Jolynn/M
+Jon/M
+Jonah/M
+Jonahs
+Jonas
+Jonathan/M
+Jonathon/M
+Jone/SM
+Jonell/M
+Joni/SM
+Jonie/M
+Jonson
+Joplin
+Jordain/M
+Jordan/M
+Jordana/M
+Jordanian/MS
+Jordanna/M
+Jordon/M
+Jorey/M
+Jorgan/M
+Jorge/M
+Jori/M
+Jorie/M
+Jorrie/M
+Jorry/M
+Jory/M
+Joscelin/M
+Jose/M
+Josee/M
+Josef/M
+Josefa/M
+Josefina/M
+Joseito/M
+Joseph/M
+Josepha/M
+Josephina/M
+Josephine
+Josephs
+Josephson/M
+Josephus
+Josey/M
+Josh
+Joshia/M
+Joshua/M
+Joshuah/M
+Josi/M
+Josiah
+Josias/M
+Josie/M
+Josselyn/M
+Josue/M
+Josy/M
+Joule
+Jourdain/M
+Jourdan/M
+Jove/M
+Jovian
+Joy/M
+Joya/M
+Joyan/M
+Joyann/M
+Joyce
+Joycean
+Joycelin/M
+Joye/M
+Joyner/M
+Jozef/M
+Jpn
+Jr/M
+Jsandye/M
+Juan/M
+Juana/M
+Juanita/M
+Juarez/M
+Jubal
+Jud
+Judah
+Judaic
+Judaical
+Judaism/MS
+Judas/MS
+Judd/M
+Jude
+Judea
+Judges
+Judi/MH
+Judie/M
+Judith/M
+Juditha/M
+Judon/M
+Judson/M
+Judy
+Judye/M
+Juggernaut/M
+Juieta/M
+Jul
+Jule/SM
+Julee/M
+Juli/M
+Julia/M
+Julian
+Juliana
+Juliane/M
+Juliann/M
+Julianna/M
+Julianne/M
+Julie/M
+Julienne/M
+Juliet
+Julieta/M
+Julietta/M
+Juliette/M
+Julina/M
+Juline/M
+Julio/M
+Julissa/M
+Julita/M
+Julius/M
+Julliard/M
+July/SM
+Jun
+June/SM
+Juneau/M
+Junette/M
+Jung/M
+Jungfrau
+Jungian
+Junia/M
+Junie/M
+Junina/M
+Junior/SM
+Junker/SM
+Juno/M
+Jupiter/M
+Jurassic/M
+Jurua/M
+Justen/M
+Justice/M
+Justin/M
+Justina/M
+Justine/M
+Justinian/M
+Justinn/M
+Justino/M
+Justis/M
+Justus/M
+Jutland/M
+Juvenal
+Jyoti/M
+K/SMNRGJ
+KB/M
+KC
+KGB
+KIA
+KKK/M
+KO/M
+KP
+KS
+KY
+Kaaba
+Kabul/M
+Kacey/M
+Kacie/M
+Kacy/M
+Kaela/M
+Kafka/M
+Kafkaesque
+Kagoshima
+Kahaleel/M
+Kahlil/M
+Kahlua/M
+Kai/M
+Kaia/M
+Kaifeng
+Kaila/M
+Kaile/M
+Kailey/M
+Kain/M
+Kaine/M
+Kaiser/MS
+Kaitlin/M
+Kaitlyn/M
+Kaitlynn/M
+Kaja/M
+Kakalina/M
+Kala/M
+Kalahari/M
+Kalamazoo
+Kalashnikov
+Kalb/M
+Kale/M
+Kaleb/M
+Kaleena/M
+Kalevala
+Kalgoorlie
+Kali/M
+Kalie/M
+Kalil/M
+Kalila/M
+Kalina/M
+Kalinda/M
+Kalindi/M
+Kalle/M
+Kalli/M
+Kally/M
+Kalmyk
+Kalvin/M
+Kama/M
+Kamchatka
+Kamehameha/M
+Kameko/M
+Kamila/M
+Kamilah/M
+Kamillah/M
+Kampala/M
+Kampuchea/M
+Kan/S
+Kanchenjunga/M
+Kandace/M
+Kandahar
+Kandinsky
+Kandy
+Kane/M
+Kania/M
+Kannada/M
+Kano
+Kanpur
+Kansan/MS
+Kansas
+Kant/M
+Kantian
+Kanya/M
+Kaohsiung
+Kaposi/M
+Kara/M
+Karachi/M
+Karaganda
+Karakorum
+Karalee/M
+Karalynn/M
+Karamazov/M
+Kare/M
+Karee/M
+Kareem/M
+Karel/M
+Karen/M
+Karena/M
+Karenina/M
+Kari/M
+Karia/M
+Karie/M
+Karil/M
+Karilynn/M
+Karim/M
+Karin/M
+Karina/M
+Karine/M
+Kariotta/M
+Karisa/M
+Karissa/M
+Karita/M
+Karl/MNX
+Karla/M
+Karlan/M
+Karlee/M
+Karleen/M
+Karlen/M
+Karlene/M
+Karlie/M
+Karlik/M
+Karlis
+Karloff/M
+Karlotta/M
+Karlotte/M
+Karly/M
+Karlyn/M
+Karmen/M
+Karna/M
+Karney/M
+Karo/MY
+Karol/M
+Karola/M
+Karole/M
+Karolina/M
+Karoline/M
+Karoly/M
+Karon/M
+Karrah/M
+Karrie/M
+Karroo/M
+Karry/M
+Kary/M
+Karyl/M
+Karylin/M
+Karyn/M
+Kasai/M
+Kasey/M
+Kashmir/SM
+Kaspar/M
+Kasparov/M
+Kasper/M
+Kass
+Kassandra/M
+Kassey/M
+Kassi/M
+Kassia/M
+Kassie/M
+Kat/M
+Kata/M
+Katalin/M
+Kate/M
+Katee/M
+Katelyn/M
+Katerina/M
+Katerine/M
+Katey/M
+Kath/M
+Katha/M
+Katharina/M
+Katharine/M
+Katharyn/M
+Kathe/M
+Katherina/M
+Katherine/M
+Katheryn/M
+Kathi/M
+Kathiawar
+Kathie/M
+Kathleen/M
+Kathlin/M
+Kathmandu/M
+Kathrine/M
+Kathryn/M
+Kathryne/M
+Kathy/M
+Kathye/M
+Kati/M
+Katie/M
+Katina/M
+Katine/M
+Katinka/M
+Katleen/M
+Katlin/M
+Katmai
+Katowice
+Katrina/M
+Katrine
+Katrinka/M
+Katti/M
+Kattie/M
+Katuscha/M
+Katusha/M
+Katy/M
+Katya/M
+Kauai/M
+Kaufman/M
+Kaunas/M
+Kaunda/M
+Kawabata/M
+Kawasaki
+Kay
+Kaycee/M
+Kaye/M
+Kayla/M
+Kayle/M
+Kaylee/M
+Kayley/M
+Kaylil/M
+Kaylyn/M
+Kayne/M
+Kazakh/M
+Kazakhs
+Kazakhstan/M
+Kazan/M
+Kazantzakis
+Kb/M
+Kean
+Keane/M
+Kearney/M
+Keary/M
+Keaton/M
+Keats
+Keck/M
+Keefe/RM
+Keefer/M
+Keelby/M
+Keeley/M
+Keelia/M
+Keely/M
+Keen/M
+Keenan/M
+Keene/M
+Keewatin
+Keillor/M
+Keir/M
+Keisha/M
+Keith/M
+Kelbee/M
+Kelby/M
+Kelcey/M
+Kelci/M
+Kelcie/M
+Kelcy/M
+Kele/M
+Kelila/M
+Kellby/M
+Kellen/M
+Keller
+Kelley/M
+Kelli/M
+Kellia/M
+Kellie/M
+Kellina/M
+Kellogg
+Kellsie/M
+Kelly
+Kellyann/M
+Kelsey/M
+Kelsi/M
+Kelsy/M
+Kelvin
+Kelwin/M
+Kemerovo
+Kemp/M
+Kempis
+Kendal/M
+Kendall/M
+Kendell/M
+Kendra/M
+Kendre/M
+Kendrick/MS
+Kenmore/M
+Kenn/M
+Kenna/M
+Kennan/M
+Kennedy/M
+Kenneth/M
+Kennett/M
+Kennie/M
+Kennith/M
+Kenny/M
+Kenon/M
+Kent/M
+Kenton/M
+Kentuckian/SM
+Kentucky/M
+Kenya/M
+Kenyan/SM
+Kenyatta
+Kenyon/M
+Keogh/M
+Keokuk/M
+Kepler/M
+Ker/M
+Kerby/M
+Kerensky/M
+Keri/M
+Keriann/M
+Kerianne/M
+Kerk/M
+Kermie/M
+Kermit/M
+Kermy/M
+Kern
+Kerouac
+Kerr
+Kerri/M
+Kerrie/M
+Kerrill/M
+Kerrin/M
+Kerry
+Kerstin/M
+Kerwin/M
+Kerwinn/M
+Kesley/M
+Keslie/M
+Kessia/M
+Kessiah/M
+Kettering
+Ketti/M
+Kettie/M
+Ketty/M
+Kev/MN
+Kevan/M
+Keven/M
+Kevin/M
+Kevina/M
+Kevlar
+Kevon/M
+Kevorkian/M
+Kevyn/M
+Kewpie
+Key
+Keynes/M
+Keynesian
+Khabarovsk
+Khachaturian
+Khalid/M
+Khalil/M
+Khan/M
+Kharkov/M
+Khartoum/M
+Khayyam/M
+Khazar/M
+Khmer/M
+Khoikhoi/M
+Khoisan/M
+Khomeini/M
+Khorana/M
+Khrushchev
+Khufu
+Khulna/M
+Khwarizmi/M
+Khyber/M
+Ki/M
+Kiah/M
+Kial/M
+Kickapoo
+Kidd/M
+Kiel
+Kiele/M
+Kienan/M
+Kierkegaard
+Kiersten/M
+Kieth/M
+Kiev/M
+Kigali/M
+Kikelia/M
+Kikuyu
+Kilauea
+Kile/M
+Kiley/M
+Kilian/M
+Kilimanjaro/M
+Killian/M
+Killie/M
+Killy/M
+Kilroy/M
+Kim/M
+Kimball/M
+Kimbell/M
+Kimberlee/M
+Kimberley
+Kimberli/M
+Kimberly/M
+Kimberlyn/M
+Kimble/M
+Kimbra/M
+Kimmi/M
+Kimmie/M
+Kimmy/M
+Kin/M
+Kincaid/M
+King/M
+Kingsley
+Kingsly/M
+Kingston/M
+Kingstown/M
+Kinko's
+Kinna/M
+Kinney/M
+Kinnie/M
+Kinny/M
+Kinsey
+Kinshasa/M
+Kinsley/M
+Kiowa/MS
+Kip/M
+Kipling/M
+Kipp/MR
+Kippar/M
+Kipper/M
+Kippie/M
+Kippy/M
+Kira/M
+Kirbee/M
+Kirbie/M
+Kirby/M
+Kirchhoff
+Kirchner/M
+Kirghistan/M
+Kirghiz/M
+Kirghizia/M
+Kiri/M
+Kiribati/M
+Kirinyaga/M
+Kirk
+Kirkland/M
+Kirkpatrick/M
+Kirov
+Kirsten/M
+Kirsteni/M
+Kirsti/M
+Kirstin/M
+Kirstyn/M
+Kisangani
+Kishinev/M
+Kislev/M
+Kissee/M
+Kissiah/M
+Kissie/M
+Kissinger
+Kit/M
+Kitakyushu/M
+Kitchener
+Kitti/M
+Kittie/M
+Kitty/M
+Kiwanis
+Kizzee/M
+Kizzie/M
+Klan/M
+Klansman/M
+Klara/M
+Klarika/M
+Klarrisa/M
+Klaus/M
+Klee
+Kleenex/MS
+Klein/M
+Klemens/M
+Klement/M
+Kleon/M
+Kliment/M
+Klimt
+Kline
+Klingon/M
+Klondike/MS
+Kmart/M
+Knapp/M
+Knesset/M
+Kngwarreye/M
+Knickerbocker
+Knievel/M
+Knight
+Knopf/M
+Knossos
+Knowles
+Knox
+Knoxville
+Knudsen/M
+Knuth/M
+Knuths
+Kobe
+Koch
+Kochab/M
+Kodachrome/M
+Kodak
+Kodaly/M
+Kodiak/M
+Koenraad/M
+Koestler
+Kohinoor
+Kohl
+Kojak/M
+Kolyma
+Kommunizma/M
+Kong/M
+Kongo/M
+Konrad/M
+Konstance/M
+Konstantin/M
+Konstantine/M
+Konstanze/M
+Koo/M
+Koontz/M
+Koppel/M
+Kora/M
+Koral/M
+Koralle/M
+Koran/MS
+Koranic
+Kordula/M
+Kore/M
+Korea/M
+Korean/SM
+Korella/M
+Koren/M
+Koressa/M
+Korey/M
+Kori/M
+Korie/M
+Kornberg/M
+Korney/M
+Korrie/M
+Korry/M
+Kort/M
+Kory/M
+Korzybski
+Kosciusko
+Kossuth
+Kosygin
+Koufax/M
+Kowloon
+Kr/M
+Kraft/M
+Krakatoa/M
+Krakow/M
+Kramer/M
+Krasnodar
+Krasnoyarsk
+Krebs
+Kremlin
+Kremlinologist
+Kremlinology
+Kresge/M
+Kringle/M
+Kris/M
+Krisha/M
+Krishna/M
+Krishnah/M
+Krishnamurti/M
+Krispin/M
+Krissie/M
+Krissy/M
+Krista/M
+Kristal/M
+Kristan/M
+Kriste/M
+Kristel/M
+Kristen/M
+Kristi/MN
+Kristian/M
+Kristie/M
+Kristien/M
+Kristin/M
+Kristina/M
+Kristine/M
+Kristo/SM
+Kristofer/M
+Kristoffer/M
+Kristofor/M
+Kristoforo/M
+Kristopher/M
+Kristy/M
+Kristyn/M
+Kroc/M
+Kroger/M
+Kronecker/M
+Kropotkin
+Kruger
+Krugerrand
+Krupp
+Krysta/M
+Krystal/M
+Krystalle/M
+Krystle/M
+Krystyna/M
+Kshatriya/M
+Kublai/M
+Kubrick
+Kuhn/M
+Kuibyshev
+Kunming
+Kuomintang
+Kurd
+Kurdish/M
+Kurdistan
+Kurosawa
+Kurt/M
+Kurtis/M
+Kusch/M
+Kutuzov
+Kuwait/M
+Kuwaiti/SM
+Kuznets/M
+Kuznetsk/M
+Kwakiutl/M
+Kwangju
+Kwanzaa/MS
+Ky/H
+Kyla/M
+Kyle/M
+Kylen/M
+Kylie/M
+Kylila/M
+Kylynn/M
+Kym/M
+Kynthia/M
+Kyoto/M
+Kyrgyzstan
+Kyrstin/M
+Kyushu/M
+L'Amour
+L'Enfant
+L'Ouverture
+L/MN
+LA
+LAN/M
+LBJ/M
+LC
+LCD/M
+LCM
+LDC
+LED/M
+LIFO
+LL
+LLB/M
+LLD/M
+LNG
+LOGO
+LP/M
+LPG
+LPN/SM
+LSAT
+LSD/M
+LVN
+La/M
+Lab
+Laban
+Labrador/SM
+Labradorean
+Lacee/M
+Lacey/M
+Lachesis/M
+Lacie/M
+Lacy/M
+Ladoga
+Ladonna/M
+Lady
+Ladyship/MS
+Laetitia/M
+Lafayette
+Lafitte/M
+Lagos/M
+Lagrange
+Lagrangian
+Lahore
+Laina/M
+Lainey/M
+Laird/M
+Laius
+Lajos/M
+Lakeisha/M
+Lakewood
+Lakisha/M
+Lakshmi/M
+Lalo/M
+Lamaism/SM
+Lamar/M
+Lamarck/M
+Lamaze
+Lamb
+Lambert
+Lamborghini/M
+Lambrusco
+Lamentations
+Lammond/M
+Lamond/M
+Lamont/M
+Lana/M
+Lanae/M
+Lanai/M
+Lancaster/M
+Lance/M
+Lancelot/M
+Land
+Landon/M
+Landry/M
+Landsat
+Landsteiner/M
+Lane/M
+Lanette/M
+Laney/M
+Lang
+Langerhans/M
+Langland
+Langley
+Langmuir
+Langsdon/M
+Langston/M
+Lani/M
+Lanie/M
+Lanita/M
+Lanna/M
+Lanni/M
+Lannie/M
+Lanny/M
+Lansing/M
+Lanzhou/M
+Lao/SM
+Laocoon/M
+Laotian/SM
+Laplace
+Lapland/MR
+Lapp/SM
+Lara/M
+Laraine/M
+Laramie/M
+Lardner/M
+Laredo
+Lari/M
+Larina/M
+Larine/M
+Larisa/M
+Larissa/M
+Lark/M
+Larousse
+Larry/M
+Lars/N
+Larsen/M
+Larson/M
+Laryssa/M
+Lascaux/M
+Lassa/M
+Lassen/M
+Lassie/M
+Lat
+Latasha/M
+Latashia/M
+Lateran/M
+Latia/M
+Latin/MRS
+Latina
+Latino/SM
+Latisha/M
+Latonya/M
+Latoya/M
+Latrena/M
+Latrina/M
+Latrobe/M
+Latvia/M
+Latvian/MS
+Laud/R
+Laue
+Laughton
+Launce/M
+Laundromat
+Laura/M
+Lauraine/M
+Laural/M
+Lauralee/M
+Laurasia/M
+Laure/M
+Lauree/M
+Laureen/M
+Laurel/M
+Laurella/M
+Lauren/SM
+Laurena/M
+Laurence/M
+Laurene/M
+Laurent/M
+Lauretta/M
+Laurette/M
+Lauri/M
+Laurianne/M
+Laurice/M
+Laurie/M
+Lauritz/M
+Lauryn/M
+Laval
+Lavena/M
+Lavern/M
+Laverna/M
+Laverne/M
+Lavina/M
+Lavinia/M
+Lavinie/M
+Lavoisier
+Lavonne/M
+Law
+Lawanda/M
+Lawrence
+Lawry/M
+Lawson
+Lawton/M
+Lay/M
+Layamon
+Layla/M
+Layne/M
+Layney/M
+Layton/M
+Lazar/M
+Lazare/M
+Lazaro/M
+Lazarus/M
+Le/SMN
+Lea/M
+Leach/M
+Leadbelly
+Leah
+Leakey/M
+Lean/M
+Leander
+Leandra/M
+Leann/M
+Leanna/M
+Leanne/M
+Leanor/M
+Leanora/M
+Lear/M
+Learjet/M
+Leary/M
+Leavenworth
+Lebanese/M
+Lebanon/M
+Lebbie/M
+Lebesgue/M
+Leblanc/M
+Leda
+Lederberg/M
+Lee/M
+Leeann/M
+Leeanne/M
+Leeds/M
+Leela/M
+Leelah/M
+Leeland/M
+Leena/M
+Leesa/M
+Leese/M
+Leeuwenhoek
+Leeward/M
+Left
+Lefty/M
+Legendre
+Leger/M
+Leghorn
+Lego/M
+Legra/M
+Legree/M
+Lehman/M
+Leia/M
+Leibniz/M
+Leicester/SM
+Leiden/M
+Leif/M
+Leigh
+Leigha/M
+Leighton/M
+Leila/M
+Leilah/M
+Leipzig/M
+Leisha/M
+Lek/M
+Lela/M
+Lelah/M
+Leland/M
+Lelia/M
+Lem/M
+Lemaitre/M
+Lemar/M
+Lemmie/M
+Lemmy/M
+Lemuel/M
+Lemuria/M
+Len/M
+Lena/M
+Lenard/M
+Lenci/M
+Lenee/M
+Lenette/M
+Lenin/M
+Leningrad/M
+Leninism/M
+Leninist
+Lenka/M
+Lenna/M
+Lennard/M
+Lennie/M
+Lennon/M
+Lenny/M
+Leno/M
+Lenoir/M
+Lenora/M
+Lenore/M
+Lent/SMN
+Leo/SM
+Leodora/M
+Leoine/M
+Leola/M
+Leoline/M
+Leon
+Leona/M
+Leonanie/M
+Leonard/M
+Leonardo/M
+Leoncavallo
+Leone/M
+Leonel/M
+Leonelle/M
+Leonerd/M
+Leonhard/M
+Leonid
+Leonidas/M
+Leonie/M
+Leonor/M
+Leonora/M
+Leonore/M
+Leontine/M
+Leontyne/M
+Leopold/M
+Leopoldo/M
+Leora/M
+Lepidus
+Lepke/M
+Lepus/M
+Lerner
+Leroi/M
+Leroy/M
+Lesa/M
+Leshia/M
+Lesley/M
+Lesli/M
+Leslie/M
+Lesly/M
+Lesotho/M
+Lesseps
+Lessie/M
+Lester/M
+Lestrade/M
+Lesya/M
+Leta/M
+Letha/M
+Lethe/M
+Lethia/M
+Leticia/M
+Letisha/M
+Letitia/M
+Letizia/M
+Letta/M
+Letterman/M
+Letti/M
+Lettie/M
+Letty/M
+Leupold/M
+Lev
+Levant/M
+Levesque/M
+Levey/M
+Levi/SM
+Leviathan
+Levin/M
+Levine/M
+Leviticus/M
+Levitt/M
+Levon/M
+Levy/M
+Lew/M
+Lewes
+Lewie/M
+Lewinsky/M
+Lewis
+Lewiss
+Lexi/SM
+Lexie/M
+Lexine/M
+Lexington/M
+Lexus/M
+Lexy/M
+Leyla/M
+Lezley/M
+Lezlie/M
+Lhasa/MS
+Lhotse/M
+Li/MY
+Lia/M
+Liam/M
+Lian/M
+Liana/M
+Liane/M
+Lianna/M
+Lianne/M
+Lib
+Libbey/M
+Libbi/M
+Libbie/M
+Libby
+Liberace/M
+Liberia/M
+Liberian/SM
+Libra/MS
+Libreville/M
+Librium/M
+Libya/M
+Libyan/SM
+Licha/M
+Lichtenstein
+Lida/M
+Lidia/M
+Lie
+Lieberman/M
+Liebfraumilch
+Liechtenstein/ZMR
+Liechtensteiner/M
+Lief/M
+Liege/M
+Liesa/M
+Lieut
+Lil/MY
+Lila/SM
+Lilah/M
+Lilia/MS
+Lilian/M
+Liliana/M
+Liliane/M
+Lilith/M
+Liliuokalani
+Lilla/M
+Lille
+Lilli/MS
+Lillian/M
+Lillie/M
+Lilliput/M
+Lilliputian/SM
+Lilllie/M
+Lilly/M
+Lilongwe/M
+Lily/M
+Lilyan/M
+Lima/M
+Limbaugh/M
+Limbo
+Limburger
+Limoges
+Limousin/M
+Limpopo/M
+Lin/M
+Lina/M
+Linc/M
+Lincoln/MS
+Lind
+Linda/M
+Lindbergh
+Lindi/M
+Lindie/M
+Lindon/M
+Lindsay
+Lindsey
+Lindsy/M
+Lindy
+Linea/M
+Linell/M
+Linet/M
+Linette/M
+Link/M
+Linn/M
+Linnaeus/M
+Linnea/M
+Linnell/M
+Linnet/M
+Linnie/M
+Linoel/M
+Linotype
+Linton/M
+Linus/M
+Linux/S
+Linwood/M
+Linzy/M
+Lionel/M
+Lionello/M
+Lipizzaner
+Lippi
+Lippmann
+Lipscomb/M
+Lipton/M
+Lira/M
+Lisa/M
+Lisabeth/M
+Lisbeth/M
+Lisbon/M
+Lise/M
+Lisetta/M
+Lisette/M
+Lisha/M
+Lishe/M
+Lisle/M
+Lissa/M
+Lissajous/M
+Lissi/M
+Lissie/M
+Lissy/M
+Lister/M
+Listerine/M
+Liston/M
+Liszt
+Lita/M
+Lithuania/M
+Lithuanian/MS
+Little/M
+Litton/M
+Liuka/M
+Liv/M
+Liva/M
+Liverpool/M
+Liverpudlian/MS
+Livia/M
+Livingston
+Livingstone
+Livonia/M
+Livvie/M
+Livvy/M
+Livvyy/M
+Livy
+Liz/M
+Liza/M
+Lizabeth/M
+Lizbeth/M
+Lizette/M
+Lizzie/M
+Lizzy/M
+Ljubljana/M
+Llewellyn
+Lloyd
+Llywellyn/M
+Ln
+Loafer/SM
+Lobachevsky
+Lochinvar
+Lock/M
+Locke/M
+Lockean
+Lockheed/M
+Lockwood/M
+Lodge
+Lodovico/M
+Lodz/M
+Loella/M
+Loewe
+Loewi
+Loews/M
+Logan/M
+Lohengrin
+Loire/M
+Lois/M
+Loise/M
+Loki/M
+Lola/M
+Loleta/M
+Lolita
+Lollard
+Lollobrigida/M
+Lolly/M
+Lombard/M
+Lombardi/M
+Lombardy/M
+Lome/M
+Lon/M
+Lona/M
+London/MRZ
+Londoner/M
+Lonee/M
+Long
+Longfellow/M
+Longstreet/M
+Longueuil
+Loni/M
+Lonna/M
+Lonnard/M
+Lonni/M
+Lonnie/M
+Lonny/M
+Lopez/M
+Lora/M
+Lorain/M
+Loraine/M
+Loralee/M
+Loralie/M
+Loralyn/M
+Lorant/M
+Lord/SM
+Lordship/SM
+Loree/M
+Loreen/M
+Lorelei/M
+Lorelle/M
+Loren/S
+Lorena/M
+Lorene/M
+Lorentz
+Lorenz
+Lorenza/M
+Lorenzo/M
+Loretta/M
+Lorette/M
+Lori/M
+Loria/M
+Lorianna/M
+Lorianne/M
+Lorie/M
+Lorilee/M
+Lorilyn/M
+Lorin/M
+Lorinda/M
+Lorine/M
+Lorita/M
+Lorna/M
+Lorne/M
+Lorraine/M
+Lorrayne/M
+Lorre/M
+Lorri/M
+Lorrie/M
+Lorrin/M
+Lorry/M
+Lory/M
+Lot/M
+Lothaire/M
+Lothario/SM
+Lott/M
+Lotta/M
+Lotte/M
+Lotti/M
+Lottie/M
+Lotty/M
+Lou/M
+Louella/M
+Louie/M
+Louis
+Louisa/M
+Louise/M
+Louisette/M
+Louisiana/M
+Louisianan/MS
+Louisianian/MS
+Louisville/M
+Lourdes
+Loutitia/M
+Louvre/M
+Love/M
+Lovecraft/M
+Lovelace
+Lovell
+Lowe/M
+Lowell
+Lowenbrau/M
+Lowery/M
+Lowlands
+Lowrance/M
+Loy/M
+Loyang/M
+Loyd/M
+Loydie/M
+Loyola
+Lr
+Lt
+Ltd
+Lu/M
+Luanda/M
+Luann/M
+Lubavitcher
+Lubbock
+Lubumbashi
+Luca/SM
+Lucais/M
+Luce/M
+Lucho/M
+Luci/MN
+Lucia/MS
+Lucian
+Luciana/M
+Luciano/M
+Lucie/M
+Lucien/M
+Lucienne/M
+Lucifer/M
+Lucila/M
+Lucile/M
+Lucilia/M
+Lucille/M
+Lucina
+Lucinda/M
+Lucine/M
+Lucio/M
+Lucita/M
+Lucite/SM
+Lucius/M
+Lucknow/M
+Lucky/M
+Lucretia
+Lucretius
+Lucy/M
+Luddite/MS
+Ludhiana
+Ludovico/M
+Ludovika/M
+Ludvig/M
+Ludwig/M
+Luella/M
+Luelle/M
+Lufthansa/M
+Luftwaffe
+Luger/M
+Lugosi/M
+Luigi/M
+Luis/M
+Luisa/M
+Luise/M
+Lukas/M
+Luke/M
+Lula/M
+Lulita/M
+Lully
+Lulu/M
+Lumiere/M
+Luna/M
+Lupe/M
+Lupus/M
+Lura/M
+Lurette/M
+Luria/M
+Lurleen/M
+Lurlene/M
+Lurline/M
+Lusa/M
+Lusaka/M
+Lusitania/M
+Lutero/M
+Luther/M
+Lutheran/SM
+Lutheranism/MS
+Luvs/M
+Luxembourg/ZMR
+Luxembourger/M
+Luxembourgian
+Luz/M
+Luzon/M
+Lvov
+Ly/MY
+LyX/M
+Lyallpur
+Lycra
+Lycurgus
+Lyda/M
+Lydia
+Lydian/SM
+Lydie/M
+Lydon/M
+Lyell
+Lyle/M
+Lyman/M
+Lyme/M
+Lyn/M
+Lynch
+Lynda/M
+Lynde/M
+Lyndel/M
+Lyndell/M
+Lyndon/M
+Lyndsay/M
+Lyndsey/M
+Lyndsie/M
+Lyndy/M
+Lynea/M
+Lynelle/M
+Lynett/M
+Lynette/M
+Lynn
+Lynna/M
+Lynne/M
+Lynnea/M
+Lynnell/M
+Lynnelle/M
+Lynnet/M
+Lynnett/M
+Lynnette/M
+Lynsey/M
+Lyon/SM
+Lyra/M
+Lysenko
+Lysistrata/M
+Lysol/M
+Lyssa/M
+M/SMGB
+MA/M
+MASH
+MB/M
+MBA/M
+MC
+MCI/M
+MD/M
+MDT
+ME
+MEGO/S
+MFA/M
+MGM/M
+MHz/M
+MI/M
+MIA
+MIDI/M
+MIPS
+MIPSes
+MIRV
+MIT/M
+MM
+MN
+MO
+MP/M
+MRI/M
+MS/M
+MSG/M
+MST/M
+MSW
+MT/M
+MTV
+MVP/M
+MW
+Maalox/M
+Mab
+Mabel/M
+Mabelle/M
+Mable/M
+Mac
+MacArthur
+MacBride/M
+MacDonald
+MacLeish/M
+Macao/M
+Macaulay
+Macbeth
+Maccabees
+Maccabeus/M
+Mace
+Macedon/M
+Macedonia/M
+Macedonian/SM
+Mach
+Machiavelli/M
+Machiavellian
+Macias/M
+Macintosh/M
+Mack/M
+Mackenzie/M
+Mackinac/M
+Mackinaw
+Macmillan
+Macon
+Macumba/M
+Macy/M
+Mada/M
+Madagascan/SM
+Madagascar/M
+Madalena/M
+Madalyn/M
+Maddalena/M
+Madden/M
+Maddi/M
+Maddie/M
+Maddox/M
+Maddy/M
+Madeira/SM
+Madel/M
+Madelaine/M
+Madeleine/M
+Madelena/M
+Madelene/M
+Madelin/M
+Madelina/M
+Madeline/M
+Madella/M
+Madelle/M
+Madelon/M
+Madelyn/M
+Madge/M
+Madison/M
+Madlen/M
+Madlin/M
+Madonna/SM
+Madras/M
+Madrid/M
+Madurai/M
+Mady/M
+Mae/M
+Maegan/M
+Maeterlinck/M
+Mafia/MS
+Mafioso
+Mag/M
+Magda/M
+Magdaia/M
+Magdalen
+Magdalena
+Magdalene/M
+Magellan/M
+Magellanic
+Maggee/M
+Maggi/M
+Maggie/M
+Maggy/M
+Maghreb/M
+Magi
+Maginot/M
+Magnitogorsk
+Magnum
+Magog
+Magoo/M
+Magritte
+Magsaysay/M
+Magus
+Magyar/SM
+Mahabharata/M
+Mahala/M
+Mahalia/M
+Maharashtra/M
+Mahavira/M
+Mahayana/M
+Mahayanist/M
+Mahdi
+Mahfouz/M
+Mahican/SM
+Mahler
+Mahmoud/M
+Mahmud/M
+Mai/M
+Maia/M
+Maible/M
+Maidenform/M
+Maiga/M
+Maighdiln/M
+Maigret/M
+Mailer
+Maillol
+Maiman/M
+Maimonides
+Maine/MZR
+Mainer/M
+Mair/M
+Maire/M
+Maisey/M
+Maisie/M
+Maison/M
+Maitilde/M
+Maitreya/M
+Maj
+Maje/M
+Majesty
+Major
+Majorca/M
+Majuro
+Makarios/M
+Maker
+Mal
+Mala/M
+Malabar/M
+Malabo/M
+Malacca
+Malachi
+Malagasy
+Malamud
+Malanie/M
+Malaprop/M
+Malawi/M
+Malawian/SM
+Malay/MS
+Malaya/M
+Malayalam/M
+Malayan/MS
+Malaysia/M
+Malaysian/MS
+Malchy/M
+Malcolm
+Maldive/MS
+Maldives/M
+Maldivian/MS
+Maldonado/M
+Male/M
+Malena/M
+Mali
+Malia/M
+Malian/SM
+Malibu/M
+Malina/M
+Malinda/M
+Malinde/M
+Malinowski
+Malissa/M
+Malissia/M
+Mallarme
+Mallissa/M
+Mallomars/M
+Mallorie/M
+Mallory/M
+Malone/M
+Malorie/M
+Malory/M
+Malplaquet/M
+Malraux
+Malta/M
+Maltese/M
+Malthus/M
+Malthusian/SM
+Malva/M
+Malvin/M
+Malvina/M
+Malynda/M
+Mame/M
+Mameluke
+Mamet
+Mamie/M
+Mamore/M
+Man/M
+Managua/M
+Manama/M
+Manasseh
+Manchester/M
+Manchu/SM
+Manchuria/M
+Manchurian
+Mancini/M
+Mancunian/MS
+Manda/M
+Mandalay/M
+Mandarin/M
+Mandel/M
+Mandela
+Mandelbrot
+Mandi/M
+Mandie/M
+Mandingo
+Mandriva/M
+Mandy/M
+Manet
+Manfred/M
+Manhattan/SM
+Mani
+Manichean
+Manila/SM
+Manitoba/M
+Manitoulin/M
+Manley/M
+Mann/G
+Mannheim/M
+Mannie/M
+Manny/M
+Mano/M
+Manolo/M
+Manon/M
+Mansfield
+Manson/M
+Mantegna
+Mantle/M
+Manuel/M
+Manuela/M
+Manx/M
+Manya/M
+Mao/M
+Maoism/SM
+Maoist/SM
+Maori/MS
+Mapplethorpe/M
+Maputo/M
+Mar/SMN
+Mara/M
+Marabel/M
+Maracaibo
+Marat
+Maratha/M
+Marathi/M
+Marathon/M
+Marc
+Marceau
+Marcel/M
+Marcela/M
+Marcelia/M
+Marcelino/M
+Marcella/M
+Marcelle/M
+Marcellina/M
+Marcelline/M
+Marcello/M
+Marcellus
+Marcelo/M
+March/MS
+Marchall/M
+Marchelle/M
+Marci/M
+Marcia/M
+Marciano
+Marcie/M
+Marcile/M
+Marcille/M
+Marco/MS
+Marconi
+Marcus/M
+Marcuse
+Marcy/M
+Marduk/M
+Mareah/M
+Maren/M
+Marena/M
+Maressa/M
+Marga/M
+Margalit/M
+Margalo/M
+Margaret
+Margareta/M
+Margarete/M
+Margaretha/M
+Margarethe/M
+Margaretta/M
+Margarette/M
+Margarita
+Margarito/M
+Margaux
+Marge/M
+Margeaux/M
+Margery/M
+Marget/M
+Margette/M
+Margi/M
+Margie/M
+Margit/M
+Margo/M
+Margot/M
+Margret/M
+Margrethe/M
+Marguerite/M
+Margy/M
+Mari/SM
+Maria/M
+Mariam/M
+Marian
+Mariana/SM
+Mariann/M
+Marianna/M
+Marianne
+Mariano/M
+Maribel/M
+Maribelle/M
+Maribeth/M
+Marice/M
+Maricela/M
+Maridel/M
+Marie/M
+Marieann/M
+Mariejeanne/M
+Mariel/M
+Mariele/M
+Marielle/M
+Mariellen/M
+Marietta/M
+Mariette/M
+Marigold/M
+Marijn/M
+Marijo/M
+Marika/M
+Marilee/M
+Marilin/M
+Marillin/M
+Marilyn/M
+Marin
+Marina/M
+Marine/SM
+Marinna/M
+Mario/M
+Marion/M
+Mariquilla/M
+Marisa/M
+Mariska/M
+Marisol/M
+Marissa/M
+Marita/M
+Maritain
+Maritsa
+Maritza/M
+Mariupol
+Marius
+Mariya/M
+Marj/M
+Marja/M
+Marje/M
+Marji/M
+Marjie/M
+Marjorie/M
+Marjory/M
+Marjy/M
+Mark/SM
+Markab/M
+Marketa/M
+Markham
+Markos
+Markov
+Markus/M
+Marla/M
+Marlane/M
+Marlboro/M
+Marlborough
+Marleah/M
+Marlee/M
+Marleen/M
+Marlena/M
+Marlene/M
+Marley/M
+Marlie/M
+Marlin
+Marline/M
+Marlo/M
+Marlon/M
+Marlow/M
+Marlowe
+Marlyn/M
+Marmaduke/M
+Marmara/M
+Marna/M
+Marne
+Marney/M
+Marni/M
+Marnia/M
+Marnie/M
+Maronite
+Marple/M
+Marquesas/M
+Marquette
+Marquez/M
+Marquis
+Marquita/M
+Marrakesh/M
+Marrilee/M
+Marriott/M
+Marris/M
+Marrissa/M
+Mars/MS
+Marsala/M
+Marseillaise/MS
+Marseilles
+Marsh/M
+Marsha/M
+Marshal/M
+Marshall/M
+Marsiella/M
+Mart/MN
+Marta/M
+Martainn/M
+Martel
+Martelle/M
+Marten/M
+Martguerita/M
+Martha
+Marthe/M
+Marthena/M
+Marti/M
+Martial
+Martian/SM
+Martica/M
+Martie/M
+Martin
+Martina/M
+Martinez/M
+Martinique/M
+Martino/M
+Martita/M
+Marty/M
+Martyn/M
+Martynne/M
+Marv/MN
+Marva/M
+Marve/M
+Marvell/M
+Marven/M
+Marvin
+Marwin/M
+Marx/M
+Marxian
+Marxism/SM
+Marxist/SM
+Mary/M
+Marya/M
+Maryann/M
+Maryanna/M
+Maryanne/M
+Marybelle/M
+Marybeth/M
+Maryellen/M
+Maryjane/M
+Maryjo/M
+Maryl/M
+Maryland/MR
+Marylee/M
+Marylin/M
+Marylinda/M
+Marylou/M
+Marylynne/M
+Maryrose/M
+Marys
+Marysa/M
+Masada/M
+Masai/M
+Masaryk
+Mascagni
+Masefield
+Maserati/M
+Maseru/M
+Masha/M
+Mashhad/M
+Mason/MS
+Masonic
+Masonite/M
+Mass/MS
+Massachusetts
+Massasoit
+Massenet
+Massey
+Massimiliano/M
+Massimo/M
+Master/S
+MasterCard/M
+Mata/M
+Matelda/M
+Mateo/M
+Mathe/MR
+Mathew/SM
+Mathewson/M
+Mathian/M
+Mathias
+Mathilda/M
+Mathilde/M
+Mathis
+Matias/M
+Matilda
+Matilde/M
+Matisse
+Matt
+Mattel/M
+Matteo/M
+Matterhorn/M
+Matthaeus/M
+Mattheus/M
+Matthew/SM
+Matthias
+Matthieu/M
+Matthiew/M
+Matthus/M
+Matti/M
+Mattias/M
+Mattie/M
+Matty/M
+Maud/M
+Maude/M
+Maudie/M
+Maugham
+Maui/M
+Maupassant
+Maura/M
+Maure/M
+Maureen/M
+Maureene/M
+Maurene/M
+Mauriac
+Maurice
+Mauricio/M
+Maurie/M
+Maurine/M
+Maurise/M
+Maurita/M
+Mauritania/M
+Mauritanian/MS
+Mauritian/SM
+Mauritius/M
+Maurits/M
+Maurizia/M
+Maurizio/M
+Mauro/M
+Maurois
+Maury
+Mauryan/M
+Mauser
+Mavis/M
+Mavra/M
+Max/M
+Maxi/M
+Maxie/M
+Maxim
+Maximilian
+Maximilianus/M
+Maximilien/M
+Maximo/M
+Maxine/M
+Maxwell
+Maxy/M
+May/SMR
+Maya/SM
+Mayan/MS
+Maybelle/M
+Maye/M
+Mayfair
+Mayflower/M
+Maynard/M
+Mayne/M
+Maynord/M
+Mayo
+Mayor/M
+Maypole
+Mayra/M
+Maytag/M
+Mazama/M
+Mazarin
+Mazatlan/M
+Mazda
+Mazola/M
+Mazzini/M
+Mb/M
+Mbabane/M
+Mbini/M
+McAdam/M
+McBride/M
+McCain/M
+McCall/M
+McCarthy
+McCarthyism/M
+McCartney/M
+McCarty/M
+McClain/M
+McClellan
+McClure/M
+McConnell/M
+McCormick
+McCoy
+McCray/M
+McCullough/M
+McDaniel/M
+McDonald/M
+McDonnell/M
+McDowell/M
+McEnroe/M
+McFadden/M
+McFarland/M
+McGee/M
+McGovern/M
+McGowan/M
+McGuffey/M
+McGuire/M
+McIntosh/M
+McIntyre/M
+McKay/M
+McKee/M
+McKenzie/M
+McKinley/M
+McKinney/M
+McKnight/M
+McLaughlin/M
+McLean/M
+McLeod/M
+McLuhan/M
+McMahon/M
+McMillan/M
+McNamara/M
+McNaughton/M
+McNeil/M
+McPherson/M
+McQueen/M
+McVeigh/M
+Md/M
+Me
+Mead
+Meade
+Meadows
+Meagan/M
+Meaghan/M
+Meany/M
+Meara/M
+Mecca/MS
+Mechelle/M
+Medan
+Medea/M
+Medellin
+Media
+Medicaid/SM
+Medicare/SM
+Medici
+Medina
+Mediterranean/SM
+Medusa/M
+Meg/MN
+Megan/M
+Megen/M
+Meggi/M
+Meggie/M
+Meggy/M
+Meghan/M
+Meghann/M
+Mehetabel/M
+Mei/MR
+Meier/M
+Meighen/M
+Meiji/M
+Meir
+Mejia/M
+Mekong/M
+Mel/MY
+Mela/M
+Melamie/M
+Melanesia/M
+Melanesian
+Melania/M
+Melanie/M
+Melantha/M
+Melany/M
+Melba
+Melbourne/M
+Melchior
+Melchizedek
+Melendez/M
+Melesa/M
+Melessa/M
+Melicent/M
+Melina/M
+Melinda/M
+Melinde/M
+Melisa/M
+Melisande/M
+Melisandra/M
+Melisenda/M
+Melisent/M
+Melissa/M
+Melisse/M
+Melita/M
+Melitta/M
+Mella/M
+Melli/M
+Mellicent/M
+Mellie/M
+Mellisa/M
+Mellisent/M
+Mellon
+Melloney/M
+Melly/M
+Melodee/M
+Melodie/M
+Melody/M
+Melonie/M
+Melony/M
+Melosa/M
+Melpomene/M
+Melton/M
+Melva/M
+Melville/M
+Melvin/M
+Melvyn/M
+Memling
+Memphis/M
+Menander
+Menard/M
+Mencius
+Mencken
+Mendel/M
+Mendeleev/M
+Mendelian
+Mendelssohn
+Mendez/M
+Mendie/M
+Mendocino/M
+Mendoza
+Mendy/M
+Menelaus/M
+Menelik/M
+Menes
+Mengzi
+Menkalinan/M
+Menkar/M
+Menkent/M
+Mennen/M
+Mennonite/MS
+Menominee/M
+Menotti
+Mensa
+Mentholatum/M
+Menuhin/M
+Menzies
+Mephistopheles
+Merak/M
+Mercado/M
+Mercator
+Mercedes
+Mercer/M
+Merci/M
+Mercia
+Mercie/M
+Merck/M
+Mercurochrome/M
+Mercury/SM
+Mercy/M
+Meredeth/M
+Meredith
+Meredithe/M
+Merell/M
+Meridel/M
+Meridith/M
+Meriel/M
+Merilee/M
+Merill/M
+Merilyn/M
+Merino
+Meris
+Merissa/M
+Merl/M
+Merla/M
+Merle/M
+Merlin/M
+Merlina/M
+Merline/M
+Merlot
+Merna/M
+Merola/M
+Merovingian
+Merralee/M
+Merrel/M
+Merriam/M
+Merrick/M
+Merridie/M
+Merrie/M
+Merrielle/M
+Merrile/M
+Merrilee/M
+Merrili/M
+Merrill/M
+Merrily/M
+Merrimack/M
+Merritt/M
+Merry/M
+Mersey
+Merthiolate/M
+Merton
+Merv/M
+Mervin/M
+Merwin/M
+Merwyn/M
+Meryl/M
+Mesa
+Mesabi/M
+Mesmer/M
+Mesolithic
+Mesopotamia/M
+Mesopotamian
+Mesozoic/M
+Messerschmidt/M
+Messiaen
+Messiah/M
+Messiahs
+Messianic
+Meta
+Metamucil/M
+Methodism/SM
+Methodist/SM
+Methuselah
+Metternich
+Meuse/M
+Mex
+Mexicali
+Mexican/MS
+Mexico/M
+Meyer/MS
+Meyerbeer
+Mfume/M
+Mg/M
+Mgr
+MiG
+Mia/M
+Miami/MS
+Miaplacidus/M
+Mic
+Micaela/M
+Micah
+Micawber
+Mich
+Michael
+Michaela/M
+Michaelina/M
+Michaeline/M
+Michaella/M
+Michaelmas/MS
+Michail/M
+Michal/M
+Michale/M
+Micheal/M
+Micheil/M
+Michel/M
+Michelangelo/M
+Michele/M
+Michelin/M
+Michelina/M
+Micheline/M
+Michell/M
+Michelle/M
+Michelob/M
+Michelson
+Michigan/M
+Michigander/SM
+Michiganite
+Mick/M
+Mickey/M
+Micki/M
+Mickie/M
+Micky/M
+Micmac/SM
+Micronesia/M
+Micronesian
+Microsoft/M
+Midas/M
+Middleton
+Mideast
+Mideastern
+Midge/M
+Midland/S
+Midway/M
+Midwest/M
+Midwestern/R
+Mignon/M
+Mignonne/M
+Miguel/M
+Miguela/M
+Miguelita/M
+Mikael/M
+Mikaela/M
+Mike/M
+Mikel/M
+Mikey/M
+Mikhail/M
+Mikkel/M
+Mikol/M
+Mikoyan/M
+Mil/MY
+Milagros/M
+Milan/M
+Milanese
+Mildred/M
+Mildrid/M
+Mile/SM
+Milena/M
+Milford/M
+Milicent/M
+Milissent/M
+Milka/M
+Milken/M
+Mill/SR
+Millard/M
+Millay
+Millet
+Milli/M
+Millicent/M
+Millie/M
+Millikan
+Millisent/M
+Milly/M
+Milne
+Milo/M
+Milosevic/M
+Milquetoast/M
+Milt/M
+Miltiades
+Miltie/M
+Milton
+Miltonic
+Miltown/M
+Milty/M
+Milwaukee/M
+Milzie/M
+Mimi/M
+Mimosa/M
+Min/MR
+Mina/M
+Minamoto/M
+Minda/M
+Mindanao
+Mindoro/M
+Mindy/M
+Miner/M
+Minerva/M
+Minetta/M
+Minette/M
+Mingus/M
+Minn
+Minna
+Minnaminnie/M
+Minne/M
+Minneapolis/M
+Minnelli/M
+Minnesota/M
+Minnesotan/SM
+Minni/M
+Minnie/M
+Minnnie/M
+Minny/M
+Minoan/MS
+Minolta/M
+Minor/M
+Minos/M
+Minot/M
+Minotaur/M
+Minsk/M
+Minsky/M
+Minta/M
+Mintaka/M
+Minuit
+Minuteman/M
+Miocene/M
+Miquela/M
+Mir/M
+Mira/M
+Mirabeau
+Mirabel/M
+Mirabella/M
+Mirabelle/M
+Mirach/M
+Miran/M
+Miranda
+Mireielle/M
+Mireille/M
+Mirella/M
+Mirelle/M
+Mirfak/M
+Miriam/M
+Mirilla/M
+Mirna/M
+Miro
+Mirzam/M
+Mischa/M
+Misha/M
+Miskito
+Miss
+Missie/M
+Mississauga
+Mississippi/M
+Mississippian/SM
+Missouri/M
+Missourian/MS
+Missy/M
+Mistassini
+Mister
+Misti
+Mistress
+Misty/M
+Mitch/M
+Mitchael/M
+Mitchel/M
+Mitchell
+Mitford/M
+Mithra/M
+Mithridates/M
+Mitsubishi/M
+Mitterrand/M
+Mitty/M
+Mitzi/M
+Mixtec
+Mizar
+Mk
+Mlle
+Mme/S
+Mn/M
+Mnemosyne/M
+Mo/M
+Mobil/M
+Mobile/M
+Mobutu/M
+Modesta/M
+Modestia/M
+Modestine/M
+Modesto
+Modesty/M
+Modigliani
+Moe/M
+Mogadishu
+Mogul/MS
+Mohacs/M
+Mohamed/M
+Mohammad/M
+Mohammedan/SM
+Mohammedanism/MS
+Mohandas/M
+Mohandis/M
+Mohave/SM
+Mohawk/SM
+Mohegan
+Moho/M
+Mohorovicic/M
+Moina/M
+Moira
+Moise/MS
+Moiseyev/M
+Moishe/M
+Mojave/SM
+Moldavia/M
+Moldavian
+Moldova/M
+Moldovan
+Moliere/M
+Molina
+Moll/M
+Mollee/M
+Molli/M
+Mollie/M
+Molly/M
+Molnar/M
+Moloch/M
+Molokai/M
+Molotov/M
+Moluccas
+Mombasa/M
+Mommy/M
+Mon/SM
+Mona/M
+Monacan
+Monaco/M
+Monah/M
+Mondale/M
+Monday/SM
+Mondrian
+Monegasque/SM
+Monera/M
+Monet
+Mongol/SM
+Mongolia/M
+Mongolian/SM
+Mongolic/M
+Mongoloid
+Monica/M
+Monika/M
+Monique/M
+Monk/M
+Monmouth
+Monongahela
+Monro/M
+Monroe/M
+Monrovia/M
+Monsanto/M
+Monsignor/SM
+Mont
+Montague
+Montaigne
+Montana/M
+Montanan/SM
+Montcalm
+Monte/M
+Montenegrin
+Montenegro/M
+Monterrey
+Montesquieu
+Montessori
+Monteverdi
+Montevideo/M
+Montezuma/M
+Montgolfier
+Montgomery/M
+Monti/M
+Monticello
+Montoya/M
+Montpelier/M
+Montrachet
+Montreal/M
+Montserrat/M
+Monty/M
+Moody
+Moog
+Moon/M
+Mooney/M
+Moor/SM
+Moore
+Moorish/M
+Mora/M
+Morales/M
+Moran/M
+Moravia
+Moravian
+Mord/M
+Mordecai
+Mordred
+Mordy/M
+More
+Moreen/M
+Morena/M
+Moreno/M
+Morey/M
+Morgan/SM
+Morgana/M
+Morganica/M
+Morganne/M
+Morgen/M
+Morgun/M
+Moria/M
+Moriarty/M
+Morie/M
+Morin/M
+Morison/M
+Morissa/M
+Morita/M
+Moritz/M
+Morlee/M
+Morley
+Morly/M
+Mormon/SM
+Mormonism/SM
+Morna/M
+Moro
+Moroccan/SM
+Morocco/M
+Moroni
+Morpheus/M
+Morphy/M
+Morrie/M
+Morris
+Morrison
+Morrow/M
+Morry/M
+Morse/M
+Mort/MN
+Morten/M
+Mortie/M
+Mortimer
+Morton/M
+Morty/M
+Mosaic/M
+Moscow/M
+Mose/SM
+Moseley
+Moselle/M
+Moses/M
+Moshe/M
+Mosley/M
+Moss/M
+Mosul
+Motorola/M
+Motown/M
+Motrin/M
+Mott
+Mount
+Mountbatten
+Mountie/MS
+Moussorgsky
+Mouthe/M
+Mouton/M
+Mowgli/M
+Moyna/M
+Moyra/M
+Mozambican/SM
+Mozambique/M
+Mozart/M
+Mozelle/M
+Mozes/M
+Mozilla/M
+Mr/SM
+Ms/S
+Msgr
+Mt
+Muawiya/M
+Mubarak/M
+Mueller/M
+Muenster/MS
+Muffin/M
+Mufi/M
+Mufinella/M
+Mugabe/M
+Muhammad/M
+Muhammadan/SM
+Muhammadanism/SM
+Muir
+Muire/M
+Mujib/M
+Mulder/M
+Mullen/M
+Muller/M
+Mulligan/M
+Mullikan/M
+Mullins
+Mulroney/M
+Multan
+Multics/S
+Mumford
+Munch
+Munchhausen/M
+Munich/M
+Munmro/M
+Munoz/M
+Munro
+Munroe/M
+Munster
+Muppet/M
+Murasaki/M
+Murat
+Murchison/M
+Murcia
+Murdoch
+Murdock/M
+Mureil/M
+Murial/M
+Muriel/M
+Murielle/M
+Murillo
+Murine/M
+Murmansk
+Murphy
+Murray/M
+Murrow/M
+Murrumbidgee
+Murry/M
+Murvyn/M
+Muscat/M
+Muscovite/M
+Muscovy/M
+Muse/M
+Musharraf/M
+Musial/M
+Muskogee/M
+Muslim/MS
+Mussolini/M
+Mussorgsky
+Mutsuhito/M
+Muzak
+My/M
+Myanmar/M
+Myca/M
+Mycah/M
+Mycenae/M
+Mycenaean
+Mychal/M
+Myer/SM
+Mylar/MS
+Myles/M
+Mylo/M
+Myra/M
+Myrah/M
+Myranda/M
+Myrdal/M
+Myriam/M
+Myrilla/M
+Myrle/M
+Myrlene/M
+Myrna/M
+Myron
+Myrta/M
+Myrtia/M
+Myrtice/M
+Myrtie/M
+Myrtle/M
+Myrvyn/M
+Myrwyn/M
+Mysore
+MySpell/M
+Myst/M
+N'Djamena
+N/MD
+NAACP
+NAFTA
+NASA/M
+NASDAQ/M
+NATO/M
+NB
+NBA
+NBC
+NBS
+NC
+NCAA
+NCO
+ND
+NE/M
+NEH
+NF
+NFC
+NFL
+NH
+NHL
+NIH
+NIMBY
+NJ
+NLRB
+NM
+NORAD/M
+NOW
+NP
+NPR
+NR
+NRA
+NRC
+NS
+NSC
+NSF
+NT
+NV
+NW/M
+NWT
+NY
+NYC
+NYSE
+NZ
+Na/M
+Nabisco/M
+Nabokov
+Nada/M
+Nadean/M
+Nadeen/M
+Nader
+Nadia/M
+Nadine/M
+Nadiya/M
+Nady/M
+Nadya/M
+Nagasaki/M
+Nagoya
+Nagpur
+Nagy
+Nahuatl/MS
+Nahum
+Naipaul/M
+Nair/M
+Nairobi/M
+Naismith/M
+Nalani/M
+Nam/M
+Namath/M
+Namibia/M
+Namibian/MS
+Nan/M
+Nana/M
+Nanak
+Nananne/M
+Nance/M
+Nancee/M
+Nancey/M
+Nanchang
+Nanci/M
+Nancie/M
+Nancy
+Nanete/M
+Nanette/M
+Nani/M
+Nanice/M
+Nanine/M
+Nanjing/M
+Nannette/M
+Nanni/M
+Nannie/M
+Nanny/M
+Nanon/M
+Nanook/M
+Nansen
+Nantes/M
+Nantucket/M
+Naoma/M
+Naomi/M
+Nap/M
+Naphtali/M
+Napier/M
+Naples/M
+Napoleon/MS
+Napoleonic
+Nappie/M
+Nappy/M
+Napster/M
+Nara
+Narcissus/M
+Nari/M
+Nariko/M
+Narmada/M
+Narnia/M
+Narraganset
+Narragansett
+Nash
+Nashua
+Nashville/M
+Nassau/M
+Nasser/M
+Nat/M
+Nata/M
+Natal/M
+Natala/M
+Natale/M
+Natalee/M
+Natalia/M
+Natalie/M
+Natalina/M
+Nataline/M
+Natalya/M
+Nataniel/M
+Natasha/M
+Natassia/M
+Natchez
+Nate/MN
+Nathalia/M
+Nathalie/M
+Nathan/S
+Nathanael
+Nathanial/M
+Nathaniel/M
+Nathanil/M
+Nationwide/M
+Natividad/M
+Nativity/M
+Natka/M
+Natty/M
+Naugahyde
+Nauru/M
+Nautilus
+Navajo/SM
+Navajoes
+Navarre
+Navarro/M
+Navratilova/M
+Navy
+Nazarene
+Nazareth
+Nazca
+Nazi/SM
+Nazism/MS
+Nb/M
+Nd/M
+Ndjamena/M
+Ne/M
+NeWS
+NeWSes
+Neal/M
+Neala/M
+Neale/M
+Neall/M
+Nealon/M
+Nealson/M
+Nealy/M
+Neanderthal/MS
+Neapolitan
+Neb
+Nebr
+Nebraska/M
+Nebraskan/MS
+Nebuchadnezzar
+Ned/M
+Neda/M
+Nedda/M
+Neddie/M
+Neddy/M
+Nedi/M
+Neel/M
+Neely/M
+Nefen/M
+Nefertiti
+Negev/M
+Negress/MS
+Negritude
+Negro/MS
+Negroes
+Negroid/SM
+Nehemiah
+Nehru/M
+Neil/SM
+Neila/M
+Neile/M
+Neill/M
+Neilla/M
+Neille/M
+Nelda/M
+Nelia/M
+Nelie/M
+Nell/M
+Nelle/M
+Nelli/M
+Nellie/M
+Nelly/M
+Nels/N
+Nelsen/M
+Nelson
+Nembutal/M
+Nemesis/M
+Neogene
+Neolithic
+Nepal/M
+Nepalese/M
+Nepali/MS
+Neptune/M
+Nereid/M
+Nerf
+Nerissa/M
+Nerita/M
+Nero
+Neron/M
+Nert/M
+Nerta/M
+Nerte/M
+Nerti/M
+Nertie/M
+Nerty/M
+Neruda
+Nessa/M
+Nesselrode
+Nessi/M
+Nessie/M
+Nessy/M
+Nesta/M
+Nester/M
+Nestle/M
+Nestor/M
+Nestorius
+Netherlander/MS
+Netherlands
+Netscape/M
+Netta/M
+Netti/M
+Nettie/M
+Nettle/M
+Netty/M
+Netzahualcoyotl/M
+Nev
+Neva
+Nevada/M
+Nevadan/SM
+Nevadian
+Nevil/M
+Nevile/M
+Neville/M
+Nevin/MS
+Nevis/M
+Nevsa/M
+Nevsky/M
+Newark/M
+Newcastle/M
+Newfoundland/MRS
+Newman
+Newport/M
+Newsweek/M
+Newton/M
+Newtonian/M
+Nexis
+Neysa/M
+Ngaliema/M
+Nguyen/M
+Ni
+Niagara/M
+Nial/M
+Niall/M
+Niamey/M
+Nibelung
+Nicaea
+Nicaragua/M
+Nicaraguan/SM
+Niccolo/M
+Nice/M
+Nicene
+Nichiren/M
+Nichol/SM
+Nicholas
+Nichole/M
+Nicholle/M
+Nicholson
+Nick/M
+Nickelodeon/M
+Nickey/M
+Nicki/M
+Nickie/M
+Nicklaus
+Nicko/M
+Nickola/SM
+Nickolai/M
+Nickolaus/M
+Nicky/M
+Nico/M
+Nicobar/M
+Nicodemus
+Nicol/M
+Nicola/SM
+Nicolai/S
+Nicole/M
+Nicolea/M
+Nicolette/M
+Nicoli/SM
+Nicolina/M
+Nicoline/M
+Nicolle/M
+Nicosia/M
+Niebuhr/M
+Niel/SM
+Niels/N
+Nietzsche
+Nieves/M
+Nigel/M
+Niger/M
+Nigeria/M
+Nigerian/MS
+Nigerien/M
+Nightingale/M
+Nijinsky
+Nikaniki/M
+Nike/M
+Niki/M
+Nikita/M
+Nikkei
+Nikki/M
+Nikkie/M
+Niko/SM
+Nikola/SM
+Nikolai/M
+Nikolaos/M
+Nikolaus/M
+Nikoletta/M
+Nikolia/M
+Nikolos/M
+Nikon/M
+Nil/SM
+Nile/SM
+Nilson/M
+Nimitz
+Nimrod
+Nina/M
+Ninetta/M
+Ninette/M
+Nineveh/M
+Ninnetta/M
+Ninnette/M
+Ninon/M
+Nintendo
+Niobe
+Nippon/M
+Nipponese/M
+Nirenberg/M
+Nirvana
+Nisan/M
+Nisei
+Nissa/M
+Nissan/M
+Nisse/M
+Nissie/M
+Nissy/M
+Nita/M
+Niven/M
+Nixie
+Nixon/M
+Nkrumah
+No/M
+NoDoz/M
+Noach/M
+Noah/M
+Noak/M
+Noam/M
+Noami/M
+Nobe/M
+Nobel
+Nobelist/MS
+Nobie/M
+Noble/M
+Noby/M
+Noe/M
+Noel/SM
+Noelani/M
+Noell/M
+Noella/M
+Noelle/M
+Noellyn/M
+Noelyn/M
+Noemi/M
+Nola/M
+Nolan/M
+Nolana/M
+Noland/M
+Nolie/M
+Noll/M
+Nollie/M
+Nolly/M
+Nome
+Nomi/M
+Nona/M
+Nonah/M
+Noni/M
+Nonie/M
+Nonna/M
+Nonnah/M
+Nora/M
+Norah/M
+Norbert/M
+Norberto/M
+Norbie/M
+Norby/M
+Nordic/MS
+Norean/M
+Noreen/M
+Norene/M
+Norfolk/M
+Noriega/M
+Norina/M
+Norine/M
+Norma
+Norman/MS
+Normand/M
+Normandy/M
+Normie/M
+Normy/M
+Norplant
+Norri/MS
+Norrie/M
+Norry/M
+Norse/M
+Norseman/M
+Norsemen
+North/M
+Northampton
+Northeast/MS
+Northerner/M
+Northrop/M
+Northrup/M
+Norths
+Northwest/SM
+Norton/M
+Norw
+Norway/M
+Norwegian/SM
+Norwich
+Nosferatu/M
+Nostradamus
+Nottingham
+Nouakchott/M
+Noumea/M
+Nov/M
+Nova
+Novelia/M
+November/MS
+Novgorod
+Novocain/MS
+Novocaine
+Novokuznetsk
+Novosibirsk/M
+Nowell/M
+Noxzema/M
+Noyce/M
+Noyes/M
+Np/M
+Nubia
+Nubian
+Nukualofa
+Numbers/M
+Nunavut/M
+Nunez/M
+Nunki/M
+Nuremberg
+Nureyev
+NutraSweet/M
+NyQuil/M
+Nyasa/M
+Nydia/M
+Nye/M
+Nyerere/M
+Nyssa/M
+O'Brien
+O'Casey
+O'Connell
+O'Connor
+O'Donnell
+O'Hara
+O'Higgins
+O'Keeffe
+O'Neil
+O'Neill
+O'Rourke
+O'Toole
+O/SM
+OAS/M
+OB
+OCR
+OD/SM
+OE
+OED
+OH
+OHSA/M
+OJ
+OK/SM
+OMB/M
+ON
+OPEC/M
+OR
+OS/M
+OSHA/M
+OSes
+OT
+OTB
+OTC
+OTOH
+Oahu/M
+Oakland/M
+Oakley
+Oates
+Oaxaca/M
+Ob/MD
+Obadiah
+Obadias/M
+Obed/M
+Obediah/M
+Oberlin/M
+Oberon
+Obidiah/M
+Obie
+Oby/M
+Occam
+Occident
+Occidental/SM
+Oceania/M
+Oceanside
+Oceanus/M
+Ochoa/M
+Oct/M
+Octavia
+Octavian/M
+Octavio/M
+Octavius/M
+October/SM
+Ode/RM
+Odele/M
+Odelia/M
+Odelinda/M
+Odell/M
+Odella/M
+Odelle/M
+Oder/M
+Odessa/M
+Odets
+Odetta/M
+Odette/M
+Odey/M
+Odie/M
+Odilia/M
+Odille/M
+Odin/M
+Odis/M
+Odo/M
+Odom/M
+Ody/M
+Odysseus/M
+Odyssey/M
+Oedipal
+Oedipus/M
+Oersted/M
+Ofelia/M
+Ofella/M
+Offenbach
+OfficeMax/M
+Ofilia/M
+Ogbomosho
+Ogdan/M
+Ogden/M
+Ogdon/M
+Ogilvy/M
+Oglethorpe
+Ohio/M
+Ohioan/SM
+Oise/M
+Ojibwa/SM
+Okayama
+Okeechobee
+Okefenokee
+Okhotsk
+Okinawa/M
+Okinawan
+Okla
+Oklahoma/M
+Oklahoman
+Oktoberfest
+Ola/M
+Olaf/M
+Olag/M
+Olajuwon/M
+Olav/M
+Oldenburg
+Oldfield/M
+Oldsmobile/M
+Olduvai/M
+Ole/MV
+Olen/M
+Olenek/M
+Olenka/M
+Olenolin/M
+Olga/M
+Olia/M
+Oligocene/M
+Olimpia/M
+Olin/M
+Olive/MR
+Olivero/M
+Olivette/M
+Olivetti/M
+Olivia/M
+Olivie/MR
+Oliviero/M
+Oliy/M
+Ollie/M
+Olly/M
+Olmec
+Olmsted/M
+Olsen/M
+Olson/M
+Olva/M
+Olvan/M
+Olwen/M
+Olympe/M
+Olympia/SM
+Olympiad/MS
+Olympian/MS
+Olympic/S
+Olympie/M
+Olympus/M
+Omaha/MS
+Oman/M
+Omani/MS
+Omar/M
+Omayyad
+Omdurman/M
+Omero/M
+Omnipotent
+Omsk/M
+Onassis
+Ondrea/M
+Oneal/M
+Onega
+Onegin/M
+Oneida/MS
+Onfre/M
+Onfroi/M
+Onida/M
+Ono/M
+Onofredo/M
+Onondaga/MS
+Onsager/M
+Ont
+Ontarian
+Ontario/M
+Oona/M
+Oort/M
+Opal/M
+Opalina/M
+Opaline/M
+Opel/M
+Ophelia/M
+Ophelie/M
+Ophiuchus
+Oppenheimer/M
+Oprah/M
+Ora/M
+Oralee/M
+Oralia/M
+Oralie/M
+Oralla/M
+Oralle/M
+Oran/M
+Orange
+Oranjestad/M
+Orazio/M
+Orbadiah/M
+Orbison/M
+Ordovician/M
+Ore/N
+Oreg
+Oregon/M
+Oregonian/SM
+Orel
+Orelee/M
+Orelia/M
+Orelie/M
+Orella/M
+Orelle/M
+Oren/M
+Oreo
+Orestes
+Oriana/M
+Orient
+Oriental/MS
+Orin/M
+Orinoco/M
+Orion/M
+Oriya/M
+Orizaba/M
+Orkney/M
+Orlan/M
+Orland/M
+Orlando/M
+Orleans/M
+Orlon/MS
+Orly/M
+Orpheus/M
+Orphic
+Orr/MN
+Orran/M
+Orren/M
+Orrin/M
+Orsa/M
+Orsola/M
+Orson/M
+Ortega/M
+Ortensia/M
+Orthodox
+Ortiz/M
+Orton/M
+Orv/M
+Orval/M
+Orville/M
+Orwell
+Orwellian
+Osage/MS
+Osaka/M
+Osbert/M
+Osborn/M
+Osborne
+Osbourn/M
+Osbourne/M
+Oscar/MS
+Osceola
+Osgood/M
+Oshawa
+Oshkosh/M
+Osiris/M
+Oslo/M
+Osman/M
+Osmond/M
+Osmund/M
+Ossie/M
+Ostrogoth/M
+Ostwald
+Osvaldo/M
+Oswald
+Oswell/M
+Otes
+Otha/M
+Othelia/M
+Othella/M
+Othello/M
+Othilia/M
+Othilie/M
+Otho/M
+Otis/M
+Ottawa/SM
+Ottilie/M
+Otto
+Ottoman
+Ouagadougou
+Ouija/MS
+Ovid
+Owen/S
+Oxford/SM
+Oxnard
+Oxonian/M
+Oxus
+Oxycontin/M
+Oz
+Ozark/MS
+Ozarks/M
+Ozymandias/M
+Ozzie/M
+Ozzy/M
+P/MN
+PA/M
+PAC/M
+PARC/S
+PASCAL
+PBS/M
+PBX
+PC/SM
+PCB
+PCP/M
+PD
+PDQ
+PDT
+PE
+PET/M
+PFC
+PG
+PIN
+PJ's
+PLO
+PM/SMDG
+PMS/M
+PO
+POW/M
+PP
+PPS
+PR
+PRC/M
+PRO
+PS/M
+PST/M
+PT
+PTA
+PTO
+PVC/M
+PW
+PX
+Pa/M
+Paar/M
+Pablo/M
+Pablum/M
+Pabst/M
+Pace/M
+Pacheco/M
+Pacific/M
+Pacino/M
+Packard/M
+Packston/M
+Paco/M
+Pacorro/M
+Padang
+Paddie/M
+Paddy/M
+Paderewski
+Padget/M
+Padgett/M
+Padilla/M
+Padraic/M
+Padraig/M
+Padriac/M
+Paganini
+Page
+Paglia/M
+Pahlavi
+Paige/M
+Pail/M
+Paine
+Paiute/SM
+Pakistan/M
+Pakistani/SM
+Palembang
+Paleocene/M
+Paleogene
+Paleolithic
+Paleozoic/M
+Palermo/M
+Palestine/M
+Palestinian/SM
+Palestrina
+Paley
+Palikir/M
+Palisades/M
+Pall/M
+Palladio
+Palm/MR
+Palmerston
+Palmolive/M
+Palmyra/M
+Paloma/M
+Palomar/M
+Pam/M
+Pamela/M
+Pamelina/M
+Pamella/M
+Pamirs
+Pammi/M
+Pammie/M
+Pammy/M
+Pampers
+Pan/M
+Panama/SM
+Panamanian/MS
+Panasonic/M
+Panchito/M
+Pancho/M
+Pandora/M
+Pangaea/M
+Pankhurst
+Panmunjom/M
+Pansie/M
+Pansy/M
+Pantagruel
+Pantaloon/M
+Pantheon
+Panza/M
+Paola/M
+Paolina/M
+Paolo/M
+Papagena/M
+Papageno/M
+Paquito/M
+Paracelsus
+Paraclete
+Paradise
+Paraguay/M
+Paraguayan/MS
+Paramaribo/M
+Paramount/M
+Parana/M
+Parcheesi/M
+Pareto
+Paris/M
+Parisian/MS
+Park/SR
+Parke/M
+Parkinson/M
+Parkman
+Parliament
+Parmesan/MS
+Parnassus/MS
+Parnell
+Parr
+Parrish
+Parrnell/M
+Parry
+Parsifal/M
+Parsons
+Parthenon/M
+Parthia/M
+Pasadena/M
+Pascal/SM
+Pascale/M
+Pasquale/M
+Passion/SM
+Passover/MS
+Pasternak
+Pasteur/M
+Pat/N
+Patagonia/M
+Patagonian
+Pate/M
+Patel/M
+Paten/M
+Paterson
+Patience/M
+Patin/M
+Patna
+Paton
+Patric/M
+Patrica/M
+Patrice/M
+Patricia/M
+Patricio/M
+Patrick/M
+Patrizia/M
+Patrizio/M
+Patrizius/M
+Patsy/M
+Patten/M
+Patterson/M
+Patti
+Pattie/M
+Pattin/M
+Patton
+Patty/M
+Paul/GM
+Paula/M
+Paule/M
+Pauletta/M
+Paulette/M
+Pauli
+Paulie/M
+Paulina/M
+Pauline
+Paulita/M
+Paulo/M
+Pauly/M
+Pavarotti
+Pavel/M
+Pavia/M
+Pavla/M
+Pavlov/M
+Pavlova
+Pavlovian
+Pawnee/SM
+Paxon/M
+Paxton
+PayPal/M
+Payne/M
+Payton/M
+Pb/M
+Pd/M
+Peabody/M
+Peace/M
+Peadar/M
+Peale
+Pearce/M
+Pearl/M
+Pearla/M
+Pearle/M
+Pearlie/M
+Pearline/M
+Pearson/M
+Peary
+Pebrook/M
+Pechora
+Peck/M
+Peckinpah/M
+Pecos/M
+Peder/M
+Pedro/M
+Peel/M
+Peg/M
+Pegasus/MS
+Pegeen/M
+Peggi/M
+Peggie/M
+Peggy/M
+Pei
+Peiping/M
+Peirce/M
+Peking/SM
+Pekingese/SM
+Pele/M
+Pelee/M
+Peloponnese/M
+Pembroke/M
+Pena/M
+Penderecki/M
+Penelopa/M
+Penelope/M
+Penn
+Penna
+Penney/M
+Penni/M
+Pennie/M
+Pennington/M
+Pennsylvania/M
+Pennsylvanian/SM
+Penny/M
+Pennzoil/M
+Penrod/M
+Pensacola/M
+Pentagon/M
+Pentateuch/M
+Pentax/M
+Pentecost/SM
+Pentecostal/MS
+Pentecostalism
+Pentium/SM
+Peoria
+Pepe/M
+Pepi/M
+Pepillo/M
+Pepin/M
+Pepita/M
+Pepito/M
+Pepsi/M
+Pepys
+Pequot
+Perceval
+Percheron
+Percival
+Percy
+Perelman/M
+Perez/M
+Peri/M
+Peria/M
+Perice/M
+Periclean
+Pericles
+Perkin/MS
+Perl/SM
+Perla/M
+Perle/M
+Perm/M
+Permalloy/M
+Permian/M
+Pernell/M
+Pernod/M
+Peron
+Perot/M
+Perren/M
+Perri/MR
+Perrine/M
+Perry
+Perseid
+Persephone/M
+Persepolis/M
+Perseus/M
+Pershing
+Persia/M
+Persian/SM
+Persis
+Perth/M
+Peru/M
+Peruvian/MS
+Peshawar
+Pet
+Peta/M
+Petain/M
+Pete/RMZ
+Peter/M
+Petersen/M
+Peterson/M
+Peterus/M
+Petey/M
+Petr/M
+Petra
+Petrarch/M
+Petrina/M
+Petronella/M
+Petronia/M
+Petronilla/M
+Petronille/M
+Petty/M
+Petunia/M
+Peugeot/M
+Peyter/M
+Peyton/M
+Pfc
+Pfizer/M
+PhD/M
+Phaedra
+Phaethon/M
+Phaidra/M
+Phanerozoic
+Pharaoh/M
+Pharaohs
+Pharisaic
+Pharisaical
+Pharisee/MS
+Phebe
+Phedra/M
+Phekda/M
+Phelia/M
+Phelps/M
+Phidias
+Phil/Y
+Philadelphia/M
+Philbert/M
+Philby/M
+Philemon
+Philip/S
+Philipa/M
+Philippa/M
+Philippe/M
+Philippians
+Philippine/SM
+Philis/M
+Philistine
+Phillida/M
+Phillie/M
+Phillip/S
+Phillipa/M
+Phillipe/M
+Phillipp/M
+Phillis/M
+Philly/M
+Philomena/M
+Phineas/M
+Phip/M
+Phipps/M
+Phobos
+Phoebe/M
+Phoenicia/M
+Phoenician/SM
+Phoenix/M
+Photostat/MS
+Photostatted
+Photostatting
+Phrygia/M
+Phylis/M
+Phyllida/M
+Phyllis/M
+Phyllys/M
+Phylys/M
+Pia/M
+Piaf/M
+Piaget/M
+Pianola/M
+Picasso/M
+Piccadilly
+Pickering/M
+Pickett
+Pickford/M
+Pickwick/M
+Pict
+Piedmont/M
+Pier/M
+Pierce/M
+Pierette/M
+Pierre/M
+Pierrette/M
+Pierrot/M
+Pierson/M
+Pieter/M
+Pietra/M
+Pietrek/M
+Pietro/M
+Piggy/M
+Pike/M
+Pilate
+Pilcomayo
+Pilgrim/S
+Pillsbury/M
+Pinatubo/M
+Pincas/M
+Pinchas/M
+Pincus/M
+Pindar/M
+Pinkerton
+Pinocchio/M
+Pinochet/M
+Pinter
+Pinyin
+Piotr/M
+Pip/MR
+Piper/M
+Pippa/M
+Pippin/M
+Pippo/M
+Pippy/M
+Piraeus
+Pirandello
+Pisa
+Pisces/M
+Pisistratus
+Pissaro/M
+Pitcairn/M
+Pitt/S
+Pittman/M
+Pittsburgh/M
+Pius/M
+Pizarro
+Pkwy
+Pl
+Planck
+Plano
+Plantagenet/M
+Plasticine/M
+Plataea/M
+Plath
+Plato/M
+Platonic
+Platonism/M
+Platonist/M
+Platte/M
+Plautus/M
+PlayStation/M
+Playboy/M
+Playtex/M
+Pleiades's
+Pleistocene/M
+Plexiglas/MS
+Pliny
+Pliocene/SM
+Plutarch/M
+Pluto/M
+Plymouth/M
+Pm/M
+Po/M
+Pocahontas/M
+Pocono/SM
+Podgorica
+Podhoretz/M
+Podunk
+Poe
+Pogo/M
+Poincare/M
+Poiret/M
+Poirot/M
+Poisson/M
+Poitier/M
+Pokemon/M
+Pol/Y
+Poland/M
+Polanski/M
+Polaris/M
+Polaroid/MS
+Pole/SM
+Polish/M
+Politburo
+Polk/M
+Pollard/M
+Pollock
+Pollux/M
+Polly/M
+Pollyanna
+Polo/M
+Poltava/M
+Polyhymnia/M
+Polynesia/M
+Polynesian/MS
+Polyphemus
+Pomerania
+Pomeranian/M
+Pomona
+Pompadour
+Pompeian
+Pompeii/M
+Pompey/M
+Ponce
+Pontchartrain
+Pontiac/M
+Pontianak
+Pooh/M
+Poole/M
+Poona
+Pope
+Popeye/M
+Popocatepetl
+Popper/M
+Poppins/M
+Poppy/M
+Popsicle
+Porfirio/M
+Porrima/M
+Porsche/M
+Port/R
+Portia/M
+Portie/M
+Portland/M
+Porto/M
+Portsmouth
+Portugal/M
+Portuguese/M
+Porty/M
+Poseidon/M
+Post/M
+Potemkin
+Potomac/M
+Potsdam
+Pottawatomie/M
+Potter
+Potts/M
+Poul/M
+Pound
+Poussin
+Powell/M
+PowerPoint/M
+Powers
+Powhatan/M
+Poznan/M
+Pr/MN
+Prado/M
+Praetorian
+Prague/M
+Praia/M
+Prakrit
+Pratchett/M
+Pratt/M
+Pravda/M
+Praxiteles
+Preakness/M
+Precambrian/M
+Preminger/M
+Premyslid/M
+Pren/M
+Prensa/M
+Prent/M
+Prentice/M
+Prentiss/M
+Pres
+Presbyterian/MS
+Presbyterianism/SM
+Prescott/M
+Presley
+Preston
+Pretoria/M
+Priam/M
+Pribilof/M
+Price
+Priestley
+Prince/M
+Princeton/M
+Principal
+Principe/M
+Prinz
+Pris
+Prisca/M
+Priscella/M
+Priscilla/M
+Prissie/M
+Private
+Procrustean
+Procrustes/M
+Procter/M
+Procyon/M
+Prof
+Prohibition
+Prokofiev
+Promethean
+Prometheus/M
+Prophets
+Proserpina/M
+Proserpine/M
+Protagoras
+Proterozoic/M
+Protestant/MS
+Protestantism/MS
+Proteus/M
+Proudhon
+Proust/M
+Provencal/MS
+Provence/M
+Proverbs
+Providence/MS
+Provo
+Prozac/MS
+Pru/M
+Prudence/M
+Prudential/M
+Prudi/M
+Prudy/M
+Prue/M
+Pruitt/M
+Prussia/M
+Prussian/MS
+Prut
+Pryce/M
+Pryor/M
+Psalms
+Psalter/MS
+Psyche/M
+Pt/M
+Ptah/M
+Ptolemaic
+Ptolemy/SM
+Pu/M
+Puccini
+Puck
+Puckett/M
+Puebla
+Pueblo
+Puff/M
+Puget/M
+Pugh/M
+Pulaski
+Pulitzer
+Pullman/MS
+Punch
+Punic/M
+Punjab/M
+Punjabi/M
+Purana
+Purcell
+Purdue/M
+Purim/MS
+Purina/M
+Puritan
+Puritanism/SM
+Purus/M
+Pusan/M
+Pusey
+Pushkin
+Pushtu/M
+Putin/M
+Putnam
+Putnem/M
+Puzo/M
+Pvt
+Pygmalion/M
+Pygmy/SM
+Pyle/M
+Pym
+Pynchon/M
+Pyongyang/M
+Pyotr/M
+Pyrenees/M
+Pyrex/MS
+Pyrrhic
+Pythagoras/M
+Pythagorean
+Pythias
+Python/M
+Q
+QB
+QC
+QED
+QM
+QWERTY
+Qaddafi/M
+Qantas/M
+Qatar/M
+Qatari/MS
+Qingdao
+Qiqihar/M
+Qom/M
+Quaalude/M
+Quaker/MS
+Quakerism/SM
+Quasimodo
+Quaternary/M
+Quayle/M
+Que
+Quebec/M
+Quebecois
+Quechua/M
+Queen/S
+Queenie/M
+Queens/M
+Queensland/M
+Quent/M
+Quentin/M
+Querida/M
+Quetzalcoatl/M
+Quezon/M
+Quill/M
+Quillan/M
+Quincey/M
+Quincy/M
+Quinlan/M
+Quinn
+Quint/M
+Quinta/M
+Quintana/M
+Quintilian/M
+Quintilla/M
+Quintin/M
+Quintina/M
+Quinton/M
+Quintus/M
+Quirinal
+Quisling/M
+Quito/M
+Quixote
+Quixotism/M
+Qumran
+Quonset
+R/MG
+RAF/M
+RAM/SM
+RBI
+RC
+RCA/M
+RCMP
+RD
+RDA
+REIT
+REM/SM
+RF
+RFC/S
+RFD
+RI
+RIF
+RIP
+RN/M
+RNA/M
+ROFL
+ROM/M
+ROTC/M
+RP
+RR
+RSFSR
+RSI
+RSV
+RSVP
+RTFM/GSD
+RV/SM
+Ra/M
+Rab/M
+Rabat/M
+Rabbi/M
+Rabelais/M
+Rabelaisian
+Rabi
+Rabin/M
+Rachael/M
+Rachel/M
+Rachele/M
+Rachelle/M
+Rachmaninoff
+Racine/M
+Rad/M
+Radcliffe/M
+Raddie/M
+Raddy/M
+Rae/M
+Raeann/M
+Raf/M
+Rafa/M
+Rafael/M
+Rafaela/M
+Rafaelia/M
+Rafaelita/M
+Rafaellle/M
+Rafaello/M
+Rafe/M
+Raff/M
+Raffaello/M
+Raffarty/M
+Rafferty/M
+Raffles/M
+Rafi/M
+Ragnar/M
+Ragnarok/M
+Rahal/M
+Rahel/M
+Raimondo/M
+Raimund/M
+Raimundo/M
+Raina/M
+Raine/MR
+Rainer/M
+Rainier
+Rakel/M
+Raleigh/M
+Ralf/M
+Ralina/M
+Ralph/M
+Ram
+Rama/M
+Ramada/M
+Ramadan/MS
+Ramakrishna
+Ramanujan/M
+Ramayana
+Rambo/M
+Ramirez/M
+Ramiro/M
+Ramon/M
+Ramona/M
+Ramonda/M
+Ramos
+Ramsay
+Ramses
+Ramsey/M
+Rana/M
+Rance/M
+Rancell/M
+Rand
+Randa/M
+Randal/M
+Randall/M
+Randee/M
+Randell/M
+Randene/M
+Randi/M
+Randie/M
+Randolf/M
+Randolph/M
+Randy/M
+Ranee/M
+Rangoon/M
+Rani/M
+Rania/M
+Ranice/M
+Ranique/M
+Rankin
+Rankine/M
+Ranna/M
+Ransell/M
+Ransom/M
+Raoul/M
+Raphael
+Raphaela/M
+Rapunzel/M
+Raquel/M
+Raquela/M
+Rasalgethi/M
+Rasalhague/M
+Rasia/M
+Rasla/M
+Rasmussen/M
+Rasputin
+Rastaban/M
+Rastafarian/M
+Rather/M
+Ratliff/M
+Raul/M
+Ravel
+Raven/M
+Ravi/M
+Ravid/M
+Raviv/M
+Rawalpindi
+Rawley/M
+Ray
+RayBan/M
+Rayburn/M
+Raychel/M
+Raye/M
+Rayleigh
+Raymond/M
+Raymund/M
+Raymundo/M
+Rayna/M
+Raynard/M
+Raynell/M
+Rayner/M
+Raynor/M
+Rayshell/M
+Rb/M
+Rd
+Re/M
+Rea/M
+Read/GM
+Reade
+Reading/M
+Reagan/M
+Reaganomics/M
+Reagen/M
+Realtor
+Reamonn/M
+Reasoner/M
+Reba/M
+Rebbecca/M
+Rebe/M
+Rebeca/M
+Rebecka/M
+Rebeka/M
+Rebekah
+Rebekkah/M
+Recife/M
+Reconstruction/M
+Redd/M
+Redeemer/M
+Redford/M
+Redgrave/M
+Redmond
+Ree/DSM
+Reeba/M
+Reebok/M
+Reece/M
+Reed/M
+Reena/M
+Reese/M
+Reeta/M
+Reeva/M
+Reeves
+Reformation/MS
+Refugio/M
+Reg/N
+Regan/M
+Regen/M
+Reggi/MS
+Reggie/M
+Reggy/M
+Regina/M
+Reginae
+Reginald/M
+Reginauld/M
+Regine/M
+Regor/M
+Regulus/M
+Rehnquist
+Reich/M
+Reid/R
+Reidar/M
+Reider/M
+Reiko/M
+Reilly/M
+Reina/M
+Reinald/M
+Reinaldo/SM
+Reine/M
+Reinhard/M
+Reinhardt
+Reinhold/M
+Reinold/M
+Reinwald/M
+Rem/M
+Remarque
+Rembrandt/M
+Remington
+Remus/M
+Remy/M
+Rena/M
+Renado/M
+Renae/M
+Renaissance/SM
+Renaldo/M
+Renard/M
+Renascence
+Renata/M
+Renate/M
+Renato/M
+Renaud/M
+Renault/M
+Rene/M
+Renee/M
+Renell/M
+Renelle/M
+Renie/M
+Rennie/M
+Reno/M
+Renoir
+Rep
+Representative
+Republican/SM
+Republicanism
+Requiem/MS
+Resistance
+Restoration/M
+Resurrection
+Reta/M
+Retha/M
+Reube/M
+Reuben
+Reunion
+Reuters
+Reuther/M
+Reuven/M
+Rev
+Reva/M
+Revelation/SM
+Revere
+Reverend/M
+Revkah/M
+Revlon/M
+Rex
+Rey/M
+Reyes
+Reykjavik/M
+Reyna/M
+Reynaldo/M
+Reynard/M
+Reynold/MS
+Rf/M
+Rh/M
+Rhea
+Rheba/M
+Rhee
+Rheingau/M
+Rhenish
+Rheta/M
+Rhett/M
+Rhetta/M
+Rhiamon/M
+Rhianna/M
+Rhiannon/M
+Rhianon/M
+Rhine/M
+Rhineland/M
+Rhoda/M
+Rhodes
+Rhodesia/M
+Rhodesian
+Rhodia/M
+Rhodie/M
+Rhody/M
+Rhona/M
+Rhonda/M
+Rhone/M
+Rhys/M
+Riane/M
+Riannon/M
+Rianon/M
+Ribbentrop
+Ric/M
+Rica/M
+Ricard/M
+Ricardo
+Ricca/M
+Riccardo/M
+Rice
+Rich/M
+Richard/S
+Richardo/M
+Richardson
+Richart/M
+Richelieu/M
+Richie/M
+Richmond/M
+Richmound/M
+Richter
+Richthofen
+Richy/M
+Rici/M
+Rick/M
+Rickard/M
+Rickenbacker/M
+Rickert/M
+Rickey/M
+Ricki/M
+Rickie/M
+Rickover
+Ricky/M
+Rico/M
+Ricoriki/M
+Riddle/M
+Ride
+Riefenstahl/M
+Riel/M
+Riemann/M
+Riesling/MS
+Riga/M
+Rigel/M
+Riggs/M
+Right
+Rigoberto/M
+Rigoletto/M
+Rik/M
+Riki/M
+Rikki/M
+Riley
+Rilke
+Rimbaud
+Rina/M
+Rinaldo/M
+Ring/M
+Ringling/M
+Ringo/M
+Rio/SM
+Riobard/M
+Riordan/M
+Rip/M
+Ripley
+Risa/M
+Risorgimento
+Rita/M
+Ritalin/M
+Ritchie/M
+Ritz/M
+Riva/SM
+Rivalee/M
+Rivera
+Rivers
+Riverside
+Rivi/M
+Riviera/MS
+Rivkah/M
+Rivy/M
+Riyadh/M
+Rizal
+Rn/M
+Roach/M
+Roana/M
+Roanna/M
+Roanne/M
+Roanoke/M
+Roarke/M
+Rob/MZ
+Robb/M
+Robbert/M
+Robbi/M
+Robbie/M
+Robbin/MS
+Robby/M
+Robbyn/M
+Robena/M
+Robenia/M
+Robers/M
+Roberson/M
+Robert/MS
+Roberta/M
+Roberto/M
+Robertson/M
+Robeson
+Robespierre
+Robin/M
+Robina/M
+Robinet/M
+Robinett/M
+Robinetta/M
+Robinette/M
+Robinia/M
+Robinson
+Robitussin/M
+Robles/M
+Robson
+Robt/M
+Roby/M
+Robyn/M
+Rocco/M
+Roch/M
+Rocha/M
+Rochambeau/M
+Roche/M
+Rochell/M
+Rochella/M
+Rochelle/M
+Rochester/M
+Rochette/M
+Rock
+Rockefeller
+Rockey/M
+Rockford
+Rockie/M
+Rockies/M
+Rockne/M
+Rockwell
+Rocky/SM
+Rod/M
+Roda/M
+Rodd/M
+Roddenberry/M
+Roddie/M
+Roddy/M
+Roderic/M
+Roderich/M
+Roderick/M
+Roderigo/M
+Rodge/MZR
+Rodger/M
+Rodi/M
+Rodie/M
+Rodin
+Rodina/M
+Rodney
+Rodolfo/M
+Rodolph/M
+Rodolphe/M
+Rodrick/M
+Rodrigo/M
+Rodriguez/M
+Rodrique/M
+Rodriquez/M
+Roeg/M
+Rog/MRZ
+Rogelio/M
+Rogerio/M
+Roget/M
+Roi/SM
+Rojas/M
+Rolaids/M
+Roland
+Rolando/M
+Roldan/M
+Rolex/M
+Roley/M
+Rolf
+Rolfe/M
+Rolland
+Rollerblade
+Rollie/M
+Rollin/MS
+Rollo
+Rolodex
+Rolph/M
+Rolvaag/M
+Rom
+Roma/M
+Romain/M
+Roman/MS
+Romanesque/MS
+Romania/M
+Romanian/MS
+Romano
+Romanov/M
+Romansh
+Romanticism
+Romany/SM
+Rome/SM
+Romeo
+Romero/M
+Rommel/M
+Romney
+Romola/M
+Romona/M
+Romonda/M
+Romulus/M
+Romy/M
+Ron/M
+Rona/M
+Ronald/M
+Ronalda/M
+Ronda/M
+Ronica/M
+Ronna/M
+Ronni/M
+Ronnica/M
+Ronnie/M
+Ronny/M
+Ronstadt/M
+Rontgen
+Roobbie/M
+Rooney/M
+Roosevelt/M
+Root/M
+Roquefort/SM
+Rora/M
+Rori/M
+Rorie/M
+Rorke/M
+Rorschach
+Rory/M
+Ros
+Rosa/M
+Rosabel/M
+Rosabella/M
+Rosabelle/M
+Rosaleen/M
+Rosales/M
+Rosalia/M
+Rosalie/M
+Rosalind/M
+Rosalinda/M
+Rosalinde/M
+Rosaline/M
+Rosalyn/M
+Rosalynd/M
+Rosamond/M
+Rosamund/M
+Rosana/M
+Rosanna/M
+Rosanne/M
+Rosario
+Rosco/M
+Roscoe/M
+Rose/M
+Roseann/M
+Roseanna/M
+Roseanne/M
+Roseau/M
+Rosecrans/M
+Roselia/M
+Roselin/M
+Roseline/M
+Rosella/M
+Roselle/M
+Rosemaria/M
+Rosemarie/M
+Rosemary/M
+Rosemonde/M
+Rosenberg/M
+Rosendo/M
+Rosene/M
+Rosenzweig/M
+Rosetta
+Rosette/M
+Roshelle/M
+Rosicrucian
+Rosie/M
+Rosina/M
+Rosita/M
+Roslyn/M
+Rosmunda/M
+Ross/M
+Rossetti/M
+Rossie/M
+Rossini/M
+Rossy/M
+Rostand
+Rostov/M
+Rostropovich/M
+Roswell/M
+Rosy/M
+Rotarian/M
+Roth/M
+Rothko
+Rothschild
+Rotterdam/M
+Rottweiler/M
+Rouault
+Rourke/M
+Rousseau/M
+Rouvin/M
+Rover
+Row/MN
+Rowan/M
+Rowe
+Rowen/M
+Rowena/M
+Rowland/M
+Rowling/M
+Rowney/M
+Roxana/M
+Roxane/M
+Roxanna/M
+Roxanne/M
+Roxi/M
+Roxie/M
+Roxine/M
+Roxy/M
+Roy/M
+Royal
+Royall/M
+Royce
+Roz/M
+Rozalie/M
+Rozalin/M
+Rozamond/M
+Rozanna/M
+Rozanne/M
+Roze/M
+Rozele/M
+Rozella/M
+Rozelle/M
+Rozina/M
+Rriocard/M
+Rte
+Ru/MH
+Rubaiyat/M
+Rubbermaid/M
+Rube/M
+Ruben/SM
+Rubetta/M
+Rubi/M
+Rubia/M
+Rubicon/MS
+Rubie/M
+Rubik/M
+Rubin/M
+Rubina/M
+Rubinstein
+Ruby/M
+Ruchbah/M
+Rudd/M
+Ruddie/M
+Ruddy/M
+Rudie/M
+Rudiger/M
+Rudolf
+Rudolfo/M
+Rudolph/M
+Rudy/M
+Rudyard/M
+Rufe/M
+Rufus/M
+Ruggiero/M
+Ruhr/M
+Ruiz/M
+Rukeyser/M
+Rumpelstiltskin/M
+Runnymede
+Runyon
+Rupert/M
+Ruperta/M
+Ruperto/M
+Ruprecht/M
+Rurik
+Rush/M
+Rushdie/M
+Rushmore/M
+Ruskin
+Russ
+Russel/M
+Russell/M
+Russia/M
+Russian/SM
+Russo/M
+Rustbelt/M
+Rustie/M
+Rustin/M
+Rusty/M
+Rutger/MS
+Ruth/M
+Ruthann/M
+Ruthanne/M
+Ruthe/M
+Rutherford
+Ruthi/M
+Ruthie/M
+Ruthy/M
+Rutledge/M
+Rutter/M
+Ruttger/M
+Ruy/M
+Rwanda/MS
+Rwandan/SM
+Rwy
+Rx
+Ry
+Ryan/M
+Ryann/M
+Rycca/M
+Rydberg/M
+Ryder
+Ryley/M
+Ryon/M
+Ryukyu/M
+Ryun/M
+S/MNY
+SA
+SAC
+SALT/M
+SAM/M
+SASE
+SAT
+SBA
+SC/M
+SCSI/M
+SD
+SDI
+SE/M
+SEATO
+SEC
+SF
+SGML/M
+SIDS/M
+SJ
+SK
+SLR
+SO/S
+SOB/M
+SOP/M
+SOS/M
+SOSes
+SPCA
+SPF
+SRO
+SS
+SSA
+SSE/M
+SSS
+SST
+SSW/M
+ST
+STD
+STOL
+SUSE
+SUV
+SW/M
+SWAK
+SWAT
+Saab/M
+Saar
+Saarinen
+Saba/M
+Sabbath/M
+Sabbaths
+Sabik/M
+Sabin
+Sabina/M
+Sabine/M
+Sabra
+Sabre/M
+Sabrina/M
+Sacajawea
+Sacco/M
+Sacha/M
+Sachs/M
+Sacramento/M
+Sada/M
+Sadat
+Saddam/M
+Sadducee
+Sade/M
+Sadella/M
+Sadie/M
+Sadr/M
+Sadye/M
+Safavid
+Safeway/M
+Sagan/M
+Saginaw/M
+Sagittarius/MS
+Sahara/M
+Saharan/M
+Sahel
+Saidee/M
+Saigon/M
+Saiph/M
+Sakai
+Sakha/M
+Sakhalin/M
+Sakharov
+Saki/M
+Saks
+Sal/Y
+Saladin
+Salado
+Salaidh/M
+Salamis
+Salas/M
+Salazar/M
+Saleem/M
+Salem/M
+Salerno/M
+Salim/M
+Salinas
+Salinger
+Salisbury/M
+Salish/M
+Salk
+Sallee/M
+Salli/M
+Sallie/M
+Sallust
+Sally/M
+Sallyann/M
+Sallyanne/M
+Salmon/M
+Saloma/M
+Salome/M
+Salomi/M
+Salomo/M
+Salomon/M
+Salomone/M
+Salonika/M
+Salton/M
+Salvador/M
+Salvadoran/SM
+Salvadorean/MS
+Salvadorian/MS
+Salvatore/M
+Salvidor/M
+Salween/M
+Salyut/M
+Sam
+Samantha/M
+Samar/M
+Samara
+Samaria
+Samaritan/MS
+Samarkand/M
+Sammie/M
+Sammy/M
+Samoa/M
+Samoan/SM
+Samoset/M
+Samoyed/M
+Sampson/M
+Samson
+Samsonite/M
+Samuel
+Samuele/M
+Samuelson/M
+San
+San'a
+Sana/M
+Sanchez/M
+Sancho/M
+Sand
+Sandburg
+Sande/MZR
+Sander/M
+Sanderson/M
+Sandi/M
+Sandie/M
+Sandinista
+Sandor/M
+Sandoval/M
+Sandra/M
+Sandro/M
+Sandy/M
+Sandye/M
+Sanford/M
+Sanforized
+Sang/MR
+Sanhedrin
+Sanka/M
+Sankara/M
+Sanskrit/M
+Sanson/M
+Sansone/M
+Santa
+Santana/M
+Santayana
+Santeria
+Santiago/M
+Santos
+Sapphira
+Sapphire/M
+Sappho/M
+Sapporo/M
+Sara/M
+Saraann/M
+Saracen/MS
+Saragossa/M
+Sarah
+Sarajane/M
+Sarajevo/M
+Saran/M
+Sarasota/M
+Saratov/M
+Sarawak/M
+Sardinia/M
+Saree/M
+Sarena/M
+Sarene/M
+Sarette/M
+Sargasso/M
+Sarge/M
+Sargent
+Sargon/M
+Sari/M
+Sarina/M
+Sarine/M
+Sarita/M
+Sarnoff/M
+Saroyan/M
+Sarto
+Sartre
+Sascha/M
+Sasha/M
+Sashenka/M
+Sask
+Saskatchewan/M
+Saskatoon/M
+Sasquatch/MS
+Sassanian
+Sassoon
+Sat/M
+Satan/M
+Satanism/M
+Satanist/M
+Saturday/MS
+Saturn/M
+Saturnalia/M
+Saudi/MS
+Saudra/M
+Saul/M
+Sauncho/M
+Saunder/MS
+Saunderson/M
+Saundra/M
+Saussure
+Sauternes
+Sauveur/M
+Savage
+Savannah/M
+Savina/M
+Savior/M
+Savonarola
+Savoy
+Savoyard/M
+Saw/M
+Sawyer/M
+Sawyere/M
+Sax
+Saxe/M
+Saxon/MS
+Saxony/M
+Say/MRZ
+Sayer/M
+Sayre/MS
+Sb/M
+Sc/M
+Scan
+Scandinavia/M
+Scandinavian/SM
+Scaramouch
+Scarborough
+Scarface/M
+Scarlatti
+Scarlet/M
+Scarlett/M
+Scheat/M
+Schedar/M
+Scheherazade/M
+Schelling
+Schenectady/M
+Schick/M
+Schiller
+Schindler/M
+Schlesinger/M
+Schliemann
+Schlitz/M
+Schmidt
+Schnabel
+Schnauzer/M
+Schneider/M
+Schoenberg/M
+Schopenhauer
+Schrieffer/M
+Schrodinger/M
+Schroeder/M
+Schubert
+Schultz/M
+Schulz/M
+Schumann
+Schuyler/M
+Schuylkill/M
+Schwartz/M
+Schwarzenegger/M
+Schwarzkopf/M
+Schweitzer
+Schweppes/M
+Schwinger/M
+Schwinn/M
+Scientology/M
+Scipio/M
+Scopes/M
+Scorpio/SM
+Scorpius/M
+Scorsese/M
+Scot/SM
+Scotch/MS
+Scotchman/M
+Scotchmen
+Scotchwoman/M
+Scotchwomen
+Scotland/M
+Scotsman/M
+Scotsmen
+Scotswoman/M
+Scotswomen
+Scott
+Scotti/M
+Scottie/SM
+Scottish/M
+Scottsdale
+Scrabble/MS
+Scranton
+Scriabin
+Scribner/M
+Scripture/SM
+Scrooge
+Scruggs/M
+Scud
+Sculley/M
+Scylla/M
+Scythia
+Scythian
+Se/MH
+Seaborg
+Seagram/M
+SeaMonkey/M
+Seamus/M
+Sean/M
+Seana/M
+Sears/M
+Seattle/M
+Sebastian/M
+Sebastiano/M
+Sebastien/M
+Sec
+Seconal/M
+Secretariat/M
+Secretary
+Seder/MS
+See/M
+Seebeck/M
+Sega/M
+Segovia/M
+Segre/M
+Segundo/M
+Seiko/M
+Seine/M
+Seinfeld/M
+Sejong/M
+Seka/M
+Sela/M
+Selassie/M
+Selby/M
+Selectric/M
+Selena/M
+Selene/M
+Selestina/M
+Seleucid
+Seleucus/M
+Selia/M
+Selie/M
+Selig/M
+Selim/M
+Selina/M
+Selinda/M
+Seline/M
+Seljuk
+Selkirk/M
+Sella/M
+Selle/MZ
+Sellers/M
+Selma/M
+Selznick/M
+Semarang
+Seminole/MS
+Semiramis
+Semite/MS
+Semitic/SM
+Semtex
+Sena/M
+Senate/MS
+Sendai
+Seneca/MS
+Senegal/M
+Senegalese/M
+Senghor
+Senior
+Sennacherib
+Sennett/M
+Sensurround/M
+Seoul/M
+Sephardi
+Sephira/M
+Sepoy/M
+Sept/M
+September/MS
+Septuagint/SM
+Sequoya
+Serb/SM
+Serbia/M
+Serbian/MS
+Serena/M
+Serene
+Serengeti/M
+Serge/M
+Sergeant/M
+Sergei/M
+Sergent/M
+Sergio/M
+Serpens
+Serra/M
+Serrano/M
+Set/M
+Seth/M
+Seton
+Seumas/M
+Seurat
+Seuss
+Sevastopol/M
+Severn
+Severus
+Seville/M
+Sevres
+Seward
+Sextans
+Sexton/M
+Seychelles/M
+Seyfert
+Seymour/M
+Sgt
+Shackleton
+Shadow/M
+Shae/M
+Shaffer/M
+Shaina/M
+Shaine/M
+Shaka/M
+Shaker
+Shakespeare/M
+Shakespearean
+Shalna/M
+Shalne/M
+Shalom/M
+Shamus/M
+Shana/M
+Shanan/M
+Shanda/M
+Shandee/M
+Shandeigh/M
+Shandie/M
+Shandra/M
+Shandy/M
+Shane/M
+Shanghai/M
+Shani/M
+Shanie/M
+Shanna/M
+Shannah/M
+Shannan/M
+Shannen/M
+Shannon
+Shanon/M
+Shanta/M
+Shantee/M
+Shantung
+Shapiro/M
+Shara/M
+Sharai/M
+Shari
+Shari'a
+Sharia/M
+Sharity/M
+Sharl/M
+Sharla/M
+Sharleen/M
+Sharlene/M
+Sharline/M
+Sharon
+Sharona/M
+Sharp/M
+Sharpe/M
+Sharron/M
+Sharyl/M
+Shasta/M
+Shaughn/M
+Shaula/M
+Shaun/M
+Shauna/M
+Shavian/M
+Shavuot/M
+Shaw/M
+Shawn/M
+Shawna/M
+Shawnee/SM
+Shay/M
+Shayla/M
+Shaylah/M
+Shaylyn/M
+Shaylynn/M
+Shayna/M
+Shayne/M
+Shcharansky/M
+Shea/M
+Sheba
+Shebeli/M
+Sheela/M
+Sheelagh/M
+Sheelah/M
+Sheena/M
+Sheeree/M
+Sheetrock/M
+Sheff/M
+Sheffie/M
+Sheffield/M
+Sheffy/M
+Sheila/M
+Sheilah/M
+Shel/MY
+Shela/M
+Shelagh/M
+Shelba/M
+Shelbi/M
+Shelby/M
+Shelden/M
+Sheldon/M
+Shelia/M
+Shell/M
+Shelley
+Shelli/M
+Shellie/M
+Shelly/M
+Shelton/M
+Shem/M
+Shena/M
+Shenandoah
+Shenyang/M
+Sheol
+Shep/M
+Shepard/M
+Shepherd/M
+Sheppard/M
+Shepperd/M
+Sher/M
+Sheratan/M
+Sheraton/M
+Sheree/M
+Sheri/M
+Sheridan
+Sherie/M
+Sherill/M
+Sherilyn/M
+Sherline/M
+Sherlock
+Sherlocke/M
+Sherm/M
+Sherman
+Shermie/M
+Shermy/M
+Sherpa
+Sherri/M
+Sherrie/M
+Sherry/M
+Sherwin/M
+Sherwood
+Sherwynd/M
+Sherye/M
+Sheryl/M
+Shetland/SM
+Shevardnadze/M
+Shevat/M
+Shi'ite
+Shields/M
+Shiite/MS
+Shijiazhuang
+Shikoku/M
+Shillong
+Shiloh/M
+Shina/M
+Shinto/MS
+Shintoism/MS
+Shintoist/MS
+Shir/M
+Shiraz/M
+Shirl/M
+Shirlee/M
+Shirleen/M
+Shirlene/M
+Shirley/M
+Shirline/M
+Shiva/M
+Shockley/M
+Sholom/M
+Short/M
+Shorthorn
+Shoshana/M
+Shoshanna/M
+Shoshone/SM
+Shostakovitch/M
+Shreveport
+Shriner
+Shropshire
+Shula/M
+Shurlock/M
+Shurlocke/M
+Shurwood/M
+Shylock
+Shylockian/M
+Si
+Siam/M
+Siamese/M
+Siana/M
+Sianna/M
+Sib/M
+Sibbie/M
+Sibby/M
+Sibeal/M
+Sibel/M
+Sibelius
+Sibella/M
+Sibelle/M
+Siberia/M
+Siberian/MS
+Sibilla/M
+Sibley/M
+Sibyl
+Sibylla/M
+Sibylle/M
+Sicilian/SM
+Sicily/M
+Sid/M
+Siddhartha/M
+Sidnee/M
+Sidney
+Sidoney/M
+Sidonia/M
+Sidonnie/M
+Siegfried
+Siemens
+Sierpinski/M
+Sierras
+Siffre/M
+Sig
+Sigfrid/M
+Sigfried/M
+Sigismond/M
+Sigismondo/M
+Sigismund
+Sigismundo/M
+Sigmund
+Sigrid/M
+Sigurd
+Sigvard/M
+Sihanouk/M
+Sikh/M
+Sikhism
+Sikhs
+Sikkim
+Sikkimese
+Sikorsky
+Silas/M
+Sile/M
+Sileas/M
+Silesia/M
+Silurian/SM
+Silva/M
+Silvain/M
+Silvan/M
+Silvana/M
+Silvano/M
+Silvanus/M
+Silvester/M
+Silvia/M
+Silvie/M
+Silvio/M
+Sim/SM
+Simenon/M
+Simeon/M
+Simmental
+Simmonds/M
+Simmons/M
+Simon
+Simona/M
+Simone/M
+Simonette/M
+Simonne/M
+Simpson/M
+Sinai/M
+Sinatra
+Sinclair
+Sinclare/M
+Sindbad/M
+Sindee/M
+Sindhi/M
+Singapore/M
+Singaporean/SM
+Singer
+Singleton/M
+Sinhalese/M
+Sinkiang/M
+Siobhan/M
+Sioux/M
+Siouxie/M
+Sir/SM
+Sirius/M
+Sisely/M
+Sisile/M
+Sissie/M
+Sissy/M
+Sistine
+Sisyphean
+Sisyphus/M
+Siusan/M
+Siva/M
+Sivan/M
+Siward/M
+Sjaelland/M
+Skell/M
+Skelly/M
+Skinner/M
+Skip/M
+Skipp/MR
+Skipper/M
+Skippie/M
+Skippy/M
+Skipton/M
+Skopje
+Sky/M
+Skye
+Skylab/M
+Skylar/M
+Skyler/M
+Slackware/M
+Slade/M
+Slashdot/M
+Slater/M
+Slav/SM
+Slavic/M
+Slavonic/M
+Slinky/M
+Sloan
+Sloane/M
+Slocum/M
+Slovak/SM
+Slovakia
+Slovakian
+Slovene/SM
+Slovenia/M
+Slovenian/MS
+Slurpee/M
+Sly/M
+Sm/M
+Small/M
+Smetana
+Smirnoff/M
+Smith
+Smithson
+Smithsonian/M
+Smitty/M
+Smokey/M
+Smolensk
+Smollett
+Smuts
+Smyrna
+Sn/M
+Snake/M
+Snapple/M
+Snead/M
+Snell/M
+Snickers/M
+Snider/M
+Snoopy/M
+Snow
+Snowbelt
+Snyder/M
+Soave/M
+Soc
+Socorro/M
+Socrates/M
+Socratic
+Soddy
+Sodom/M
+Sofia/M
+Sofie/M
+Soho
+Sol/MY
+Solis/M
+Sollie/M
+Solly/M
+Solomon
+Solon
+Solzhenitsyn
+Somali/SM
+Somalia/M
+Somalian/MS
+Somerset
+Somme/M
+Somoza/M
+Son/M
+Sondheim
+Sondra/M
+Songhai/M
+Songhua/M
+Sonia/M
+Sonja/M
+Sonni/M
+Sonnie/M
+Sonnnie/M
+Sonny/M
+Sonora/M
+Sontag/M
+Sony/M
+Sonya/M
+Sophey/M
+Sophi/M
+Sophia
+Sophie/M
+Sophoclean
+Sophocles
+Sophronia/M
+Sopwith/M
+Sorbonne/M
+Sorcha/M
+Sosa/M
+Sosanna/M
+Soto/M
+Souphanouvong/M
+Sousa/M
+South/M
+Southampton
+Southeast/MS
+Southerner/SM
+Southey
+Souths
+Southwest/MS
+Soviet
+Soweto/M
+Soyinka/M
+Soyuz
+Sp
+Spaatz/M
+Spackle
+Spahn/M
+Spain/M
+Spam/M
+Span
+Spanglish
+Spaniard/SM
+Spanish/M
+Sparks
+Sparta/M
+Spartacus
+Spartan/MS
+Spears
+Spence/R
+Spencerian
+Spengler/M
+Spenglerian
+Spense/RM
+Spenser/M
+Spenserian
+Sperry/M
+Sphinx/M
+Spica/M
+Spielberg/M
+Spike/M
+Spillane/M
+Spinoza
+Spinx/M
+Spiro/M
+Spirograph/M
+Spitsbergen/M
+Spitz/M
+Spock
+Spokane
+Springfield/M
+Springsteen/M
+Sprint/M
+Sprite/M
+Sputnik
+Sq
+Squanto
+Squibb/M
+Sr/M
+Srinagar
+Srivijaya/M
+St
+Sta
+Stace/M
+Stacee/M
+Stacey/M
+Staci/M
+Stacia/M
+Stacie/M
+Stacy/M
+Stael/M
+Stafani/M
+Staffard/M
+Stafford
+Staford/M
+StairMaster
+Stalin/M
+Stalingrad/M
+Stalinist
+Stallone/M
+Stamford
+Stan/MY
+Standford/M
+Standish
+Stanfield/M
+Stanford/M
+Stanislas/M
+Stanislaus/M
+Stanislavsky
+Stanislaw/M
+Stanleigh/M
+Stanley
+Stanly/M
+Stanton
+Stanwood/M
+Staples/M
+Star/M
+Starbucks
+Stark
+Starkey/M
+Starla/M
+Starlene/M
+Starlin/M
+Starr/M
+Staten/M
+States
+Stavro/MS
+Ste
+Steadicam
+Stearn/M
+Stearne/M
+Steele
+Stefa/M
+Stefan/M
+Stefania/M
+Stefanie/M
+Stefano/M
+Steffane/M
+Steffen/M
+Steffi/M
+Steffie/M
+Stein/R
+Steinbeck
+Steinem/M
+Steinmetz/M
+Steinway/M
+Stella
+Stendhal
+Stengel/M
+Stepha/M
+Stephan/M
+Stephana/M
+Stephani/M
+Stephanie/M
+Stephannie/M
+Stephanus/M
+Stephen/S
+Stephenie/M
+Stephenson
+Stephi/M
+Stephie/M
+Stephine/M
+Sterling/M
+Stern
+Sterne/M
+Sterno
+Stesha/M
+Stetson/M
+Steuben/M
+Stevana/M
+Steve/M
+Steven/MS
+Stevena/M
+Stevenson
+Stevie/M
+Stevy/M
+Steward/M
+Stewart/M
+Stieglitz/M
+Stillman/M
+Stillmann/M
+Stilton/SM
+Stimson/M
+Stine/M
+Stinky/M
+Stirling
+Stockhausen/M
+Stockholm/M
+Stockton
+Stoddard/M
+Stoic/SM
+Stoicism/MS
+Stokes/M
+Stolichnaya/M
+Stolypin/M
+Stone
+Stonehenge
+Stoppard/M
+Storm/M
+Stormi/M
+Stormie/M
+Stormy/M
+Stout
+Stowe
+Strabo/M
+Stradivari
+Stradivarius
+Strasbourg
+Strauss
+Stravinsky/M
+Streisand/M
+Strickland/M
+Strindberg
+Stromboli
+Strong/M
+Stu/M
+Stuart/MS
+Studebaker/M
+Stuttgart/M
+Stuyvesant
+Stygian
+Styrofoam/SM
+Styron/M
+Styx/M
+Suarez/M
+Subaru/M
+Sucre
+Sucrets/M
+Sudan/M
+Sudanese/M
+Sudetenland/M
+Sudra/M
+Sue
+Suellen/M
+Suetonius
+Suez
+Suffolk
+Sufi
+Sufism
+Suharto/M
+Sui/M
+Sukarno
+Sukey/M
+Suki/M
+Sukkot
+Sula/M
+Sulawesi/M
+Suleiman/M
+Sulla/M
+Sullivan/M
+Sully
+Sumatra/M
+Sumatran/SM
+Sumeria/M
+Sumerian/SM
+Summer/MS
+Sumner/M
+Sumter
+Sun/SM
+Sunbeam/M
+Sunbelt/M
+Sunbird/M
+Sundanese/M
+Sundas
+Sunday/MS
+Sung
+Sunkist/M
+Sunni/SM
+Sunnite/MS
+Sunny/M
+Sunnyvale
+Sunshine/M
+Superbowl/M
+Superfund/M
+Superglue/M
+Superior
+Superman/M
+Supt
+Surabaya
+Surat
+Suriname/M
+Surinamese
+Surya/M
+Susan/M
+Susana/M
+Susanetta/M
+Susann/M
+Susanna
+Susannah/M
+Susanne/M
+Susette/M
+Susi/M
+Susie/M
+Susquehanna/M
+Sussex
+Susy/M
+Sutherlan/M
+Sutherland/M
+Sutton/M
+Suva/M
+Suwanee/M
+Suzann/M
+Suzanna/M
+Suzanne/M
+Suzette/M
+Suzhou/M
+Suzi/M
+Suzie/M
+Suzuki/M
+Suzy/M
+Svalbard/M
+Sven/M
+Svend/M
+Svengali
+Sverdlovsk
+Swahili/SM
+Swammerdam/M
+Swanee
+Swansea/M
+Swanson/M
+Swazi/SM
+Swaziland/M
+Swed/N
+Swede/SM
+Sweden/M
+Swedenborg/M
+Swedish/M
+Sweeney/M
+Sweet
+Swen/M
+Swift/M
+Swinburne/M
+Swiss/MS
+Swissair/M
+Switz
+Switzerland/M
+Sybil/M
+Sybila/M
+Sybilla/M
+Sybille/M
+Sybyl/M
+Syd/M
+Sydel/M
+Sydelle/M
+Sydney/M
+Sykes/M
+Sylas/M
+Sylvan/M
+Sylvester/M
+Sylvia/M
+Sylvie/M
+Syman/M
+Symon/M
+Synge
+Syracuse/M
+Syria/M
+Syriac
+Syrian/MS
+Szilard/M
+Szymborska/M
+T'ang
+T/MDG
+TA
+TB/M
+TBA
+TD
+TDD
+TEFL
+TELNET/S
+TELNETTed
+TELNETTing
+TESL
+TESOL
+TEirtza/M
+TGIF
+THC
+TKO/M
+TLC/M
+TM
+TN
+TNT/M
+TOEFL
+TQM
+TV/SM
+TVA
+TWA/M
+TWX
+TX
+Ta/M
+Tab/MR
+Tabasco/SM
+Tabatha/M
+Tabb/M
+Tabbatha/M
+Tabbi/M
+Tabbie/M
+Tabbitha/M
+Tabby/M
+Taber/M
+Tabernacle/MS
+Tabina/M
+Tabitha/M
+Tabor
+Tabriz/MS
+Tacitus
+Tacoma/M
+Tad/M
+Tadd/M
+Taddeo/M
+Taddeusz/M
+Tadeas/M
+Tadeo/M
+Tades
+Tadio/M
+Tadzhik/M
+Taegu/M
+Taejon
+Taffy/M
+Taft/M
+Tagalog/SM
+Tagore
+Tagus/M
+Tahiti/M
+Tahitian/MS
+Tahoe
+Taichung/M
+Tailor/M
+Tainan
+Taine/M
+Taipei/M
+Taiping
+Tait/M
+Taite/M
+Taiwan/M
+Taiwanese/M
+Taiyuan
+Tajikistan/M
+Taklamakan/M
+Talbert/M
+Talbot
+Talia/M
+Taliban/M
+Taliesin
+Tallahassee/M
+Tallchief/M
+Talley/M
+Talleyrand/M
+Tallia/M
+Tallie/M
+Tallinn/M
+Tallou/M
+Tallulah/M
+Tally/M
+Talmud/MS
+Talmudic
+Talmudist
+Talya/M
+Talyah/M
+Tam/M
+Tamar/M
+Tamara/M
+Tamarah/M
+Tamarra/M
+Tamas
+Tameka/M
+Tamera/M
+Tamerlane/M
+Tami/M
+Tamika/M
+Tamiko/M
+Tamil/MS
+Tamma/M
+Tammany/M
+Tammara/M
+Tammi/M
+Tammie/M
+Tammuz/M
+Tammy/M
+Tampa/M
+Tampax/M
+Tamqrah/M
+Tamra/M
+Tamworth
+Tan
+Tana
+Tancred
+Tandi/M
+Tandie/M
+Tandy/M
+Taney
+Tanganyika/M
+Tangier/M
+Tangshan
+Tanhya/M
+Tani/M
+Tania/M
+Tanisha/M
+Tanitansy/M
+Tann/MR
+Tanner/M
+Tanney/M
+Tannhauser/M
+Tannie/M
+Tanny/M
+Tansy/M
+Tantalus/M
+Tanya/M
+Tanzania/M
+Tanzanian/SM
+Tao/M
+Taoism/MS
+Taoist/MS
+Tara/M
+Tarah/M
+Tarawa/M
+Tarazed/M
+Tarbell/M
+Target/M
+Tarim
+Tarkenton/M
+Tarkington
+Tarra/M
+Tarrah/M
+Tarrance/M
+Tartary
+Tartuffe
+Taryn/M
+Tarzan/M
+Tasha/M
+Tashkent/M
+Tasia/M
+Tasman
+Tasmania/M
+Tasmanian
+Tass
+Tatar/MS
+Tate
+Tatiana/M
+Tatiania/M
+Tatum
+Taurus/MS
+Tawney
+Tawnya/M
+Tawsha/M
+Taylor/M
+Tb/M
+Tbilisi/M
+Tc/M
+Tchaikovsky
+Te/M
+TeX
+TeXes
+Teador/M
+Teasdale/M
+Technicolor
+Tecumseh/M
+Ted/M
+Tedd/M
+Tedda/M
+Teddi/M
+Teddie/M
+Teddy/M
+Tedi/M
+Tedie/M
+Tedman/M
+Tedmund/M
+Tedra/M
+Teena/M
+Teflon/MS
+Tegucigalpa/M
+Tehran
+TelePrompTer
+TelePrompter
+Telemachus
+Telemann
+Teletype
+Tell/MR
+Telugu/M
+Temp/M
+Tempe
+Templar/M
+Temple/M
+Templeton/M
+Tenn
+Tennessean/SM
+Tennessee/M
+Tennyson
+Tenochtitlan/M
+Teodoor/M
+Teodor/M
+Teodora/M
+Teodorico/M
+Teodoro/M
+Teotihuacan/M
+Tera/M
+Terence
+Terencio/M
+Teresa/M
+Terese/M
+Tereshkova
+Teresina
+Teresita/M
+Teressa/M
+Teri/M
+Teriann/M
+Terkel/M
+Terpsichore/M
+Terr/M
+Terra/M
+Terran/M
+Terrance/M
+Terrel/M
+Terrell/M
+Terrence/M
+Terri/M
+Terrie/M
+Terrijo/M
+Terrill/M
+Terry
+Terrye/M
+Tersina/M
+Tertiary/M
+Terza/M
+Tesla
+Tess
+Tessa/M
+Tessi/M
+Tessie/M
+Tessy/M
+Tet/M
+Tethys/M
+Tetons
+Teuton/MS
+Teutonic
+Tevet/M
+Tex
+Texaco/M
+Texan/MS
+Texas/M
+Th/M
+Thacher/M
+Thackeray
+Thad/M
+Thaddeus
+Thaddus/M
+Thadeus/M
+Thai/SM
+Thailand/M
+Thain/M
+Thaine/M
+Thales
+Thalia/M
+Thames/M
+Thane/M
+Thanh/M
+Thanksgiving/SM
+Thant
+Thar/M
+Tharp/M
+Thatch/MR
+Thaxter/M
+Thayne/M
+Thea/M
+Theadora/M
+Thebault/M
+Thebes/M
+Theda/M
+Thedric/M
+Thedrick/M
+Theiler/M
+Thekla/M
+Thelma/M
+Themistocles
+Theo/M
+Theobald/M
+Theocritus
+Theodor/M
+Theodora
+Theodore/M
+Theodoric/M
+Theodosia/M
+Theodosius/M
+Theosophy
+Theravada
+Theresa
+Therese/M
+Theresina/M
+Theresita/M
+Theressa/M
+Therine/M
+Thermopylae/M
+Thermos
+Theron/M
+Theseus/M
+Thespian
+Thespis/M
+Thessalonian/S
+Thessaloniki/M
+Thessaly/M
+Thia/M
+Thibaud/M
+Thibaut/M
+Thieu/M
+Thimbu
+Thimphu
+Thom/M
+Thoma/SM
+Thomas
+Thomasa/M
+Thomasin/M
+Thomasina/M
+Thomasine/M
+Thomism/M
+Thomistic
+Thompson
+Thomson
+Thor/M
+Thorazine/M
+Thoreau/M
+Thorin/M
+Thorn
+Thorndike
+Thornie/M
+Thornton/M
+Thorny/M
+Thoroughbred
+Thorpe
+Thorstein/M
+Thorsten/M
+Thorvald/M
+Thoth/M
+Thrace/M
+Thracian/M
+Thu
+Thucydides/M
+Thule/M
+Thunderbird/M
+Thur/S
+Thurber
+Thurman/M
+Thurmond/M
+Thursday/SM
+Thurstan/M
+Thurston/M
+Thutmose/M
+Ti/M
+Tia/M
+Tianjin/M
+Tiber/M
+Tiberius
+Tibet/M
+Tibetan/MS
+Tibold/M
+Ticketmaster/M
+Ticonderoga
+Tide/M
+Tiebold/M
+Tiebout/M
+Tiena/M
+Tienanmen/M
+Tierney/M
+Tiertza/M
+Tiff/M
+Tiffani/M
+Tiffanie/M
+Tiffany
+Tiffi/M
+Tiffie/M
+Tiffy/M
+Tigris/M
+Tijuana/M
+Tilda/M
+Tildi/M
+Tildie/M
+Tildy/M
+Tiler/M
+Tillich
+Tillie/M
+Tillman/M
+Tilly/M
+Tilsit
+Tim/M
+Timbuktu/M
+Timex/M
+Timi/M
+Timmi/M
+Timmie/M
+Timmy/M
+Timofei/M
+Timon/M
+Timoteo/M
+Timothea/M
+Timothee/M
+Timotheus/M
+Timothy
+Timur/M
+Timurid/M
+Tina/M
+Tine/M
+Ting/M
+Tinkerbell/M
+Tinkertoy
+Tinseltown/M
+Tintoretto
+Tiphani/M
+Tiphanie/M
+Tiphany/M
+Tippecanoe/M
+Tipperary
+Tirane
+Tiresias/M
+Tirol/M
+Tirolean
+Tirrell/M
+Tish/M
+Tisha/M
+Tishri/M
+Titan/SM
+Titania
+Titanic
+Titian/M
+Titicaca
+Tito/SM
+Titus
+Tl/M
+Tlaloc/M
+Tlingit/M
+Tm/M
+Tobago/M
+Tobe/M
+Tobey
+Tobi/M
+Tobiah/M
+Tobias/M
+Tobie/M
+Tobin/M
+Tobit
+Toby
+Tobye/M
+Tocantins
+Tocqueville
+Tod/M
+Todd
+Toddie/M
+Toddy/M
+Togo/M
+Togolese/M
+Toiboid/M
+Toinette/M
+Tojo
+Tokay/M
+Tokugawa
+Tokyo/M
+Tokyoite
+Toledo/MS
+Tolkien
+Tolstoy/M
+Toltec
+Tolyatti/M
+Tom/M
+Toma/SM
+Tomasina/M
+Tomasine/M
+Tomaso/M
+Tombaugh/M
+Tome/M
+Tomi/M
+Tomkin/M
+Tomlin/M
+Tommi/M
+Tommie/M
+Tommy
+Tompkins/M
+Tomsk
+Tonga/M
+Tongan/MS
+Toni/M
+Tonia/M
+Tonie/M
+Tonnie/M
+Tonto/M
+Tony
+Tonya/M
+Tonye/M
+Tootsie/M
+Topeka/M
+Topsy/M
+Torah/M
+Torahs
+Tore/M
+Torey/M
+Tori/M
+Torie/M
+Torin/M
+Toronto/M
+Torquemada
+Torr/MX
+Torrance
+Torre/SM
+Torrence/M
+Torrey/M
+Torricelli/M
+Torrie/M
+Torrin/M
+Torry/M
+Tortola
+Tortuga
+Torvalds/M
+Tory/SM
+Tosca/M
+Toscanini
+Toshiba/M
+Toto/M
+Toulouse
+Tova/M
+Tove/M
+Town/M
+Townes
+Towney/M
+Townie/M
+Townsend/M
+Towny/M
+Toynbee/M
+Toyoda/M
+Toyota/M
+Trace/M
+Tracee/M
+Tracey/M
+Traci/M
+Tracie/M
+Tracy/M
+Trafalgar/M
+Trailways/M
+Trajan
+Tran/M
+Transcaucasia
+Transvaal/M
+Transylvania
+Trappist/SM
+Traver/MS
+Travis/M
+Travolta/M
+Travus/M
+Treasury/SM
+Treblinka
+Trefor/M
+Trekkie/M
+Tremain/M
+Tremaine/M
+Tremayne/M
+Trenna/M
+Trent/M
+Trenton/M
+Tresa/M
+Trescha/M
+Tressa/M
+Trev/MR
+Trevar/M
+Trevelyan
+Trever/M
+Trevino/M
+Trevor/M
+Trey/M
+Triangulum/M
+Triassic/M
+Tricia/M
+Trident/M
+Trieste
+Trimurti/M
+Trina/M
+Trinidad/M
+Trinidadian/MS
+Trinity/SM
+Trip/M
+Tripitaka
+Tripoli/M
+Tripp/M
+Trippe/M
+Tris
+Trish/M
+Trisha/M
+Trista/M
+Tristam/M
+Tristan/M
+Triton/M
+Trix/M
+Trixi/M
+Trixie/M
+Trixy/M
+Trobriand/M
+Trojan/MS
+Trollope
+Trondheim/M
+Tropicana/M
+Trotsky
+Troy/M
+Troyes
+Trstram/M
+Truckee/M
+Truda/M
+Trude/M
+Trudeau
+Trudey/M
+Trudi/M
+Trudie/M
+Trudy/M
+Trueman/M
+Truffaut/M
+Trujillo
+Trula/M
+Trumaine/M
+Truman/M
+Trumann/M
+Trumbull/M
+Trump/M
+Truth
+Tsimshian/M
+Tsiolkovsky/M
+Tsitsihar/M
+Tswana/M
+Tu
+Tuamotu/M
+Tuareg/M
+Tubman
+Tuck/R
+Tucker/M
+Tuckie/M
+Tucky/M
+Tucson/M
+Tucuman/M
+Tudor/SM
+Tue/S
+Tues/M
+Tuesday/MS
+Tulane/M
+Tull/M
+Tulley/M
+Tully/M
+Tulsa/M
+Tums/M
+Tungus/M
+Tunguska/M
+Tunis/M
+Tunisia/M
+Tunisian/MS
+Tunney/M
+Tupi/M
+Tupperware
+Tupungato/M
+Turgenev
+Turin/M
+Turing/M
+Turk/SM
+Turkestan/M
+Turkey/M
+Turkic/MS
+Turkish/M
+Turkmenistan/M
+Turner
+Turpin
+Tuscaloosa/M
+Tuscan/M
+Tuscany/M
+Tuscarora/MS
+Tuscon/M
+Tuskegee/M
+Tussuad/M
+Tut/M
+Tutankhamen
+Tutsi
+Tutu/M
+Tuvalu/M
+Tuvaluan
+Twain
+Tweed
+Tweedledee/M
+Tweedledum/M
+Twila/M
+Twinkies
+Twp
+Twyla/M
+Ty/M
+Tybalt/M
+Tybi/M
+Tybie/M
+Tycho
+Tye/M
+Tylenol/M
+Tyler/M
+Tymon/M
+Tymothy/M
+Tynan/M
+Tyndale
+Tyndall
+Tyne/M
+Tyre
+Tyree/M
+Tyrolean
+Tyrone
+Tyrus/M
+Tyson/M
+U/M
+UAR
+UAW
+UCLA/M
+UFO/SM
+UHF/M
+UK/M
+UL
+UN/M
+UNESCO/M
+UNICEF/M
+UNIX/M
+UPC
+UPI
+UPS
+URL/S
+US/M
+USA/M
+USAF
+USCG
+USDA
+USIA
+USMC
+USN
+USO
+USP
+USPS
+USS
+USSR/M
+UT/M
+UV/M
+Ubangi
+Ucayali
+Uccello/M
+Udale/M
+Udall
+Udell/M
+Ufa/M
+Uganda/M
+Ugandan/MS
+Ugo/M
+Uighur/M
+Ujungpandang/M
+Ukraine/M
+Ukrainian/SM
+Ula/M
+Ulberto/M
+Ulick/M
+Ulises/M
+Ulla/M
+Ulric/M
+Ulrica/M
+Ulrich/M
+Ulrick/M
+Ulrika/M
+Ulrikaumeko/M
+Ulrike/M
+Ulster/M
+Ultrasuede/M
+Ulyanovsk
+Ulysses/M
+Umberto/M
+Umbriel/M
+Umeko/M
+Una/M
+Underwood/M
+Ungava
+Unicode/M
+Unilever/M
+Union/SM
+Unionist
+Uniroyal/M
+Unitarian/MS
+Unitarianism/MS
+Unitas/M
+Unix/S
+Unukalhai/M
+Upanishads
+Updike
+Upjohn/M
+Upton/M
+Ur
+Ural/S
+Urania/M
+Uranus/M
+Urbain/M
+Urban/M
+Urbano/M
+Urbanus/M
+Urdu/M
+Urey
+Uri/SM
+Uriah
+Uriel
+Urquhart
+Ursa/M
+Ursala/M
+Ursola/M
+Urson/M
+Ursula
+Ursulina/M
+Ursuline
+Uruguay/M
+Uruguayan/MS
+Urumqi
+Usenet/MS
+Ustinov
+Uta/M
+Utah/M
+Utahan/MS
+Ute/SM
+Utopia/SM
+Utopian/SM
+Utrecht/M
+Utrillo/M
+Uzbek/M
+Uzbekistan/M
+Uzi/SM
+V/M
+VA
+VAT/M
+VAX
+VAXes
+VCR/M
+VD/M
+VDT
+VDU
+VF
+VFW/M
+VG
+VGA
+VHF/M
+VHS
+VI/M
+VIP/SM
+VISTA
+VJ
+VLF/M
+VOA
+VP
+VT
+VTOL
+Va
+Vachel/M
+Vaclav/M
+Vader/M
+Vaduz/M
+Vail/M
+Val/MY
+Valaree/M
+Valaria/M
+Valarie/M
+Valdemar/M
+Valdez/M
+Vale/M
+Valeda/M
+Valencia/SM
+Valene/M
+Valenka/M
+Valenti/M
+Valentia/M
+Valentijn/M
+Valentin/M
+Valentina/M
+Valentine/M
+Valentino
+Valenzuela/M
+Valera
+Valeria/M
+Valerian/M
+Valerie/M
+Valery
+Valerye/M
+Valhalla/M
+Valida/M
+Valina/M
+Valium/MS
+Valkyrie/SM
+Valle/M
+Vallejo
+Valletta/M
+Valli/M
+Vallie/M
+Vally/M
+Valma/M
+Valois
+Valparaiso/M
+Valry/M
+Valvoline/M
+Van
+Vance
+Vancouver/M
+Vanda/M
+Vandal/MS
+Vanderbilt
+Vandyke
+Vanessa/M
+Vang/M
+Vania/M
+Vanna/M
+Vanni/M
+Vannie/M
+Vanny/M
+Vanuatu/M
+Vanya/M
+Vanzetti/M
+Varanasi
+Varese
+Vargas
+Vaseline/SM
+Vasili/MS
+Vasily/M
+Vasquez/M
+Vassar/M
+Vassili/M
+Vassily/M
+Vatican/M
+Vauban
+Vaughan
+Vaughn/M
+Vazquez/M
+Veblen/M
+Veda/SM
+Vedanta
+Vega/SM
+Vegemite/M
+Vela
+Velasquez/M
+Velazquez
+Velcro/MS
+Velez/M
+Velma/M
+Velveeta/M
+Velvet/M
+Venetian/SM
+Venezuela/M
+Venezuelan/SM
+Venice/M
+Venita/M
+Venn/M
+Ventolin/M
+Venus/MS
+Venusian
+Vera/M
+Veracruz/M
+Veradis
+Verde
+Verdi
+Verdun/M
+Vere/M
+Verena/M
+Verene/M
+Verge/M
+Veriee/M
+Verile/M
+Verina/M
+Verine/M
+Verizon/M
+Verla/M
+Verlaine/M
+Vermeer
+Vermont/ZMR
+Vermonter/M
+Vern/MN
+Verna/M
+Verne
+Vernen/M
+Verney/M
+Vernice/M
+Vernon/M
+Vernor/M
+Verona/M
+Veronese
+Veronica
+Veronika/M
+Veronike/M
+Veronique
+Versailles/M
+Vesalius/M
+Vespasian
+Vespucci/M
+Vesta/M
+Vesuvius/M
+Vevay/M
+Vi/M
+Viacom/M
+Viagra
+Vic
+Vicente/M
+Vichy
+Vick/M
+Vicki/M
+Vickie/M
+Vicksburg/M
+Vicky
+Victoir/M
+Victor/M
+Victoria/M
+Victorian/MS
+Victorianism
+Victrola/M
+Vida/M
+Vidal/M
+Vidovic/M
+Vidovik/M
+Vienna/M
+Viennese
+Vientiane/M
+Vietcong
+Vietminh
+Vietnam/M
+Vietnamese/M
+Vijayanagar/M
+Vijayawada/M
+Viki/M
+Viking/MS
+Vikki/M
+Vikky/M
+Vila/M
+Vilhelmina/M
+Villa
+Villarreal/M
+Villon
+Vilma/M
+Vilnius/M
+Vilyui/M
+Vin/M
+Vina/M
+Vince/M
+Vincent/MS
+Vincenty/M
+Vincenz/M
+Vindemiatrix/M
+Vinita/M
+Vinni/M
+Vinnie/M
+Vinny/M
+Vinson/M
+Viola/M
+Violante/M
+Viole/M
+Violet/M
+Violetta/M
+Violette/M
+Virge/M
+Virgie/M
+Virgil/M
+Virgilio/M
+Virgina/M
+Virginia/M
+Virginian/SM
+Virginie/M
+Virgo/SM
+Visa/M
+Visayans
+Vishnu/M
+Visigoth/M
+Visigoths
+Vistula/M
+Vita/M
+Vite/M
+Vitia/M
+Vitim/M
+Vito/M
+Vitoria
+Vittoria/M
+Vittorio/M
+Vitus/M
+Viv/M
+Viva/M
+Vivaldi
+Vivekananda/M
+Vivi/MN
+Vivia/M
+Vivian
+Viviana/M
+Vivianna/M
+Vivianne/M
+Vivie/M
+Vivien/M
+Viviene/M
+Vivienne/M
+Viviyan/M
+Vivyan/M
+Vivyanne/M
+Vlad/M
+Vladamir/M
+Vladimir
+Vladivostok/M
+Vlasic/M
+Vogue/M
+Volcker/M
+Volga/M
+Volgograd/M
+Volkswagen/M
+Volstead/M
+Volta
+Voltaire/M
+Volvo/M
+Von/M
+Vonda/M
+Vonnegut/M
+Vonni/M
+Vonnie/M
+Vonny/M
+Voronezh
+Vorster/M
+Voyager/M
+Vt
+Vulcan/M
+Vulg
+Vulgate/SM
+Vyky/M
+W/MDT
+WA
+WAC
+WASP/M
+WATS/M
+WC
+WHO/M
+WI
+WNW/M
+WP
+WSW/M
+WV
+WW
+WWI
+WWII
+WWW/M
+WY
+WYSIWYG
+Wabash/M
+Wac
+Waco
+Wade
+Wadsworth/M
+Wagner/M
+Wagnerian
+Wahhabi
+Waikiki
+Wain/M
+Wainwright/M
+Wait/MR
+Waite/M
+Waiter/M
+Wake/M
+Wakefield
+Waksman
+Wald/MN
+Waldemar/M
+Walden/M
+Waldensian
+Waldheim
+Waldo/M
+Waldon/M
+Waldorf/M
+Wales/M
+Walesa
+Walgreen/M
+Walker/M
+Walkman
+Wall/SMR
+Wallace
+Wallache/M
+Wallas/M
+Wallenstein
+Wallie/M
+Wallis
+Walliw/M
+Walloon
+Wally/M
+Walpole/M
+Walpurgisnacht
+Walsh/M
+Walt/MRZ
+Walther/M
+Walton/M
+Waly/M
+Wanamaker/M
+Wanda/M
+Wandie/M
+Wandis/M
+Waneta/M
+Wang/M
+Wanids/M
+Wankel/M
+Ward/N
+Warde/M
+Ware/MG
+Warhol
+Waring/M
+Warner/M
+Warren
+Warsaw/M
+Warwick
+Wasatch/M
+Wash
+Washington/M
+Washingtonian/SM
+Wassermann
+Wat/MZ
+Waterbury
+Waterford
+Watergate
+Waterloo/MS
+Waters/M
+Watkins
+Watson
+Watt/S
+Watteau
+Watusi
+Waugh
+Wave
+Waverley/M
+Waverly/M
+Way/M
+Waylan/M
+Wayland/M
+Waylen/M
+Waylin/M
+Waylon/M
+Wayne
+Weaver/M
+Web/R
+Webb
+Webern/M
+Webster/MS
+Wed/M
+Weddell/M
+Wedgwood
+Wednesday/MS
+Weeks/M
+Wehrmacht
+Wei/M
+Weidar/M
+Weider/M
+Weierstrass/M
+Weill/M
+Weinberg/M
+Weiss/M
+Weizmann
+Welbie/M
+Welby/M
+Weldon/M
+Welland/M
+Weller/M
+Welles
+Wellington/SM
+Wells
+Welsh/M
+Welshman/M
+Welshmen
+Welshwoman
+Wenda/M
+Wendall/M
+Wendel/M
+Wendeline/M
+Wendell/M
+Wendi/M
+Wendie/M
+Wendy/M
+Wendye/M
+Wenona/M
+Wenonah/M
+Werner/M
+Wernher/M
+Wes
+Wesak/M
+Wesley/M
+Wesleyan/M
+Wessex
+Wesson/M
+West/SM
+Westbrook/M
+Westbrooke/M
+Western/MRS
+Westinghouse
+Westleigh/M
+Westley/M
+Westminster
+Weston/M
+Westphalia
+Weyden/M
+Weylin/M
+Wezen/M
+Wharton
+Wheaties/M
+Wheatstone/M
+Wheeler/M
+Wheeling/M
+Whig/SM
+Whipple/M
+Whirlpool/M
+Whistler
+Whit
+Whitaker
+Whitby/M
+White/SM
+Whitefield/M
+Whitehall
+Whitehead
+Whitehorse/M
+Whiteley/M
+Whitfield/M
+Whitley/M
+Whitman
+Whitney/M
+Whitsunday/SM
+Whittaker/M
+Whittier
+Wiatt/M
+Wicca
+Wichita/M
+Wiemar/M
+Wiesel/M
+Wiesenthal/M
+Wiggins
+Wigner/M
+Wikipedia/M
+Wilberforce
+Wilbert/M
+Wilbur/M
+Wilburn/M
+Wilburt/M
+Wilcox/M
+Wilda/M
+Wilde/R
+Wilden/M
+Wildon/M
+Wileen/M
+Wilek/M
+Wiley/M
+Wilford/M
+Wilfred/M
+Wilfredo/M
+Wilfrid/M
+Wilhelm/M
+Wilhelmina/M
+Wilhelmine
+Wilie/M
+Wilkerson/M
+Wilkes
+Wilkins
+Wilkinson/M
+Will/M
+Willa/M
+Willabella/M
+Willamette/M
+Willamina/M
+Willard
+Willdon/M
+Willem/M
+Willemstad
+Willetta/M
+Willette/M
+Willey/M
+Willi/MS
+William/S
+Williamson
+Willie/M
+Willow/M
+Willy/M
+Willyt/M
+Wilma/M
+Wilmar/M
+Wilmer/M
+Wilmette/M
+Wilmington/M
+Wilona/M
+Wilone/M
+Wilow/M
+Wilson/M
+Wilsonian
+Wilt/M
+Wilton/M
+Wimbledon/M
+Wimsey/M
+Win/M
+Winchell/M
+Winchester/S
+Windbreaker
+Windex/M
+Windham/M
+Windhoek
+Windows
+Windsor/SM
+Windward/M
+Windy/M
+Winesap/M
+Winfield/M
+Winfred/M
+Winfrey/M
+Wini/M
+Winifield/M
+Winifred/M
+Winkle/M
+Winn/M
+Winna/M
+Winnah/M
+Winne/M
+Winnebago/M
+Winni/M
+Winnie
+Winnifred/M
+Winnipeg/M
+Winny/M
+Winona/M
+Winonah/M
+Winslow/M
+Winston/M
+Winters
+Winthrop/M
+Wis
+Wisc
+Wisconsin/M
+Wisconsinite/SM
+Wise/M
+Wit/M
+Witt/M
+Wittgenstein/M
+Wittie/M
+Witty/M
+Witwatersrand
+Wm/M
+Wobegon/M
+Wodehouse/M
+Wolf
+Wolfe
+Wolff
+Wolfgang/M
+Wolfie/M
+Wolfy/M
+Wollongong
+Wollstonecraft/M
+Wolsey
+Wolverhampton
+Wonder
+Wonderbra/M
+Wong/M
+Wood/S
+Woodard/M
+Woodhull/M
+Woodie/M
+Woodman
+Woodrow/M
+Woodstock/M
+Woodward/M
+Woody/M
+Woolf
+Woolite/M
+Woolongong/M
+Woolworth
+Wooster/M
+Wooten/M
+Worcester/SM
+Worcestershire
+Worden/M
+Wordsworth/M
+Workman/M
+Worms
+Worth
+Worthington/M
+Worthy/M
+Wotan/M
+Wozniak/M
+Wozzeck/M
+Wrangell/M
+Wren
+Wrennie/M
+Wright
+Wrigley/M
+Wroclaw/M
+Wu/M
+Wuhan
+Wurlitzer/M
+Wyatan/M
+Wyatt
+Wycherley/M
+Wycliffe/M
+Wye/H
+Wylie/M
+Wylma/M
+Wyn/M
+Wyndham/M
+Wynn/M
+Wynne/M
+Wynnie/M
+Wynny/M
+Wyo
+Wyoming/M
+Wyomingite/MS
+X/M
+XEmacs/M
+XL/M
+XML
+XS
+XXL
+Xanadu
+Xanthippe
+Xavier
+Xaviera/M
+Xe/SM
+Xena/M
+Xenakis/M
+Xenia/M
+Xenophon
+Xenos
+Xerox/MS
+Xerxes
+Xever/M
+Xhosa/M
+Xi'an
+Xian/SM
+Xiaoping/M
+Ximenes
+Ximenez/M
+Xingu/M
+Xiongnu/M
+Xmas/MS
+Xochipilli/M
+Xuzhou/M
+Xylia/M
+Xylina/M
+Xymenes/M
+Y/M
+YMCA
+YMHA
+YMMV
+YT
+YWCA
+YWHA
+Yacc/M
+Yahtzee/M
+Yahweh/M
+Yakima
+Yakut/M
+Yakutsk
+Yale/M
+Yalonda/M
+Yalow/M
+Yalta/M
+Yalu/M
+Yamagata/M
+Yamaha/M
+Yamoussoukro
+Yanaton/M
+Yance/M
+Yancey/M
+Yancy/M
+Yang
+Yangon/M
+Yangtze/M
+Yank/SM
+Yankee/SM
+Yaobang/M
+Yaounde/M
+Yaqui
+Yard/M
+Yardley/M
+Yaren
+Yaroslavl
+Yasmeen/M
+Yasmin/M
+Yates
+Yb/M
+Yeager/M
+Yeats/M
+Yehudi/M
+Yehudit/M
+Yekaterinburg
+Yelena/M
+Yellowknife
+Yellowstone/M
+Yeltsin
+Yemen/M
+Yemeni/SM
+Yemenite
+Yenisei/M
+Yerevan
+Yerkes/M
+Yesenia/M
+Yetta/M
+Yettie/M
+Yetty/M
+Yevette/M
+Yevtushenko/M
+Yggdrasil
+Yiddish/M
+Ymir/M
+Ynes/M
+Ynez/M
+Yoda/M
+Yoknapatawpha/M
+Yoko/M
+Yokohama
+Yolanda/M
+Yolande/M
+Yolane/M
+Yolanthe/M
+Yong/M
+Yonkers
+Yorgo/MS
+York/MR
+Yorke/M
+Yorker/M
+Yorkie
+Yorkshire/MS
+Yorktown/M
+Yoruba/M
+Yosemite/M
+Yoshi/M
+Yoshiko/M
+Young
+Youngstown
+Yovonnda/M
+Ypres/M
+Ypsilanti
+Ysabel/M
+Yuan/M
+Yucatan/M
+Yugo
+Yugoslav/MS
+Yugoslavia/M
+Yugoslavian/SM
+Yukon/M
+Yul/M
+Yule/SM
+Yuletide/MS
+Yulma/M
+Yuma/SM
+Yunnan/M
+Yuri/M
+Yurik/M
+Yves/M
+Yvette/M
+Yvon/M
+Yvonne/M
+Yvor/M
+Z/SDNXT
+Zabrina/M
+Zaccaria/M
+Zach
+Zacharia/SM
+Zachariah/M
+Zacharie/M
+Zachary/M
+Zacherie/M
+Zachery/M
+Zack/M
+Zackariah/M
+Zagreb/M
+Zahara/M
+Zaire/M
+Zairian
+Zak/M
+Zambezi/M
+Zambia/M
+Zambian/SM
+Zamboni
+Zamenhof/M
+Zamora
+Zandra/M
+Zane/M
+Zaneta/M
+Zanuck/M
+Zanzibar/M
+Zapata
+Zaporozhye
+Zapotec
+Zappa/M
+Zara/M
+Zarah/M
+Zarathustra/M
+Zared/M
+Zaria/M
+Zarla/M
+Zea/M
+Zeb/M
+Zebadiah/M
+Zebedee
+Zebulen/M
+Zebulon/M
+Zechariah
+Zed/M
+Zedekiah/M
+Zedong/M
+Zeffirelli/M
+Zeke/M
+Zelda/M
+Zelig
+Zelma/M
+Zen/M
+Zena/M
+Zenger/M
+Zenia/M
+Zeno/M
+Zephaniah
+Zephyrus
+Zerk/M
+Zest/M
+Zeus/M
+Zhdanov
+Zhengzhou
+Zhivago/M
+Zhukov
+Zia/M
+Zibo/M
+Ziegfeld
+Ziegler/M
+Ziggy/M
+Zilvia/M
+Zimbabwe/M
+Zimbabwean/SM
+Zimmerman/M
+Zinfandel/M
+Zion/SM
+Zionism/SM
+Zionist/SM
+Ziploc
+Zita/M
+Zitella/M
+Zn/M
+Zoe/M
+Zola/M
+Zollie/M
+Zollverein
+Zolly/M
+Zoloft
+Zomba/M
+Zonda/M
+Zondra/M
+Zonnya/M
+Zora/M
+Zorah/M
+Zorana/M
+Zorina/M
+Zorine/M
+Zorn
+Zoroaster/M
+Zoroastrian/MS
+Zoroastrianism/SM
+Zorro/M
+Zosma/M
+Zr/M
+Zsazsa/M
+Zsigmondy
+Zubenelgenubi/M
+Zubeneschamali/M
+Zukor/M
+Zulema/M
+Zulu/SM
+Zululand
+Zuni
+Zurich/M
+Zuzana/M
+Zwingli/M
+Zworykin
+Zyrtec/M
+Zyuganov/M
+Zzz
+a/S
+aah
+aardvark/SM
+ab/SDY
+aback
+abacus/MS
+abaft
+abalone/SM
+abandon/LSDG
+abandonment/M
+abase/LGDS
+abasement/M
+abash/GLDS
+abashed/UY
+abashment/M
+abate/LGDS
+abated/U
+abatement/M
+abattoir/MS
+abbe/SM
+abbess/MS
+abbey/MS
+abbot/MS
+abbr
+abbrev/S
+abbreviate/XDSGN
+abbreviation/M
+abdicate/GNDSX
+abdication/M
+abdomen/SM
+abdominal
+abduct/DSG
+abduction/SM
+abductor/MS
+abeam
+aberrant
+aberration/SM
+aberrational
+abet/S
+abetted
+abetting
+abettor/SM
+abeyance/M
+abhor/S
+abhorred
+abhorrence/M
+abhorrent/Y
+abhorring
+abidance/M
+abide/GS
+abiding/Y
+ability/IEMS
+abject/YP
+abjection/M
+abjectness/M
+abjuration/MS
+abjuratory
+abjure/ZGDRS
+abjurer/M
+ablate/XGNVDS
+ablation/M
+ablative/MS
+ablaze
+able/UT
+abler
+abloom
+ablution/SM
+abnegate/GNDS
+abnegation/M
+abnormal/Y
+abnormality/SM
+aboard
+abode/MS
+abolish/GDS
+abolition/M
+abolitionism/M
+abolitionist/MS
+abominable
+abominably
+abominate/XDSGN
+abomination/M
+aboriginal/MS
+aborigine/SM
+aborning
+abort/GVDS
+abortion/MS
+abortionist/SM
+abortive/Y
+abound/DSG
+about
+above/M
+aboveboard
+abracadabra/M
+abrade/GDS
+abrasion/MS
+abrasive/MYSP
+abrasiveness/M
+abreast
+abridge/DSG
+abridgment/MS
+abroad
+abrogate/XGNDS
+abrogation/M
+abrogator/MS
+abrupt/TPRY
+abruptness/M
+abs/M
+abscess/MDSG
+abscissa/SM
+abscission/M
+abscond/ZGSDR
+absconder/M
+abseil/MDRSG
+absence/SM
+absent/DYSG
+absentee/MS
+absenteeism/M
+absentminded/PY
+absentmindedness/M
+absinthe/M
+absolute/PMYTNRS
+absoluteness/M
+absolution/M
+absolutism/M
+absolutist/MS
+absolve/DSG
+absorb/AGDS
+absorbed/U
+absorbency/M
+absorbent/SM
+absorber/S
+absorbing/Y
+absorption/SM
+absorptive
+absorptivity
+abstain/DRZGS
+abstainer/M
+abstemious/YP
+abstemiousness/M
+abstention/SM
+abstinence/M
+abstinent
+abstract/TGSPMDRY
+abstracted/YP
+abstractedness/M
+abstraction/SM
+abstractness/MS
+abstruse/RPYT
+abstruseness/M
+absurd/TPRY
+absurdity/SM
+absurdness/M
+abundance/SM
+abundant/Y
+abuse's
+abuse/EGVDS
+abuser/MS
+abusive/YP
+abusiveness/M
+abut/SL
+abutment/MS
+abutted
+abutting
+abuzz
+abysmal/Y
+abyss/MS
+abyssal
+ac
+acacia/MS
+academe/M
+academia/M
+academic/SM
+academical/Y
+academician/SM
+academy/SM
+acanthus/MS
+accede/GDS
+accelerate/GNDSX
+acceleration/M
+accelerator/SM
+accelerometer/S
+accent/MDSG
+accented/U
+accentual
+accentuate/DSGN
+accentuation/M
+accept/DSBG
+acceptability/M
+acceptableness/M
+acceptably/U
+acceptance/SM
+acceptation/MS
+accepted/U
+acceptor/S
+access/MDSG
+accessed/A
+accessibility/IM
+accessible/I
+accessibly/I
+accession/GMDS
+accessorize/DSG
+accessory/SM
+accidence
+accident/MS
+accidental/MYS
+acclaim/MDGS
+acclamation/SM
+acclimate/DSGN
+acclimation/M
+acclimatisation
+acclimatise/DSG
+acclimatization/M
+acclimatize/DSG
+acclivity/SM
+accolade/SM
+accommodate/DSGNX
+accommodating/Y
+accommodation/M
+accompanied/U
+accompaniment/SM
+accompanist/SM
+accompany/DSG
+accomplice/SM
+accomplish/GLDS
+accomplished/U
+accomplishment/MS
+accord/GMDS
+accordance/M
+accordant
+according/Y
+accordion/MS
+accordionist/SM
+accost/GMDS
+account/MDSBG
+accountability/M
+accountable/U
+accountancy/M
+accountant/MS
+accounted/U
+accounting/M
+accouter/SGD
+accouterments/M
+accoutrement
+accredit/SGD
+accreditation/M
+accredited/U
+accreted
+accretion/MS
+accrual/MS
+accrue/GDS
+acct
+acculturate/GNDS
+acculturation/M
+accumulate/DSGNVX
+accumulation/M
+accumulator/SM
+accuracy/ISM
+accurate/IY
+accurateness/M
+accursed/P
+accursedness/M
+accusal
+accusation/MS
+accusative/MS
+accusatory
+accuse/ZGDRS
+accuser/M
+accusing/Y
+accustom/DSG
+accustomed/U
+ace/DSMG
+acerbate/DSG
+acerbic
+acerbically
+acerbity/M
+acetaminophen/M
+acetate/MS
+acetic
+acetone/M
+acetonic
+acetylene/M
+ache/DSMG
+achene/MS
+achievable/U
+achieve/BLZGDRS
+achieved/A
+achievement/SM
+achiever/M
+aching/Y
+achoo/M
+achromatic
+achy/TR
+acid/SMY
+acidic
+acidify/GDSN
+acidity/M
+acidophiles
+acidosis/M
+acidulous
+acknowledge/DSG
+acknowledged/U
+acknowledgment/MS
+acme/SM
+acne/M
+acolyte/MS
+aconite/MS
+acorn/MS
+acoustic/S
+acoustical/Y
+acoustics/M
+acquaint/AGSD
+acquaintance/MS
+acquaintanceship/M
+acquainted/U
+acquiesce/DSG
+acquiescence/M
+acquiescent/Y
+acquire/ZGBDRSL
+acquirement/M
+acquisition/SM
+acquisitive/YP
+acquisitiveness/M
+acquit/S
+acquittal/MS
+acquittance
+acquitted
+acquitting
+acre/SM
+acreage/MS
+acrid/PTRY
+acridity/M
+acridness/M
+acrimonious/PY
+acrimoniousness/M
+acrimony/M
+acrobat/MS
+acrobatic/S
+acrobatically
+acrobatics/M
+acronym/MS
+acrophobia/M
+acropolis/MS
+across
+acrostic/SM
+acrylic/MS
+act's
+act/ASDGV
+acting/M
+actinides
+actinium/M
+action/ASM
+actionable
+activate/ICANGSD
+activated/U
+activation/CAIM
+activations
+activator/MS
+active's
+active/IKY
+activeness/M
+actives
+activism/M
+activist/MS
+activity's/I
+activity/AS
+actor/AMS
+actress/MS
+actual/Y
+actuality/SM
+actualization/M
+actualize/GDS
+actuarial
+actuary/SM
+actuate/GNDS
+actuation/M
+actuator/SM
+acuity/M
+acumen/M
+acupressure/M
+acupuncture/M
+acupuncturist/SM
+acute/PMYTRS
+acuteness/M
+acyclic
+acyclovir/M
+ad/SM
+adage/MS
+adagio/MS
+adamant/MY
+adapt/BZGVDRS
+adaptability/M
+adaptation/SM
+adapted/U
+adapter/M
+adaption/S
+adaptive/Y
+adaptivity
+add/SDRBZG
+addend/MS
+addenda
+addendum/M
+adder/M
+addict/GVMDS
+addiction/SM
+addictive/P
+addition/SM
+additional/Y
+additive/SMY
+addle/GDS
+address's
+address/AGDS
+addressable/U
+addressed/U
+addressee/SM
+adduce/GDS
+adenine/M
+adenoid/SM
+adenoidal
+adept/TMRYPS
+adeptness/M
+adequacy/IM
+adequate/IY
+adequateness/M
+adhere/ZGDRS
+adherence/M
+adherent/SM
+adhesion/M
+adhesive/SPM
+adhesiveness/M
+adiabatic
+adiabatically
+adieu/MS
+adios
+adipose
+adj
+adjacency/M
+adjacent/Y
+adjectival/Y
+adjective/MS
+adjoin/GDS
+adjourn/DGLS
+adjournment/MS
+adjudge/GDS
+adjudicate/GNVDSX
+adjudication/M
+adjudicator/SM
+adjudicatory
+adjunct/MS
+adjuration/SM
+adjure/GDS
+adjust/AGDSL
+adjustable
+adjusted/U
+adjuster/SM
+adjustment/AMS
+adjutant/SM
+adman/M
+admen
+admin/S
+administer/SDG
+administrate/GNVXDS
+administration/M
+administrative/Y
+administrator/SM
+admirably
+admiral/MS
+admiralty/M
+admiration/M
+admire/BZGDRS
+admirer/M
+admiring/Y
+admissibility/IM
+admissible/I
+admissibly
+admission/AM
+admissions
+admit/AS
+admittance/SM
+admitted/Y
+admitting/A
+admix/GDS
+admixture/SM
+admonish/LDSG
+admonishment/SM
+admonition/MS
+admonitory
+ado/M
+adobe/MS
+adolescence/SM
+adolescent/SM
+adopt/AGVDS
+adoptable
+adopter/MS
+adoption/SM
+adorableness/M
+adorably
+adoration/M
+adore/BZGDRS
+adorer/M
+adoring/Y
+adorn/LGDS
+adorned/U
+adornment/MS
+adrenal/MS
+adrenalin/M
+adrenaline/M
+adrift
+adroit/PTRY
+adroitness/M
+adsorb/SDG
+adsorbent/MS
+adsorption/MS
+adulate/DSGN
+adulation/M
+adulator/MS
+adulatory
+adult/MS
+adulterant/MS
+adulterate/XGNDS
+adulterated/U
+adulteration/M
+adulterer/SM
+adulteress/MS
+adulterous
+adultery/SM
+adulthood/M
+adumbrate/GNDS
+adumbration/M
+adv
+advance/LDSMG
+advancement/SM
+advantage/EDSMG
+advantageous/EY
+advent/SM
+adventitious/Y
+adventure/DRSMZG
+adventurer/M
+adventuresome
+adventuress/MS
+adventurism
+adventurist/S
+adventurous/YP
+adventurousness/M
+adverb/SM
+adverbial/SMY
+adversarial
+adversary/SM
+adverse/PRYT
+adverseness/M
+adversity/SM
+advert/SMDG
+advertise/ZGLDRS
+advertised/U
+advertisement/MS
+advertiser/M
+advertising/M
+advertorial/SM
+advice/SM
+advisability/IM
+advisable/I
+advisably
+advise/LDRSZGB
+advised/UY
+advisedly/I
+advisement/M
+adviser/M
+advisory/SM
+advocacy/M
+advocate/MGDS
+advt
+adz/MS
+aegis/M
+aeolian
+aerate/DSGN
+aeration/M
+aerator/SM
+aerial/SMY
+aerialist/MS
+aerie/MTRS
+aerobatic/S
+aerobatics/M
+aerobic/S
+aerobically
+aerobics/M
+aerobraking
+aerodrome/MS
+aerodynamic/S
+aerodynamically
+aerodynamics/M
+aerogram/S
+aeronautic/S
+aeronautical
+aeronautics/M
+aerosol/MS
+aerospace/M
+aesthete/S
+aesthetic/S
+aesthetically
+aestheticism/M
+aesthetics/M
+aether
+afar
+affability/M
+affable/TR
+affably
+affair/MS
+affect's
+affect/EGVDS
+affectation/SM
+affected/UY
+affecting/Y
+affection/EM
+affectionate/Y
+affections
+afferent
+affiance/GDS
+affidavit/SM
+affiliate's
+affiliate/EGNDS
+affiliated/U
+affiliation/EM
+affiliations
+affine
+affinity/SM
+affirm/AGDS
+affirmation/AMS
+affirmative/MYS
+affix/GMDS
+afflatus/M
+afflict/GDS
+affliction/SM
+affluence/M
+affluent/Y
+afford/GDSB
+affordability
+affordable/U
+afforest/EGSD
+afforestation/M
+affray/MS
+affront/GMDS
+afghan/MS
+aficionado/MS
+afield
+afire
+aflame
+afloat
+aflutter
+afoot
+aforementioned
+aforesaid
+aforethought
+afoul
+afraid/U
+afresh
+aft/RZ
+afterbirth/M
+afterbirths
+afterburner/SM
+aftercare/M
+aftereffect/MS
+afterglow/SM
+afterimage/MS
+afterlife/M
+afterlives
+aftermarket/SM
+aftermath/M
+aftermaths
+afternoon/MS
+aftershave/SM
+aftershock/SM
+aftertaste/SM
+afterthought/MS
+afterward
+afterword/MS
+again
+against
+agape/M
+agar/M
+agate/MS
+agave/M
+age/DSMGJ
+ageism/M
+ageist/SM
+ageless/YP
+agelessness/M
+agency/SM
+agenda/SM
+agent/AMS
+ageratum/M
+agglomerate/XDSMGN
+agglomeration/M
+agglutinate/XDSGNV
+agglutination/M
+aggrandize/LGDS
+aggrandizement/M
+aggravate/GNDSX
+aggravating/Y
+aggravation/M
+aggregate/MGNDSX
+aggregated/E
+aggregation/M
+aggression/SM
+aggressive/YP
+aggressiveness/M
+aggressor/SM
+aggrieve/DSG
+aggrieved/Y
+aggro
+aghast
+agile/YTR
+agility/M
+aging/M
+agitate/XGNDS
+agitated/Y
+agitation/M
+agitator/MS
+agitprop/M
+agleam
+aglitter
+aglow
+agnostic/MS
+agnosticism/M
+ago
+agog
+agonize/GDS
+agonizing/Y
+agony/SM
+agoraphobia/M
+agoraphobic/SM
+agouti
+agrarian/MS
+agrarianism/M
+agree/EBLDS
+agreeableness/EM
+agreeably/E
+agreeing/E
+agreement/ESM
+agribusiness/MS
+agricultural/Y
+agriculturalist/MS
+agriculture/M
+agriculturist/MS
+agrochemical/S
+agronomic
+agronomist/MS
+agronomy/M
+aground
+ague/M
+ah
+aha
+ahchoo
+ahead
+ahem
+ahoy
+aid/SMDRZG
+aide/SM
+aided/U
+aigrette/MS
+ail/SDLG
+aileron/SM
+ailment/SM
+aim/SMDG
+aimless/YP
+aimlessness/M
+ain't
+air/SMDJG
+airbag/MS
+airbase/SM
+airbed/S
+airborne
+airbrush/MDSG
+airbus/MS
+aircraft/M
+aircraftman
+aircraftmen
+aircrew/S
+airdrome/S
+airdrop/SM
+airdropped
+airdropping
+airfare/SM
+airfield/SM
+airflow/M
+airfoil/SM
+airframe/S
+airfreight/M
+airguns
+airhead/SM
+airily
+airiness/M
+airing/M
+airless/P
+airlessness/M
+airletters
+airlift/SGMD
+airline/RSMZ
+airliner/M
+airlock/SM
+airmail/GSMD
+airman/M
+airmen
+airplane/MS
+airplay/M
+airport/SM
+airship/SM
+airshow/S
+airsick/P
+airsickness/M
+airspace/M
+airspeed
+airstream
+airstrip/SM
+airtight
+airtime/M
+airwaves/M
+airway/MS
+airwoman
+airwomen
+airworthiness/M
+airworthy/TPR
+airy/PTR
+aisle/MS
+aitch/MS
+ajar
+aka
+akimbo
+akin
+alabaster/M
+alack
+alacrity/M
+alanine
+alarm/GMDS
+alarming/Y
+alarmist/SM
+alas
+alb/SM
+albacore/SM
+albatross/MS
+albedo
+albeit
+albinism/M
+albino/MS
+album/MNS
+albumen/M
+albumin/M
+albuminous
+alchemical
+alchemist/SM
+alchemy/M
+alcohol/SM
+alcoholic/MS
+alcoholically
+alcoholism/M
+alcove/MS
+aldehyde
+alder/MS
+alderman/M
+aldermen
+alderwoman/M
+alderwomen
+ale/SMV
+aleatory
+alehouse/SM
+alembic/SM
+alert/TGMDRYPS
+alertness/M
+alewife/M
+alewives
+alfalfa/M
+alfresco
+alga/M
+algae
+algal
+algebra/SM
+algebraic
+algebraical/Y
+algebraist
+algorithm/SM
+algorithmic
+algorithmically
+alias/GMDS
+alibi/GMDS
+alien/BGMDS
+alienable/IU
+alienate/DSGN
+alienation/M
+alienist/SM
+alight/GDS
+align/ALGDS
+aligned/U
+aligner/MS
+alignment/AMS
+alike/U
+aliment/MDSG
+alimentary
+alimony/M
+aliphatic
+aliquot/S
+aliveness/M
+aliyah/M
+aliyahs
+alkali/M
+alkalies
+alkaline
+alkalinity/M
+alkalize/DSG
+alkaloid/SM
+alkyd/MS
+all/M
+allay/GDS
+allegation/MS
+allege/GDS
+alleged/Y
+allegiance/SM
+allegoric
+allegorical/Y
+allegorist/MS
+allegory/SM
+allegretto/MS
+allegri
+allegro/MS
+allele/MS
+allelic
+alleluia/SM
+allergen/SM
+allergenic
+allergic
+allergically
+allergist/SM
+allergy/SM
+alleviate/DSXGN
+alleviation/M
+alley/MS
+alleyway/SM
+alliance/SM
+alligator/MS
+alliterate/DSGNVX
+alliteration/M
+alliterative/Y
+allocatable
+allocate/ADSGN
+allocated/U
+allocation/AM
+allocations
+allocator/S
+allophones
+allot/LS
+allotment/SM
+allotrope
+allotropic
+allotted
+allotting
+allover
+allow/EGDS
+allowable
+allowably
+allowance/SM
+alloy/GMDS
+alloyed/U
+allspice/M
+allude/GDS
+allure/MGLDS
+allurement/MS
+alluring/Y
+allusion/SM
+allusive/YP
+allusiveness/M
+alluvial/M
+alluvium/SM
+ally/GDSM
+almanac/SM
+almanack/S
+almighty
+almond/MS
+almoner/SM
+almost
+alms/M
+almshouse/MS
+aloe/SM
+aloft
+aloha/MS
+alone
+along
+alongshore
+alongside
+aloof/PY
+aloofness/M
+aloud
+alp/SM
+alpaca/MS
+alpha/MS
+alphabet/SM
+alphabetic
+alphabetical/Y
+alphabetization/MS
+alphabetize/DRSZG
+alphabetizer/M
+alphanumeric
+alphanumerical/Y
+alpine/S
+already
+alright
+also
+alt/S
+altar/MS
+altarpiece/SM
+alter/GDBS
+alterable/U
+alteration/MS
+altercate/XN
+altercation/M
+altered/U
+alternate/XDSMYGNV
+alternation/M
+alternative/MYS
+alternator/MS
+although
+altimeter/MS
+altitude/MS
+alto/SM
+altogether
+altruism/M
+altruist/SM
+altruistic
+altruistically
+alum/SM
+alumina/M
+aluminum/M
+alumna/M
+alumnae
+alumni
+alumnus/M
+alveolar/S
+always
+am/N
+amalgam/SM
+amalgamate/DSGNX
+amalgamation/M
+amanuenses
+amanuensis/M
+amaranth/M
+amaranths
+amaretto/M
+amaryllis/MS
+amass/GDS
+amateur/SM
+amateurish/PY
+amateurishness/M
+amateurism/M
+amatory
+amaze/LMGDS
+amazement/M
+amazing/Y
+amazon/MS
+amazonian
+ambassador/SM
+ambassadorial
+ambassadorship/MS
+ambassadress/MS
+amber/M
+ambergris/M
+ambiance/MS
+ambidexterity/M
+ambidextrous/Y
+ambient
+ambiguity/SM
+ambiguous/UY
+ambit
+ambition/MS
+ambitious/PY
+ambitiousness/M
+ambivalence/M
+ambivalent/Y
+amble/MZGDRS
+ambler/M
+ambrosia/M
+ambrosial
+ambulance/MS
+ambulanceman
+ambulancemen
+ambulancewoman
+ambulancewomen
+ambulant
+ambulate/DSXGN
+ambulation/M
+ambulatory/SM
+ambuscade/MGDS
+ambush/ZGMDS
+ameliorate/GNVDS
+amelioration/M
+amen/B
+amenability/M
+amenably
+amend/BLGDS
+amended/U
+amendment/SM
+amenity/SM
+amerce/GLDS
+amercement/MS
+americium/M
+amethyst/SM
+amethystine
+amiability/M
+amiable/P
+amiably
+amicability/M
+amicable
+amicably
+amid
+amide/MS
+amidships
+amidst
+amigo/MS
+amine/S
+amino
+amiss
+amity/M
+ammeter/SM
+ammo/M
+ammonia/M
+ammonites
+ammonium
+ammunition/M
+amnesia/M
+amnesiac/MS
+amnesic/SM
+amnesty/GDSM
+amniocenteses
+amniocentesis/M
+amnion/MS
+amniotic
+amoeba/MS
+amoebae
+amoebic
+amok
+among
+amongst
+amontillado/MS
+amoral/Y
+amorality/M
+amorous/YP
+amorousness/M
+amorphous/PY
+amorphousness/M
+amortization/MS
+amortize/DSGB
+amount/GMDS
+amour/MS
+amp/SMY
+amperage/M
+ampere/MS
+ampersand/MS
+amphetamine/SM
+amphibian/MS
+amphibious/Y
+amphitheater/SM
+amphora/M
+amphorae
+ample/TR
+amplification/M
+amplifier/M
+amplify/DRSZGNX
+amplitude/SM
+ampule/MS
+amputate/GNDSX
+amputation/M
+amputee/MS
+amt
+amulet/MS
+amuse/LGDS
+amused/U
+amusement/MS
+amusing/Y
+amylase/M
+an/CS
+anabolic
+anabolism/M
+anachronism/SM
+anachronistic
+anachronistically
+anaconda/SM
+anaerobe/SM
+anaerobic
+anaerobically
+anagram/MS
+anagrammatic
+anagrammatically
+anal/Y
+analgesia/M
+analgesic/SM
+analog/MS
+analogical/Y
+analogize/GDS
+analogous/PY
+analogousness/M
+analogue/SM
+analogy/SM
+analysand/MS
+analysis/AM
+analyst/SM
+analytic
+analytical/Y
+analyzable
+analyze/ADSG
+analyzer/SM
+anamorphic
+anapest/SM
+anapestic/MS
+anaphora
+anaphoric
+anarchic
+anarchical/Y
+anarchism/M
+anarchist/MS
+anarchistic
+anarchy/M
+anathema/SM
+anathematize/DSG
+anatomic
+anatomical/Y
+anatomist/SM
+anatomize/DSG
+anatomy/SM
+ancestor/SM
+ancestral/Y
+ancestress/MS
+ancestry/SM
+anchor/MDGS
+anchorage/MS
+anchorite/MS
+anchorman/M
+anchormen
+anchorpeople
+anchorperson/MS
+anchorwoman/M
+anchorwomen
+anchovy/SM
+ancient/SPMRYT
+ancientness/M
+ancillary/SM
+and
+andante/SM
+andiron/SM
+androgen/M
+androgenic
+androgynous
+androgyny/M
+android/SM
+anecdotal
+anecdote/MS
+anechoic
+anemia/M
+anemic
+anemically
+anemometer/MS
+anemone/SM
+anent
+aneroid
+anesthesia/M
+anesthesiologist/SM
+anesthesiology/M
+anesthetic/SM
+anesthetist/SM
+anesthetization/M
+anesthetize/DSG
+aneurysm/SM
+anew
+angel/MS
+angelfish/MS
+angelic
+angelica/M
+angelical/Y
+anger/GMDS
+angina/M
+angioplasty/SM
+angiosperm/SM
+angle/MZGDRS
+anglepoise
+angler/M
+angleworm/MS
+anglicism/S
+anglicize/GDS
+angling/M
+anglophile/S
+anglophone/S
+angora/MS
+angostura
+angrily
+angry/TR
+angst/M
+angstrom/MS
+anguish/GMDS
+angular
+angularity/SM
+anhydrous
+aniline/M
+animadversion/MS
+animadvert/SGD
+animal/MS
+animalcule/MS
+animate/ADSGN
+animated/Y
+animation/AM
+animations
+animator/MS
+animism/M
+animist/SM
+animistic
+animosity/SM
+animus/M
+anion/MS
+anionic
+anise/M
+aniseed/M
+anisette/M
+anisotropic
+anisotropy/S
+ankh/M
+ankhs
+ankle/MS
+anklebone/MS
+anklet/MS
+annal/S
+annalist/SM
+annals/M
+anneal/GDRS
+annelid/MS
+annex/GMDS
+annexation/MS
+annihilate/DSGN
+annihilation/M
+annihilator/MS
+anniversary/SM
+annotate/DSXGNV
+annotated/U
+annotation/M
+annotator/MS
+announce/DRSLZG
+announced/U
+announcement/MS
+announcer/M
+annoy/GDS
+annoyance/MS
+annoying/Y
+annoyware/S
+annual/MYS
+annualized
+annuitant/SM
+annuity/SM
+annul/LS
+annular
+annuli
+annulled
+annulling
+annulment/SM
+annulus
+annunciation/MS
+anode/MS
+anodize/GDS
+anodyne/MS
+anoint/GDLS
+anointment/M
+anomalous/Y
+anomaly/SM
+anon/S
+anonymity/M
+anonymous/Y
+anopheles/M
+anorak/MS
+anorectic/SM
+anorexia/M
+anorexic/MS
+another
+answer/BMDRGS
+answerable/U
+answered/U
+answerphone/S
+ant/SMD
+antacid/SM
+antagonism/SM
+antagonist/SM
+antagonistic
+antagonistically
+antagonize/DSG
+antarctic
+ante/SM
+anteater/MS
+antebellum
+antecedence/M
+antecedent/SM
+antechamber/SM
+antedate/GDS
+antediluvian
+anteing
+antelope/MS
+antenatal
+antenna/SM
+antennae
+anterior
+anteroom/MS
+anthem/MS
+anther/MS
+anthill/SM
+anthologist/SM
+anthologize/DSG
+anthology/SM
+anthracite/M
+anthrax/M
+anthropic
+anthropocentric
+anthropogenic
+anthropoid/SM
+anthropological/Y
+anthropologist/MS
+anthropology/M
+anthropometric
+anthropomorphic
+anthropomorphically
+anthropomorphism/M
+anthropomorphizing
+anthropomorphous
+anti/SM
+antiabortion
+antiabortionist/MS
+antiaircraft
+antibacterial/MS
+antibiotic/SM
+antibody/SM
+antic/MS
+anticancer
+anticipate/GNVXDS
+anticipated/U
+anticipation/M
+anticipatory
+anticked
+anticking
+anticlerical
+anticlimactic
+anticlimactically
+anticlimax/MS
+anticline/SM
+anticlockwise
+anticoagulant/SM
+anticommunism/M
+anticommunist/MS
+anticyclone/MS
+anticyclonic
+antidemocratic
+antidepressant/MS
+antidote/MS
+antifascist/MS
+antifreeze/M
+antigen/SM
+antigenic
+antigenicity/M
+antihero/M
+antiheroes
+antihistamine/SM
+antiknock/M
+antilabor
+antilogarithm/MS
+antimacassar/SM
+antimalarial
+antimatter/M
+antimicrobial
+antimissile
+antimony/M
+antinuclear
+antioxidant/SM
+antiparticle/MS
+antipasti
+antipasto/MS
+antipathetic
+antipathy/SM
+antipersonnel
+antiperspirant/SM
+antiphon/SM
+antiphonal/MYS
+antipodal/S
+antipodean/MS
+antipodes/M
+antipollution
+antipoverty
+antiquarian/MS
+antiquarianism/M
+antiquary/SM
+antiquate/GDS
+antique/DSMG
+antiquity/SM
+antirrhinum/S
+antisemitic
+antisemitism/M
+antisepsis/M
+antiseptic/SM
+antiseptically
+antiserum/MS
+antislavery
+antisocial/Y
+antispasmodic/SM
+antistatic
+antisubmarine
+antisymmetric
+antisymmetry
+antitank
+antitheses
+antithesis/M
+antithetic
+antithetical/Y
+antitoxin/MS
+antitrust
+antivenin/MS
+antiviral/S
+antivivisectionist/MS
+antiwar
+antler/MDS
+antonym/SM
+antonymous
+antral
+antsy/TR
+anus/MS
+anvil/MS
+anxiety/SM
+anxious/YP
+anxiousness/M
+any
+anybody/SM
+anyhow
+anymore
+anyone/M
+anyplace
+anything/SM
+anytime
+anyway/S
+anywhere
+anywise
+aorist
+aorta/MS
+aortic
+apace
+apart
+apartheid/M
+apartment/MS
+apathetic
+apathetically
+apathy/M
+apatite/M
+ape/DSMG
+apelike
+aperiodic
+aperiodically
+aperitif/MS
+aperture/SM
+apex/MS
+aphasia/M
+aphasic/MS
+aphelia
+aphelion/SM
+aphid/MS
+aphorism/MS
+aphoristic
+aphoristically
+aphrodisiac/MS
+apiarist/SM
+apiary/SM
+apical/Y
+apiece
+apish/Y
+aplenty
+aplomb/M
+apnea
+apocalypse/SM
+apocalyptic
+apocrypha/M
+apocryphal/Y
+apogee/MS
+apolitical/Y
+apologetic/U
+apologetically
+apologia/SM
+apologist/MS
+apologize/GDS
+apology/SM
+apoplectic
+apoplexy/SM
+apostasy/SM
+apostate/SM
+apostatize/DSG
+apostle/MS
+apostleship/M
+apostolic
+apostrophe/SM
+apostrophized
+apothecary/SM
+apothegm/SM
+apotheoses
+apotheosis/M
+apotheosizes
+app/S
+appall/GDS
+appalling/Y
+appaloosa/MS
+apparatchik/S
+apparatus/MS
+apparel/MDGS
+apparent/Y
+apparition/SM
+appeal/GMDS
+appealing/UY
+appear/AESDG
+appearance/EAMS
+appease/LZGDRS
+appeased/U
+appeasement/MS
+appeaser/M
+appellant/SM
+appellate/XN
+appellation/M
+append/GDS
+appendage/SM
+appendectomy/SM
+appendices
+appendicitis/M
+appendix/MS
+appertain/DGS
+appetite/SM
+appetizer/MS
+appetizing/Y
+applaud/ZGDRS
+applauder/M
+applause/M
+apple/MS
+applecart
+applejack/M
+applesauce/M
+applet/MS
+appliance/SM
+applicability/M
+applicable/I
+applicably
+applicant/SM
+application/AM
+applicative
+applicator/SM
+applier/MS
+applique/DSM
+appliqueing
+apply/ANXGDS
+appoint/AELSVGD
+appointee/SM
+appointment's/A
+appointment/ESM
+apportion/ALDGS
+apportionment/AM
+appose/GDS
+apposite/PYNV
+appositeness/M
+apposition/M
+appositive/MS
+appraisal/AMS
+appraise/ADSG
+appraisees
+appraiser/MS
+appreciable/I
+appreciably/I
+appreciate/XDSGNV
+appreciated/U
+appreciation/M
+appreciative/Y
+appreciator/MS
+appreciatory
+apprehend/GDS
+apprehension/MS
+apprehensive/PY
+apprehensiveness/M
+apprentice/DSMG
+apprenticeship/MS
+apprise/GDS
+approach/GBMDS
+approachability
+approachable/IU
+approbation/EM
+approbations
+appropriate/DSPXYGN
+appropriated/U
+appropriateness/IM
+appropriation/M
+appropriator/MS
+approval/EM
+approvals
+approve/EGDS
+approved/U
+approving/EY
+approx
+approximate/XYGNDS
+approximation/M
+appurtenance/SM
+appurtenant
+apricot/MS
+apron/MS
+apropos
+apse/SM
+apt/IYPT
+apter
+aptitude/SM
+aptness/IM
+aqua/SM
+aquaculture/M
+aqualung/MS
+aquamarine/SM
+aquanaut/MS
+aquaplane/MGDS
+aquarium/MS
+aquatic/SM
+aquatically
+aquatics/M
+aquatint/S
+aquavit/M
+aqueduct/MS
+aqueous
+aquifer/SM
+aquiline
+arabesque/MS
+arability/M
+arachnid/MS
+arachnoid
+arachnophobia
+arbiter/SM
+arbitrage/MZGDRS
+arbitrager/M
+arbitrageur/MS
+arbitrament/MS
+arbitrarily
+arbitrariness/M
+arbitrary/P
+arbitrate/GNDS
+arbitration/M
+arbitrator/SM
+arbor/MS
+arboreal
+arbores
+arboretum/SM
+arborvitae/SM
+arbutus/MS
+arc/SMDG
+arcade/MGS
+arcana
+arcane/PY
+arch/PZTGVMDRSY
+archaeological/Y
+archaeologist/SM
+archaeology/M
+archaic
+archaically
+archaism/MS
+archaist/MS
+archangel/MS
+archbishop/SM
+archbishopric/MS
+archdeacon/SM
+archdeaconry
+archdiocesan
+archdiocese/SM
+archduchess/MS
+archduke/MS
+archenemy/SM
+archeological/Y
+archeologist/SM
+archeology/M
+archeopteryx
+archer/M
+archery/M
+archetypal
+archetype/MS
+archfiend/MS
+archiepiscopal
+archipelago/MS
+architect/SM
+architectonic/S
+architectonics/M
+architectural/Y
+architecture/SM
+architrave/SM
+archival
+archive/DSMG
+archived/U
+archivist/MS
+archness/M
+archway/SM
+arctic/MS
+ardency
+ardent/Y
+ardor/MS
+arduous/YP
+arduousness/M
+are/SMB
+area/SM
+areal
+aren't
+arena/MS
+argent/M
+argon/M
+argosy/SM
+argot/MS
+arguable/IU
+arguably/U
+argue/ZGDRS
+arguer/M
+argument/MS
+argumentation/M
+argumentative/YP
+argumentativeness/M
+argyle/MS
+aria/SM
+arid/TRY
+aridity/M
+aright
+arise/GS
+arisen
+aristocracy/SM
+aristocrat/SM
+aristocratic
+aristocratically
+arithmetic/M
+arithmetical/Y
+arithmetician/SM
+ark/SM
+arm's
+arm/EAGDS
+armada/MS
+armadillo/SM
+armament/AEM
+armaments
+armature/MS
+armband/MS
+armchair/MS
+armed/U
+armful/MS
+armhole/SM
+armistice/SM
+armless
+armlet/MS
+armload/S
+armor/ZGMDRS
+armored/U
+armorer/M
+armorial
+armory/SM
+armpit/MS
+armrest/SM
+army/SM
+aroma/MS
+aromatherapist/MS
+aromatherapy/M
+aromatic/MS
+aromatically
+aromaticity
+arose
+around
+arousal/M
+arouse/GDS
+aroused/U
+arpeggio/MS
+arr
+arraign/DGSL
+arraignment/MS
+arrange/AESDLG
+arrangeable
+arrangement's/E
+arrangement/ASM
+arranger/SM
+arrant
+arras/MS
+array/EGMDS
+arrears/M
+arrest/AGMDS
+arrestable
+arrhythmia/M
+arrhythmic
+arrhythmical
+arrival/MS
+arrive/GDS
+arrogance/M
+arrogant/Y
+arrogate/GNDS
+arrogation/M
+arrow/GMDS
+arrowhead/MS
+arrowroot/M
+arroyo/MS
+arsed
+arsenal/MS
+arsenic/M
+arsenide
+arsing
+arson/M
+arsonist/SM
+art/SM
+artefactual
+arterial
+arteriole/MS
+arteriosclerosis/M
+artery/SM
+artful/PY
+artfulness/M
+arthritic/MS
+arthritis/M
+arthropod/MS
+arthroscope/SM
+arthroscopic
+artichoke/SM
+article/MDS
+articulacy/I
+articular
+articulate/PXDSYGN
+articulateness/IM
+articulation/M
+articulatory
+artifact/SM
+artifice/RSMZ
+artificer/M
+artificial/Y
+artificiality/M
+artillery/M
+artilleryman/M
+artillerymen
+artiness/M
+artisan/MS
+artist/MS
+artiste/MS
+artistic/I
+artistically
+artistry/M
+artless/PY
+artlessness/M
+artsy/TR
+artwork/MS
+arty/PTR
+arugula
+arum/SM
+asap
+asbestos/M
+asbestosis
+ascend/AGDS
+ascendancy/M
+ascendant/SM
+ascension/MS
+ascent/MS
+ascertain/BLGDS
+ascertainment/M
+ascetic/MS
+ascetically
+asceticism/M
+ascorbic
+ascot/MS
+ascribe/GBDS
+ascription/MS
+aseptic
+aseptically
+asexual/Y
+asexuality/M
+ash/MDNSG
+ashamed/UY
+ashcan/MS
+ashlar/MS
+ashore
+ashram/MS
+ashtray/SM
+ashy/TR
+aside/MS
+asinine/Y
+asininity/SM
+ask/SDG
+askance
+asked/U
+askew
+aslant
+asleep
+asocial
+asp/SMNX
+asparagus/M
+aspartame/M
+aspect/MS
+aspen/M
+asperity/SM
+aspersion/MS
+asphalt/MDGS
+asphodel/SM
+asphyxia/M
+asphyxiate/DSGNX
+asphyxiation/M
+aspic/MS
+aspidistra/MS
+aspirant/MS
+aspirate/MGNDSX
+aspiration/M
+aspirational
+aspirator/SM
+aspire/GDS
+aspirin/MS
+ass/MS
+assail/GBDS
+assailable/U
+assailant/SM
+assailed/U
+assassin/SM
+assassinate/GNDSX
+assassination/M
+assault/MDRGS
+assay/ZGMDRS
+assayer/M
+assemblage/MS
+assemble/EADSG
+assembler/MS
+assemblies
+assembly/AM
+assemblyman/M
+assemblymen
+assemblywoman/M
+assemblywomen
+assent/GMDS
+assert/AGVDS
+assertion/AM
+assertions
+assertive/YP
+assertiveness/M
+assess/ALGDS
+assessable
+assessment/ASM
+assessor/MS
+asset/MS
+asseverate/DSGN
+asseveration/M
+asshole/SM!
+assiduity/M
+assiduous/PY
+assiduousness/M
+assign's
+assign/ALGDS
+assignable
+assignation/SM
+assigned/U
+assignees
+assigner/MS
+assignment/AMS
+assignor/MS
+assimilable
+assimilate/DSGN
+assimilation/M
+assist/GMDS
+assistance/M
+assistant/SM
+assisted/U
+assize/MS
+assn
+assoc
+associate's
+associate/EDSGNV
+associated/U
+associateship
+association/EM
+associational
+associations
+associative/Y
+associativity
+assonance/M
+assonant/MS
+assort/GLDS
+assortment/SM
+asst
+assuage/GDS
+assuaged/U
+assume/BGDS
+assuming/AU
+assumption/MS
+assumptive
+assurance/ASM
+assure/AGDS
+assured/MYS
+astatine/M
+aster/EMS
+asterisk/GMDS
+astern
+asteroid/MS
+asthma/M
+asthmatic/SM
+asthmatically
+astigmatic
+astigmatism/SM
+astir
+astonish/DSGL
+astonishing/Y
+astonishment/M
+astound/GDS
+astounding/Y
+astraddle
+astrakhan/M
+astral/Y
+astray
+astride
+astringency/M
+astringent/MYS
+astrolabe/SM
+astrologer/SM
+astrological/Y
+astrologist/SM
+astrology/M
+astronaut/MS
+astronautic/S
+astronautical
+astronautics/M
+astronomer/SM
+astronomic
+astronomical/Y
+astronomy/M
+astrophysical
+astrophysicist/MS
+astrophysics/M
+astute/PYTR
+astuteness/M
+asunder
+asylum/SM
+asymmetric
+asymmetrical/Y
+asymmetry/SM
+asymptomatic
+asymptote/S
+asymptotic
+asymptotically
+asynchronous/Y
+at
+atavism/M
+atavist/SM
+atavistic
+ataxia/M
+ataxic/MS
+ate
+atelier/SM
+atheism/M
+atheist/MS
+atheistic
+atheistically
+atherosclerosis/M
+athirst
+athlete/MS
+athletic/S
+athletically
+athleticism
+athletics/M
+athwart
+atilt
+atishoo
+atlantes
+atlas/MS
+atmosphere/SM
+atmospheric/S
+atmospherically
+atmospherics/M
+atoll/MS
+atom/SM
+atomic
+atomically
+atomicity
+atomistic
+atomization
+atomize/ZGDRS
+atomizer/M
+atonal/Y
+atonality/M
+atone/LGDS
+atonement/M
+atop
+atria
+atrial
+atrium/M
+atrocious/PY
+atrociousness/M
+atrocity/SM
+atrophy/DSMG
+atropine/M
+attach/ALGDS
+attache/BM
+attached/U
+attachment/AM
+attachments
+attack/ZGMDRS
+attacker/M
+attain/AGDS
+attainability/M
+attainable/U
+attainder/M
+attained/U
+attainment/MS
+attar/M
+attempt's
+attempt/ASDG
+attend/SDRZG
+attendance/MS
+attendant/SM
+attended/U
+attendee/SM
+attention/IM
+attentional
+attentions
+attentive/IYP
+attentiveness/IM
+attenuate/DSGN
+attenuated/U
+attenuation/M
+attenuator/S
+attest/SDG
+attestation/MS
+attested/U
+attic/SM
+attire/DSMG
+attitude/SM
+attitudinal
+attitudinize/GDS
+attn
+attorney/MS
+attract/SGVDB
+attractant/SM
+attraction/SM
+attractive/UPY
+attractiveness/M
+attractor/S
+attributable/U
+attribute/BXDSMGNV
+attributed/U
+attribution/M
+attributive/SMY
+attrition/M
+attune/DSG
+atty
+atwitter
+atypical/Y
+aubergine/S
+auburn/M
+auction/MDGS
+auctioneer/SM
+audacious/PY
+audaciousness/M
+audacity/M
+audibility/IM
+audible/MS
+audibly/I
+audience/MS
+audio/MS
+audiological
+audiologist/MS
+audiology/M
+audiometer/SM
+audiophile/MS
+audiotape/SM
+audiovisual/S
+audiovisuals/M
+audit/GVMDS
+audited/U
+audition/SMDG
+auditor/MS
+auditorium/SM
+auditory
+auger/MS
+aught/MS
+augite
+augment/DRZGS
+augmentation/SM
+augmentative
+augmenter/M
+augur/GMDS
+augury/SM
+august/PTRY
+augustness/M
+auk/SM
+aunt/SM
+auntie/SM
+aura/MS
+aural/Y
+aureole/SM
+auric
+auricle/SM
+auricular
+aurora/SM
+auroral
+auscultate/XDSGN
+auscultation/M
+auspice/SM
+auspicious/IY
+auspiciousness/M
+austere/RYT
+austerity/SM
+austral
+auteur
+authentic/IU
+authentically
+authenticate/GNDSX
+authenticated/U
+authentication/M
+authenticator/S
+authenticity/M
+author/SMDG
+authoress/MS
+authorial
+authoritarian/SM
+authoritarianism/M
+authoritative/YP
+authoritativeness/M
+authority/SM
+authorization/MS
+authorize/AGDS
+authorized/U
+authorship/M
+autism/M
+autistic
+auto/MS
+autobahn/SM
+autobiographer/SM
+autobiographic
+autobiographical/Y
+autobiography/SM
+autoclave/MS
+autocracy/SM
+autocrat/SM
+autocratic
+autocratically
+autocross
+autocue
+autodidact/MS
+autograph/MDG
+autographs
+autoignition
+autoimmune
+autoimmunity/M
+automaker/SM
+automate/GNDS
+automatic/SM
+automatically
+automation/M
+automatism/M
+automatize/GDS
+automaton/SM
+automobile/MGDS
+automorphism/S
+automotive
+autonomic
+autonomous/Y
+autonomy/M
+autopilot/SM
+autopsy/GDSM
+autosuggestion
+autoworker/MS
+autumn/SM
+autumnal
+aux
+auxiliary/SM
+auxin/M
+av/RZ
+avail/BGMDS
+availabilities
+availability/UM
+available/U
+avalanche/SM
+avarice/M
+avaricious/YP
+avast
+avatar/MS
+avaunt
+avdp
+ave
+avenge/ZGDRS
+avenged/U
+avenger/M
+avenue/MS
+average/MYGDS
+averred
+averring
+averse/XNV
+aversion/M
+avert/GDS
+avg
+avian
+aviary/SM
+aviation/M
+aviator/MS
+aviatrices
+aviatrix/MS
+avid/TRY
+avidity/M
+avionic/S
+avionics/M
+avitaminosis/M
+avocado/SM
+avocation/MS
+avocational
+avoid/SDGB
+avoidable/U
+avoidably/U
+avoidance/M
+avoirdupois/M
+avouch/DSG
+avow/EDGS
+avowal/ESM
+avowed/Y
+avuncular/Y
+aw
+await/GDS
+awake/GS
+awaken/AGDS
+awakened/U
+awakening/SM
+award/GMDS
+aware/UPT
+awareness/UM
+awarer
+awash
+away
+awe/DSMG
+aweigh
+awesome/YP
+awesomeness/M
+awestruck
+awful/YP
+awfuller
+awfullest
+awfulness/M
+awhile
+awkward/RYPT
+awkwardness/M
+awl/SM
+awn/GJSM
+awning/M
+awoke
+awoken
+awry
+ax/MDSG
+axe/M
+axehead/S
+axeman
+axial/Y
+axillary
+axiom/SM
+axiomatic
+axiomatically
+axiomatizing
+axis/MS
+axle/MS
+axletree/SM
+axolotl/SM
+axon/MS
+ayah/M
+ayahs
+ayatollah/M
+ayatollahs
+aye/SM
+azalea/SM
+azimuth/M
+azimuthal
+azimuths
+azure/SM
+b/KDT
+baa/SMDG
+babble/MZGDRS
+babbler/M
+babe/SM
+babel/MS
+baboon/MS
+babushka/SM
+baby/TGDRSM
+babyhood/M
+babyish
+babysat
+babysit/S
+babysitter/SM
+babysitting/M
+baccalaureate/MS
+baccarat/M
+bacchanal/MS
+bacchanalia/M
+bacchanalian/MS
+baccy
+bachelor/SM
+bachelorhood/M
+bacillary
+bacilli
+bacillus/M
+back/SJZGMDR
+backache/MS
+backbench/S
+backbit
+backbite/ZGRS
+backbiter/M
+backbitten
+backboard/SM
+backbone/MS
+backbreaking
+backchat
+backcloth
+backcloths
+backcomb/DSG
+backdate/GDS
+backdoor
+backdrop/MS
+backer/M
+backfield/SM
+backfire/MGDS
+backgammon/M
+background/MRSZ
+backgrounder/M
+backhand/MDRSZG
+backhanded/Y
+backhander/M
+backhoe/MS
+backing/M
+backlash/MS
+backless
+backlog/MS
+backlogged
+backlogging
+backpack/ZGMDRS
+backpacker/M
+backpacking/M
+backpedal/SDG
+backrest/SM
+backroom/S
+backscratching/M
+backseat/SM
+backside/SM
+backslapper/MS
+backslapping/M
+backslash/MS
+backslid
+backslide/RSZG
+backslider/M
+backspace/DSMG
+backspin/M
+backstabber/MS
+backstabbing
+backstage/M
+backstair/S
+backstop/SM
+backstopped
+backstopping
+backstreet/S
+backstretch/MS
+backstroke/MGDS
+backtalk/M
+backtrack/GSD
+backup/MS
+backward/SPY
+backwardness/M
+backwash/M
+backwater/SM
+backwoods/M
+backwoodsman/M
+backwoodsmen
+backyard/SM
+bacon/M
+bacteria/SM
+bacterial
+bactericidal
+bactericide/SM
+bacteriologic
+bacteriological
+bacteriologist/MS
+bacteriology/M
+bacteriophage
+bacterium/M
+bad/MYP
+badder
+baddest
+baddie/MS
+bade
+badge/MZDRS
+badger/GMD
+badinage/M
+badlands/M
+badman/M
+badmen
+badminton/M
+badmouth/GD
+badmouths
+badness/M
+baffle/MZGDRSL
+bafflement/M
+baffler/M
+bag/SM
+bagatelle/SM
+bagel/MS
+bagful/MS
+baggage/M
+bagged
+baggie/M
+baggily
+bagginess/M
+bagging
+baggy/PTRS
+bagpipe/MZRS
+bagpiper/M
+baguette/MS
+bah
+baht/SM
+bail/SBGMD
+bailey/S
+bailiff/S
+bailiwick/MS
+bailout/SM
+bailsman/M
+bailsmen
+bairn/MS
+bait/SGMD
+baize/M
+bake/DRSMZG
+baked/U
+bakehouse
+baker/M
+bakery/SM
+bakeshop/MS
+baklava/M
+baksheesh/M
+balaclava/MS
+balalaika/MS
+balance's
+balance/UDSG
+balanced/A
+balboa/SM
+balcony/SM
+bald/STGPDRY
+balderdash/M
+baldfaced
+baldness/M
+baldric/SM
+baldy/S
+bale/DRSMZG
+baleen/M
+baleful/PY
+balefuller
+balefullest
+balefulness/M
+baler/M
+balk/SGMD
+balky/RT
+ball/SGMD
+ballad/SM
+ballade/S
+balladeer/MS
+balladry/M
+ballast/GSMD
+ballcock/MS
+ballerina/SM
+ballet/SM
+balletic
+ballgame/MS
+ballgirl/S
+ballgown/S
+ballistic/S
+ballistics/M
+balloon/SGMD
+balloonist/MS
+ballot/SMDG
+ballpark/MS
+ballplayer/MS
+ballpoint/MS
+ballroom/MS
+balls/DSG
+ballsy/RT
+bally
+ballyhoo/SMDG
+balm/SM
+balminess/M
+balmy/RTP
+baloney/M
+balsa/MS
+balsam/SM
+balsamic
+baluster/SM
+balustrade/MS
+bamboo/SM
+bamboozle/DSG
+ban/SM
+banal/RYT
+banality/SM
+banana/SM
+band's
+band/ESGD
+bandage/DSMG
+bandanna/MS
+bandbox/MS
+bandeau/M
+bandeaux
+bandit/SM
+banditry/M
+bandleader/S
+bandmaster/SM
+bandoleer/SM
+bandpass
+bandsman/M
+bandsmen
+bandstand/SM
+bandwagon/SM
+bandwidth
+bandwidths
+bandy/DRSTG
+bane/SM
+baneful
+banefuller
+banefullest
+bang/SGMD
+bangle/SM
+bani
+banish/GLDS
+banishment/M
+banister/SM
+banjo/MS
+banjoist/SM
+bank/SZGBMDR
+bankbook/SM
+bankcard/SM
+banker/M
+banking/M
+banknote/SM
+bankroll/SGMD
+bankrupt/SGMD
+bankruptcy/SM
+banned/U
+banner/SM
+banning/U
+bannock/MS
+banns/M
+banquet/ZGMDRS
+banqueter/M
+banquette/SM
+banshee/MS
+bantam/SM
+bantamweight/SM
+banter/GSMD
+bantering/Y
+banyan/SM
+banzai/SM
+baobab/SM
+bap/S
+baptism/MS
+baptismal
+baptist/S
+baptistery/SM
+baptize/ZGDRS
+baptized/U
+baptizer/M
+bar's
+bar/ECUTS
+barb/SZGMDR
+barbarian/SM
+barbarianism/SM
+barbaric
+barbarically
+barbarism/SM
+barbarity/SM
+barbarize/DSG
+barbarous/Y
+barbecue/DSMG
+barbel/SM
+barbell/MS
+barber/GMD
+barberry/SM
+barbershop/MS
+barbie/S
+barbiturate/SM
+barbwire/M
+barcarole/SM
+bard/SM
+bardic
+bare/DRSPYG
+bareback/D
+barefaced/Y
+barefoot/D
+barehanded
+bareheaded
+barelegged
+bareness/M
+barf/SGMDY
+barfly/SM
+bargain/MDRZGS
+bargainer/M
+barge/MGDS
+bargeman/M
+bargemen
+bargepole
+barhop/S
+barhopped
+barhopping
+baritone/MS
+barium/M
+bark's
+bark/CSGD
+barkeep/ZMRS
+barkeeper/M
+barker/SM
+barley/M
+barleycorn/S
+barmaid/MS
+barman/M
+barmen
+barmy/RT
+barn/SM
+barnacle/MDS
+barney/S
+barnstorm/ZGSDR
+barnstormer/M
+barnyard/SM
+barometer/MS
+barometric
+barometrically
+baron/MS
+baronage/MS
+baroness/MS
+baronet/MS
+baronetcy/SM
+baronial
+barony/SM
+baroque/M
+barrack/MDGS
+barracuda/SM
+barrage/MGDS
+barre/MGJDS
+barred/UEC
+barrel/GSMD
+barren/TPSMR
+barrenness/M
+barrette/SM
+barricade/MGDS
+barrier/MS
+barring/ECU
+barrio/SM
+barrister/MS
+barroom/MS
+barrow/SM
+bartender/SM
+barter/ZGSMDR
+barterer/M
+barycenter
+barycentric
+baryon/SM
+basal/Y
+basalt/SM
+basaltic
+base's
+base/CDRSLTG
+baseball/SM
+baseboard/MS
+baseless
+baseline/MS
+basely
+baseman/M
+basemen
+basement/CMS
+baseness/M
+bash/GMDS
+bashful/PY
+bashfulness/M
+bashing/M
+basic/MS
+basically
+basil/M
+basilica/MS
+basilisk/MS
+basin/MS
+basinful/MS
+basis/M
+bask/SGD
+basket/SM
+basketball/MS
+basketful
+basketry/M
+basketwork/M
+basque/S
+bass/MS
+basset/SM
+bassinet/MS
+bassist/MS
+basso/MS
+bassoon/MS
+bassoonist/MS
+basswood/MS
+bast/M
+bastard/MS
+bastardization/MS
+bastardize/GDS
+bastardy/M
+baste/ZGNXDRS
+baster/M
+bastion/M
+bat/SM
+batch/MDSG
+bate/KACGSD
+bath/ZGMDRS
+bathe/M
+bather/M
+bathetic
+bathhouse/MS
+bathing/M
+bathmat/MS
+bathos/M
+bathrobe/SM
+bathroom/SM
+baths
+bathtub/MS
+bathwater
+bathysphere/SM
+batik/MS
+batiste/M
+batman/M
+batmen
+baton/MS
+batsman/M
+batsmen
+battalion/SM
+batted
+batten/GSMD
+batter/JZGSMDR
+batterer/M
+battery/SM
+batting/M
+battle/LDRSMZG
+battledore/SM
+battledress
+battlefield/MS
+battlefront/SM
+battleground/MS
+battlement/SM
+battler/M
+battleship/MS
+batty/RT
+bauble/SM
+baud/SM
+bauxite/M
+bawd/SM
+bawdily
+bawdiness/M
+bawdy/PRT
+bawl/SGMD
+bay/SMDG
+bayberry/SM
+bayonet/SMDG
+bayou/MS
+bazaar/SM
+bazillion/S
+bazooka/SM
+bbl
+bdrm
+be
+beach/MDSG
+beachcomber/MS
+beachfront
+beachhead/MS
+beachwear/M
+beacon/SM
+bead/SGMD
+beading/M
+beadle/SM
+beady/RT
+beagle/SM
+beak/SZMDR
+beaker/M
+beam/SGMD
+bean/SGMD
+beanbag/MS
+beanfeast/S
+beanie/SM
+beanpole/MS
+beansprout/S
+beanstalk/MS
+bear/SZGBJMR
+bearable/U
+bearably/U
+beard/MDGS
+beardless
+bearer/M
+bearing/M
+bearish/PY
+bearishness/M
+bearlike
+bearskin/MS
+beast/MS
+beastliness/M
+beastly/TPRM
+beat/SZGBMNRJ
+beatable/U
+beaten/U
+beater/M
+beatific
+beatifically
+beatification/M
+beatify/GDSXN
+beating/M
+beatitude/SM
+beatnik/MS
+beau/SM
+beaut/MS
+beauteous/Y
+beautician/MS
+beautification/M
+beautifier/M
+beautiful/TRY
+beautify/DRSZGN
+beauty/SM
+beaver/SGMD
+bebop/MS
+becalm/GSD
+became
+because
+beck/SM
+beckon/SGD
+becloud/GDS
+become/S
+becoming/UY
+becquerel/S
+bed/SM
+bedaub/GSD
+bedazzle/GLDS
+bedazzlement/M
+bedbug/SM
+bedchamber/S
+bedclothes/M
+bedded
+bedder
+bedding/M
+bedeck/GSD
+bedevil/LGDS
+bedevilment/M
+bedfellow/SM
+bedhead/S
+bedim/S
+bedimmed
+bedimming
+bedizen/GDS
+bedlam/SM
+bedlinen
+bedmaker/S
+bedpan/SM
+bedpost/SM
+bedraggle/GDS
+bedridden
+bedrock/SM
+bedroll/SM
+bedroom/SM
+bedsheets
+bedside/SM
+bedsit/S
+bedsitter/S
+bedsore/SM
+bedspread/SM
+bedstead/SM
+bedtime/SM
+bee/RSMZGJ
+beebread/M
+beech/MS
+beechnut/MS
+beechwood
+beef/SGMD
+beefburger/MS
+beefcake/MS
+beefeater
+beefiness/M
+beefsteak/MS
+beefy/RPT
+beehive/MS
+beekeeper/MS
+beekeeping/M
+beeline/MS
+been
+beep/SZGMDR
+beeper/M
+beer/M
+beermat/S
+beery/TR
+beeswax/M
+beet/SM
+beetle/MGDS
+beetroot/S
+beeves
+befall/SGN
+befell
+befit/S
+befitted
+befitting/Y
+befog/S
+befogged
+befogging
+before
+beforehand
+befoul/DGS
+befriend/SGD
+befuddle/GDSL
+befuddlement/M
+beg/S
+began
+beget/S
+begetter/S
+begetting
+beggar/MDYGS
+beggary/M
+begged
+begging
+begin/S
+beginner/SM
+beginning/MS
+begone
+begonia/SM
+begot
+begotten
+begrime/DSG
+begrudge/DSG
+begrudging/Y
+beguile/DRSZGL
+beguilement/M
+beguiler/M
+beguiling/Y
+beguine/SM
+begum/MS
+begun
+behalf/M
+behalves
+behave/GDS
+behavior/SM
+behavioral/Y
+behaviorism/M
+behaviorist/SM
+behead/DGS
+beheld
+behemoth/M
+behemoths
+behest/MS
+behind/MS
+behindhand
+behold/NRZGS
+beholder/M
+behoove/DSG
+beige/M
+being/M
+bejewel/SDG
+belabor/SDG
+belated/PY
+belay/GDS
+belch/GMDS
+beleaguer/SGD
+belfry/SM
+belie/DS
+belief/EUM
+beliefs
+believability/U
+believable/U
+believably/U
+believe/EDRSZG
+believed/U
+believer/EUMS
+believing/U
+belittle/DSLG
+belittlement/M
+bell/SGMD
+belladonna/M
+bellboy/SM
+belle/MS
+belled/A
+belletrist/SM
+belletristic
+bellhop/SM
+bellicose
+bellicosity/M
+belligerence/M
+belligerency/M
+belligerent/SMY
+belling/A
+bellman/M
+bellmen
+bellow/MDGS
+bellwether/MS
+belly/GDSM
+bellyache/MGDS
+bellybutton/MS
+bellyful/MS
+belong/JDGS
+belonging/M
+beloved/SM
+below
+belt/SGMD
+beltway/SM
+beluga/MS
+belying
+bemire/GDS
+bemoan/DGS
+bemuse/LGDS
+bemused/Y
+bemusement/M
+bench/GMDS
+benchmark/GMS
+bend/BSZGMDR
+bender/M
+bendy/TR
+beneath
+benedictine
+benediction/SM
+benedictory
+benefaction/SM
+benefactor/MS
+benefactress/MS
+benefice/SM
+beneficence/M
+beneficent/Y
+beneficial/Y
+beneficiary/SM
+benefit/SMDG
+benevolence/MS
+benevolent/Y
+benighted/Y
+benign/Y
+benignant
+benignity/M
+bent/SM
+bentwood/M
+benumb/DSG
+benzene/M
+benzine/M
+bequeath/DG
+bequeaths
+bequest/MS
+berate/GDS
+bereave/DSLG
+bereavement/MS
+bereft
+beret/MS
+berg/SM
+beriberi/M
+berk/S
+berkelium/M
+berm/SM
+berry/GDSM
+berrylike
+berserk
+berth/GMD
+berths
+beryl/MS
+beryllium/M
+beseech/ZGRS
+beseecher/M
+beseeching/Y
+beseem/DSG
+beset/S
+besetting
+beside/S
+besiege/ZGDRS
+besieger/M
+besmear/DSG
+besmirch/GDS
+besom/MS
+besot/S
+besotted
+besotting
+besought
+bespangle/DSG
+bespatter/GSD
+bespeak/SG
+bespectacled
+bespoke
+bespoken
+best/SGMD
+bestial/Y
+bestiality/M
+bestiary/SM
+bestir/S
+bestirred
+bestirring
+bestow/DGS
+bestowal/SM
+bestrew/SDG
+bestrewn
+bestridden
+bestride/SG
+bestrode
+bestseller/MS
+bestselling
+bet/SM
+beta/SM
+betake/GS
+betaken
+betcha
+betel/M
+bethink/SG
+bethought
+betide/GDS
+betimes
+betoken/GDS
+betook
+betray/DRZGS
+betrayal/SM
+betrayer/M
+betroth/DG
+betrothal/SM
+betrothed/M
+betroths
+better/MDGLS
+betterment/M
+betting
+bettor/MS
+between
+betwixt
+bevel/JGMDS
+beverage/SM
+bevvy/S
+bevy/SM
+bewail/DGS
+beware/GDS
+bewhiskered
+bewigged
+bewilder/SLGD
+bewildering/Y
+bewilderment/M
+bewitch/GLDS
+bewitching/Y
+bewitchment/M
+bey/SM
+beyond
+bezel/MS
+bf
+bhaji
+bi/SMRZ
+biannual/Y
+bias/GMDS
+biathlon/SM
+bib/SM
+bible/MS
+biblical
+biblicists
+bibliographer/SM
+bibliographic
+bibliographical/Y
+bibliography/SM
+bibliophile/SM
+bibulous
+bicameral
+bicameralism/M
+bicarb/MS
+bicarbonate/MS
+bicentenary/SM
+bicentennial/SM
+bicep/MS
+biceps/M
+bicker/MDRZGS
+bickerer/M
+biconcave
+biconvex
+bicuspid/MS
+bicycle/DRSMZG
+bicycler/M
+bicyclist/SM
+bid/SMG
+biddable
+bidden/U
+bidder/MS
+bidding/M
+biddy/SM
+bide/S
+bidet/MS
+bidirectional/Y
+biennial/MYS
+biennium/MS
+bier/M
+biff/SGD
+bifocal/S
+bifocals/M
+bifurcate/DSXGN
+bifurcation/M
+big/P
+bigamist/SM
+bigamous
+bigamy/M
+bigger
+biggest
+biggie/MS
+biggish
+bighead/SM
+bighearted/P
+bigheartedness/M
+bighorn/SM
+bight/MS
+bigmouth/M
+bigmouths
+bigness/M
+bigot/MDS
+bigotry/SM
+bigwig/MS
+bijou/M
+bijoux
+bike/DRSMZG
+biker/M
+bikini/MS
+bilabial/MS
+bilateral/Y
+bilberry/S
+bile/M
+bilge/MS
+bilharzia
+biliary
+bilingual/SMY
+bilingualism/M
+bilious/P
+biliousness/M
+bilk/SZGDR
+bilker/M
+bill/SBJGMD
+billboard/MS
+billet/GMDS
+billfold/SM
+billhook/S
+billiard/S
+billiards/M
+billing/M
+billingsgate/M
+billion/MHS
+billionaire/MS
+billionth/M
+billionths
+billow/GMDS
+billowy/RT
+billposters
+billy/SM
+billycan/S
+bimbo/MS
+bimetallic/SM
+bimetallism/M
+bimodal
+bimonthly/SM
+bin/SM
+binary/SM
+bind's
+bind/AUGS
+binder/MS
+bindery/SM
+binding/MS
+bindweed/M
+binge/MGDS
+bingo/M
+binman
+binmen
+binnacle/SM
+binned
+binning
+binocular/MS
+binodal
+binomial/SM
+bio/SM
+biochemical/SMY
+biochemist/MS
+biochemistry/M
+biodegradability/M
+biodegrade/DSGB
+biodiversity/M
+bioengineering
+bioethics/M
+biofeedback/M
+biog
+biographer/SM
+biographic
+biographical/Y
+biography/SM
+biol
+biologic
+biological/Y
+biologist/MS
+biology/M
+biomass/M
+biomedical
+biometric/S
+biometry
+biomorph
+bionic/S
+bionically
+bionics/M
+biophysical
+biophysicist/MS
+biophysics/M
+biopic/MS
+biopsy/GDSM
+biorhythm/MS
+biosphere/SM
+biota
+biotechnological
+biotechnologist
+biotechnology/M
+biotic
+biotin/M
+bipartisan
+bipartisanship/M
+bipartite
+biped/MS
+bipedal
+bipedalism
+biplane/MS
+bipolar
+bipolarity/M
+biracial
+birch/GMDS
+bird/SZGMDR
+birdbath/M
+birdbaths
+birdbrain/SMD
+birdcage/S
+birder/M
+birdhouse/MS
+birdie/MDS
+birdieing
+birdlike
+birdlime/M
+birdseed/M
+birdsong
+birdtables
+birdwatcher/MS
+birdwatching
+birdying
+birefringence
+birefringent
+biretta/SM
+birth/GMD
+birthday/MS
+birthmark/MS
+birthplace/MS
+birthrate/MS
+birthright/SM
+births/A
+birthstone/MS
+biscuit/SM
+bisect/DGS
+bisection/MS
+bisector/SM
+bisexual/MYS
+bisexuality/M
+bishop/MS
+bishopric/SM
+bismuth/M
+bison/M
+bisque/M
+bistable
+bistro/MS
+bit/CSMG
+bitch/GMDS
+bitchily
+bitchiness/M
+bitchy/PRT
+bite/RSMZ
+biter/M
+biting/Y
+bitmap/S
+bitten
+bitter/PMRYTS
+bittern/SM
+bitterness/M
+bitters/M
+bittersweet/MS
+bitty/TPR
+bitumen/M
+bituminous
+bivalent
+bivalve/SM
+bivouac/MS
+bivouacked
+bivouacking
+biweekly/SM
+biyearly
+biz/M
+bizarre/YP
+bk
+bl/D
+blab/SM
+blabbed
+blabber/DGS
+blabbermouth/M
+blabbermouths
+blabbing
+black/PXTGMDNRYS
+blackamoor/MS
+blackball/SMDG
+blackberry/SMG
+blackbird/SM
+blackboard/MS
+blackcurrant/S
+blacken/DG
+blackguard/SM
+blackhead/MS
+blacking/M
+blackish
+blackjack/MDGS
+blackleg/S
+blacklist/MDSG
+blackmail/MDRSZG
+blackmailer/M
+blackness/M
+blackout/SM
+blackshirts
+blacksmith/M
+blacksmiths
+blacksnake/SM
+blackthorn/SM
+blacktop/SM
+blacktopped
+blacktopping
+bladder/MS
+blade/MDS
+blag/S
+blagged
+blagging
+blah/M
+blahs/M
+blame/BMGDRS
+blameless/PY
+blamelessness/M
+blameworthiness/M
+blameworthy/P
+blammo/GDS
+blanch/GDS
+blancmange/MS
+bland/PTRY
+blandish/DSLG
+blandishment/MS
+blandness/M
+blank/TGPMDRYS
+blanket/GMDS
+blankness/M
+blare/MGDS
+blarney/SMDG
+blase
+blaspheme/ZGDRS
+blasphemer/M
+blasphemous/Y
+blasphemy/SM
+blast/ZGMDRS
+blaster/M
+blastoff/MS
+blat/S
+blatancy/SM
+blatant/Y
+blather/SMDG
+blaze/MZGDRS
+blazer/M
+blazon/MDGS
+bldg
+bleach/MDRSZG
+bleached/U
+bleacher/M
+bleak/TPRY
+bleakness/M
+blear
+blearily
+bleariness/M
+bleary/PRT
+bleat/GMDS
+bleed/ZGRS
+bleeder/M
+bleeding/M
+bleep/ZGMDRS
+bleeper/M
+blemish/GMDS
+blemished/U
+blench/DSG
+blend/ZGMDRS
+blender/M
+bless/GDSJ
+blessed/TRYP
+blessedness/M
+blessing/M
+bletch
+blew
+blight/ZGMDRS
+blimey
+blimp/MS
+blimpish
+blind/PZTGMDRYS
+blinder/M
+blindfold/GSMD
+blinding/Y
+blindness/M
+blindside/DSG
+blini/MS
+blink/ZGMDRS
+blinker/MDG
+blintz/MS
+blintze/M
+blip/SM
+bliss/M
+blissful/PY
+blissfulness/M
+blister/GMDS
+blistering/Y
+blistery
+blithe/PYTR
+blitheness/M
+blither/G
+blithesome
+blitz/GMDS
+blitzkrieg/MS
+blivet/S
+blizzard/SM
+bloat/ZGDRS
+bloatware/S
+blob/SM
+blobbed
+blobbing
+bloc/SM
+block's
+block/UGDS
+blockade/MZGDRS
+blockader/M
+blockage/MS
+blockbuster/SM
+blockbusting/M
+blocker/MS
+blockhead/SM
+blockhouse/MS
+blog/S
+blogged
+blogger
+blogging
+bloke/MS
+blokish
+blond/PTMRS
+blondish
+blondness/M
+blood/GMDS
+bloodbath/M
+bloodbaths
+bloodcurdling
+bloodhound/SM
+bloodied/U
+bloodily
+bloodiness/M
+bloodless/YP
+bloodlessness/M
+bloodletting/M
+bloodline/SM
+bloodmobile/SM
+bloodshed/M
+bloodshot
+bloodsport/S
+bloodstain/SMD
+bloodstock/M
+bloodstone
+bloodstream/MS
+bloodsucker/MS
+bloodsucking
+bloodthirstily
+bloodthirstiness/M
+bloodthirsty/TPR
+bloodworm
+bloody/PTGDRS
+bloodymindedness
+bloom/ZGMDRS
+bloomer/M
+bloop/ZGMDRS
+blooper/M
+blossom/GMDS
+blossomy
+blot/SM
+blotch/GMDS
+blotchy/TR
+blotted
+blotter/MS
+blotting
+blotto
+blouse/MGDS
+blow/SZGMR
+blower/M
+blowfly/SM
+blowgun/MS
+blowhard/MS
+blowhole/S
+blowlamp/S
+blown
+blowout/SM
+blowpipe/SM
+blowtorch/MS
+blowup/MS
+blowy/TR
+blowzy/RT
+blubber/GSMD
+blubbery
+bludgeon/MDGS
+blue/DRSPMTG
+bluebell/MS
+blueberry/SM
+bluebird/MS
+bluebonnet/SM
+bluebottle/SM
+bluefish/MS
+bluegill/MS
+bluegrass/M
+blueish
+bluejacket/MS
+bluejeans/M
+blueness/M
+bluenose/MS
+bluepoint/MS
+blueprint/GMDS
+bluestocking/MS
+bluesy/RT
+bluet/MS
+bluff/ZTGPMDRYS
+bluffer/M
+bluffness/M
+bluing/M
+bluish
+blunder/MDRZGJS
+blunderbuss/MS
+blunderer/M
+blunt/PTGDRYS
+bluntness/M
+blur/SM
+blurb/MS
+blurred
+blurriness/M
+blurring
+blurry/TRP
+blurt/GDS
+blush/ZGMDRS
+blusher/M
+blushing/UY
+bluster/MDRSZG
+blusterer/M
+blusterous
+blustery
+blvd
+boa/SM
+boar/SM
+board/JZGMDRS
+boarder/M
+boardgames
+boarding/M
+boardinghouse/SM
+boardroom/MS
+boardwalk/MS
+boast/ZGMDRS
+boaster/M
+boastful/PY
+boastfulness/M
+boat/SZGMDR
+boatclubs
+boater/M
+boathouse/MS
+boating/M
+boatload/S
+boatman/M
+boatmen
+boatswain/SM
+boatyard/S
+bob/SM
+bobbed
+bobbin/MS
+bobbing
+bobble/MGDS
+bobby/SM
+bobcat/MS
+bobolink/SM
+bobsled/SM
+bobsledded
+bobsledder/SM
+bobsledding
+bobsleigh/M
+bobsleighs
+bobtail/SM
+bobwhite/MS
+boccie/M
+bock/M
+bod/SMDG
+bodacious
+bode/S
+bodega/MS
+bodge/GDS
+bodice/MS
+bodiless
+bodily
+bodkin/MS
+body/DSM
+bodybuilder/MS
+bodybuilding/M
+bodyguard/MS
+bodysuit/SM
+bodywork/M
+boffin/S
+boffo
+bog/SM
+boga
+bogey/GMDS
+bogeyman/M
+bogeymen
+bogged
+bogging
+boggle/GDS
+boggling/Y
+boggy/TR
+bogometer/S
+bogon
+bogosity/S
+bogotify/DSG
+bogus
+bogyman/M
+bogymen
+bohemian/SM
+bohemianism/M
+boil/SJZGMDR
+boiled/U
+boiler/M
+boilermaker/SM
+boilerplate/M
+boink/GDS
+boisterous/YP
+boisterousness/M
+bola/SM
+bold/PTRY
+boldface/DM
+boldness/M
+bole/SM
+bolero/MS
+bolivar/MS
+bolivares
+boll/SM
+bollard/S
+bollix/GMDS
+bollocking/S
+bollocks
+bologna/M
+bolshie
+bolster/GMDS
+bolt's
+bolt/USGD
+bolthole/S
+bolus/MS
+bomb/SJZGMDR
+bombard/GDLS
+bombardier/MS
+bombardment/MS
+bombast/M
+bombastic
+bombastically
+bomber/M
+bombproof
+bombshell/SM
+bombsite/S
+bonanza/MS
+bonbon/MS
+bonce/S
+bond/SGMD
+bondage/M
+bondholder/MS
+bonding/M
+bondman/M
+bondmen
+bondsman/M
+bondsmen
+bondwoman/M
+bondwomen
+bone/DRSMZG
+bonehead/SMD
+boneless
+boner/M
+boneshaker/S
+bonfire/MS
+bong/SGMD
+bongo/MS
+bonhomie/M
+boniness/M
+bonito/MS
+bonk/SZGD
+bonnet/MS
+bonny/TR
+bonsai/MS
+bonus/MS
+bony/PTR
+boo/SMDHG
+boob/SGMD
+booby/SM
+boodle/MS
+booger/S
+boogie/MDS
+boogieing
+boogieman/M
+boohoo/GMDS
+book/SBJGMD
+bookbinder/MS
+bookbindery/SM
+bookbinding/M
+bookcase/MS
+booked/U
+bookend/MS
+bookie/MS
+booking/M
+bookish
+bookkeeper/MS
+bookkeeping/M
+booklet/MS
+bookmaker/SM
+bookmaking/M
+bookmark/SMDG
+bookmobile/SM
+bookplate/MS
+bookseller/SM
+bookshelf/M
+bookshelves
+bookshop/SM
+bookstall/S
+bookstore/MS
+bookwork
+bookworm/SM
+boom/SZGMDR
+boomerang/MDGS
+boon/SM
+boondocks/M
+boondoggle/MZGDRS
+boondoggler/M
+boonies/M
+boor/SM
+boorish/PY
+boorishness/MS
+boost/ZGMDRS
+booster/M
+boot's
+boot/ASGD
+bootblack/SM
+bootee/MS
+booth/M
+booths
+bootlace/S
+bootleg/MS
+bootlegged
+bootlegger/SM
+bootlegging/M
+bootless
+bootprints
+bootstrap/MS
+bootstrapped
+bootstrapping
+booty/SM
+booze/MZGDRS
+boozer/M
+boozy/TR
+bop/SM
+bopped
+bopping
+borax/M
+bordello/MS
+border/GMDS
+borderland/SM
+borderline/SM
+bore/DRSMZG
+boredom/M
+borehole/S
+borer/M
+boring/Y
+born/IAU
+borne
+boron/M
+borough/M
+boroughs
+borrow/SDRZGBJ
+borrower/M
+borrowing/M
+borscht/M
+borstal/S
+borzoi/SM
+bosh/M
+bosom's
+bosom/US
+bosomy/RT
+boson/S
+boss/DRSGM
+bossily
+bossiness/M
+bossism/M
+bossy/RTP
+bot/S
+botanic
+botanical/Y
+botanist/SM
+botany/M
+botch/DRSZGM
+botcher/M
+both
+bother/SMDG
+botheration
+bothersome
+bothy
+bottle/DRSMZG
+bottleneck/MS
+bottler/M
+bottom/SMDG
+bottomless
+bottommost
+botulism/M
+boudoir/SM
+bouffant/SM
+bougainvillea/SM
+bough/M
+boughs
+bought
+bouillabaisse/SM
+bouillon/MS
+boulder/SM
+boules
+boulevard/SM
+bounce/DRSMZG
+bouncer/M
+bouncily
+bounciness/M
+bouncy/RTP
+bound/ASMGD
+boundary/SM
+boundedness
+bounden
+bounder/SM
+boundless/YP
+boundlessness/M
+bounteous/PY
+bounteousness/M
+bountiful/PY
+bountifulness/M
+bounty/SM
+bouquet/SM
+bourbon/SM
+bourgeois/M
+bourgeoisie/M
+boustrophedon/S
+bout/MS
+boutique/SM
+boutonniere/SM
+bouzouki/MS
+bovine/SM
+bovver
+bow/ZGSMDR
+bowdlerization/MS
+bowdlerize/DSG
+bowed/U
+bowel/SM
+bower/M
+bowie
+bowl/MDRZGS
+bowleg/SM
+bowlegged
+bowler/M
+bowlful/SM
+bowline/SM
+bowling/M
+bowman/M
+bowmen
+bowsprit/SM
+bowstring/SM
+bowwow/SM
+box/ZGMDNRS
+boxcar/SM
+boxer/M
+boxful
+boxing/M
+boxlike
+boxroom/S
+boxtops
+boxwood/M
+boxy/RT
+boy/SM
+boycott/SGMD
+boyfriend/MS
+boyhood/SM
+boyish/YP
+boyishness/M
+boyscout
+boysenberry/SM
+bozo/MS
+bps
+bra/SM
+brace/MZGDRS
+braced/U
+bracelet/MS
+bracer/M
+bracero/MS
+bracing/Y
+bracken/M
+bracket/GMDS
+bracketed/U
+brackish/P
+brackishness/M
+bract/MS
+brad/SM
+bradawl/S
+brae/SM
+brag/SM
+braggadocio/MS
+braggart/SM
+bragged
+bragger/MS
+bragging
+braid/GMDS
+braiding/M
+braille/M
+brain/GMDS
+braincell/S
+brainchild/M
+brainchildren
+braininess/M
+brainless/YP
+brainpower
+brainstorm/GSMD
+brainstorming/M
+brainteaser/MS
+brainteasing
+brainwash/DSG
+brainwashing/M
+brainwave/S
+brainy/PTR
+braise/GDS
+brake/MGDS
+brakeman/M
+brakemen
+bramble/MS
+brambly/TR
+bran/M
+branch/GMDS
+branchlike
+brand/ZGMDRS
+branded/U
+brander/M
+brandish/DSG
+brandy/GDSM
+brash/PTRY
+brashness/M
+brass/MS
+brasserie/MS
+brassiere/MS
+brassily
+brassiness/M
+brassy/PTR
+brat/SM
+bratty/RT
+bratwurst/SM
+bravado/M
+brave/GPMYDTRS
+braveness/M
+bravery/M
+bravo/SM
+bravura/SM
+brawl/SDRZGM
+brawler/M
+brawn/M
+brawniness/M
+brawny/RTP
+bray/DGSM
+braze/DRSZG
+brazen/SDYGP
+brazenness/M
+brazer/M
+brazier/SM
+breach/GMDS
+bread/GMDHS
+breadbasket/SM
+breadboard/MS
+breadbox/MS
+breadcrumb/SM
+breadfruit/SM
+breadline/MS
+breadth/M
+breadths
+breadwinner/MS
+break/BMZGRS
+breakable/MS
+breakage/MS
+breakaway/MS
+breakdown/MS
+breaker/M
+breakfast/GMDS
+breakfront/MS
+breakneck
+breakout/MS
+breakpoints
+breakthrough/M
+breakthroughs
+breakup/SM
+breakwater/SM
+bream/MS
+breast/SMDG
+breastbone/MS
+breastfed
+breastfeed/GS
+breastplate/MS
+breaststroke/MS
+breastwork/SM
+breath/MDRSZGBJ
+breathalyze/ZGDRS
+breathe
+breather/M
+breathing/M
+breathless/PY
+breathlessness/M
+breaths
+breathtaking/Y
+breathy/RT
+breccias
+brecciated
+bred/I
+breech/MS
+breed/SRZGM
+breeder/M
+breeding/IM
+breeze/DSMG
+breezeway/SM
+breezily
+breeziness/M
+breezy/RTP
+brethren
+breve/SM
+brevet/SM
+brevetted
+brevetting
+breviary/SM
+brevity/M
+brew/MDRZGS
+brewer/M
+brewery/SM
+brewpub/SM
+bribe/DRSMZG
+briber/M
+bribery/M
+brick/SMDG
+brickbat/SM
+brickie/S
+bricklayer/MS
+bricklaying/M
+brickwork/M
+brickyard/S
+bridal/SM
+bride/SM
+bridegroom/SM
+bridesmaid/MS
+bridge/DSMG
+bridgeable/U
+bridged/U
+bridgehead/MS
+bridgework/M
+bridle/DSMG
+bridled/U
+bridleway/S
+brie/MZR
+brief's
+brief/CSDTGJ
+briefcase/SM
+briefer
+briefing/CM
+briefly
+briefness/M
+brier/M
+brig/MS
+brigade/SM
+brigadier/MS
+brigand/SM
+brigandage/M
+brigantine/SM
+bright/SPNRYXT
+brighten/DRZG
+brightener/M
+brightness/MS
+brights/M
+brill
+brilliance/M
+brilliancy/M
+brilliant/MYS
+brilliantine/M
+brim/MS
+brimful
+brimless
+brimmed
+brimming
+brimstone/M
+brindle/DM
+brine/M
+bring/SRZG
+bringer/M
+brininess/M
+brink/SM
+brinkmanship/M
+briny/RTP
+brio
+brioche/SM
+briquette/MS
+brisk/SDRYTGP
+brisket/SM
+briskness/M
+bristle/DSMG
+bristly/TR
+britches/M
+brittle/PRMT
+brittleness/M
+bro/SMH
+broach/MDSG
+broad/SMNRYXTP
+broadband/M
+broadcast/AMGS
+broadcaster/SM
+broadcasting/M
+broadcloth/M
+broaden/DG
+broadleaved
+broadloom/M
+broadminded/P
+broadness/M
+broadsheet/SM
+broadside/MGDS
+broadsword/MS
+brocade/DSMG
+broccoli/M
+brochette/SM
+brochure/MS
+brogan/SM
+brogue/SM
+broil/SMDRZG
+broiler/M
+broke/G
+broken/YP
+brokenhearted/Y
+brokenness/M
+broker/SMDG
+brokerage/MS
+brolly/S
+bromide/SM
+bromidic
+bromine/M
+bronc/SM
+bronchi
+bronchial
+bronchitic
+bronchitis/M
+bronchus/M
+bronco/SM
+broncobuster/MS
+brontosaur/SM
+brontosaurus/MS
+bronze/DSMG
+brooch/MS
+brood/SMDRZG
+brooder/M
+broodily
+brooding/MY
+broodmare/MS
+broody/RMPT
+brook/SMDG
+brooklet/SM
+broom/SM
+broomstick/MS
+broth/MRZ
+brothel/MS
+brother/MY
+brotherhood/SM
+brotherliness/M
+broths
+brougham/SM
+brought
+brouhaha/SM
+brow/MS
+browbeat/SNG
+brown/SMDRPTG
+brownfield
+brownie/MS
+brownish
+brownness/M
+brownout/SM
+brownstone/MS
+browse/DRSMZG
+browser/M
+brr
+bruin/SM
+bruise/DRSMZG
+bruised/U
+bruiser/M
+bruising/M
+bruit/SDG
+brunch/MDSG
+brunet/SM
+brunette/MS
+brunt/M
+brush/MDSG
+brushoff/SM
+brushstroke/S
+brushwood/M
+brushwork/M
+brushy
+brusque/RPYT
+brusqueness/M
+brutal/Y
+brutality/SM
+brutalization/M
+brutalize/GDS
+brute/SM
+brutish/PY
+brutishness/M
+bu
+bub/SM
+bubble/DSMG
+bubblegum/M
+bubbly/RMT
+bubo/M
+buboes
+bubonic
+buccaneer/SMDG
+buck/MDGS
+buckaroo/SM
+buckboard/MS
+bucket/SGMD
+bucketful/MS
+buckeye/MS
+buckle's
+buckle/UDSG
+buckler/MS
+buckminsterfullerene
+buckram/M
+bucksaw/MS
+buckshot/M
+buckskin/MS
+buckteeth
+bucktooth/MD
+buckwheat/M
+bucolic/MS
+bucolically
+bud/SM
+budded
+budding/S
+buddy/SM
+budge/DSG
+budgerigar/SM
+budget/SGMD
+budgetary
+budgie/SM
+buff/AMDGS
+buffalo/MDG
+buffaloes
+buffer/SMDG
+buffet/SMDGJ
+buffoon/SM
+buffoonery/M
+buffoonish
+bug's
+bug/CS
+bugaboo/SM
+bugbear/SM
+bugged/C
+bugger/SMDG
+buggery
+bugging/C
+buggy/RSMT
+bugle/DRSMZG
+bugler/M
+build/SMRZGJ
+builder/M
+building/M
+buildup/SM
+built/AI
+bulb/MS
+bulbous
+bulge/DSMG
+bulgy/RT
+bulimarexia/M
+bulimia/M
+bulimic/SM
+bulk/MDGS
+bulkhead/MS
+bulkiness/M
+bulky/RTP
+bull/MDGS
+bulldog/SM
+bulldogged
+bulldogging
+bulldoze/ZGDRS
+bulldozer/M
+bullet/SM
+bulletin/MDGS
+bulletproof/GSD
+bullfight/SMRZG
+bullfighter/M
+bullfighting/M
+bullfinch/MS
+bullfrog/MS
+bullhead/MDS
+bullheaded/YP
+bullheadedness/M
+bullhorn/MS
+bullion/M
+bullish/YP
+bullishness/M
+bullock/SM
+bullpen/SM
+bullring/MS
+bullshit/MS!
+bullshitted/!
+bullshitter's
+bullshitter/S!
+bullshitting/!
+bullwhip/S
+bully/DRSMTG
+bulrush/MS
+bulwark/MS
+bum/SM
+bumbag/S
+bumble/DRSZG
+bumblebee/SM
+bumbler/M
+bumf
+bummed
+bummer/SM
+bummest
+bumming
+bump/MDRZGS
+bumper/M
+bumph
+bumpiness/M
+bumpkin/MS
+bumptious/YP
+bumptiousness/M
+bumpy/PRT
+bun/SM
+bunch/MDSG
+bunchy/RT
+bundle/DSMG
+bundled/U
+bung/MDGS
+bungalow/MS
+bungee/SM
+bunghole/MS
+bungle/DRSMZG
+bungler/M
+bunion/SM
+bunk's
+bunk/CDGS
+bunker/SM
+bunkhouse/SM
+bunkum/M
+bunny/SM
+bunt/MDGSJ
+bunting/M
+buoy/MDGS
+buoyancy/M
+buoyant/Y
+bur/SMY
+burble/DSMG
+burbs/M
+burden's
+burden/USGD
+burdensome
+burdock/M
+bureau/SM
+bureaucracy/SM
+bureaucrat/SM
+bureaucratic
+bureaucratically
+bureaucratization/M
+bureaucratize/GDS
+burg/MRZS
+burgeon/DSG
+burger/M
+burgh/MRZ
+burgher/M
+burghs
+burglar/MS
+burglarize/GDS
+burglarproof
+burglary/SM
+burgle/DSG
+burgomaster/MS
+burgundy/SM
+burial/ASM
+buried/U
+burl/MDS
+burlap/M
+burlesque/MGDS
+burliness/M
+burly/RPT
+burn/MDRZGSBJ
+burnable/SM
+burned/U
+burner/M
+burnish/ZGMDRS
+burnisher/M
+burnoose/MS
+burnout/MS
+burnt/U
+burp/MDGS
+burr/MDGS
+burrito/MS
+burro/SM
+burrow/SMDRZG
+burrower/M
+bursa/M
+bursae
+bursar/SM
+bursary/SM
+bursitis/M
+burst/SMG
+bury/ADSG
+bus/AMS
+busboy/SM
+busby/SM
+bused
+busgirl/MS
+bush/MDSGJ
+bushel/SGMD
+bushfire
+bushiness/M
+bushing/M
+bushland
+bushman/M
+bushmaster/SM
+bushmen
+bushwhack/DRSZG
+bushwhacker/M
+bushy/RPT
+busily
+business/MS
+businesslike
+businessman/M
+businessmen
+businesspeople
+businessperson/MS
+businesswoman/M
+businesswomen
+busing/M
+busk/DRZGS
+buskin/SM
+busload/S
+busmen
+buss/MD
+bust/MDRZGS
+bustard/S
+buster/M
+bustle/DSMG
+busty/RZT
+busy/DRSTGP
+busybody/SM
+busyness/M
+busywork/M
+but/ACS
+butane/M
+butch/MRSZ
+butcher/MDG
+butchery/SM
+butler/SM
+butt/MDRZGS
+butte/SM
+butted/A
+butter/MDG
+butterball/MS
+buttercup/SM
+butterfat/M
+butterfingered
+butterfingers/M
+butterfly/GDSM
+buttermilk/M
+butternut/SM
+butterscotch/M
+buttery/TRSM
+butting/A
+buttock/SM
+button's
+button/USDG
+buttonhole/MGDS
+buttonwood/MS
+buttress/MDSG
+butty/S
+buxom/RT
+buy/ZGSMR
+buyback/SM
+buyer/M
+buyout/SM
+buzz/MDRSZG
+buzzard/MS
+buzzer/M
+buzzword/SM
+bx
+bxs
+by/M
+bye/SM
+bygone/SM
+bylaw/SM
+byline/SM
+bypass/GMDS
+bypath/M
+bypaths
+byplay/M
+byproduct/MS
+byre/S
+byroad/SM
+bystander/MS
+byte/MS
+byway/SM
+byword/SM
+byzantine
+c/IES
+ca
+cab/SMRZ
+cabal/MS
+cabala/M
+caballero/MS
+cabana/SM
+cabaret/SM
+cabbage/MS
+cabbed
+cabbing
+cabdriver/SM
+cabin/MS
+cabinet/SM
+cabinetmaker/SM
+cabinetmaking/M
+cabinetry/M
+cabinetwork/M
+cable/MGDS
+cablecast/MGS
+cablegram/MS
+cabochon/SM
+caboodle/M
+caboose/SM
+cabriolet/SM
+cabstand/SM
+cacao/MS
+cache/MGDS
+cachepot/SM
+cachet/MS
+cackle/MZGDRS
+cackler/M
+cacophonous
+cacophony/SM
+cactus/Mi
+cad/SM
+cadaver/SM
+cadaverous
+caddish/YP
+caddishness/M
+caddy/GDSM
+cadence/DSM
+cadenza/SM
+cadet/MS
+cadge/ZGDRS
+cadger/M
+cadmium/M
+cadre/MS
+caducei
+caduceus/M
+caesura/SM
+cafe/SM
+cafeteria/MS
+cafetiere/S
+caff/CS
+caffeinated
+caffeine/M
+caftan/MS
+cage/DSMG
+cagey
+cagier
+cagiest
+cagily
+caginess/M
+cagoule/S
+cahoot/MS
+cairn/MS
+caisson/SM
+caitiff/SM
+cajole/ZGLDRS
+cajolement/M
+cajoler/M
+cajolery/M
+cake/DSMG
+cakewalk/SM
+cal
+calabash/MS
+calaboose/SM
+calamari/SM
+calamine/M
+calamitous/Y
+calamity/SM
+calcareous
+calciferous
+calcification/M
+calcify/GNDS
+calcimine/DSMG
+calcine/DSG
+calcite/M
+calcium/M
+calculable/I
+calculate/AXGNVDS
+calculated/Y
+calculating/Y
+calculation/AM
+calculator/MS
+calculi
+calculus/M
+caldera/SM
+calendar/MDGS
+calender/MDGS
+calf/M
+calfskin/M
+caliber/SM
+calibrate/GNDSX
+calibrated/U
+calibration/M
+calibrator/SM
+calico/M
+calicoes
+californium/M
+caliper/SGMD
+caliph/M
+caliphate/MS
+caliphs
+calisthenic/S
+calisthenics/M
+call/ASGMD
+calla/MS
+callable
+callback/MS
+called/U
+caller/MS
+calligrapher/SM
+calligraphic
+calligraphist/MS
+calligraphy/M
+calling/SM
+calliope/MS
+callosity/SM
+callous/PGDSY
+callousness/M
+callow/RPT
+callowness/M
+callus/MDSG
+calm/PSTGMDRY
+calmness/M
+caloric
+calorie/MS
+calorific
+calorimeter/S
+calorimetry
+calumet/MS
+calumniate/DSGN
+calumniation/M
+calumniator/MS
+calumnious
+calumny/SM
+calve/GDS
+calypso/MS
+calyx/MS
+cam/SM
+camaraderie/M
+camber/MDSG
+cambial
+cambium/SM
+cambric/M
+camcorder/SM
+came
+camel/MS
+camellia/MS
+cameo/MS
+camera/MS
+camerae
+cameraman/M
+cameramen
+camerawoman/M
+camerawomen
+camerawork
+camiknickers
+camisole/SM
+camomile's
+camouflage/MZGDRS
+camouflager/M
+camp's
+camp/CSTGD
+campaign/SMDRZG
+campaigner/M
+campanile/SM
+campanological
+campanologist/SM
+campanology/M
+camper/MS
+campfire/SM
+campground/SM
+camphor/M
+camping/M
+campsite/SM
+campus/MS
+campy/TR
+camshaft/SM
+can't
+can/SMDRJZG
+canal/MS
+canalization/M
+canalize/GDS
+canape/MS
+canard/MS
+canary/SM
+canasta/M
+cancan/MS
+cancel/DRSZG
+canceled/U
+canceler/M
+cancellation/MS
+cancer/MS
+cancerous
+candelabra/SM
+candelabrum/M
+candelas
+candid/RYPT
+candida
+candidacy/SM
+candidate/MS
+candidature/SM
+candidness/M
+candle/MZGDRS
+candlelight/M
+candlelit
+candlepower/M
+candler/M
+candlestick/SM
+candlewick/MS
+candor/M
+candy/GDSM
+candyfloss
+cane/SM
+canebrake/MS
+caner/M
+canine/MS
+canister/SM
+canker/GMDS
+cankerous
+cannabis/MS
+canned
+cannelloni/M
+cannery/SM
+cannibal/SM
+cannibalism/M
+cannibalistic
+cannibalization/M
+cannibalize/DSG
+cannily/U
+canniness/M
+canning
+cannon/GMDS
+cannonade/MGDS
+cannonball/SM
+cannot
+cannula
+canny/UTR
+canoe/MDS
+canoeing
+canoeist/SM
+canola/M
+canon/MS
+canonical/Y
+canonization/MS
+canonize/DSG
+canoodle/DSG
+canopy/GDSM
+canst
+cant's
+cant/CZRDGS
+cantabile
+cantaloupe/SM
+cantankerous/PY
+cantankerousness/M
+cantata/MS
+canteen/MS
+canter/CM
+cantered
+cantering
+canticle/MS
+cantilever/GSMD
+canto/MS
+canton/MLS
+cantonal
+cantonment/SM
+cantor/MS
+canvas/MGDS
+canvasback/SM
+canvass/MDRSZG
+canvasser/M
+canyon/MGS
+cap/SMDRBZ
+capabilities
+capability/IM
+capable/TR
+capably/I
+capacious/PY
+capaciousness/M
+capacitance/M
+capacities
+capacitive
+capacitor/SM
+capacity/IM
+caparison/MDSG
+cape/SM
+caper/GMD
+capeskin/M
+capillarity/M
+capillary/SM
+capital/MSY
+capitalism/M
+capitalist/SM
+capitalistic
+capitalistically
+capitalization/M
+capitalize/ADSG
+capitation/CSM
+capitol/SM
+capitulate/AGNXDS
+capitulation/AM
+caplet/MS
+capo/SM
+capon/MS
+capped/UA
+capping/UA
+cappuccino/SM
+caprice/SM
+capricious/YP
+capriciousness/M
+capsicum/SM
+capsize/DSG
+capstan/SM
+capstone/MS
+capsular
+capsule/DSMG
+capsulize/DSG
+capt
+captain/SMDG
+captaincy/SM
+caption/SMDG
+captious/YP
+captiousness/M
+captivate/DSGN
+captivation/M
+captivator/SM
+captive/SM
+captivity/SM
+captor/MS
+capture/ADSMG
+car/SMDRZG
+carafe/MS
+caramel/SM
+caramelize/GDS
+carapace/SM
+carat/MS
+caravan/SM
+caravansary/SM
+caravel/SM
+caraway/SM
+carbide/SM
+carbine/SM
+carbohydrate/MS
+carbolic
+carbon/MS
+carbonaceous
+carbonate/MGNDS
+carbonation/M
+carbonic
+carboniferous
+carbonize/GDS
+carbonyl
+carborundum/M
+carboy/MS
+carbuncle/SM
+carbuncular
+carburetor/MS
+carcass/MS
+carcinogen/SM
+carcinogenesis
+carcinogenic/SM
+carcinogenicity/M
+carcinoma/MS
+card/ESGMD
+cardamom/SM
+cardamon/S
+cardboard/M
+carder/MS
+cardholder/S
+cardiac
+cardie/S
+cardigan/SM
+cardinal/SMY
+cardinality
+cardiogram/MS
+cardiograph/M
+cardiographs
+cardioid
+cardiologist/SM
+cardiology/M
+cardiopulmonary
+cardiovascular
+cardsharp/MRZS
+cardsharper/M
+care/SM
+cared/U
+careen/DGS
+career/MDGS
+careerism
+careerist/SM
+carefree
+careful/YP
+carefuller
+carefullest
+carefulness/M
+caregiver/SM
+careless/YP
+carelessness/M
+carer/M
+caress/MDSG
+caret/MS
+caretaker/MS
+careworn
+carfare/M
+cargo/M
+cargoes
+carhop/MS
+caribou/SM
+caricature/MGDS
+caricaturisation
+caricaturist/MS
+caricaturization
+caries/M
+carillon/SM
+caring/M
+carious
+carjack/JSDRZG
+carjacker/M
+carjacking/M
+carload/SM
+carmine/SM
+carnage/M
+carnal/Y
+carnality/M
+carnation/IMS
+carnelian/MS
+carnival/MS
+carnivore/SM
+carnivorous/YP
+carnivorousness/M
+carny/SM
+carob/MS
+carol/ZGMDRS
+caroler/M
+carom/GMDS
+carotene/M
+carotid/SM
+carousal/SM
+carouse/DRSMZG
+carousel/SM
+carouser/M
+carp/SZGMDR
+carpal/MS
+carpel/MS
+carpenter/MDSG
+carpentry/M
+carper/M
+carpet/MDGS
+carpetbag/MS
+carpetbagged
+carpetbagger/MS
+carpetbagging
+carpeting/M
+carpi
+carpool/SMDG
+carport/SM
+carpus/M
+carrel/MS
+carriage/SM
+carriageway/S
+carrier/M
+carrion/M
+carrot/MS
+carroty/RT
+carry/ZGDRSM
+carryall/SM
+carrycot/S
+carryout
+carryover/MS
+carsick/P
+carsickness/M
+cart/SZGMDR
+cartage/M
+cartel/MS
+carter/M
+carthorse/SM
+cartilage/SM
+cartilaginous
+cartload/SM
+cartographer/MS
+cartographic
+cartography/M
+carton/MS
+cartoon/SMDG
+cartoonist/SM
+cartridge/MS
+cartwheel/GMDS
+carve/JZGDRS
+carver/M
+carvery/S
+carving/M
+caryatid/MS
+casaba/MS
+cascade/DSMG
+cascara/SM
+case/LDSJMG
+casebook/S
+cased/U
+caseharden/GSD
+casein/M
+caseload/MS
+casement/MS
+casework/ZMR
+caseworker/M
+cash/GMDS
+cashbook/MS
+cashew/MS
+cashier/GSMD
+cashless
+cashmere/M
+casing/M
+casino/MS
+cask/SM
+casket/MS
+cassava/SM
+casserole/DSMG
+cassette/MS
+cassia/MS
+cassock/SM
+cassowary/SM
+cast/ASGM
+castanet/MS
+castaway/MS
+caste/JMZRS
+castellated
+caster/M
+castigate/DSGN
+castigation/M
+castigator/MS
+casting/AM
+castle/MGDS
+castoff/SM
+castrate/GNXDS
+castration/M
+castrato
+casual/PMYS
+casualness/M
+casualty/SM
+casuist/SM
+casuistic
+casuistry/M
+cat/SM
+cataclysm/MS
+cataclysmal
+cataclysmic
+catacomb/SM
+catafalque/MS
+catalepsy/M
+cataleptic/SM
+catalog/ZGSMDR
+cataloger/M
+catalpa/SM
+catalysis/M
+catalyst/MS
+catalytic/M
+catalyze/GDS
+catamaran/SM
+catapult/GMDS
+cataract/MS
+catarrh/M
+catastrophe/SM
+catastrophic
+catastrophically
+catatonia/M
+catatonic/SM
+catbird/SM
+catboat/SM
+catcall/GSMD
+catch/ZGJLMRS
+catchall/MS
+catcher/M
+catchment/MS
+catchpenny
+catchphrase/MS
+catchup/M
+catchword/MS
+catchy/RT
+catechism/SM
+catechist/SM
+catechize/DSG
+categorical/Y
+categorization/MS
+categorize/GDS
+category/SM
+cater/ZGJDRS
+catercorner
+caterer/M
+caterpillar/MS
+caterwaul/GSMD
+catfish/MS
+catgut/M
+catharses
+catharsis/M
+cathartic/SM
+cathedral/SM
+catheter/SM
+catheterize/GDS
+cathode/SM
+cathodic
+catholic
+catholicity/M
+cation/MS
+cationic
+catkin/MS
+catlike
+catnap/MS
+catnapped
+catnapping
+catnip/M
+catsuit/S
+cattail/SM
+catted
+cattery/S
+cattily
+cattiness/M
+catting
+cattle/M
+cattleman/M
+cattlemen
+catty/TPR
+catwalk/SM
+caucus/MDSG
+caudal/Y
+caught/U
+cauldron/MS
+cauliflower/SM
+caulk/ZGMDRS
+caulker/M
+caulking/M
+causal/Y
+causality/SM
+causation/M
+causative
+cause/MZGDRS
+causeless
+causer/M
+causerie/SM
+causeway/SM
+caustic/SM
+caustically
+causticity/M
+cauterization/M
+cauterize/GDS
+caution/SMDG
+cautionary
+cautious/IY
+cautiousness/M
+cavalcade/MS
+cavalier/SMY
+cavalry/SM
+cavalryman/M
+cavalrymen
+cave/DRSMZG
+caveat/MS
+caveman/M
+cavemen
+cavern/MS
+cavernous/Y
+caviar/M
+cavil/ZGJMDRS
+caviler/M
+caving/M
+cavitation
+cavity/FSM
+cavort/DGS
+caw/SMDG
+cay/CSM
+cayenne/M
+cayman/MS
+cayuse/MS
+cc
+cease/CMGDS
+ceasefire/MS
+ceaseless/YP
+ceaselessness/M
+ceca
+cecal
+cecum/M
+cedar/MS
+cede/FAGSD
+ceder/MS
+cedilla/SM
+ceilidh
+ceilidhs
+ceiling/MS
+celandine/M
+celeb/S
+celebrant/SM
+celebrate/DSGNX
+celebrated/U
+celebration/M
+celebrator/SM
+celebratory
+celebrity/SM
+celeriac
+celerity/M
+celery/M
+celesta/MS
+celestial/Y
+celibacy/M
+celibate/MS
+cell/SMD
+cellar/MS
+cellist/SM
+cellmate/SM
+cello/MS
+cellophane/M
+cellphone/MS
+cellular/SM
+cellulite/M
+celluloid/M
+cellulose/M
+cement/MDRZGS
+cementer/M
+cementum/M
+cemetery/SM
+cenobite/MS
+cenobitic
+cenotaph/M
+cenotaphs
+censer/MS
+censor/MDGS
+censored/U
+censorial
+censorious/PY
+censoriousness/M
+censorship/M
+censure/BDRSMZG
+censurer/M
+census/MDSG
+cent's
+cent/AR
+centaur/SM
+centavo/SM
+centenarian/SM
+centenary/SM
+centennial/MYS
+center/MDGS
+centerboard/SM
+centerfold/SM
+centerpiece/SM
+centigrade
+centigram/SM
+centiliter/SM
+centime/SM
+centimeter/SM
+centipede/SM
+central/TSMRY
+centralism
+centralist
+centrality/M
+centralization/CM
+centralize/CDSG
+centralizer/SM
+centric/F
+centrifugal/Y
+centrifuge/MGDS
+centripetal/Y
+centrism/M
+centrist/MS
+centroid/S
+cents
+centurion/SM
+century/SM
+cephalic
+ceramic/SM
+ceramicist/SM
+ceramics/M
+ceramist/MS
+cereal/MS
+cerebellar
+cerebellum/SM
+cerebra
+cerebral
+cerebrate/GNDS
+cerebration/M
+cerebrum/MS
+cerement/MS
+ceremonial/SMY
+ceremonious/UY
+ceremoniousness/M
+ceremony/SM
+cerise/M
+cerium/M
+cermet/M
+cert/S
+certain/UYT
+certainer
+certainty/USM
+certifiable
+certifiably
+certificate/MGNXDS
+certification/M
+certify/DSG
+certitude/IM
+certitudes
+cerulean/M
+cervical
+cervices
+cervix/M
+cesarean/MS
+cesium/M
+cessation/MS
+cession/KAFSM
+cesspit/S
+cesspool/MS
+cetacean/MS
+cf
+cg
+ch/IFVT
+chad/S
+chafe/GDS
+chaff/GMDS
+chaffinch/MS
+chagrin/GSMD
+chain's
+chain/UGDS
+chainsaw/MDGS
+chair/GMDS
+chairlift/MS
+chairman/M
+chairmanship/MS
+chairmen
+chairperson/MS
+chairwoman/M
+chairwomen
+chaise/MS
+chalcedony/M
+chalet/MS
+chalice/SM
+chalk/GMDS
+chalkboard/SM
+chalkiness/M
+chalky/PRT
+challenge/DRSMZG
+challenged/U
+challenger/M
+challenging/Y
+challis/M
+chamber/SMD
+chamberlain/SM
+chambermaid/SM
+chamberpot/S
+chambray/M
+chameleon/SM
+chamois/M
+chamomile/MS
+champ/ZGMDS
+champagne/MS
+champion/GMDS
+championship/MS
+chance/MGDS
+chancel/SM
+chancellery/SM
+chancellor/SM
+chancellorship/M
+chancery/SM
+chanciness/M
+chancre/SM
+chancy/PRT
+chandelier/MS
+chandler/MS
+change/MZGDRS
+changeability/M
+changeable/P
+changeableness/M
+changeably
+changed/U
+changeless/Y
+changeling/SM
+changeover/SM
+changer/M
+changing/U
+channel/GSMD
+channelization/M
+channelize/GDS
+chanson/SM
+chant/ZGMDRJS
+chanter/M
+chanteuse/MS
+chantey/SM
+chanticleer/SM
+chantry/S
+chaos/M
+chaotic
+chaotically
+chap/SM
+chaparral/SM
+chapati/S
+chapatti/S
+chapbook/MS
+chapeau/SM
+chapel/MS
+chaperon/MDGS
+chaperonage/M
+chaperoned/U
+chaplain/MS
+chaplaincy/SM
+chaplet/SM
+chapped
+chapping
+chappy/S
+chapter/SM
+char/SM
+charabanc/MS
+character/MS
+characterful
+characteristic/MS
+characteristically/U
+characterization/MS
+characterize/GDS
+characterless
+charade/SM
+charbroil/GDS
+charcoal/MS
+chard/M
+chardonnay/SM
+charge/EAMGDS
+chargeable/A
+charged/U
+charger/SM
+charily
+chariness/M
+chariot/SM
+charioteer/SM
+charisma/M
+charismatic/SM
+charismatically
+charitable/P
+charitableness/M
+charitably/U
+charity/SM
+charlady/S
+charlatan/SM
+charlatanism/M
+charlatanry/M
+charlie/S
+charm/ZGMDRS
+charmer/M
+charming/TRY
+charmless
+charred
+charring
+chart/GMDS
+charted/U
+charter's
+charter/ASGD
+charterer/MS
+chartists
+chartreuse/M
+charwoman/M
+charwomen
+chary/TRP
+chase/MZGDRS
+chaser/M
+chasm/MS
+chassis/M
+chaste/PYTR
+chasten/DGS
+chasteness/M
+chastise/DRSZGL
+chastisement/MS
+chastiser/M
+chastity/M
+chasuble/SM
+chat/SM
+chateau/SM
+chatelaine/SM
+chatline/S
+chatted
+chattel/MS
+chatter/MDRZGS
+chatterbox/MS
+chatterer/M
+chattily
+chattiness/M
+chatting
+chatty/TPR
+chauffeur/MDGS
+chauvinism/M
+chauvinist/SM
+chauvinistic
+chauvinistically
+cheap/PXTNRY
+cheapen/DG
+cheapish
+cheapness/M
+cheapo
+cheapskate/SM
+cheat/ZGMDRS
+cheater/M
+check/AGMDS
+checkbook/SM
+checked/U
+checker/MDGS
+checkerboard/MS
+checkers/M
+checklist/MS
+checkmate/MGDS
+checkoff/SM
+checkout/SM
+checkpoint/SM
+checkroom/MS
+checkup/MS
+cheddar/M
+cheek/GMDS
+cheekbone/SM
+cheekily
+cheekiness/M
+cheeky/TPR
+cheep/GMDS
+cheer/ZGMDRS
+cheerer/M
+cheerful/YP
+cheerfuller
+cheerfullest
+cheerfulness/M
+cheerily
+cheeriness/M
+cheerio/MS
+cheerleader/MS
+cheerless/YP
+cheerlessness/M
+cheery/TPR
+cheese/MGDS
+cheeseboard/S
+cheeseburger/MS
+cheesecake/SM
+cheesecloth/M
+cheeseparing/M
+cheesiness/M
+cheesy/TPR
+cheetah/M
+cheetahs
+chef/SM
+chem
+chemical/SMY
+chemiluminescence
+chemiluminescent
+chemise/MS
+chemist/MS
+chemistry/M
+chemo/M
+chemosynthesis
+chemotherapeutic
+chemotherapy/M
+chemurgy/M
+chenille/M
+cherish/DSG
+cheroot/MS
+cherry/SM
+chert/M
+cherub/MS
+cherubic
+cherubim
+chervil/M
+chess/M
+chessboard/MS
+chessman/M
+chessmen
+chest/MDS
+chesterfield/MS
+chestful/SM
+chestnut/SM
+chesty/TR
+chevalier/SM
+cheviot/M
+chevron/MS
+chew/SBZGMDR
+chewer/M
+chewiness/M
+chewy/PTR
+chg
+chge
+chi/SM
+chiaroscuro/M
+chic/PTMR
+chicane/MS
+chicanery/SM
+chichi/TMRS
+chick/XMNS
+chickadee/SM
+chicken/MDG
+chickenfeed/M
+chickenhearted
+chickenpox/M
+chickenshit/S!
+chickpea/SM
+chickweed/M
+chicle/M
+chicness/M
+chicory/SM
+chide/GDS
+chiding/Y
+chief/TMRYS
+chiefdom/M
+chieftain/MS
+chieftainship/MS
+chiffon/M
+chiffonier/MS
+chigger/MS
+chignon/MS
+chihuahua/SM
+chilblain/SM
+child/M
+childbearing/M
+childbirth/M
+childbirths
+childcare/M
+childhood/SM
+childish/PY
+childishness/M
+childless/P
+childlessness/M
+childlike
+childminder/S
+childminding
+childproof/SGD
+children
+chili/M
+chilies
+chill/JPZTGMDRS
+chiller/M
+chilliness/M
+chilling/Y
+chillness/M
+chilly/TPRS
+chimaerical
+chime/MZGDRS
+chimer/M
+chimera/MS
+chimeric
+chimerical
+chimney/MS
+chimp/MS
+chimpanzee/MS
+chin/SM
+china/M
+chinaware/M
+chinchilla/MS
+chine/MS
+chink/GMDS
+chinless
+chinned
+chinning
+chino/MS
+chinstrap/MS
+chintz/M
+chintzy/RT
+chinwag/S
+chip/SM
+chipboard
+chipmunk/SM
+chipolata/S
+chipped
+chipper/MS
+chippie
+chipping/S
+chippy/S
+chiral
+chirography/M
+chiropodist/MS
+chiropody/M
+chiropractic/MS
+chiropractor/MS
+chirp/GMDS
+chirpily
+chirpy/PTR
+chirrup/GMDS
+chisel/ZGMDRS
+chiseler/M
+chit/SM
+chitchat/SM
+chitchatted
+chitchatting
+chitin/M
+chitinous
+chitterlings/M
+chivalric
+chivalrous/PY
+chivalrousness/M
+chivalry/M
+chive/MS
+chivvy/GDS
+chlamydia/MS
+chlamydiae
+chloral/M
+chlorate
+chlordane/M
+chloride/MS
+chlorinate/DSGN
+chlorination/M
+chlorine/M
+chlorofluorocarbon/MS
+chloroform/SMDG
+chlorophyll/M
+chloroplast/MS
+chloroquine
+chm
+choc/S
+chock/GMDS
+chockablock
+chocoholic/MS
+chocolate/MS
+chocolaty
+choice/MTRS
+choir/MS
+choirboy/MS
+choirmaster/MS
+choke/MZGDRS
+chokecherry/SM
+choker/M
+choler/M
+cholera/M
+choleric
+cholesterol/M
+choline
+chomp/ZGMDRS
+choose/ZGRS
+chooser/M
+choosiness/M
+choosy/TPR
+chop/SM
+chophouse/SM
+chopped
+chopper/MDGS
+choppily
+choppiness/M
+chopping
+choppy/TPR
+chopstick/SM
+choral/MYS
+chorale/MS
+chord/MS
+chordal
+chordate/SM
+chore/MS
+chorea/M
+choreograph/ZGDR
+choreographer/M
+choreographic
+choreographically
+choreographs
+choreography/M
+chorister/SM
+choroid/MS
+chortle/MZGDRS
+chortler/M
+chorus/GMDS
+chose
+chosen
+chow/SGMD
+chowder/MS
+chrism/M
+christen/ASGD
+christened/U
+christening/SM
+christian/U
+chroma
+chromatic
+chromatically
+chromaticism
+chromatin/M
+chromatographic
+chromatography
+chrome/MGDS
+chromite
+chromium/M
+chromosomal
+chromosome/MS
+chronic
+chronically
+chronicle/DRSMZG
+chronicled/U
+chronicler/M
+chronograph/M
+chronographs
+chronological/Y
+chronologist/SM
+chronology/SM
+chronometer/MS
+chronometric
+chrysalis/MS
+chrysanthemum/MS
+chub/SM
+chubbiness/M
+chubby/TPR
+chuck/GMDS
+chuckhole/SM
+chuckle/MGDS
+chuff/D
+chug/SM
+chugged
+chugging
+chukka/MS
+chum/SM
+chummed
+chummily
+chumminess/M
+chumming
+chummy/PTR
+chump/MS
+chunder/GDS
+chunk/MS
+chunkiness/M
+chunky/PTR
+chunter/DGS
+church/MS
+churchgoer/SM
+churchgoing/M
+churchman/M
+churchmen
+churchwarden/SM
+churchwoman
+churchwomen
+churchyard/SM
+churl/MS
+churlish/PY
+churlishness/M
+churn/ZGMDRS
+churner/M
+chute/MS
+chutney/MS
+chutzpa/M
+chutzpah/M
+chyme/M
+ciao/S
+cicada/MS
+cicatrice/SM
+cicerone/SM
+ciceroni
+cider's
+cider/S
+cigar/MS
+cigarette/MS
+cigarillo/MS
+cilantro/M
+cilia
+cilium/M
+cinch/GMDS
+cinchona/SM
+cincture/SM
+cinder/GMDS
+cine
+cinema/MS
+cinematic
+cinematographer/MS
+cinematographic
+cinematography/M
+cinnabar/M
+cinnamon/M
+cipher's
+cipher/CGDS
+cir
+circa
+circadian
+circle/MGDS
+circlet/MS
+circuit/MDGS
+circuital
+circuitous/YP
+circuitousness/M
+circuitry/M
+circuity/M
+circulant
+circular/SMY
+circularity/M
+circularize/GDS
+circulate/ADSGN
+circulation/SM
+circulatory
+circumcise/GNDSX
+circumcised/U
+circumcision/M
+circumference/SM
+circumferential
+circumflex/MS
+circumlocution/MS
+circumlocutory
+circumnavigate/XDSGN
+circumnavigation/M
+circumnavigational
+circumpolar
+circumscribe/DSG
+circumscription/SM
+circumspect/Y
+circumspection/M
+circumstance/DSMG
+circumstantial/Y
+circumvent/GDBS
+circumvention/MS
+circus/MS
+cirque/MS
+cirrhosis/M
+cirrhotic/SM
+cirri
+cirrus/M
+cistern/MS
+cit
+citadel/MS
+citation/AMS
+cite's
+cite/IAGSD
+citified
+citizen/MS
+citizenry/M
+citizenship/M
+citrate
+citric
+citron/MS
+citronella/M
+citrus/MS
+city/SM
+cityscape
+citywide
+civet/MS
+civic/S
+civics/M
+civil/UY
+civilian/MS
+civility/ISM
+civilization/SM
+civilize/GDS
+civilized/U
+civvies/M
+ck
+cl
+clack/GMDS
+clad/U
+cladding/M
+claim's
+claim/CKEAGDS
+claimable
+claimant/MS
+claimed/U
+claimer/CEMS
+clairvoyance/M
+clairvoyant/SM
+clam/SM
+clambake/MS
+clamber/ZGMDRS
+clamberer/M
+clammed
+clammily
+clamminess/M
+clamming
+clammy/PTR
+clamor/GMDS
+clamorous/Y
+clamp/GMDS
+clampdown/MS
+clan/SM
+clandestine/Y
+clang/ZGMDRS
+clangor/M
+clangorous/Y
+clank/GMDS
+clannish/P
+clannishness/M
+clansman/M
+clansmen
+clanswoman
+clanswomen
+clap/SM
+clapboard/MDSG
+clapped
+clapper/MS
+clapperboard/S
+clapping/M
+claptrap/M
+claque/MS
+claret/MS
+clarification/M
+clarify/NXDSG
+clarinet/SM
+clarinetist/SM
+clarion/MDGS
+clarity/M
+clash/GMDS
+clasp's
+clasp/UGDS
+class/GMDS
+classic/MS
+classical/MY
+classicism/M
+classicist/SM
+classifiable/U
+classification/CAM
+classifications
+classificatory
+classified's
+classified/U
+classifieds
+classifier/SM
+classify/ACSDGN
+classiness/M
+classless/P
+classmate/MS
+classroom/MS
+classwork/M
+classy/TRP
+clatter/GMDS
+clausal
+clause/MS
+claustrophobia/M
+claustrophobic
+clavichord/SM
+clavicle/MS
+clavier/MS
+claw/SGMD
+clay/SM
+clayey
+clayier
+clayiest
+claymore/S
+clean/BJPZTGDRYS
+cleaner/M
+cleaning/M
+cleanliness/UM
+cleanly/UTPR
+cleanness/UM
+cleanse/ZGDRS
+cleanser/M
+cleanup/MS
+clear/JPTGMDRYS
+clearance/SM
+clearheaded
+clearing/M
+clearinghouse/SM
+clearness/M
+clearway/S
+cleat/MS
+cleavage/MS
+cleave/ZGDRS
+cleaver/M
+clef/SM
+cleft/MS
+clematis/MS
+clemency/IM
+clement/Y
+clementine/S
+clench/GMDS
+clerestory/SM
+clergy/SM
+clergyman/M
+clergymen
+clergywoman/M
+clergywomen
+cleric/MS
+clerical/Y
+clericalism/M
+clerk/GMDS
+clerkship/M
+clever/PTRY
+cleverness/M
+clevis/MS
+clew/SGMD
+cliche/MDS
+click/ZGMDRS
+clicker/M
+client/MS
+clientele/MS
+cliff/MS
+cliffhanger/SM
+cliffhanging
+clifftop/S
+clii
+climacteric/M
+climactic
+climate/SM
+climatic
+climatically
+climatological
+climatologist/MS
+climatology/M
+climax/MDSG
+climb/SMDRZGB
+climbable/U
+climbdown
+climbed/U
+climber/M
+climbing/M
+clime/SM
+clinch/MDRSZG
+clincher/M
+cling/SMRZG
+clinger/M
+clingfilm
+clingy/RT
+clinic/SM
+clinical/Y
+clinician/SM
+clink/SMDRZG
+clinker/M
+cliometric/S
+cliometrician/SM
+cliometrics/M
+clip/SM
+clipboard/MS
+clipped
+clipper/SM
+clipping/SM
+clique/SM
+cliquey
+cliquier
+cliquiest
+cliquish/YP
+cliquishness/M
+clitoral
+clitorides
+clitoris/MS
+clix
+cloaca/M
+cloacae
+cloak's
+cloak/USDG
+cloakroom/MS
+clobber/SMDG
+cloche/SM
+clock/SMDG
+clockmaker
+clockwise
+clockwork/SM
+clod/MS
+cloddish
+clodhopper/MS
+clog's
+clog/US
+clogged/U
+clogging/U
+cloisonne/M
+cloister/SMDG
+cloistral
+clomp/SDG
+clonal
+clone/DSMG
+clonk/SMDG
+clop/MS
+clopped
+clopping
+close/DRSMYZTGJP
+closed/U
+closefisted
+closemouthed
+closeness/M
+closeout/MS
+closet/SMDG
+closeup/SM
+closing/M
+closure/ESM
+clot/MS
+cloth/M
+clothe/UDSG
+clotheshorse/SM
+clothesline/MS
+clothespin/SM
+clothier/MS
+clothing/M
+cloths
+clotted
+clotting
+cloture/SM
+cloud/SMDG
+cloudburst/SM
+clouded/U
+cloudiness/M
+cloudless
+cloudscape/S
+cloudy/RPT
+clout/SMDG
+clove/RSMZ
+cloven
+clover/M
+cloverleaf/MS
+clown/SMDG
+clownish/PY
+clownishness/M
+cloy/DGS
+cloying/Y
+club/MS
+clubbable
+clubbed
+clubber/S
+clubbing
+clubfeet
+clubfoot/MD
+clubhouse/SM
+clubland
+clubroom
+cluck/SMDG
+clue/MGDS
+clueless
+clump/SMDG
+clumpy/TR
+clumsily
+clumsiness/M
+clumsy/TRP
+clung
+clunk/SMDRZG
+clunker/M
+clunky/TR
+cluster/MDSG
+clutch/GMDS
+clutter/MDSG
+cluttered/U
+clvi
+clvii
+clxi
+clxii
+clxiv
+clxix
+clxvi
+clxvii
+cm
+cnidarian/MS
+co/ESD
+coach/MDSG
+coachload/S
+coachman/M
+coachmen
+coachwork
+coadjutor/MS
+coagulant/MS
+coagulate/GNDS
+coagulation/M
+coagulator/MS
+coal/MDGS
+coalesce/GDS
+coalescence/M
+coalescent
+coalface/MS
+coalfield/S
+coalition/MS
+coalitionist/MS
+coalmine/ZS
+coarse/RYTP
+coarsen/SDG
+coarseness/M
+coast/SMDRZG
+coastal
+coaster/M
+coastguard/S
+coastline/MS
+coat/MDGJS
+coating/M
+coatroom/S
+coattail/SM
+coauthor/MDGS
+coax/DRSZG
+coaxer/M
+coaxial
+coaxing/Y
+cob/SM
+cobalt/M
+cobber/S
+cobble/DRSMZG
+cobbler/M
+cobblestone/SM
+cobnut/S
+cobra/SM
+cobweb/SM
+cobwebbed
+cobwebby/RT
+coca/M
+cocaine/M
+cocci/S
+coccus/M
+coccyges
+coccyx/M
+cochineal/M
+cochlea/SM
+cochleae
+cochlear
+cock/MDGS
+cockade/SM
+cockamamie
+cockatoo/SM
+cockatrice/SM
+cockchafer/S
+cockcrow/SM
+cockerel/SM
+cockeyed
+cockfight/MGS
+cockfighting/M
+cockily
+cockiness/M
+cockle/SM
+cockleshell/SM
+cockney/SM
+cockpit/SM
+cockroach/MS
+cockscomb/SM
+cockshies
+cocksucker's
+cocksucker/S!
+cocksure
+cocktail/MS
+cocky/RTP
+coco/MS
+cocoa/SM
+coconut/SM
+cocoon/SMDG
+cod/ZSMR
+coda/MS
+codded
+codding
+coddle/DSG
+code's
+code/CAGDS
+codebreaker
+codeine/M
+codename/D
+codependency/M
+codependent/MS
+coder/CSM
+codeword/S
+codex/M
+codfish/MS
+codger/SM
+codices
+codicil/SM
+codification/M
+codifier/M
+codify/DRSNXZG
+codling
+codpiece/MS
+codswallop
+coed/MS
+coeducation/M
+coeducational
+coefficient/MS
+coelenterate/SM
+coequal/MYS
+coerce/XDRSZGNV
+coercer/M
+coercible
+coercion/M
+coeval/SMY
+coexist/DSG
+coexistence/M
+coexistent
+coextensive
+coffee/SM
+coffeecake/SM
+coffeehouse/MS
+coffeemaker/MS
+coffeepot/MS
+coffer/SM
+cofferdam/MS
+coffin/SMDG
+cog/SM
+cogency/M
+cogent/Y
+cogitate/DSXGNV
+cogitation/M
+cogitator/MS
+cognac/SM
+cognate/MS
+cognition/AM
+cognitional
+cognitive/Y
+cognizable
+cognizance/AM
+cognizant
+cognomen/SM
+cognoscente/M
+cognoscenti
+cogwheel/SM
+cohabit/SGD
+cohabitant/MS
+cohabitation/M
+coheir/SM
+cohere/DSG
+coherence/IM
+coherency/M
+coherent/IY
+cohesion/M
+cohesive/YP
+cohesiveness/M
+coho/MS
+cohort/SM
+coif/MS
+coiffed
+coiffing
+coiffure/DSMG
+coil's/A
+coil/UADGS
+coin/MDRZGS
+coinage/SM
+coincide/DSG
+coincidence/SM
+coincident
+coincidental/Y
+coiner/M
+coinsurance/M
+cointreau
+coir
+coital
+coitus/M
+coke/MGDS
+col/S
+cola/MS
+colander/SM
+cold/MRYTPS
+coldblooded
+coldish
+coldness/M
+coleslaw/M
+coleus/MS
+coley/S
+colic/M
+colicky
+coliseum/MS
+colitis/M
+coll
+collaborate/GNVXDS
+collaboration/M
+collaborationist
+collaborative/Y
+collaborator/SM
+collage/SM
+collagen
+collapse/MGDS
+collapsible
+collar/SMDG
+collarbone/SM
+collard/SM
+collarless
+collate/DSXGN
+collated/U
+collateral/MY
+collateralize
+collation/M
+collator/MS
+colleague/MS
+collect's
+collect/ASGVD
+collected/U
+collectedly
+collectible/SM
+collection/ASM
+collective/SMY
+collectivism/M
+collectivist/MS
+collectivity
+collectivization/M
+collectivize/GDS
+collector/MS
+colleen/SM
+college/SM
+collegial
+collegiality/M
+collegian/MS
+collegiate
+collide/DSG
+collie/RSMZ
+collier/M
+colliery/SM
+collimation
+collimator
+collinear
+collision/SM
+collisional
+collocate/MGNXDS
+collocation/M
+colloid/SM
+colloidal
+colloq
+colloquial/Y
+colloquialism/MS
+colloquies
+colloquium/SM
+colloquy/M
+collude/DSG
+collusion/M
+collusive
+cologne/SM
+colon/SM
+colonel/SM
+colonelcy/M
+colones
+colonial/SMY
+colonialism/M
+colonialist/SM
+colonic
+colonist/SM
+colonization/CAM
+colonizations
+colonize/CAGSD
+colonizer/MS
+colonnade/MDS
+colony/SM
+colophon/SM
+color's
+color/AEGDS
+colorant/SM
+coloration/EM
+coloratura/MS
+colorblind/P
+colorblindness/M
+colored's
+colored/U
+coloreds
+colorfast/P
+colorfastness/M
+colorful/PY
+colorfulness/M
+colorimetric
+coloring/SM
+colorist/S
+colorization/M
+colorize/DSG
+colorizing/C
+colorless/PY
+colorlessness/M
+colorway/S
+colossal/Y
+colossi
+colossus/M
+colostomy/SM
+colostrum/M
+colt/MS
+coltish
+columbine/SM
+column/SMD
+columnar
+columnist/SM
+com/JL
+coma/MS
+comae
+comaker/SM
+comatose
+comb/MDRZGJS
+combat/SMDGV
+combatant/SM
+combativeness/M
+combed/U
+comber/M
+combination/M
+combinatorial
+combine's
+combine/ADSG
+combined/U
+combiner/MS
+combings/M
+combo/SM
+combusted
+combustibility/M
+combustible/SM
+combustion/M
+combustive
+come/IMZGRS
+comeback/MS
+comedian/MS
+comedic
+comedienne/MS
+comedown/MS
+comedy/SM
+comeliness/M
+comely/RPT
+comer's
+comestible/SM
+comet/SM
+cometary
+comeuppance/MS
+comfit's
+comfit/ES
+comfort/ESMDG
+comfortable/UP
+comfortableness/M
+comfortably/U
+comforter/MS
+comforting/Y
+comfortless
+comfy/RT
+comic/SM
+comical/Y
+comicality/M
+coming/M
+comity/M
+comm
+comma/SM
+command/SMDRLZG
+commandant/MS
+commandeer/DGS
+commander/M
+commanding/Y
+commandment/SM
+commando/SM
+commemorate/XDSGNV
+commemoration/M
+commemorator/MS
+commence/ALDSG
+commencement/AM
+commencements
+commend/ASDBG
+commendably
+commendation/ASM
+commendatory
+commensurable/I
+commensurate/IY
+comment/GSMDR
+commentary/SM
+commentate/DSG
+commentator/SM
+commerce/M
+commercial/SMY
+commercialism/M
+commercialization/M
+commercialize/GDS
+commie/SM
+commingle/DSG
+commiserate/DSXGNV
+commiseration/M
+commissar/SM
+commissariat/MS
+commissary/SM
+commission's
+commission/ACGSD
+commissionaire/S
+commissioner/SM
+commit/AS
+commitment/MS
+committal/SM
+committed/AU
+committee/SM
+committeeman/M
+committeemen
+committeewoman/M
+committeewomen
+committing/A
+commode's
+commode/EIS
+commodious/Y
+commodity/SM
+commodore/SM
+common's
+common/UPRYT
+commonality/S
+commonalty/M
+commoner/MS
+commonness/UM
+commonplace/SM
+commons
+commonsense
+commonsensical
+commonweal/MH
+commonwealth/M
+commonwealths
+commotion/SM
+communal/Y
+communality
+commune/XDSMGN
+communicability/M
+communicable/I
+communicably
+communicant/SM
+communicate/XDSGNV
+communication/M
+communicative/P
+communicator/MS
+communion/M
+communique/SM
+communism/M
+communist/SM
+communistic
+communitarian
+community/SM
+commutation/MS
+commutative
+commutativity
+commutator/SM
+commute/BDRSMZG
+commuter/M
+comp/MDYGS
+compact/TGSMDRYP
+compaction/S
+compactness/M
+compactor/SM
+companion/SMB
+companionably
+companionship/M
+companionway/MS
+company/SM
+comparability/M
+comparable/I
+comparably/I
+comparative/SMY
+comparator/S
+compare/BDSMG
+comparison/MS
+compartment/MS
+compartmental
+compartmentalization/M
+compartmentalize/DSG
+compass/GMDS
+compassion/M
+compassionate/Y
+compatibility/ISM
+compatible/IMS
+compatibly/I
+compatriot/MS
+compeer/SM
+compel/S
+compelled
+compelling/Y
+compendious
+compendium/SM
+compensate/DSGNX
+compensated/U
+compensation/M
+compensator
+compensatory
+compere/DSG
+compete/DSG
+competence/IM
+competences
+competencies
+competency/IM
+competent/IY
+competition/MS
+competitive/UP
+competitively
+competitiveness/M
+competitor/SM
+compilable/U
+compilation's
+compilation/AS
+compile/BDRSZG
+compiler/M
+complacence/M
+complacency/M
+complacent/Y
+complain/DRZGS
+complainant/MS
+complainer/M
+complaining/UY
+complaint/SM
+complaisance/M
+complaisant/Y
+complected
+complement/MDGS
+complementarity
+complementary
+complete/PYTGNBXDRS
+completed/U
+completeness/IM
+completion/M
+complex/TMRSY
+complexion/MDS
+complexional
+complexity/SM
+compliance/M
+compliant/Y
+complicate/GDS
+complicated/Y
+complication/M
+complicit
+complicity/M
+compliment/MDSG
+complimentary/U
+comply/XDSNG
+compo/S
+component/SM
+comport/LSGD
+comportment/M
+compose/AECGSD
+composedly
+composer/MS
+composite/MYNSX
+composition/CSM
+compositional
+compositor/SM
+compost/SGMD
+composure/EM
+compote/SM
+compound/GMDBS
+compounded/U
+comprehend/SDG
+comprehensibility/IM
+comprehensible/I
+comprehensibly/I
+comprehension/IM
+comprehensions
+comprehensive/PMYS
+comprehensiveness/M
+compress's
+compress/CGVDS
+compressed/U
+compressibility
+compressible/I
+compression/CM
+compressional
+compressions
+compressor/SM
+comprise/GDS
+compromise/DSMG
+comptroller/SM
+compulsion/MS
+compulsive/PY
+compulsiveness/M
+compulsorily
+compulsory/SM
+compunction/MS
+computability
+computably
+computation/MS
+computational/Y
+compute/ADSBG
+computer/MS
+computerate
+computerization/M
+computerize/GDS
+computing/M
+comrade/SMY
+comradeship/M
+con/GSM
+concatenate/DSGNX
+concatenation/M
+concave/YP
+concaveness/M
+conceal/SDRZGBL
+concealed/U
+concealer/M
+concealment/M
+conceit/SMD
+conceited/PY
+conceitedness/M
+conceivability/I
+conceivable/I
+conceivably/I
+conceive/DSGB
+concentrate/MGNDSX
+concentration/M
+concentrator/S
+concentrically
+concept/SM
+conception/SM
+conceptional
+conceptual/Y
+conceptualization/MS
+conceptualize/GDS
+concern/UMD
+concerned/UY
+concerning
+concerns
+concert's
+concert/ESDG
+concerted/Y
+concertgoer/S
+concertina/SMDG
+concertize/DSG
+concertmaster/SM
+concerto/SM
+concessionaire/MS
+concessional
+concessionary
+conch/M
+conchie/S
+conchs
+concierge/MS
+conciliar
+conciliate/DSGN
+conciliation/AM
+conciliator/MS
+conciliatory
+concise/RPYTN
+conciseness/M
+concision/M
+conclave/SM
+conclude/DSG
+conclusion/MS
+conclusive/IPY
+conclusiveness/IM
+concoct/SDG
+concoction/MS
+concomitant/SMY
+concord/M
+concordance/MS
+concordant
+concordat/SM
+concourse/SM
+concrete/DSMYGNPX
+concreteness/M
+concretion/M
+concubinage/M
+concubine/MS
+concupiscence/M
+concupiscent
+concur/S
+concurred
+concurrence/MS
+concurrency
+concurring
+concuss/V
+concussion/MS
+condemn/SBDRZG
+condemnation/SM
+condemnatory
+condemner/M
+condensate/MNSX
+condensation/M
+condense/DRSZG
+condenser/M
+condescending/Y
+condescension/M
+condign
+condiment/MS
+condition's
+condition/AGSD
+conditional/SMY
+conditionality
+conditioned/U
+conditioner/SM
+conditioning/M
+condo/SM
+condolence/SM
+condom/SM
+condominium/SM
+condone/DSGB
+condor/SM
+conduce/DSGV
+conduct/SMV
+conductance/M
+conductibility/M
+conductible
+conduction/M
+conductivity/SM
+conductor/MS
+conductress/MS
+conduit/SM
+cone/M
+confab/SM
+confabbed
+confabbing
+confabulate/XGNDS
+confabulation/M
+confection/SMRZ
+confectioner/M
+confectionery/SM
+confectionist
+confederacy/SM
+confederate/M
+confer/SB
+conferee/SM
+conference/SMG
+conferral/M
+conferred
+conferrer/MS
+conferring
+confessed/Y
+confession/SM
+confessional/MS
+confessor/MS
+confetti/M
+confidant/MS
+confidante/SM
+confide/DRSZG
+confidence/SM
+confident/Y
+confidential/Y
+confidentiality/M
+confider/M
+confiding/Y
+configuration/AS
+configure/ABGDS
+confined/U
+confinement/SM
+confirm/ASDG
+confirmation/AMS
+confirmatory
+confirmed/U
+confiscate/GNXDS
+confiscation/M
+confiscator/SM
+confiscatory
+conflagration/SM
+conflate/XDSGN
+conflation/M
+conflict/SGMD
+conflicting/Y
+conflictual
+confluence/MS
+confluent
+confocal
+conformable/U
+conformal
+conformance/M
+conformational
+conformism/M
+conformist/SM
+conformity/M
+confounded/Y
+confrere/MS
+confrontation/SM
+confrontational
+confuse/BRZ
+confused/Y
+confusing/Y
+confutation/M
+confute/DSG
+conga/SMDG
+congeal/SLDG
+congealment/M
+conger/SM
+congeries/M
+congest/SDGV
+congestion/M
+conglomerate/XMGNDS
+conglomeration/M
+congrats/M
+congratulate/DSXGN
+congratulation/M
+congratulatory
+congregant/SM
+congregate/XDSGN
+congregation/M
+congregational
+congregationalism/M
+congregationalist/MS
+congress/MS
+congressional
+congressman/M
+congressmen
+congresspeople
+congressperson/MS
+congresswoman/M
+congresswomen
+congruence/SM
+congruency
+congruent/Y
+congruential
+congruity/ISM
+congruous
+conic/SM
+conical/Y
+conifer/SM
+coniferous
+conjectural
+conjecture/MGDS
+conjoint
+conjugacy
+conjugal/Y
+conjugate/DSXGN
+conjugation/M
+conjunct/VMS
+conjunctiva/MS
+conjunctive/MS
+conjunctivitis/M
+conjuration/SM
+conjure/DRSZG
+conjurer/M
+conk/MDRZ
+conman
+connect/AEDVGS
+connected/U
+connectedness
+connectible
+connection/ESM
+connectionless
+connective/SM
+connectivity/M
+connector/MS
+conned
+conning
+conniption/SM
+connivance/M
+connive/DRSZG
+conniver/M
+connoisseur/MS
+connoisseurship
+connotative
+connubial
+conquer/ASDG
+conquerable/U
+conquered/U
+conqueror/MS
+conquest/AM
+conquistador/SM
+cons/DSG
+consanguineous
+consanguinity/M
+conscienceless
+conscientious/PY
+conscientiousness/M
+conscionable/U
+conscious/UPY
+consciousness/UM
+consciousnesses
+conscription/M
+consecrate/ADSGN
+consecrated/U
+consecration/AM
+consecrations
+consecutive/Y
+consensus/MS
+consent/SMDG
+consequence/MS
+consequent/Y
+consequential/IY
+conservancy/SM
+conservation/MS
+conservationism/M
+conservationist/SM
+conservatism/M
+conservative/PMYS
+conservatoire/S
+conservator/SM
+conservatory/SM
+consider/AGSD
+considerable/I
+considerably
+considerate/IYNP
+considerateness/IM
+consideration/IAM
+considerations
+considered/U
+consign/ASDG
+consignee/MS
+consignment/SM
+consist/SDG
+consistence/MS
+consistency/ISM
+consistent/IY
+consistory/SM
+consolable/I
+consolation/SM
+consolatory
+consoled/U
+consolidate/GNXDS
+consolidated/U
+consolidation/M
+consolidator/SM
+consoling/Y
+consomme/M
+consonance/SM
+consonant/SMY
+consonantal
+consortia
+consortium/M
+conspectus/MS
+conspicuous/IPY
+conspicuousness/IM
+conspiracy/SM
+conspirator/SM
+conspiratorial/Y
+conspire/GD
+constable/SM
+constabulary/SM
+constancy/IM
+constant/MYS
+constellation/SM
+consternating
+consternation/M
+constipate/DSGN
+constipation/M
+constituency/SM
+constituent/MS
+constitute/ADSGNV
+constitution/AM
+constitutional/MYS
+constitutionalism
+constitutionalists
+constitutionality/UM
+constitutions
+constrained/U
+constraint/MS
+constrict/SGVD
+constriction/MS
+constrictor/SM
+construable
+construct's
+construct/CADVGS
+constructable
+construction/CASM
+constructional
+constructionist's
+constructionist/CS
+constructive/YP
+constructiveness/M
+constructivism
+constructivist
+constructor/SM
+construe/GDS
+consul/KSM
+consular/K
+consulate/SM
+consulship/M
+consult/AGD
+consultancy/SM
+consultant/MS
+consultation/SM
+consultative
+consults
+consumable/MS
+consume/BDRSZG
+consumed/U
+consumer/M
+consumerism/M
+consumerist/SM
+consummate/YGNDSX
+consummated/U
+consumption/SM
+consumptive/SM
+cont
+contact/ASDG
+contactable
+contagion/MS
+contagious/PY
+contagiousness/M
+contain/SBLDRZG
+containable/U
+container/M
+containerization/M
+containerize/GDS
+containment/M
+contaminant/SM
+contaminate/ACDSG
+contaminated/U
+contamination/CM
+contaminator/MS
+contd
+contemn/SDG
+contemplate/XGNVDS
+contemplation/M
+contemplative/SMY
+contemporaneity/M
+contemporaneous/Y
+contempt/M
+contemptible
+contemptibly
+contemptuous/YP
+contemptuousness/M
+contender/MS
+content/ESLMDG
+contented/EY
+contentedness/M
+contention/MS
+contentious/YP
+contentiousness/M
+contently
+contentment/EM
+conterminous/Y
+contestable/I
+contestant/MS
+contested/U
+contextualization
+contextualize/DSG
+contiguity/M
+contiguous/Y
+continence/IM
+continent/SM
+continental/SM
+contingency/SM
+contingent/SMY
+continua
+continuable
+continual/Y
+continuance/ESM
+continuation/ESM
+continue/EGDS
+continuity/ESM
+continuous/EY
+continuum/M
+contort/GD
+contortion/MS
+contortionist/SM
+contra/S
+contraband/M
+contraception/M
+contraceptive/SM
+contract/MDG
+contractible
+contractile
+contraction/S
+contractual/Y
+contradict/DGS
+contradiction/SM
+contradictorily
+contradictory
+contradistinction/SM
+contraflow/S
+contrail/MS
+contraindicate/GNDSX
+contraindication/M
+contralto/SM
+contraption/SM
+contrapuntal/Y
+contrariety/M
+contrarily
+contrariness/M
+contrariwise
+contrary/SMP
+contrast/MDGVS
+contrasting/Y
+contrasty
+contravene/GDS
+contravention/SM
+contretemps/M
+contribute/GNDX
+contribution/M
+contributor/SM
+contributory
+contrition/M
+contrivance/SM
+contrive/ZGDRS
+contriver/M
+control's
+control/CS
+controllable/U
+controlled/UC
+controller/MS
+controlling/C
+controversial/UY
+controversy/SM
+controvert/DGS
+controvertible/I
+contumacious/Y
+contumacy/M
+contumelious
+contumely/SM
+contuse/XDSGN
+contusion/M
+conundrum/SM
+conurbation/SM
+convalesce/GDS
+convalescence/MS
+convalescent/SM
+convect/GVSD
+convection/M
+convectional
+convector/S
+convene/ADSG
+convener/MS
+convenience/IMS
+convenient/IY
+convent/SM
+conventicle/SM
+convention/MS
+conventional/UY
+conventionalism
+conventionalist
+conventionality/UM
+conventionalize/GDS
+conventioneer/S
+convergence/SM
+convergent
+conversant
+conversation/MS
+conversational/Y
+conversationalist/SM
+conversazione
+converse/Y
+convert's
+convert/AGSD
+converted/U
+converter/SM
+convertibility/M
+convertible/SM
+convex/Y
+convexity/M
+convey/SBDG
+conveyance/MGS
+conveyor/MS
+convict/GSMD
+conviction/SM
+convince/GDS
+convinced/U
+convincing/UY
+convivial/Y
+conviviality/M
+convoke/DSG
+convoluted
+convolution/MS
+convolve/D
+convoy/SMDG
+convulse/GNVXDS
+convulsion/M
+convulsive/Y
+cony/SM
+coo/GSMD
+cook's
+cook/ADGS
+cookbook/MS
+cooked/U
+cooker/SM
+cookery/SM
+cookhouse/S
+cookie/SM
+cooking/M
+cookout/SM
+cookware/SM
+cool/MDRYZTGPS
+coolant/SM
+cooler/M
+coolie/SM
+coolness/M
+coon/SM!
+coonskin/MS
+coop/MDRZGS
+cooper/MDG
+cooperage/M
+cooperate/DSGNV
+cooperation/M
+cooperative/PSMY
+cooperativeness/M
+cooperator/MS
+coordinate/MYGNDS
+coordinated/U
+coordination/M
+coordinator/SM
+coot/MS
+cootie/SM
+cop/GJSMD
+copacetic
+copay/M
+cope/MS
+copier/M
+copilot/SM
+coping/M
+copious/PY
+copiousness/M
+coplanar
+copped
+copper/SM
+copperhead/MS
+copperplate/M
+coppery
+copping
+copra/M
+coprocessor/S
+coprolite
+coprophagous
+copse/SM
+copter/SM
+copula/SM
+copulate/XGNVDS
+copulation/M
+copulative/SM
+copulatory
+copy/DRSMZGB
+copybook/SM
+copycat/MS
+copycatted
+copycatting
+copyist/MS
+copyleft/S
+copyright/SGMDB
+copywriter/SM
+coquetry/SM
+coquette/DSMG
+coquettish/Y
+cor
+coracle/SM
+coral/SM
+coralline
+corbel/SM
+cord/EASGDM
+cordage/M
+cordial/SMY
+cordiality/M
+cordillera/MS
+cordite/M
+cordless
+cordon/SMDG
+cordovan/M
+corduroy/MS
+corduroys/M
+core/MZGDRS
+coreligionist/S
+corer/M
+corespondent/SM
+corgi/SM
+coriander/M
+cork's
+cork/UDGS
+corkage
+corker/SM
+corkscrew/SMDG
+corm/MS
+cormorant/SM
+corn/MDRZGS
+cornball/MS
+cornbread/M
+corncob/MS
+corncrake/S
+cornea/SM
+corneal
+corner/GMD
+cornerstone/SM
+cornet/SM
+cornfield/S
+cornflake/S
+cornflakes/M
+cornflour
+cornflower/MS
+cornice/MS
+cornily
+corniness/M
+cornmeal/M
+cornrow/MDGS
+cornstalk/SM
+cornstarch/M
+cornucopia/MS
+corny/PRT
+corolla/MS
+corollary/SM
+corona/SM
+coronal/MS
+coronary/SM
+coronation/SM
+coroner/MS
+coronet/MS
+corp
+corpora
+corporal/SM
+corporate/SN
+corporately
+corporation/IM
+corporations
+corporatism
+corporatist
+corporeal/Y
+corporeality/M
+corps/MS
+corpse/M
+corpsman/M
+corpsmen
+corpulence/M
+corpulent
+corpus/M
+corpuscle/MS
+corpuscular
+corr
+corral/SM
+corralled
+corralling
+correct/DRYTGVSBP
+correctable/U
+corrected/U
+correction/MS
+correctional
+corrective/MS
+correctness/IM
+corrector/S
+correlate/DSXMGNV
+correlated/U
+correlation/M
+correlative/SM
+correspond/SDG
+correspondence/MS
+correspondent/SM
+corresponding/Y
+corridor/SM
+corrie/S
+corrigenda
+corroborate/GNVXDS
+corroborated/U
+corroboration/M
+corroborator/SM
+corroboratory
+corrode/GDS
+corrosion/M
+corrosive/SMY
+corrugate/GNXDS
+corrugation/M
+corrupt/DRYPSTG
+corrupted/U
+corruptibility/IM
+corruptible/I
+corruption/SM
+corruptness/M
+corsage/MS
+corsair/MS
+corset/SGMD
+cortege/MS
+cortex/M
+cortical
+cortices
+corticosteroid/S
+cortisol
+cortisone/M
+corundum/M
+coruscate/GNDS
+coruscation/M
+corvette/SM
+cos/M
+cosh/DSG
+cosign/ZGSDR
+cosignatory/SM
+cosigner/M
+cosine/SM
+cosmetic/SM
+cosmetically
+cosmetician/SM
+cosmetologist/MS
+cosmetology/M
+cosmic
+cosmical/Y
+cosmogonist/SM
+cosmogony/SM
+cosmological/Y
+cosmologist/MS
+cosmology/SM
+cosmonaut/SM
+cosmopolitan/SM
+cosmopolitanism/M
+cosmos/MS
+cosponsor/SGMD
+cossacks
+cosset/SGD
+cossetted
+cossetting
+cost/MYGSJ
+costar/SM
+costarred
+costarring
+costless
+costliness/M
+costly/PTR
+costume/MZGDRS
+costumer/M
+costumier/S
+cot/SM
+cotangent/MS
+cote/MS
+coterie/MS
+coterminous
+cotillion/SM
+cottage/MZGRS
+cottager/M
+cotter/SM
+cotton/SGMD
+cottonmouth/M
+cottonmouths
+cottonseed/SM
+cottontail/SM
+cottonwood/SM
+cottony
+cotyledon/MS
+couch/MDSG
+couchette/S
+cougar/SM
+cough/MDG
+coughs
+could
+couldn't
+coulee/SM
+coulis
+coulomb/MS
+council/MS
+councilman/M
+councilmen
+councilor/MS
+councilperson/SM
+councilwoman/M
+councilwomen
+counsel/JMDGS
+counselor/MS
+count/ERBZGDMS
+countability/E
+countable/U
+countably/U
+countdown/MS
+counted/U
+countenance's
+countenance/EGDS
+counter/EM
+counteract/GVSD
+counteraction/MS
+counterargument/S
+counterattack/MDGS
+counterbalance/DSMG
+counterblast/S
+counterclaim/SGMD
+counterclockwise
+counterculture/SM
+countered
+counterespionage/M
+counterexample/S
+counterfeit/ZGMDRS
+counterfeiter/M
+counterfoil/MS
+countering
+counterinsurgency/SM
+counterintelligence/M
+counterman/M
+countermand/MDGS
+countermeasure/SM
+countermen
+counteroffensive/MS
+counteroffer/SM
+counterpane/MS
+counterpart/MS
+counterpoint/MDGS
+counterpoise/MGDS
+counterproductive
+counterrevolution/MS
+counterrevolutionary/SM
+countersign/GMDS
+countersignature/MS
+countersink/GMS
+counterspy/SM
+counterstrike
+countersunk
+countertenor/MS
+countervail/GDS
+counterweight/MS
+countess/MS
+countless
+countrified
+country/SM
+countryman/M
+countrymen
+countryside/MS
+countrywide
+countrywoman/M
+countrywomen
+county/SM
+countywide
+coup's
+coup/AS
+coupe/SM
+couple's
+couple/CUDSG
+coupler/S
+couplet/MS
+coupling/SM
+coupon/SM
+courage/M
+courageous/YP
+courageousness/M
+courgette/S
+courier/MDSG
+course/EDGMS
+coursebook/S
+courser/MS
+coursework
+court/SMDYG
+courteous/EY
+courteousness/M
+courtesan/SM
+courtesy/ESM
+courthouse/MS
+courtier/SM
+courtliness/M
+courtly/PRT
+courtroom/MS
+courtship/MS
+courtyard/MS
+couscous/M
+cousin/SMY
+couture/M
+couturier/MS
+covalent/Y
+covariance/S
+cove/MS
+coven/SM
+covenant/MDSG
+cover's
+cover/AEUGDS
+coverage/MS
+coverall/MS
+covering's
+coverings
+coverlet/MS
+coversheet
+covert/SPMY
+covertness/M
+covet/SDG
+covetous/YP
+covetousness/M
+covey/SM
+cow/ZGSMDR
+coward/SMY
+cowardice/M
+cowardliness/M
+cowbell/MS
+cowbird/MS
+cowboy/SM
+cowcatcher/MS
+cower/DG
+cowgirl/MS
+cowhand/MS
+cowherd/MS
+cowhide/MS
+cowl/MDGSJ
+cowlick/MS
+cowling/M
+cowman/M
+cowmen
+coworker/MS
+cowpat/S
+cowpoke/MS
+cowpox/M
+cowpuncher/SM
+cowrie/SM
+cowshed/S
+cowslip/SM
+cox/GDS
+coxcomb/MS
+coxswain/MS
+coy/TPRY
+coyness/M
+coyote/SM
+coypu/SM
+cozen/SDG
+cozenage/M
+cozily
+coziness/M
+cozy/RSMTP
+cpd
+cpl
+cps
+crab/MS
+crabbed
+crabber/SM
+crabbily
+crabbiness/M
+crabbing
+crabby/PRT
+crabgrass/M
+crablike
+crabwise
+crack/SMDRYZGBJ
+crackable/U
+crackdown/MS
+cracker/M
+crackerjack/MS
+crackhead/MS
+crackle/DSJMG
+crackling/M
+crackly/TR
+crackpot/MS
+crackup/SM
+cradle/DSMG
+craft/SMDG
+craftily
+craftiness/M
+craftsman/M
+craftsmanship/M
+craftsmen
+craftspeople
+craftswoman/M
+craftswomen
+crafty/RTP
+crag/MS
+cragginess/M
+craggy/RPT
+cram/S
+crammed
+crammer/S
+cramming
+cramp/SMDG
+cramping/M
+crampon/SM
+cranberry/SM
+crane/DSMG
+cranial
+cranium/SM
+crank/SMDRTG
+crankcase/SM
+crankily
+crankiness/M
+crankshaft/MS
+cranky/PRT
+cranny/DSM
+crap/MS
+crape/SM
+crapped
+crapper/S
+crappie/RSMT
+crapping
+crappy
+craps/M
+crapshooter/SM
+crash/MDRSZG
+crashing/Y
+crass/RYTP
+crassness/M
+crate/DRSMZG
+crater/MDG
+cravat/SM
+crave/DSGJ
+craven/SMYP
+cravenness/M
+craving/M
+craw/MS
+crawdad/SM
+crawl/SMDRZG
+crawler/M
+crawlspace/MS
+crawly/TRSM
+cray/S
+crayfish/MS
+crayola/S
+crayon/GSMD
+craze/DSMG
+crazily
+craziness/M
+crazy/PRSMT
+creak/SMDG
+creakily
+creakiness/M
+creaky/RPT
+cream/SMDRZG
+creamer/M
+creamery/SM
+creamily
+creaminess/M
+creamy/RPT
+crease/ICGMSD
+creased/U
+creatable
+create/KADSGNV
+created/U
+creation's/K
+creation/ASM
+creationism/SM
+creationist/SM
+creative/SMYP
+creativeness/M
+creativity/M
+creator/MS
+creature/SM
+creche/SM
+cred
+credence/M
+credential/GSMD
+credenza/SM
+credibility/IM
+credible/I
+credibly/I
+credit/EGSBMD
+creditability
+creditably/E
+credited/U
+creditor/SM
+creditworthy/P
+credo/SM
+credulity/IM
+credulous/IY
+credulousness/M
+creed/SM
+creek/SM
+creel/SM
+creep/SMRZG
+creeper/M
+creepily
+creepiness/M
+creepy/TPR
+cremains/M
+cremate/GNDSX
+cremation/M
+crematoria
+crematorium/SM
+crematory/SM
+creme/SM
+crenelate/GNXDS
+crenelation/M
+creole/SM
+creosote/MGDS
+crepe/SM
+crept
+crepuscular
+crescendo/CSM
+crescent/MS
+cress/M
+crest/SMDG
+crestfallen
+crestless
+cretaceous
+cretin/SM
+cretinism/M
+cretinous
+cretonne/M
+crevasse/SM
+crevice/MS
+crew/MDGS
+crewel/M
+crewelwork/M
+crewman/M
+crewmen
+crib/MS
+cribbage/M
+cribbed
+cribber/MS
+cribbing
+crick/SMDG
+cricket/MRSZG
+cricketer/M
+crier/M
+crikey
+crime/SM
+criminal/MYS
+criminality/M
+criminalization/C
+criminalize/CGDS
+criminological
+criminologist/MS
+criminology/M
+crimp/SMDG
+crimson/SMDG
+cringe/DSMG
+crinkle/DSMG
+crinkly/RT
+crinoline/SM
+cripes
+cripple/DRSMZG
+crippler/M
+crippleware/S
+crippling/Y
+crises
+crisis/M
+crisp/SMDRYTGP
+crispbread/S
+crispiness/M
+crispness/M
+crispy/PRT
+crisscross/MDSG
+criteria
+criterion/M
+critic/SM
+critical/UY
+criticism/MS
+criticize/ZGDRS
+criticizer/M
+critique/MGDS
+critter/SM
+croak/SMDG
+croaky/RT
+crochet/SMDRZG
+crocheter/M
+crocheting/M
+crock/SMD
+crockery/M
+crocodile/SM
+crocus/MS
+croft/SRZG
+croissant/MS
+crone/SM
+crony/SM
+cronyism/M
+crook/SMDG
+crooked/PTRY
+crookedness/M
+crookneck/SM
+croon/SMDRZG
+crooner/M
+crop/MS
+cropland/SM
+cropped
+cropper/MS
+cropping
+croquet/MDG
+croquette/SM
+crosier/MS
+cross's
+cross/AUGTSD
+crossbar/SM
+crossbeam/MS
+crossbones/M
+crossbow/SM
+crossbowman/M
+crossbowmen
+crossbred
+crossbreed/SMG
+crosscheck/SGMD
+crosscurrent/SM
+crosscut/SM
+crosscutting
+crosser
+crossfire/MS
+crosshatch/DSG
+crossing/SM
+crossly
+crossness/M
+crossover/MS
+crosspatch/MS
+crosspiece/SM
+crossroad/MS
+crossroads/M
+crosstalk
+crosstown
+crosswalk/MS
+crosswind/MS
+crosswise
+crossword/MS
+crotch/MS
+crotchet/SM
+crotchety/P
+crotchless
+crouch/GMDS
+croup/M
+croupier/M
+croupy/ZTR
+crouton/MS
+crow/MDGS
+crowbar/MS
+crowd/SMDG
+crowded/U
+crowfeet
+crowfoot/M
+crown/SMDG
+crowned/U
+crucial/Y
+cruciate
+crucible/SM
+crucifiable
+crucifix/MS
+crucifixion/MS
+cruciform/SM
+crucify/DSG
+crud/M
+cruddy/TR
+crude/RMYTP
+crudeness/M
+crudites/M
+crudity/SM
+cruel/RYPT
+cruelness/M
+cruelty/SM
+cruet/SM
+cruft/SDG
+crufty/S
+cruise/DRSMZG
+cruiser/M
+cruller/MS
+crumb/SMDYG
+crumble/MGDS
+crumbliness/M
+crumbly/TPR
+crumby/TR
+crumminess/M
+crummy/PTR
+crumpet/MS
+crumple/MGDS
+crunch/ZGMDRS
+crunchiness/M
+crunchy/TRP
+crupper/MS
+crusade/MZGDRS
+crusader/M
+cruse/SM
+crush/MDRSZG
+crusher/M
+crushing/Y
+crust/SMDG
+crustacean/SM
+crustal
+crustily
+crustiness/M
+crusty/TRP
+crutch/MS
+crux/MS
+cry/ZGJDRSM
+crybaby/SM
+cryogenic/S
+cryogenics/M
+cryonics
+cryostat
+cryosurgery/M
+crypt's
+crypt/CS
+cryptanalysis
+cryptanalyst
+cryptanalytic
+cryptic
+cryptically
+cryptogram/SM
+cryptographer/MS
+cryptographic
+cryptographically
+cryptography/M
+cryptology
+crystal/SM
+crystalline
+crystallization/M
+crystallize/ADSG
+crystallographer/S
+crystallographic
+crystallography
+ct
+ctn
+ctr
+cu
+cub/ZGSJMDR
+cubbyhole/MS
+cube/MS
+cuber/M
+cubic
+cubical/Y
+cubicle/MS
+cubing/GD
+cubism/M
+cubist/SM
+cubit/SM
+cuboid/S
+cuckold/MDSG
+cuckoldry/M
+cuckoo/SM
+cucumber/SM
+cud/SM
+cuddle/DSMG
+cuddly/TRP
+cudgel/SGMDJ
+cue/DSMG
+cuff/MDGS
+cuisine/SM
+culinary
+cull/MDGS
+culminate/DSXGN
+culmination/M
+culotte/SM
+culpability/M
+culpable/I
+culpably
+culprit/SM
+cult/MS
+cultism/M
+cultist/MS
+cultivable
+cultivate/DSBXGN
+cultivated/U
+cultivation/M
+cultivator/MS
+cultural/Y
+culture/MGDS
+cultured/U
+culvert/MS
+cum/SM
+cumber/SDG
+cumbersome/PY
+cumbersomeness/M
+cumbrous
+cumin/M
+cummerbund/MS
+cumming
+cumulative/Y
+cumuli
+cumulonimbi
+cumulonimbus/M
+cumulus/M
+cuneiform/M
+cunnilingus/M
+cunning/MRYT
+cunt/SM!
+cup/SM
+cupboard/SM
+cupcake/MS
+cupful/SM
+cupid/SM
+cupidinously
+cupidity/M
+cupola/SMD
+cuppa/S
+cupped
+cupping
+cupric
+cur/SMY
+curability/M
+curacao
+curacy/SM
+curare/M
+curate/DSMGV
+curative/MS
+curator/KMS
+curatorial
+curatorships
+curb/MDGS
+curbing/M
+curbside
+curbstone/SM
+curd/MS
+curdle/DSG
+cure's
+cure/KZGBDRS
+cured/U
+curer/KM
+curettage/M
+curfew/SM
+curia/M
+curiae
+curial
+curie/SM
+curio/SM
+curiosity/SM
+curious/RYTP
+curiousness/M
+curium/M
+curl's
+curl/UDGS
+curler/SM
+curlew/SM
+curlicue/DSMG
+curliness/M
+curling/M
+curly/RPT
+curmudgeon/MYS
+currant/MS
+currency/SM
+current's
+current/FAY
+currents
+curricle
+curricula
+curricular
+curriculum/M
+curry/DSMG
+currycomb/SGMD
+curse/DSMGV
+cursed/TRY
+cursive's
+cursive/EAY
+cursor/SM
+cursorily
+cursoriness/M
+cursory/P
+curt/RYTP
+curtail/GDSL
+curtailment/MS
+curtain/GMDS
+curtness/M
+curtsy/GDSM
+curvaceous/P
+curvaceousness/M
+curvature/SM
+curve/DSMG
+curvilinear
+curvy/RT
+cushion/MDSG
+cushy/RT
+cusp/MS
+cuspid/SM
+cuspidor/SM
+cuss's
+cuss/EFGSD
+cussed/PY
+custard/MS
+custodial
+custodian/MS
+custodianship/M
+custody/M
+custom/SZMR
+customarily
+customary/U
+customer/M
+customhouse/MS
+customization/MS
+customize/DSGB
+cut/TSMR
+cutaneous
+cutaway/MS
+cutback/MS
+cute/YP
+cuteness/M
+cutesy/TR
+cutey/S
+cuticle/MS
+cutie/SM
+cutlass/MS
+cutler/SM
+cutlery/M
+cutlet/SM
+cutoff/SM
+cutout/SM
+cutter/SM
+cutthroat/SM
+cutting/MYS
+cuttle
+cuttlefish/MS
+cutup/SM
+cutworm/MS
+cw
+cwt
+cyan/M
+cyanide/M
+cyanogen
+cybercafe/S
+cybernetic/S
+cybernetics/M
+cyberpunk/SM
+cyberspace/MS
+cyborg/SM
+cyclamen/MS
+cycle/ADSMG
+cycleway/S
+cyclic
+cyclical/Y
+cyclist/MS
+cycloid
+cyclometer/MS
+cyclone/MS
+cyclonic
+cyclopedia/MS
+cyclopes
+cyclops/M
+cyclotron/MS
+cygnet/MS
+cylinder/MS
+cylindrical/Y
+cymbal/MS
+cymbalist/MS
+cynic/SM
+cynical/Y
+cynicism/M
+cynosure/MS
+cypress/MS
+cyst/MS
+cysteine
+cystic
+cystitis
+cytochrome
+cytological
+cytologist/MS
+cytology/M
+cytoplasm/M
+cytoplasmic
+cytosine/M
+cytotoxic
+czar/MS
+czarina/SM
+czarism
+czarist/SM
+d'Arezzo
+d'Estaing
+d/NXGJ
+dB
+dab/SM
+dabbed
+dabber/MS
+dabbing
+dabble/ZGDRS
+dabbler/M
+dace/SM
+dacha/MS
+dachshund/MS
+dactyl/MS
+dactylic/MS
+dad/SM
+dadaism/M
+dadaist/MS
+daddy/SM
+dado/M
+dadoes
+daemon/MS
+daemonic
+daffiness/M
+daffodil/SM
+daffy/PTR
+daft/PTRY
+daftness/M
+dag/S
+dagger/MS
+dago/S
+dagoes
+daguerreotype/DSMG
+dahlia/MS
+dailiness/M
+daily/PSM
+daintily
+daintiness/M
+dainty/RSMTP
+daiquiri/MS
+dairy/GSM
+dairying/M
+dairymaid/MS
+dairyman/M
+dairymen
+dairywoman/M
+dairywomen
+dais/MS
+daisy/SM
+dale/SM
+dalesman
+dalliance/MS
+dallier/M
+dally/ZGDRS
+dalmatian/MS
+dam/SM
+damage/MGDS
+damageable
+damaged/U
+damages/M
+damaging/Y
+damask/MDGS
+dame/SM
+dammed
+damming
+dammit
+damn/SBGMD
+damnably
+damnation/M
+damned/TR
+damning/Y
+damp/SPXZTGMDNRY
+dampen/ZGDR
+dampener/M
+damper/M
+dampness/M
+damsel/MS
+damselfly/SM
+damson/MS
+dance/MZGDRS
+danceable
+dancer/M
+dancing/M
+dandelion/SM
+dander/M
+dandify/GDS
+dandle/GDS
+dandruff/M
+dandy/TRSM
+dang/SZGDR
+danger/M
+dangerous/PY
+dangle/ZGDRS
+dangler/M
+danish/MS
+dank/PTRY
+dankness/M
+danseuse/MS
+dapper/TR
+dapple/MGDS
+dare/DRSMZG
+daredevil/MS
+daredevilry/M
+darer/M
+daresay
+daring/MY
+dark/PXTMNRY
+darken/ZGDR
+darkener/M
+darkie/S
+darkish
+darkly/TR
+darkness/M
+darkroom/MS
+darling/MS
+darn/SZGMDR
+darned/TR
+darner/M
+dart/SZGMDR
+dartboard/MS
+darter/M
+dash/ZGMRS
+dashboard/SM
+dasher/M
+dashiki/MS
+dashing/Y
+dastard/MYS
+dastardliness/M
+data
+database/SM
+date/DRSBMZGV
+datebook/S
+dated/U
+dateless
+dateline/MGDS
+dater/M
+dative/MS
+datum/MS
+daub/SZGMDR
+dauber/M
+daughter/SMY
+daunt/GDS
+daunting/Y
+dauntless/YP
+dauntlessness/M
+dauphin/MS
+davenport/MS
+davit/MS
+dawdle/ZGDRS
+dawdler/M
+dawn/SGMD
+day/SM
+daybed/MS
+daybreak/M
+daycare/M
+daydream/MDRZGS
+daydreamer/M
+daylight/MS
+daylights/M
+daylong
+daysack
+daytime/M
+daze/DSMG
+dazed/Y
+dazzle/MZGDRS
+dazzler/M
+dazzling/Y
+db
+dbl
+dc
+dd/SDG
+dded/K
+dding/K
+deacon/MS
+deaconess/MS
+dead/PXTMNRY
+deadbeat/MS
+deadbolt/SM
+deaden/GD
+deadhead/SDG
+deadline/SM
+deadliness/M
+deadlock/GSMD
+deadly/TPR
+deadpan/MS
+deadpanned
+deadpanning
+deadwood/M
+deaf/PXTNR
+deafen/GD
+deafening/Y
+deafness/M
+deal/SJZGMR
+dealer/M
+dealership/MS
+dealing/M
+dealt
+dean/M
+deanery/SM
+deanship/M
+dear/SPTMRYH
+dearest/S
+dearness/M
+dearth/M
+dearths
+deary/SM
+death/MY
+deathbed/SM
+deathblow/MS
+deathless/Y
+deathlike
+deathly/RT
+deaths
+deathtrap/MS
+deathwatch/MS
+deaves
+deb/SM
+debacle/MS
+debarkation/M
+debarment/M
+debate/BMZR
+debater/M
+debating/M
+debauch/MDSG
+debauchee/MS
+debauchery/SM
+debenture/MS
+debilitate/GNDS
+debilitation/M
+debility/SM
+debit/D
+debonair/PY
+debonairness/M
+debouch/GDS
+debris/M
+debt/SM
+debtor/MS
+debugger/S
+debut/GMD
+debutant
+debutante/SM
+decade/MS
+decadence/M
+decadency/M
+decadent/MYS
+decaf/MS
+decaffeinate/GDS
+decagon/MS
+decal/MS
+decampment/M
+decapitate/XDSGN
+decapitator/MS
+decathlete/S
+decathlon/SM
+decay/GD
+deceased/M
+decedent/MS
+deceit/MS
+deceitful/PY
+deceitfulness/M
+deceive/UGDS
+deceiver/MS
+deceiving/Y
+decelerate/XDSGN
+deceleration/M
+decelerator/MS
+decency/ISM
+decennial/SM
+decent/ITRY
+deception/MS
+deceptive/YP
+deceptiveness/M
+decibel/MS
+decidability/U
+decidable/U
+decide/BZGDRS
+decided/Y
+deciduous
+deciles
+deciliter/MS
+decimal/SM
+decimalization
+decimalize
+decimate/DSGN
+decimation/M
+decimeter/MS
+decipherable/IU
+decipherment/S
+decision/IM
+decisions
+decisive/IPY
+decisiveness/IM
+deck/SGMD
+deckchair/S
+deckhand/SM
+deckle/S
+declamation/SM
+declamatory
+declaration/SM
+declarative
+declaratory
+declare/DRSZGB
+declared/U
+declarer/M
+declension/SM
+declination/MS
+decline/DRSMZG
+decliner/M
+declivity/SM
+deco
+decolletage/MS
+decollete
+decompose/B
+decongestant/MS
+deconstruct/V
+deconstructionism
+deconvolution
+deconvolve
+decor/MS
+decorate/AGNVDS
+decorated/U
+decorating/M
+decoration/AM
+decorations
+decorative/Y
+decorator/MS
+decorous/IY
+decorousness/M
+decorum/M
+decoupage/DSMG
+decoy/GMDS
+decreasing/Y
+decree/MDS
+decreeing
+decrement/GDS
+decremental
+decrepit
+decrepitude/M
+decriminalization/M
+decry/GDS
+decrypt/GD
+decryption
+decustomised
+dedicate/AGDS
+dedication/SM
+dedicator/SM
+dedicatory
+deduce/GDS
+deducible
+deductible/SM
+deduction/SM
+deductive/Y
+deed/GD
+deejay/MS
+deem/ASGD
+deep/SPXTMNRY
+deepen/GD
+deepish
+deepness/M
+deer/SM
+deerskin/M
+deerstalker/S
+deerstalking
+def/Z
+defacement/M
+defacer/SM
+defaecate
+defalcate/XDSGN
+defalcation/M
+defamation/M
+defamatory
+defame/ZGDRS
+defamer/M
+defaulter/SM
+defeat/MDRZGS
+defeated/U
+defeater/M
+defeatism/M
+defeatist/MS
+defecate/GNDS
+defecation/M
+defect/MDGVS
+defection/MS
+defective/MYSP
+defectiveness/M
+defector/MS
+defendant/SM
+defended/U
+defenestrate/NDX
+defense/DSMGV
+defenseless/PY
+defenselessness/M
+defensibility
+defensible/I
+defensibly/I
+defensive/MYP
+defensiveness/M
+deference/M
+deferential/Y
+deferral/MS
+deferred
+deferring
+deffer
+deffest
+defiant/Y
+defibrillator/S
+deficiency/SM
+deficient
+deficit/SM
+defiled/U
+defilement/M
+definable/IU
+definably/I
+define/AGDRS
+defined/U
+definer/MS
+definite/IYVP
+definiteness/IM
+definition/ASM
+definitional
+definitive/PY
+deflate/GNBDS
+deflation/M
+deflationary
+deflect/DGVS
+deflection/MS
+deflector/SM
+defogger/SM
+defoliant/SM
+defoliate/DSGN
+defoliation/M
+defoliator/MS
+deform/B
+deformity/SM
+defraud/DRZGS
+defrauder/M
+defrayal/M
+defrock/DG
+defroster/MS
+deft/PTRY
+deftness/M
+defunct
+defy/GDS
+deg
+degauss/GD
+degeneracy/SM
+degenerate/MV
+degrade/B
+degrease
+degree/MS
+dehydrator/SM
+deicer/MS
+deictic
+deification/M
+deify/NGDS
+deign/GDS
+deist/MS
+deistic
+deity/SM
+deject/GDS
+dejected/Y
+dejection/M
+delay/ZDR
+delectable
+delectably
+delectation/M
+delegate/GD
+delete/BXGNDRS
+deleterious/Y
+deletion/M
+delft/M
+delftware/M
+deli/SM
+deliberate/YVPX
+deliberateness/M
+delicacy/ISM
+delicate/IY
+delicateness/M
+delicatessen/SM
+delicious/YP
+deliciousness/M
+delighted/Y
+delightful/Y
+deliminator/S
+delineate/GNDSX
+delineation/M
+delinquency/SM
+delinquent/SMY
+deliquesce/GDS
+deliquescent
+delirious/PY
+deliriousness/M
+delirium/SM
+deliver/ADGS
+deliverable/U
+deliverance/M
+delivered/U
+deliverer/SM
+dell/SM
+delphinium/MS
+delta/MS
+deltoids
+delude/GDS
+deluge/MGDS
+delusion/MS
+delusional
+delusive/Y
+deluxe
+delve/ZGDRS
+delver/M
+demagogic
+demagogically
+demagogue/SM
+demagoguery/M
+demagogy/M
+demand/GMDS
+demanding/U
+demarcate/XDSGN
+demarcation/M
+demean/GDS
+demeanor/M
+demented/Y
+dementia/M
+demesne/MS
+demigod/MS
+demigoddess/MS
+demijohn/SM
+demimondaine/SM
+demimonde/M
+demise/MGDS
+demitasse/MS
+demo/GMD
+democracy/SM
+democrat/MS
+democratic/U
+democratically/U
+democratization/M
+democratize/DSG
+demode
+demodulator
+demographer/MS
+demographic/MS
+demographically
+demographics/M
+demography/M
+demolish/DRSG
+demolition/MS
+demon/MS
+demonetization/M
+demoniac
+demoniacal/Y
+demonic
+demonically
+demonize/GDS
+demonology/SM
+demonstrability
+demonstrable/I
+demonstrably
+demonstrate/GNVXDS
+demonstration/M
+demonstrative/SMYP
+demonstrativeness/M
+demonstrator/SM
+demote/GD
+demotic
+demount/BG
+demulcent/SM
+demur/TMRS
+demure/PY
+demureness/M
+demurral/SM
+demurred
+demurrer/SM
+demurring
+den/M
+denationalization
+denature/DG
+dendrite/SM
+dendrochronological
+dendrochronology
+dengue/M
+deniable/U
+denial/MS
+denier/M
+denigrate/DSXGN
+denigration/M
+denim/MS
+denizen/MS
+denominational
+denotational
+denotative
+denouement/SM
+denounce/DSGL
+denouncement/SM
+dense/PYTR
+denseness/M
+density/SM
+dent/ISGMD
+dental/Y
+dentifrice/SM
+dentin/M
+dentist/MS
+dentistry/M
+dentition/M
+denture/IMS
+denuclearize/GDS
+denudation/M
+denude/GDS
+denunciation/MS
+deny/ZGDRS
+deodorant/SM
+deodorization/M
+deodorize/DRSZG
+deodorizer/M
+departed/M
+department/MS
+departmental/Y
+departmentalization/M
+departmentalize/GDS
+departure/SM
+dependability/M
+dependable/U
+dependably
+dependence/IM
+dependency/SM
+dependent/IMYS
+depict/GDS
+depiction/MS
+depilatory/SM
+deplete/GNDS
+depletion/M
+deplorably
+deplore/BGDS
+deploy/ALGDS
+deployment/AM
+deployments
+deponent/MS
+deportation/SM
+deportee/MS
+deportment/M
+deposit/AGMDS
+depositary
+depositor/MS
+depository/SM
+deprave/GDS
+depravity/SM
+deprecate/GNXDS
+deprecating/Y
+deprecation/M
+deprecatory
+depreciate/DSGN
+depreciation/M
+depredation/MS
+depressant/MS
+depressing/Y
+depression/MS
+depressive/MS
+depressor/MS
+depressurization
+deprive/GDS
+deprogramming
+depth/M
+depths
+deputation/SM
+depute/DSG
+deputize/DSG
+deputy/SM
+derailleur/MS
+derailment/MS
+derangement/M
+derby/SM
+derelict/MS
+dereliction/MS
+deride/D
+derision/M
+derisive/PY
+derisiveness/M
+derisory
+derivation/MS
+derivative/MYS
+derive/B
+dermal
+dermatitis/M
+dermatological
+dermatologist/MS
+dermatology/M
+dermis/M
+derogate/DSGN
+derogation/M
+derogatorily
+derogatory
+derrick/SM
+derriere/SM
+derringer/SM
+derv
+dervish/MS
+desalinate/DSGN
+desalination/M
+desalinization/M
+desalinize/GDS
+descant/M
+descend/FGDS
+descendant/SM
+descender/S
+describable/I
+describer/MS
+description/SM
+descriptive/YP
+descriptiveness/M
+descriptivism
+descriptor/S
+descry/GDS
+desecrate/DSGN
+desecration/M
+deselection
+desert/SDRZGM
+deserter/M
+desertification
+desertion/SM
+deserved/UY
+deserving/U
+desiccant/SM
+desiccate/DSGN
+desiccation/M
+desiccator/SM
+desiderata
+desideratum/M
+design/MRZB
+designate/XDSGN
+designation/M
+designational
+designator/S
+designed/Y
+desirabilia
+desirability/UM
+desirableness/M
+desirably/U
+desire/B
+desired/U
+desirous
+desist/SDG
+desk/SM
+deskill/G
+desktop/SM
+desolate/DSPYGN
+desolateness/M
+desolation/M
+desorption
+despair/SMDG
+despairing/Y
+desperado/M
+desperadoes
+desperate/PYN
+desperateness/M
+desperation/M
+despicable
+despicably
+despise/DSG
+despite
+despoilment/M
+despond
+despondence/M
+despondency/M
+despondent/Y
+despotic
+despotically
+despotism/M
+dessert/SM
+dessertspoon/S
+dessertspoonful/S
+dessicated
+dessication
+destination/MS
+destine/DSG
+destiny/SM
+destitute/N
+destitution/M
+destroy/SBZGDR
+destroyer/M
+destruct/GVMDS
+destructibility/IM
+destructible/I
+destruction/M
+destructive/PY
+destructiveness/M
+desuetude/M
+desultorily
+desultory/P
+detach/BLGDS
+detachment/SM
+detain/LGDS
+detainee/MS
+detainment/M
+detect/SDGVB
+detectability/U
+detectable/U
+detectably/U
+detected/U
+detection/SM
+detective/SM
+detector/SM
+detente/SMNX
+detention/M
+deter/SL
+detergent/SM
+deteriorate/DSGN
+deterioration/M
+determent/M
+determinable/I
+determinacy/I
+determinant/SM
+determinate/YV
+determine/AGDS
+determined/U
+determinedly
+determiner/SM
+determinism/M
+determinist
+deterministic
+deterministically
+deterred/U
+deterrence/M
+deterrent/MS
+deterring
+detest/RZB
+detestably
+detestation/M
+dethrone/GL
+dethronement/M
+detonate/GNDSX
+detonated/U
+detonation/M
+detonator/SM
+detox/MDSG
+detoxification/M
+detoxify/DSGN
+detract/GD
+detriment/SM
+detrimental/Y
+detritus/M
+deuce/SM
+deuterium/M
+deuteron
+devastate/GNDS
+devastating/Y
+devastation/M
+devastator/MS
+develop/ASGDL
+developed/U
+developer/SM
+development/ASM
+developmental/Y
+deviance/M
+deviancy/M
+deviant/SM
+deviate/DSMGNX
+deviating/U
+deviation/M
+devil/SMDGL
+devilish/YP
+devilishness/M
+devilment/M
+devilry/SM
+deviltry/SM
+devious/YP
+deviousness/M
+devoid
+devolution/M
+devolve/DSG
+devoted/PY
+devotee/SM
+devotion/MS
+devotional/SM
+devour/SDRZG
+devout/PRYT
+devoutness/M
+dew/SM
+dewberry/SM
+dewclaw/SM
+dewdrop/SM
+dewiness/M
+dewlap/SM
+dewy/RTP
+dexterity/M
+dexterous/YP
+dexterousness/M
+dextrose/M
+dhoti/SM
+dhow/MS
+diabetes/M
+diabetic/SM
+diabolic
+diabolical/Y
+diabolism
+diachronic
+diacritic/MS
+diacritical/S
+diadem/SM
+diaereses
+diaeresis/M
+diagnosable/U
+diagnose/DSBG
+diagnosed/U
+diagnosis/M
+diagnostic/S
+diagnostically
+diagnostician/MS
+diagnostics/M
+diagonal/SMY
+diagonalize/DSG
+diagram/SM
+diagrammatic
+diagrammatically
+diagrammed
+diagramming
+dial/AMDGS
+dialect/SM
+dialectal
+dialectic/SM
+dialectical/Y
+dialectics/M
+dialer
+dialing/S
+dialog/SMGD
+dialogue/SMRGD
+dialysis/M
+dialyzes
+diam
+diamante
+diameter/SM
+diametric
+diametrical/Y
+diamond/SM
+diamondback/SM
+diapason/SM
+diaper/SMDG
+diaphanous
+diaphragm/SM
+diaphragmatic
+diarist/SM
+diarrhea/M
+diary/SM
+diaspora
+diastase/M
+diastole/M
+diastolic
+diathermy/M
+diatom/SM
+diatomic
+diatonic
+diatribe/SM
+dibble/DSMG
+dibs/M
+dice/GDS
+dicey
+dichloride
+dichotomous
+dichotomy/SM
+dicier
+diciest
+dick/MRXZS
+dicker/DG
+dickey/SM
+dickhead/S
+dickier
+dickiest
+dickybird/S
+dicotyledon/MS
+dicotyledonous
+dict
+dicta
+dictate/DSMGNX
+dictation/M
+dictator/SM
+dictatorial/Y
+dictatorship/SM
+diction/M
+dictionary/SM
+dictum/M
+did/AU
+didactic
+didactically
+diddle/DRSZG
+diddler/M
+diddly
+diddlysquat
+diddums
+didgeridoo/S
+didn't
+dido/M
+didoes
+didst
+die/DSM
+dieing
+dielectric/MS
+diereses
+dieresis/M
+diesel/SMDG
+diet/MDRZGS
+dietary/SM
+dieter/M
+dietetic/S
+dietetics/M
+dietitian/MS
+diff/DRZGS
+differ/DG
+difference/MGS
+different/IY
+differentiability
+differentiable
+differential/MYS
+differentiate/DSGNX
+differentiated/U
+differentiation/M
+differentiators
+difficult/Y
+difficulty/SM
+diffidence/M
+diffident/Y
+diffract/GSD
+diffraction/M
+diffuse/DRSYZGNVP
+diffuseness/M
+diffusion/M
+diffusional
+diffusivity
+dig/SM
+digerati/M
+digest/SMDGV
+digested/U
+digestibility/M
+digestible/I
+digestion/IM
+digestions
+digestive/S
+digger/SM
+digging/S
+diggings/M
+digit/SM
+digital/Y
+digitalis/M
+digitization
+digitize/ZGDRS
+dignified/U
+dignify/DSG
+dignitary/SM
+dignity/ISM
+digraph/M
+digraphs
+digress/GVDS
+digression/SM
+dihedral
+dike/MGDS
+diktat/S
+dilapidated
+dilapidation/M
+dilatation/M
+dilate/DSGN
+dilation/M
+dilator/SM
+dilatory
+dildo/S
+dilemma/MS
+dilettante/SM
+dilettantish
+dilettantism/M
+diligence/M
+diligent/Y
+dill/MS
+dilly/SM
+dillydally/GDS
+diluent
+dilute/DSGNX
+diluted/U
+dilution/M
+dim/ZPSRY
+dime/MS
+dimension/SGMD
+dimensional/Y
+dimensionality
+dimensionless
+diminish/GBDS
+diminished/U
+diminuendo/SM
+diminution/SM
+diminutive/SM
+dimity/M
+dimmed/U
+dimmer/SM
+dimmest
+dimming
+dimness/M
+dimorphic
+dimorphism
+dimple/DSMG
+dimply/RT
+dimwit/SM
+dimwitted
+din/ZGSMDR
+dinar/SM
+dine/S
+diner/M
+dinette/MS
+ding/MDG
+dingbat/MS
+dinghy/SM
+dingily
+dinginess/M
+dingle/SM
+dingo/SM
+dingoes
+dingus/MS
+dingy/RPT
+dink/RT
+dinky/RSMT
+dinned
+dinner/SMDG
+dinnertime/M
+dinnerware/M
+dinning
+dinosaur/SM
+dint/MS
+diocesan/MS
+diocese/MS
+diode/SM
+diopter/S
+diorama/SM
+dioxide/SM
+dioxin/SM
+dip/SM
+diphtheria/M
+diphthong/SM
+diplexers
+diploid/SM
+diploma/SM
+diplomacy/M
+diplomat/MS
+diplomata
+diplomatic/U
+diplomatically
+diplomatist/SM
+dipole/SM
+dipped
+dipper/SM
+dipping
+dippy/RT
+dipso/S
+dipsomania/M
+dipsomaniac/MS
+dipstick/SM
+dipterous
+diptych/M
+diptychs
+dire/YTPR
+direct/ASDGVT
+directed/U
+directer
+direction/ISM
+directional/Y
+directionality
+directionless
+directive/SM
+directly
+directness/IM
+director/MS
+directorate/SM
+directorial
+directorship/SM
+directory/SM
+direful
+dirge/SM
+dirigible/MS
+dirk/MS
+dirndl/SM
+dirt/M
+dirtball/S
+dirtily
+dirtiness/M
+dirty/DRSTGP
+dis/M
+disable/DSGL
+disablement/M
+disaggregation
+disambiguate/DGN
+disappointing/Y
+disarming/Y
+disassemble/R
+disastrous/Y
+disbandment/M
+disbarment/M
+disbelieving/Y
+disbursal/M
+disburse/LDSG
+disbursement/SM
+disc/M
+discern/LSDG
+discernible/I
+discernibly
+discerning/Y
+discernment/M
+discharged/U
+disciple/SM
+discipleship/M
+disciplinarian/MS
+disciplinary
+discipline/DSMG
+disciplined/U
+disclose/DSG
+disclosed/U
+disco/MG
+discography/SM
+discoloration/S
+discombobulate/DSGN
+discombobulation/M
+discomfit/GD
+discomfiture/M
+discommode/GD
+disconcerting/Y
+disconnected/PY
+disconnectedness/M
+disconsolate/YN
+discordance/M
+discordant/Y
+discotheque/MS
+discourage/LGDS
+discouragement/MS
+discouraging/Y
+discover/ASDG
+discoverable
+discovered/U
+discoverer/MS
+discovery/ASM
+discreet/PRYT
+discreetness/M
+discrepancy/SM
+discrepant
+discrete/YNP
+discreteness/M
+discretion/IM
+discretionary
+discriminant/S
+discriminate/DSGNV
+discriminated/U
+discriminating/U
+discrimination/M
+discriminator/MS
+discriminatory
+discursiveness/M
+discus/MS
+discuss/B
+discussant/MS
+discussed/A
+discussion/MS
+disdain/SMDG
+disdainful/Y
+disembowel/GLSD
+disembowelment/M
+disfigurement/MS
+disfranchisement/M
+disgorgement/M
+disgruntle/LDSG
+disgruntlement/M
+disguise/GD
+disgusted/Y
+disgusting/Y
+dish/MDSG
+dishabille/M
+disharmonious
+dishcloth/M
+dishcloths
+disheartening/Y
+dishevel/DGSL
+dishevelment/M
+dishpan/SM
+dishrag/SM
+dishtowel/MS
+dishware/M
+dishwasher/SM
+dishwater/M
+dishy
+disillusion/DGL
+disillusionment/M
+disinfectant/SM
+disinfection/M
+disinterestedness/M
+disinvest
+disjoint/P
+disjointed/PY
+disjointedness/M
+disjunction/S
+disjunctive
+disjuncture
+disk/MS
+diskette/MS
+dislike/DSMG
+dislodge/GDS
+dismal/RYT
+dismantlement/M
+dismay/SMDG
+dismayed/U
+dismember/LGD
+dismemberment/M
+dismissible
+dismissive/Y
+disorder/Y
+disorganization/M
+disparage/LDSG
+disparagement/M
+disparaging/Y
+disparate/Y
+dispatcher/MS
+dispel/S
+dispelled
+dispelling
+dispensary/SM
+dispensation/MS
+dispense/BZGDRS
+dispenser/M
+dispersal/M
+dispersant
+disperse/XZGNVDRS
+dispersion/M
+dispersive/Y
+dispirit/GDS
+dispirited/Y
+displace/R
+displayed/AU
+displeasure/M
+disposable/SM
+disposal/SM
+disposition/ISM
+dispossession/M
+disproof/SM
+disputable/I
+disputably/I
+disputant/MS
+disputation/MS
+disputatious/Y
+dispute/DRSMZGB
+disputed/U
+disputer/M
+disquiet/GSMD
+disquisition/SM
+disregardful
+disrepair/M
+disrepute/MB
+disrupt/GVSD
+disruption/SM
+disruptive/Y
+disruptor
+dissect/SDG
+dissed
+dissemblance/M
+dissemble/ZGDRS
+dissembler/M
+disseminate/DSGN
+dissemination/M
+dissension/MS
+dissent/SMDRZG
+dissenter/M
+dissertation/MS
+disses
+dissidence/M
+dissident/MS
+dissimilar
+dissimilitude/S
+dissing
+dissipate/GNVDS
+dissipated/U
+dissipation/M
+dissociate/GNVDS
+dissociation/M
+dissociative/Y
+dissoluble/I
+dissolute/YNP
+dissoluteness/M
+dissolve/AGDS
+dissolved/U
+dissonance/SM
+dissonant
+dissuade/GDS
+dissuasive
+dist
+distaff/SM
+distal/Y
+distance/DSMG
+distant/Y
+distaste/SM
+distention/MS
+distillate/SMNX
+distillation/M
+distillery/SM
+distinct/IYTVP
+distincter
+distinction/SM
+distinctive/PY
+distinctiveness/M
+distinctness/IM
+distinguish/GDSB
+distinguishable/I
+distinguishably/I
+distinguished/U
+distort/GDR
+distorted/U
+distortion/MS
+distracted/YP
+distracting/Y
+distraction/S
+distrait
+distraught
+distress/DG
+distressful
+distressing/Y
+distribute/AGNVDSB
+distributed/U
+distribution/AM
+distributional
+distributions
+distributive/Y
+distributivity
+distributor/SM
+distributorship/S
+district's
+district/AS
+disturb/ZGSDR
+disturbance/SM
+disturbed/U
+disturber/M
+disturbing/Y
+disulphide
+disunion/M
+disyllabic
+disyllable
+ditch/MDSG
+dither/SMDRZG
+ditherer/M
+ditransitive
+ditsy/RT
+ditto/SMDG
+ditty/SM
+ditz/MS
+diuresis
+diuretic/MS
+diurnal/Y
+div
+diva/MS
+divalent
+divan/SM
+dive/MZTGDRS
+diver/M
+diverge/DSG
+divergence/MS
+divergent
+diverse/XYNP
+diverseness/M
+diversification/M
+diversify/NGDS
+diversion/M
+diversionary
+diversity/SM
+divert/SDG
+diverticulitis/M
+divest/SLDG
+divestiture/SM
+divestment/M
+divide/DRSMZGB
+divided/U
+dividend/MS
+divider/M
+divination/M
+divine/DRSMYZTG
+diviner/M
+diving/M
+divinity/SM
+divisibility/IM
+divisible/I
+division/MS
+divisional
+divisive/PY
+divisiveness/M
+divisor/SM
+divorce/DSLMG
+divorcee/MS
+divorcement/SM
+divot/SM
+divulge/GDS
+divvy/DSMG
+dixieland/M
+dizzily
+dizziness/M
+dizzy/DRSPTG
+djellaba/MS
+do/SJRHZG
+doable
+dob/S
+dobbed
+dobbin/SM
+dobbing
+doberman/MS
+doc/SM
+docent/SM
+docile/Y
+docility/M
+dock/MDRZGS
+docket/SMDG
+dockland/S
+dockside
+dockworker/SM
+dockyard/MS
+doctor/SMDG
+doctoral
+doctorate/MS
+doctrinaire/MS
+doctrinal/Y
+doctrine/MS
+docudrama/SM
+document/GMDS
+documentary/SM
+documentation/SM
+documented/U
+dodder/SMDG
+doddery
+doddle
+dodecahedra
+dodecahedral
+dodecahedron
+dodge/DRSMZG
+dodgem/S
+dodger/M
+dodgy/RT
+dodo/MS
+doe/SM
+doer/M
+does/AU
+doeskin/MS
+doesn't
+doff/DGS
+dog/SM
+dogcart/SM
+dogcatcher/SM
+doge/MS
+dogeared
+dogfight/SM
+dogfish/MS
+dogged/PY
+doggedness/M
+doggerel/M
+dogging
+doggone/TGRS
+doggy/RSMT
+doghouse/SM
+dogie/SM
+dogleg/SM
+doglegged
+doglegging
+dogma/SM
+dogmatic
+dogmatically
+dogmatism/M
+dogmatist/SM
+dogsbody/S
+dogsled/S
+dogtrot/MS
+dogtrotted
+dogtrotting
+dogwood/MS
+doily/SM
+doing/USM
+doldrums/M
+dole's
+dole/FGDS
+doleful/YP
+dolefuller
+dolefullest
+dolefulness/M
+dolerite
+doll/MDGS
+dollar/SM
+dollhouse/SM
+dollop/SGMD
+dolly/SM
+dolmen/SM
+dolomite/M
+dolor/M
+dolorous/Y
+dolphin/MS
+dolt/MS
+doltish/YP
+doltishness/M
+domain/SM
+dome/MGDS
+domestic/SM
+domestically
+domesticate/GNDS
+domesticated/U
+domestication/M
+domesticity/M
+domicile/DSMG
+domiciliary
+dominance/M
+dominant/SMY
+dominate/DSGN
+domination/M
+dominatrices
+dominatrix/M
+domineer/SGD
+domineering/Y
+dominion/SM
+domino/M
+dominoes
+don't
+don/SM
+dona/MS
+donate/DSXGN
+donation/M
+done/AU
+dong/MDGS
+dongle/SM
+donkey/SM
+donned
+donning
+donnish
+donnybrook/SM
+donor/SM
+donuts/S
+doodad/SM
+doodah
+doodahs
+doodle/DRSMZG
+doodlebug/SM
+doodler/M
+doohickey/SM
+doolally
+doom/MDGS
+doomsayer/MS
+doomsday/M
+doomster/S
+door's
+door/IS
+doorbell/MS
+doorhandles
+doorjamb/S
+doorkeeper/MS
+doorknob/MS
+doorknocker/S
+doorman/M
+doormat/SM
+doormen
+doornail
+doorplate/SM
+doorpost/S
+doorstep/MS
+doorstepped
+doorstepping
+doorstop/MS
+doorway/SM
+dooryard/MS
+dopa/M
+dopamine
+dope/MZGDRS
+doper/M
+dopey
+dopier
+dopiest
+dopiness/M
+doping/M
+doppelganger/S
+dork/MS
+dorky/RT
+dorm/MRZS
+dormancy/M
+dormant
+dormer/M
+dormice
+dormitory/SM
+dormouse/M
+dorsal/Y
+dory/SM
+dosage/SM
+dose/MGDS
+dosh
+dosimeter/SM
+doss/DRZG
+dosshouse/S
+dossier/MS
+dost
+dot/ZGSMDR
+dotage/M
+dotard/SM
+dote/S
+doter/M
+doting/Y
+dotted
+dotting
+dotty/RPT
+double's
+double/ADSG
+doubleheader/MS
+doubler
+doublespeak/M
+doublet/MS
+doublethink
+doubloon/SM
+doubly
+doubt/SMDRZG
+doubter/M
+doubtful/YP
+doubtfulness/M
+doubting/Y
+doubtless/Y
+douche/DSMG
+dough/M
+doughnut/SM
+doughs
+doughty/RT
+doughy/TR
+dour/RYTP
+dourness/M
+douse/DSG
+dove/MS
+dovecot/S
+dovecote/SM
+dovetail/MDSG
+dovish
+dowager/MS
+dowdily
+dowdiness/M
+dowdy/RSPT
+dowel/SMDG
+dower/SMDG
+down/MDRZGS
+downbeat/SM
+downcast
+downdraft/MS
+downer/M
+downfall/SMN
+downgrade/DSMG
+downhearted/YP
+downheartedness/M
+downhill/MS
+downland/S
+download/MDSG
+downmarket
+downpipes
+downplay/DSG
+downpour/MS
+downrange
+downright
+downriver
+downscale
+downshift/SGD
+downside/MS
+downsize/GDS
+downsizing/M
+downspout/MS
+downstage
+downstairs/M
+downstate/M
+downstream
+downswing/MS
+downtime/M
+downtown/M
+downtrend/MS
+downtrodden
+downturn/MS
+downward/YS
+downwind
+downy/RT
+dowry/SM
+dowse/DRSZG
+dowser/M
+doxology/SM
+doyen/SM
+doyenne/MS
+doz/XGDNS
+doze/M
+dozen/MH
+dozily
+dozy/RTP
+dpt
+drab/MYSP
+drabber
+drabbest
+drabness/M
+drachma/MS
+draconian
+draft's
+draft/ASDG
+draftboard
+draftee/SM
+drafter/SM
+draftily
+draftiness/M
+drafting/M
+draftsman/M
+draftsmanship/M
+draftsmen
+draftswoman/M
+draftswomen
+drafty/RTP
+drag/MS
+dragged
+dragging
+draggy/TR
+dragnet/SM
+dragon/SM
+dragonfly/SM
+dragoon/SMDG
+dragster/S
+drain/SMDRZG
+drainage/M
+drainboard/MS
+drainer/M
+drainpipe/MS
+drake/SM
+dram/MS
+drama/SM
+dramatic/S
+dramatically
+dramatics/M
+dramatist/SM
+dramatization/MS
+dramatize/DSG
+drank
+drape/DRSMZG
+draper/M
+drapery/SM
+drastic
+drastically
+drat
+dratted
+draughtboards
+draughtswoman
+draughtswomen
+draw/MRZGSBJ
+drawback/MS
+drawbridge/MS
+drawcord
+drawer/M
+drawing/M
+drawl/SMDG
+drawn/AI
+drawstring/MS
+dray/MS
+dread/SMDG
+dreadful/PY
+dreadfulness/M
+dreadlocks/M
+dreadnought/MS
+dream/SMDRZG
+dreamboat/MS
+dreamed/U
+dreamer/M
+dreamily
+dreaminess/M
+dreamland/M
+dreamless
+dreamlike
+dreamworld/MS
+dreamy/RPT
+drear
+drearily
+dreariness/M
+dreary/RPT
+dredge/DRSMZG
+dredger/M
+dregs/M
+drench/GDS
+dress/AUGSDM
+dressage/M
+dresser/MS
+dressiness/M
+dressing/SM
+dressmaker/SM
+dressmaking/M
+dressy/TPR
+drew/A
+dribble/MZGDRS
+dribbler/M
+driblet/MS
+drier/M
+drift/SMDRZG
+drifter/M
+driftnet/S
+driftwood/M
+drill/SMDRZG
+driller/M
+drillmaster/MS
+drink/SMRBJZG
+drinkable/U
+drinker/M
+drip/MS
+dripped
+dripping/SM
+drippy/TR
+drive/RSMZGBJ
+drivel/SZGMDR
+driveler/M
+driven
+driver/M
+driveway/MS
+drizzle/MGDS
+drizzly/TR
+drogue/SM
+droid/S
+droll/RPT
+drollery/SM
+drollness/M
+drolly
+dromedary/SM
+drone/DSMG
+drool/SMDG
+droop/GSMD
+droopiness/M
+drooping/Y
+droopy/TPR
+drop/MS
+dropkick/MS
+droplet/SM
+dropout/SM
+dropped
+dropper/SM
+dropping/S
+droppings/M
+dropsical
+dropsy/M
+dross/M
+drought/SM
+drove/RSMZG
+drover/M
+drown/GSJD
+drowning/M
+drowse/MGDS
+drowsily
+drowsiness/M
+drowsy/RTP
+drub/S
+drubbed
+drubber/SM
+drubbing/MS
+drudge/MGDS
+drudgery/M
+drug/MS
+drugged
+druggie/SM
+drugging
+druggist/SM
+drugstore/MS
+druid/SM
+druidism/M
+drum/MS
+drumbeat/SM
+drumlin/SM
+drummed
+drummer/SM
+drumming
+drumstick/SM
+drunk/STMNR
+drunkard/MS
+drunken/PY
+drunkenness/M
+drupe/SM
+druthers/M
+dry/ZTGDRSMY
+dryad/SM
+dryer/SM
+dryish
+dryness/M
+drys
+drystone
+drywall/M
+dual/YS
+dualism/M
+dualist
+dualistic
+duality/SM
+dub/SM
+dubbed
+dubber/SM
+dubbin/M
+dubbing
+dubiety/M
+dubious/YP
+dubiousness/M
+ducal
+ducat/SM
+duchess/MS
+duchy/SM
+duck/JMDGS
+duckbill/SM
+duckboards
+duckling/SM
+duckpins/M
+duckpond
+duckweed/M
+ducky/TRSM
+duct's
+duct/CIFDG
+ductile
+ductility/M
+ductless
+ducts/IKC
+dud/GSMD
+dude/MS
+dudgeon/M
+due/SM
+duel/MDRJZGS
+dueler/M
+duelist/SM
+duenna/MS
+duet/MS
+duff/MDRZGS
+duffel
+duffer/M
+dug
+dugout/MS
+duh
+duke/MS
+dukedom/SM
+dulcet
+dulcimer/MS
+dull/DRPTGS
+dullard/SM
+dullness/M
+dully
+duly/U
+dumb/RYPT
+dumbbell/SM
+dumbfound/SDG
+dumbness/M
+dumbo/S
+dumbstruck
+dumbwaiter/SM
+dumdum/MS
+dummy/SM
+dump/MDRZGS
+dumpiness/M
+dumpling/SM
+dumpster/SM
+dumpy/PTR
+dun/SM
+dunce/SM
+dunderhead/SM
+dune/MS
+dung/MDGS
+dungaree/MS
+dungeon/SM
+dunghill/MS
+dunk/MDGS
+dunned
+dunner
+dunnest
+dunning
+dunno
+duo/SM
+duodecimal
+duodena
+duodenal
+duodenum/M
+duologue
+duopoly/S
+dupe/MZGDRS
+duper/M
+duple
+duplex/MS
+duplicability
+duplicate's
+duplicate/AGNDS
+duplication/AM
+duplications
+duplicator/MS
+duplicitous
+duplicity/SM
+durability/M
+durable/S
+durably
+durance/M
+duration/MS
+duress/M
+during
+durst
+durum/M
+dusk/M
+duskiness/M
+dusky/RTP
+dust/MDRZGS
+dustbin/SM
+dustcart/S
+dustcover
+duster/M
+dustily
+dustiness/M
+dustless
+dustman
+dustmen
+dustpan/SM
+dustsheet/S
+dusty/RTP
+dutch
+duteous/Y
+dutiable
+dutiful/YP
+dutifulness/M
+duty/SM
+duvet/SM
+dwarf/STGMDR
+dwarfish
+dwarfism/M
+dweeb/SM
+dwell/SJZGR
+dweller/M
+dwelling/M
+dwelt/I
+dwindle/DSG
+dyad
+dyadic
+dybbuk/SM
+dybbukim
+dye's
+dye/ADSG
+dyeing/A
+dyer/MS
+dyestuff/SM
+dying's
+dying/U
+dynamic/MS
+dynamical/Y
+dynamics/M
+dynamism/M
+dynamite/MZGDRS
+dynamiter/M
+dynamo/SM
+dynastic
+dynasty/SM
+dyne
+dysentery/M
+dysfunction/SM
+dysfunctional
+dyslectic/SM
+dyslexia/M
+dyslexic/SM
+dyslexically
+dyspepsia/M
+dyspeptic/MS
+dysprosium/M
+dystrophy
+dz
+e'en
+e'er
+e/FDST
+eBay/M
+ea
+each
+eager/PTRY
+eagerness/M
+eagle/MS
+eaglet/MS
+ear/SMDY
+earache/SM
+eardrum/SM
+earful/SM
+earl/MS
+earldom/SM
+earliness/M
+earlobe/SM
+early/RTP
+earmark/SMDG
+earmuff/SM
+earn/DRZTGJS
+earned/U
+earner/M
+earnest/SMYP
+earnestness/M
+earnings/M
+earphone/MS
+earpiece/S
+earplug/SM
+earring/SM
+earshot/M
+earsplitting
+earth's
+earth/UDYG
+earthbound
+earthen
+earthenware/M
+earthiness/M
+earthling/MS
+earthly/RT
+earthquake/SM
+earths/U
+earthshaking
+earthward/S
+earthwork/MS
+earthworm/MS
+earthy/RTP
+earwax/M
+earwig/SM
+ease/EDSM
+easel/SM
+easement/SM
+easily/U
+easiness/UM
+easing
+east/MG
+eastbound
+easterly/SM
+eastern/ZR
+easterner/M
+easternmost
+eastward/S
+easy/URTP
+easygoing
+eat/ZGBSNR
+eatable/SM
+eaten/U
+eater/M
+eatery/SM
+eave/MS
+eavesdrop/S
+eavesdropped
+eavesdropper/MS
+eavesdropping
+ebb/SMDG
+ebony/SM
+ebullience/M
+ebullient/Y
+ebullition/M
+eccentric/SM
+eccentrically
+eccentricity/SM
+eccl
+ecclesiastic/SM
+ecclesiastical/Y
+echelon/SM
+echinoderm/SM
+echo's
+echo/ADG
+echoes/A
+echoic
+echolocation/M
+echos
+eclair/SM
+eclat/M
+eclectic/SM
+eclectically
+eclecticism/M
+eclipse/DSMG
+ecliptic/M
+eclogue/SM
+ecocide/M
+ecol
+ecologic
+ecological/Y
+ecologist/MS
+ecology/M
+econ
+econometric/S
+economic/S
+economical/UY
+economics/M
+economist/SM
+economization
+economize/DRSZG
+economizer/M
+economy/SM
+ecosystem/MS
+ecru/M
+ecstasy/SM
+ecstatic
+ecstatically
+ectopic
+ectoplasm
+ecu/S
+ecumenical/Y
+ecumenicism/M
+ecumenism/M
+eczema/M
+ed/ACSM
+eddy/DSMG
+edelweiss/M
+edema/SM
+edge/MZGJDRS
+edgeless
+edger/M
+edgewise
+edgily
+edginess/M
+edging/M
+edgy/RTP
+edibility/M
+edible/SMP
+edibleness/M
+edict/SM
+edification/M
+edifice/SM
+edifier/M
+edify/DRSZGN
+edifying/U
+edit's
+edit/ADGS
+editable
+edited/U
+edition/MS
+editor/SM
+editorial/SMY
+editorialize/GDS
+editorship/MS
+educ
+educability/M
+educable/I
+educate/ADSGNV
+educated/U
+education/AM
+educational/Y
+educationalist/S
+educationist/S
+educations
+educator/MS
+educe/DSGB
+eduction
+edutainment/M
+eek
+eel/SM
+eerie/RT
+eerily
+eeriness/M
+eff/GSD
+efface/DSLG
+effacement/M
+effect/SMDGV
+effective/IYP
+effectiveness/IM
+effector/S
+effectual/IY
+effectuate/GDS
+effeminacy/M
+effeminate/Y
+effendi/SM
+efferent
+effervesce/GDS
+effervescence/M
+effervescent/Y
+effete/YP
+effeteness/M
+efficacious/Y
+efficacy/IM
+efficiency/ISM
+efficient/IY
+effigy/SM
+efflorescence/M
+efflorescent
+effluence/M
+effluent/MS
+effluvia
+effluvium/M
+effort/SM
+effortless/PY
+effortlessness/M
+effrontery/M
+effulgence/M
+effulgent
+effuse/DSGNVX
+effusion/M
+effusive/YP
+effusiveness/M
+egad
+egalitarian/SM
+egalitarianism/M
+egg/GSMD
+eggbeater/MS
+eggcup/SM
+egghead/SM
+eggnog/M
+eggplant/MS
+eggshell/SM
+eglantine/SM
+ego/SM
+egocentric/MS
+egocentrically
+egocentricity/M
+egoism/M
+egoist/SM
+egoistic
+egoistical/Y
+egomania/M
+egomaniac/MS
+egotism/M
+egotist/SM
+egotistic
+egotistical/Y
+egregious/PY
+egregiousness/M
+egress/MS
+egret/SM
+eh
+eider/SM
+eiderdown/MS
+eidetic
+eigenfunction/S
+eigenstate/S
+eigenvalue/S
+eight/SM
+eighteen/MHS
+eighteenth/M
+eighteenths
+eightfold
+eighth/M
+eighths
+eightieth/M
+eightieths
+eightpence
+eighty/SMH
+einsteinium/M
+eisteddfod/S
+either
+ejaculate/GNXDS
+ejaculation/M
+ejaculatory
+eject/SDG
+ejecta
+ejection/MS
+ejector/SM
+eke/DSG
+elaborate/PYGNDSX
+elaborateness/M
+elaboration/M
+elan/M
+eland/SM
+elapse/DSG
+elastic/MS
+elastically
+elasticated
+elasticity/SM
+elasticize/DSG
+elastodynamics
+elate/DSGN
+elated/Y
+elation/M
+elbow/SMDG
+elbowroom/M
+elder/SMY
+elderberry/SM
+elderflower
+eldest
+elect's
+elect/ASDGV
+electability
+electable/U
+elected/U
+election/AMS
+electioneer/DSG
+elective/MS
+elector/MS
+electoral/Y
+electorate/MS
+electric/S
+electrical/Y
+electrician/MS
+electricity/M
+electrification/M
+electrifier/M
+electrify/NZGDRS
+electrocardiogram/SM
+electrocardiograph/M
+electrocardiographs
+electrocardiography/M
+electrochemical/Y
+electrocute/GNDSX
+electrocution/M
+electrode/SM
+electrodynamic/S
+electroencephalogram/MS
+electroencephalograph/M
+electroencephalographic
+electroencephalographs
+electroencephalography/M
+electrologist/SM
+electroluminescent
+electrolysis/M
+electrolyte/MS
+electrolytic
+electrolytically
+electrolyze/GD
+electromagnet/MS
+electromagnetic
+electromagnetically
+electromagnetism/M
+electromechanical
+electromechanics
+electromotive
+electron/MS
+electronegative
+electronic/S
+electronically
+electronics/M
+electrophoresis
+electroplate/DSG
+electroscope/SM
+electroscopic
+electroshock/M
+electrostatic/S
+electrostatics/M
+electrotype/MS
+eleemosynary
+elegance/IM
+elegant/IY
+elegiac/MS
+elegiacal
+elegy/SM
+elem
+element/MS
+elemental/Y
+elementarily
+elementary
+elephant/SM
+elephantiasis/M
+elephantine
+elev
+elevate/XDSGN
+elevation/M
+elevator/MS
+eleven/SMH
+elevens/S
+eleventh/M
+elevenths
+elf/M
+elfin
+elfish
+elicit/SDG
+elicitation/M
+elide/DSG
+eligibility/IM
+eligible
+eligibly/I
+eliminate/DSXGN
+elimination/M
+eliminator/S
+elision/MS
+elite/SM
+elitism/M
+elitist/MS
+elixir/SM
+elk/SM
+ell/SM
+ellipse/MS
+ellipsis/M
+ellipsoid/SM
+ellipsoidal
+elliptic
+elliptical/Y
+elm/SM
+elocution/M
+elocutionary
+elocutionist/SM
+elodea/SM
+elongate/DSGNX
+elongation/M
+elope/DSGL
+elopement/MS
+eloquence/M
+eloquent/Y
+else
+elsewhere
+elucidate/XDSGN
+elucidation/M
+elude/DSG
+elusive/YP
+elusiveness/M
+eluted
+elven
+elver/SM
+elves
+elvish/S
+em's
+em/S
+emaciate/GNDS
+emaciation/M
+email/SMDG
+emanate/XDSGN
+emanation/M
+emancipate/GNDS
+emancipation/M
+emancipator/SM
+emancipatory
+emasculate/DSGN
+emasculation/M
+embalm/SZGDR
+embalmer/M
+embank/SLGD
+embankment/SM
+embargo/MDG
+embargoes
+embark/AEGDS
+embarkation/EM
+embarkations
+embarrass/LGDS
+embarrassed/U
+embarrassing/Y
+embarrassment/SM
+embassy/SM
+embattled
+embed/S
+embeddable
+embedded
+embedding/S
+embellish/LDSG
+embellishment/SM
+ember/SM
+embezzle/ZGLDRS
+embezzlement/M
+embezzler/M
+embitter/GDLS
+embitterment/M
+emblazon/GDLS
+emblazonment/M
+emblem/SM
+emblematic
+emblematically
+embodiment/EM
+embodiments
+embody/AEGSD
+embolden/DGS
+embolism/MS
+embosom
+emboss/DRSZG
+embosser/M
+embouchure/M
+embower/SGD
+embrace/DSMG
+embraceable
+embrasure/MS
+embrocation/MS
+embroider/SDRZG
+embroiderer/M
+embroidery/SM
+embroil/DGLS
+embroilment/M
+embryo/SM
+embryological
+embryologist/SM
+embryology/M
+embryonic
+emcee/DSM
+emceeing
+emend/SDG
+emendation/SM
+emerald/MS
+emerge/ADSG
+emergence/AM
+emergency/SM
+emergent
+emerita
+emeritus
+emery/M
+emetic/SM
+emf/S
+emigrant/SM
+emigrate/DSXGN
+emigration/M
+emigre/SM
+eminence/MS
+eminent/Y
+emir/MS
+emirate/MS
+emissary/SM
+emission/SM
+emissivity/S
+emit/S
+emitted
+emitter/MS
+emitting
+emollient/MS
+emolument/MS
+emote/XDSGNV
+emoticon/SM
+emotion/M
+emotional/UY
+emotionalism/M
+emotionality
+emotionalize/DSG
+emotionless
+emotive/Y
+empaneled
+empaneling
+empathetic
+empathetical
+empathic
+empathize/DSG
+empathy/M
+emperor/MS
+emphases
+emphasis/M
+emphasize/AGDS
+emphatic/U
+emphatically
+emphysema/M
+empire/SM
+empiric
+empirical/Y
+empiricism/M
+empiricist/SM
+emplacement/MS
+employ's
+employ/ADGLS
+employable/U
+employee/SM
+employer/SM
+employment/UAM
+employments
+emporium/SM
+empower/SDGL
+empowerment/M
+empress/MS
+emptily
+emptiness/M
+empty/TGPDRSM
+empyrean/M
+emu/SM
+emulate/DSGNVX
+emulation/M
+emulator/SM
+emulsification/M
+emulsifier/M
+emulsify/NDRSZG
+emulsion/MS
+en/SM
+enable/DRSZG
+enabler/M
+enact/ASLDG
+enactment/ASM
+enamel/JSZGMDR
+enameler/M
+enamelware/M
+enamor/SGD
+enc
+encamp/LSGD
+encampment/MS
+encapsulate/GNXDS
+encapsulation/M
+encase/LDSG
+encasement/M
+encephalitic
+encephalitis/M
+encephalopathy
+enchain/DGS
+enchant/ELDGS
+enchanter/MS
+enchanting/Y
+enchantment/EM
+enchantments
+enchantress/MS
+enchilada/SM
+encipher/SGD
+encircle/LDSG
+encirclement/SM
+encl
+enclave/MS
+enclose/GDS
+enclosed/U
+enclosure/SM
+encode/DRSZG
+encoder/M
+encomium/MS
+encompass/GDS
+encore/DSMG
+encounter/GSMD
+encourage/DRSGL
+encouragement/SM
+encouraging/Y
+encroach/GDSL
+encroachment/SM
+encrust/DGS
+encrustation/MS
+encrypt/DGS
+encrypted/U
+encryption
+encumber/EGSD
+encumbered/U
+encumbrance/SM
+ency
+encyclical/SM
+encyclopaedia
+encyclopedia/MS
+encyclopedic
+encyst/LSGD
+encystment/M
+end/GVSJMD
+endanger/SGDL
+endangerment/M
+endear/SGLD
+endearing/Y
+endearment/SM
+endeavor/GSMD
+endemic/MS
+endemically
+endgame/S
+ending/M
+endive/SM
+endless/PY
+endlessness/M
+endmost
+endocrine/MS
+endocrinologist/MS
+endocrinology/M
+endogenous/Y
+endomorphism/S
+endoplasmic
+endorphin/MS
+endorse/LZGDRS
+endorsement/SM
+endorser/M
+endoscope/MS
+endoscopic
+endoscopy/M
+endothermic
+endow/SDLG
+endowment/MS
+endpapers
+endpoint/SM
+endue/DSG
+endungeoned
+endurable/U
+endurance/M
+endure/DSBG
+endways
+enema/SM
+enemy/SM
+energetic/S
+energetically
+energize/ZGDRS
+energizer/M
+energy/SM
+enervate/GNDS
+enervation/M
+enfeeble/GDSL
+enfeeblement/M
+enfilade/DSMG
+enfold/SGD
+enforce/LZGDRS
+enforceability
+enforceable/U
+enforced/U
+enforcement/MS
+enforcer/M
+enfranchise/ELGDS
+enfranchisement/EM
+enfranchiser
+engage/EADSG
+engaged/U
+engagement/ESM
+engagingly
+engender/SGD
+engine/DSM
+engineer/MDGS
+engineering/M
+engorge/LGDS
+engorgement/M
+engram/SM
+engrave/ZGJDRS
+engraver/M
+engraving/M
+engross/GLDS
+engrossment/M
+engulf/SLGD
+engulfment/M
+enhance/LZGDRS
+enhanceable
+enhancement/SM
+enharmonic
+enigma/SM
+enigmatic
+enigmatically
+enjambment/SM
+enjoin/SGD
+enjoy/GBLSD
+enjoyability
+enjoyably
+enjoyment/SM
+enlarge/LZGDRS
+enlargeable
+enlargement/MS
+enlarger/M
+enlighten/LSGD
+enlightened/U
+enlightening/U
+enlightenment/M
+enlist/ADGSL
+enlistee/SM
+enlistment/AM
+enlistments
+enliven/SLDG
+enlivenment/M
+enmesh/DSGL
+enmeshment/M
+enmity/SM
+ennoble/DSGL
+ennoblement/M
+ennui/M
+enormity/SM
+enormous/YP
+enormousness/M
+enough/M
+enplane/DSG
+enquirer/S
+enquiringly
+enrage/GDS
+enrapture/DSG
+enrich/DSLG
+enrichment/M
+enrobed
+enroll/DLSG
+enrollment/MS
+ensconce/DSG
+ensemble/SM
+enshrine/GDSL
+enshrinement/M
+enshroud/DGS
+ensign/MS
+ensilage/M
+enslave/DSGL
+enslavement/M
+ensnare/DSLG
+ensnarement/M
+ensue/DSG
+ensure/ZGDRS
+ensurer/M
+entail/DSGL
+entailment/M
+entangle/EDSGL
+entanglement/EM
+entanglements
+entangler
+entente/SM
+enter/ASGD
+entered/U
+enteritis/M
+enterprise/SMG
+enterprising/Y
+entertain/DRSZGL
+entertainer/M
+entertaining/MY
+entertainment/MS
+enthalpy/S
+enthrall/GDSL
+enthrallment/M
+enthrone/LGDS
+enthronement/SM
+enthuse/DSG
+enthusiasm/MS
+enthusiast/MS
+enthusiastic/U
+enthusiastically/U
+entice/GDSL
+enticement/MS
+enticing/Y
+entire/Y
+entirety/M
+entitle/DSGL
+entitlement/SM
+entity/SM
+entomb/DSGL
+entombment/M
+entomological
+entomologist/SM
+entomology/M
+entourage/SM
+entr'acte
+entrails/M
+entrain/DL
+entrance/DSLMG
+entrancement/M
+entrancing/Y
+entrant/SM
+entrap/LS
+entrapment/M
+entrapped
+entrapping
+entreat/GSD
+entreating/Y
+entreaty/SM
+entree/MS
+entrench/DSGL
+entrenchment/MS
+entrepreneur/MS
+entrepreneurial
+entrepreneurship
+entropic
+entropy/M
+entrust/SGD
+entry/ASM
+entryphone/S
+entryway/MS
+entwine/DSG
+enumerable
+enumerate/DSGNX
+enumeration/M
+enumerator/SM
+enunciate/DSGN
+enunciation/M
+enuresis/M
+envelop/SLDRZG
+envelope/SM
+enveloper/M
+envelopment/M
+envenom/SDG
+enviable/U
+enviably
+envious/PY
+enviousness/M
+environ/SL
+environment/MS
+environmental/Y
+environmentalism/M
+environmentalist/MS
+environs/M
+envisage/GDS
+envision/DGS
+envoy/SM
+envy/DSMG
+envying/Y
+enzymatic
+enzyme/SM
+eolian
+eon/SM
+epaulet/SM
+epee/MS
+ephedrine/M
+ephemera/M
+ephemeral/Y
+ephemeris
+epic/MS
+epically
+epicenter/MS
+epicure/SM
+epicurean/MS
+epicycles
+epicycloid
+epidemic/SM
+epidemically
+epidemiological
+epidemiologist/MS
+epidemiology/M
+epidermal
+epidermic
+epidermis/MS
+epidural/S
+epiglottis/MS
+epigram/SM
+epigrammatic
+epigraph/M
+epigraphical
+epigraphs
+epigraphy/M
+epilepsy/M
+epileptic/SM
+epilogue/MS
+epinephrine/M
+epiphany/SM
+epiphenomena
+epiphenomenon
+episcopacy/M
+episcopal
+episcopalian
+episcopate/M
+episode/SM
+episodic
+episodically
+epistemic
+epistemological
+epistemology
+epistle/SM
+epistolary
+epitaph/M
+epitaphs
+epitaxial
+epitaxy
+epithelial
+epithelium/M
+epithet/SM
+epithetic
+epitome/SM
+epitomize/GDS
+epoch/M
+epochal
+epochs
+eponymous
+epoxy/DSMG
+epsilon/SM
+equability/M
+equable
+equably
+equal/SMDYG
+equality/ISM
+equalization/M
+equalize/ZGDRS
+equalizer/M
+equanimity/M
+equate/DSGNBX
+equation/M
+equator/SM
+equatorial
+equerry/SM
+equestrian/SM
+equestrianism/M
+equestrienne/SM
+equiangular
+equidistant/Y
+equilateral/MS
+equilibrating
+equilibration
+equilibrium/EM
+equine/SM
+equinoctial
+equinox/MS
+equip/AS
+equipage/MS
+equipartition
+equipment/MS
+equipoise/M
+equipped/UA
+equipping/A
+equitable/I
+equitably/I
+equitation/M
+equity/ISM
+equiv
+equivalence/SM
+equivalency/SM
+equivalent/MYS
+equivocal/UY
+equivocalness/M
+equivocate/XGNDS
+equivocation/M
+equivocator/MS
+er
+era/SM
+eradicable/I
+eradicate/DSGN
+eradication/M
+eradicator/MS
+erase/DRSBZG
+eraser/M
+erasure/SM
+erbium/M
+ere
+erect/PSGDY
+erectile
+erection/SM
+erectness/M
+erector/MS
+erelong
+eremite/MS
+erg/SM
+ergo
+ergodic
+ergonomic/S
+ergonomically
+ergonomics/M
+ergophobia
+ergosterol/M
+ergot/M
+ermine/SM
+erode/DSG
+erodible
+erogenous
+erosion/M
+erosional
+erosive
+erotic/S
+erotica/M
+erotically
+eroticism/M
+erotics/S
+err/GSD
+errand/SM
+errant/I
+errata/SM
+erratic
+erratically
+erratum/M
+erroneous/Y
+error/SM
+ersatz/MS
+erst
+erstwhile
+eruct/SDG
+eructation/SM
+erudite/YN
+erudition/M
+erupt/SDGV
+eruption/MS
+erysipelas/M
+erythrocyte/MS
+escalate/CDSGN
+escalation/CM
+escalations
+escalator/MS
+escallop/SGMD
+escalope/S
+escapade/MS
+escape/LMGDS
+escapee/MS
+escapement/MS
+escapism/M
+escapist/MS
+escapologist/S
+escapology
+escargot/MS
+escarole/MS
+escarpment/SM
+eschatology
+eschew/SDG
+escort/SMDG
+escorted/U
+escritoire/MS
+escrow/SM
+escudo/SM
+escutcheon/MS
+esophageal
+esophagi
+esophagus/M
+esoteric
+esoterica
+esoterically
+esp
+espadrille/SM
+espalier/MDSG
+especial/Y
+espionage/M
+esplanade/MS
+espousal/M
+espouse/GDS
+espresso/MS
+esprit/M
+espy/DSG
+esquire/SM
+essay/SMDRZG
+essayer/M
+essayist/SM
+essence/SM
+essential/IMS
+essentialist
+essentially
+establish/EASDGL
+established/U
+establishment/AEM
+establishments
+estate/SM
+esteem/ESMDG
+ester/SM
+esthete's
+esthetically
+estimable/I
+estimate/MGNDSX
+estimation/M
+estimator/SM
+estrange/LDSG
+estrangement/SM
+estrogen/M
+estrous
+estrus/MS
+estuarine
+estuary/SM
+eta/SM
+etc
+etch/DRSZGJ
+etcher/M
+etching/M
+eternal/YP
+eternalness/M
+eternity/SM
+ethane/M
+ethanol/M
+ether/M
+ethereal/Y
+etherized
+ethic/SM
+ethical/UY
+ethicist
+ethics/M
+ethnic/SM
+ethnically
+ethnicity/M
+ethnocentric
+ethnocentrism/M
+ethnographer/S
+ethnographic
+ethnographically
+ethnography
+ethnological/Y
+ethnologist/MS
+ethnology/M
+ethological
+ethologist/MS
+ethology/M
+ethos/M
+ethyl/M
+ethylene/M
+etiolated
+etiologic
+etiological
+etiology/SM
+etiquette/M
+etude/SM
+etymological/Y
+etymologist/SM
+etymology/SM
+eucalypti
+eucalyptus/MS
+euchre/DSMG
+euclidean
+eugenic/S
+eugenically
+eugenicist/MS
+eugenics/M
+eukaryote
+eulogist/MS
+eulogistic
+eulogize/ZGDRS
+eulogizer/M
+eulogy/SM
+eunuch/M
+eunuchs
+euphemism/SM
+euphemistic
+euphemistically
+euphonious/Y
+euphonium/S
+euphony/M
+euphoria/M
+euphoric
+euphorically
+eureka
+euro/MS
+europium/M
+eutectic
+euthanasia/M
+euthanize
+euthenics/M
+evacuate/XDSGN
+evacuation/M
+evacuee/MS
+evade/DRSZGB
+evader/M
+evaluable
+evaluate/AGNVDSX
+evaluated/U
+evaluation/AM
+evaluational
+evaluator/S
+evanescence/M
+evanescent
+evangelic
+evangelical/SMY
+evangelicalism/M
+evangelism/M
+evangelist/MS
+evangelistic
+evangelize/GDS
+evaporate/GNDS
+evaporation/M
+evaporator/SM
+evasion/SM
+evasive/YP
+evasiveness/M
+eve/ASM
+even/MDRYTGSJP
+evenhanded/Y
+evening/M
+evenness/UM
+evensong/M
+event/SMG
+eventful/UY
+eventfulness/M
+eventide/M
+eventual/Y
+eventuality/SM
+eventuate/GDS
+ever
+everglade/SM
+evergreen/SM
+everlasting/SMY
+everliving
+evermore
+every
+everybody/M
+everyday
+everyman
+everyone/M
+everyplace
+everything/M
+everywhere
+evict/SDG
+eviction/MS
+evidence/MGDS
+evident/Y
+evidential
+evil/MRYTSP
+evildoer/SM
+evildoing/M
+eviller
+evillest
+evilness/M
+evince/DSG
+eviscerate/DSGN
+evisceration/M
+evocation/MS
+evocative/Y
+evoke/DSG
+evolute/NX
+evolution/M
+evolutionarily
+evolutionary
+evolutionism
+evolutionist/MS
+evolve/DSG
+ewe/RSMZ
+ewer/M
+ex/MS
+exacerbate/GNDS
+exacerbation/M
+exact/SPDRYTG
+exacting/Y
+exaction/M
+exactitude/M
+exactness/IM
+exaggerate/DSGNX
+exaggerated/Y
+exaggeration/M
+exaggerator/SM
+exalt/SDG
+exaltation/M
+exam/MS
+examinable
+examination/AMS
+examine/AGDS
+examined/U
+examinees
+examiner/MS
+example/MGDS
+exampled/U
+exasperate/DSGN
+exasperated/Y
+exasperating/Y
+exasperation/M
+excavate/GNDSX
+excavation/M
+excavator/SM
+exceed/GSD
+exceeding/Y
+excel/S
+excelled
+excellence/M
+excellency/SM
+excellent/Y
+excelling
+excelsior/M
+except/GSD
+exception/SMB
+exceptionable/U
+exceptional/UY
+excerpt/MDGS
+excess/VMS
+excessive/Y
+exchange/DRSMZG
+exchangeable
+exchequer/SM
+excise/XDSMGN
+excision/M
+excitability/M
+excitably
+excitation/SM
+excite/BDRSLZG
+excited/Y
+excitement/SM
+exciter/M
+exciting/Y
+exciton
+excl/S
+exclaim/DGS
+exclamation/MS
+exclamatory
+exclude/GDS
+exclusion/MS
+exclusionary
+exclusive/MYPS
+exclusiveness/M
+exclusivity/M
+excommunicate/GNXDS
+excommunication/M
+excoriate/DSXGN
+excoriation/M
+excrement/M
+excremental
+excrescence/MS
+excrescent
+excreta/M
+excrete/XGNDS
+excretion/M
+excretory
+excruciating/Y
+excruciation
+exculpate/DSGN
+exculpation/M
+exculpatory
+excursion/MS
+excursionist/SM
+excursive/YP
+excursiveness/M
+excusable/I
+excusably/I
+excuse/DSBMG
+excused/U
+exec/MS
+execked
+execking
+execrable
+execrably
+execrate/DSGN
+execration/M
+execute/BXGNVDS
+execution/MRZ
+executioner/M
+executive/SM
+executor/MS
+executrices
+executrix/M
+exegeses
+exegesis/M
+exegetic
+exegetical
+exemplar/SM
+exemplary
+exemplification/M
+exemplify/XGDSN
+exempt/SGD
+exemption/SM
+exercise/DRSBMZG
+exerciser/M
+exert/SDG
+exertion/MS
+exeunt
+exfoliate/GNDS
+exhalation/MS
+exhale/DSG
+exhaust/GVMDS
+exhaustible/I
+exhaustion/M
+exhaustive/YP
+exhaustiveness/M
+exhibit/GMDS
+exhibition/ZMRS
+exhibitionism/M
+exhibitionist/MS
+exhibitor/SM
+exhilarate/GNDS
+exhilaration/M
+exhort/SDG
+exhortation/SM
+exhumation/MS
+exhume/DSG
+exigence/MS
+exigency/SM
+exigent
+exiguity/M
+exiguous
+exile/DSMG
+exist/SDG
+existence/MS
+existent
+existential/Y
+existentialism/M
+existentialist/SM
+existentialistic
+exit/MDGS
+exobiology/M
+exocrine
+exodus/MS
+exogenous
+exonerate/GNDS
+exoneration/M
+exorbitance/M
+exorbitant/Y
+exorcise/DSG
+exorcism/SM
+exorcist/SM
+exoskeleton/MS
+exosphere/SM
+exothermic
+exothermically
+exotic/SM
+exotica
+exotically
+exoticism/M
+exp
+expand/BGSDR
+expandability
+expanded/U
+expanse/XMNVS
+expansible
+expansion/M
+expansionary
+expansionism/M
+expansionist/MS
+expansive/PY
+expansiveness/M
+expat/S
+expatiate/GNDS
+expatiation/M
+expatriate/MGNDS
+expatriation/M
+expect/GSD
+expectancy/SM
+expectant/Y
+expectation/MS
+expectational
+expectorant/MS
+expectorate/GNDS
+expectoration/M
+expedience/IM
+expediences
+expediencies
+expediency/IM
+expedient/SMY
+expedite/DRSZGNX
+expediter/M
+expedition/M
+expeditionary
+expeditious/YP
+expeditiousness/M
+expel/S
+expelled
+expelling
+expend/GSBD
+expendable/SM
+expenditure/MS
+expense/MS
+expensive/IPY
+expensiveness/IM
+experience/IDM
+experiences
+experiencing
+experiential
+experiment/ZGSMDR
+experimental/Y
+experimentalist/S
+experimentation/M
+experimenter/M
+expert/SPMY
+expertise/M
+expertize
+expertness/M
+expiate/GNDS
+expiation/M
+expiatory
+expiration/M
+expiratory
+expire/DSG
+expired/U
+expiry/M
+explain/ADGS
+explainable/U
+explained/U
+explanation/MS
+explanatory
+expletive/MS
+explicable/I
+explicate/XGNVDS
+explication/M
+explicit/PY
+explicitness/M
+explode/ZGDRS
+exploded/U
+exploit/ZGBMDRS
+exploitation/MS
+exploitative
+exploited/U
+exploiter/M
+exploration/MS
+exploratory
+explore/BZGDRS
+explored/U
+explorer/M
+explosion/SM
+explosive/SMYP
+explosiveness/M
+expo/MS
+exponent/MS
+exponential/Y
+exponentiation
+export/BSZGMDR
+exportability
+exportation/M
+exporter/M
+expose/DSMG
+exposed/U
+exposition/SM
+expositor/SM
+expository
+expostulate/GNXDS
+expostulation/M
+exposure/MS
+expound/ZGDRS
+expounder/M
+express/GVMDSY
+expressed/U
+expressible/I
+expression/MS
+expressionism/M
+expressionist/SM
+expressionistic
+expressionless/Y
+expressive/YP
+expressiveness/M
+expressway/MS
+expropriate/XGNDS
+expropriation/M
+expropriator/MS
+expulsion/MS
+expunge/GDS
+expurgate/XDSGN
+expurgated/U
+expurgation/M
+exquisite/YP
+exquisiteness/M
+ext
+extant
+extemporaneous/YP
+extemporaneousness/M
+extempore
+extemporization/M
+extemporize/GDS
+extend/SZGDR
+extendability
+extender/M
+extensibility
+extensible/I
+extension/SM
+extensional/Y
+extensive/YP
+extensiveness/M
+extensors
+extent/SM
+extenuate/DSGN
+extenuation/M
+exterior/MS
+exterminate/GNDSX
+extermination/M
+exterminator/SM
+external/MYS
+externalization/SM
+externalize/GDS
+extinct/GDS
+extinction/MS
+extinguish/BZGDRS
+extinguishable/I
+extinguisher/M
+extirpate/GNDS
+extirpation/M
+extol/S
+extolled
+extolling
+extort/SGD
+extortion/ZMR
+extortionate/Y
+extortioner/M
+extortionist/SM
+extra/SM
+extracellular
+extract/BMDGVS
+extraction/MS
+extractor/MS
+extracurricular
+extradite/GNDSBX
+extradition/M
+extragalactic
+extrajudicial
+extralegal
+extralinguistic
+extramarital
+extramural
+extraneous/Y
+extraordinaire
+extraordinarily
+extraordinary
+extrapolate/GNXDS
+extrapolation/M
+extrasensory
+extrasolar
+extraterrestrial/SM
+extraterritorial
+extraterritoriality/M
+extravagance/SM
+extravagant/Y
+extravaganza/SM
+extravehicular
+extrema
+extremal
+extreme/PMYTRS
+extremeness/M
+extremism/M
+extremist/MS
+extremity/SM
+extricable/I
+extricate/GNDS
+extrication/M
+extrinsic
+extrinsically
+extroversion/M
+extrovert/SMD
+extrude/GDS
+extrusion/SM
+extrusive
+exuberance/M
+exuberant/Y
+exudate/N
+exudation/M
+exude/DSG
+exult/SDG
+exultant/Y
+exultation/M
+exulting/Y
+exurb/SM
+exurban
+exurbanite/MS
+exurbia/M
+eye/DSMG
+eyeball/GMDS
+eyebrow/SM
+eyedropper/SM
+eyeful/SM
+eyeglass/MS
+eyelash/MS
+eyeless
+eyelet/SM
+eyelid/SM
+eyeliner/MS
+eyeopener/MS
+eyeopening
+eyepiece/MS
+eyeshadow
+eyesight/M
+eyesore/MS
+eyestrain/M
+eyeteeth
+eyetooth/M
+eyewash/M
+eyewitness/MS
+f/CIAVTR
+fa/M
+fab
+fable/DSM
+fabric/SM
+fabricate/DSXGN
+fabrication/M
+fabricator/MS
+fabulists
+fabulous/Y
+facade/SM
+face's
+face/ACSDG
+facecloth/M
+facecloths
+faceless
+faceplate
+facet/SMDG
+facetious/YP
+facetiousness/M
+facial/SMY
+facile/Y
+facilitate/GNVDS
+facilitation/M
+facilitator/SM
+facility/SM
+facing/SM
+facsimile/DSM
+facsimileing
+fact/MS
+faction/SM
+factional
+factionalism/M
+factious
+factitious
+factoid/SM
+factor/SMDG
+factorial/MS
+factorisable
+factorization/S
+factorize/GDS
+factory/SM
+factotum/SM
+factual/Y
+faculty/SM
+fad/GSMD
+faddish/P
+faddist/MS
+faddy/P
+fade/MS
+fadeout
+fading/U
+faerie/SM
+faff/DGS
+fag/SM
+fagged
+fagging
+fagot/SMG
+fagoting/M
+faience/M
+fail/MDGJS
+failing/M
+faille/M
+failure/SM
+fain/RT
+faint/SMDRYTGP
+fainthearted
+faintness/M
+fair/MRYTGJPS
+fairground/SM
+fairing/M
+fairings/S
+fairish
+fairness/UM
+fairway/SM
+fairy/SM
+fairyland/SM
+fairytale
+faith/M
+faithful's
+faithful/UPY
+faithfulness/UM
+faithfuls
+faithless/PY
+faithlessness/M
+faiths
+fajita/SM
+fajitas/M
+fake/MZGDRS
+faker/M
+fakir/SM
+falcon/SMRZ
+falconer/M
+falconry/M
+fall/MNRZGS
+fallacious/Y
+fallacy/SM
+fallback
+fallibility/IM
+fallible/P
+fallibleness/M
+fallibly/I
+falloff/SM
+fallopian
+fallout/M
+fallow/SMDG
+false/PRYT
+falsehood/SM
+falseness/M
+falsetto/SM
+falsie/SM
+falsifiability
+falsifiable/U
+falsification/M
+falsifier/M
+falsify/DRSZGXN
+falsity/SM
+falter/GSJMD
+faltering/Y
+fame's
+fame/D
+familial
+familiar/MYS
+familiarities
+familiarity/UM
+familiarization/M
+familiarize/GDS
+family/SM
+famine/SM
+famish/DSG
+famous/IY
+fan/SM
+fanatic/SM
+fanatical/Y
+fanaticism/M
+fanciable
+fancier/M
+fanciful/PY
+fancifulness/M
+fancily
+fanciness/M
+fancy/DRSMZTGP
+fancywork/M
+fandango/MS
+fanfare/SM
+fang/MDS
+fanlight/SM
+fanned
+fanning
+fanny/SM
+fantail/MS
+fantasia/SM
+fantasist/S
+fantasize/GDS
+fantastic
+fantastical/Y
+fantasy/DSMG
+fanzine/MS
+far
+farad/SM
+faradize/DSG
+faraway
+farce/SM
+farcical/Y
+fare/MGDS
+farewell/SM
+farina/M
+farinaceous
+farm/MDRZGSJ
+farmer/M
+farmhand/SM
+farmhouse/SM
+farming/M
+farmland/MS
+farmstead/MS
+farmyard/MS
+faro/M
+farrago/M
+farragoes
+farrier/MS
+farrow/SMDG
+farseeing
+farsighted/P
+farsightedness/M
+fart/MDGS
+farther
+farthermost
+farthest
+farthing/SM
+fascia/SM
+fascicle/SM
+fascinate/XGNDS
+fascinating/Y
+fascination/M
+fascism/M
+fascist/MS
+fascistic
+fashion/ZGBMDRS
+fashionable/U
+fashionably/U
+fashioner/M
+fast/MDRTGSP
+fastback/SM
+fastball/SM
+fasten/UAGDS
+fastener/SM
+fastening/MS
+fastidious/YP
+fastidiousness/M
+fastness/MS
+fat/GSPMD
+fatal/Y
+fatalism/M
+fatalist/SM
+fatalistic
+fatalistically
+fatality/SM
+fatback/M
+fate/MS
+fateful/YP
+fatefulness/M
+fathead/MDS
+fatheaded/P
+father/SGMDY
+fatherhood/M
+fatherland/MS
+fatherless
+fathom/SMDGB
+fathomable/U
+fathomed/U
+fathomless
+fatigue/MDSG
+fatigued/U
+fatigues/M
+fatness/M
+fatso/S
+fatted
+fatten/SDG
+fatter
+fattest
+fattiness/M
+fatty/RSMTP
+fatuity/M
+fatuous/YP
+fatuousness/M
+fatwa/SM
+faucet/SM
+fault/CSMDG
+faultfinder/MS
+faultfinding/M
+faultily
+faultiness/M
+faultless/YP
+faultlessness/M
+faulty/PRT
+faun/MS
+fauna/SM
+fauvism/M
+fauvist/SM
+fave/S
+favor/ESMDG
+favorable/U
+favorably/U
+favored/U
+favorite/SM
+favoritism/M
+fawn/MDRZGS
+fawner/M
+fawning/Y
+fax/GMDS
+fay/TSMR
+faze/GDS
+fazed/U
+fealty/M
+fear/MDGS
+fearful/YP
+fearfuller
+fearfullest
+fearfulness/M
+fearless/PY
+fearlessness/M
+fearsome/YP
+feasibility/M
+feasible/IU
+feasibly/U
+feast/SMDG
+feat/MS
+feather/SGMD
+featherbedding/M
+featherbrained
+featherless
+featherlight
+featherweight/MS
+feathery/TR
+feature/DSMG
+featureless
+febrile
+fecal
+feces/M
+feckless/PY
+fecund
+fecundate/GNDS
+fecundation/M
+fecundity/M
+fed/SM
+federal/SMY
+federalism/M
+federalist/MS
+federalization/M
+federalize/GDS
+federate/FXDSGN
+federation/FM
+fedora/SM
+fee/SM
+feeble/RTP
+feebleness/M
+feebly
+feed/MRZGSJ
+feedback/M
+feedbag/SM
+feeder/M
+feeding/M
+feedlot/SM
+feedstock
+feedstuffs
+feel/MRZGSJ
+feeler/M
+feelgood
+feeling/MY
+feet
+feign/SDG
+feigned/U
+feint/SMDG
+feisty/TR
+feldspar/M
+felicitate/XGNDS
+felicitation/M
+felicitous/Y
+felicity/ISM
+feline/SM
+fell/MDRZTGS
+fella/S
+fellatio/M
+fellow/SM
+fellowman/M
+fellowmen
+fellowship/SM
+felon/SM
+felonious
+felony/SM
+felt/MDGS
+fem
+female/PSM
+femaleness/M
+feminine/SMY
+femininity/M
+feminism/M
+feminist/SM
+feminize/DSG
+femoral
+femur/SM
+fen/SM
+fence/DRSMZG
+fenced/U
+fencepost
+fencer/M
+fencing/M
+fend/CDRZGS
+fender/CM
+fenestration/M
+fenland
+fennel/M
+feral
+ferment/FCMS
+fermentation/M
+fermented
+fermenting
+fermion/S
+fermium/M
+fern/MS
+ferny/RT
+ferocious/YP
+ferociousness/M
+ferocity/M
+ferret/GSMD
+ferric
+ferrite
+ferromagnetic
+ferrous
+ferrule/MS
+ferry/DSMG
+ferryboat/SM
+ferryman/M
+ferrymen
+fertile/I
+fertility/IM
+fertilization/M
+fertilize/DRSZG
+fertilized/U
+fertilizer/M
+ferule/SM
+fervency/M
+fervent/Y
+fervid/Y
+fervor/M
+fess/FKGSD
+fest/MRZVS
+festal
+fester/GMD
+festival/SM
+festive/YP
+festiveness/M
+festivity/SM
+festoon/GMDS
+feta/M
+fetal
+fetch/DRSZG
+fetcher/M
+fetching/Y
+fete/MGDS
+fetid/P
+fetidness/M
+fetish/MS
+fetishism/M
+fetishist/SM
+fetishistic
+fetlock/MS
+fetter's
+fetter/USGD
+fettle/M
+fettuccine/M
+fetus/MS
+feud/MDGS
+feudal
+feudalism/M
+feudalistic
+fever/SMD
+feverish/YP
+feverishness/M
+few/TPMR
+fewness/M
+fey
+fez/M
+fezzes
+ff
+fiance/CM
+fiancee/MS
+fiances
+fiasco/M
+fiascoes
+fiat/MS
+fib/ZSMR
+fibbed
+fibber/SM
+fibbing
+fiber/MD
+fiberboard/M
+fiberfill/M
+fiberglass/M
+fibril/SM
+fibrillate/GNDS
+fibrillation/M
+fibrin/M
+fibroblast/S
+fibroid
+fibrosis/M
+fibrous
+fibula/M
+fibulae
+fibular
+fices
+fiche/SM
+fichu/SM
+fickle/RPT
+fickleness/M
+fiction/MS
+fictional/Y
+fictionalization/MS
+fictionalize/GDS
+fictitious/Y
+fictive
+ficus/M
+fiddle/DRSJMZG
+fiddler/M
+fiddlesticks
+fiddly/TR
+fidelity/IM
+fidget/SGMD
+fidgety
+fiduciary/SM
+fie
+fief/MS
+fiefdom/MS
+field/ISMRZ
+fielded
+fielder/IM
+fielding
+fieldsman
+fieldsmen
+fieldwork/ZMR
+fieldworker/M
+fiend/SM
+fiendish/Y
+fierce/PRYT
+fierceness/M
+fierily
+fieriness/M
+fiery/RPT
+fiesta/SM
+fife/MZRS
+fifer/M
+fifteen/MHS
+fifteenth/M
+fifteenths
+fifth/MY
+fifths
+fiftieth/M
+fiftieths
+fifty/SMH
+fig/SLM
+fight/SMRZG
+fightback
+fighter/IMS
+fighting/IM
+figment/MS
+figural
+figuration/FM
+figurative/Y
+figure's
+figure/EFGSD
+figurehead/SM
+figurine/MS
+filament/MS
+filamentary
+filamentous
+filbert/MS
+filch/DSG
+file's/KC
+file/CAKGDS
+filer/CSM
+filial
+filibuster/ZGSMDR
+filibusterer/M
+filigree/DSM
+filigreeing
+filing's
+filings
+fill's
+fill/AIDGS
+filled/U
+filler/MS
+fillet/MDGS
+filling's
+filling/S
+fillip/MDGS
+filly/SM
+film/MDGS
+filminess/M
+filmmaker/SM
+filmstrip/MS
+filmy/TPR
+filo
+filter/MDRBSZG
+filtered/U
+filterer/M
+filth/M
+filthily
+filthiness/M
+filthy/RPT
+filtrate's
+filtrate/IGNDS
+filtration/IM
+fin/SMR
+finagle/DRSZG
+finagler/M
+final/SMY
+finale/MS
+finalist/SM
+finality/M
+finalization/M
+finalize/DSG
+finance's
+finance/ADSG
+financial/Y
+financier/MS
+financing/M
+finch/MS
+find/BJMRZGS
+finder/M
+finding/M
+findings/M
+fine's/F
+fine/CAFTGDS
+finely
+fineness/M
+finery/AM
+finespun
+finesse/DSMG
+finger/MDGSJ
+fingerboard/MS
+fingering/M
+fingerless
+fingerling/SM
+fingermark/S
+fingernail/SM
+fingerprint/MDSG
+fingertip/MS
+finial/MS
+finical
+finickiness/M
+finicky/RPT
+finis/MS
+finish's
+finish/ADSG
+finished/U
+finisher/MS
+finite/PY
+fink/MDGS
+finned
+finny/TR
+fir/ZGSJMDRH
+fire/MS
+firearm/SM
+fireball/MS
+firebomb/MDSJG
+firebox/MS
+firebrand/SM
+firebreak/SM
+firebrick/SM
+firebug/SM
+firecracker/SM
+fired/U
+firedamp/M
+firefight/MRSJZG
+firefighter/M
+firefighting/M
+firefly/SM
+fireguard/S
+firehouse/SM
+firelight/ZMR
+fireman/M
+firemen
+fireplace/SM
+fireplug/MS
+firepower/M
+fireproof/DSG
+firer/M
+firesafe
+firescreen/S
+fireside/MS
+firestorm/MS
+firetrap/MS
+firetruck/MS
+firewall/MS
+firewater/M
+firewood/M
+firework/SM
+firkin
+firm/MDRYPTGS
+firmament/SM
+firmness/M
+firmware/MS
+first/SMY
+firstborn/SM
+firsthand
+firth/M
+firths
+fiscal/MYS
+fish/MDRSZG
+fishbowl/SM
+fishcake/SM
+fisher/M
+fisherman/M
+fishermen
+fishery/SM
+fishhook/SM
+fishily
+fishiness/M
+fishing/M
+fishmonger/MS
+fishnet/SM
+fishpond/MS
+fishtail/DGS
+fishwife/M
+fishwives
+fishy/TRP
+fissile
+fission/BSM
+fissure/DSM
+fist/MS
+fistfight/MS
+fistful/SM
+fisticuffs/M
+fistula/SM
+fistulous/M
+fit/KAMS
+fitful/YP
+fitfulness/M
+fitly
+fitment/S
+fitness/UM
+fitted/UA
+fitter/MS
+fittest
+fitting/SMY
+five/MZRS
+fivefold
+fix/ZGBJMDRS
+fixate/GNVDSX
+fixation/M
+fixative/MS
+fixed/Y
+fixer/M
+fixings/M
+fixity/M
+fixture/MS
+fizz/MDSG
+fizzle/DSMG
+fizzy/RT
+fjord/SM
+fl/JDG
+flab/M
+flabbergast/GSD
+flabbily
+flabbiness/M
+flabby/RPT
+flaccid/Y
+flaccidity/M
+flack/SM
+flag/MS
+flagella
+flagellant/S
+flagellate/GNDS
+flagellation/M
+flagellum/M
+flagged
+flagging/U
+flagman/M
+flagmen
+flagon/MS
+flagpole/SM
+flagrance/M
+flagrancy/M
+flagrant/Y
+flagship/SM
+flagstaff/MS
+flagstone/MS
+flail/SGMD
+flair/SM
+flak/M
+flake/DSMG
+flakiness/M
+flaky/TRP
+flam
+flamage/S
+flambe/MS
+flambeed
+flambeing
+flamboyance/M
+flamboyancy/M
+flamboyant/Y
+flame/DRSJMZG
+flamenco/MS
+flameproof/DSG
+flamethrower/MS
+flamingo/MS
+flammability/IM
+flammable/SM
+flan/MS
+flange/MDS
+flank/SZGMDR
+flanker/M
+flannel/SGMD
+flannelet/M
+flap/MS
+flapjack/MS
+flapped
+flapper/SM
+flapping
+flare/DSMG
+flareup/SM
+flash/ZTGMDRS
+flashback/SM
+flashbulb/SM
+flashcard/SM
+flashcube/SM
+flasher/M
+flashgun/SM
+flashily
+flashiness/M
+flashing/M
+flashlight/MS
+flashy/RTP
+flask/SM
+flat/MYPS
+flatbed/SM
+flatboat/SM
+flatcar/SM
+flatfeet
+flatfish/MS
+flatfoot/SMD
+flatiron/SM
+flatland/M
+flatlet/S
+flatmate/S
+flatness/M
+flatted
+flatten/SDG
+flatter/SDRZG
+flatterer/M
+flattering/Y
+flattery/M
+flattest
+flatting
+flattish
+flattop/SM
+flatulence/M
+flatulent
+flatus/M
+flatware/M
+flatworm/SM
+flaunt/MDSG
+flaunting/Y
+flautist/SM
+flavor/MDSGJ
+flavored/U
+flavorful
+flavoring/M
+flavorless
+flavorsome
+flaw/MDGS
+flawless/PY
+flawlessness/M
+flax/MN
+flay/DRZGS
+flea/MS
+fleabag/SM
+fleabite/S
+fleapit/S
+fleck/SGMD
+fledged/U
+fledgelings
+fledgling/MS
+flee/S
+fleece/MZGDRS
+fleecer/M
+fleeciness/M
+fleecy/RTP
+fleeing
+fleet/STGMDRYP
+fleetingly/M
+fleetingness/M
+fleetness/M
+flesh/GMDSY
+fleshless
+fleshly/TR
+fleshpot/MS
+fleshy/RT
+flew
+flex/AMS
+flexed
+flexibilities
+flexibility/IM
+flexible/I
+flexibly/I
+flexing
+flextime/M
+flibbertigibbet/MS
+flick/SZGMDR
+flicker/GMD
+flickery
+flier/M
+flight/MDS
+flightiness/M
+flightless
+flightpath
+flighty/PTR
+flimflam/SM
+flimflammed
+flimflamming
+flimsily
+flimsiness/M
+flimsy/TRP
+flinch/GMDS
+fling/GM
+flint/SM
+flintlock/SM
+flinty/TR
+flip/MS
+flippable
+flippancy/M
+flippant/Y
+flipped
+flipper/MS
+flippest
+flipping
+flippy/S
+flirt/SGMD
+flirtation/SM
+flirtatious/YP
+flirtatiousness/M
+flirty
+flit/MS
+flitted
+flitting
+float/SMDRZG
+floater/M
+floaty
+flocculation
+flock/SMDG
+flocking/M
+floe/MS
+flog/S
+flogged
+flogger/SM
+flogging/MS
+flood/SMDRG
+floodgate/MS
+floodlight/MDGS
+floodlit
+floodplain/MS
+floodwater/M
+floor/SMDG
+floorboard/MS
+flooring/M
+floorspace
+floorwalker/MS
+floozy/SM
+flop/MS
+flophouse/MS
+flopped
+flopper
+floppily
+floppiness/M
+flopping
+floppy/PRSMT
+flora/SM
+floral
+florescence/IM
+florescent/I
+floret/SM
+florid/PY
+floridness/M
+florin/SM
+florist/SM
+floss/MDSG
+flossy/RT
+flotation/SM
+flotilla/MS
+flotsam/M
+flounce/DSMG
+flouncy/TR
+flounder/MDSG
+flour/SMDG
+flourish/GMDS
+floury/RT
+flout/SMDRZG
+flouter/M
+flow/IMGS
+flowchart/SM
+flowed
+flower's
+flower/CSDG
+flowerbed/MS
+floweriness/M
+flowering/S
+flowerless
+flowerpot/MS
+flowery/PTR
+flown
+flt
+flu/M
+flub/MS
+flubbed
+flubbing
+fluctuate/XGNDS
+fluctuation/M
+flue/MS
+fluency/M
+fluent/Y
+fluff/SMDG
+fluffiness/M
+fluffy/RPT
+fluid/SMY
+fluidity/M
+fluidized
+fluke/SM
+fluky/RT
+flume/SM
+flummox/DSG
+flung
+flunk/SMDG
+flunky/SM
+fluoresce/DSG
+fluorescence/M
+fluorescent
+fluoridate/GNDS
+fluoridation/M
+fluoride/SM
+fluorine/M
+fluorite/M
+fluorocarbon/SM
+fluoroscope/MS
+fluoroscopic
+flurry/GDSM
+flush/MDRSTG
+fluster/MDSG
+flute/DSMG
+fluting/M
+flutist/MS
+flutter/MDSG
+fluttery
+fluvial
+flux's
+flux/ADG
+fluxes
+fly/ZTGBDRSM
+flyaway
+flyblown
+flyby/M
+flybys
+flycatcher/MS
+flying/M
+flyleaf/M
+flyleaves
+flyover/MS
+flypaper/SM
+flypast/S
+flysheet/S
+flyspeck/GMDS
+flyswatter/MS
+flytrap/S
+flyway/SM
+flyweight/SM
+flywheel/MS
+foal/MDGS
+foam/MDGS
+foaminess/M
+foamy/RTP
+fob/SM
+fobbed
+fobbing
+focal/Y
+focus/ACGRSMBi
+focused/UC
+fodder/SM
+foe/SM
+foetid
+fog's
+fog/CS
+fogbound
+fogged/C
+foggily
+fogginess/M
+fogging/C
+foggy/RTP
+foghorn/MS
+fogy/SM
+fogyish
+foible/SM
+foil/MDGS
+foist/SDG
+fol
+fold's
+fold/AUSGD
+foldaway
+folder/SM
+foldout/MS
+foliage/M
+foliate
+folio/SM
+folk/MS
+folklore/M
+folkloric
+folklorist/MS
+folksiness/M
+folksinger/SM
+folksinging/M
+folksong
+folksy/PTR
+folktale/MS
+folkway/MS
+foll
+follicle/MS
+follicular
+follow/SDRZGBJ
+follower/M
+following/M
+followup/S
+folly/SM
+foment/SGD
+fomentation/M
+fond/RYTP
+fondant/MS
+fondle/DSG
+fondness/M
+fondue/SM
+font/MS
+fontanel/MS
+foo
+foobar/S
+food/MS
+foodie/SM
+foodstuff/SM
+fool/MDGS
+foolery/SM
+foolhardily
+foolhardiness/M
+foolhardy/PTR
+foolish/TRYP
+foolishness/M
+foolproof
+foolscap/M
+foot/MDRZGSJ
+footage/M
+football/MRZGS
+footballer/M
+footbridge/MS
+footfall/MS
+foothill/MS
+foothold/MS
+footie
+footing/M
+footless
+footlights/M
+footling/MS
+footlocker/SM
+footloose
+footman/M
+footmarks
+footmen
+footnote/MGDS
+footpads
+footpath/M
+footpaths
+footplate/S
+footprint/SM
+footrace/MS
+footrest/MS
+footsie/SM
+footslogging
+footsore
+footstep/MS
+footstool/SM
+footwear/M
+footwork/M
+footy
+fop/SM
+foppery/M
+foppish/P
+foppishness/M
+for/H
+fora
+forage/DRSMZG
+forager/M
+foray/SMDG
+forbade
+forbear/SMG
+forbearance/M
+forbid/S
+forbidden
+forbidding/YS
+forbore
+forborne
+force/DSMG
+forced/U
+forceful/PY
+forcefulness/M
+forceps/M
+forcible
+forcibly
+ford/MDGSB
+fordable/U
+fore/MS
+forearm/GSMD
+forebear/MS
+forebode/GJDS
+foreboding/M
+forecast/MRZGS
+forecaster/M
+forecastle/MS
+foreclose/DSG
+foreclosure/SM
+forecourt/SM
+foredeck
+foredoom/DGS
+forefather/MS
+forefeet
+forefinger/SM
+forefoot/M
+forefront/SM
+foregoing
+foregone
+foreground/MDGS
+forehand/MS
+forehead/MS
+foreign/ZRP
+foreigner/M
+foreignness/M
+foreknew
+foreknow/GS
+foreknowledge/M
+foreknown
+foreleg/SM
+forelimb/MS
+forelock/MS
+foreman/M
+foremast/MS
+foremen
+foremost
+forename/MDS
+forenoon/MS
+forensic/MS
+forensically
+forensics/M
+foreordain/GDS
+forepart/MS
+forepaws
+foreperson/SM
+foreplay/M
+forequarter/SM
+forerunner/MS
+foresail/MS
+foresaw
+foresee/RSBZ
+foreseeability
+foreseeable/U
+foreseeing
+foreseen/U
+foreseer/M
+foreshadow/SGD
+foreshore/S
+foreshorten/SDG
+foresight/MD
+foresightedness/M
+foreskin/MS
+forest's
+forest/ACGDS
+forestall/SGD
+forestation/ACM
+forester/MS
+forestland/M
+forestry/M
+foretaste/DSMG
+foretell/GS
+forethought/M
+foretold
+forever/M
+forevermore
+forewarn/DSG
+forewent
+forewoman/M
+forewomen
+foreword/MS
+forfeit/GSMD
+forfeiture/SM
+forgather/SDG
+forgave
+forge/DRSMZGVJ
+forger/M
+forgery/SM
+forget/S
+forgetful/PY
+forgetfulness/M
+forgettable/U
+forgetting
+forging/M
+forgivable/U
+forgive/BRSZGP
+forgiven/U
+forgiveness/M
+forgiver/M
+forgiving/U
+forgo/RZG
+forgoer/M
+forgoes
+forgone
+forgot
+forgotten/U
+fork/MDGS
+forkful/SM
+forklift/MS
+forlorn/PTRY
+form's
+form/CAIFDGS
+formal/SMY
+formaldehyde/M
+formalin
+formalism/MS
+formalist/MS
+formalistic
+formalities
+formality/IM
+formalization/MS
+formalize/GDS
+formant
+format/SMV
+formation/CFASM
+formatted/A
+formatting/M
+formed/U
+former/AIFMS
+formerly
+formfitting
+formic
+formidable
+formidably
+formless/PY
+formlessness/M
+formula/MS
+formulaic
+formulate/ADSGNX
+formulated/U
+formulation/AM
+formulator/SM
+fornicate/GNDS
+fornication/M
+fornicator/MS
+forsake/GS
+forsaken
+forsook
+forsooth
+forswear/SG
+forswore
+forsworn
+forsythia/SM
+fort/MS
+forte/SM
+forthcoming/M
+forthright/PY
+forthrightness/M
+forthwith
+fortieth/M
+fortieths
+fortification/M
+fortified/U
+fortifier/M
+fortify/DRSZGNX
+fortissimo
+fortitude/M
+fortnight/MYS
+fortress/MS
+fortuitous/PY
+fortuitousness/M
+fortuity/M
+fortunate/UY
+fortune/MS
+fortuneteller/SM
+fortunetelling/M
+forty/SMH
+forum/SM
+forward/MDRYZTGSP
+forwarder/M
+forwardness/M
+forwent
+fossil/SM
+fossiliferous
+fossilization/M
+fossilize/GDS
+foster/GSD
+fought
+foul/MDRYTGSP
+foulard/M
+foulmouthed
+foulness/M
+found/FSDG
+foundation/SM
+foundational
+founded/U
+founder/GMDS
+foundling/SM
+foundry/SM
+fount/SM
+fountain/SM
+fountainhead/MS
+four/MHS
+fourfold
+fourpence
+fourpenny
+fourposter/MS
+fourscore/M
+foursome/SM
+foursquare
+fourteen/SMH
+fourteenth/M
+fourteenths
+fourth/MY
+fourths
+fowl/MDGS
+fox/GMDS
+foxfire/M
+foxglove/SM
+foxhole/MS
+foxhound/SM
+foxhunt/GS
+foxily
+foxiness/M
+foxtrot/MS
+foxtrotted
+foxtrotting
+foxy/RTP
+foyer/SM
+fps
+fr
+fracas/MS
+fractal/SM
+fraction/IASM
+fractional/Y
+fractionate/GND
+fractious/YP
+fractiousness/M
+fracture/MGDS
+frag/S
+fragile/RT
+fragility/M
+fragment/GMDS
+fragmentary/M
+fragmentation/M
+fragrance/MS
+fragrant/Y
+frail/RYTP
+frailness/M
+frailty/SM
+frame/DRSMZG
+framed/U
+framer/M
+framework/SM
+franc/SM
+franchise's
+franchise/EDSG
+franchisee/SM
+franchiser/SM
+francium/M
+francophone
+frangibility/M
+frangible
+frank/SMDRYTGP
+frankfurter/MS
+frankincense/M
+frankness/M
+frantic
+frantically
+frappe/SM
+frat/MS
+fraternal/Y
+fraternity/FSM
+fraternization/M
+fraternize/ZGDRS
+fraternizer/M
+fratricidal
+fratricide/MS
+fraud's
+fraud/S
+fraudster/S
+fraudulence/M
+fraudulent/Y
+fraught
+fray's
+fray/CDGS
+frazzle/MGDS
+freak/SMDG
+freakish/YP
+freakishness/M
+freaky/RT
+freckle/DSMG
+freckly/TR
+free/YTDRS
+freebase/MGDS
+freebie/SM
+freebooter/SM
+freeborn
+freedman/M
+freedmen
+freedom/SM
+freehand
+freehold/ZMRS
+freeholder/M
+freeing
+freelance/DRSMZG
+freelancer/M
+freeload/SDRZG
+freeloader/M
+freeman/M
+freemasonry
+freemen
+freephone
+freesia/S
+freestanding
+freestone/SM
+freestyle/SM
+freethinker/SM
+freethinking/M
+freeware/SM
+freeway/MS
+freewheel/DSG
+freewill
+freezable
+freeze's
+freeze/UAGS
+freezer/MS
+freezing's
+freight/MDRZGS
+freighter/M
+french
+frenetic
+frenetically
+frenzied/Y
+frenzy/DSM
+freon/S
+freq
+frequencies
+frequency/IM
+frequent/DRYSZTG
+frequented/U
+frequenter/M
+fresco/M
+frescoes
+fresh/PNRYXZT
+freshen/ZGDR
+freshener/M
+freshet/MS
+freshman/M
+freshmen
+freshness/M
+freshwater/M
+fret/MS
+fretboard
+fretful/YP
+fretfulness/M
+fretsaw/MS
+fretted
+fretting
+fretwork/M
+friable
+friar/SM
+friary/SM
+fricassee/DSM
+fricasseeing
+fricative/SM
+friction/SM
+frictional
+frictionless
+fridge/SM
+friedcake/MS
+friend/SM
+friendless/P
+friendlies
+friendlily
+friendliness/UM
+friendly's
+friendly/UTPR
+friendship/SM
+frieze/SM
+frig/S
+frigate/MS
+frigged
+frigging
+fright/SXGMDN
+frighten/DZG
+frightening/Y
+frightful/PY
+frightfulness/M
+frigid/YP
+frigidity/M
+frigidness/M
+frill/SMD
+frilly/TR
+fringe's
+fringe/IDSG
+frippery/SM
+frisk/SDG
+friskily
+friskiness/M
+frisky/TRP
+frisson/S
+fritter/MDSG
+fritz/M
+frivolity/SM
+frivolous/YP
+frivolousness/M
+frizz/MDSYG
+frizzle/MGDS
+frizzly/TR
+frizzy/TR
+fro
+frock's
+frock/CUS
+frog/MS
+frogging/DGS
+frogman/M
+frogmarch/GDS
+frogmen
+frogspawn
+frolic/SM
+frolicked
+frolicker/SM
+frolicking
+frolicsome
+from
+frond/SM
+front's
+front/FSDG
+frontage/MS
+frontal/Y
+frontbench/ZRS
+frontier/MS
+frontiersman/M
+frontiersmen
+frontierswoman
+frontierswomen
+frontispiece/SM
+frontward/S
+frosh/M
+frost's
+frost/CSDG
+frostbit
+frostbite/MGS
+frostbitten
+frostily
+frostiness/M
+frosting/M
+frosty/TPR
+froth/MDG
+frothiness/M
+froths
+frothy/TPR
+froufrou/M
+froward/P
+frowardness/M
+frown/SMDG
+frowning/Y
+frowzily
+frowziness/M
+frowzy/TPR
+froze/AU
+frozen/UA
+fructify/DSG
+fructose/M
+frugal/Y
+frugality/M
+fruit/SMDG
+fruitcake/MS
+fruiterer/S
+fruitful/PY
+fruitfuller
+fruitfullest
+fruitfulness/M
+fruitiness/M
+fruition/M
+fruitless/YP
+fruitlessness/M
+fruity/TPR
+frump/SM
+frumpish
+frumpy/TR
+frustrate/GNDSX
+frustrated/Y
+frustrating/Y
+frustration/M
+frustum/MS
+fry/GDSM
+fryer/SM
+ft
+ftp/ZGSR
+fuchsia/MS
+fuck/GDRMZS!
+fucker/M!
+fuckhead/S!
+fuddle/DSMG
+fudge/DSMG
+fuel's
+fuel/ADGS
+fug
+fugal
+fuggy
+fugitive/MS
+fugue/SM
+fuhrer/SM
+fulcrum/MS
+fulfill/LDGS
+fulfilled/U
+fulfillment/M
+full/MDRZTGSP
+fullback/MS
+fuller/M
+fullish
+fullness/M
+fullstops
+fully
+fulminate/DSXGN
+fulmination/M
+fulsome/PY
+fulsomeness/M
+fum/S
+fumarole/S
+fumble/DRSMZG
+fumbler/M
+fumbling/Y
+fume/MGDS
+fumigant/MS
+fumigate/GNDS
+fumigation/M
+fumigator/SM
+fuming/Y
+fumy/RT
+fun/M
+function/MDGS
+functional/Y
+functionalism
+functionalist/S
+functionality
+functionary/SM
+functionless
+fund/AMDGS
+fundamental/SMY
+fundamentalism/M
+fundamentalist/MS
+funded/U
+fundholders
+fundholding
+funding/M
+fundraiser/MS
+funeral/MS
+funerary
+funereal/Y
+funfair/S
+fungal
+fungi
+fungible/MS
+fungicidal
+fungicide/MS
+fungoid
+fungous
+fungus/M
+funicular/SM
+funk/MDGS
+funkiness/M
+funky/PRT
+funnel/MDGS
+funner
+funnest
+funnily
+funniness/M
+funny/TPRSM
+funnyman/M
+funnymen
+fur/SM
+furbelow/M
+furbish/ADSG
+furious/Y
+furl's
+furl/UDGS
+furlong/SM
+furlough/GMD
+furloughs
+furn
+furnace/SM
+furnish/ADSG
+furnished/U
+furnishings/M
+furniture/M
+furor/SM
+furred
+furrier/M
+furriness/M
+furring/M
+furrow/MDSG
+furry/ZTRP
+further/SGD
+furtherance/M
+furthermore
+furthermost
+furthest
+furtive/YP
+furtiveness/M
+fury/SM
+furze/M
+fuse's/A
+fuse/CAIFGDS
+fusee/SM
+fuselage/SM
+fusibility/M
+fusible
+fusilier/SM
+fusillade/MS
+fusion/IFKSM
+fuss/MDSG
+fussbudget/SM
+fussily
+fussiness/M
+fusspot/SM
+fussy/TRP
+fustian/M
+fustiness/M
+fusty/TRP
+fut
+futile/Y
+futility/M
+futon/SM
+future/MS
+futurism/M
+futurist/MS
+futuristic
+futurity/SM
+futurologist/MS
+futurology/M
+futz/DSG
+fuzz/MDSG
+fuzzball/S
+fuzzily
+fuzziness/M
+fuzzy/PTR
+fwd
+fwy
+g/SNXB
+gab/SM
+gabardine/SM
+gabbed
+gabbiness/M
+gabbing
+gabble/DSMG
+gabby/RTP
+gabfest/MS
+gable/DSM
+gad/S
+gadabout/SM
+gadded
+gadder/SM
+gadding
+gadfly/SM
+gadget/SM
+gadgetry/M
+gadolinium/M
+gaff/MDRZGS
+gaffe/SM
+gaffer/M
+gag/SM
+gaga
+gagged
+gagging
+gaggle/SM
+gaiety/M
+gaily
+gain's
+gain/ADGS
+gainer/SM
+gainful/Y
+gainsaid
+gainsay/ZGRS
+gainsayer/M
+gait/MRZS
+gaiter/M
+gal/SM
+gala/MS
+galactic
+galaxy/SM
+gale's
+gale/AS
+galena/M
+gall/MDGS
+gallant/SMY
+gallantry/SM
+gallbladder/SM
+galleon/SM
+galleria/MS
+gallery/DSM
+galley/SM
+gallimaufry/SM
+gallium/M
+gallivant/GSD
+gallon/SM
+gallop/SMDG
+gallows/M
+gallstone/MS
+galoot/SM
+galore
+galosh/MS
+galumph/DG
+galumphs
+galvanic
+galvanism/M
+galvanization/M
+galvanize/DSG
+galvanometer/MS
+galvanometric
+gambit/SM
+gamble/DRSMZG
+gambler/M
+gambling/M
+gambol/SMDG
+game/MYZTGDRSP
+gamecock/MS
+gamekeeper/SM
+gameness/M
+gamesmanship/M
+gamesmen
+gamester/MS
+gamete/SM
+gametic
+gamin/SM
+gamine/SM
+gaminess/M
+gaming/M
+gamma/SM
+gammon/M
+gammy
+gamut/SM
+gamy/RTP
+gander/SM
+gang/MDGS
+gangbusters/M
+gangland/M
+ganglia
+gangling
+ganglion/M
+ganglionic
+gangplank/SM
+gangrene/DSMG
+gangrenous
+gangsta/S
+gangster/SM
+gangsterism
+gangway/MS
+ganja
+gannet/SM
+gantlet/MS
+gantry/SM
+gaolbirds
+gaolbreak/S
+gap/GSMD
+gape/MS
+gaping/Y
+gar/SLM
+garage/DSMG
+garb/MDGS
+garbage/M
+garbageman
+garbanzo/SM
+garble/DSG
+garcon/SM
+garden/SZGMDR
+gardener/M
+gardenia/MS
+gardening/M
+garfish/MS
+gargantuan
+gargle/DSMG
+gargoyle/SM
+garish/PY
+garishness/M
+garland/MDGS
+garlic/M
+garlicky
+garment/MS
+garner/SGD
+garnet/SM
+garnish/GLMDS
+garnishee/DSM
+garnisheeing
+garnishment/MS
+garret/SM
+garrison/MDSG
+garrote/MZGDRS
+garroter/M
+garrulity/M
+garrulous/YP
+garrulousness/M
+garter/SM
+gas's
+gas/CS
+gasbag/SM
+gaseous
+gash/MDSG
+gasholder/S
+gasket/SM
+gaslight/MS
+gasman
+gasmen
+gasohol/M
+gasoline/M
+gasometer/S
+gasp/MDGS
+gassed/C
+gasses
+gassing/C
+gassy/RT
+gastric
+gastritis/M
+gastroenteritis/M
+gastrointestinal
+gastronome/S
+gastronomic
+gastronomical/Y
+gastronomy/M
+gastropod/SM
+gasworks/M
+gate/MGDS
+gateau/S
+gateaux
+gatecrash/DRSZG
+gatecrasher/M
+gatehouse/SM
+gatekeeper/MS
+gatepost/MS
+gateway/MS
+gather/SJZGMDR
+gathered/I
+gatherer/M
+gathering/M
+gator/SM
+gauche/RPYT
+gaucheness/M
+gaucherie/M
+gaucho/SM
+gaudily
+gaudiness/M
+gaudy/RPT
+gauge/DSMG
+gaunt/RYPT
+gauntlet/MS
+gauntness/M
+gauze/M
+gauziness/M
+gauzy/RPT
+gave
+gavel/SM
+gavotte/MS
+gawd
+gawk/DGS
+gawkily
+gawkiness/M
+gawky/RPT
+gawp/DGS
+gay/TSPMR
+gayness/M
+gaze/MZGDRS
+gazebo/SM
+gazelle/MS
+gazer/M
+gazette/MGDS
+gazetteer/MS
+gazillion/S
+gazpacho/M
+gazump/DGS
+gear/MDGS
+gearbox/MS
+gearing/M
+gearshift/MS
+gearstick
+gearwheel/SM
+gecko/SM
+geddit
+gee/DS
+geeing
+geek/MS
+geeky/RT
+geese
+geezer/MS
+geisha/M
+gel/SM
+gelatin/M
+gelatinous
+gelcap/M
+geld/DJGS
+gelding/M
+gelid
+gelignite/M
+gelled
+gelling
+gem/SM
+gemological
+gemologist/MS
+gemology/M
+gemstone/MS
+gendarme/MS
+gender/MDS
+genderless
+gene/MS
+genealogical/Y
+genealogist/SM
+genealogy/SM
+genera
+general/SMY
+generalissimo/SM
+generalist/MS
+generality/SM
+generalization/MS
+generalize/GBDS
+generalship/M
+generate/ACDSGNV
+generation's/C
+generation/ASM
+generational
+generator/SM
+generic/SM
+generically
+generosity/SM
+generous/UY
+generousness/M
+genes/S
+genesis/M
+genetic/S
+genetically
+geneticist/SM
+genetics/M
+genial/FY
+geniality/FM
+genie/SM
+genii
+genital/FY
+genitalia/M
+genitals/M
+genitive/MS
+genitourinary
+genius/MS
+genned
+genning
+genocidal
+genocide/MS
+genome/MS
+genomic
+genotype/S
+genre/SM
+gent/AMS
+genteel/RYTP
+genteelness/M
+gentian/SM
+gentile/SM
+gentility/M
+gentle/TGDRSP
+gentlefolk/SM
+gentlefolks/M
+gentleman/MY
+gentlemanly/U
+gentlemen
+gentleness/M
+gentlewoman/M
+gentlewomen
+gently
+gentrification/M
+gentrify/DSGN
+gentry/SM
+genuflect/DGS
+genuflection/MS
+genuine/PY
+genuineness/M
+genus/M
+geocentric
+geocentrically
+geochemical
+geochemistry/M
+geode/SM
+geodesic/SM
+geodesy/M
+geodetic
+geog
+geographer/SM
+geographic
+geographical/Y
+geography/SM
+geologic
+geological/Y
+geologist/MS
+geology/SM
+geom
+geomagnetic
+geomagnetically
+geomagnetism/M
+geometer/S
+geometric
+geometrical/Y
+geometry/SM
+geomorphology
+geophysical
+geophysicist/SM
+geophysics/M
+geopolitical
+geopolitics/M
+geoscientific
+geostationary
+geosynchronous
+geosyncline/SM
+geothermal
+geothermic
+geranium/MS
+gerbil/MS
+geriatric/S
+geriatrician/S
+geriatrics/M
+germ/MS
+germane
+germanium/M
+germicidal
+germicide/MS
+germinal/M
+germinate/GNDS
+germinated/U
+germination/M
+gerontocracy
+gerontological
+gerontologist/SM
+gerontology/M
+gerrymander/SMDG
+gerrymandering/M
+gerund/VMS
+gestalt/S
+gestapo/MS
+gestate/GNDS
+gestation/M
+gestational
+gesticulate/XDSGN
+gesticulation/M
+gestural
+gesture/MGDS
+gesundheit
+get/SM
+getaway/SM
+gettable
+getter
+getting
+getup/M
+gewgaw/SM
+geyser/SM
+ghastliness/M
+ghastly/TPR
+ghat/MS
+ghee
+gherkin/MS
+ghetto/SM
+ghettoize/GDS
+ghost/SMDYG
+ghostlike
+ghostliness/M
+ghostly/RTP
+ghostwrite/ZGRS
+ghostwriter/M
+ghostwritten
+ghostwrote
+ghoul/SM
+ghoulish/PY
+ghoulishness/M
+giant/SM
+giantess/MS
+giantkiller
+gibber/GDS
+gibberish/M
+gibbet/GMDS
+gibbon/MS
+gibbous
+gibe/MGDS
+giblet/SM
+giddily
+giddiness/M
+giddy/RTP
+gift/MDGS
+gig/SM
+gigabyte/MS
+gigahertz/M
+gigantic
+gigantically
+gigavolt
+gigged
+gigging
+giggle/DRSMZG
+giggler/M
+giggly/RT
+gigolo/SM
+gild/MDRZGS
+gilder/M
+gilding/M
+gill/MS
+gillie/S
+gillion/S
+gilt/MS
+gimbals/M
+gimcrack/SM
+gimcrackery/M
+gimlet/GSMD
+gimme/SM
+gimmick/MS
+gimmickry/M
+gimmicky
+gimp/MDGS
+gimpy/RT
+gin/SM
+ginger/GSMDY
+gingerbread/M
+gingersnap/SM
+gingery
+gingham/M
+gingivitis/M
+ginkgo/M
+ginkgoes
+ginned
+ginning
+ginormous
+ginseng/M
+giraffe/MS
+gird/DRZGS
+girder/M
+girdle/DSMG
+girl/MS
+girlfriend/SM
+girlhood/SM
+girlie
+girlish/YP
+girlishness/M
+giro/S
+girt/MDGS
+girth/M
+girths
+gist/M
+git/S
+gite/S
+give/MZGJRS
+giveaway/MS
+giveback/MS
+given/SM
+giver/M
+gizzard/MS
+glace/S
+glaceed
+glaceing
+glacial/Y
+glaciate/XGNDS
+glaciation/M
+glacier/MS
+glaciological
+glaciologist/S
+glaciology
+glad/MYSP
+gladden/GDS
+gladder
+gladdest
+glade/SM
+gladiator/SM
+gladiatorial
+gladiola/SM
+gladioli
+gladiolus/M
+gladly/TR
+gladness/M
+gladsome/RT
+glam
+glamor/SGMD
+glamorization/M
+glamorize/DSG
+glamorous/Y
+glance/DSMG
+gland/SM
+glandes
+glandular
+glans/M
+glare/DSMG
+glaring/Y
+glasnost/M
+glass/MDSG
+glassblower/MS
+glassblowing/M
+glassful/SM
+glasshouse/S
+glassily
+glassiness/M
+glassless
+glassware/M
+glassy/RTP
+glaucoma/M
+glaze/DSMG
+glazed/U
+glazier/SM
+glazing/M
+gleam/SMDGJ
+glean/SDRZGJ
+gleaner/M
+gleanings/M
+glee/M
+gleeful/YP
+gleefulness/M
+glen/MS
+glib/YP
+glibber
+glibbest
+glibness/M
+glide/DRSMZG
+glider/M
+gliding/M
+glimmer/MDGJS
+glimmering/M
+glimpse/MGDS
+glint/SMDG
+glissandi
+glissando/M
+glisten/MDSG
+glister/DSG
+glitch/GMDS
+glitter/MDSG
+glitterati
+glittery
+glitz/M
+glitzy/TR
+gloaming/SM
+gloat/SMDG
+gloating/Y
+glob/MDGS
+global/Y
+globalism/M
+globalist/MS
+globalization/M
+globalize/GDS
+globe/SM
+globetrotter/MS
+globetrotting
+globular
+globule/MS
+globulin/M
+glockenspiel/MS
+gloom/M
+gloomily
+gloominess/M
+gloomy/TRP
+glop/M
+gloppy/TR
+glorification/M
+glorify/GNDS
+glorious/IY
+glory/DSMG
+gloss/MDSG
+glossary/SM
+glossily
+glossiness/M
+glossolalia/M
+glossy/PTRSM
+glottal
+glottis/MS
+glove/DSMG
+glow/MDRZGS
+glower/GMD
+glowing/Y
+glowworm/MS
+glucose/M
+glue/MGDS
+glued/U
+gluey
+gluier
+gluiest
+glum/YP
+glummer
+glummest
+glumness/M
+gluon
+glut/MNS
+glutamate
+gluten/M
+glutenous
+glutinous/Y
+glutted
+glutting
+glutton/MS
+gluttonous/Y
+gluttony/M
+glycerin/M
+glycerol/M
+glycine
+glycogen/M
+glycol
+glyph
+glyphs
+gm
+gnarl/SMDG
+gnarly/TR
+gnash/MDSG
+gnat/MS
+gnaw/DGS
+gneiss/M
+gnocchi
+gnome/SM
+gnomic
+gnomish
+gnostic
+gnosticism
+gnu/SM
+go/SJMRHZG
+goad/MDGS
+goal/MS
+goalie/SM
+goalkeeper/SM
+goalkeeping/M
+goalless
+goalmouth
+goalmouths
+goalpost/MS
+goalscorer/S
+goalscoring
+goaltender/SM
+goat/MS
+goatee/SM
+goatherd/MS
+goatskin/MS
+gob/SM
+gobbed
+gobbet/SM
+gobbing
+gobble/DRSMZG
+gobbledygook/M
+gobbler/M
+goblet/SM
+goblin/SM
+gobsmacked
+gobstopper/S
+god/SM
+godawful
+godchild/M
+godchildren
+goddammit
+goddamn
+goddaughter/SM
+goddess/MS
+godfather/SM
+godforsaken
+godhead/M
+godhood/M
+godless/PY
+godlessness/M
+godlike
+godliness/UM
+godly/URTP
+godmother/SM
+godparent/SM
+godsend/SM
+godson/SM
+godspeed
+goer/M
+goes
+gofer/SM
+goggle/DSMG
+goggles/M
+going/M
+goiter/SM
+gold/MNRTS
+goldbrick/SZGMDR
+goldbricker/M
+golden/TR
+goldenrod/M
+goldfield/S
+goldfinch/MS
+goldfish/MS
+goldmine/SM
+goldsmith/M
+goldsmiths
+golf/MDRZGS
+golfer/M
+golliwog/S
+golly/SM
+gonad/SM
+gonadal
+gondola/MS
+gondolier/SM
+gone/ZR
+goner/M
+gong/MDGS
+gonk/DGS
+gonna
+gonorrhea/M
+gonorrheal
+gonzo
+goo/M
+goober/SM
+good/MYSP
+goodbye/MS
+goodhearted
+goodish
+goodly/TR
+goodness/M
+goodnight
+goods/M
+goodwill/M
+goody/SM
+gooey
+goof/MDGS
+goofball/SM
+goofiness/M
+goofy/RPT
+googly/S
+gooier
+gooiest
+gook/MS
+goon/MS
+goop/M
+goose/DSMG
+gooseberry/SM
+goosebumps/M
+goosestep/S
+goosestepped
+goosestepping
+gopher/SM
+gore/MGDS
+gorge's
+gorge/EDSG
+gorgeous/YP
+gorgeousness/M
+gorgon/SM
+gorilla/MS
+gorily
+goriness/M
+gormandize/DRSZG
+gormandizer/M
+gormless
+gorp/MS
+gorse/M
+gory/RTP
+gosh
+goshawk/MS
+gosling/SM
+gospel/MS
+gossamer/M
+gossip/MDRZGS
+gossiper/M
+gossipy
+got
+gotcha/S
+goths
+gotta
+gotten
+gouache/S
+gouge/DRSMZG
+gouger/M
+goulash/MS
+gourd/SM
+gourde/MS
+gourmand/SM
+gourmet/SM
+gout/M
+gouty/TR
+gov
+govern/DGSBL
+governable/U
+governance/M
+governed/U
+governess/MS
+government/MS
+governmental
+governor/SM
+governorship/MS
+govt
+gown/MDGS
+gr
+grab/MS
+grabbed
+grabber/MS
+grabbing
+grabby/TR
+grace/EDSMG
+graceful/EPY
+gracefuller
+gracefullest
+gracefulness/EM
+graceless/YP
+gracelessness/M
+gracious/UY
+graciousness/M
+grackle/MS
+grad/MRZSBJ
+gradate/XGNDS
+gradation/CSM
+grade's
+grade/CADSG
+graded/U
+grader/M
+gradient/MS
+gradual/PY
+gradualism/M
+gradualist
+gradualness/M
+graduand/S
+graduate/XMGNDS
+graduation/M
+graffiti
+graffito/M
+graft/SMDRZG
+grafter/M
+graham/S
+grail/S
+grain/ISMD
+graininess/M
+grainy/PTR
+gram/KMS
+grammar/MS
+grammarian/SM
+grammatical/UY
+gramophone/MS
+grampus/MS
+gran/S
+granary/SM
+grand/SMRYPT
+grandam/MS
+grandaunt/MS
+grandchild/M
+grandchildren
+granddad/SM
+granddaddy/SM
+granddaughter/MS
+grandee/MS
+grandeur/M
+grandfather/SMDYG
+grandiloquence/M
+grandiloquent
+grandiose/Y
+grandiosity/M
+grandma/MS
+grandmaster/S
+grandmother/MYS
+grandnephew/MS
+grandness/M
+grandniece/MS
+grandpa/MS
+grandparent/MS
+grandson/MS
+grandstand/SMDG
+granduncle/SM
+grange/SM
+granite/MS
+granitic
+granny/SM
+granola/M
+grant/SMDRZG
+grantee/MS
+granter/M
+grantsmanship/M
+granular
+granularity/M
+granulate/GNDS
+granulation/M
+granule/MS
+grape/SM
+grapefruit/SM
+grapeshot/M
+grapevine/SM
+graph/MDG
+graphic/MS
+graphical/Y
+graphite/M
+graphologist/SM
+graphology/M
+graphs
+grapnel/MS
+grapple/MGDS
+grasp/SMDRBG
+grass/MDSG
+grasshopper/SM
+grassland/MS
+grassroots
+grassy/TR
+grate/DRSMZGJ
+grateful/UYP
+gratefuller
+gratefullest
+gratefulness/UM
+grater/M
+graticule
+gratification/M
+gratify/XNGDS
+gratifying/Y
+gratin/S
+grating/MY
+gratis
+gratitude/IM
+gratuitous/YP
+gratuitousness/M
+gratuity/SM
+gravamen/MS
+grave/DRSMYTGP
+gravedigger/MS
+gravel/SGMDY
+graven
+graveness/M
+graveside/MS
+gravestone/SM
+graveyard/MS
+gravid
+gravimeter/SM
+gravitas
+gravitate/GNDS
+gravitation/M
+gravitational/Y
+graviton/S
+gravity/SM
+gravy/SM
+gray/MDRTGSP
+graybeard/SM
+grayish
+grayness/M
+graze/DRSMZG
+grazer/M
+grease/DRSMZG
+greasepaint/M
+greaseproof
+greasily
+greasiness/M
+greasy/PTR
+great/SMRYPT
+greatcoat/SM
+greathearted
+greatness/M
+grebe/SM
+greed/M
+greedily
+greediness/M
+greedy/PTR
+green/GPSMDRYT
+greenback/MS
+greenbelt/MS
+greenery/M
+greenfield
+greenfly/S
+greengage/MS
+greengrocer/MS
+greengrocery
+greenhorn/SM
+greenhouse/SM
+greenish
+greenmail/M
+greenness/M
+greenroom/SM
+greensward/M
+greenwood/M
+greet/ZGJSDR
+greeter/M
+greeting/M
+gregarious/PY
+gregariousness/M
+gremlin/SM
+grenade/SM
+grenadier/MS
+grenadine/M
+grep/S
+grepped
+grepping
+grew/A
+greybeard
+greyhound/SM
+greyness
+gribble/S
+grid/MS
+gridded
+griddle/SM
+griddlecake/SM
+gridiron/SM
+gridlock/SMD
+grief/SM
+grievance/MS
+grieve/ZGDRS
+griever/M
+grievous/YP
+grievousness/M
+griffin/SM
+grill/SGMDJ
+grille/MS
+grim/DYPG
+grimace/DSMG
+grime/SM
+griminess/M
+grimmer
+grimmest
+grimness/M
+grimy/TRP
+grin/MS
+grind/SZGMRJ
+grinder/M
+grindstone/SM
+gringo/MS
+grinned
+grinner
+grinning
+grip/MDRSZG
+gripe/SM
+griper/M
+grippe/MZGDR
+gripper/M
+grisliness/M
+grisly/RTP
+grist/MY
+gristle/M
+gristly/RT
+gristmill/MS
+grit/MS
+grits/M
+gritted
+gritter/SM
+grittiness/M
+gritting
+gritty/RTP
+grizzle/DSG
+grizzly/TRSM
+groan/SZGMDR
+groat/SM
+grocer/MS
+grocery/SM
+grog/M
+groggily
+grogginess/M
+groggy/PRT
+groin/SM
+grok/S
+grokked
+grokking
+grommet/SM
+groom/SZGMDR
+groomer/M
+grooming/M
+groomsman/M
+groomsmen
+groove/MGDS
+groovy/RT
+grope/DRSJMZG
+groper/M
+groping/Y
+grosbeak/MS
+grosgrain/M
+gross/PTGMDRSY
+grossness/M
+grotesque/SMYP
+grotesqueness/M
+grotto/M
+grottoes
+grotty/TR
+grouch/GMDS
+grouchily
+grouchiness/M
+grouchy/RTP
+ground/ZGMDRJS
+groundbreaking/MS
+groundcloth
+groundcloths
+grounded/U
+grounder/M
+groundhog/MS
+grounding/M
+groundless/Y
+groundnut/MS
+groundsheet/S
+groundskeeper/S
+groundsman
+groundsmen
+groundswell/SM
+groundwater/M
+groundwork/M
+group/JSZGMDR
+grouper/M
+groupie/MS
+grouping/M
+groupware/M
+grouse/MZGDRS
+grouser/M
+grout/SGMD
+grove/SM
+grovel/ZGDRS
+groveler/M
+grovelled
+grovelling
+grow/AHSG
+grower/MS
+growing/I
+growl/SZGMDR
+growler/M
+grown/AI
+grownup/MS
+growth/AM
+growths
+groyne/S
+grub/MS
+grubbed
+grubber/MS
+grubbily
+grubbiness/M
+grubbing
+grubby/TRP
+grubstake/M
+grudge/MGDS
+grudging/Y
+grue/S
+gruel/GJM
+grueling/Y
+gruesome/RYTP
+gruesomeness/M
+gruff/TPRY
+gruffness/M
+grumble/DRSMZGJ
+grumbler/M
+grump/SM
+grumpily
+grumpiness/M
+grumpy/PRT
+grunge/MS
+grungy/RT
+grunion/SM
+grunt/SGMD
+gt
+guacamole/M
+guanine/M
+guano/M
+guarani/MS
+guarantee/MDS
+guaranteeing
+guarantor/MS
+guaranty/GDSM
+guard/SZGMDR
+guarded/YP
+guarder/M
+guardhouse/SM
+guardian/SM
+guardianship/M
+guardrail/SM
+guardroom/SM
+guardsman/M
+guardsmen
+guava/SM
+gubernatorial
+gudgeon
+guerrilla/SM
+guess/ZGBMDRS
+guessable/U
+guesser/M
+guesstimate/DSMG
+guesswork/M
+guest/SGMD
+guesthouse/S
+guestroom/S
+guff/M
+guffaw/MDGS
+guidance/M
+guide/DRSMZG
+guidebook/SM
+guided/U
+guideline/SM
+guidepost/SM
+guider/M
+guild/SZMR
+guilder/M
+guildhall/MS
+guile/M
+guileful
+guileless/PY
+guilelessness/M
+guillemot/S
+guillotine/DSMG
+guilt/M
+guiltily
+guiltiness/M
+guiltless
+guilty/PRT
+guinea/MS
+guise/ESM
+guitar/MS
+guitarist/SM
+gulag/SM
+gulch/MS
+gulden/MS
+gulf/MS
+gull/MDSG
+gullet/MS
+gullibility/M
+gullible
+gully/SM
+gulp/MDRSZG
+gulper/M
+gum/M
+gumball/S
+gumbo/SM
+gumboil/SM
+gumboot/S
+gumdrop/SM
+gummed
+gumming
+gummy/TR
+gumption/M
+gumshoe/MDS
+gumshoeing
+gumtree/S
+gun/SM
+gunboat/SM
+gunfight/MRZS
+gunfighter/M
+gunfire/M
+gunge
+gungy
+gunk/M
+gunky/TR
+gunman/M
+gunmen
+gunmetal/M
+gunned
+gunner/MS
+gunnery/M
+gunning
+gunny/M
+gunnysack/MS
+gunpoint/M
+gunpowder/M
+gunrunner/MS
+gunrunning/M
+gunship/MS
+gunshot/MS
+gunslinger/SM
+gunsmith/M
+gunsmiths
+gunwale/MS
+guppy/SM
+gurgle/MGDS
+gurney/MS
+guru/MS
+gush/MDRSZG
+gusher/M
+gushing/Y
+gushy/TR
+gusset/MSDG
+gussy/DSG
+gust/EMDSG
+gustatory
+gustily
+gusto/M
+gusty/RT
+gut/SM
+gutless/P
+gutlessness/M
+gutsy/RT
+gutted
+gutter/SMDG
+guttersnipe/SM
+gutting
+guttural/MYS
+gutty/RT
+guv/S
+guvnor/S
+guy/SGMD
+guzzle/DRSZG
+guzzler/M
+gym/SM
+gymkhana/MS
+gymnasium/MS
+gymnast/MS
+gymnastic/S
+gymnastically
+gymnastics/M
+gymnosperm/SM
+gymslip/S
+gynecologic
+gynecological
+gynecologist/MS
+gynecology/M
+gyp/SM
+gypped
+gypper/SM
+gypping
+gypster/SM
+gypsum/M
+gypsy/SM
+gyrate/DSGNX
+gyration/M
+gyrator/SM
+gyrfalcon/MS
+gyro/MS
+gyromagnetic
+gyroscope/MS
+gyroscopic
+gyve/MGDS
+h'm
+h/NRSXZGVJ
+ha/SH
+haberdasher/MS
+haberdashery/SM
+habiliment/SM
+habit's
+habit/ISB
+habitability/M
+habitat/SM
+habitation/MS
+habitual/YP
+habitualness/M
+habituate/GNDS
+habituation/M
+habitue/SM
+hacienda/SM
+hack/BMDRZGS
+hacker/M
+hacking/M
+hackish/SP
+hackishness/S
+hackitude/S
+hackle/MS
+hackney/SMDG
+hacksaw/SM
+hackwork/M
+had
+haddock/SM
+hadn't
+hadron/S
+hadst
+haemorrhoid
+hafnium/M
+haft/MS
+hag/SM
+haggard/YP
+haggardness/M
+haggis/MS
+haggish
+haggle/MZGDRS
+haggler/M
+hagiographer/SM
+hagiography/SM
+hahnium/M
+haiku/M
+hail/MDGS
+hailstone/MS
+hailstorm/MS
+hair/MDS
+hairball/MS
+hairband/S
+hairbreadth/M
+hairbreadths
+hairbrush/MS
+haircare
+haircloth/M
+haircut/SM
+hairdo/MS
+hairdresser/MS
+hairdressing/M
+hairdryer/MS
+hairgrip/S
+hairiness/M
+hairless
+hairlike
+hairline/SM
+hairnet/SM
+hairpiece/MS
+hairpin/SM
+hairsbreadth/M
+hairsbreadths
+hairsplitter/MS
+hairsplitting/M
+hairspray/S
+hairspring/SM
+hairstyle/MGS
+hairstylist/MS
+hairy/TRP
+haj
+hajj/M
+hajjes
+hajji/SM
+hake/MS
+halal/M
+halberd/SM
+halcyon
+hale/ITGDRS
+half/M
+halfback/SM
+halfbreed
+halfhearted/YP
+halfheartedness/M
+halfpence
+halfpenny/SM
+halfpennyworth
+halftime/MS
+halftone/MS
+halfway
+halfwit/SM
+halibut/SM
+halide/S
+halite/M
+halitosis/M
+hall/MS
+hallelujah/M
+hallelujahs
+hallmark/GMDS
+hallow/DSG
+hallowed/U
+hallucinate/DSXGN
+hallucination/M
+hallucinatory
+hallucinogen/SM
+hallucinogenic/MS
+hallway/SM
+halo/MDGS
+halogen/SM
+halogenated
+halon/S
+halt/MDRZGS
+halter/GMD
+halterneck/S
+halting/Y
+halve/DSG
+halyard/MS
+ham/SM
+hamburg/SZMR
+hamburger/M
+hamlet/MS
+hammed
+hammer/MDRSJZG
+hammerer/M
+hammerhead/SM
+hammerlock/SM
+hammertoe/MS
+hamming
+hammock/SM
+hammy/TR
+hamper/GMDS
+hampered/U
+hamster/MS
+hamstring/SGM
+hamstrung
+hand's
+hand/UDGS
+handbag/SM
+handball/MS
+handbarrow/SM
+handbasin
+handbill/MS
+handbook/MS
+handbrake/S
+handcar/SM
+handcart/MS
+handclasp/MS
+handcraft/SMDG
+handcuff/MDGS
+handed/P
+handful/SM
+handgun/SM
+handhold/MS
+handicap/MS
+handicapped
+handicapper/SM
+handicapping
+handicraft/MS
+handily
+handiness/M
+handiwork/M
+handkerchief/SM
+handle/MZGDRS
+handlebar/MS
+handler/M
+handmade
+handmaid/XMNS
+handmaiden/M
+handout/SM
+handover/S
+handpick/GDS
+handrail/MS
+handsaw/SM
+handset/SM
+handshake/JMGS
+handsome/PYTR
+handsomeness/M
+handspring/MS
+handstand/SM
+handwork/M
+handwoven
+handwriting/M
+handwritten
+handy/UTR
+handyman/M
+handymen
+hang/MDRJZGS
+hangar/MS
+hangdog
+hanger/M
+hanging/M
+hangman/M
+hangmen
+hangnail/MS
+hangout/SM
+hangover/MS
+hangup/MS
+hank/MRZS
+hanker/GJD
+hankering/M
+hankie/MS
+hansom/MS
+hap/MY
+haphazard/YP
+haphazardness/M
+hapless/YP
+haplessness/M
+haploid/MS
+happen/SDGJ
+happening/M
+happenstance/MS
+happily/U
+happiness/UM
+happy/URTP
+harangue/MGDS
+harass/LZGDRS
+harasser/M
+harassment/M
+harbinger/SM
+harbor/GMDS
+harbormaster/S
+hard/NRYXTP
+hardback/MS
+hardball/M
+hardboard/M
+hardbound
+hardcore
+hardcover/SM
+harden/ZGDR
+hardened/U
+hardener/M
+hardhat/MS
+hardheaded/PY
+hardheadedness/M
+hardhearted/PY
+hardheartedness/M
+hardihood/M
+hardily
+hardiness/M
+hardliner/MS
+hardness/M
+hardscrabble
+hardship/SM
+hardstand/SM
+hardtack/M
+hardtop/SM
+hardware/M
+hardwired
+hardwood/SM
+hardworking
+hardy/PTR
+hare/MGDS
+harebell/MS
+harebrained
+harelip/SM
+harelipped
+harem/SM
+haricot/S
+hark/DGS
+harlequin/SM
+harlot/SM
+harlotry/M
+harm/MDRGS
+harmed/U
+harmful/YP
+harmfulness/M
+harmless/PY
+harmlessness/M
+harmonic/SM
+harmonica/MS
+harmonically
+harmonies
+harmonious/PY
+harmoniousness/M
+harmonium/MS
+harmonization/M
+harmonize/ZGDRS
+harmonizer/M
+harmony/EM
+harness's
+harness/UDSG
+harp/MDGS
+harpist/SM
+harpoon/ZGSMDR
+harpooner/M
+harpsichord/SM
+harpsichordist/MS
+harpy/SM
+harridan/MS
+harrier/M
+harrow/SMDG
+harrumph/GD
+harrumphs
+harry/DRSZG
+harsh/RYTP
+harshness/M
+hart/MS
+harvest/SMDRZG
+harvested/U
+harvester/M
+hash/AMDSG
+hashish/M
+hasn't
+hasp/MS
+hassle/DSMG
+hassock/SM
+hast/DNXG
+haste/SM
+hasten/DG
+hastily
+hastiness/M
+hasty/RTP
+hat/ZGSMDR
+hatband/S
+hatbox/MS
+hatch/MDSG
+hatchback/MS
+hatcheck/SM
+hatched/U
+hatchery/SM
+hatchet/SM
+hatching/M
+hatchway/SM
+hate/MS
+hateful/PY
+hatefulness/M
+hatemonger/MS
+hater/M
+hatpin/S
+hatred/SM
+hatstand/S
+hatted
+hatter/SM
+hatting
+hauberk/SM
+haughtily
+haughtiness/M
+haughty/PRT
+haul/MDRZGS
+haulage/M
+hauler/M
+haulier/S
+haunch/MS
+haunt/SMDRZG
+haunter/M
+haunting/Y
+hauteur/M
+have/MGS
+haven't
+haven/SM
+havering
+haversack/SM
+havoc/M
+haw/GSMD
+hawk/MDRZGS
+hawker/M
+hawkish/P
+hawkishness/M
+hawser/SM
+hawthorn/MS
+hay/GSMD
+haycock/SM
+hayfield
+hayloft/SM
+haymaking
+haymow/SM
+hayrick/MS
+hayride/MS
+hayseed/MS
+haystack/SM
+haywain
+haywire
+hazard/SMDG
+hazardous/Y
+haze/MZGJDRS
+hazel/SM
+hazelnut/MS
+hazer/M
+hazily
+haziness/M
+hazing/M
+hazy/RTP
+hdqrs
+he'd
+he'll
+he/M
+head/MDRZGJS
+headache/MS
+headband/MS
+headbanger/S
+headbanging
+headboard/SM
+headbutt/DSG
+headcase/S
+headcheese
+headcount/S
+headdress/MS
+header/M
+headfirst
+headgear/M
+headhunt/DRSZG
+headhunter/M
+headhunting/M
+headily
+headiness/M
+heading/M
+headlamp/MS
+headland/MS
+headless
+headlight/MS
+headline/MZGDRS
+headliner/M
+headlock/MS
+headlong
+headman/M
+headmaster/SM
+headmastership
+headmen
+headmistress/MS
+headnote
+headphone/MS
+headpiece/MS
+headpin/SM
+headquarter/SGD
+headquarters/M
+headrest/MS
+headroom/M
+headscarf
+headscarves
+headset/SM
+headship/SM
+headshrinker/MS
+headsman/M
+headsmen
+headstall/SM
+headstand/SM
+headstock
+headstone/SM
+headstrong
+headteacher/S
+headwaiter/MS
+headwaters/M
+headway/M
+headwind/SM
+headword/SM
+heady/RTP
+heal/DRHZGS
+healed/U
+healer/M
+health/M
+healthful/PY
+healthfulness/M
+healthily/U
+healthiness/UM
+healths
+healthy/UTRP
+heap/MDGS
+hear/AHGJS
+heard/AU
+hearer/SM
+hearing/AM
+hearken/SGD
+hearsay/M
+hearse's
+hearse/AS
+heart/SM
+heartache/MS
+heartbeat/MS
+heartbreak/MSG
+heartbroken
+heartburn/M
+hearten/ESGD
+heartfelt
+hearth/M
+hearthrug/S
+hearths
+hearthstone/MS
+heartily
+heartiness/M
+heartland/MS
+heartless/YP
+heartlessness/M
+heartrending/Y
+heartsick/P
+heartsickness/M
+heartstrings/M
+heartthrob/MS
+heartwarming
+heartwood/M
+hearty/RSMPT
+heat's
+heat/ADGS
+heated/U
+heatedly
+heater/SM
+heath/MNRXZ
+heathen/M
+heathendom/M
+heathenish
+heathenism/M
+heather/M
+heathery
+heathland
+heaths
+heating/M
+heatproof
+heatstroke/M
+heatwave/S
+heave/DRSMZG
+heaven/SMY
+heavenly/TR
+heavens/M
+heavenward/S
+heaver/M
+heavily
+heaviness/M
+heavy/RSMTP
+heavyhearted
+heavyset
+heavyweight/SM
+heck/M
+heckle/DRSMZG
+heckler/M
+heckling/M
+hectare/SM
+hectic
+hectically
+hectogram/SM
+hectoliters
+hectometer/MS
+hector/SMDG
+hedge/DRSMZG
+hedgehog/MS
+hedgehop/S
+hedgehopped
+hedgehopping
+hedger/M
+hedgerow/SM
+hedonism/M
+hedonist/MS
+hedonistic
+heed/MDGS
+heeded/U
+heedful/Y
+heedless/PY
+heedlessness/M
+heehaw/SMDG
+heel/MDGS
+heelless
+heft/MDGS
+heftily
+heftiness/M
+hefty/PRT
+hegemonic
+hegemony/M
+hegira/SM
+heifer/SM
+height/XSMN
+heighten/DG
+heinous/YP
+heinousness/M
+heir/MS
+heiress/MS
+heirloom/SM
+heist/SMDG
+held
+helical
+helices
+helicopter/SMDG
+heliocentric
+heliography
+heliosphere
+heliotrope/SM
+helipad/S
+heliport/MS
+helium/M
+helix/M
+hell/MS
+hellbent
+hellcat/MS
+hellebore/M
+hellfire
+hellhole/MS
+hellion/MS
+hellish/YP
+hellishness/M
+hello/SM
+helluva
+helm/MS
+helmet/SMD
+helmsman/M
+helmsmen
+helot/SM
+help/MDRZGSJ
+helper/M
+helpful/UY
+helpfulness/M
+helping/M
+helpless/PY
+helplessness/M
+helpline/S
+helpmate/SM
+helve/SM
+hem/SM
+hematite/M
+hematologic
+hematological
+hematologist/SM
+hematology/M
+heme/M
+hemisphere/SM
+hemispheric
+hemispherical
+hemline/SM
+hemlock/SM
+hemmed
+hemmer/SM
+hemming
+hemoglobin/M
+hemophilia/M
+hemophiliac/SM
+hemorrhage/MGDS
+hemorrhagic
+hemorrhoid/MS
+hemostat/MS
+hemp/MN
+hemstitch/MDSG
+hen/M
+hence
+henceforth
+henceforward
+henchman/M
+henchmen
+henge
+henna/SMDG
+henpeck/GSD
+hep
+heparin/M
+hepatic
+hepatitis/M
+hepper
+heppest
+heptagon/MS
+heptagonal
+heptane
+heptathlon/SM
+her/M
+herald/SMDG
+heralded/U
+heraldic
+heraldry/M
+herb/MS
+herbaceous
+herbage/M
+herbal/S
+herbalism
+herbalist/MS
+herbicidal
+herbicide/MS
+herbivore/SM
+herbivorous
+herculean
+herd/MDRZGS
+herder/M
+herdsman/M
+herdsmen
+here/M
+hereabout/S
+hereafter/SM
+hereby
+hereditary
+heredity/M
+herein
+hereinafter
+hereof
+hereon
+heresy/SM
+heretic/SM
+heretical
+hereto
+heretofore
+hereunder
+hereunto
+hereupon
+herewith
+heritability
+heritable/I
+heritage/MS
+hermaphrodite/SM
+hermaphroditic
+hermeneutic/S
+hermetic
+hermetical/Y
+hermit/SM
+hermitage/MS
+hernia/SM
+hernial
+herniate/GNDS
+herniation/M
+hero/M
+heroes
+heroic/S
+heroically
+heroics/M
+heroin/SM
+heroine/SM
+heroism/M
+heron/SM
+herpes/M
+herpetologist/SM
+herpetology/M
+herring/MS
+herringbone/M
+herself
+hertz/M
+hesitance/M
+hesitancy/M
+hesitant/Y
+hesitate/DSGNX
+hesitating/UY
+hesitation/M
+hessian
+hetero/SM
+heterodox
+heterodoxy/M
+heterogeneity/M
+heterogeneous/Y
+heterosexual/MYS
+heterosexuality/M
+heterozygous
+heuristic/MS
+heuristically
+heuristics/M
+hew/ZGSDR
+hewer/M
+hex/GMDS
+hexadecimal/S
+hexagon/MS
+hexagonal
+hexagram/SM
+hexameter/SM
+hexane
+hey
+heyday/SM
+hf
+hgt
+hgwy
+hi/SD
+hiatus/MS
+hibachi/MS
+hibernate/GNDS
+hibernation/M
+hibernator/SM
+hibiscus/MS
+hiccup/GSMD
+hick/MS
+hickey/SM
+hickory/SM
+hid
+hidden/U
+hide/MZGJDRS
+hideaway/SM
+hidebound
+hideous/YP
+hideousness/M
+hideout/MS
+hider/M
+hiding/M
+hie/S
+hieing
+hierarchic
+hierarchical/Y
+hierarchy/SM
+hieratic
+hieroglyph/M
+hieroglyphic/SM
+hieroglyphs
+high/MRYZTP
+highball/SM
+highborn
+highboy/MS
+highbrow/SM
+highchair/MS
+highfalutin
+highhanded/PY
+highhandedness/M
+highish
+highland/MRZS
+highlander/M
+highlight/SMDRZG
+highlighter/M
+highness/M
+highpoint
+highroad/MS
+highs
+hightail/DSG
+highway/MS
+highwayman/M
+highwaymen
+hijack/SJZGMDR
+hijacker/M
+hijacking/M
+hike/MZGDRS
+hiker/M
+hiking/M
+hilarious/PY
+hilariousness/M
+hilarity/M
+hill/MS
+hillbilly/SM
+hilliness/M
+hillock/MS
+hillside/SM
+hilltop/MS
+hillwalking
+hilly/PRT
+hilt/MS
+him/SM
+himself
+hind/MRZS
+hinder/GD
+hindered/U
+hindmost
+hindquarter/MS
+hindrance/SM
+hindsight/M
+hinge's
+hinge/UDSG
+hint/MDRZGS
+hinter/M
+hinterland/MS
+hip/SPM
+hipbath
+hipbaths
+hipbone/MS
+hiphuggers
+hipness/M
+hipped
+hipper
+hippest
+hippie/SM
+hipping
+hippo/SM
+hippodrome/SM
+hippopotamus/MS
+hipster/MS
+hire's
+hire/AGDS
+hireling/MS
+hirer
+hirsute/P
+hirsuteness/M
+hiss/MDSGJ
+hist
+histamine/MS
+histogram/MS
+histological
+histologist/SM
+histology/M
+historian/MS
+historic
+historical/Y
+historicist
+historicity/M
+historiographer/MS
+historiographical
+historiography/M
+history/SM
+histrionic/S
+histrionically
+histrionics/M
+hit/SM
+hitch's
+hitch/UDSG
+hitcher/MS
+hitchhike/DRSMZG
+hitchhiker/M
+hither
+hitherto
+hittable
+hitter/SM
+hitting
+hive/MGDS
+hiya
+hm
+ho/SMDRYZ
+hoar
+hoard/SZGMDRJ
+hoarder/M
+hoarding/M
+hoarfrost/M
+hoariness/M
+hoarse/YTRP
+hoarseness/M
+hoary/TRP
+hoax/MDRSZG
+hoaxer/M
+hob/SM
+hobbit/S
+hobble/MZGDRS
+hobbler/M
+hobby/SM
+hobbyhorse/MS
+hobbyist/SM
+hobgoblin/MS
+hobnail/SGMD
+hobnob/S
+hobnobbed
+hobnobbing
+hobo/MS
+hock/MDSG
+hockey/M
+hockshop/MS
+hod/SM
+hodgepodge/SM
+hoe/SM
+hoecake/SM
+hoedown/SM
+hoeing
+hoer/M
+hog/SM
+hogan/SM
+hogback/SM
+hogged
+hogger
+hogging
+hoggish/Y
+hogshead/SM
+hogtie/DS
+hogtying
+hogwash/M
+hoick/SGD
+hoist/SGMD
+hoke/GDS
+hokey
+hokier
+hokiest
+hokum/M
+hold/MRBJSZG
+holdall/S
+holder/M
+holding/M
+holdout/SM
+holdover/SM
+holdup/MS
+hole/MGDS
+holey
+holiday/SMDG
+holidaymaker/S
+holiness/UM
+holism
+holistic
+holistically
+holler/MDGS
+hollow/MDRYPSTG
+hollowness/M
+holly/SM
+hollyhock/MS
+holmium/M
+holocaust/SM
+hologram/MS
+holograph/M
+holographic
+holographs
+holography/M
+hols
+holster/SMDG
+holy/URPT
+homage/MS
+hombre/MS
+homburg/SM
+home/MYZGDRS
+homebody/SM
+homeboy/SM
+homecoming/SM
+homegrown
+homeland/MS
+homeless/MP
+homelessness/M
+homelike
+homeliness/M
+homely/PRT
+homemade
+homemaker/SM
+homemaking/M
+homeomorphism/S
+homeopath/M
+homeopathic
+homeopaths
+homeopathy/M
+homeostasis/M
+homeostatic
+homeowner/MS
+homepage/MS
+homer/GMD
+homeroom/MS
+homeschooling/M
+homesick/P
+homesickness/M
+homespun/M
+homestead/SMDRZG
+homesteader/M
+homestretch/MS
+hometown/MS
+homeward
+homework/MRZG
+homey/SMP
+homeyness/M
+homicidal
+homicide/MS
+homier
+homiest
+homiletic
+homily/SM
+hominid/SM
+hominy/M
+homo/MS
+homoerotic
+homogenates
+homogeneity/M
+homogeneous/Y
+homogenization/M
+homogenize/DSG
+homograph/M
+homographs
+homological
+homologous
+homologue
+homology/S
+homomorphism/S
+homonym/SM
+homophobes
+homophobia/M
+homophobic
+homophone/MS
+homophony
+homosexual/SMY
+homosexuality/M
+homotopy
+homozygous
+homunculus
+hon/SZTGMDR
+honcho/MS
+hone/MS
+honer/M
+honest/EYT
+honester
+honesty/EM
+honey/SGMD
+honeybee/SM
+honeycomb/GMDS
+honeydew/SM
+honeylocust/M
+honeymoon/MDRSZG
+honeymooner/M
+honeypot/S
+honeysuckle/SM
+honk/MDRSZG
+honker/M
+honky/SM
+honor/ESGMDB
+honorableness/M
+honorably/E
+honorarily
+honorarium/MS
+honorary
+honored/U
+honoree/SM
+honorer/SM
+honorific/MS
+hooch/M
+hood/MDSG
+hoodlum/SM
+hoodoo/MDSG
+hoodwink/DGS
+hooey/M
+hoof/MDRSZG
+hook's
+hook/UDSG
+hookah/M
+hookahs
+hooker/MS
+hookup/MS
+hookworm/MS
+hooky/M
+hooligan/MS
+hooliganism/M
+hoop/MDSG
+hoopla/M
+hooray/MDSG
+hoosegow/SM
+hoot/MDRSZG
+hootenanny/SM
+hooter/M
+hoover/DSG
+hooves
+hop/SGMD
+hope/MS
+hoped/U
+hopeful/PSMY
+hopefulness/M
+hopeless/PY
+hopelessness/M
+hopped
+hopper/MS
+hopping
+hopscotch/GMDS
+hora/MS
+horde/DSMG
+horehound/SM
+horizon/SM
+horizontal/MYS
+hormonal/Y
+hormone/SM
+horn/MDS
+hornbeam
+hornblende/M
+hornet/MS
+hornless
+hornlike
+hornpipe/MS
+horny/TR
+horologic
+horological
+horologist/MS
+horology/M
+horoscope/SM
+horrendous/Y
+horrible/P
+horribleness/M
+horribly
+horrid/Y
+horrific
+horrifically
+horrify/DSG
+horrifying/Y
+horror/MS
+horse's
+horse/UDSG
+horseback/M
+horsebox/S
+horseflesh/M
+horsefly/SM
+horsehair/M
+horsehide/M
+horselaugh/M
+horselaughs
+horseless
+horseman/M
+horsemanship/M
+horsemen
+horseplay/M
+horsepower/M
+horseradish/MS
+horseshit/!
+horseshoe/DSM
+horseshoeing
+horsetail/SM
+horsetrading
+horsewhip/SM
+horsewhipped
+horsewhipping
+horsewoman/M
+horsewomen
+horsey
+horsier
+horsiest
+hortatory
+horticultural
+horticulturalist/S
+horticulture/M
+horticulturist/MS
+hosanna/SM
+hose/MGDS
+hosepipe/S
+hosier/MS
+hosiery/M
+hosp
+hospice/MS
+hospitable/I
+hospitably/I
+hospital/SM
+hospitality/M
+hospitalization/MS
+hospitalize/GDS
+host/MDSG
+hostage/MS
+hostel/ZGMDRS
+hosteler/M
+hostelry/SM
+hostess/MDSG
+hostile/MYS
+hostilities/M
+hostility/SM
+hostler/MS
+hot/SYP
+hotbed/MS
+hotblooded
+hotbox/MS
+hotcake/SM
+hotel/SM
+hotelier/MS
+hotfoot/MDGS
+hothead/DSM
+hotheaded/YP
+hotheadedness/M
+hothouse/SM
+hotlink/S
+hotness/M
+hotplate/SM
+hotpot/S
+hots/M
+hotshot/MS
+hotted
+hotter
+hottest
+hotting
+hound/SGMD
+hour/MYS
+hourglass/MS
+houri/SM
+house's
+house/ADSG
+houseboat/SM
+housebound
+houseboy/SM
+housebreak/RSZG
+housebreaker/M
+housebreaking/M
+housebroke
+housebroken
+housebuilding
+houseclean/DGS
+housecleaning/M
+housecoat/SM
+housefly/SM
+houseful/SM
+household/SMRZ
+householder/M
+househusband/MS
+housekeeper/MS
+housekeeping/M
+houselights/M
+housemaid/SM
+houseman/M
+housemaster/S
+housemate/S
+housemen
+housemistress/S
+housemother/SM
+housemoving
+houseparent/SM
+houseplant/MS
+houseproud
+houseroom
+housetop/SM
+housewares/M
+housewarming/MS
+housewife/MY
+housewives
+housework/M
+housing/MS
+hove
+hovel/SM
+hover/SGDR
+hovercraft/MS
+how/SM
+howbeit
+howdah/M
+howdahs
+howdy
+however
+howitzer/SM
+howl/MDRSZG
+howler/M
+howsoever
+hoyden/MS
+hoydenish
+hp
+hr/S
+ht
+huarache/SM
+hub/SM
+hubbub/SM
+hubby/SM
+hubcap/SM
+hubris/M
+huckleberry/SM
+huckster/SGMD
+hucksterism/M
+huddle/DSMG
+hue/DSM
+huff/MDSG
+huffily
+huffiness/M
+huffy/PRT
+hug/STMR
+huge/YP
+hugeness/M
+hugged
+hugging
+huh
+hula/MS
+hulk/MSG
+hull/MDRSZG
+hullabaloo/SM
+huller/M
+hum/SM
+human/SMRYTP
+humane/PY
+humaneness/M
+humanism/M
+humanist/SM
+humanistic
+humanitarian/SM
+humanitarianism/M
+humanities/M
+humanity/ISM
+humanization/CM
+humanize/CDSG
+humanizer/SM
+humankind/M
+humanness/M
+humanoid/SM
+humble/DRSZTGJP
+humbleness/M
+humbler/M
+humbly
+humbug/SM
+humbugged
+humbugging
+humdinger/MS
+humdrum/M
+humeral
+humeri
+humerus/M
+humid/Y
+humidification/M
+humidifier/CM
+humidify/CZGDRS
+humidity/M
+humidor/SM
+humiliate/XDSGN
+humiliating/Y
+humiliation/M
+humility/M
+hummable
+hummed
+hummer/SM
+humming
+hummingbird/SM
+hummock/SM
+hummocky
+hummus/M
+humongous
+humor/SMDG
+humorist/MS
+humorless/PY
+humorlessness/M
+humorous/PY
+humorousness/M
+hump/MDSG
+humpback/MDS
+humph/DG
+humphs
+humus/M
+hunch/MDSG
+hunchback/SMD
+hundred/SMH
+hundredfold
+hundredth/M
+hundredths
+hundredweight/MS
+hung
+hunger/SMDG
+hungover
+hungrily
+hungriness/M
+hungry/PRT
+hunk/MRSZ
+hunker/DG
+hunky/RT
+hunt/MDRSZG
+hunter/M
+hunting/M
+huntress/MS
+huntsman/M
+huntsmen
+hurdle/DRSMZG
+hurdler/M
+hurdling/M
+hurl/MDRSZG
+hurler/M
+hurling/M
+hurrah's
+hurray/GSD
+hurricane/MS
+hurried/UY
+hurry/DSMG
+hurt/MSG
+hurtful/YP
+hurtfulness/M
+hurtle/DSG
+husband/GMDS
+husbandman/M
+husbandmen
+husbandry/M
+hush/MDSG
+husk/MDRSZG
+husker/M
+huskily
+huskiness/M
+husky/PRSMT
+hussar/SM
+hussy/SM
+hustings/M
+hustle/DRSMZG
+hustler/M
+hut/SM
+hutch/MS
+huzzah/MDG
+huzzahs
+hwy
+hyacinth/M
+hyacinths
+hybrid/SM
+hybridism/M
+hybridization/M
+hybridize/DSG
+hydra/SM
+hydrangea/SM
+hydrant/MS
+hydrate's
+hydrate/CGNDS
+hydration/CM
+hydraulic/S
+hydraulically
+hydraulics/M
+hydrazine
+hydride
+hydro/M
+hydrocarbon/SM
+hydrocephalus/M
+hydrochloric
+hydrochloride
+hydrodynamic/S
+hydrodynamical
+hydrodynamics/M
+hydroelectric
+hydroelectrically
+hydroelectricity/M
+hydrofluoric
+hydrofoil/MS
+hydrogen/M
+hydrogenate/CDSGN
+hydrogenation/M
+hydrogenous
+hydrological
+hydrologist/MS
+hydrology/M
+hydrolysis/M
+hydrolyze/DSG
+hydromagnetic
+hydromechanics
+hydrometer/SM
+hydrometry/M
+hydrophobia/M
+hydrophobic
+hydrophone/MS
+hydroplane/MGDS
+hydroponic/S
+hydroponically
+hydroponics/M
+hydrosphere/M
+hydrostatic/S
+hydrotherapy/M
+hydrothermal
+hydrous
+hydroxide/SM
+hyena/SM
+hygiene/M
+hygienic/U
+hygienically
+hygienist/MS
+hygrometer/SM
+hygroscopic
+hying
+hymen/SM
+hymeneal
+hymn/MDSG
+hymnal/MS
+hymnbook/SM
+hype/MGDRS
+hyperactive
+hyperactivity/M
+hyperbola/SM
+hyperbole/M
+hyperbolic
+hyperboloid/S
+hypercritical/Y
+hypercube/S
+hyperfine
+hyperglycemia/M
+hyperinflation
+hyperlink/SM
+hypermarket/S
+hypermedia/M
+hyperplane/S
+hypersensitive/P
+hypersensitiveness/M
+hypersensitivity/SM
+hypersonic
+hyperspace/S
+hypersphere
+hypertension/M
+hypertensive/MS
+hypertext/M
+hyperthyroid/M
+hyperthyroidism/M
+hypertrophy/GDSM
+hyperventilate/GNDS
+hyperventilation/M
+hyphen/MDSG
+hyphenate/XDSMGN
+hyphenated/U
+hyphenation/M
+hypnoses
+hypnosis/M
+hypnotherapist/S
+hypnotherapy/M
+hypnotic/SM
+hypnotically
+hypnotism/M
+hypnotist/MS
+hypnotize/GDS
+hypo/MS
+hypoallergenic
+hypocaust
+hypochondria/M
+hypochondriac/MS
+hypocrisy/SM
+hypocrite/MS
+hypocritical/Y
+hypodermic/SM
+hypoglycemia/M
+hypoglycemic/SM
+hypotenuse/SM
+hypothalami
+hypothalamus/M
+hypothermia/M
+hypotheses
+hypothesis/M
+hypothesize/GDRS
+hypothetical/Y
+hypothyroid/M
+hypothyroidism/M
+hypoxia
+hyssop/M
+hysterectomy/SM
+hysteresis
+hysteria/M
+hysteric/SM
+hysterical/Y
+hysterics/M
+i/US
+iamb/MS
+iambi
+iambic/SM
+iambus/MS
+iatrogenic
+ibex/MS
+ibid
+ibidem
+ibis/MS
+ibuprofen/M
+ice's
+ice/CDSG
+iceberg/SM
+iceboat/SM
+icebound
+icebox/MS
+icebreaker/MS
+icecap/SM
+iceman/M
+icemen
+icepack
+icepick/S
+ichneumon
+ichthyologist/MS
+ichthyology/M
+icicle/SM
+icily
+iciness/M
+icing/SM
+icky/RT
+icon/MS
+iconic
+iconoclasm/M
+iconoclast/MS
+iconoclastic
+iconographic
+iconography/M
+icosahedra
+icosahedral
+icosahedron
+ictus/M
+icy/TPR
+id/SMY
+idea/MS
+ideal/SMY
+idealism/M
+idealist/SM
+idealistic
+idealistically
+idealization/SM
+idealize/DSG
+idem
+idempotent
+identical/Y
+identifiable/U
+identifiably
+identification/M
+identified/U
+identify/ZGNDRSX
+identikit/S
+identity/SM
+ideogram/SM
+ideograph/M
+ideographic
+ideographs
+ideological/Y
+ideologist/MS
+ideologue/MS
+ideology/SM
+ides/M
+idiocy/SM
+idiolect
+idiom/SM
+idiomatic/U
+idiomatically
+idiopathic
+idiosyncrasy/SM
+idiosyncratic
+idiosyncratically
+idiot/SM
+idiotic
+idiotically
+idle/MZTGDRSP
+idleness/M
+idler/M
+idol/MS
+idolater/SM
+idolatress/MS
+idolatrous
+idolatry/M
+idolization/M
+idolize/GDS
+idyll/SM
+idyllic
+idyllically
+if/SM
+iffiness/M
+iffy/RTP
+igloo/SM
+igneous
+ignitable
+ignite/AGDS
+ignition/MS
+ignoble
+ignobly
+ignominious/Y
+ignominy/SM
+ignoramus/MS
+ignorance/M
+ignorant/Y
+ignore/GDSB
+iguana/MS
+ii
+iii
+ilea
+ileitis/M
+ileum/M
+ilia
+ilium/M
+ilk/SM
+ill/SMP
+illegal/MYS
+illegality/SM
+illegibility/M
+illegible
+illegibly
+illegitimacy/M
+illegitimate/Y
+illiberal/Y
+illiberality/M
+illicit/YP
+illicitness/M
+illimitable
+illiquid
+illiteracy/M
+illiterate/MYS
+illness/MS
+illogical/Y
+illogicality/M
+illuminant
+illuminate/XDSGN
+illuminating/Y
+illumination/M
+illumine/DSBG
+illus/V
+illusion/EMS
+illusionist/SM
+illusory
+illustrate/GNVDSX
+illustrated/U
+illustration/M
+illustrative/Y
+illustrator/SM
+illustrious/PY
+illustriousness/M
+ilmenite
+image/DSMG
+imagery/M
+imaginable/U
+imaginably/U
+imaginary
+imagination/SM
+imaginative/UY
+imagine/DSBJG
+imagined/U
+imago/M
+imagoes
+imam/MS
+imbalance/DSM
+imbecile/MS
+imbecilic
+imbecility/SM
+imbibe/ZGDRS
+imbiber/M
+imbrication/M
+imbroglio/SM
+imbue/DSG
+imitable/I
+imitate/DSGNVX
+imitation/M
+imitative/PY
+imitativeness/M
+imitator/SM
+immaculate/PY
+immaculateness/M
+immanence/M
+immanency/M
+immanent/Y
+immaterial/YP
+immateriality/M
+immaterialness/M
+immature/Y
+immaturity/M
+immeasurable
+immeasurably
+immediacies/M
+immediacy/SM
+immediate/YP
+immediateness/M
+immemorial/Y
+immense/RYTP
+immensity/SM
+immerse/XDSGN
+immersible
+immersion/M
+immigrant/SM
+immigrate/DSGNX
+immigration/M
+imminence/M
+imminent/Y
+immiscible
+immobile
+immobilisers
+immobility/M
+immobilization/M
+immobilize/ZGDRS
+immoderate/Y
+immodest/Y
+immodesty/M
+immolate/DSGN
+immolation/M
+immoral/Y
+immorality/SM
+immortal/MYS
+immortality/M
+immortalize/GDS
+immovability/M
+immovable
+immovably
+immune
+immunity/SM
+immunization/MS
+immunize/GDS
+immunoassay
+immunodeficiency/M
+immunodeficient
+immunologic
+immunological/Y
+immunologist/MS
+immunology/M
+immure/DSG
+immutability/M
+immutable
+immutably
+imp/SMR
+impact/SMDG
+impaction
+impair/SDGL
+impaired/U
+impairment/SM
+impala/SM
+impale/DRSGL
+impalement/M
+impalpable
+impalpably
+impanel/SDG
+impart/SDG
+impartial/Y
+impartiality/M
+impassably
+impasse/BSMV
+impassibility/M
+impassible
+impassibly
+impassioned
+impassive/PY
+impassiveness/M
+impassivity/M
+impasto/M
+impatience/MS
+impatiens/M
+impatient/Y
+impeach/ZGBLDRS
+impeachable/U
+impeacher/M
+impeachment/SM
+impeccability/M
+impeccable
+impeccably
+impecunious/PY
+impecuniousness/M
+impedance/M
+impede/DSG
+impeded/U
+impediment/MS
+impedimenta/M
+impel/S
+impelled
+impeller/MS
+impelling
+impend/SDG
+impenetrability/M
+impenetrable
+impenetrably
+impenitence/M
+impenitent/Y
+imperative/MYS
+imperceptibility/M
+imperceptible
+imperceptibly
+imperceptive
+imperf
+imperfect/SPMY
+imperfection/SM
+imperfectness/M
+imperial/MYS
+imperialism/M
+imperialist/SM
+imperialistic
+imperialistically
+imperil/GSLD
+imperilment/M
+imperious/PY
+imperiousness/M
+imperishable
+imperishably
+impermanence/M
+impermanent/Y
+impermeability/M
+impermeable
+impermeably
+impermissible
+impersonal/Y
+impersonality
+impersonate/XDSGN
+impersonation/M
+impersonator/MS
+impertinence/MS
+impertinent/Y
+imperturbability/M
+imperturbable
+imperturbably
+impervious/Y
+impetigo/M
+impetuosity/M
+impetuous/YP
+impetuousness/M
+impetus/MS
+impiety/SM
+impinge/LDSG
+impingement/M
+impious/PY
+impiousness/M
+impish/YP
+impishness/M
+implacability/M
+implacable
+implacably
+implant/BSGMD
+implantation/M
+implausibility/SM
+implausible
+implausibly
+implement/BZGMDRS
+implementable/U
+implementation/SM
+implemented/UA
+implementing/A
+implicate/DSG
+implication/M
+implicit/PY
+implicitness/M
+implied/Y
+implode/DSG
+implore/DSG
+imploring/Y
+implosion/MS
+implosive
+imply/XDSGN
+impolite/YP
+impoliteness/MS
+impolitic
+imponderable/SM
+import/ZGBSMDR
+importance/M
+important/Y
+importation/SM
+importer/M
+importing/A
+importunate/Y
+importune/GDS
+importunity/M
+imposable
+impose/ADSG
+imposer/MS
+imposing/U
+imposingly
+imposition/SM
+impossibility/SM
+impossible/S
+impossibly
+impost/SM
+impostor/SM
+imposture/MS
+impotence/M
+impotency/M
+impotent/Y
+impound/DGS
+impoverish/LGDS
+impoverishment/M
+impracticability
+impracticable
+impracticably
+impractical/Y
+impracticality/SM
+imprecate/DSXGN
+imprecation/M
+imprecise/PYN
+impreciseness/M
+imprecision/M
+impregnability/M
+impregnable
+impregnably
+impregnate/GNDS
+impregnation/M
+impresario/SM
+impress/MDSGV
+impressed/U
+impressibility/M
+impressible
+impression/MSB
+impressionability/M
+impressionism/M
+impressionist/SM
+impressionistic
+impressive/YP
+impressiveness/M
+imprimatur/MS
+imprint/MDRZGS
+imprinter/M
+imprison/SDGL
+imprisonment/MS
+improbability/SM
+improbable
+improbably
+impromptu/SM
+improper/Y
+impropriety/SM
+improve/GBDRSL
+improved/U
+improvement/SM
+improvidence/M
+improvident/Y
+improvisation/SM
+improvisational
+improvisatory
+improvise/ZGDRS
+improviser/M
+imprudence/M
+imprudent/Y
+impudence/M
+impudent/Y
+impugn/ZGBSDR
+impugner/M
+impulse/MGNVDS
+impulsion/M
+impulsive/PY
+impulsiveness/M
+impunity/M
+impure/RYT
+impurity/SM
+imputation/SM
+impute/BDSG
+in/ASM
+inaction/M
+inactivity
+inadequacy/S
+inadvertence/M
+inadvertent/Y
+inalienability/M
+inalienably
+inamorata/SM
+inane/RYT
+inanimate/PY
+inanimateness/M
+inanity/SM
+inapplicability
+inappropriate/Y
+inarticulate/Y
+inasmuch
+inaudible
+inaugural/SM
+inaugurate/GNDSX
+inauguration/M
+inboard/MS
+inbound
+inbreed/S
+inc/TGD
+incalculably
+incandescence/M
+incandescent/Y
+incant
+incantation/SM
+incantatory
+incapable
+incapacitate/DSGN
+incarcerate/GNXDS
+incarceration/M
+incarnadine/GDS
+incarnate/AXGNDS
+incarnation/AM
+incendiary/SM
+incense/MGDS
+incentive's
+incentive/ES
+inception/SM
+incessant/Y
+incest/MS
+incestuous/PY
+incestuousness/M
+inch/MDSG
+inchoate
+inchworm/SM
+incidence/SM
+incident/SM
+incidental/MYS
+incinerate/DSGN
+incineration/M
+incinerator/SM
+incipience/M
+incipient/Y
+incise/XGNVDS
+incision/M
+incisive/YP
+incisiveness/M
+incisor/MS
+incitement/MS
+inciter/MS
+incl
+inclement
+inclination/EM
+inclinations
+incline's
+incline/EGDS
+include/GDS
+inclusion/MS
+inclusive/YP
+inclusiveness/M
+incognito/MS
+incoherency
+incombustible
+incommode/GD
+incommodious
+incommunicado
+incompetent/SM
+incomplete/Y
+inconceivability/M
+incongruous/PY
+incongruousness/M
+inconsolably
+inconstant/Y
+incontestability/M
+incontestably
+incontinent/Y
+incontrovertibly
+inconvenience/DG
+incorporable
+incorporate/AGNDS
+incorporated/U
+incorporation/AM
+incorporeal
+incorrect/Y
+incorrigibility/M
+incorrigible
+incorrigibly
+incorruptibly
+increasing/Y
+increment/SMDG
+incremental/Y
+incrementation
+incriminate/GNDS
+incrimination/M
+incriminatory
+incrustation/MS
+incubate/GNDS
+incubation/M
+incubator/SM
+incubus/MS
+inculcate/DSGN
+inculcation/M
+inculpate/DSG
+incumbency/SM
+incumbent/SM
+incunabula
+incunabulum/M
+incur/SB
+incurable/MS
+incurably
+incurious
+incurred
+incurring
+incursion/MS
+ind
+indebted/P
+indebtedness/M
+indecent/T
+indeclinable
+indeed
+indefatigable
+indefatigably
+indefeasible
+indefeasibly
+indelible
+indelibly
+indemnification/M
+indemnify/XGNDS
+indemnity/SM
+indentation/SM
+indention/M
+indenture/DG
+indescribably
+indestructibly
+indeterminably
+indeterminacy/M
+indeterminate/Y
+index/ZGMDRS
+indexation/SM
+indexer/M
+indicant/S
+indicate/XDSGNV
+indication/M
+indicative/SMY
+indicator/MS
+indict/GDSBL
+indictment/SM
+indie/S
+indifference/M
+indigence/M
+indigenous
+indigent/SMY
+indignant/Y
+indignation/M
+indigo/M
+indirect/Y
+indiscipline
+indiscreet/Y
+indiscretion/S
+indiscriminate/Y
+indispensability/M
+indispensable/MS
+indispensably
+indispose/D
+indissolubility
+indissolubly
+indite/GDS
+indium/M
+individual/MYS
+individualism/M
+individualist/SM
+individualistic
+individualistically
+individuality/M
+individualization/M
+individualize/DSG
+individuate/DSGN
+individuation/M
+indivisibly
+indoctrinate/DSXGN
+indoctrination/M
+indoctrinator/S
+indolence/M
+indolent/Y
+indomitable
+indomitably
+indubitable
+indubitably
+induce/DRSZGL
+inducement/SM
+inducer/M
+inducible
+inductance/M
+inductee/SM
+induction/MS
+inductive/Y
+inductor/S
+indulge/DRSG
+indulgence/MS
+indulgent/Y
+industrial/Y
+industrialism/M
+industrialist/MS
+industrialization/M
+industrialize/GDS
+industrious/YP
+industriousness/M
+industry/SM
+indwell/SG
+inebriate/MGNDS
+inebriation/M
+inedible
+ineffability/M
+ineffable
+ineffably
+ineffectual/P
+inelastic
+ineligible/MS
+ineluctable
+ineluctably
+inept/YP
+ineptitude/M
+ineptness/M
+ineradicably
+inert/YP
+inertia/M
+inertial
+inertness/M
+inescapable
+inescapably
+inestimably
+inevitability/M
+inevitable/M
+inevitably
+inexact/Y
+inexactitude/S
+inexhaustibly
+inexorability
+inexorable
+inexorably
+inexpedient
+inexpert/Y
+inexpiable
+inexplicably
+inexpressibility
+inexpressibly
+inexpressive
+inextricably
+inf/ZT
+infallible
+infamy/SM
+infancy/M
+infant/MS
+infanticide/SM
+infantile
+infantry/SM
+infantryman/M
+infantrymen
+infarct/MS
+infarction/M
+infatuate/DSXGN
+infatuation/M
+infeasibility
+infect/AESDVG
+infected/U
+infection/ASM
+infectious/PY
+infectiousness/M
+infelicitous
+inference/SM
+inferential/Y
+inferior/MS
+inferiority/M
+infernal/Y
+inferno/MS
+inferred
+inferring
+infest/GDS
+infestation/SM
+infidel/MS
+infidelity/S
+infiltrate/X
+infiltrator/SM
+infinite/MYV
+infinitesimal/SMY
+infinitival
+infinitive/SM
+infinitude/M
+infinity/SM
+infirm
+infirmary/SM
+infirmity/SM
+infix
+inflame/DSG
+inflammable
+inflammation/SM
+inflammatory
+inflatable/SM
+inflate/DSGNB
+inflation/EM
+inflationary
+inflect/SDG
+inflection/MS
+inflectional
+inflict/SDRGV
+infliction/MS
+influence/MGDS
+influenced/U
+influential/Y
+influenza/M
+influx/MS
+info/M
+infomercial/MS
+informal/Y
+informant/SM
+informatics
+information/EM
+informational
+informative/UY
+informativeness/M
+informatory
+informed/U
+infotainment/M
+infra
+infrared/M
+infrasonic
+infrastructural
+infrastructure/MS
+infrequence/M
+infrequent/Y
+infringement/MS
+infuriate/GDS
+infuriating/Y
+infuser/SM
+ingenious/PY
+ingeniousness/M
+ingenue/SM
+ingenuity/M
+ingenuous/EY
+ingenuousness/M
+ingest/SDG
+ingestion/M
+inglenook/SM
+ingoing
+ingot/SM
+ingrain/G
+ingrate/SM
+ingratiate/GNDS
+ingratiating/Y
+ingratiation/M
+ingredient/MS
+ingress/MS
+ingression
+inguinal
+inhabit/DG
+inhabitable/U
+inhabitant/SM
+inhabited/U
+inhalant/SM
+inhalation/SM
+inhalator/MS
+inhaler/SM
+inharmonious
+inhere/DSG
+inherent/Y
+inherit/EGSD
+inheritance/EM
+inheritances
+inheritor/SM
+inhibit/GSD
+inhibition/SM
+inhibitor/SM
+inhibitory
+inhomogeneity/S
+inhomogeneous
+inhuman/Y
+inhumane/Y
+inimical/Y
+inimitably
+iniquitous/Y
+iniquity/SM
+initial/SGMDY
+initialization/S
+initialize/ADG
+initialized/U
+initializes
+initiate/XMGNVDS
+initiated/U
+initiation/M
+initiative/SM
+initiator/MS
+initiatory
+inject/SDG
+injection/SM
+injector/SM
+injure/DRSZG
+injured/U
+injurer/M
+injurious/Y
+ink/MD
+inkblot/SM
+inkiness/M
+inkling/SM
+inkstand/SM
+inkwell/MS
+inky/RTP
+inland/M
+inline
+inmate/SM
+inmost
+inn/SGMRJ
+innards/M
+innate/PY
+innateness/M
+innermost
+innersole/SM
+innerspring
+innervate/GNDS
+innervation/M
+inning/M
+innit
+innkeeper/MS
+innocence/M
+innocent/MRYST
+innocuous/PY
+innocuousness/M
+innovate/XDSGNV
+innovation/M
+innovator/MS
+innovatory
+innuendo/SM
+innumerably
+innumerate
+inoculate/AGDS
+inoculation/MS
+inoperative
+inordinate/Y
+inorganic
+inquire/ZGDR
+inquirer/M
+inquiring/Y
+inquiry/SM
+inquisition/SM
+inquisitional
+inquisitive/YP
+inquisitiveness/M
+inquisitor/MS
+inquisitorial/Y
+inrush/MS
+insane/T
+insanity/S
+insatiability/M
+insatiably
+inscriber/SM
+inscription/SM
+inscrutability/M
+inscrutable/P
+inscrutableness/M
+inscrutably
+inseam/SM
+insecticidal
+insecticide/SM
+insectivore/MS
+insectivorous
+insecure/Y
+inseminate/GNDS
+insemination/M
+insensate
+insensible
+insensitive/Y
+inseparable/SM
+insert's
+insert/AGSD
+insertion/AM
+insertions
+insetting
+inshore
+inside/RSMZ
+insider/M
+insidious/PY
+insidiousness/M
+insight/MS
+insightful
+insignia/SM
+insinuate/GNVXDS
+insinuating/Y
+insinuation/M
+insinuator/SM
+insipid/PY
+insipidity/M
+insist/SGD
+insistence/M
+insistent/Y
+insisting/Y
+insofar
+insole/SM
+insolence/M
+insolent/Y
+insoluble
+insolubly
+insolvency/S
+insomnia/M
+insomniac/SM
+insomuch
+insouciance/M
+insouciant
+inspect/AGDS
+inspection/SM
+inspector/MS
+inspectorate/SM
+inspiration/SM
+inspirational
+inspired/U
+inspiring/U
+inst
+instability/S
+install/BLZR
+installation/SM
+installer/M
+installment/MS
+instance/GD
+instant/MRYS
+instantaneous/Y
+instantiate/GNDSX
+instate/AGDS
+instead
+instigate/DSGN
+instigation/M
+instigator/SM
+instillation/M
+instinct/VMS
+instinctive/Y
+instinctual
+institute/MZGNXDRS
+instituter/M
+institution/M
+institutional/Y
+institutionalism
+institutionalization/M
+institutionalize/GDS
+instr
+instruct/SDGV
+instructed/U
+instruction/SM
+instructional
+instructive/Y
+instructor/MS
+instrument/GMDS
+instrumental/SMY
+instrumentalist/MS
+instrumentality/M
+instrumentation/M
+insubordinate
+insufferable
+insufferably
+insular
+insularity/M
+insulate/GNDS
+insulated/U
+insulation/M
+insulator/MS
+insulin/M
+insult/SMDRG
+insulting/Y
+insuperable
+insuperably
+insurance/SM
+insure/DRSZGB
+insured/SM
+insurer/M
+insurgence/SM
+insurgency/SM
+insurgent/MS
+insurmountably
+insurrection/MS
+insurrectionist/MS
+int
+intact
+intaglio/MS
+integer/MS
+integrability
+integrable
+integral/SMY
+integrand/S
+integrate/EAVNGSD
+integration/AEM
+integrations
+integrator/S
+integrity/M
+integument/SM
+intellect/MS
+intellectual/SMY
+intellectualism/M
+intellectuality
+intellectualize/GDS
+intelligence/MS
+intelligent/Y
+intelligentsia/M
+intelligibility/M
+intelligible/U
+intelligibly/U
+intended/SM
+intense/YTVR
+intensification/M
+intensifier/M
+intensify/ZGDRSN
+intensity/S
+intensive/PMYS
+intensiveness/M
+intent/SMYP
+intention/MDS
+intentional/UY
+intentionality
+intentness/M
+inter/ESL
+interact/SGVD
+interaction/SM
+interactive/PY
+interactivity
+interbank
+interbred
+interbreed/SG
+intercede/GDS
+intercept/GMDS
+interception/MS
+interceptor/SM
+intercession/MS
+intercessor/SM
+intercessory
+interchange/DSMG
+interchangeability
+interchangeable
+interchangeably
+intercity
+intercollegiate
+intercom/SM
+intercommunicate/GNDS
+intercommunication/M
+interconnect/GSD
+interconnected/P
+interconnection/SM
+intercontinental
+interconversion
+intercourse/M
+intercultural
+interdenominational
+interdepartmental
+interdependence/M
+interdependency
+interdependent/Y
+interdict/GMDS
+interdiction/M
+interdisciplinary
+interest/ESMD
+interested/UEY
+interesting/Y
+interface/MGDS
+interfaith
+interfere/GDRS
+interference/MS
+interferometer/S
+interferometric
+interferometry
+interferon/M
+interfile/GDS
+intergalactic
+interglacial
+intergovernmental
+interim/M
+interior/SM
+interj
+interject/DGS
+interjection/MS
+interjectional
+interlace/GDS
+interlard/GDS
+interleave/GDS
+interleukin/M
+interline/JGDS
+interlinear
+interlingual
+interlining/M
+interlink/GDS
+interlock/GMDS
+interlocutor/MS
+interlocutory
+interlope/ZGDRS
+interloper/M
+interlude/MGDS
+intermarriage/MS
+intermarry/DSG
+intermediary/SM
+intermediate/SMY
+interment/EM
+interments
+intermezzi
+intermezzo/MS
+interminably
+intermingle/DSG
+intermission/MS
+intermittent/Y
+intermix/GDS
+intermolecular
+intern/GDL
+internal/SY
+internalization/M
+internalize/DSG
+international/SMY
+internationalism/M
+internationalist/MS
+internationalization
+internationalize/GDS
+internecine
+internee/SM
+internet
+internist/MS
+internment/MS
+internship/MS
+internuclear
+interocular
+interoffice
+interoperability
+interoperable
+interpenetrate/GNDS
+interpersonal
+interplanetary
+interplay/MS
+interpolate/BXGNDS
+interpolation/M
+interpose/GDS
+interposition/M
+interpret/AGVDS
+interpretable/U
+interpretation/ASM
+interpretative
+interpreted/U
+interpreter/MS
+interpretive/Y
+interracial
+interred/E
+interregnum/MS
+interrelate/XGNDS
+interrelated/P
+interrelation/M
+interrelationship/MS
+interring/E
+interrogate/GNVDSX
+interrogation/M
+interrogative/MYS
+interrogator/SM
+interrogatory/SM
+interrupt/ZGMDRS
+interrupter/M
+interruptibility
+interruption/MS
+interscholastic
+intersect/GDS
+intersection/SM
+intersession/MS
+intersperse/GNDS
+interspersion/M
+interstate/MS
+interstellar
+interstice/MS
+interstitial/Y
+intertidal
+intertwine/GDS
+interurban
+interval/SM
+intervene/GDS
+intervention/SM
+interventionism/M
+interventionist/SM
+interview/MDRZGS
+interviewee/MS
+interviewer/M
+intervocalic
+interwar
+interweave/SG
+interwove
+interwoven
+intestacy/M
+intestate
+intestinal
+intestine/MS
+intifada
+intimacy/SM
+intimate/MYGNDSX
+intimation/M
+intimidate/GNDS
+intimidating/Y
+intimidation/M
+intimidatory
+intonation/SM
+intonational
+intoxicant/MS
+intoxicate/GNDS
+intoxication/M
+intracellular
+intramural
+intramuscular
+intranet/S
+intransigence/M
+intransigent/SMY
+intrastate
+intrauterine
+intravenous/MSY
+intrepid/Y
+intrepidity/M
+intricacy/SM
+intricate/Y
+intrigue/DRSMZG
+intriguer/M
+intriguing/Y
+intrinsic
+intrinsically
+intro/SM
+introduce/AGDS
+introduction/ASM
+introductory
+introit/SM
+introspect/DGVS
+introspection/M
+introspective/Y
+introversion/M
+introvert/MDS
+intrude/DRSZG
+intruder/M
+intrusion/SM
+intrusive/YP
+intrusiveness/M
+intuit/SDGV
+intuition/S
+intuitionist
+intuitive/YP
+intuitiveness/M
+inundate/XDSGN
+inundation/M
+inure/DSG
+invade/DRSZG
+invader/M
+invalid/GMDYS
+invalidism/M
+invaluable
+invaluably
+invariance
+invasion/MS
+invasive
+invective/SM
+inveigh/GD
+inveighs
+inveigle/ZGDRS
+inveigler/M
+invent/ASGVD
+invented/U
+invention/AMS
+inventive/PY
+inventiveness/M
+inventor/MS
+inventory/GDSM
+inverse/SMY
+invert/SMDRZG
+invertible
+invest/ASDGL
+investigate/DSXGNV
+investigation/M
+investigator/MS
+investigatory
+investiture/MS
+investment/EAM
+investor/SM
+inveteracy/M
+inveterate
+invidious/PY
+invidiousness/M
+invigilate/GNDS
+invigilator/S
+invigorate/ADSG
+invigorating/Y
+invigoration/M
+invincibility/M
+invincibly
+inviolability/M
+inviolably
+inviolate
+invitation/MS
+invitational/MS
+invite/DSMG
+invited/U
+invitee/SM
+inviting/Y
+invoke/DRSZGB
+involuntariness/M
+involuntary/P
+involute/XN
+involution/M
+involve/LDSG
+involved/U
+involvement/SM
+inward/SY
+ioctl
+iodide/SM
+iodine/M
+iodize/DSG
+ion/USM
+ionic
+ionization/UM
+ionize/UDSG
+ionized/C
+ionizer/MS
+ionosphere/MS
+ionospheric
+iota/MS
+ipecac/SM
+irascibility/M
+irascible
+irascibly
+irate/RYTP
+irateness/M
+ire/M
+ireful
+irenic
+irides
+iridescence/M
+iridescent/Y
+iridium/M
+iris/MS
+irk/SGD
+irksome/YP
+irksomeness/M
+iron/MDSG
+ironclad/MS
+ironic
+ironical/Y
+ironing/M
+ironmonger/S
+ironmongery
+ironstone/M
+ironware/M
+ironwood/MS
+ironwork/MS
+irony/SM
+irradiate/DSGN
+irradiation/M
+irrational/SMY
+irrationality/SM
+irreclaimable
+irreconcilability/M
+irreconcilable
+irreconcilably
+irrecoverable
+irrecoverably
+irredeemable
+irredeemably
+irreducibility
+irreducible
+irreducibly
+irrefutable
+irrefutably
+irregardless
+irregular/MYS
+irregularity/SM
+irrelevance/SM
+irrelevancy/SM
+irrelevant/Y
+irreligious
+irremediable
+irremediably
+irremovable
+irreparable
+irreparably
+irreplaceable
+irrepressible
+irrepressibly
+irreproachable
+irreproachably
+irresistible
+irresistibly
+irresolute/PYN
+irresoluteness/M
+irresolution/M
+irresolvable
+irrespective/Y
+irresponsibility/M
+irresponsible
+irresponsibly
+irretrievable
+irretrievably
+irreverence/M
+irreverent/Y
+irreversibility
+irreversible
+irreversibly
+irrevocable
+irrevocably
+irrigable
+irrigate/DSGN
+irrigation/M
+irritability/M
+irritable
+irritably
+irritant/SM
+irritate/DSXGN
+irritated/Y
+irritating/Y
+irritation/M
+irrupt/DGVS
+irruption/SM
+isinglass/M
+isl
+island/SZMR
+islander/M
+isle/MS
+islet/SM
+ism/CM
+isms
+isn't
+isobar/MS
+isobaric
+isolate/DSMGN
+isolation/M
+isolationism/M
+isolationist/MS
+isolator/S
+isomer/MS
+isomeric
+isomerism/M
+isometric/S
+isometrically
+isometrics/M
+isomorphic
+isomorphism/S
+isoperimetrical
+isosceles
+isostatic
+isotherm/SM
+isothermal/Y
+isotonic
+isotope/SM
+isotopic
+isotropic
+isotropically
+isotropy
+issuable
+issuance/M
+issue/ADSMG
+issued/U
+issuer/MS
+isthmian
+isthmus/MS
+it'd
+it'll
+it/USM
+ital
+italic/SM
+italicization/M
+italicize/GDS
+italics/M
+itch/MDSG
+itchiness/M
+itchy/RPT
+item/MS
+itemization/M
+itemize/GDS
+iterate/AXGNVDS
+iteration/AM
+iterative/Y
+iterator/S
+itinerant/SM
+itinerary/SM
+itself
+iv/U
+ivory/SM
+ivy/DSM
+ix
+j/F
+jab/SM
+jabbed
+jabber/SMDRZG
+jabberer/M
+jabbing
+jabot/SM
+jacaranda/MS
+jack/MDGS
+jackal/SM
+jackass/MS
+jackboot/SMD
+jackdaw/MS
+jacket/SMD
+jackhammer/MS
+jackknife/MGDS
+jackknives
+jackpot/MS
+jackrabbit/SM
+jackstraw/MS
+jacquard/M
+jacuzzi
+jade/MGDS
+jaded/PY
+jadedness/M
+jadeite/M
+jag/SM
+jagged/TPRY
+jaggedness/M
+jaggies/S
+jaguar/SM
+jail/MDRZGS
+jailbird/SM
+jailbreak/SM
+jailer/M
+jailhouse/S
+jalapeno/MS
+jalopy/SM
+jalousie/MS
+jam/SM
+jamb/MS
+jambalaya/M
+jamboree/MS
+jammed/U
+jamming/U
+jammy/RT
+jangle/DRSMZG
+jangler/M
+jangly
+janitor/SM
+janitorial
+japan/SM
+japanned
+japanning
+jape/MGDS
+jar/SM
+jardiniere/SM
+jarful/MS
+jargon/M
+jarred
+jarring/Y
+jasmine/SM
+jasper/M
+jato/MS
+jaundice/DSMG
+jaundiced/U
+jaunt/SGMD
+jauntily
+jauntiness/M
+jaunty/RPT
+java/M
+javelin/SM
+jaw/SGMD
+jawbone/DSMG
+jawbreaker/SM
+jawline/S
+jay/SM
+jaybird/SM
+jaywalk/DRSZG
+jaywalker/M
+jaywalking/M
+jazz/MDSG
+jazzy/TR
+jct
+jealous/Y
+jealousy/SM
+jean/MS
+jeans/M
+jeep/MS
+jeer/MDSG
+jeering/MY
+jeez
+jejuna
+jejune
+jejunum/M
+jell/DSG
+jello/S
+jelly/GDSM
+jellybean/MS
+jellyfish/MS
+jellylike
+jellyroll/SM
+jemmy/GDS
+jennet/MS
+jenny/SM
+jeopardize/DSG
+jeopardy/M
+jeremiad/MS
+jerk/MDSG
+jerkily
+jerkin/MS
+jerkiness/M
+jerkwater
+jerky/TRMP
+jeroboam/S
+jerrybuilt
+jerrycan/S
+jersey/MS
+jest/MDRSZG
+jester/M
+jesting/Y
+jet/SM
+jetliner/SM
+jetport/MS
+jetsam/M
+jetted
+jetting
+jettison/MDSG
+jetty/SM
+jewel/SZGMDR
+jeweler/M
+jewelery/S
+jewelry/SM
+jg
+jib/SGMD
+jibbed
+jibbing
+jibe/MS
+jiff/MS
+jiffy/SM
+jig's
+jig/AS
+jigged/A
+jigger's
+jigger/ASDG
+jigging/A
+jiggle/DSMG
+jiggly/RT
+jigsaw/SMDG
+jihad/SM
+jilt/MDSG
+jimmy/DSMG
+jimsonweed/M
+jingle/DSMG
+jingly/TR
+jingo
+jingoism/M
+jingoist/SM
+jingoistic
+jink/DSG
+jinn/MS
+jinrikisha/SM
+jinx/MDSG
+jitney/SM
+jitter/S
+jitterbug/MS
+jitterbugged
+jitterbugger/M
+jitterbugging
+jitters/M
+jittery/RT
+jive/MGDS
+job/SM
+jobbed
+jobber/SM
+jobbing
+jobholder/MS
+jobless/P
+joblessness/M
+jobshare/S
+jobsworth
+jobsworths
+jock/MS
+jockey/SGMD
+jockstrap/MS
+jocose/PY
+jocoseness/M
+jocosity/M
+jocular/Y
+jocularity/M
+jocund/Y
+jocundity/M
+jodhpurs/M
+joey/S
+jog/SM
+jogged
+jogger/SM
+jogging/M
+joggle/DSMG
+john/MS
+johnny/SM
+johnnycake/MS
+join's
+join/AFDSG
+joiner/FMS
+joinery/M
+joint's
+joint/EGSD
+jointly/F
+jointures
+joist/SM
+jojoba
+joke/MZGDRS
+joker/M
+jokey
+jokier
+jokiest
+jokily
+joking/Y
+jollification/SM
+jollily
+jolliness/M
+jollity/M
+jolly/TGPDRSM
+jolt/MDRSZG
+jolter/M
+jonquil/SM
+josh/MDRSZG
+josher/M
+jostle/MGDS
+jot/SM
+jotted
+jotter/MS
+jotting/MS
+joule/SM
+jounce/MGDS
+jouncy/TR
+journal/MS
+journalese/M
+journalism/M
+journalist/SM
+journalistic
+journey/ZGMDRS
+journeyer/M
+journeyman/M
+journeymen
+journo/S
+joust/SZGMDR
+jouster/M
+jousting/M
+jovial/Y
+joviality/M
+jowl/MS
+jowly/TR
+joy/SGMD
+joyful/YP
+joyfuller
+joyfullest
+joyfulness/M
+joyless/PY
+joylessness/M
+joyous/YP
+joyousness/M
+joyridden
+joyride/RSMZG
+joyrider/M
+joyriding/M
+joyrode
+joystick/SM
+jubilant/Y
+jubilation/M
+jubilee/SM
+judder/GDS
+judge's
+judge/ADSG
+judgeship/M
+judgment/SM
+judgmental/Y
+judicatory/SM
+judicature/M
+judicial/Y
+judiciary/SM
+judicious/IPY
+judiciousness/IM
+judo/M
+jug/SM
+jugful/MS
+jugged
+juggernaut/SM
+jugging
+juggle/MZGDRS
+juggler/M
+jugglery/M
+jugular/SM
+juice/DRSMZG
+juicer/M
+juicily
+juiciness/M
+juicy/PTR
+jujitsu/M
+jujube/MS
+jukebox/MS
+julep/SM
+julienne
+jumble/MGDS
+jumbo/SM
+jump/MDRSZG
+jumper/M
+jumpily
+jumpiness/M
+jumpsuit/MS
+jumpy/TRP
+jun
+junco/SM
+junction/FISM
+juncture/FMS
+jungle/MS
+junior/MS
+juniority
+juniper/SM
+junk/MDRSZG
+junker/M
+junket/MDSG
+junketeer/MS
+junkie/MTRS
+junkyard/MS
+junta/SM
+juridic
+juridical/Y
+jurisdiction/SM
+jurisdictional
+jurisprudence/M
+jurisprudential
+jurist/MS
+juristic
+juror/SM
+jury/ISM
+juryman/M
+jurymen
+jurywoman/M
+jurywomen
+jussive
+just/UYPT
+juster
+justice/IMS
+justifiability
+justifiable/U
+justifiably/U
+justification/M
+justificatory
+justified/AU
+justify/NGDSX
+justness/M
+jut/SM
+jute/M
+jutted
+jutting
+juvenile/SM
+juxtapose/DSG
+juxtaposition/MS
+k/IFGS
+kHz
+kW
+kWh
+kabob/SM
+kaboom
+kabuki/M
+kaddish/MS
+kaffeeklatch/MS
+kaffeeklatsch/MS
+kahuna/S
+kaiser/MS
+kale/M
+kaleidoscope/SM
+kaleidoscopic
+kaleidoscopically
+kamikaze/MS
+kangaroo/MS
+kaolin/M
+kapok/M
+kappa/SM
+kaput
+karakul/M
+karaoke/MS
+karat/SM
+karate/M
+karma/M
+karmic
+kart/MS
+katydid/SM
+kayak/SMDG
+kayaking/M
+kayo/MDSG
+kazoo/SM
+kc
+kebab/SM
+kedgeree
+keel/MDSG
+keelhaul/DGS
+keen/MDRYSTGP
+keenness/M
+keep/MRSZG
+keeper/M
+keeping/M
+keepsake/MS
+keg/SM
+kelp/MZ
+kelvin/SM
+ken/SM
+kenned
+kennel/SGMD
+kenning
+keno/M
+kepi/MS
+kept
+keratin/M
+kerbside
+kerchief/SM
+kerfuffle/S
+kerned
+kernel/SM
+kerning
+kerosene/M
+kestrel/MS
+ketch/MS
+ketchup/M
+kettle/SM
+kettledrum/SM
+kettleful
+key/SGMD
+keyboard/ZGSMDR
+keyboarder/M
+keyboardist/MS
+keyhole/MS
+keynote/MZGDRS
+keynoter/M
+keypad/SM
+keypunch/ZGMDRS
+keypuncher/M
+keyring
+keystone/MS
+keystroke/SM
+keyword/MS
+kg
+khaki/SM
+khan/MS
+kibble/DSMG
+kibbutz/MS
+kibbutzim
+kibitz/ZGDRS
+kibitzer/M
+kibosh/M
+kick/MDRSZG
+kickback/SM
+kickball/M
+kickboxing
+kicker/M
+kickoff/MS
+kickstand/MS
+kicky/RT
+kid/SM
+kidded
+kidder/SM
+kiddie/SM
+kidding
+kiddish
+kiddo/SM
+kidnap/S
+kidnapped
+kidnapper/MS
+kidnapping/MS
+kidney/SM
+kidskin/M
+kielbasa/MS
+kielbasi
+kike/S
+kill/JMDRSZG
+killdeer/SM
+killer/M
+killing/M
+killjoy/SM
+kiln/MDSG
+kilo/MS
+kilobits
+kilobyte/SM
+kilocycle/SM
+kilogram/SM
+kilohertz/M
+kilojoules
+kiloliter/MS
+kilometer/MS
+kiloton/SM
+kilowatt/SM
+kilt/MDRS
+kilter/M
+kimono/MS
+kin/SM
+kind's
+kind/UPRYT
+kinda
+kindergarten/MS
+kindergartner/SM
+kindhearted/PY
+kindheartedness/M
+kindle/AGDS
+kindliness/M
+kindling/M
+kindly/URT
+kindness/UM
+kindnesses
+kindred/M
+kinds
+kine/S
+kinematic/S
+kinematics/M
+kinetic/S
+kinetically
+kinetics/M
+kinfolk/SM
+kinfolks/M
+king/MYS
+kingdom/SM
+kingfisher/MS
+kingly/RT
+kingmaker/S
+kingpin/SM
+kingship/M
+kink/MDSG
+kinkily
+kinkiness/M
+kinky/TPR
+kinsfolk/M
+kinship/M
+kinsman/M
+kinsmen
+kinswoman/M
+kinswomen
+kiosk/SM
+kip/SM
+kipped
+kipper/MDGS
+kipping
+kirsch/MS
+kismet/M
+kiss/MDRSBZG
+kisser/M
+kissoff/SM
+kissogram/S
+kit/SGMD
+kitchen/SM
+kitchenette/SM
+kitchenware/M
+kite/MS
+kith/M
+kitsch/M
+kitschy
+kitted
+kitten/MS
+kittenish
+kitting
+kittiwakes
+kitty/SM
+kiwi/MS
+kiwifruit/MS
+kl
+klaxon/S
+kleptomania/M
+kleptomaniac/MS
+kludge/GDS
+kluge/DSG
+klutz/MS
+klutziness/M
+klutzy/TRP
+km
+kn
+knack/SZMR
+knacker/GD
+knackwurst/SM
+knapsack/MS
+knave/SM
+knavery/M
+knavish/Y
+knead/SZGDR
+kneader/M
+knee/MDS
+kneecap/SM
+kneecapped
+kneecapping
+kneeing
+kneel/SG
+knell/SGMD
+knelt
+knew
+knicker/S
+knickerbockers/M
+knickers/M
+knickknack/MS
+knife/DSMG
+knight/MDYSG
+knighthood/MS
+knightliness/M
+knish/MS
+knit/MS
+knitted
+knitter/SM
+knitting/M
+knitwear/M
+knives
+knob/MS
+knobbly
+knobby/TR
+knock/JSZGMDR
+knockabout
+knockdown/SM
+knocker/M
+knockoff/SM
+knockout/SM
+knoll/SM
+knot/MS
+knothole/SM
+knotted
+knotting
+knotty/TR
+know/SB
+knowing/UTYS
+knowinger
+knowledge/M
+knowledgeable
+knowledgeably
+known
+knuckle/DSMG
+knuckleduster/S
+knucklehead/MS
+knurl/SGMD
+koala/SM
+koan/S
+kohl
+kohlrabi/M
+kohlrabies
+kola/MS
+kook/MS
+kookaburra/SM
+kookiness/M
+kooky/TPR
+kopeck/MS
+korma
+kosher/DSG
+kowtow/GMDS
+kph
+kraal/SM
+kraut's
+kraut/S!
+kriegspiel
+krill/M
+krona/M
+krone/RM
+kronor
+kronur
+krypton/M
+kt
+kuchen/SM
+kudos/M
+kudzu/SM
+kulaks
+kumquat/MS
+kvetch/GMDS
+kw
+kyle/S
+l/SDXTGJ
+la/M
+lab/SM
+label's
+label/ASDG
+labeled/U
+labellings/A
+labia
+labial/SM
+labile
+labium/M
+labor/SMDRZG
+laboratory/SM
+laborer/M
+laborious/PY
+laboriousness/M
+laborsaving
+laburnum/MS
+labyrinth/M
+labyrinthine
+labyrinths
+lac/M
+lace's
+lace/UGDS
+lacerate/DSGNX
+laceration/M
+lacewing/SM
+lacework/M
+lachrymal
+lachrymose
+lack/MDSG
+lackadaisical/Y
+lackey/SM
+lackluster
+laconic
+laconically
+lacquer/GMDS
+lacrosse/M
+lactate/GNDS
+lactation/M
+lacteal
+lactic
+lactose/M
+lacuna/M
+lacunae
+lacy/RT
+lad/SGMDNJ
+ladder/GSMD
+laddie/SM
+laddish/P
+lade/S
+laden/U
+lading/M
+ladle/DSMG
+lady/SM
+ladybird/SM
+ladybug/MS
+ladyfinger/MS
+ladylike/U
+ladylove/MS
+ladyship/MS
+laetrile/M
+lag/SZMR
+lager/M
+laggard/MYS
+lagged
+lagging/M
+lagniappe/SM
+lagoon/SM
+laid/IA
+lain
+lair/MS
+laird/SM
+laity/M
+lake/MS
+lakefront/S
+lakeside
+lallygag/S
+lallygagged
+lallygagging
+lam/SM
+lama/MS
+lamasery/SM
+lamb/MDSG
+lambada/MS
+lambaste/GDS
+lambda/SM
+lambency/M
+lambent/Y
+lambkin/SM
+lambskin/SM
+lambswool
+lame/MYZTGDRSP
+lamebrain/MS
+lameness/M
+lament/BSMDG
+lamentably
+lamentation/MS
+lamented/U
+lamina/M
+laminae
+laminar
+laminate/MGNDS
+lamination/M
+lammed
+lamming
+lamp/MS
+lampblack/M
+lamplight/ZMR
+lamplighter/M
+lampoon/SGMD
+lampoonery
+lamppost/SM
+lamprey/MS
+lampshade/SM
+lanai/SM
+lance/DRSMZG
+lancer/M
+lancet/SM
+land/MDRSGJ
+landau/SM
+landfall/MS
+landfill/MS
+landforms
+landholder/MS
+landholding/SM
+landing/M
+landlady/SM
+landless/M
+landlines
+landlocked
+landlord/MS
+landlubber/MS
+landmark/MS
+landmass/MS
+landmine/S
+landowner/MS
+landownership
+landowning/SM
+landscape/MZGDRS
+landscaper/M
+landslid
+landslide/MGS
+landslip/S
+landsman/M
+landsmen
+landward/S
+lane/MS
+language/MS
+languid/PY
+languidness/M
+languish/DSG
+languor/SM
+languorous/Y
+lank/RYTP
+lankiness/M
+lankness/M
+lanky/RTP
+lanolin/M
+lantern/MS
+lanthanum/M
+lanyard/MS
+lap/SM
+lapboard/SM
+lapdog/SM
+lapel/SM
+lapidary/SM
+lapin/SM
+lapped
+lappet/SM
+lapping
+lapse/AKGMSD
+laptop/SM
+lapwing/MS
+larboard/SM
+larcenist/SM
+larcenous
+larceny/SM
+larch/MS
+lard/MDRSZG
+larder/M
+lardy/RT
+large/RSPMYT
+largehearted
+largeness/M
+largess/M
+largish
+largo/SM
+lariat/SM
+lark/MDSG
+larkspur/SM
+larva/M
+larvae
+larval
+laryngeal
+larynges
+laryngitis/M
+larynx/M
+lasagna/MS
+lascivious/YP
+lasciviousness/M
+lase/ZGDRS
+laser/M
+lash/MDSGJ
+lashing/M
+lass/MS
+lassie/SM
+lassitude/M
+lasso/SMDG
+last/MDYSG
+lasting/Y
+lat/S
+latch's
+latch/UDSG
+latchkey/SM
+late/YTRP
+latecomer/MS
+latency/SM
+lateness/M
+latent
+lateral/MDYSG
+lateralization
+latest/M
+latex/M
+lath/MDRSZG
+lathe/M
+lather/GMD
+lathery
+laths
+latices
+latish
+latitude/MS
+latitudinal
+latitudinarian/MS
+latrine/MS
+latte/RSM
+latter/MY
+lattice/MDS
+latticework/SM
+laud/MDSGB
+laudably
+laudanum/M
+laudatory
+laugh/BMDG
+laughably
+laughing/MY
+laughingstock/SM
+laughs
+laughter/M
+launch/AGMDS
+launcher/SM
+launchpad/SM
+launder/DRZGS
+launderer/M
+launderette/MS
+laundress/MS
+laundromat/SM
+laundry/SM
+laundryman/M
+laundrymen
+laundrywoman/M
+laundrywomen
+laureate/MS
+laureateship/M
+laurel/SM
+lav/SGD
+lava/MS
+lavage/M
+lavaliere/SM
+lavatorial
+lavatory/SM
+lave/S
+lavender/SM
+lavish/PTGDRSY
+lavishness/M
+law/SM
+lawbreaker/SM
+lawbreaking/M
+lawful/UPY
+lawfulness/UM
+lawgiver/MS
+lawless/PY
+lawlessness/M
+lawmaker/MS
+lawmaking/M
+lawman/M
+lawmen
+lawn/MS
+lawnmower/SM
+lawrencium/M
+lawsuit/MS
+lawyer/SM
+lax/TRYP
+laxative/MS
+laxity/M
+laxness/M
+lay/AICSGM
+layabout/S
+layaway/M
+layer/CSM
+layered
+layering/M
+layette/MS
+layman/M
+laymen
+layoff/SM
+layout/SM
+layover/MS
+laypeople
+layperson/MS
+layup/SM
+laywoman/M
+laywomen
+laze/MGDS
+lazily
+laziness/M
+lazuli
+lazy/DRSTGP
+lazybones/M
+lb/S
+lbw
+lea/SM
+leach/DSG
+lead/MDNRSZG
+leader/M
+leaderless
+leadership/SM
+leading/M
+leaf/MDSG
+leafage/M
+leafless
+leaflet/GMDS
+leafstalk/MS
+leafy/PRT
+league/DSMG
+leak/MDSG
+leakage/MS
+leakiness/M
+leaky/PRT
+lean/MDRSTGJP
+leaning/M
+leanness/M
+leap/MDRSZG
+leaper/M
+leapfrog/MS
+leapfrogged
+leapfrogging
+learn/AUGDS
+learnedly
+learner/MS
+learning's
+lease/ADSMG
+leaseback/SM
+leasehold/MRSZ
+leaseholder/M
+leaser/SM
+leash's
+leash/UDSG
+least/M
+leastwise
+leather/MS
+leatherette/M
+leatherneck/MS
+leathery
+leave/DRSMZGJ
+leaven/SGMD
+leavened/U
+leavening/M
+leaver/M
+leavings/M
+lebensraum
+lech/MDRSZG
+lecher/M
+lecherous/PY
+lecherousness/M
+lechery/M
+lecithin/M
+lectern/MS
+lecture/MZGDRS
+lecturer/M
+lectureship/MS
+ledge/RSMZ
+ledger/M
+lee/RSMZ
+leech/MDSG
+leek/MS
+leer/MDG
+leeriness/M
+leering/Y
+leery/RPT
+leeward/SM
+leeway/M
+left/MRST
+leftism/M
+leftist/SM
+leftmost
+leftover/SM
+leftward/S
+lefty/SM
+leg/SM
+legacy/SM
+legal/SMY
+legalese/MS
+legalism/MS
+legalistic
+legalistically
+legality/SM
+legalization/M
+legalize/GDS
+legate/CXMNS
+legatee/MS
+legation's/AC
+legato/SM
+legend/SM
+legendarily
+legendary
+legerdemain/M
+legged
+legginess/M
+legging/MS
+leggy/RPT
+leghorn/MS
+legibility/M
+legible
+legibly
+legion/SM
+legionary/SM
+legionnaire/SM
+legislate/DSGNV
+legislation/M
+legislative/Y
+legislator/SM
+legislature/SM
+legit
+legitimacy/M
+legitimate/DSYGN
+legitimatize/DSG
+legitimization/M
+legitimize/DSG
+legless
+legman/M
+legmen
+legroom/SM
+legstraps
+legume/MS
+leguminous
+legwarmer/S
+legwork/M
+lei/SM
+leisure/DMY
+leisureliness/M
+leisurewear/M
+leitmotif/MS
+leitmotiv/MS
+lemma/S
+lemme/JG
+lemming/M
+lemon/SM
+lemonade/SM
+lemongrass
+lemony
+lemur/SM
+lend/RSZG
+lender/M
+length/MNX
+lengthen/GD
+lengthily
+lengthiness/M
+lengths
+lengthwise
+lengthy/PRT
+lenience/M
+leniency/M
+lenient/Y
+lenitive
+lens/MSG
+lent
+lentil/MS
+lento
+leonine
+leopard/SM
+leopardess/MS
+leopardskin
+leotard/SM
+leper/SM
+leprechaun/MS
+leprosy/M
+leprous
+lepta
+lepton/MS
+lesbian/SM
+lesbianism/M
+lesion/MS
+less/MNRX
+lessee/MS
+lessen/GD
+lesson/MS
+lessor/MS
+let/ISM
+letdown/SM
+lethal/Y
+lethality
+lethargic
+lethargically
+lethargy/M
+letter/ZGMDRS
+letterbomb/S
+letterbox/S
+lettered/U
+letterer/M
+letterhead/MS
+lettering/M
+letterpress/M
+letting/S
+lettuce/MS
+letup/SM
+leucotomy/S
+leukemia/M
+leukemic/SM
+leukocyte/MS
+levee/SM
+level/PSZTGMDRY
+leveler/M
+levelheaded/P
+levelheadedness/M
+levelness/M
+lever/SGMD
+leverage/DSMG
+leviathan/MS
+levier/M
+levitate/DSGN
+levitation/M
+levity/M
+levy/DRSMZG
+lewd/RYPT
+lewdness/M
+lexeme/S
+lexer/S
+lexical/Y
+lexicographer/SM
+lexicographic
+lexicographical/Y
+lexicography/M
+lexicon/SM
+lexis
+lg
+liability/ASM
+liable/A
+liaise/GDS
+liaison/MS
+liar/MS
+lib/M
+libation/SM
+libber/MS
+libel/SZGMDR
+libeler/M
+libelous
+liberal/MYPS
+liberalism/M
+liberality/M
+liberalization/SM
+liberalize/DSG
+liberalness/M
+liberate/CDSGN
+liberation/CM
+liberationists
+liberator/MS
+libero
+libertarian/MS
+libertarianism
+libertine/MS
+liberty/SM
+libidinal
+libidinous
+libido/MS
+librarian/MS
+librarianship
+library/SM
+librettist/MS
+libretto/SM
+lice
+license/MGDS
+licensed/U
+licensee/MS
+licentiate/MS
+licentious/YP
+licentiousness/M
+lichen/MDS
+licit/Y
+lick/MDJSG
+lickerish
+licking/M
+licorice/SM
+lid/SM
+lidded
+lidless
+lido/MS
+lie/DSM
+lied/MR
+lief/RT
+liege/SM
+lien/MS
+lieu/M
+lieutenancy/M
+lieutenant/SM
+life/MZR
+lifebelt/S
+lifeblood/M
+lifeboat/MS
+lifeboatmen
+lifebuoy/MS
+lifeforms
+lifeguard/SM
+lifeless/PY
+lifelessness/M
+lifelike
+lifeline/MS
+lifelong
+lifer/M
+lifesaver/SM
+lifesaving/M
+lifespan/S
+lifestyle/SM
+lifetaking
+lifetime/MS
+lifework/MS
+lift/MDRSZG
+lifter/M
+liftoff/SM
+ligament/MS
+ligand/S
+ligate/GNDS
+ligation/M
+ligature/MGDS
+light's/C
+light/CASTGD
+lighted/U
+lighten/SDRZG
+lightener/M
+lighter/SM
+lightface/MD
+lightheaded
+lighthearted/PY
+lightheartedness/M
+lighthouse/MS
+lighting's
+lightly
+lightness/M
+lightning/MDS
+lightproof
+lightship/MS
+lightweight/SM
+ligneous
+lignite/M
+lii
+likability/M
+likableness/M
+like/MYTGPDRSBJ
+likelihood/UM
+likelihoods
+likeliness/UM
+likely/UPRT
+liken/SGD
+likeness/UM
+likenesses
+likewise
+liking/M
+lilac/SM
+lilliputian
+lilo/S
+lilt/MDSG
+lily/SM
+limb/MS
+limber/UDSTG
+limberer
+limberness/M
+limbless
+limbo/SM
+lime/MGDS
+limeade/SM
+limekiln
+limelight/M
+limerick/SM
+limescale
+limestone/M
+limey/S
+limit's
+limit/CSZGDR
+limitation/CM
+limitations
+limited/U
+limiter's
+limiting/S
+limitless/P
+limitlessness/M
+limn/DSG
+limo/MS
+limousine/MS
+limp/MDRYSPTG
+limpet/MS
+limpid/YP
+limpidity/M
+limpidness/M
+limpness/M
+limy/RT
+linage/M
+linchpin/SM
+linden/MS
+line/MZGDRSJ
+lineage/MS
+lineal/Y
+lineament/SM
+linear/Y
+linearity/M
+linearized
+linebacker/SM
+lined/U
+linefeed
+lineman/M
+linemen
+linen/SM
+linens/M
+liner/M
+linesman/M
+linesmen
+lineup/MS
+ling/M
+linger/ZGJDRS
+lingerer/M
+lingerie/M
+lingering/Y
+lingo/M
+lingoes
+lingual
+linguine/M
+linguist/SM
+linguistic/S
+linguistically
+linguistics/M
+liniment/SM
+lining/M
+link/MDRBSZG
+linkage/MS
+linkman
+linkmen
+linkup/MS
+linnet/MS
+lino
+linoleum/M
+linseed/M
+lint's
+lint/CDSG
+lintel/MS
+linty/TR
+lion/MS
+lioness/MS
+lionhearted
+lionization/M
+lionize/GDS
+lip/SM
+lipase
+lipid/SM
+liposuction/M
+lipped
+lippy/TR
+lipread/GRS
+lipreader/M
+lipreading/M
+lipstick/MDSG
+liq
+liquefaction/M
+liquefy/DSG
+liqueur/SM
+liquid/MS
+liquidate/XGNDS
+liquidation/M
+liquidator/MS
+liquidity/M
+liquidize/ZGDRS
+liquidizer/M
+liquor/MDGS
+liquorish
+lira/M
+lire
+lisle/M
+lisp/MDRSZG
+lisper/M
+lissome/P
+lissomness
+list/MDNSJXG
+listed/U
+listen/BMDRZG
+listener/M
+listeria
+listing/M
+listless/YP
+listlessness/M
+lit/ZR
+litany/SM
+litchi/MS
+lite
+liter/M
+literacy/M
+literal/SMYP
+literalism
+literalistic
+literalness/M
+literariness/M
+literary/P
+literate/SMY
+literati/M
+literature/M
+lithe/RPYT
+litheness/M
+lithesome
+lithium/M
+lithograph/ZGMDR
+lithographer/M
+lithographic
+lithographically
+lithographs
+lithography/M
+lithological
+lithology
+lithosphere/SM
+litigant/SM
+litigate/DSGN
+litigation/M
+litigator/MS
+litigious/P
+litigiousness/M
+litmus/M
+litotes/M
+litter/MDRSZG
+litterateur/MS
+litterbug/MS
+litterer/M
+little/MTRP
+littleness/M
+littoral/SM
+liturgical/Y
+liturgist/SM
+liturgy/SM
+livability/M
+livable/U
+live/ATGDSB
+livelihood/MS
+liveliness/M
+livelong/S
+lively/PRT
+liven/SGD
+liver's
+liver/S
+liveried
+liverish
+liverwort/MS
+liverwurst/M
+livery/CSM
+liveryman/CM
+liverymen/C
+livestock/M
+liveware/S
+livid/Y
+living/MS
+lix/K
+lizard/MS
+ll
+llama/SM
+llano/SM
+lo
+load's
+load/AUGSD
+loadable
+loader/MS
+loading/MS
+loaf/MDRSZG
+loafer/M
+loam/MS
+loamy/TR
+loan/MDRSBZG
+loaner/M
+loansharking/M
+loanword/MS
+loath/JZGDRS
+loathe
+loather/M
+loathing/M
+loathsome/YP
+loathsomeness/M
+loaves
+lob/SMD
+lobar
+lobbed
+lobber/MS
+lobbing
+lobby/GDSM
+lobbyist/MS
+lobe/MS
+lobotomist
+lobotomize/GDS
+lobotomy/SM
+lobster/MS
+local/SMY
+locale/MS
+locality/SM
+localization/MS
+localize/DSG
+locatable/A
+locate/EAGNVDS
+location's/A
+location/ESM
+locational
+lock/MDRSBZG
+locked/A
+locker/M
+locket/MS
+lockjaw/M
+lockout/MS
+locksmith/M
+locksmiths
+lockstep/M
+lockup/MS
+loco/S
+locomotion/M
+locomotive/MS
+locoweed/SM
+locum/S
+locus/Mi
+locust/SM
+locution/MS
+lode/MS
+lodestar/MS
+lodestone/MS
+lodge/DRSJMZG
+lodger/M
+lodging/M
+lodgings/M
+loft/MDSG
+loftily
+loftiness/M
+lofty/PRT
+log/SM
+loganberry/SM
+logarithm/SM
+logarithmic
+logarithmically
+logbook/SM
+loge/MS
+logged
+logger/SM
+loggerhead/SM
+loggia/SM
+logging/M
+logic/M
+logical/Y
+logicality/M
+logician/MS
+logistic/S
+logistical/Y
+logistics/M
+logjam/SM
+logo/MS
+logotype/SM
+logrolling/M
+logy/RT
+loin/MS
+loincloth/M
+loincloths
+loiter/ZGSDR
+loiterer/M
+loitering/M
+loll/DSG
+lollipop/SM
+lollop/GSD
+lolly/S
+lone/YZR
+loneliness/M
+lonely/PTR
+loner/M
+lonesome/YP
+lonesomeness/M
+long's
+long/KDSTG
+longboat/MS
+longbow/MS
+longer
+longevity/M
+longhair/MS
+longhand/M
+longhorn/MS
+longhouse/S
+longing/MYS
+longish
+longitude/MS
+longitudinal/Y
+longshoreman/M
+longshoremen
+longsighted
+longstanding
+longsword
+longtime
+longueur/SM
+longways
+loo
+loofah/M
+loofahs
+look/MDRSZG
+lookalike/MS
+looker/M
+lookout/MS
+loom/MDSG
+loon/MS
+loony/RSMT
+loop/MDSG
+loophole/MS
+loopy/RT
+loos/NRX
+loose/UDSTG
+loosely
+loosen/UGSD
+looseness/M
+loot/MDRSZG
+looter/M
+looting/M
+lop/S
+lope/MGDS
+lopped
+lopper/S
+lopping
+lopsided/YP
+lopsidedness/M
+loquacious/YP
+loquaciousness/M
+loquacity/M
+lord/MDYSG
+lordliness/M
+lordly/TPR
+lordship/SM
+lore/M
+lorgnette/SM
+loris/MS
+lorn
+lorry/SM
+lorryload/S
+lose/ZGRSBJ
+loser/M
+losing/M
+loss/MS
+lost
+lot/SM
+lotion/SM
+lottery/SM
+lotto/M
+lotus/MS
+louche
+loud/RYTP
+loudhailer/SM
+loudly/TR
+loudmouth/MD
+loudmouths
+loudness/M
+loudspeaker/SM
+lough
+loughs
+lounge/MZGDRS
+lounger/M
+lour/DSG
+louse's
+louse/CDSG
+lousily
+lousiness/M
+lousy/TPR
+lout/MS
+loutish/PY
+louver/MDS
+lovableness/M
+lovably
+love/MYZGDRSB
+lovebird/SM
+lovechild/M
+loved/U
+loveless
+loveliness/M
+lovelorn
+lovely/RSMTP
+lovemaking/M
+lover/M
+lovesick
+lovestruck
+lovey/S
+loving/Y
+low/SZTGMDRYP
+lowborn
+lowboy/MS
+lowbrow/SM
+lowdown/M
+lower/GD
+lowercase/M
+lowermost
+lowish
+lowland/SZMR
+lowlander/M
+lowlife/SM
+lowliness/M
+lowly/TPR
+lowness/M
+lox/M
+loyal/ETY
+loyaler
+loyalism/M
+loyalist/SM
+loyalties
+loyalty/EM
+lozenge/SM
+ltd
+luau/MS
+lubber/MYS
+lube/MGDS
+lubricant/SM
+lubricate/DSGN
+lubrication/M
+lubricator/MS
+lubricious/Y
+lubricity/M
+lucid/PY
+lucidity/M
+lucidness/M
+luck/MDSG
+luckily/U
+luckiness/UM
+luckless
+lucky/UPTR
+lucrative/PY
+lucrativeness/M
+lucre/M
+lucubrate/GNDS
+lucubration/M
+ludicrous/YP
+ludicrousness/M
+ludo
+luff/DSG
+lug/SM
+luge/S
+luggage/M
+lugged
+lugger/MS
+lugging
+lughole/S
+lugsail/SM
+lugubrious/PY
+lugubriousness/M
+lukewarm/YP
+lukewarmness/M
+lull/MDSG
+lullaby/SM
+lulu/S
+lumbago/M
+lumbar
+lumber/MDRZGS
+lumberer/M
+lumbering/M
+lumberjack/SM
+lumberman/M
+lumbermen
+lumberyard/SM
+lumen
+luminance
+luminary/SM
+luminescence/M
+luminescent
+luminosity/SM
+luminous/Y
+lummox/MS
+lump/MDNSG
+lumpectomy/S
+lumpiness/M
+lumpish
+lumpy/TRP
+lunacy/SM
+lunar
+lunatic/SM
+lunch/GMDS
+lunchbox/S
+luncheon/SM
+luncheonette/MS
+lunchpack
+lunchroom/MS
+lunchtime/MS
+lune
+lung/MDSG
+lunge/SM
+lungfish/MS
+lungful/S
+lunkhead/MS
+lupine/MS
+lupus/M
+lurch/GMDS
+lure/MGDS
+lurex
+lurgy
+lurid/PY
+luridness/M
+lurk/DRSZG
+luscious/PY
+lusciousness/M
+lush/MRSYPT
+lushness/M
+lust/MDRSG
+luster/M
+lusterless
+lustful/Y
+lustily
+lustiness/M
+lustrous/Y
+lusty/PTR
+lutanist/SM
+lute/MS
+lutenist/SM
+lutetium/M
+luxuriance/M
+luxuriant/Y
+luxuriate/DSGN
+luxuriation/M
+luxurious/PY
+luxuriousness/M
+luxury/SM
+lvi
+lvii
+lxi
+lxii
+lxiv
+lxix
+lxvi
+lxvii
+lyceum/MS
+lychgate/S
+lye/MG
+lying/M
+lymph/M
+lymphatic/SM
+lymphocyte/MS
+lymphoid
+lymphoma/SM
+lynch/JZGDRS
+lyncher/M
+lynching/M
+lynx/MS
+lyre/MS
+lyrebird/MS
+lyric/SM
+lyrical/Y
+lyricism/M
+lyricist/SM
+lysine
+m/KAS
+ma'am
+ma/SMH
+mac/SGMD
+macabre
+macadam/M
+macadamia/SM
+macadamize/GDS
+macaque/MS
+macaroni/MS
+macaroon/MS
+macaw/SM
+mace/MS
+macerate/DSGN
+maceration/M
+mach/M
+machete/SM
+machinate/GNDSX
+machination/M
+machine/DSMGB
+machinery/M
+machinist/MS
+machismo/M
+macho/M
+mackerel/SM
+mackinaw/SM
+mackintosh/MS
+macrame/M
+macro/SM
+macrobiotic/S
+macrobiotics/M
+macrocosm/SM
+macroeconomic/S
+macroeconomics/M
+macrology/S
+macromolecular
+macromolecules
+macron/MS
+macrophage/S
+macroscopic
+macroscopically
+mad/SMYP
+madam/SM
+madame/M
+madcap/MS
+madden/DGS
+maddening/Y
+madder/MS
+maddest
+madding
+made/AU
+mademoiselle/SM
+madhouse/SM
+madman/M
+madmen
+madness/M
+madras/MS
+madrigal/SM
+madwoman/M
+madwomen
+maelstrom/SM
+maestro/SM
+mafia/SM
+mafiosi
+mafioso/M
+mag/SM
+magazine/SM
+magenta/M
+maggot/MS
+maggoty/RT
+magi/M
+magic/SM
+magical/Y
+magician/SM
+magicked
+magicking
+magisterial/Y
+magistracy/M
+magistrate/SM
+magma/SM
+magmatic
+magnanimity/M
+magnanimosity
+magnanimous/Y
+magnate/SM
+magnesia/M
+magnesium/M
+magnet/MS
+magnetic
+magnetically
+magnetism/M
+magnetite/M
+magnetizable
+magnetization/CM
+magnetize/CGDS
+magneto/SM
+magnetodynamics
+magnetohydrodynamical
+magnetohydrodynamics
+magnetometer/SM
+magnetosphere
+magnetron
+magnification/M
+magnificence/M
+magnificent/Y
+magnified/U
+magnifier/M
+magnify/NZGDRSX
+magniloquence/M
+magniloquent
+magnitude/SM
+magnolia/MS
+magnum/MS
+magpie/MS
+maharajah/M
+maharajahs
+maharani/SM
+maharishi/SM
+mahatma/SM
+mahogany/SM
+mahout/MS
+maid/MNSX
+maiden/MY
+maidenhair/M
+maidenhead/SM
+maidenhood/M
+maidservant/MS
+mail/BJMDRSZG
+mailbag/SM
+mailbomb/GSD
+mailbox/MS
+mailer/M
+mailing/M
+maillot/SM
+mailman/M
+mailmen
+mailshot/S
+maim/DSG
+main/MYS
+mainbrace
+mainframe/SM
+mainland/MS
+mainline/MGDS
+mainmast/MS
+mainsail/MS
+mainspring/SM
+mainstay/MS
+mainstream/SGMD
+maintain/ZGDRBS
+maintainability
+maintainable/U
+maintained/U
+maintenance/M
+maintop/SM
+maisonette/MS
+maize/SM
+majestic
+majestically
+majesty/SM
+majolica/M
+major/SGMDY
+majordomo/MS
+majorette/MS
+majority/SM
+make's/A
+make/UAGS
+makeover/MS
+maker/SM
+makeshift/SM
+makeup/MS
+makeweight/S
+making/MS
+makings/M
+malachite/M
+maladaptive
+maladjusted
+maladjustment/M
+maladministration
+maladroit/PY
+maladroitness/M
+malady/SM
+malaise/M
+malamute/MS
+malapropism/SM
+malaria/M
+malarial
+malarkey/M
+malathion/M
+malcontent/SM
+male/MPS
+malediction/MS
+malefaction/SM
+malefactor/SM
+malefic
+maleficence/M
+maleficent
+maleness/M
+malevolence/M
+malevolent/Y
+malfeasance/M
+malformation/MS
+malformed
+malfunction/GSMD
+malice/M
+malicious/PY
+maliciousness/M
+malign/DSZG
+malignancy/SM
+malignant/Y
+malignity/M
+malinger/ZGSDR
+malingerer/M
+mall/MS
+mallard/SM
+malleability/M
+malleable
+mallet/MS
+mallow/MS
+malnourished
+malnourishment
+malnutrition/M
+malocclusion/M
+malodorous
+malpractice/SM
+malt/MDSG
+malted/MS
+maltose/M
+maltreat/GLDS
+maltreatment/M
+malty/TR
+mam/S
+mama/MS
+mamba/SM
+mambo/SGMD
+mammal/MS
+mammalian/MS
+mammary
+mammogram/MS
+mammography/M
+mammon/M
+mammoth/M
+mammoths
+mammy/SM
+man's/F
+man/USY
+manacle/DSMG
+manage/ZGDRSL
+manageability/M
+manageable/U
+management/MS
+manager/M
+manageress/S
+managerial/Y
+managership
+manana/MS
+manatee/SM
+manciple
+mandala/SM
+mandamus/MS
+mandarin/MS
+mandate/DSMG
+mandatory
+mandible/MS
+mandibular
+mandolin/MS
+mandrake/MS
+mandrel/SM
+mandrill/MS
+mane/MDS
+manege/M
+maneuver/BJMDGS
+maneuverability/M
+manful/Y
+manganese/M
+mange/DRMZ
+manged/S
+manger/M
+mangetout/S
+manginess/M
+mangle/MZGDRS
+mango/M
+mangoes
+mangrove/MS
+mangy/TRP
+manhandle/GDS
+manhole/SM
+manhood/M
+manhunt/SM
+mania/SM
+maniac/MS
+maniacal/Y
+manic/SM
+manically
+manicure/MGDS
+manicurist/MS
+manifest/MDYSG
+manifestation/MS
+manifesto/SM
+manifold/GMDS
+manikin/SM
+manila/M
+manioc/MS
+manipulable
+manipulate/GNVXDS
+manipulation/M
+manipulative/Y
+manipulator/SM
+mankind/M
+manky
+manlike
+manliness/M
+manly/UTR
+manna/M
+manned/U
+mannequin/SM
+manner/MDYS
+mannerism/SM
+mannerist
+mannerly/P
+manning/U
+mannish/YP
+mannishness/M
+manoeuvrings
+manometer/SM
+manor/SM
+manorial
+manpower/M
+manque
+mansard/MS
+manse/SXMN
+manservant/M
+mansion/M
+manslaughter/M
+manta/SM
+mantel/MS
+mantelpiece/MS
+mantelshelf
+mantelshelves
+mantes
+mantilla/SM
+mantis/MS
+mantissa/SM
+mantle's
+mantle/EGDS
+mantra/MS
+mantrap/S
+manual/MYS
+manufacture/MZGDRS
+manufacturer/M
+manufacturing/M
+manumission/SM
+manumit/S
+manumitted
+manumitting
+manure/MGDS
+manuscript/SM
+many/M
+map's
+map/AS
+maple/SM
+mapmaker/SM
+mappable
+mapped/UA
+mapper/MS
+mapping/S
+mar/S
+marabou/MS
+maraca/MS
+maraschino/SM
+marathon/SMRZ
+marathoner/M
+maraud/ZGDRS
+marauder/M
+marble/MGDS
+marbleize/GDS
+marbling/M
+march/ZGMDRS
+marcher/M
+marchioness/MS
+mare/MS
+margarine/M
+margarita/MS
+marge
+margin/MS
+marginal/YS
+marginalia/M
+marginality
+marginalization/M
+marginalize/DSG
+maria/M
+mariachi/MS
+marigold/MS
+marijuana/M
+marimba/SM
+marina/MS
+marinade/DSMG
+marinara/M
+marinate/DSGN
+marination/M
+marine/MZRS
+mariner/M
+marionette/SM
+marital/Y
+maritime
+marjoram/M
+mark/AMDSG
+markdown/SM
+marked/U
+markedly
+marker/MS
+market/MDRZGBS
+marketability/M
+marketable/U
+marketeer/SM
+marketer/M
+marketing/M
+marketplace/SM
+marking/SM
+markka/M
+markkaa
+marksman/M
+marksmanship/M
+marksmen
+markup/MS
+marl/MS
+marlin/MS
+marlinespike/MS
+marmalade/M
+marmoreal
+marmoset/SM
+marmot/MS
+maroon/MDGS
+marque/MS
+marquee/SM
+marquess/MS
+marquetry/M
+marquis/MS
+marquise/M
+marquisette/M
+marred/U
+marriage/ASM
+marriageability/M
+marriageable
+married/SM
+marring
+marrow/MS
+marry/AGDS
+marsh/MS
+marshal/SMDG
+marshaller
+marshland/SM
+marshmallow/MS
+marshy/PRT
+marsupial/MS
+mart/MNSX
+marten/M
+martial/Y
+martian/S
+martin/MS
+martinet/MS
+martingale/MS
+martini/SM
+martyr/MDGS
+martyrdom/M
+marvel/MDGS
+marvelous/Y
+marzipan/M
+masc
+mascara/GMDS
+mascot/MS
+masculine/SM
+masculinity/M
+maser/SM
+mash/MDRSZG
+masher/M
+mask's
+mask/UDSG
+masker/MS
+masochism/M
+masochist/SM
+masochistic
+masochistically
+mason/SM
+masonic
+masonry/M
+masque/MS
+masquerade/DRSMZG
+masquerader/M
+mass/MDSGV
+massacre/MGDS
+massage/DSMG
+masseur/SM
+masseuse/MS
+massif/MS
+massive/PY
+massiveness/M
+mast/MDS
+mastectomy/SM
+master's
+master/ADGS
+masterclass/S
+masterful/Y
+masterly
+mastermind/MDSG
+masterpiece/SM
+mastership
+masterstroke/SM
+masterwork/MS
+mastery/M
+masthead/MS
+mastic/M
+masticate/GNDS
+mastication/M
+mastiff/SM
+mastitis
+mastodon/SM
+mastoid/SM
+masturbate/GNDS
+masturbation/M
+masturbatory
+mat/SZGMDRJ
+matador/SM
+match/AGMS
+matchable/U
+matchbook/SM
+matchbox/MS
+matched/U
+matcher
+matchless
+matchlock/SM
+matchmaker/SM
+matchmaking/M
+matchplay
+matchstick/MS
+matchwood/M
+mate/MS
+material/SMY
+materialism/M
+materialist/SM
+materialistic
+materialistically
+materiality
+materialization/M
+materialize/CDS
+materialized/A
+materializing
+materiel/M
+maternal/Y
+maternity/M
+matey/S
+math/M
+mathematical/Y
+mathematician/SM
+mathematics/M
+maths
+matinee/SM
+mating/M
+matins/M
+matriarch/M
+matriarchal
+matriarchs
+matriarchy/SM
+matrices
+matricidal
+matricide/MS
+matriculate/GNDS
+matriculation/M
+matrimonial/Y
+matrimony/M
+matrix/M
+matron/MYS
+matte/DRSMZG
+matter/MDG
+matting/M
+mattock/SM
+mattress/MS
+maturate/GNDS
+maturation/M
+mature/YTGDRS
+maturity/SM
+matzo/SM
+matzoh/M
+matzohs
+matzot
+maudlin
+maul/MDRSZG
+mauler/M
+maunder/SDG
+mausoleum/SM
+mauve/M
+maven/SM
+maverick/SM
+maw/SM
+mawkish/PY
+mawkishness/M
+max/GMDS
+maxi/MS
+maxilla/M
+maxillae
+maxillary
+maxim/SM
+maximal/Y
+maximality
+maximization/M
+maximize/GDRS
+maximum/SM
+may/M
+maybe/SM
+mayday/MS
+mayflower/MS
+mayfly/SM
+mayhem/M
+mayn't
+mayo/M
+mayonnaise/M
+mayor/SM
+mayoral
+mayoralty/M
+mayoress/MS
+maypole/SM
+mayst
+maze/MS
+mazurka/MS
+mdse
+me/DS
+mead/M
+meadow/MS
+meadowland
+meadowlark/MS
+meager/PY
+meagerness/M
+meagreness
+meal/MS
+mealiness/M
+mealtime/SM
+mealy/TPR
+mealybug/SM
+mealymouthed
+mean/MRYJPSTG
+meander/SMDJG
+meanderings/M
+meanie/MS
+meaning/M
+meaningful/YP
+meaningfulness/M
+meaningless/PY
+meaninglessness/M
+meanness/M
+meant/U
+meantime/M
+meanwhile/M
+meas
+measles/M
+measly/RT
+measurable/U
+measurably
+measure's
+measure/ADSG
+measured/U
+measureless
+measurement/SM
+meat/MS
+meataxe
+meatball/MS
+meatiness/M
+meatless
+meatloaf/M
+meatloaves
+meatpacking/M
+meaty/TPR
+mecca/SM
+mechanic/MS
+mechanical/Y
+mechanics/M
+mechanism/SM
+mechanist
+mechanistic
+mechanistically
+mechanization/M
+mechanize/DSBG
+mechanized/U
+medal/SM
+medalist/MS
+medallion/SM
+meddle/ZGDRS
+meddler/M
+meddlesome
+media/SM
+medial/AY
+median/MS
+mediate/DSGN
+mediated/U
+mediation/AM
+mediator/MS
+medic/SM
+medicaid/M
+medical/SMY
+medicament/M
+medicare/M
+medicate/GNXDS
+medication/M
+medicinal/Y
+medicine/MS
+medico/MS
+medieval
+medievalist/SM
+mediocre
+mediocrity/SM
+meditate/DSGNVX
+meditation/M
+meditative/Y
+medium/MS
+medley/MS
+medulla/SM
+meed/M
+meek/RYPT
+meekness/M
+meerschaum/SM
+meet/MRJSG
+meeting/M
+meetinghouse/SM
+meg/S
+mega
+megabit/SM
+megabucks/M
+megabyte/MS
+megacycle/SM
+megadeath/M
+megadeaths
+megahertz/M
+megajoules
+megalith/M
+megalithic
+megaliths
+megalomania/M
+megalomaniac/SM
+megalopolis/MS
+megaparsec
+megaphone/DSMG
+megapixel
+megastar/S
+megaton/SM
+megawatt/MS
+meiosis/M
+meiotic
+melamine/M
+melancholia/M
+melancholic/S
+melancholy/SM
+melange/MS
+melanin/M
+melanoma/SM
+melatonin
+meld/MDSG
+melee/SM
+meliorate/GNVDS
+melioration/M
+mellifluous/YP
+mellifluousness/M
+mellow/PTGDRYS
+mellowness/M
+melodic
+melodically
+melodious/YP
+melodiousness/M
+melodrama/MS
+melodramatic/S
+melodramatically
+melodramatics/M
+melody/SM
+melon/SM
+melt's
+melt/ADSG
+meltdown/SM
+melter
+member's
+member/EAS
+membership/SM
+membrane/SM
+membranous
+meme/S
+memento/MS
+memo/MS
+memoir/MS
+memorabilia/M
+memorability/M
+memorable/U
+memorably
+memorandum/MS
+memorial/SM
+memorialize/DSG
+memorization/M
+memorize/DSG
+memorized/U
+memory/SM
+memsahib/S
+men
+menace/MGDS
+menacing/Y
+menage/MS
+menagerie/MS
+menarche
+mend/MDRSZG
+mendacious/Y
+mendacity/M
+mendelevium/M
+mender/M
+mendicancy/M
+mendicant/SM
+mending/M
+menfolk/MS
+menfolks/M
+menhaden/M
+menial/MYS
+meningeal
+meninges
+meningitis/M
+meninx/M
+menisci
+meniscus/M
+menopausal
+menopause/M
+menorah/M
+menorahs
+mensch/MS
+menservants
+menses/M
+menstrual
+menstruate/GNDS
+menstruation/M
+mensurable
+mensuration/M
+menswear/M
+mental/Y
+mentalist/SM
+mentality/SM
+menthol/M
+mentholated
+mention/BGSMD
+mentioned/U
+mentor/MDSG
+menu/MS
+meow/MDSG
+mercantile
+mercantilism/M
+mercenary/SM
+mercer/MS
+mercerize/GDS
+merchandise/DRSMZG
+merchandiser/M
+merchandising/M
+merchant/MSB
+merchantability
+merchantman/M
+merchantmen
+merciful/UY
+merciless/YP
+mercilessness/M
+mercurial/Y
+mercuric
+mercury/M
+mercy/SM
+mere/MYTRS
+meretricious/PY
+meretriciousness/M
+merganser/MS
+merge/DRSZG
+merger/M
+meridian/MS
+meridional
+meringue/MS
+merino/MS
+merit/CSM
+merited/U
+meriting
+meritocracy/SM
+meritocratic
+meritocrats
+meritorious/YP
+meritoriousness/M
+mermaid/SM
+merman/M
+mermen
+meromorphic
+merrily
+merriment/M
+merriness/M
+merry/TRP
+merrymaker/MS
+merrymaking/M
+mesa/MS
+mescal/MS
+mescalin
+mescaline/M
+mesdames
+mesdemoiselles
+mesh/MDSG
+mesmeric
+mesmerism/M
+mesmerize/ZGDRS
+mesmerizer/M
+mesomorph/M
+mesomorphs
+meson/SM
+mesosphere/MS
+mesozoic
+mesquite/SM
+mess/MDSG
+message/MGDS
+messeigneurs
+messenger/SM
+messiah/M
+messiahs
+messianic
+messieurs
+messily
+messiness/M
+messmate/SM
+messy/PTR
+mestizo/MS
+met
+meta
+metabolic
+metabolically
+metabolism/SM
+metabolite/SM
+metabolize/DSG
+metacarpal/SM
+metacarpi
+metacarpus/M
+metal/SMD
+metalanguage/MS
+metalinguistic
+metalized
+metallic
+metallurgic
+metallurgical
+metallurgist/MS
+metallurgy/M
+metalwork/MRZG
+metalworker/M
+metalworking/M
+metamorphic
+metamorphism/M
+metamorphose/DSG
+metamorphosis/M
+metaphor/MS
+metaphoric
+metaphorical/Y
+metaphysical/Y
+metaphysics/M
+metastability
+metastable
+metastases
+metastasis/M
+metastasize/GDS
+metastatic
+metatarsal/SM
+metatarsi
+metatarsus/M
+metatheses
+metathesis/M
+metathesizes
+mete/MZGDRS
+metempsychoses
+metempsychosis/M
+meteor/MS
+meteoric
+meteorically
+meteorite/SM
+meteoroid/SM
+meteorologic
+meteorological
+meteorologist/SM
+meteorology/M
+meter/GMD
+methadone/M
+methamphetamine/M
+methane/M
+methanol/M
+methinks
+methionine
+method/MS
+methodical/YP
+methodicalness/M
+methodological/Y
+methodology/SM
+methought
+meths
+methyl/M
+methylated
+methylene
+meticulous/YP
+meticulousness/M
+metier/MS
+metonymy
+metric/S
+metrical/Y
+metricate/GNDS
+metrication/M
+metricize/GDS
+metro/SM
+metronome/MS
+metronomic
+metropolis/MS
+metropolitan
+mettle/M
+mettlesome
+mew/SGMD
+mewl/DSG
+mews/M
+mezzanine/MS
+mezzo/SM
+mfg
+mfr/S
+mg
+mgr
+mi/MNX
+miasma/MS
+mic/S
+mica/M
+mice
+micelles
+mick/S
+mickey/MS
+micro/SM
+microanalyses
+microbe/MS
+microbial
+microbiological
+microbiologist/SM
+microbiology/M
+microbrewery/SM
+microchip/MS
+microcircuit/SM
+microcode
+microcomputer/SM
+microcosm/MS
+microcosmic
+microdensitometer
+microdot/SM
+microeconomics/M
+microelectronic/S
+microelectronics/M
+microfarad
+microfiber/MS
+microfiche/M
+microfilm/GMDS
+microfloppies/S
+micrograms
+micrograph
+microgravity
+microgroove/MS
+microhydrodynamics
+microlight/SM
+micromanage/GLDS
+micromanagement/M
+micrometeorite/MS
+micrometer/MS
+micron/MS
+microorganism/MS
+microphone/SM
+microprocessor/SM
+microprogram
+microscope/SM
+microscopic
+microscopical/Y
+microscopist
+microscopy/M
+microsecond/SM
+microsurgery/M
+microwave/DSMGB
+microwaveable
+mid
+midair/M
+midday/M
+midden/MS
+middle/MGS
+middlebrow/SM
+middleman/M
+middlemen
+middlemost
+middleweight/SM
+middy/SM
+midfield/RZ
+midge/SM
+midget/MS
+midi/MS
+midland/MS
+midlife/M
+midmost
+midnight/SM
+midpoint/MS
+midrib/MS
+midriff/MS
+midsection/MS
+midshipman/M
+midshipmen
+midships
+midsized
+midst/M
+midstream/M
+midsummer/M
+midterm/MS
+midtown/M
+midway/MS
+midweek/MS
+midwicket
+midwife/MGDS
+midwifery/SM
+midwinter/M
+midwives
+midyear/MS
+mien/M
+miff/DSG
+might/SM
+mightily
+mightiness/M
+mightn't
+mighty/TRP
+mignonette/SM
+migraine/MS
+migrant/MS
+migrate/AGDS
+migration/SM
+migratory
+mikado/MS
+mike/MGDS
+mil/SZMR
+milady/SM
+milch
+mild/MRYTP
+mildew/SMDG
+mildewy
+mildness/M
+mile/MS
+mileage/SM
+mileometer/S
+milepost/MS
+miler/M
+milestone/MS
+milieu/SM
+militancy/M
+militant/MYS
+militarily
+militarism/M
+militarist/SM
+militaristic
+militarization/CM
+militarize/CDSG
+military/M
+militate/GDS
+militia/SM
+militiaman/M
+militiamen
+milk/MDRSZG
+milker/M
+milkiness/M
+milkmaid/MS
+milkman/M
+milkmen
+milkshake/SM
+milksop/MS
+milkweed/SM
+milky/RTP
+mill/MDRSZGJ
+millage/M
+millenarian
+millennial
+millennium/SM
+miller/M
+millet/M
+milliard/MS
+millibar/MS
+milligram/MS
+milliliter/MS
+millimeter/MS
+milliner/MS
+millinery/M
+milling/M
+million/HSM
+millionaire/MS
+millionairess/S
+millionth/M
+millionths
+millipede/SM
+millisecond/MS
+millpond/SM
+millrace/SM
+millstone/SM
+millstream/MS
+millwright/MS
+milquetoast/SM
+milt/MDSG
+mime/MGDS
+mimeograph/MDG
+mimeographs
+mimetic
+mimic/SM
+mimicked
+mimicker/SM
+mimicking
+mimicry/SM
+mimosa/SM
+min
+minaret/MS
+minatory
+mince/DRSMZG
+mincemeat/M
+mincer/M
+mind's
+mind/ADRSZG
+mindbogglingly
+minded/P
+mindful/YP
+mindfulness/M
+mindless/YP
+mindlessness/M
+mindset/MS
+mine/MZGNDRSX
+minefield/SM
+miner/M
+mineral/MS
+mineralization
+mineralogical
+mineralogist/SM
+mineralogy/M
+mineshaft
+minestrone/M
+minesweeper/MS
+mineworkers
+mingle/DSG
+mingy
+mini/MS
+miniature/MS
+miniaturist/SM
+miniaturization/M
+miniaturize/DSG
+minibar/S
+minibike/SM
+minibus/MS
+minicab/S
+minicam/MS
+minicomputer/MS
+minifloppies/S
+minim/SM
+minimal/Y
+minimalism/M
+minimalist/MS
+minimalistic
+minimality
+minimization
+minimize/DRSG
+minimum/MS
+mining/M
+minion/M
+miniseries/M
+miniskirt/MS
+minister/SGMD
+ministerial/Y
+ministrant/SM
+ministration/MS
+ministry/SM
+minivan/MS
+mink/MS
+minke
+minnesinger/SM
+minnow/SM
+minor/SMDG
+minority/SM
+minotaur/S
+minoxidil/M
+minster/MS
+minstrel/SM
+minstrelsy/M
+mint/MDRSZG
+mintage/M
+minter/M
+minty/RT
+minuend/MS
+minuet/SM
+minus/MS
+minuscule/MS
+minute/PDRSMYTG
+minuteman/M
+minutemen
+minuteness/M
+minutia/M
+minutiae
+minx/MS
+miracle/MS
+miraculous/YP
+mirage/SM
+mire/MGDS
+mirror/GSMD
+mirth/M
+mirthful/PY
+mirthfulness/M
+mirthless/Y
+miry/RT
+misaddress/DSG
+misadventure/SM
+misaligned
+misalignment/M
+misalliance/MS
+misanalysed
+misanthrope/SM
+misanthropic
+misanthropically
+misanthropist/SM
+misanthropy/M
+misapplication/M
+misapply/DSGNX
+misapprehend/SDG
+misapprehension/MS
+misappropriate/DSXGN
+misappropriation/M
+misbegotten
+misbehave/GDS
+misbehavior/M
+misc
+miscalculate/GNXDS
+miscalculation/M
+miscall/DSG
+miscarriage/SM
+miscarry/GDS
+miscast/SG
+miscegenation/M
+miscellanea
+miscellaneous/Y
+miscellany/SM
+mischance/SM
+mischief/M
+mischievous/YP
+mischievousness/M
+miscibility/M
+miscible
+misclassified
+miscomprehended
+misconceive/DSG
+misconception/SM
+misconduct/MDGS
+misconfiguration
+misconstruction/SM
+misconstrue/DSG
+miscopying
+miscount/MDSG
+miscreant/SM
+miscue/DSMG
+misdeal/GMS
+misdealt
+misdeed/MS
+misdemeanor/MS
+misdiagnose/GDS
+misdiagnosis/M
+misdid
+misdirect/GSD
+misdirection/SM
+misdo/JG
+misdoes
+misdoing/M
+misdone
+miser/SBMY
+miserableness/M
+miserably
+miserliness/M
+misery/SM
+misfeasance/M
+misfeature/S
+misfield
+misfile/GDS
+misfire/MGDS
+misfit/SM
+misfitted
+misfitting
+misfortune/SM
+misgiving/MS
+misgovern/SDLG
+misgovernment/M
+misguidance/M
+misguide/DSG
+misguided/Y
+mishandle/DSG
+mishap/SM
+mishear/GS
+misheard
+mishit/S
+mishitting
+mishmash/MS
+misidentify/GDS
+misinform/DGS
+misinformation/M
+misinterpret/SGD
+misinterpretation/SM
+misjudge/DSG
+misjudgment/MS
+mislabel/GSD
+mislaid
+mislay/GS
+mislead/GS
+misleading/Y
+misled
+mismanage/LGDS
+mismanagement/M
+mismatch/GMDS
+misname/GDS
+misnomer/MS
+misogamist/SM
+misogamy/M
+misogynist/SM
+misogynistic
+misogynous
+misogyny/M
+misplace/GDSL
+misplacement/M
+misplay/GMDS
+mispositioned
+misprint/GMDS
+misprision/M
+mispronounce/GDS
+mispronunciation/SM
+misquotation/MS
+misquote/MGDS
+misread/GJS
+misreading/M
+misremember/DG
+misreport/MDSG
+misrepresent/SDG
+misrepresentation/SM
+misrule/MGDS
+miss's
+miss/EDSGV
+missal/ESM
+misshape/GDS
+misshapen
+missile/MS
+missilery/M
+mission/AMS
+missionary/SM
+missioner/SM
+missive/MS
+misspeak/GS
+misspell/GDSJ
+misspelling/M
+misspend/GS
+misspent
+misspoke
+misspoken
+misstate/LGDS
+misstatement/MS
+misstep/MS
+missus/MS
+mist's
+mist/CDRSZG
+mistakable/U
+mistake/BMGS
+mistaken/Y
+mister's
+mistily
+mistime/GDS
+mistiness/M
+mistletoe/M
+mistook
+mistral/MS
+mistranslated
+mistranslates
+mistranslating
+mistranslation/S
+mistreat/LDGS
+mistreatment/M
+mistress/MS
+mistrial/MS
+mistrust/MDSG
+mistrustful/Y
+misty/PRT
+mistype/JGDS
+misunderstand/GSJ
+misunderstanding/M
+misunderstood
+misuse/DRSMG
+mite/MZRS
+miter/MDG
+mitigate/DSGN
+mitigated/U
+mitigation/M
+mitigatory
+mitochondria
+mitochondrial
+mitoses
+mitosis/M
+mitotic
+mitt/MNSX
+mitten/M
+mix/ZGMDRSB
+mixed/U
+mixer/M
+mixture/SM
+mizzen/MS
+mizzenmast/SM
+mks
+ml
+mm
+mnemonic/MS
+mnemonically
+mo/CKHS
+moan/MDRSZG
+moaner/M
+moat/MDS
+mob's
+mob/CS
+mobbed/C
+mobbing/C
+mobile/MS
+mobility/SM
+mobilizable
+mobilization/CM
+mobilizations
+mobilize/CDSG
+mobilizer/SM
+mobster/SM
+moccasin/SM
+mocha/M
+mock/DRSZG
+mocker/M
+mockery/SM
+mocking/Y
+mockingbird/MS
+mod/STM
+modal/SM
+modality/S
+modded
+modding
+mode/MS
+model/ZGSJMDR
+modeler/M
+modeling/M
+modem/SM
+moderate/MYGNPDS
+moderateness/M
+moderation/M
+moderator/SM
+modern/MRYPTS
+modernism/M
+modernist/SM
+modernistic
+modernity/M
+modernization/SM
+modernize/DRSZG
+modernizer/M
+modernness/M
+modest/RYT
+modesty/M
+modicum/SM
+modifiable/U
+modification/M
+modified/U
+modifier/M
+modify/NDRSZGX
+modish/YP
+modishness/M
+modular
+modularity
+modularization
+modularize/DG
+modulate/CGNDS
+modulation/CM
+modulations
+modulator/MS
+module/MS
+moduli
+modulo
+modulus
+moggy
+mogul/SM
+mohair/M
+moi
+moiety/SM
+moil/MDSG
+moire/SM
+moist/XTPNRY
+moisten/DRZG
+moistener/M
+moistness/M
+moisture/M
+moisturize/ZGDRS
+moisturizer/M
+molar/SM
+molarity/S
+molasses/M
+mold/MDRJSZG
+moldboard/SM
+molder/GMD
+moldiness/M
+molding/M
+moldy/TPR
+mole/MS
+molecular
+molecularity/M
+molecule/SM
+molehill/SM
+moleskin/M
+molest/DRZGS
+molestation/SM
+molested/U
+molester/M
+moll/MS
+mollification/M
+mollify/NDSG
+mollusk/SM
+molly/SM
+mollycoddle/MGDS
+molt/MDNRSZG
+molter/M
+molybdenum/M
+mom/SM
+moment/MS
+momenta
+momentarily
+momentariness/M
+momentary/P
+momentous/YP
+momentousness/M
+momentum/M
+momma/SM
+mommy/SM
+monadic
+monarch/M
+monarchic
+monarchical
+monarchism/M
+monarchist/SM
+monarchistic
+monarchs
+monarchy/SM
+monastery/SM
+monastic/MS
+monastical/Y
+monasticism/M
+monaural
+monetarily
+monetarism/M
+monetarist/SM
+monetary
+monetize/CGDS
+money/SMD
+moneybag/MS
+moneybox/S
+moneychangers
+moneylender/MS
+moneyless
+moneymaker/SM
+moneymaking/M
+monger/MDGS
+mongol/S
+mongolism/M
+mongoloid/MS
+mongoose/MS
+mongrel/SM
+monies
+moniker/SM
+monism/M
+monist/MS
+monition/SM
+monitor/SMDG
+monitored/U
+monitory
+monk/MS
+monkey/MDGS
+monkeyshine/MS
+monkish
+monkshood/SM
+mono/M
+monochromatic
+monochrome/SM
+monocle/DSM
+monoclonal
+monocotyledon/MS
+monocotyledonous
+monocular
+monoculture
+monodic
+monodist/SM
+monody/SM
+monogamist/MS
+monogamous/Y
+monogamy/M
+monogram/SM
+monogrammed
+monogramming
+monograph/M
+monographs
+monolayers
+monolingual/MS
+monolith/M
+monolithic
+monoliths
+monologist/SM
+monologue/SM
+monomania/M
+monomaniac/MS
+monomaniacal
+monomer/SM
+monomeric
+monomial/S
+monomolecular
+mononucleosis/M
+monophonic
+monophthongs
+monoplane/SM
+monopole/S
+monopolist/SM
+monopolistic
+monopolization/M
+monopolize/DRSZG
+monopolizer/M
+monopoly/SM
+monorail/MS
+monostable
+monosyllabic
+monosyllable/MS
+monotheism/M
+monotheist/SM
+monotheistic
+monotone/MS
+monotonic
+monotonically
+monotonicity
+monotonous/YP
+monotonousness/M
+monotony/M
+monounsaturated
+monoxide/MS
+monseigneur/M
+monsieur/M
+monsignor/SM
+monsoon/SM
+monsoonal
+monster/SM
+monstrance/ASM
+monstrosity/SM
+monstrous/Y
+montage/SM
+month/MY
+monthly/SM
+months
+monument/MS
+monumental/Y
+moo/SGMD
+mooch/ZGMDRS
+moocher/M
+mood/MS
+moodily
+moodiness/M
+moody/TPR
+moon/MDSG
+moonbeam/MS
+moonless
+moonlight/SMDRZG
+moonlighter/M
+moonlighting/M
+moonlit
+moonrise
+moonscape/SM
+moonshine/MZRS
+moonshiner/M
+moonshot/MS
+moonstone/MS
+moonstruck
+moonwalk/MS
+moor/MDJSG
+moorhen/S
+mooring/M
+moorland/MS
+moose/M
+moot/DRSG
+mop/SZGMDR
+mope/MS
+moped/SM
+moper/M
+mopey
+mopier
+mopiest
+mopish
+mopped
+moppet/MS
+mopping
+moraine/SM
+moral/SMY
+morale/M
+moralist/MS
+moralistic
+moralistically
+moralities
+morality/UM
+moralization/CM
+moralize/CGDS
+moralizer/MS
+morass/MS
+moratorium/SM
+moray/SM
+morbid/YP
+morbidity/M
+morbidness/M
+mordancy/M
+mordant/SMY
+more/MS
+moreish
+morel/SM
+moreover
+mores/M
+morgue/MS
+moribund/Y
+moribundity
+morn/MJSG
+morning/M
+morocco/M
+moron/SM
+moronic
+moronically
+morose/YP
+moroseness/M
+morph/GD
+morpheme/MS
+morphemic
+morphia/M
+morphine/M
+morphing/M
+morphism/S
+morphogenesis
+morphological/Y
+morphology/SM
+morphs
+morrow/MS
+morsel/MS
+mortal/MYS
+mortality/M
+mortar/MDSG
+mortarboard/MS
+mortgage's
+mortgage/AGDS
+mortgageable
+mortgagee/MS
+mortgagor/MS
+mortician/MS
+mortification/M
+mortify/NGDS
+mortise/DSMG
+mortuary/SM
+mosaic/MS
+mosey/SGD
+mosh/DSG
+mosque/MS
+mosquito/M
+mosquitoes
+moss/MS
+mossback/SM
+mossy/TR
+most/MY
+mot/SM
+mote's
+mote/KCXSVN
+motel/SM
+motet/SM
+moth/M
+mothball/GMDS
+mother/MDYSG
+motherboard/SM
+motherfucker/MS!
+motherfucking/!
+motherhood/M
+motherland/MS
+motherless
+motherliness/M
+moths
+motif/SM
+motile/S
+motility/M
+motion/KCM
+motioned
+motioning
+motionless/YP
+motionlessness/M
+motivate/CDSG
+motivated/U
+motivation/MS
+motivational
+motivator/SM
+motive/MS
+motiveless
+motley/MS
+motlier
+motliest
+motocross/MS
+motor/SGMD
+motorbike/MGDS
+motorboat/MS
+motorcade/MS
+motorcar/SM
+motorcycle/DSMG
+motorcyclist/MS
+motorist/SM
+motorization/M
+motorize/DSG
+motorman/M
+motormen
+motormouth/M
+motormouths
+motorway/SM
+mottle/GDS
+motto/M
+mottoes
+moue/MS
+mound/SGMD
+mount/AEDMGS
+mountable
+mountain/SM
+mountaineer/GMDS
+mountaineering/M
+mountainous
+mountainside/SM
+mountaintop/MS
+mountebank/MS
+mounted/UC
+mounter/MS
+mounties
+mounting's
+mountings
+mourn/SZGDR
+mourner/M
+mournful/YP
+mournfuller
+mournfullest
+mournfulness/M
+mourning/M
+mouse/DRSMZG
+mouser/M
+mousetrap/SM
+mousetrapped
+mousetrapping
+mousiness/M
+moussaka/S
+mousse/MGDS
+mousy/PTR
+mouth/GMD
+mouthful/MS
+mouthiness/M
+mouthorgan
+mouthpiece/MS
+mouths
+mouthwash/MS
+mouthwatering
+mouthy/PTR
+mouton/M
+movable/SM
+move/AMZGDRSB
+moved/U
+movement/SM
+mover/AM
+movie/SM
+moviegoer/SM
+moving/U
+movingly
+mow/SZGMDR
+mower/M
+moxie/M
+mozzarella/M
+mp
+mpg
+mph
+mt
+mtg
+mtge
+mu/SM
+much/MP
+mucilage/M
+mucilaginous
+muck/MDSG
+muckrake/DRSZG
+muckraker/M
+mucky/TR
+mucosa
+mucous
+mucus/M
+mud/M
+muddily
+muddiness/M
+muddle/MGDS
+muddleheaded
+muddy/PTGDRS
+mudflap/S
+mudflat/MS
+mudflow/S
+mudguard/SM
+mudlarks
+mudpack/S
+mudroom/MS
+mudslide/MS
+mudslinger/SM
+mudslinging/M
+muenster/M
+muesli
+muezzin/MS
+muff/MDSG
+muffin/MS
+muffle/ZGDRS
+muffler/M
+mufti/SM
+mug/SM
+mugful/MS
+mugged
+mugger/MS
+mugginess/M
+mugging/MS
+muggins
+muggy/PTR
+mugshot/MS
+mugwump/MS
+mujaheddin
+mukluk/MS
+mulatto/M
+mulattoes
+mulberry/SM
+mulch/GMDS
+mulct/SGMD
+mule/MS
+muleskinner/SM
+muleteer/MS
+mulish/PY
+mulishness/M
+mull/DSG
+mullah/M
+mullahs
+mullein/M
+mullet/MS
+mulligan/SM
+mulligatawny/M
+mullion/SMD
+multichannel
+multicolor/D
+multicultural
+multiculturalism/M
+multidimensional
+multidisciplinary
+multifaceted
+multifamily
+multifarious/PY
+multifariousness/M
+multiform
+multifunction
+multifunctional
+multilateral/Y
+multilayer
+multilevel
+multilingual
+multilingualism/M
+multimedia/M
+multimeter
+multimillion
+multimillionaire/MS
+multinational/MS
+multiparty
+multiphase
+multiple/MS
+multiplex/ZGMDRS
+multiplexer/M
+multiplicand/SM
+multiplication/M
+multiplicative
+multiplicity/SM
+multiplier/M
+multiply/NXZGDRS
+multiprocessing
+multiprocessor/SM
+multiprogramming
+multipurpose
+multiracial
+multistage
+multistory
+multitask/SG
+multitasking/M
+multitude/SM
+multitudinous
+multivalued
+multivariate
+multivitamin/SM
+mum/SM
+mumble/JMZGDRS
+mumbler/M
+mumbletypeg/M
+mummer/MS
+mummery/M
+mummification/M
+mummify/NGDS
+mummy/SM
+mumps/M
+mun
+munch/ZGDRS
+munchies/M
+munchkin/SM
+mundane/SY
+mung/DSG
+municipal/SMY
+municipality/SM
+munificence/M
+munificent/Y
+munition/MDGS
+muons
+mural/SM
+muralist/SM
+murder/ZGMDRS
+murderer/M
+murderess/MS
+murderous/Y
+murk/MS
+murkily
+murkiness/M
+murky/PTR
+murmur/ZGJMDRS
+murmurer/M
+murmuring/M
+murmurous
+murrain/M
+muscat/MS
+muscatel/SM
+muscle/MGDS
+musclebound
+muscleman
+musclemen
+muscly
+muscular/Y
+muscularity/M
+musculature/M
+muse/MGDSJ
+musette/MS
+museum/MS
+mush/MDRSZG
+mushiness/M
+mushroom/GSMD
+mushy/PTR
+music/SM
+musical/MYS
+musicale/MS
+musicality/M
+musician/SMY
+musicianship/M
+musicological
+musicologist/MS
+musicology/M
+musing/MY
+musk/M
+muskeg/MS
+muskellunge/SM
+musket/MS
+musketeer/MS
+musketry/M
+muskie/M
+muskiness/M
+muskmelon/SM
+muskox/MN
+muskrat/MS
+musky/PTRS
+muslin/M
+muss/MDSG
+mussel/MS
+mussy/TR
+must/MRSZ
+mustache/MDS
+mustachio/SMD
+mustang/MS
+mustard/M
+muster/GMD
+mustily
+mustiness/M
+mustn't
+musty/PTR
+mutability/M
+mutably
+mutagen/MS
+mutant/MS
+mutate/XGNVDS
+mutation/M
+mutational
+mute/MYTGDRSPB
+muteness/M
+mutilate/DSGNX
+mutilated/U
+mutilation/M
+mutilator/SM
+mutineer/SM
+mutinous/Y
+mutiny/GDSM
+mutt/MS
+mutter/ZGJMDRS
+mutterer/M
+muttering/M
+mutton/M
+muttonchops/M
+mutual/Y
+mutuality/M
+muumuu/MS
+muzak
+muzzily
+muzzle/DSMG
+muzzled/U
+muzzy/P
+my
+mycologist/SM
+mycology/M
+myelitis/M
+myna/MS
+myocardial
+myopia/M
+myopic
+myopically
+myriad/SM
+myrmidon/MS
+myrrh/M
+myrtle/SM
+mys
+myself
+mysterious/YP
+mysteriousness/M
+mystery/SM
+mystic/SM
+mystical/Y
+mysticism/M
+mystification/CM
+mystify/CDSGN
+mystique/M
+myth/M
+mythic
+mythical
+mythological
+mythologist/MS
+mythologize/GDS
+mythology/SM
+myths
+myxomatosis
+n/IKTH
+nab/S
+nabbed
+nabbing
+nabob/SM
+nacelle/SM
+nacho/SM
+nacre/M
+nacreous
+nadir/SM
+nae
+naff/RT
+nag/SM
+nagged
+nagger/MS
+nagging
+nagware/S
+nah
+naiad/SM
+naif/MS
+nail/MDSG
+nailbrush/MS
+naive/RYT
+naivete/M
+naivety/M
+naked/TPRY
+nakedness/M
+name's
+name/AGDS
+nameable/U
+named/U
+namedrop
+namedropping/M
+nameless/Y
+namely
+nameplate/MS
+namesake/SM
+naming/S
+nan/S
+nanny/SM
+nanobot/S
+nanometer/S
+nanosecond/SM
+nanotechnology/S
+nap/SM
+napalm/MDSG
+nape/MS
+naphtha/M
+naphthalene/M
+napkin/MS
+napless
+napoleon/SM
+napped
+napper/MS
+napping
+nappy/TRSM
+narc/MS
+narcissism/M
+narcissist/MS
+narcissistic
+narcissus/M
+narcolepsy/M
+narcoleptic
+narcoses
+narcosis/M
+narcotic/SM
+narcotization/M
+narcotize/GDS
+narky
+narrate/GNVDSX
+narration/M
+narrative/SM
+narratology
+narrator/SM
+narrow/PTGMDRYS
+narrowness/M
+narwhal/MS
+nary
+nasal/SMY
+nasality/M
+nasalization/M
+nasalize/DSG
+nascence/AM
+nascent/A
+nastily
+nastiness/M
+nasturtium/SM
+nasty/PTR
+natal
+natch
+nation/MS
+national/MYS
+nationalism/M
+nationalist/MS
+nationalistic
+nationalistically
+nationality/SM
+nationalization/SM
+nationalize/CGDS
+nationalized/A
+nationhood/M
+nationwide
+native/MS
+nativity/SM
+natl
+natter/GMDS
+nattily
+nattiness/M
+natty/PTR
+natural's
+natural/UPY
+naturalism/M
+naturalist/MS
+naturalistic
+naturalization/M
+naturalize/GDS
+naturalness/UM
+naturals
+nature's
+nature/CS
+naturism
+naturist/S
+naught/MS
+naughtily
+naughtiness/M
+naughty/PTR
+nausea/M
+nauseate/GDS
+nauseating/Y
+nauseous/YP
+nauseousness/M
+nautical/Y
+nautilus/MS
+naval
+nave/MS
+navel/SM
+navigability/M
+navigable/U
+navigate/DSGN
+navigation/M
+navigational
+navigator/MS
+navvy/S
+navy/SM
+nay/SM
+naysayer/MS
+ne'er
+neanderthal/SM
+neap/MS
+near/DRYSPTG
+nearby
+nearly/TR
+nearness/M
+nearside
+nearsighted/PY
+nearsightedness/M
+neat/NRYPXT
+neaten/GD
+neath
+neatness/M
+nebula/M
+nebulae
+nebular
+nebulosity
+nebulous/YP
+nebulousness/M
+necessarily/U
+necessary/SM
+necessitate/GDS
+necessitous
+necessity/SM
+neck/MDSG
+neckband/S
+neckerchief/MS
+necking/M
+necklace/MGDSJ
+neckline/MS
+necktie/MS
+necrology/M
+necromancer/MS
+necromancy/M
+necromantic
+necrophilia
+necrophiliac/S
+necropolis/MS
+necropsy
+necroses
+necrosis/M
+necrotic
+nectar/M
+nectarine/MS
+nee
+need/MDSG
+needed/U
+needful/Y
+neediness/M
+needle/MGDS
+needlecraft
+needlepoint/M
+needless/PY
+needlessness/M
+needlewoman/M
+needlewomen
+needlework/M
+needn't
+needy/PTR
+nefarious/PY
+nefariousness/M
+neg
+negate/DSGNVX
+negation/M
+negative/MYGPDS
+negativeness/M
+negativism/M
+negativity/M
+neglect/SGMD
+neglectful/PY
+neglectfulness/M
+negligee/MS
+negligence/M
+negligent/Y
+negligibility
+negligible
+negligibly
+negotiability/M
+negotiable/A
+negotiate/ADSGN
+negotiation/AM
+negotiations
+negotiator/MS
+negritude/M
+negro
+negroid
+neigh/MDG
+neighbor/SMDYG
+neighborhood/SM
+neighborliness/M
+neighs
+neither
+nelson/SM
+nematode/SM
+nemeses
+nemesis/M
+neoclassic
+neoclassical
+neoclassicism/M
+neocolonialism/M
+neocolonialist/MS
+neoconservative/SM
+neodymium/M
+neolithic
+neologism/SM
+neon/M
+neonatal
+neonate/MS
+neophilia/S
+neophyte/MS
+neoplasm/MS
+neoplastic
+neoprene/M
+nepenthe/M
+nephew/SM
+nephrite/M
+nephritic
+nephritis/M
+nepotism/M
+nepotist/SM
+nepotistic
+neptunium/M
+nerd/MS
+nerdy/RT
+nerve's
+nerve/UDSG
+nerveless/PY
+nervelessness/M
+nerviness/M
+nervous/YP
+nervousness/M
+nervy/TPR
+nest/BMDSG
+nestle/GJDS
+nestling/M
+net/SM
+netball
+nether
+nethermost
+netherworld/M
+netiquette/S
+netted
+netter/S
+netting/M
+nettle/MGDS
+nettlesome
+network/SGMD
+networking/M
+neural/Y
+neuralgia/M
+neuralgic
+neurasthenia/M
+neurasthenic/MS
+neuritic/MS
+neuritis/M
+neurobiology
+neurological/Y
+neurologist/MS
+neurology/M
+neuron/MS
+neuronal
+neurophysiology
+neuroscience
+neuroses
+neurosis/M
+neurosurgeon/MS
+neurosurgery/M
+neurotic/MS
+neurotically
+neurotransmitter/SM
+neut
+neuter/MDGS
+neutral/SMY
+neutralism/M
+neutralist/SM
+neutrality/M
+neutralization/M
+neutralize/DRSZG
+neutralizer/M
+neutrino/SM
+neutron/SM
+never
+nevermore
+nevertheless
+nevi
+nevus/M
+new/STMRYP
+newbie/MS
+newborn/SM
+newcomer/SM
+newel/SM
+newfangled
+newish
+newline/S
+newlywed/SM
+newness/M
+news/M
+newsagent/S
+newsboy/SM
+newscast/SMRZ
+newscaster/M
+newsdealer/SM
+newsflash/S
+newsgirl/SM
+newsgroup/MS
+newshound/S
+newsletter/SM
+newsman/M
+newsmen
+newspaper/MS
+newspaperman/M
+newspapermen
+newspaperwoman/M
+newspaperwomen
+newsprint/M
+newsreader/S
+newsreel/MS
+newsroom/MS
+newsstand/SM
+newsweekly/SM
+newswoman/M
+newswomen
+newsworthiness/M
+newsworthy/PRT
+newsy/TR
+newt/MS
+newton/MS
+next/M
+nexus/MS
+niacin/M
+nib/SM
+nibble/MZGDRS
+nibbler/M
+nice/PYTR
+niceness/M
+nicety/SM
+niche/SM
+nick/MDRSZG
+nickel/MS
+nickelodeon/MS
+nicker/MDG
+nickle/S
+nickname/DSMG
+nicotine/M
+niece/SM
+niff
+niffy
+niftily
+nifty/TR
+niggard/SMY
+niggardliness/M
+nigger/SM!
+niggle/MZGDRS
+niggler/M
+nigh/RT
+night/SMY
+nightcap/SM
+nightclothes/M
+nightclub/SM
+nightclubbed
+nightclubbing
+nightdress/MS
+nightfall/M
+nightgown/SM
+nighthawk/SM
+nightie/SM
+nightingale/MS
+nightlife/M
+nightlight/S
+nightlong
+nightmare/SM
+nightmarish
+nightshade/SM
+nightshirt/SM
+nightspot/MS
+nightstand/SM
+nightstick/SM
+nighttime/M
+nightwatchman
+nightwatchmen
+nightwear/M
+nihilism/M
+nihilist/MS
+nihilistic
+nil/M
+nimbi
+nimble/TPR
+nimbleness/M
+nimbly
+nimbus/M
+nimby
+nimrod/MS
+nincompoop/SM
+nine/MS
+ninepence
+ninepin/MS
+ninepins/M
+nineteen/SMH
+nineteenth/M
+nineteenths
+ninetieth/M
+ninetieths
+ninety/HSM
+ninja/SM
+ninny/SM
+ninth/M
+ninths
+niobium/M
+nip/SM
+nipped
+nipper/MS
+nippiness/M
+nipping
+nipple/MS
+nippy/TPR
+nirvana/M
+nisei/M
+nit/SMR
+niter/M
+nitpick/SZGDR
+nitpicker/M
+nitpicking/M
+nitrate/DSMGN
+nitration/M
+nitric
+nitride/S
+nitrification/M
+nitrite/SM
+nitrocellulose/M
+nitrogen/M
+nitrogenous
+nitroglycerin/M
+nitrous
+nitwit/MS
+nix/GMDS
+no/SM
+nob/SY
+nobble/GDS
+nobelium/M
+nobility/M
+noble/RSPMT
+nobleman/M
+noblemen
+nobleness/M
+noblewoman/M
+noblewomen
+nobody/SM
+nocturnal/Y
+nocturne/MS
+nod/SM
+nodal
+nodded
+nodding
+noddle/MS
+noddy
+node/MS
+nodular
+nodule/MS
+noel/MS
+noes
+noggin/MS
+nohow
+noise/DSMG
+noiseless/PY
+noiselessness/M
+noisemaker/SM
+noisily
+noisiness/M
+noisome
+noisy/PTR
+nomad/SM
+nomadic
+nomenclature/MS
+nominal/Y
+nominate/ACGNVDS
+nomination's/A
+nomination/CSM
+nominative/SM
+nominator/CSM
+nominee/MS
+non
+nonabrasive
+nonabsorbent/SM
+nonacademic
+nonacceptance/M
+nonacid
+nonactive/MS
+nonaddictive
+nonadhesive
+nonadjacent
+nonadjustable
+nonadministrative
+nonage/MS
+nonagenarian/SM
+nonaggression/M
+nonalcoholic
+nonaligned
+nonalignment/M
+nonallergic
+nonappearance/SM
+nonassignable
+nonathletic
+nonattendance/M
+nonautomotive
+nonavailability/M
+nonbasic
+nonbeliever/MS
+nonbelligerent/MS
+nonbinding
+nonbreakable
+nonburnable
+noncaloric
+noncancerous
+nonce/M
+nonchalance/M
+nonchalant/Y
+nonchargeable
+nonclerical/SM
+nonclinical
+noncollectable
+noncom/MS
+noncombat
+noncombatant/SM
+noncombustible
+noncommercial/SM
+noncommittal/Y
+noncommunicable
+noncompeting
+noncompetitive
+noncompliance/M
+noncomplying
+noncomprehending
+nonconducting
+nonconductor/SM
+nonconforming
+nonconformism
+nonconformist/SM
+nonconformity/M
+nonconsecutive
+nonconstructive
+noncontagious
+noncontinuous
+noncontributing
+noncontributory
+noncontroversial
+nonconvertible
+noncooperation/M
+noncorroding
+noncorrosive
+noncredit
+noncriminal/MS
+noncritical
+noncrystalline
+noncumulative
+noncustodial
+nondairy
+nondeductible/M
+nondelivery/SM
+nondemocratic
+nondenominational
+nondepartmental
+nondepreciating
+nondescript/Y
+nondestructive
+nondetachable
+nondisciplinary
+nondisclosure/M
+nondiscrimination/M
+nondiscriminatory
+nondramatic
+nondrinker/SM
+nondrying
+none
+noneducational
+noneffective
+nonelastic
+nonelectric
+nonelectrical
+nonempty
+nonenforceable
+nonentity/SM
+nonequivalent/SM
+nonessential
+nonesuch/MS
+nonetheless
+nonevent/MS
+nonexchangeable
+nonexclusive
+nonexempt/M
+nonexistence/M
+nonexistent
+nonexplosive/SM
+nonfactual
+nonfading
+nonfat
+nonfatal
+nonfattening
+nonferrous
+nonfiction/M
+nonfictional
+nonflammable
+nonflowering
+nonfluctuating
+nonflying
+nonfood/M
+nonfreezing
+nonfunctional
+nongovernmental
+nongranular
+nonhazardous
+nonhereditary
+nonhuman
+nonidentical
+noninclusive
+nonindependent
+nonindustrial
+noninfectious
+noninflammatory
+noninflationary
+noninflected
+nonintellectual/SM
+noninterchangeable
+noninterference/M
+nonintervention/M
+nonintoxicating
+noninvasive
+nonirritating
+nonjudgmental
+nonjudicial
+nonlegal
+nonlethal
+nonlinear
+nonliterary
+nonliving/M
+nonmagnetic
+nonmalignant
+nonmember/MS
+nonmetal/SM
+nonmetallic
+nonmigratory
+nonmilitant
+nonmilitary
+nonnarcotic/SM
+nonnative/MS
+nonnegotiable
+nonnuclear
+nonnumerical
+nonobjective
+nonobligatory
+nonobservance/M
+nonobservant
+nonoccupational
+nonoccurence/M
+nonofficial
+nonoperational
+nonoperative
+nonparallel/SM
+nonparametric
+nonpareil/MS
+nonparticipant/MS
+nonparticipating
+nonpartisan/MS
+nonpaying
+nonpayment/MS
+nonperformance/M
+nonperforming
+nonperishable
+nonperson/MS
+nonphysical/Y
+nonplus/S
+nonplussed
+nonplussing
+nonpoisonous
+nonpolitical
+nonpolluting
+nonporous
+nonpracticing
+nonprejudicial
+nonprescription
+nonproductive
+nonprofessional/MS
+nonprofit/SBM
+nonproliferation/M
+nonpublic
+nonpunishable
+nonracial
+nonradioactive
+nonrandom
+nonreactive
+nonreciprocal/MS
+nonreciprocating
+nonrecognition/M
+nonrecoverable
+nonrecurring
+nonredeemable
+nonrefillable
+nonrefundable
+nonreligious
+nonrenewable
+nonrepresentational
+nonresident/SM
+nonresidential
+nonresidual/M
+nonresistance/M
+nonresistant
+nonrestrictive
+nonreturnable/SM
+nonrhythmic
+nonrigid
+nonsalaried
+nonscheduled
+nonscientific
+nonscoring
+nonseasonal
+nonsectarian
+nonsecular
+nonsegregated
+nonsense/MS
+nonsensical/Y
+nonsensitive
+nonsexist
+nonsexual
+nonskid
+nonslip
+nonsmoker/SM
+nonsmoking
+nonsocial
+nonspeaking
+nonspecialist/SM
+nonspecializing
+nonspecific
+nonspiritual/MS
+nonstaining
+nonstandard
+nonstarter/SM
+nonstick
+nonstop
+nonstrategic
+nonstriking
+nonstructural
+nonsuccessive
+nonsupport/MG
+nonsurgical
+nonsustaining
+nonsympathizer/M
+nontarnishable
+nontaxable
+nontechnical
+nontenured
+nontheatrical
+nonthinking
+nonthreatening
+nontoxic
+nontraditional
+nontransferable
+nontransparent
+nontrivial
+nontropical
+nonuniform
+nonunion
+nonuser/MS
+nonvenomous
+nonverbal
+nonviable
+nonviolence/M
+nonviolent/Y
+nonvirulent
+nonvocal
+nonvocational
+nonvolatile
+nonvoter/MS
+nonvoting
+nonwhite/MS
+nonworking
+nonyielding
+nonzero
+noodle/MGDS
+nook/MS
+nookie
+nooky
+noon/MS
+noonday/M
+noontide/M
+noontime/M
+noose/SM
+nope
+nor
+nor'easter
+noradrenalin
+noradrenaline
+norm/MDS
+normal/MYS
+normalcy/M
+normality/M
+normalization/MS
+normalize/DRSBZG
+normative
+north/ZMR
+northbound
+northeast/MRZ
+northeaster/MY
+northeastern
+northeastward/S
+norther/MY
+northerly/SM
+northern/ZR
+northerner/M
+northernmost
+northmen
+northward/S
+northwest/ZMR
+northwester/MY
+northwestern
+northwestward/S
+nose/MGDS
+nosebag/S
+nosebleed/MS
+nosecone/SM
+nosedive/DSMG
+nosegay/SM
+nosh/MDRSZG
+nosher/M
+nosily
+nosiness/M
+nostalgia/M
+nostalgic
+nostalgically
+nostril/MS
+nostrum/MS
+nosy/RPT
+not/B
+notability/SM
+notable/SM
+notably
+notarial
+notarization/M
+notarize/GDS
+notary/SM
+notate/GDS
+notation/FCSM
+notational/Y
+notch/GMDS
+note's
+note/FCSDG
+notebook/MS
+notelet/S
+notepad/S
+notepaper/M
+noteworthiness/M
+noteworthy/P
+nothing/PSM
+nothingness/M
+notice/MGDS
+noticeable/U
+noticeably
+noticeboard/S
+noticed/U
+notifiable
+notification/M
+notifier/M
+notify/NXDRSZG
+notion/MS
+notional/Y
+notoriety/M
+notorious/Y
+notwithstanding
+notwork/S
+nougat/MS
+noun/KMS
+nounal
+nourish/DSLG
+nourishment/M
+nous
+nova/MS
+novae
+novel/SM
+novelette/SM
+novelist/SM
+novelistic
+novelization/SM
+novelize/DSG
+novella/MS
+novelty/SM
+novena/MS
+novene
+novice/MS
+novitiate/MS
+now/M
+nowadays/M
+noway/S
+nowhere/M
+nowise
+nowt
+noxious/YP
+nozzle/MS
+nu/SM
+nuance/MDS
+nub/SM
+nubbin/MS
+nubby/TR
+nubile
+nuclear/K
+nuclease
+nucleate/DSGN
+nucleated/A
+nucleation/M
+nuclei
+nucleic
+nucleoli
+nucleolus/M
+nucleon/SM
+nucleotide/S
+nucleus/M
+nude/MTRS
+nudge/GDSM
+nudism/M
+nudist/SM
+nudity/M
+nugatory
+nugget/SM
+nuisance/MS
+nuke/MGDS
+null/S
+nullification/M
+nullify/NDSG
+nullity/M
+numb/ZTGPDRYS
+number's
+number/ASDG
+numbered/U
+numbering/S
+numberless
+numberplate
+numbers/S
+numbing/Y
+numbness/M
+numerable/I
+numeracy/IM
+numeral/SM
+numerate/XGNDS
+numeration/M
+numerator/MS
+numeric
+numerical/Y
+numerological
+numerologist/SM
+numerology/M
+numerous/Y
+numinous
+numismatic/S
+numismatics/M
+numismatist/MS
+numskull/MS
+nun/SM
+nuncio/SM
+nunnery/SM
+nuptial/MS
+nurse/MZGDRS
+nurselings
+nursemaid/MS
+nurser/M
+nursery/SM
+nurseryman/M
+nurserymen
+nursing/M
+nursling/SM
+nurture/DRSMZG
+nurturer/M
+nut/SM
+nutation
+nutcase/S
+nutcracker/MS
+nuthatch/MS
+nuthouse/S
+nutmeat/SM
+nutmeg/SM
+nutpick/SM
+nutria/SM
+nutrient/MS
+nutriment/MS
+nutrition/M
+nutritional/Y
+nutritionist/MS
+nutritious/YP
+nutritiousness/M
+nutritive
+nutshell/MS
+nutted
+nutter/S
+nuttiness/M
+nutting
+nutty/RTP
+nuzzle/DRSMZG
+nuzzler/M
+nybble/DSG
+nyetwork/S
+nylon/MS
+nylons/M
+nymph/M
+nymphet/MS
+nympho/S
+nympholepsy
+nymphomania/M
+nymphomaniac/MS
+nymphs
+o
+o'clock
+o'er
+oaf/SM
+oafish/PY
+oafishness/M
+oak/SMN
+oakum/M
+oar/SGMD
+oarlock/SM
+oarsman/M
+oarsmen
+oarswoman/M
+oarswomen
+oases
+oasis/M
+oat/SMN
+oatcake/SM
+oath/M
+oaths
+oatmeal/M
+oats/M
+ob/S
+obbligato/MS
+obduracy/M
+obdurate/PY
+obdurateness/M
+obedience/EM
+obedient/EY
+obeisance/SM
+obeisant
+obelisk/MS
+obese
+obesity/M
+obey/EDSG
+obfuscate/GNDSX
+obfuscation/M
+obfuscatory
+obi/SM
+obit/MS
+obituary/SM
+obj
+object/SGVMD
+objectify/GDSN
+objection/BSM
+objectionable/P
+objectionably
+objective/PSMY
+objectiveness/M
+objectivity/M
+objectless
+objector/MS
+objurgate/XGNDS
+objurgation/M
+oblate/NX
+oblation/M
+obligate/DSXGN
+obligation/M
+obligatorily
+obligatory
+oblige/EGDS
+obliging/U
+obligingly
+oblique/DSMYP
+obliqueness/M
+obliquity/M
+obliterate/GNDS
+obliteration/M
+oblivion/M
+oblivious/PY
+obliviousness/M
+oblong/MS
+obloquy/M
+obnoxious/YP
+obnoxiousness/M
+oboe/MS
+oboist/MS
+obscene/RYT
+obscenity/SM
+obscurantism/M
+obscurantist/MS
+obscuration
+obscure/DRSLPYTG
+obscurity/SM
+obsequies
+obsequious/PY
+obsequiousness/M
+obsequy/M
+observability
+observable/S
+observably
+observance/SM
+observant/Y
+observation/MS
+observational/Y
+observatory/SM
+observe/DRSBZG
+observed/U
+observer/M
+obsess/DSGV
+obsession/SM
+obsessional/Y
+obsessive/SMYP
+obsessiveness/M
+obsidian/M
+obsolesce/DSG
+obsolescence/M
+obsolescent
+obsolete/GDS
+obstacle/MS
+obstetric/S
+obstetrical
+obstetrician/MS
+obstetrics/M
+obstinacy/M
+obstinate/Y
+obstreperous/PY
+obstreperousness/M
+obstruct/DGVS
+obstructed/U
+obstruction/MS
+obstructionism/M
+obstructionist/SM
+obstructive/YP
+obstructiveness/M
+obtain/DBLGS
+obtainable/U
+obtainment/M
+obtrude/DSG
+obtrusion/M
+obtrusive/UYP
+obtrusiveness/UM
+obtuse/YTRP
+obtuseness/M
+obverse/SM
+obviate/DSGN
+obviation/M
+obvious/PY
+obviousness/M
+ocarina/MS
+occasion/GMDS
+occasional/Y
+occidental/SM
+occipital
+occlude/GDS
+occlusion/SM
+occlusive
+occult/MS
+occultism/M
+occultist/SM
+occupancy/SM
+occupant/SM
+occupation/AM
+occupational/Y
+occupations
+occupied/U
+occupier/SM
+occupy/ADSG
+occur/AS
+occurred/A
+occurrence/SM
+occurring/A
+ocean/SM
+oceanfront/MS
+oceangoing
+oceanic/M
+oceanographer/SM
+oceanographic
+oceanography/M
+oceanology/M
+ocelot/MS
+och/ZR
+ocher/M
+ocker/S
+octagon/MS
+octagonal
+octahedral
+octahedron
+octal
+octane/MS
+octant
+octave/MS
+octavo/MS
+octet/SM
+octogenarian/MS
+octopus/MSi
+ocular/MS
+oculist/SM
+odalisque/SM
+odd/STRYLP
+oddball/SM
+oddity/SM
+oddment/SM
+oddness/M
+odds/M
+ode/SM
+odious/YP
+odiousness/M
+odium/M
+odometer/MS
+odor/MDS
+odoriferous
+odorless
+odorous
+odyssey/MS
+oedipal
+oenology/M
+oenophile/SM
+oeuvre/MS
+of
+off/SZGDRJ
+offal/M
+offbeat/MS
+offcuts
+offend/ZGDRS
+offender/M
+offense/MS
+offensive's
+offensive/IYP
+offensiveness/IM
+offensives
+offer/JGMD
+offering/M
+offertory/SM
+offhand
+offhanded/YP
+offhandedness/M
+office/MZRS
+officeholder/MS
+officer/M
+officership/S
+official/MYSP
+officialdom/M
+officialese
+officialism/M
+officiant/SM
+officiate/DSG
+officiator/MS
+officious/YP
+officiousness/M
+offing/M
+offish
+offline
+offload/SDG
+offprint/SM
+offset/MS
+offsetting
+offshoot/MS
+offshore
+offside
+offspring/M
+offstage/S
+offtrack
+oft/TNR
+often/TR
+oftentimes
+ofttimes
+ogle/MZGDRS
+ogler/M
+ogre/MS
+ogreish
+ogress/MS
+oh/M
+ohm/SM
+ohmic
+ohmmeter/MS
+oho
+ohs
+oi
+oik/S
+oil/SGMD
+oilcan/S
+oilcloth/M
+oilcloths
+oilfield/S
+oiliness/M
+oilman
+oilmen
+oilseed
+oilskin/MS
+oilskins/M
+oily/RPT
+oink/MDSG
+ointment/SM
+okapi/SM
+okay/MSG
+okra/MS
+old/TMNRP
+oldie/SM
+oldish
+oldness/M
+oldster/MS
+ole/SMV
+oleaginous
+oleander/MS
+olefin
+oleo/M
+oleomargarine/M
+olfactory/SM
+oligarch/M
+oligarchic
+oligarchical
+oligarchs
+oligarchy/SM
+oligopoly/SM
+olive/SM
+olivine
+om/SMNX
+ombudsman/M
+ombudsmen
+omega/SM
+omelet/MS
+omen/M
+omicron/MS
+ominous/YP
+ominousness/M
+omission/MS
+omit/S
+omitted
+omitting
+omnibus/MS
+omnidirectional
+omnipotence/M
+omnipotent
+omnipresence/M
+omnipresent
+omniscience/M
+omniscient
+omnivore/MS
+omnivorous/PY
+omnivorousness/M
+on/Y
+once/M
+oncogene/SM
+oncologist/MS
+oncology/M
+oncoming
+one/SXMNP
+oneness/M
+onerous/PY
+onerousness/M
+oneself
+onetime
+ongoing
+onion/M
+onionskin/M
+online
+onlooker/SM
+onlooking
+only/T
+onomatopoeia/M
+onomatopoeic
+onomatopoetic
+onrush/MSG
+onscreen
+onset/MS
+onshore
+onside
+onslaught/MS
+onstage
+onto
+ontogeny/M
+ontological/Y
+ontology/M
+onus/MS
+onward/S
+onyx/MS
+oodles/M
+ooh/GD
+oohs
+oolitic
+oomph
+oops
+ooze/MGDS
+oozy/TR
+op/SMDG
+opacity/M
+opal/MS
+opalescence/M
+opalescent
+opaque/PYTGDRS
+opaqueness/M
+ope/S
+open/ZTGJPMDRYS
+opencast
+opened/U
+opener/M
+openhanded/P
+openhandedness/M
+openhearted
+opening/M
+openness/M
+openwork/M
+opera/MS
+operable/I
+operand/S
+operate/DSGNVX
+operatic
+operatically
+operation/M
+operational/Y
+operative/SM
+operator/SM
+operetta/SM
+ophthalmic/S
+ophthalmologist/SM
+ophthalmology/M
+opiate/SM
+opine/GNXDS
+opinion/M
+opinionated
+opioid
+opium/M
+opossum/MS
+opp
+opponent/SM
+opportune/IY
+opportunism/M
+opportunist/MS
+opportunistic
+opportunistically
+opportunity/SM
+oppose/DSG
+opposed/U
+opposite/SMYNX
+opposition/M
+oppositional
+oppress/DSGV
+oppression/SM
+oppressive/PY
+oppressiveness/M
+oppressor/MS
+opprobrious/Y
+opprobrium/M
+opt/SGD
+optic/MS
+optical/Y
+optician/SM
+optics/M
+optima
+optimal/Y
+optimality
+optimism/SM
+optimist/SM
+optimistic
+optimistically
+optimization/MS
+optimize/DRSZG
+optimized/U
+optimum/SM
+option/SMDG
+optional/Y
+optionality
+optoelectronic
+optometrist/MS
+optometry/M
+opulence/M
+opulent/Y
+opus/MS
+or
+oracle/SM
+oracular
+oral/MYS
+orange/SMP
+orangeade/MS
+orangery/SM
+orangutan/SM
+orate/GNXDS
+oration/M
+orator/SM
+oratorical/Y
+oratorio/MS
+oratory/SM
+orb/SM
+orbicular
+orbit/MDRZGS
+orbital/SM
+orbiter/M
+orchard/SM
+orchestra/MS
+orchestral
+orchestrate/XGNDS
+orchestration/M
+orchestrator
+orchid/SM
+ordain/SDLG
+ordainment/M
+ordeal/SM
+order/EAMDGS
+ordered/U
+orderings
+orderless
+orderliness/EM
+orderly/PSM
+ordinal/SM
+ordinance/SM
+ordinands
+ordinarily
+ordinariness/M
+ordinary/RSMPT
+ordinate/MNSX
+ordination/M
+ordnance/M
+ordure/M
+ore/SM
+oregano/M
+org
+organ/MS
+organdy/M
+organelle/MS
+organic/SM
+organically/I
+organism/MS
+organismic
+organist/MS
+organizable
+organization/ASM
+organizational/Y
+organize/AESDG
+organized/U
+organizer/MS
+organza/M
+orgasm/SM
+orgasmic
+orgiastic
+orgy/SM
+oriel/MS
+orient's
+orient/AEDGS
+orientable
+oriental/MS
+orientalist/S
+orientate/EDSGN
+orientated/A
+orientates/A
+orientation/AEM
+orientations
+orienteering
+orifice/MS
+orig
+origami/M
+origin/SM
+original/MYS
+originality/M
+originate/DSGN
+origination/M
+originator/MS
+oriole/SM
+orison/SM
+ormolu/M
+ornament/SGMD
+ornamental
+ornamentation/M
+ornate/YP
+ornateness/M
+orneriness/M
+ornery/PRT
+ornithological
+ornithologist/SM
+ornithology/M
+orotund
+orotundity/SM
+orphan/SMDG
+orphanage/MS
+orris/MS
+orthodontia/M
+orthodontic/S
+orthodontics/M
+orthodontist/SM
+orthodox/U
+orthodoxy/SM
+orthogonal/Y
+orthogonality
+orthographic
+orthographical/Y
+orthography/SM
+orthonormal
+orthopedic/S
+orthopedics/M
+orthopedist/MS
+orthorhombic
+orzo/M
+oscillate/XGNDS
+oscillation/M
+oscillator/MS
+oscillatory
+oscilloscope/MS
+osculate/DSXGN
+osculation/M
+osier/MS
+osmium/M
+osmosis/M
+osmotic
+osprey/SM
+ossification/M
+ossify/GNDS
+ostensible
+ostensibly
+ostentation/M
+ostentatious/Y
+osteoarthritis/M
+osteopath/M
+osteopathic
+osteopaths
+osteopathy/M
+osteoporosis/M
+ostler/S
+ostracism/M
+ostracize/GDS
+ostrich/MS
+other/SP
+otherwise
+otherworldly
+otiose
+otter/MS
+ottoman/MS
+oubliette/MS
+ouch
+ought
+oughtn't
+ounce/MS
+our/S
+ourselves
+oust/ZGDRS
+ouster/M
+out/SJGMDR
+outage/SM
+outargue/GDS
+outback/MS
+outbalance/GDS
+outbid/S
+outbidding
+outboard/MS
+outboast/DSG
+outbound
+outbox/MS
+outbreak/MS
+outbuilding/MS
+outburst/SM
+outcast/MS
+outclass/DSG
+outcome/MS
+outcrop/MS
+outcropped
+outcropping/MS
+outcry/SM
+outdated
+outdid
+outdistance/DSG
+outdo/G
+outdoes
+outdone
+outdoor/S
+outdoors/M
+outdoorsy
+outdraw/GS
+outdrawn
+outdrew
+outermost
+outerwear/M
+outface/GDS
+outfall/S
+outfield/SMRZ
+outfielder/M
+outfight/SG
+outfit/SM
+outfitted
+outfitter/MS
+outfitting
+outflank/GSD
+outflow/MS
+outfought
+outfox/GDS
+outgo/MJG
+outgoes
+outgrew
+outgrow/HGS
+outgrown
+outgrowth/M
+outgrowths
+outguess/GDS
+outgun/S
+outgunned
+outgunning
+outhit/S
+outhitting
+outhouse/SM
+outing/M
+outlaid
+outlandish/YP
+outlandishness/M
+outlast/DSG
+outlaw/SGMD
+outlawry
+outlay/SGM
+outlet/SM
+outlier/S
+outline/MGDS
+outlive/GDS
+outlook/MS
+outlying
+outmaneuver/SGD
+outmatch/GDS
+outmoded
+outnumber/DSG
+outpace/GDS
+outpatient/SM
+outperform/DSG
+outplace/L
+outplacement/M
+outplay/GDS
+outpoint/DGS
+outpost/MS
+outpouring/MS
+outproduce/DSG
+output/SM
+outputted
+outputting
+outrace/GDS
+outrage/MGDS
+outrageous/Y
+outran
+outrank/GDS
+outre
+outreach/MDSG
+outrider/MS
+outrigger/SM
+outright
+outrun/S
+outrunning
+outscore/GDS
+outsell/GS
+outset/SM
+outshine/GS
+outshone
+outshout/GDS
+outside/MZRS
+outsider/M
+outsize/MS
+outskirt/MS
+outsmart/GDS
+outsold
+outsource/DSG
+outsourcing/M
+outspend/SG
+outspent
+outspoken/PY
+outspokenness/M
+outspread/GS
+outstanding/Y
+outstation/MS
+outstay/DGS
+outstretch/GDS
+outstrip/S
+outstripped
+outstripping
+outta
+outtake/MS
+outvote/GDS
+outward/YS
+outwear/GS
+outweigh/GD
+outweighs
+outwit/S
+outwith
+outwitted
+outwitting
+outwore
+outwork/MDRSZG
+outworn
+ouzo/MS
+ova
+oval/MS
+ovarian
+ovary/SM
+ovate/NX
+ovation/M
+oven/MS
+ovenbird/SM
+ovenproof
+ovenware
+over/MYS
+overabundance/M
+overabundant
+overachieve/ZGDRS
+overachiever/M
+overact/GVSD
+overage/SM
+overaggressive
+overall/SM
+overallocation
+overalls/M
+overambitious
+overanxious
+overarching
+overarm/GSD
+overate
+overattentive
+overawe/DSG
+overbalance/DSMG
+overbear/GS
+overbearing/Y
+overbid/SM
+overbidding
+overbite/MS
+overblown
+overboard
+overbold
+overbook/DGS
+overbore
+overborne
+overbought
+overbuild/SG
+overbuilt
+overburden/SDG
+overbuy/GS
+overcame
+overcapacity/M
+overcapitalize/GDS
+overcareful
+overcast/MGS
+overcautious
+overcharge/MGDS
+overclock/SDG
+overcloud/SDG
+overcoat/MS
+overcome/GS
+overcommitment/S
+overcompensate/GNDS
+overcompensation/M
+overcomplexity
+overcomplicated
+overconfidence/M
+overconfident
+overconscientious
+overcook/DGS
+overcritical
+overcrowd/GSD
+overcrowding/M
+overdecorate/DSG
+overdependent
+overdetermined
+overdevelop/SGD
+overdid
+overdo/G
+overdoes
+overdone
+overdose/MGDS
+overdraft/SM
+overdraw/GS
+overdrawn
+overdress/GMDS
+overdrew
+overdrive/SM
+overdub/SM
+overdubbed
+overdubbing
+overdue
+overeager
+overeat/GSN
+overemotional
+overemphasis/M
+overemphasize/DSG
+overenthusiastic
+overestimate/DSMGN
+overestimation/M
+overexcite/GDS
+overexercise/DSG
+overexert/GSD
+overexertion/M
+overexpose/GDS
+overexposure/M
+overextend/GDS
+overfed
+overfeed/GS
+overfill/DGS
+overfishing
+overflew
+overflight/MS
+overflow/MDSG
+overflown
+overfly/GS
+overfond
+overfull
+overgeneralize/DSG
+overgenerous
+overgraze/DSG
+overgrew
+overground
+overgrow/HSG
+overgrown
+overgrowth/M
+overhand/MS
+overhang/MSG
+overhasty
+overhaul/MDSG
+overhead/MS
+overhear/SG
+overheard
+overheat/DSG
+overhung
+overincredulous
+overindulge/GDS
+overindulgence/M
+overindulgent
+overinflated
+overjoy/GSD
+overkill/M
+overladen
+overlaid
+overlain
+overland
+overlap/SM
+overlapped
+overlapping
+overlarge
+overlay/GSM
+overleaf
+overlie
+overload/GMDS
+overlong
+overlook/GMDS
+overlord/MS
+overly/SG
+overmanned
+overmanning
+overmaster/SGD
+overmatching
+overmodest
+overmuch/S
+overnice
+overnight/MS
+overoptimism/M
+overoptimistic
+overpaid
+overparticular
+overpass/MS
+overpay/LGS
+overplay/GDS
+overpopulate/GNDS
+overpopulation/M
+overpopulous
+overpower/GSD
+overpowering/Y
+overpraise/DSG
+overprecise
+overpressure
+overprice/DSG
+overprint/GSMD
+overproduce/DSG
+overproduction/M
+overprotect/SDGV
+overqualified
+overran
+overrate/GDS
+overreach/DSG
+overreact/SDG
+overreaction/SM
+overrefined
+overrepresented
+overridden
+override/MGS
+overripe/M
+overrode
+overrule/GDS
+overrun/SM
+overrunning
+oversampled
+oversampling
+oversaw
+oversea/S
+oversee/RSZ
+overseeing
+overseen
+overseer/M
+oversell/GS
+oversensitive/P
+oversensitiveness/M
+oversensitivity
+oversexed
+overshadow/GDS
+overshoe/MS
+overshoot/SG
+overshot
+oversight/SM
+oversimple
+oversimplification/M
+oversimplify/NXDSG
+oversize
+oversleep/SG
+overslept
+oversold
+overspecialization/M
+overspecialize/GDS
+overspend/GS
+overspent
+overspread/GS
+overstaffed
+overstate/LDSG
+overstatement/SM
+overstay/DSG
+overstep/S
+overstepped
+overstepping
+overstimulate/DSG
+overstock/GSD
+overstress/D
+overstretch/DSG
+overstrict
+overstrung
+overstuffed
+oversubscribe/DSG
+oversubtle
+oversupply/DSG
+oversuspicious
+overt/YP
+overtake/ZGRS
+overtaken
+overtax/GDS
+overthrew
+overthrow/GSM
+overthrown
+overtightened
+overtime/MS
+overtire/GDS
+overtone/MS
+overtook
+overture/MS
+overturn/DSG
+overuse/DSMG
+overvaluation/S
+overvalue/DSG
+overview/MS
+overweening/Y
+overweight/M
+overwhelm/GSD
+overwhelming/Y
+overwinter/SDG
+overwork/GMDS
+overwrite/GS
+overwritten
+overwrote
+overwrought
+overzealous
+oviduct/SM
+oviparous
+ovoid/MS
+ovular
+ovulate/DSGN
+ovulation/M
+ovule/MS
+ovum/M
+ow
+owe/DSG
+owl/SM
+owlet/MS
+owlish/Y
+own/ESGD
+owned/U
+owner/MS
+ownership/SM
+ox/MNS
+oxalate
+oxalic
+oxblood/M
+oxbow/MS
+oxcart/SM
+oxford/SM
+oxidant/MS
+oxidation/M
+oxide/MS
+oxidization/M
+oxidize/ZGDRS
+oxidizer/M
+oxtail/S
+oxyacetylene/M
+oxygen/M
+oxygenate/DSGN
+oxygenation/M
+oxymora
+oxymoron/M
+oyster/SM
+oz
+ozone/M
+p/NRXTGJ
+pH
+pa/SMH
+pablum/M
+pabulum/M
+pace/MZGDRS
+pacemaker/SM
+pacemen
+pacer/M
+pacesetter/MS
+pacey
+pachyderm/MS
+pachysandra/SM
+pacific
+pacifically
+pacification/M
+pacifier/M
+pacifism/M
+pacifist/SM
+pacifistic
+pacify/ZGDRSN
+pack's
+pack/UADSG
+packable
+package's
+package/AGDS
+packager/SM
+packaging/M
+packer/MS
+packet/MS
+packhorse
+packing's
+packinghouse/MS
+packsaddle/MS
+pact/MS
+pacy/RT
+pad/SM
+padded
+padding/M
+paddle/MZGDRS
+paddler/M
+paddock/MDGS
+paddy/SM
+padlock/MDSG
+padre/SM
+paean/SM
+paella/MS
+paeony
+pagan/SM
+paganism/M
+page/MZGDRS
+pageant/MS
+pageantry/M
+pageboy/SM
+pageful
+pager/M
+paginate/DSGN
+pagination/M
+pagoda/MS
+pah
+paid/AU
+pail/MS
+pailful/SM
+pain/MDSG
+painful/PY
+painfuller
+painfullest
+painfulness/M
+painkiller/SM
+painkilling
+painless/PY
+painlessness/M
+painstaking/MY
+paint/SZGJMDR
+paintball
+paintbox/MS
+paintbrush/MS
+painted/U
+painter/MY
+painting/M
+paintwork
+pair/AMDSG
+paired/U
+pairing/S
+pairwise
+paisley/SM
+pajama/S
+pajamas/M
+pal/SMY
+palace/MS
+paladin/SM
+palaeontologist/S
+palanquin/SM
+palatable/U
+palatal/SM
+palatalization/M
+palatalize/GDS
+palate/MBS
+palatial/Y
+palatinate/MS
+palatine/MS
+palaver/GSMD
+pale/MYTGPDRSJ
+paleface/MS
+paleness/M
+paleographer/SM
+paleographic
+paleography/M
+paleolithic
+paleontological
+paleontologist/MS
+paleontology/M
+palette/SM
+palfrey/SM
+palimony/M
+palimpsest/SM
+palindrome/MS
+palindromic
+paling/M
+palisade/SM
+palish
+pall/MDSG
+palladium/M
+pallbearer/MS
+pallet/MS
+palliate/DSGNV
+palliation/M
+palliative/MS
+pallid/YP
+pallidness/M
+pallor/M
+palm/MDSG
+palmate
+palmetto/SM
+palmist/SM
+palmistry/M
+palmtop/SM
+palmy/TR
+palomino/MS
+palpable
+palpably
+palpate/DSGN
+palpation/M
+palpitate/GNDSX
+palpitation/M
+palsy/GDSM
+paltriness/M
+paltry/RPT
+paludal
+pampas/M
+pamper/DSG
+pamphlet/MS
+pamphleteer/SM
+pan/SMD
+panacea/SM
+panache/M
+panama/MS
+panatella/S
+pancake/DSMG
+panchromatic
+pancreas/MS
+pancreatic
+panda/SM
+pandemic/SM
+pandemonium/M
+pander/MDRZGS
+panderer/M
+pane/MS
+panegyric/SM
+panel/SGJMD
+paneling/M
+panelist/MS
+pang/MS
+pangolin
+panhandle/DRSMZG
+panhandler/M
+panic/SM
+panicked
+panicking
+panicky/TR
+panjandrum
+panned
+pannier/SM
+panning
+panoply/SM
+panorama/SM
+panoramic
+panpipes/M
+pansy/SM
+pant/MDSG
+pantaloons/M
+pantechnicon/S
+pantheism/M
+pantheist/SM
+pantheistic
+pantheon/SM
+panther/MS
+pantie/MS
+pantiled
+pantiles
+panto/S
+pantograph
+pantographs
+pantomime/MGDS
+pantomimic
+pantomimist/MS
+pantry/SM
+pantsuit/SM
+pantyhose/M
+pantyliner/M
+pantywaist/SM
+panzer
+pap/SM
+papa/MS
+papacy/SM
+papal
+paparazzi/M
+paparazzo
+papaw/SM
+papaya/MS
+paper/SZGMDR
+paperback/SM
+paperbark/S
+paperboard/M
+paperboy/SM
+paperclip/S
+paperer/M
+papergirl/SM
+paperhanger/MS
+paperhanging/M
+paperless
+paperweight/MS
+paperwork/M
+papery
+papilla/M
+papillae
+papillary
+papist/MS
+papoose/MS
+pappy/SM
+paprika/M
+papyri
+papyrus/M
+par/SZGMDRBJ
+para/MS
+parable/MS
+parabola/SM
+parabolic
+paraboloid/S
+paracetamol/S
+parachute/DSMG
+parachutist/SM
+parade/MZGDRS
+parader/M
+paradigm/SM
+paradigmatic
+paradisaical
+paradise/SM
+paradox/MS
+paradoxical/Y
+paraffin/M
+paragliding
+paragon/MS
+paragraph/GMD
+paragraphs
+parakeet/SM
+paralegal/MS
+paralinguistic
+parallax/MS
+parallel/SGMD
+paralleled/U
+parallelepiped
+parallelism/SM
+parallelogram/SM
+paralysis/M
+paralytic/SM
+paralytically
+paralyze/DSG
+paralyzing/Y
+paramagnetic
+paramagnetism
+paramecia
+paramecium/M
+paramedic/MS
+paramedical/SM
+parameter/MS
+parametric
+parametrically
+parametrization
+parametrize/DS
+paramilitary/SM
+paramount
+paramountcy
+paramour/SM
+paranoia/M
+paranoiac/MS
+paranoid/SM
+paranormal
+parapet/MS
+paraphernalia/M
+paraphrase/MGDS
+paraplegia/M
+paraplegic/MS
+paraprofessional/MS
+parapsychologist/SM
+parapsychology/M
+paraquat/M
+parascending
+parasite/SM
+parasitic
+parasitical/Y
+parasitism/M
+parasitologist
+parasitology
+parasol/MS
+parasympathetic/S
+parathion/M
+parathyroid/MS
+paratroop/RZS
+paratrooper/M
+paratroops/M
+paratyphoid/M
+parboil/DSG
+parcel/GMDS
+parch/LGDS
+parchment/SM
+pardner/S
+pardon/ZGMDRBS
+pardonable/U
+pardonably/U
+pardoner/M
+pare/S
+paregoric/M
+parent/GMDS
+parentage/M
+parental
+parenteral
+parentheses
+parenthesis/M
+parenthesize/GDS
+parenthetic
+parenthetical/Y
+parenthood/M
+parenting/M
+parer/M
+pares/S
+paresis/M
+parfait/MS
+pariah/M
+pariahs
+parietal
+parimutuel/SM
+paring/M
+parish/MS
+parishioner/SM
+parity/ESM
+park/MDSG
+parka/SM
+parking/M
+parkland
+parkway/MS
+parky
+parlance/M
+parlay/GMDS
+parley/GMDS
+parliament/SM
+parliamentarian/MS
+parliamentary
+parlor/MS
+parlormaid
+parlous
+parmigiana
+parochial/Y
+parochialism/M
+parochiality
+parodied/U
+parodist/SM
+parody/GDSM
+parole/MGDS
+parolee/MS
+paroxysm/SM
+paroxysmal
+parquet/MDSG
+parquetry/M
+parred
+parricidal
+parricide/MS
+parring
+parrot/GMDS
+parry/GDSM
+parse/DRSJZG
+parsec/MS
+parsimonious/Y
+parsimony/M
+parsley/M
+parsnip/MS
+parson/MS
+parsonage/MS
+part's
+part/CDSG
+partake/ZGRS
+partaken
+partaker/M
+parterre/SM
+parthenogenesis/M
+partial/MYS
+partiality/M
+participant/MS
+participate/GNVDS
+participation/M
+participator/SM
+participatory
+participial/M
+participle/SM
+particle/SM
+particleboard/M
+particular/SMY
+particularism
+particularity/SM
+particularization/M
+particularize/DSG
+particulate/MS
+parting/MS
+partisan/SM
+partisanship/M
+partition's
+partition/ADG
+partitions
+partitive/MS
+partly
+partner/MDSG
+partnership/MS
+partook
+partridge/SM
+parturition/M
+partway
+party/GDSM
+parvenu/MS
+pascal/MS
+paschal
+pasha/SM
+pass/M
+passably
+passage/MS
+passageway/SM
+passbook/MS
+passe/DRSBXZGNV
+passel/MS
+passenger/SM
+passer/M
+passerby/M
+passersby
+passim
+passing/MY
+passion/EM
+passionate/EY
+passionateness
+passionflower/MS
+passionless
+passivated
+passive/PMYS
+passiveness/M
+passivisation
+passivised
+passivises
+passivising
+passivity/M
+passivization
+passivize/DSG
+passkey/MS
+passmark
+passover
+passport/MS
+password/MS
+past/AMS
+pasta/SM
+paste/DSMG
+pasteboard/M
+pasted/U
+pastel/MS
+pastern/MS
+pasteurization/M
+pasteurize/DRSZG
+pasteurized/U
+pasteurizer/M
+pastiche/MS
+pastie
+pastille/MS
+pastime/MS
+pastiness/M
+pastis
+pastor/MS
+pastoral/MS
+pastoralism
+pastorate/MS
+pastrami/M
+pastry/SM
+pasturage/M
+pasture/DSMG
+pastureland/M
+pasty/PTRSM
+pat/SM
+patch/EGMDS
+patchable
+patchily
+patchiness/M
+patchouli
+patchwork/SM
+patchy/TPR
+pate/MS
+patella/MS
+patellae
+patent/GMDYBS
+paterfamilias/MS
+paternal/Y
+paternalism/M
+paternalist/S
+paternalistic
+paternity/M
+paternoster/SM
+path/M
+pathetic
+pathetically
+pathfinder/SM
+pathless
+pathogen/SM
+pathogenesis
+pathogenic
+pathological/Y
+pathologist/MS
+pathology/SM
+pathos/M
+paths
+pathway/MS
+patience/M
+patient/IMST
+patienter
+patiently
+patina/MS
+patine
+patio/SM
+patisserie/S
+patois/M
+patresfamilias
+patriarch/M
+patriarchal
+patriarchate/SM
+patriarchs
+patriarchy/SM
+patrician/SM
+patricide/SM
+patrimonial
+patrimony/SM
+patriot/SM
+patriotic/U
+patriotically
+patriotism/M
+patrol/MS
+patrolled
+patrolling
+patrolman/M
+patrolmen
+patrolwoman/M
+patrolwomen
+patron/MS
+patronage/MS
+patroness/MS
+patronization
+patronize/ZGDRS
+patronizer/M
+patronizing/Y
+patronymic/SM
+patronymically
+patroon/SM
+patsy/SM
+patted
+patten/S
+patter/MDGS
+pattern/SMDG
+patternless
+patting
+patty/SM
+paucity/M
+paunch/MS
+paunchy/RT
+pauper/MS
+pauperism/M
+pauperize/DSG
+pause/DSMG
+pave/AGDS
+paved/U
+pavement/MS
+pavilion/SM
+paving/MS
+pavlova/S
+paw/SGMD
+pawl/MS
+pawn/MDSG
+pawnbroker/SM
+pawnbroking/M
+pawnshop/MS
+pay's
+pay/ASGBL
+payback/SM
+paycheck/MS
+payday/MS
+payed
+payee/SM
+payer/SM
+payload/SM
+paymaster/SM
+payment/ASM
+payoff/MS
+payola/M
+payout/MS
+payphone/S
+payroll/SM
+payslip/SM
+payware/S
+pct
+pd
+pea/SM
+peace/SM
+peaceable
+peaceably
+peaceful/PY
+peacefuller
+peacefullest
+peacefulness/M
+peacekeeper/MS
+peacekeeping/M
+peacemaker/SM
+peacemaking/M
+peacetime/M
+peach/MS
+peachy/TR
+peacock/MS
+peafowl/MS
+peahen/MS
+peak/MDSG
+peaky/P
+peal/AMDSG
+peanut/MS
+pear/MYS
+pearl/SGMD
+pearly/RT
+peartrees
+peasant/SM
+peasantry/M
+peashooter/MS
+peat/M
+peaty/TR
+pebble/MGDS
+pebbly/TR
+pecan/SM
+peccadillo/M
+peccadilloes
+peccary/SM
+peck/MDRSZG
+peckish
+pecs
+pectic
+pectin/M
+pectoral/MS
+peculate/GNXDS
+peculation/M
+peculator/M
+peculiar/Y
+peculiarity/SM
+pecuniary
+pedagogic
+pedagogical/Y
+pedagogue/SM
+pedagogy/M
+pedal/SGMD
+pedalo/S
+pedant/MS
+pedantic
+pedantically
+pedantry/M
+peddle/ZGDRS
+peddler/M
+pederast/MS
+pederasty/M
+pedestal/MS
+pedestrian/SM
+pedestrianization
+pedestrianize/DSG
+pediatric/S
+pediatrician/MS
+pediatrics/M
+pedicab/SM
+pedicure/MGDS
+pedicurist/MS
+pedigree/MDS
+pediment/MS
+pedology
+pedometer/MS
+pedophile/S
+pedophilia
+peduncle/MS
+pee/DRSMZ
+peeing
+peek/MDSG
+peekaboo/M
+peel/MDRSJZG
+peeled/U
+peeler/M
+peeling/M
+peen/MS
+peep/MDRSZG
+peepbo
+peeper/M
+peephole/MS
+peepshow/MS
+peer/MDG
+peerage/SM
+peeress/MS
+peerless
+peeve/DSMG
+peevish/PY
+peevishness/M
+peewee/MS
+peewit/S
+peg/SM
+pegboard/MS
+pegged
+pegging
+peignoir/SM
+pejoration/M
+pejorative/SMY
+peke/MS
+pekineses
+pekingese/SM
+pekoe/M
+pelagic
+pelf/M
+pelican/MS
+pellagra/M
+pellet/GMDS
+pellucid
+pelmet/S
+pelt/MDSG
+pelvic
+pelvis/MS
+pemmican/M
+pen/M
+penal
+penalization/M
+penalize/DSG
+penalty/SM
+penance/MS
+pence
+penchant/SM
+pencil/GMDJS
+pend/CDSG
+pendant/MS
+pendent/MS
+pendulous
+pendulum/MS
+penetrability/M
+penetrable
+penetrate/XDSGNV
+penetrating/Y
+penetration/M
+penfriend/S
+penguin/MS
+penicillin/M
+penile
+peninsula/SM
+peninsular
+penis/MS
+penitence/M
+penitent/SMY
+penitential
+penitentiary/SM
+penknife/M
+penknives
+penlight/SM
+penman/M
+penmanship/M
+penmen
+pennant/MS
+penned
+penniless
+penning
+pennon/MS
+penny/SM
+pennyweight/SM
+pennyworth
+penologist/MS
+penology/M
+pension/BZGMDRS
+pensioner/M
+pensive/PY
+pensiveness/M
+pent
+pentacle/MS
+pentagon/MS
+pentagonal
+pentagram/SM
+pentameter/MS
+pentasyllabic
+pentathlete/SM
+pentathlon/MS
+pentatonic
+pentecostal
+penthouse/SM
+penuche/M
+penultimate/SMY
+penumbra/MS
+penumbrae
+penurious/YP
+penuriousness/M
+penury/M
+peon/MS
+peonage/M
+peony/SM
+people/MGDS
+pep/SM
+peperoni
+pepped
+pepper/GMDS
+peppercorn/SM
+peppermint/MS
+pepperoni/MS
+peppery
+peppiness/M
+pepping
+peppy/TPR
+pepsin/M
+peptic/MS
+peptide/S
+peradventure/M
+perambulate/DSGNX
+perambulation/M
+perambulator/SM
+percale/MS
+perceive/BGDS
+perceived/U
+percent/MS
+percentage/SM
+percentile/SM
+perceptibility
+perceptible
+perceptibly
+perception/MS
+perceptional
+perceptive/YP
+perceptiveness/M
+percepts
+perceptual/Y
+perch/GMDS
+perchance
+perchlorate
+percipience/M
+percipient
+percolate/GNDS
+percolation/M
+percolator/SM
+percuss/GVDS
+percussion/AM
+percussionist/SM
+percussive/Y
+perdition/M
+perdurable
+peregrinate/GNXDS
+peregrination/M
+peregrine/MS
+peremptorily
+peremptory/P
+perennial/SMY
+perestroika/M
+perfect/PTGMDRYS
+perfecta/MS
+perfectibility/M
+perfectible
+perfection/SM
+perfectionism/M
+perfectionist/MS
+perfectness/M
+perfidious/Y
+perfidy/SM
+perforate/GNDSX
+perforation/M
+perforce
+perform/BSDRZG
+performance/SM
+performed/U
+performer/M
+perfume/DRSMZG
+perfumer/M
+perfumery/SM
+perfunctorily
+perfunctory
+perfused
+perfusion
+pergola/SM
+perhaps
+periastron
+pericardia
+pericardium/M
+perigee/SM
+periglacial
+perihelia
+perihelion/M
+peril/SGMD
+perilous/Y
+perimeter/SM
+perinatal
+perinea
+perineum/M
+period/MS
+periodic
+periodical/SMY
+periodicity/M
+periodontal
+periodontics/M
+periodontist/SM
+peripatetic/SM
+peripheral/SMY
+periphery/SM
+periphrases
+periphrasis/M
+periphrastic
+periscope/SM
+perish/BDRSZG
+perishable/MS
+peristalses
+peristalsis/M
+peristaltic
+peristyle/SM
+peritoneal
+peritoneum/MS
+peritonitis/M
+periwig/SM
+periwinkle/SM
+perjure/DRSZG
+perjurer/M
+perjury/SM
+perk/MDSG
+perkily
+perkiness/M
+perky/TPR
+perm/MDSG
+permafrost/M
+permanence/M
+permanency/M
+permanent/SMY
+permanganate
+permeability/M
+permeable
+permeate/GNDS
+permeation/M
+permissibility
+permissible
+permissibly
+permission/SM
+permissive/PY
+permissiveness/M
+permit/MS
+permitted
+permitting
+permittivity
+permutation/MS
+permute/DSG
+pernicious/PY
+perniciousness/M
+peroration/MS
+peroxidase
+peroxide/MGDS
+perpendicular/MYS
+perpendicularity/M
+perpetrate/GNDS
+perpetration/M
+perpetrator/SM
+perpetual/SMY
+perpetuate/GNDS
+perpetuation/M
+perpetuity/M
+perplex/GDS
+perplexed/Y
+perplexity/SM
+perquisite/SM
+perry
+persecute/GNDSX
+persecution/M
+persecutor/SM
+perseverance/M
+persevere/DSG
+persevering/Y
+persiflage/M
+persimmon/SM
+persist/SGD
+persistence/M
+persistent/Y
+persnickety
+person/UMS
+persona/M
+personable
+personae
+personage/MS
+personal/MYS
+personality/SM
+personalization/C
+personalize/CGDS
+personalized/U
+personalty/M
+personification/M
+personify/XDSGN
+personnel/M
+perspective/SM
+perspex
+perspicacious/Y
+perspicacity/M
+perspicuity/M
+perspicuous/Y
+perspiration/M
+perspire/GDS
+persuade/BZGDRS
+persuaded/U
+persuader/M
+persuasion/SM
+persuasive/YP
+persuasiveness/M
+pert/RYPT
+pertain/GSD
+pertinacious/Y
+pertinacity/M
+pertinence/M
+pertinent/Y
+pertness/M
+perturb/DGS
+perturbation/MS
+perturbed/U
+pertussis/M
+peruke/MS
+perusal/MS
+peruse/GDS
+perv/S
+pervade/DSG
+pervasive/PY
+pervasiveness/M
+perverse/PXYN
+perverseness/M
+perversion/M
+perversity/M
+pervert/SGMD
+peseta/MS
+peskily
+peskiness/M
+pesky/TPR
+peso/MS
+pessary/S
+pessimal/SDYG
+pessimism/M
+pessimist/SM
+pessimistic
+pessimistically
+pest/MRSZ
+pester/GD
+pesticide/MS
+pestiferous
+pestilence/SM
+pestilent
+pestilential
+pestle/MGDS
+pesto/M
+pet/SZMR
+petal/SMD
+petard/MS
+petcock/SM
+peter/GMD
+pethidine
+petiole/SM
+petite/MS
+petition/ZGMDRS
+petitioner/M
+petrel/MS
+petrifaction/M
+petrify/NDSG
+petrochemical/SM
+petrodollar/SM
+petrographic
+petrographical
+petrol/M
+petrolatum/M
+petroleum/M
+petrological
+petrologist/SM
+petrology/M
+petted
+petticoat/MS
+pettifog/S
+pettifogged
+pettifogger/SM
+pettifoggery/M
+pettifogging
+pettily
+pettiness/M
+petting/M
+pettish/YP
+petty/PTR
+petulance/M
+petulant/Y
+petunia/MS
+pew/SM
+pewee/SM
+pewit/SM
+pewter/MS
+peyote/M
+pf
+pfennig/MS
+pg
+phaeton/MS
+phage/S
+phagocyte/SM
+phalanger/SM
+phalanges
+phalanx/MS
+phalli
+phallic
+phallus/M
+phantasm/MS
+phantasmagoria/MS
+phantasmagorical
+phantasmal
+phantom/SM
+pharaoh/M
+pharaohs
+pharisaic
+pharisee/SM
+pharmaceutic/MS
+pharmaceutical/MS
+pharmaceutics/M
+pharmacist/SM
+pharmacological
+pharmacologist/MS
+pharmacology/M
+pharmacopoeia/SM
+pharmacy/SM
+pharyngeal
+pharynges
+pharyngitis/M
+pharynx/M
+phase/DSMG
+phaseout/SM
+phat
+pheasant/MS
+phenacetin/M
+phenobarbital/M
+phenol/MS
+phenolic
+phenolphthalein
+phenom/MS
+phenomena
+phenomenal/Y
+phenomenological/Y
+phenomenology
+phenomenon/MS
+phenotype/S
+phenylalanine
+pheromone/MS
+phew
+phi/SM
+phial/SM
+philander/DRSZG
+philanderer/M
+philandering/M
+philanthropic
+philanthropically
+philanthropist/SM
+philanthropy/SM
+philatelic
+philatelist/SM
+philately/M
+philharmonic/SM
+philippic/MS
+philistine/SM
+philistinism/M
+philodendron/SM
+philological
+philologist/MS
+philology/M
+philosopher/SM
+philosophic
+philosophical/Y
+philosophize/ZGDRS
+philosophizer/M
+philosophy/SM
+philter/MS
+phish/DGS
+phisher/MS
+phlebitis/M
+phlebotomy
+phlegm/M
+phlegmatic
+phlegmatically
+phloem/M
+phlogiston
+phlox/M
+phobia/MS
+phobic/MS
+phoebe/MS
+phoenix/MS
+phone/DSMG
+phonecard/S
+phoneme/MS
+phonemic
+phonemically
+phonetic/S
+phonetically
+phonetician/SM
+phoneticist
+phonetics/M
+phonic/S
+phonically
+phonics/M
+phoniness/M
+phonograph/M
+phonographic
+phonographs
+phonological/Y
+phonologist/SM
+phonology/M
+phonon
+phony/PTGDRSM
+phooey
+phosphatase
+phosphate/MS
+phosphor/MS
+phosphorescence/M
+phosphorescent/Y
+phosphoric
+phosphorous
+phosphorus/M
+photo/SGMD
+photocell/MS
+photochemical/Y
+photochemistry
+photocopier/M
+photocopy/DRSMZG
+photoelectric
+photoelectrically
+photoengrave/ZGDRSJ
+photoengraver/M
+photoengraving/M
+photofinishing/M
+photogenic
+photogenically
+photograph/MDRZG
+photographer/M
+photographic
+photographically
+photographs/A
+photography/M
+photojournalism/M
+photojournalist/MS
+photolysis
+photolytic
+photometer/MS
+photometric
+photometrically
+photometry
+photomultiplier
+photon/MS
+photoreceptor
+photosensitive
+photosphere
+photostat/SM
+photostatic
+photostatted
+photostatting
+photosynthesis/M
+photosynthesize/GDS
+photosynthetic
+photosynthetically
+phototypesetter
+phototypesetting
+photovoltaic
+phrasal
+phrase's
+phrase/AGDS
+phrasebook/S
+phraseology/M
+phrasing/MS
+phreaking/S
+phrenological/Y
+phrenologist/SM
+phrenology/M
+phyla
+phylactery/SM
+phylogenetic
+phylogeny/M
+phylum/M
+phys
+physic/SM
+physical/MYS
+physicality
+physician/SM
+physicist/SM
+physicked
+physicking
+physics/M
+physio/S
+physiognomy/SM
+physiography/M
+physiologic
+physiological/Y
+physiologist/SM
+physiology/M
+physiotherapist/SM
+physiotherapy/M
+physique/MS
+phytoplankton
+pi/SMDRHZG
+pianissimo/SM
+pianist/MS
+pianistic
+piano/SM
+pianoforte/SM
+pianola/S
+piaster/MS
+piazza/MS
+pibroch/M
+pibrochs
+pic/SM
+pica/M
+picador/MS
+picaresque
+picayune
+piccalilli/M
+piccolo/MS
+pick/MDRSJZG
+pickax/GMDS
+picker/M
+pickerel/MS
+picket/ZGMDRS
+pickings/M
+pickle/MGDS
+pickpocket/SMG
+pickup/MS
+picky/TR
+picnic/MS
+picnicked
+picnicker/SM
+picnicking
+picoseconds
+picot/SM
+pictogram
+pictograph/M
+pictographic
+pictographs
+pictorial/MYS
+picture/MGDS
+picturesque/YP
+picturesqueness/M
+piddle/MGDS
+piddly
+pidgin/MS
+pie/SM
+piebald/MS
+piece/DSMG
+piecemeal
+piecewise
+piecework/ZMR
+pieceworker/M
+pieing
+pier/M
+pierce/JZGDRS
+piercing/MY
+piety/M
+piezoelectric
+piffle/MG
+pig/SML
+pigeon/MS
+pigeonhole/MGDS
+pigged
+piggery/S
+pigging
+piggish/PY
+piggishness/M
+piggy/TRSM
+piggyback/MDSG
+pigheaded/PY
+pigheadedness/M
+piglet/MS
+pigment/MDS
+pigmentation/M
+pigpen/MS
+pigskin/MS
+pigsty/SM
+pigswill
+pigtail/MDS
+pike/MZGDRS
+piker/M
+pikestaff/SM
+pilaf/SM
+pilaster/MS
+pilchard/MS
+pile/MGDSJ
+pileup/MS
+pilfer/ZGDRS
+pilferage/M
+pilferer/M
+pilgrim/MS
+pilgrimage/MS
+piling/M
+pill/MS
+pillage/MZGDRS
+pillager/M
+pillar/MDS
+pillbox/MS
+pillion/MS
+pillock/S
+pillory/GDSM
+pillow/GMDS
+pillowcase/MS
+pillowslip/MS
+pilot/DGSM
+pilothouse/SM
+pimento/MS
+pimiento/MS
+pimp/GMDYS
+pimpernel/MS
+pimple/DSM
+pimply/RT
+pin/SM
+pinafore/MS
+pinata/MS
+pinball/M
+pincer/MDS
+pinch/GMDRS
+pincushion/MS
+pine's
+pine/AGDS
+pineal
+pineapple/MS
+pinewood/S
+pinfeather/SM
+ping/GMD
+pinhead/SM
+pinhole/SM
+pinion/SMDG
+pink/TGPMDRS
+pinkeye/M
+pinkie/SM
+pinkish
+pinkness/M
+pinko/MS
+pinnacle/DSM
+pinnate
+pinned/U
+pinning/U
+pinny/S
+pinochle/M
+pinon/MS
+pinpoint/SGMD
+pinprick/MS
+pinsetter/SM
+pinstripe/DSM
+pint/MS
+pinto/MS
+pinup/MS
+pinwheel/GSMD
+piny/TR
+pinyin/M
+pioneer/SGMD
+pious/YP
+piousness/M
+pip/SZGMDR
+pipe/MS
+pipeline/SM
+piper/M
+pipette/SM
+pipework
+piping/M
+pipit/MS
+pipped
+pippin/SM
+pipping
+pipsqueak/SM
+piquancy/M
+piquant/Y
+pique/MGDS
+piracy/M
+piranha/SM
+pirate/DSMG
+piratical/Y
+pirogi/M
+pirouette/DSMG
+piscatorial
+pismire/SM
+piss/ZGMDRS
+pissoir/S
+pistachio/SM
+piste/S
+pistil/SM
+pistillate
+pistol/SM
+piston/SM
+pit/SM
+pita/MS
+pitapat/SM
+pitch/MDRSZG
+pitchblende/M
+pitcher/M
+pitchfork/MDSG
+pitchman/M
+pitchmen
+piteous/YP
+piteousness/M
+pitfall/SM
+pith/M
+pithead/S
+pithily
+pithiness/M
+piths
+pithy/RTP
+pitiable
+pitiably
+pitiful/Y
+pitifuller
+pitifullest
+pitiless/PY
+pitilessness/M
+piton/MS
+pitta/S
+pittance/MS
+pitted
+pitting
+pituitary/SM
+pity/GDSM
+pitying/Y
+pivot/MDGS
+pivotal
+pix/M
+pixel/MS
+pixie/MS
+pizazz/M
+pizza/MS
+pizzeria/SM
+pizzicati
+pizzicato/M
+pj's
+pk
+pkg
+pkt
+pkwy
+pl
+placard/SMDG
+placate/DSGN
+placation/M
+placatory
+place's
+place/EAGLDS
+placebo/SM
+placed/U
+placeholder/SM
+placekick/MDRZGS
+placekicker/M
+placemen
+placement/EASM
+placenta/SM
+placental/S
+placer/SM
+placid/Y
+placidity/M
+placings
+placket/SM
+plagiarism/MS
+plagiarist/MS
+plagiarize/ZGDRS
+plagiarizer/M
+plagiary/M
+plague/DSMG
+plaice
+plaid/MS
+plain/MRYTSP
+plainchant
+plainclothes
+plainclothesman/M
+plainclothesmen
+plainness/M
+plainsman/M
+plainsmen
+plainsong/M
+plainspoken
+plaint/SMV
+plaintiff/SM
+plaintive/Y
+plait/MDGS
+plan/ZMRS
+planar
+plane's
+plane/CGDS
+planeload/MS
+planer/M
+planet/SM
+planetarium/MS
+planetary
+planetesimals
+planetoids
+plangency/M
+plangent
+plank/MDGS
+planking/M
+plankton/M
+planned/U
+planner/SM
+planning/S
+plant/MDRZGSJ
+plantain/SM
+plantar
+plantation/SM
+planter/M
+planting/M
+plantlike
+plaque/SM
+plash/MDSG
+plasma/SM
+plasmid/S
+plaster/SZGMDR
+plasterboard/M
+plasterer/M
+plasterwork
+plastic/SM
+plasticine
+plasticity/M
+plasticize/DSZG
+plat/XGMDNS
+plate/MS
+plateau/SMDG
+plateful/SM
+platelet/SM
+platen/M
+platform/SGMD
+plating/M
+platinum/M
+platitude/SM
+platitudinous
+platonic
+platoon/SGMD
+platted
+platter/SM
+platting
+platy/M
+platypus/MS
+plaudit/SM
+plausibility/M
+plausible
+plausibly
+play/AEGMDS
+playability/U
+playable/EU
+playact/SGD
+playacting/M
+playback/MS
+playbill/MS
+playbook/MS
+playboy/SM
+player/SM
+playfellow/SM
+playful/PY
+playfulness/M
+playgirl/MS
+playgoer/MS
+playground/SM
+playgroup/S
+playhouse/MS
+playings
+playmate/MS
+playoff/SM
+playpen/SM
+playroom/SM
+playschool/S
+plaything/SM
+playtime/M
+playwright/SM
+plaza/MS
+plea/MS
+plead/DRZGSJ
+pleader/M
+pleading/MY
+pleasant/UTYP
+pleasanter
+pleasantness/UM
+pleasantry/SM
+please/EDSG
+pleasing/YS
+pleasurably
+pleasure/MGDSB
+pleasureful
+pleat/MDGS
+pleb/S
+plebby
+plebe/MS
+plebeian/MS
+plebiscite/MS
+plectra
+plectrum/MS
+pledge/DSMG
+plenary/SM
+plenipotentiary/SM
+plenitude/SM
+plenteous/Y
+plentiful/Y
+plenty/M
+plenum/S
+pleonasm/MS
+plethora/M
+pleura/M
+pleurae
+pleural
+pleurisy/M
+plexus/MS
+pliability/M
+pliable
+pliancy/M
+pliant/Y
+pliers/M
+plight/SMDG
+plimsoll/S
+plinth/M
+plinths
+plod/S
+plodded
+plodder/MS
+plodding/S
+plonk/DRSZG
+plop/MS
+plopped
+plopping
+plosive/S
+plot/MS
+plotted/A
+plotter/SM
+plotting
+plover/SM
+plow/ZGMDS
+plowman/M
+plowmen
+plowshare/MS
+ploy's
+ploy/S
+pluck/MDRSG
+pluckily
+pluckiness/M
+plucky/RPT
+plug's
+plug/US
+plugged/UA
+plugging/UA
+plughole/S
+plum/GMDS
+plumage/M
+plumb/MDRSZGJ
+plumbago
+plumbed/U
+plumber/M
+plumbing/M
+plume/MS
+plummet/SGMD
+plummy
+plump/MDRYSTGP
+plumpness/M
+plumy/RT
+plunder/SZGMDR
+plunderer/M
+plunge/DRSMZG
+plunger/M
+plunk/MDSG
+pluperfect/SM
+plural/SM
+pluralism/M
+pluralist/MS
+pluralistic
+plurality/SM
+pluralization/M
+pluralize/GDS
+plus/MS
+plush/MRYTP
+plushness/M
+plushy/RT
+plutocracy/SM
+plutocrat/SM
+plutocratic
+plutonium/M
+pluvial
+ply/AZGDSM
+plywood/M
+pm
+pneumatic/S
+pneumatically
+pneumonia/M
+poach/DRSZG
+poacher/M
+poaching/M
+pock/GMDS
+pocket/SMDG
+pocketbook/SM
+pocketful/SM
+pocketknife/M
+pocketknives
+pockmark/MDGS
+pod/SM
+podcast
+podded
+podding
+podiatrist/SM
+podiatry/M
+podium/SM
+poem/MS
+poesy/M
+poet/MS
+poetaster/MS
+poetess/MS
+poetic/S
+poetical/Y
+poetry/M
+pogo
+pogrom/SM
+poi/M
+poignancy/M
+poignant/Y
+poikilothermic
+poinciana/SM
+poinsettia/SM
+point/MDRSZG
+pointblank
+pointed/PY
+pointer/M
+pointillism/M
+pointillist/SM
+pointless/YP
+pointlessness/M
+pointy/TR
+poise/MGDS
+poison/SJZGMDR
+poisoner/M
+poisoning/M
+poisonous/Y
+poke/MZGDRS
+poker/M
+poky/TR
+pol/SGMD
+polar
+polarity/SM
+polarization/CMS
+polarize/CDSG
+pole/MS
+poleaxe/GDS
+polecat/MS
+polemic/MS
+polemical/Y
+polemicist/SM
+polemics/M
+polestar/SM
+poleward/S
+police/DSMG
+policeman/M
+policemen
+policewoman/M
+policewomen
+policy/SM
+policyholder/SM
+policymaker/S
+polio/MS
+poliomyelitis/M
+polish/ZGMDRSJ
+polished/U
+polisher/M
+politburo/MS
+polite/RYTP
+politeness/M
+politesse/M
+politic/S
+political/Y
+politician/MS
+politicization/M
+politicize/CDSG
+politicking/M
+politico/SM
+politics/M
+polity/SM
+polka/MDSG
+poll/XGMDNS
+pollack/MS
+pollard/S
+pollen/M
+pollinate/GNDS
+pollination/M
+pollinator/MS
+polling/M
+polliwog/SM
+pollster/SM
+pollutant/MS
+pollute/ZGNDRSX
+polluted/U
+polluter/M
+pollution/M
+polo/M
+polonaise/SM
+polonium/M
+poltergeist/MS
+poltroon/SM
+poly
+polyandrous
+polyandry/M
+polyatomic
+polycarbonate
+polychromatic
+polychrome
+polyclinic/SM
+polycrystalline
+polycyclic
+polyester/MS
+polyethylene/M
+polygamist/MS
+polygamous
+polygamy/M
+polyglot/SM
+polygon/SM
+polygonal
+polygraph/GMD
+polygraphs
+polyhedral
+polyhedron/SM
+polymath/M
+polymaths
+polymer/SM
+polymerase/S
+polymeric
+polymerization/M
+polymerize/GDS
+polymorphic
+polymorphism/S
+polymorphous
+polynomial/SMY
+polyp/MS
+polypeptide/S
+polyphonic
+polyphony/M
+polypropylene/M
+polysaccharides
+polysemous
+polystyrene/M
+polysyllabic
+polysyllable/MS
+polytechnic/SM
+polytheism/M
+polytheist/SM
+polytheistic
+polythene
+polytopes
+polyunsaturate/DS
+polyurethane/SM
+polyvinyl
+pom/S
+pomade/DSMG
+pomander/SM
+pomegranate/MS
+pommel/SGMD
+pommy/S
+pomp/M
+pompadour/SMD
+pompano/MS
+pompom/SM
+pomposity/M
+pompous/YP
+pompousness/M
+ponce/GDS
+poncho/SM
+poncy
+pond/MS
+ponder/SZGDR
+ponderer/M
+ponderous/PY
+ponderousness/M
+pone/MS
+pong/GDS
+pongee/M
+poniard/MS
+pontiff/SM
+pontifical/Y
+pontificate/MGNDSX
+pontoon/SM
+pony/GDSM
+ponytail/MS
+poo/SGD
+pooch/MDSG
+poodle/SM
+poof/MS
+poofter/S
+pooh/GMD
+poohs
+pool/GMDS
+poolroom/MS
+poolside/S
+poop/GMDS
+poor/TRYP
+poorboy/M
+poorhouse/SM
+poorness/M
+pop/SM
+popcorn/M
+pope/MS
+popgun/SM
+popinjay/MS
+poplar/SM
+poplin/M
+popover/SM
+poppa/MS
+poppadom/S
+popped
+popper/SM
+poppet/S
+popping
+poppy/SM
+poppycock/M
+populace/MS
+popular/Y
+popularity/UM
+popularization/SM
+popularize/DSG
+populate/ACGDS
+populated/U
+population/CM
+populations
+populism/M
+populist/MS
+populous/P
+populousness/M
+porcelain/SM
+porch/MS
+porcine
+porcupine/SM
+pore/MGDS
+porgy/SM
+pork/ZMR
+porker/M
+porky/RSMT
+porn/M
+porno/M
+pornographer/MS
+pornographic
+pornographically
+pornography/M
+porosity/M
+porous/P
+porousness/M
+porphyritic
+porphyry/M
+porpoise/MGDS
+porridge/M
+porringer/SM
+port's
+port/CAEGDS
+portability/M
+portable/MS
+portage/DSMG
+portal/SM
+portcullis/MS
+portend/SGD
+portent/SM
+portentous/YP
+porter/ASM
+porterage
+porterhouse/MS
+portfolio/MS
+porthole/MS
+portico/M
+porticoes
+portiere/MS
+portion/KSGMD
+portliness/M
+portly/RPT
+portmanteau/SM
+portrait/MS
+portraitist/MS
+portraiture/M
+portray/SGD
+portrayal/MS
+portulaca/M
+pose's/A
+pose/CAKEGDS
+poser/EKSM
+poseur/SM
+posh/TR
+posit/DSGV
+position's/KC
+position/ACKES
+positionable
+positional/KC
+positionally
+positioned/KA
+positioning/AK
+positive/PMYTRS
+positiveness/M
+positivism
+positivist/S
+positivity
+positron/MS
+poss
+posse/MS
+possess/AEVGSD
+possession/ASM
+possessive/SPMY
+possessiveness/M
+possessor/SM
+possibility/SM
+possible/RSMT
+possibly
+possum/SM
+post/ZGMDRSJ
+postage/M
+postal
+postbag/S
+postbox/S
+postcard/SM
+postcode/S
+postconsonantal
+postdate/DSG
+postdoc
+postdoctoral
+poster/M
+posterior/SM
+posterity/M
+postfixes
+postgraduate/MS
+posthaste
+posthumous/Y
+posthypnotic
+postie/S
+postilion/SM
+postindustrial
+posting/M
+postlude/SM
+postman/M
+postmark/SMDG
+postmaster/MS
+postmen
+postmenopausal
+postmeridian
+postmistress/MS
+postmodern
+postmodernism/M
+postmodernist/MS
+postmortem/SM
+postnasal
+postnatal
+postoperative
+postpaid
+postpartum
+postpone/DSGL
+postponement/MS
+postprandial
+postscript/SM
+postseason/SM
+postulate/XDSMGN
+postulation/M
+postural
+posture/MGJDS
+posturing/M
+postwar
+postwoman
+postwomen
+posy/SM
+pot/CSM
+potability/M
+potable/SM
+potash/M
+potassium/M
+potato/M
+potatoes
+potbelly/DSM
+potboiler/SM
+potency/M
+potent/Y
+potentate/MS
+potential/MYS
+potentiality/SM
+potentiometer/S
+potful/SM
+pothead/SM
+pother/SMDG
+potherb/SM
+potholder/MS
+pothole/DRSMZG
+pothook/SM
+potion/SM
+potluck/MS
+potpie/SM
+potpourri/SM
+potsherd/SM
+potshot/MS
+pottage/M
+potted
+potter/GSMD
+pottery/SM
+potting
+potty/PRSMT
+pouch/MDSG
+pouf/S
+pouffe/S
+poulterer/MS
+poultice/DSMG
+poultry/M
+pounce/DSMG
+pound's
+pound/KDSG
+poundage/M
+pounding/SM
+pour/GDSBJ
+pout/ZGMDRS
+pouter/M
+poverty/M
+pow
+powder/GSMD
+powdery
+power/MDSG
+powerboat/MS
+powerful/YP
+powerhouse/SM
+powerless/YP
+powerlessness/M
+powwow/SGMD
+pox/MS
+pp
+ppm
+ppr
+pr
+practicability/SM
+practicably
+practical/SMY
+practicality/SM
+practice/DSMGB
+practiced/U
+practicum/SM
+practitioner/MS
+praetor/SM
+praetorian
+pragmatic/MS
+pragmatical/Y
+pragmatism/M
+pragmatist/SM
+prairie/SM
+praise/EDSMG
+praiseworthiness/M
+praiseworthy/P
+praline/SM
+pram/MS
+prance/DRSMZG
+prancer/M
+prancing/Y
+prang/DSG
+prank/MS
+prankster/SM
+praseodymium/M
+prat/S
+prate/MZGDRS
+prater/M
+pratfall/SM
+prattle/DRSMZG
+prattler/M
+prawn/MDSG
+pray/ZGDRS
+prayer/M
+prayerbook
+prayerful/Y
+preach/DRSZGJL
+preacher/M
+preachment/M
+preachy/RT
+preadolescence/MS
+preallocate
+preamble/MGDS
+preamp
+preamplifier
+prearrange/LGDS
+prearrangement/M
+preassigned
+preauthorize
+prebendary
+precancel/SMDG
+precancerous
+precarious/YP
+precariousness/M
+precast
+precaution/MS
+precautionary
+precede/DSG
+precedence/MS
+precedent/SM
+precept/SM
+preceptor/SM
+precess/GD
+precession
+precinct/MS
+preciosity/M
+precious/PY
+preciousness/M
+precipice/SM
+precipitant/SM
+precipitate/DSXMYGN
+precipitation/M
+precipitous/Y
+precis/M
+precise/XDRSYTGNP
+preciseness/M
+precision/M
+preclinical
+preclude/GDS
+preclusion/M
+precocious/PY
+precociousness/M
+precocity/M
+precognition/SM
+precognitive
+precolonial
+precomputed
+preconceive/DSG
+preconception/MS
+precondition/GSMD
+precook/GSD
+precursor/SM
+precursory
+predate/XDSGN
+predator/MS
+predatory
+predawn
+predecease/GDS
+predecessor/MS
+predeclared
+predefine/DG
+predesignate/GDS
+predestination/M
+predestine/DSG
+predetermination/M
+predetermine/DRSZG
+predeterminer/M
+predicable
+predicament/MS
+predicate/MGNVDS
+predication/M
+predicative/Y
+predict/BGVSD
+predictability/UM
+predictable/U
+predictably/U
+predicted/U
+prediction/MS
+predictor/MS
+predigest/DSG
+predilection/SM
+predispose/GDS
+predisposition/SM
+predominance/M
+predominant/Y
+predominate/DSYG
+preemie/SM
+preeminence/M
+preeminent/Y
+preempt/GSD
+preemption/M
+preemptive/Y
+preen/DSG
+preexist/DGS
+preexistence/M
+pref
+prefab/SM
+prefabbed
+prefabbing
+prefabricate/GNDS
+prefabrication/M
+preface/DSMG
+prefatory
+prefect/SM
+prefecture/MS
+prefer/SBL
+preferably
+preference/MS
+preferential/Y
+preferment/M
+preferred
+preferring
+prefigure/GDS
+prefix/MDSG
+preform/GSD
+pregame/SM
+pregnancy/SM
+pregnant
+preheat/GSD
+prehensile
+prehistoric
+prehistorical/Y
+prehistory/M
+prejudge/GDS
+prejudgment/MS
+prejudice/MGDS
+prejudiced/U
+prejudicial
+prekindergarten/SM
+prelacy/M
+prelate/SM
+prelim/SM
+preliminarily
+preliminary/SM
+preliterate
+preloaded
+prelude/MS
+premarital
+premature/YP
+prematurity
+premed/SM
+premedical
+premeditate/GNDS
+premeditated/U
+premeditation/M
+premenstrual
+premier/SGMD
+premiere/MS
+premiership/SM
+premise/DSMG
+premium/SM
+premix/GDS
+premolar/SM
+premonition/SM
+premonitory
+prenatal/Y
+prenuptial
+preoccupation/MS
+preoccupy/DSG
+preoperative
+preordain/DSG
+prep/MS
+prepackage/DSG
+prepacked
+prepaid
+preparation/MS
+preparative
+preparatory
+prepare/ZGDRS
+prepared/UP
+preparedness/UM
+prepay/GSL
+prepayment/MS
+preplanned
+preponderance/SM
+preponderant/Y
+preponderate/GDS
+preposition/MS
+prepositional/Y
+prepossess/GDS
+prepossessing/U
+prepossession/SM
+preposterous/Y
+prepped
+prepping
+preppy/TRSM
+preprocessed
+prepubescence/M
+prepubescent/MS
+prepuce/MS
+prequel/MS
+prerecord/SGD
+preregister/DGS
+preregistration/M
+prerequisite/SM
+prerogative/SM
+pres
+presage/MGDS
+presbyopia/M
+presbyter/SM
+presbytery/SM
+preschool/SMRZ
+preschooler/M
+prescience/M
+prescient/Y
+prescribe/DSG
+prescript/SVM
+prescription/SM
+prescriptive/Y
+prescriptivism
+prescriptivist
+preseason/SM
+preselect/SD
+presence/SM
+present/LMDRYZGSB
+presentably
+presentation/ASM
+presentational/A
+presenter/M
+presentiment/MS
+presentment/SM
+preservation/M
+preservationist/SM
+preservative/SM
+preserve/BDRSMZG
+preserver/M
+preset/S
+presetting
+preshrank
+preshrink/SG
+preshrunk
+preside/GDS
+presidency/SM
+president/MS
+presidential
+presidia
+presidium/M
+presort/DGS
+press's
+press/ACGSD
+pressed/U
+presser/MS
+pressie/S
+pressing/SMY
+pressman/M
+pressmen
+pressure/DSMG
+pressurization/M
+pressurize/CDSG
+pressurized/U
+pressurizer/MS
+prestidigitation/M
+prestidigitator
+prestidigitatorial
+prestige/M
+prestigious
+presto/SM
+presumably
+presume/GDSB
+presumption/SM
+presumptive/Y
+presumptuous/PY
+presumptuousness/M
+presuppose/DSG
+presupposition/MS
+pretax
+preteen/MS
+pretend/DRZGS
+pretender/M
+pretending/U
+pretense/SXMN
+pretension/M
+pretentious/UY
+pretentiousness/M
+preterit/SM
+preterm
+preternatural/Y
+pretest/DGS
+pretext/MS
+pretreated
+pretreatment/S
+pretrial/S
+prettify/GDS
+prettily
+prettiness/M
+pretty/TGDRSMP
+pretzel/MS
+prevail/DGS
+prevalence/M
+prevalent/Y
+prevaricate/GNXDS
+prevarication/M
+prevaricator/SM
+prevent/DBSGV
+preventable/U
+preventative/SM
+prevention/SM
+preventive/SM
+preview/MDRSZG
+previous/Y
+prevision/MS
+prewar
+prey/GMDS
+prezzie/S
+priapic
+price's
+price/AGDS
+priceless
+pricey
+pricier
+priciest
+prick/MDRYSZG
+pricker/M
+prickle/MGDS
+prickliness/M
+prickly/PRT
+pride/MGDS
+prideful/Y
+prier/M
+priest/SMY
+priestess/MS
+priesthood/MS
+priestliness/M
+priestly/PRT
+prig/MS
+priggish/YP
+priggishness/M
+prim/YP
+primacy/M
+primal
+primarily
+primary/SM
+primate/MS
+prime/MZGDRSP
+primer/M
+primeval
+priming/M
+primitive/PSMY
+primitiveness/M
+primmer
+primmest
+primness/M
+primogenitor/MS
+primogeniture/M
+primordial/Y
+primp/DSG
+primrose/SM
+primula/S
+prince/SMY
+princedom/SM
+princeliness/M
+princely/PRT
+princess/MS
+principal/SMY
+principality/SM
+principle/DSM
+principled/U
+print/AMDSG
+printable/U
+printed/U
+printer/MS
+printing/SM
+printmaking
+printout/SM
+prion/S
+prior/MS
+prioress/MS
+prioritization
+prioritize/DSG
+priority/SM
+priory/SM
+prism/MS
+prismatic
+prison/SZMR
+prisoner/M
+prissily
+prissiness/M
+prissy/PTR
+pristine
+prithee
+privacy/M
+private/XMYTNRS
+privateer/SM
+privation/CSM
+privatization/MS
+privatize/DSG
+privet/SM
+privilege/DSMG
+privileged/U
+privily
+privy/RSMT
+prize/MGDS
+prized/A
+prizefight/MRSZG
+prizefighter/M
+prizefighting/M
+prizewinner/SM
+prizewinning
+pro/SM
+probabilist
+probabilistic
+probabilistically
+probability/SM
+probable/SM
+probably
+probate/MNV
+probation/ZMR
+probational
+probationary
+probationer/M
+probe/MGDSBJ
+probity/M
+problem/MS
+problematic/U
+problematical/Y
+probosces
+proboscis/MS
+procaine/M
+procedural/Y
+procedure/SM
+proceed/GJDS
+proceeding/M
+proceeds/M
+process's
+process/AGDS
+processable
+processed/U
+procession/DG
+processional/SM
+processor/SM
+proclaim/Z
+proclamation/MS
+proclivity/SM
+procrastinate/GNXDS
+procrastination/M
+procrastinator/SM
+procreate/V
+procreational
+procreatory
+proctor/GMDS
+proctorial
+procurement/SM
+prod/MS
+prodigal/MYS
+prodigality/M
+prodigious/Y
+prodigy/SM
+produce's
+produce/AZGDRS
+producer/AM
+producible/A
+product/M
+production/ASM
+productive/UAY
+productiveness/M
+productivity/M
+prof/MS
+profanation/SM
+profane/PYGDS
+profaneness/M
+profanity/SM
+professed/Y
+profession/MS
+professional/SMY
+professionalism/M
+professionalization
+professionalize/DSG
+professor/SM
+professorial/Y
+professorship/MS
+proffer/GMDS
+proficiency/SM
+proficient/MYS
+profit/BGD
+profitability/M
+profitable/U
+profitably/U
+profiteer/MDSG
+profiteering/M
+profiterole/MS
+profitless
+profligacy/M
+profligate/SMY
+proforma/S
+profound/PRYT
+profoundness/M
+profundity/SM
+profuse/PY
+profuseness/M
+progenitor/SM
+progeny/M
+progesterone/M
+prognathous
+prognoses
+prognosis/M
+prognostic/MS
+prognosticate/XDSGN
+prognostication/M
+prognosticator/MS
+program/CAS
+programed
+programing
+programmable/SM
+programmatic
+programmed/CA
+programmer/MS
+programming/MS
+progress/MDSGV
+progression/SM
+progressive/SMYP
+progressiveness/M
+prohibit/DGVS
+prohibition/SM
+prohibitionist/MS
+prohibitive/Y
+prohibitory
+project/GVMDS
+projected/A
+projectile/SM
+projection/SM
+projectionist/MS
+projective/Y
+projector/MS
+prole/S
+proletarian/MS
+proletariat/M
+proliferate/DSGN
+proliferation/M
+prolific
+prolifically
+prolix/Y
+prolixity/M
+prologize
+prologue/SM
+prologuize
+prolongation/SM
+prom/M
+promenade/MZGDRS
+promethium/M
+prominence/MS
+prominent/Y
+promiscuity/M
+promiscuous/Y
+promise/DSMG
+promising/Y
+promissory
+promo/M
+promontory/SM
+promote/BDRZG
+promoter/M
+promotional
+prompt/JPSMDRYZTG
+prompted/U
+prompter/M
+prompting/M
+promptitude/M
+promptness/M
+promulgate/XGNDS
+promulgation/M
+promulgator/MS
+prone/P
+proneness/M
+prong/MDS
+pronghorn/MS
+pronominal/M
+pronounce/DSLG
+pronounceable/U
+pronounced/Y
+pronouncement/MS
+pronto
+pronunciation/MS
+proof/ADGSM
+proofread/SZGR
+proofreader/M
+prop/MS
+propaganda/M
+propagandist/SM
+propagandize/DSG
+propagate/DSGN
+propagation/M
+propagator/SM
+propane/M
+propel/S
+propellant/MS
+propelled
+propeller/SM
+propelling
+propensity/SM
+proper/MRYT
+property/DSM
+prophecy/SM
+prophesier/M
+prophesy/DRSMZG
+prophet/SM
+prophetess/MS
+prophetic
+prophetical/Y
+prophylactic/SM
+prophylaxes
+prophylaxis/M
+propinquity/M
+propitiate/DSGN
+propitiation/M
+propitiatory
+propitious/Y
+proponent/SM
+proportion/ESM
+proportional/EY
+proportionality
+proportionals
+proportionate/EY
+proposal/MS
+propped
+propping
+proprietary/SM
+proprieties/M
+proprietor/MS
+proprietorial/Y
+proprietorship/M
+proprietress/MS
+propriety/SM
+proprioceptive
+propulsion/M
+propulsive
+propylene
+prorate/DSG
+prorogation/M
+prorogue/GD
+prosaic
+prosaically
+proscenium/SM
+prosciutto/M
+proscription/MS
+proscriptive
+prose/MS
+prosecute/DSGNBX
+prosecution/M
+prosecutor/SM
+proselyte/DSMG
+proselytism/M
+proselytize/ZGDRS
+proselytizer/M
+prosodic
+prosody/SM
+prospect/MDGVS
+prospective/Y
+prospector/MS
+prospectus/MS
+prosper/GSD
+prosperity/M
+prosperous/Y
+prostate/MS
+prostheses
+prosthesis/M
+prosthetic
+prostitute/MGNDS
+prostitution/M
+prostrate/GNXDS
+prostration/M
+prosy/RT
+protactinium/M
+protagonist/MS
+protean
+protease
+protect/GVSD
+protected/U
+protection/SM
+protectionism/M
+protectionist/MS
+protective/YP
+protectiveness/M
+protector/MS
+protectorate/SM
+protege/SM
+protegee/S
+protein/SM
+protestant/S
+protestantism
+protestation/SM
+protists
+protocol/MS
+proton/SM
+protoplasm/M
+protoplasmic
+prototype/MGDS
+prototypical
+protozoa
+protozoan/MS
+protozoic
+protract/GD
+protrude/GDS
+protrusile
+protrusion/MS
+protrusive
+protuberance/MS
+protuberant
+proud/RYT
+prov/ZNRB
+provability/M
+provable/EU
+provably
+prove/EAGDS
+proved/U
+proven/U
+provenance/SM
+provender/M
+provenience/M
+proverbial/Y
+provide/BDRSZG
+provided/U
+providence/M
+provident/Y
+providential/Y
+provider/M
+province/MS
+provincial/SMY
+provincialism/M
+provisional/Y
+proviso/SM
+provocateur/S
+provocative/YP
+provocativeness/M
+provoke/DRSZG
+provoked/U
+provoker/M
+provoking/Y
+provolone/M
+provost/SM
+prow/MS
+prowess/M
+prowl/MDRSZG
+prowler/M
+proximal
+proximate/Y
+proximity/M
+proxy/SM
+prude/MS
+prudence/M
+prudent/Y
+prudential/Y
+prudery/M
+prudish/YP
+prudishness/M
+prune/MZGDRS
+pruner/M
+prurience/M
+prurient/Y
+prussic
+pry/ZTGDRSM
+psalm/MS
+psalmist/SM
+psalter
+psaltery/SM
+psephologist/S
+psephology
+pseud/S
+pseudo/S
+pseudonym/SM
+pseudonymous
+pseudopod
+pseudopodia
+pseudoscience/MS
+pseudy
+pshaw/MS
+psi/SM
+psittacosis/M
+psoriasis/M
+psst
+psych/MDSG
+psyche/M
+psychedelia
+psychedelic/SM
+psychedelically
+psychiatric
+psychiatrist/SM
+psychiatry/M
+psychic/MS
+psychical/Y
+psycho/SM
+psychoactive
+psychoanalysis/M
+psychoanalyst/MS
+psychoanalytic
+psychoanalytical/Y
+psychoanalyze/GDS
+psychobabble/M
+psychodrama/SM
+psychogenic
+psychokinesis
+psychokinetic
+psycholinguistic/S
+psycholinguists
+psychological/Y
+psychologist/SM
+psychology/SM
+psychometric
+psychoneuroses
+psychoneurosis/M
+psychopath/M
+psychopathic
+psychopathology
+psychopaths
+psychopathy/M
+psychos/S
+psychosis/M
+psychosocial
+psychosomatic
+psychotherapist/MS
+psychotherapy/SM
+psychotic/SM
+psychotically
+psychotropic/MS
+psychs
+pt/C
+ptarmigan/MS
+pterodactyl/SM
+pterosaurs
+ptomaine/SM
+pub/SM
+pubertal
+puberty/M
+pubes/M
+pubescence/M
+pubescent
+pubic
+pubis/M
+public/AM
+publican/AMS
+publication/AMS
+publicist/MS
+publicity/M
+publicize/GDS
+publicized/U
+publicly
+publish/AGDS
+publishable/U
+published/U
+publisher/MS
+publishing/M
+puce/M
+puck/ZMRS
+pucker/MDG
+puckish/YP
+puckishness/M
+pud/S
+pudding/SM
+puddle/DSMG
+puddling/M
+pudenda
+pudendum/M
+pudginess/M
+pudgy/PRT
+pueblo/SM
+puerile
+puerility/M
+puerperal
+puff/ZGMDRS
+puffball/SM
+puffer/M
+puffin/SM
+puffiness/M
+puffy/PRT
+pug/SM
+pugilism/M
+pugilist/SM
+pugilistic
+pugnacious/PY
+pugnaciousness/M
+pugnacity/M
+puissant
+puke/MGDS
+pukka
+pulchritude/M
+pulchritudinous
+pule/GDS
+pull/ZGMDRS
+pullback/MS
+puller/M
+pullet/SM
+pulley/SM
+pullout/MS
+pullover/SM
+pulmonary
+pulp/GMDS
+pulpiness/M
+pulpit/SM
+pulpwood/M
+pulpy/RPT
+pulsar/SM
+pulsate/XGNDS
+pulsation/M
+pulse/AMGDS
+pulverization/M
+pulverize/DSG
+puma/MS
+pumice/SM
+pummel/SGD
+pump/ZGMDRS
+pumper/M
+pumpernickel/M
+pumpkin/MS
+pun/SM
+punch/MDRSBZG
+punchbag/S
+punchbowl
+puncheon/MS
+puncher/M
+punchline/S
+punchy/TR
+punctilio/M
+punctilious/YP
+punctiliousness/M
+punctual/Y
+punctuality/M
+punctuate/XGNDS
+punctuation/M
+punctuational
+puncture/DSMG
+pundit/SM
+punditry/M
+pungency/M
+pungent/Y
+puniness/M
+punish/BLGDS
+punished/U
+punishing/Y
+punishment/SM
+punitive/Y
+punk/TMRS
+punned
+punnet/S
+punning
+punster/SM
+punt/ZGMDRS
+punter/M
+puny/TRP
+pup/SM
+pupa/M
+pupae
+pupal
+pupate/DSG
+pupil/MS
+pupillage
+pupped
+puppet/MS
+puppeteer/SM
+puppetry/M
+pupping
+puppy/SM
+purblind
+purchase/DRSMZGB
+purchaser/M
+purdah/M
+pure/PYTR
+purebred/SM
+puree/MDS
+pureeing
+pureness/M
+purgative/SM
+purgatorial
+purgatory/SM
+purge/MZGDRS
+purger/M
+purification/M
+purifier/M
+purify/DRSZGN
+purine/MS
+purism/M
+purist/MS
+puristic
+puritan/SM
+puritanical/Y
+puritanism/M
+purity/SM
+purl/GMDS
+purlieu/SM
+purloin/SGD
+purple/MTRS
+purplish
+purport/SMDG
+purported/Y
+purpose/DSMYGV
+purposeful/PY
+purposefulness/M
+purposeless/YP
+purr/GMDS
+purse/MZGDRS
+purser/M
+pursuance/M
+pursuant
+pursue/ZGDRS
+pursuer/M
+pursuit/SM
+purulence/M
+purulent
+purvey/DSG
+purveyance/M
+purveyor/SM
+purview/M
+pus/M
+push/BZGMDRS
+pushbike/S
+pushcart/SM
+pushchair/S
+pusher/M
+pushily
+pushiness/M
+pushover/MS
+pushpin/S
+pushy/TRP
+pusillanimity/M
+pusillanimous/Y
+puss/MS
+pussy/TRSM
+pussycat/MS
+pussyfoot/DSG
+pustular
+pustule/SM
+put/ISM
+putative/Y
+putout/MS
+putrefaction/M
+putrefactive
+putrefy/GDS
+putrescence/M
+putrescent
+putrid
+putridity
+putsch/MS
+putt/ZGMDRS
+putted/I
+puttee/MS
+putter/MDRZG
+putterer/M
+putting/I
+putty/GDSM
+putz/S
+puzzle/MZGDRSL
+puzzlement/M
+puzzler/M
+puzzling/Y
+pvt
+pygmy/SM
+pylon/SM
+pylori
+pyloric
+pylorus/M
+pyorrhea/M
+pyramid/GSMD
+pyramidal
+pyre/MS
+pyridine
+pyrimidine/MS
+pyrite/SM
+pyrites/M
+pyrolysis
+pyrolyze
+pyromania/M
+pyromaniac/MS
+pyrotechnic/S
+pyrotechnical
+pyrotechnics/M
+pyroxene/S
+python/SM
+pyx/MS
+pzazz
+q
+qr
+qt
+qty
+qua
+quack/GMDS
+quackery/M
+quackish
+quad/MS
+quadrangle/MS
+quadrangular
+quadrant/MS
+quadraphonic
+quadratic/MS
+quadratically
+quadrature/S
+quadrennial
+quadrennium/SM
+quadriceps/MS
+quadrilateral/MS
+quadrille/MNSX
+quadrillion/M
+quadripartite
+quadriplegia/M
+quadriplegic/SM
+quadrivium/M
+quadruped/MS
+quadrupedal
+quadruple/MGDS
+quadruplet/SM
+quadruplicate/DSMGN
+quadruplication/M
+quadruply
+quadrupole
+quaff/GMDS
+quagmire/SM
+quahog/MS
+quail/GMDS
+quaint/PRYT
+quaintness/M
+quake/MGDS
+quaky/TR
+qualification/EM
+qualified/U
+qualifier/SM
+qualify/EXGNDS
+qualitative/Y
+quality/SM
+qualm/MS
+qualmish
+quandary/SM
+quango/S
+quanta
+quantifiable/U
+quantification/M
+quantified/U
+quantifier/M
+quantify/NDRSZG
+quantitative/Y
+quantity/SM
+quantization
+quantize/D
+quantum/M
+quarantine/MGDS
+quark/MS
+quarrel/SZGMDR
+quarreler/M
+quarrelsome/P
+quarrelsomeness/M
+quarry/DSMG
+quarrymen
+quart/MS
+quarter/SGMDY
+quarterback/SGMD
+quarterdeck/MS
+quarterfinal/SM
+quarterly/SM
+quartermaster/MS
+quarterstaff/M
+quarterstaves
+quartet/SM
+quartic/S
+quartile/S
+quarto/MS
+quartz/M
+quartzite
+quasar/MS
+quash/GDS
+quasi
+quasilinear
+quaternary
+quaternion/S
+quatrain/MS
+quaver/MDSG
+quavery
+quay/MS
+quayside/S
+queasily
+queasiness/M
+queasy/TPR
+queen/GMDYS
+queenly/RT
+queer/PTGMDRYS
+queerness/M
+quell/GDS
+quench/ZGDRSB
+quenchable/U
+quencher/M
+quenchless
+quern
+querulous/YP
+querulousness/M
+query/DSMG
+ques/S
+quest/IFAMS
+quested
+questing
+question/BJSMDRZG
+questionable/U
+questionably/U
+questioned/U
+questioner/M
+questioning/MY
+questionnaire/MS
+queue/MDSG
+quibble/DRSMZG
+quibbler/M
+quiche/SM
+quick/MNRYXTP
+quicken/DG
+quickfire
+quickie/SM
+quicklime/M
+quickness/M
+quicksand/MS
+quicksilver/M
+quickstep/MS
+quid/MS
+quiesce/D
+quiescence/M
+quiescent/Y
+quiet/SMDNRYXTGP
+quieten/DG
+quietism
+quietness/M
+quietude/IEM
+quietus/MS
+quiff/S
+quill/SM
+quilt/SMDRZG
+quilter/M
+quilting/M
+quin/S
+quince/SM
+quincentenary
+quine/S
+quinine/M
+quinquennial
+quinsy/M
+quint/SM
+quintessence/MS
+quintessential/Y
+quintet/SM
+quintic
+quintillion
+quintuple/MGDS
+quintuplet/SM
+quip/MS
+quipped
+quipper
+quipping
+quipster/SM
+quire's
+quire/IAS
+quirk/SMDG
+quirkiness/M
+quirky/RTP
+quirt/SM
+quisling/SM
+quit/S
+quitclaim/MS
+quite
+quittance/M
+quitter/SM
+quitting
+quiver/SMDG
+quivering/Y
+quivery
+quixotic
+quixotically
+quiz/M
+quizzed
+quizzer/SM
+quizzes
+quizzical/Y
+quizzing
+quoin/SM
+quoit/SMDG
+quondam
+quorate/I
+quorum/SM
+quot/RB
+quota/SM
+quotability/M
+quotation/SM
+quote's
+quote/UDSG
+quoth
+quotidian
+quotient/SM
+qwerty
+r/S
+rabbet/GMDS
+rabbi/SM
+rabbinate/M
+rabbinic
+rabbinical
+rabbit/GMDS
+rabble/MS
+rabid/PY
+rabidness/M
+rabies/M
+raccoon/MS
+race/MZGDRS
+racecourse/MS
+racegoer/S
+racehorse/MS
+raceme/MS
+racer/M
+racetrack/MS
+raceway/MS
+racial/Y
+racialism/M
+racialist/MS
+racily
+raciness/M
+racing/M
+racism/M
+racist/SM
+rack/GMDS
+racket/SMDG
+racketeer/GSMD
+racketeering/M
+raconteur/SM
+racquetball/MS
+racy/PRT
+rad/SM
+radar/SM
+radarscope/MS
+radder
+raddest
+raddled
+radial/SMY
+radian/S
+radiance/M
+radiant/Y
+radiate/DSGNVX
+radiation/M
+radiative/Y
+radiator/SM
+radical/SMY
+radicalism/M
+radicalization/M
+radicalize/DSG
+radicchio/M
+radii
+radio/MDGS
+radioactive/Y
+radioactivity/M
+radioastronomical
+radiocarbon/M
+radiogalaxy/S
+radiogram/MS
+radiographer/SM
+radiography/M
+radioisotope/SM
+radiological
+radiologist/SM
+radiology/M
+radioman/M
+radiomen
+radiometer/SM
+radiometric
+radiometry/M
+radionuclide
+radiophone/SM
+radioscopy/M
+radiosonde/MS
+radiotelegraph/M
+radiotelegraphs
+radiotelegraphy/M
+radiotelephone/SM
+radiotherapist/SM
+radiotherapy/M
+radish/MS
+radium/M
+radius/M
+radix
+radon/M
+raffia/M
+raffish/YP
+raffishness/M
+raffle/DSMG
+raft/ZGMDRS
+rafter/M
+rafting/M
+rag/SGMD
+raga/MS
+ragamuffin/MS
+ragbag/M
+rage/MS
+ragga
+ragged/RYTP
+raggedness/M
+raggedy/RT
+ragging
+raging/Y
+raglan/SM
+ragout/SM
+ragtag/S
+ragtime/M
+ragweed/M
+ragwort
+rah
+raid/ZGMDRS
+raider/M
+rail's
+rail/CGDS
+railcard/S
+railing/SM
+raillery/SM
+railroad/SZGMDR
+railroader/M
+railroading/M
+railway/SM
+railwayman
+railwaymen
+raiment/M
+rain/GMDS
+rainbow/SM
+raincloud/S
+raincoat/SM
+raindrop/SM
+rainfall/SM
+rainless
+rainmaker/SM
+rainmaking/M
+rainproof
+rainstorm/MS
+rainswept
+rainwater/M
+rainy/RT
+raise/MZGDRS
+raiser/M
+raisin/SM
+raj
+rajah/M
+rajahs
+rake/MGDS
+rakish/YP
+rakishness/M
+rally/DSMG
+ram/SM
+ramble/DRSMZGJ
+rambler/M
+rambunctious/PY
+rambunctiousness/M
+ramekin/SM
+ramie/M
+ramification/M
+ramify/DSGXN
+ramjet/SM
+rammed
+ramming
+ramp/MDS
+rampage/DSMG
+rampancy/M
+rampant/Y
+rampart/SM
+ramrod/SM
+ramrodded
+ramrodding
+ramshackle
+ran/A
+ranch/MDRSZG
+rancher/M
+ranching/M
+rancid/P
+rancidity/M
+rancidness/M
+rancor/M
+rancorous/Y
+rand/MS
+randiness/M
+random/PSY
+randomization/M
+randomize/DSG
+randomness/MS
+randy/RTP
+ranee/MS
+rang/ZR
+range's
+range/CGDS
+rangefinder/S
+ranger/M
+ranginess/M
+rangy/RTP
+rank/TGJPMDRYS
+ranking/M
+rankle/DSG
+rankness/M
+ransack/SGD
+ransom/SZGMDR
+ransomer/M
+rant/ZGMDJRS
+ranter/M
+rap/SZGMDR
+rapacious/PY
+rapaciousness/M
+rapacity/M
+rape/MS
+raper/M
+rapeseed/M
+rapid/PMRYTS
+rapidity/M
+rapidness/M
+rapier/SM
+rapine/M
+rapist/SM
+rapped
+rappel/SM
+rappelled
+rappelling
+rapper/SM
+rapping
+rapport/MS
+rapporteur/S
+rapprochement/SM
+rapscallion/SM
+rapt/YP
+raptness/M
+raptor/S
+rapture/MS
+rapturous/Y
+rare/YTGPDRS
+rarebit/MS
+rarefaction/SM
+rarefy/GDS
+rareness/M
+rarity/SM
+rascal/SMY
+rash/ZTMRSYP
+rasher/M
+rashness/M
+rasp/GMDRS
+raspberry/SM
+raspy/RT
+raster
+rat/SM
+ratatouille/M
+ratbag/S
+ratchet/GMDS
+rate/BJXMZGNDRS
+rateable
+rated/U
+ratepayer/S
+rater/M
+rather
+rathskeller/MS
+ratification/M
+ratifier/M
+ratify/DRSZGNX
+rating/M
+ratio/MS
+ratiocinate/GNDS
+ratiocination/M
+ration/MDG
+rational/SMY
+rationale/MS
+rationalism/M
+rationalist/MS
+rationalistic
+rationality/SM
+rationalization/MS
+rationalize/GDS
+ratlike
+ratline/SM
+rattan/SM
+ratted
+ratter/SM
+ratting
+rattle/DRSMZGJ
+rattlebrain/MDS
+rattler/M
+rattlesnake/MS
+rattletrap/SM
+rattly/RT
+rattrap/SM
+ratty/RT
+raucous/YP
+raucousness/M
+raunchily
+raunchiness/M
+raunchy/TRP
+ravage/DRSMZG
+ravager/M
+ravages/M
+rave/JMZGDRS
+ravel's
+ravel/UDSG
+raveling/S
+raven/MDSG
+ravenous/Y
+ravine/SM
+raving/MY
+ravioli/SM
+ravish/DRSZGL
+ravisher/M
+ravishing/Y
+ravishment/M
+raw/PTMR
+rawboned
+rawhide/M
+rawness/M
+ray/SM
+rayon/M
+raze/GDS
+razor/MSG
+razorback/MS
+razorbills
+razorblades
+razz/GMDS
+razzmatazz/M
+rcpt
+rd
+re/DSMYTGVJ
+reach/MDSGB
+reachable/U
+reached/U
+reacquire/DSG
+reacquisition
+react/V
+reactant/SM
+reactionary/SM
+read/ZGMRBJS
+readability/SM
+reader/M
+readership/SM
+readily
+readiness/M
+reading/M
+readmitted
+readout/SM
+ready/DRSTGP
+reafforestation
+real/TMRYPS
+realism/M
+realist/SM
+realistic/U
+realistically/U
+realities
+reality/UM
+realizable/U
+realization/MS
+realize/DSBG
+realized/U
+realm/MS
+realness/M
+realpolitik/M
+realty/M
+ream/ZGMDRS
+reamer/M
+reap/ZGDRS
+reaper/M
+rear/GMDS
+rearguard/MS
+rearmost
+rearward/S
+reason/SMDRZGB
+reasonable/UP
+reasonableness/UM
+reasonably/U
+reasoned/U
+reasoner/M
+reasoning/M
+reasonless
+reassuring/Y
+rebate/M
+rebel/MS
+rebellion/MS
+rebellious/YP
+rebelliousness/M
+rebid/S
+rebidding
+rebirth/M
+reboil/SDG
+rebook
+rebuild/SG
+rebuke/DSMG
+rebuking/Y
+rebuttal/MS
+rec'd
+rec/M
+recalcitrance/M
+recalcitrant
+recalibrate/GN
+recant/SDG
+recantation/SM
+recap/MS
+recapitalization
+recce/S
+recd
+receipt/SMDG
+receivables/M
+receive/DRSZGB
+received/U
+receiver/M
+receivership/M
+recension
+recent/YTP
+recentness/M
+receptacle/MS
+reception/MS
+receptionist/MS
+receptive/YP
+receptiveness/M
+receptivity/M
+receptor/SM
+recess/MDSGV
+recessional/MS
+recessionary
+recessive/SM
+recharge/R
+recherche
+recidivism/M
+recidivist/SM
+recipe/SM
+recipient/SM
+reciprocal/MYS
+reciprocate/DSGN
+reciprocation/M
+reciprocity/M
+recital/SM
+recitalist/SM
+recitative/SM
+reciter/SM
+reckless/YP
+recklessness/M
+reckon/SJDRG
+reckoning/M
+reclaim/BR
+reclamation/MS
+recline/DRSZG
+recliner/M
+recluse/SMV
+recognition/S
+recognizable/U
+recognizably/U
+recognizance/S
+recognize/BDRSZG
+recognized/U
+recombinant
+recombination
+recommended/U
+recompense/DSMG
+recompile/GD
+recon/S
+reconcile/GLDSB
+reconciled/U
+reconciliation/S
+recondite
+reconnaissance/SM
+reconnection
+reconnoiter/DGS
+reconstruct/V
+reconstructed/U
+recontribute
+reconversion
+recopy/DSG
+record/RBJZ
+recorded/U
+recorder/M
+recording/M
+recordists
+recount/SGMD
+recoup/DG
+recouple
+recourse/M
+recoverable/U
+recovery/SM
+recreant/MS
+recreational
+recriminate/GNXDS
+recrimination/M
+recriminatory
+recrudesce/GDS
+recrudescence/M
+recrudescent
+recruit/LSMDRZG
+recruiter/M
+recruitment/M
+recrystallization
+rectal/Y
+rectangle/MS
+rectangular
+rectifiable
+rectification/M
+rectifier/M
+rectify/NDRSZGX
+rectilinear
+rectitude/M
+recto/MS
+rector/SM
+rectory/SM
+rectum/SM
+recumbent
+recuperate/DSGNV
+recuperation/M
+recur/S
+recurred
+recurrence/SM
+recurring
+recursion/S
+recyclable/MS
+recycle/BZ
+recycling/M
+red/PSM
+redact/SDG
+redaction/M
+redactor/SM
+redbird/SM
+redbreast/MS
+redbrick
+redcap/SM
+redcoat/SM
+redcurrant/S
+redden/SDG
+redder
+reddest
+reddish
+redeclaration
+redeem/RZB
+redeemed/U
+redeemer/M
+redelivery
+redemption/M
+redemptive
+redeposition
+redesign/DSG
+redhead/SMD
+redirection
+redisplay
+redistribute/V
+redistrict/DG
+redivide/GDS
+redlining/M
+redneck/SM
+redness/M
+redo/G
+redolence/M
+redolent
+redoubt/SBM
+redoubtably
+redound/SDG
+redraw/SG
+redshift/S
+redskin/SM
+reduce/DRSZG
+reduced/U
+reducer/M
+reducibility
+reducible
+reduction/SM
+reductionism
+reductionist/S
+reductive
+redundancy/SM
+redundant/Y
+redwood/SM
+reediness/M
+reedy/RTP
+reef/ZGMDRS
+reefer/M
+reek/GMDS
+reel's
+reel/UGDS
+reeve/G
+reexport/SDG
+ref/SZM
+refashion/DGS
+refection/M
+refectory/SM
+refer/B
+referee/DSM
+refereed/U
+refereeing
+reference/MGDRS
+referenced/U
+referencing/U
+referendum/SM
+referent/SM
+referential/Y
+referral/SM
+referred
+referrer/SM
+referring
+reffed
+reffing
+refill/BJM
+refined/U
+refinement/MS
+refiner/SM
+refinery/S
+refitting
+reflate/XDSGN
+reflationary
+reflect/GVSD
+reflectance
+reflected/U
+reflection/SM
+reflectional
+reflective/PY
+reflectivity
+reflector/MS
+reflexive/PSMY
+reflexivity
+reflexology
+reflooring
+reforge/DSG
+reform/MB
+reformat/V
+reformatory/SM
+reformatting
+reformed/U
+reformist/S
+refortify/DSG
+refract/SGVD
+refractors
+refractory/SM
+refrain/SGMD
+refresh/ZGBLDRS
+refreshed/U
+refresher/M
+refreshing/Y
+refreshment/SM
+refreshments/M
+refrigerant/SM
+refrigerate/DSGN
+refrigerated/U
+refrigeration/M
+refrigerator/MS
+refuge/SM
+refugee/SM
+refulgence/M
+refulgent
+refund/B
+refurbishment/MS
+refusal/MS
+refuseniks
+refutation/MS
+refute/BDRSZG
+refuter/M
+reg
+regal/DYG
+regalement/M
+regalia/M
+regard/ESMDG
+regarded/U
+regardless
+regards/M
+regather/DGS
+regatta/SM
+regency/SM
+regeneracy/M
+regenerate/VX
+regexp/S
+reggae/M
+regicide/MS
+regime/SM
+regimen/SM
+regiment/MDGS
+regimental
+regimentation/M
+region/SM
+regional/Y
+regionalism/MS
+register/GMDS
+registered/U
+registrable
+registrant/MS
+registrar/MS
+registration/SM
+registry/SM
+regnant
+regress/MDSGV
+regression/MS
+regret/SM
+regretful/Y
+regrettable
+regrettably
+regretted
+regretting
+regrind/GS
+reground
+regroup/DGS
+regular/MYS
+regularity/SM
+regularization/M
+regularize/DSG
+regulate/CDSGNV
+regulated/U
+regulation/CM
+regulations
+regulator/MS
+regulatory
+regurgitate/GNDS
+regurgitation/M
+rehab/MS
+rehabbed
+rehabbing
+rehabilitate/DSGNV
+rehabilitation/M
+rehang/SDG
+rehears/GD
+rehearsal/MS
+rehearsed/U
+rehi
+rehung
+rehydrate
+reign/MDSG
+reimburse/BLDSG
+reimbursement/MS
+reimplementation
+rein/GD
+reindeer/M
+reinforce/GDSL
+reinforcement/MS
+reinitialization
+reinstall/DG
+reinstatement/M
+reinsurance
+reinvestigation
+reiterate/V
+reject/GSMD
+rejection/SM
+rejoice/JGDS
+rejoicing/M
+rejoinder/SM
+rejuvenate/DSXGN
+rejuvenation/M
+rejuvenatory
+rel
+relate/DRSXZGNV
+relatedness/M
+relater/M
+relation/M
+relational/Y
+relationship/SM
+relative/MYS
+relativism/M
+relativist/S
+relativistic
+relativistically
+relativity/M
+relax/DRSZG
+relaxant/MS
+relaxation/SM
+relaxer/M
+relaxing/Y
+relay/D
+releasable/U
+released/U
+relegate/GNDS
+relent/SGD
+relentless/PY
+relentlessness/M
+relevance/M
+relevancy/M
+relevant/Y
+reliability/UM
+reliable/U
+reliably/U
+reliance/M
+reliant
+relic/MS
+relict
+relief/SM
+relieve/ZGDRS
+reliever/M
+religion/SM
+religiosity
+religious/MYP
+religiousness/M
+reline/DSG
+relink/GD
+relinquish/GLDS
+relinquishment/M
+reliquary/SM
+relish/GMDS
+reluctance/M
+reluctant/Y
+rely/GDS
+rem/M
+remain/SGD
+remainder/MDSG
+remand/SGD
+remapping
+remark/B
+remarkableness/M
+remarkably
+remarked/U
+remediable
+remedy/GDSM
+remember/DG
+remembered/U
+remembrance/SM
+reminder/M
+reminisce/GDS
+reminiscence/SM
+reminiscent/Y
+remiss/PY
+remissness/M
+remit/S
+remittance/SM
+remitted
+remitting/U
+remix/DSG
+remnant/MS
+remodel/GDS
+remold/SGD
+remonstrant/MS
+remonstrate/XGNDS
+remorse/M
+remorseful/Y
+remorseless/PY
+remorselessness/M
+remote/RSMYTP
+remoteness/M
+remould/SDG
+removal/SM
+remunerate/DSGNVX
+remuneration/M
+renaissance/MS
+renal
+renascence/S
+renationalisation
+rend/GS
+render/SGMDJ
+rendering/M
+rendezvous/GMDS
+rendition/MS
+renegade/DSMG
+renege/DRSZG
+reneger/M
+renew/DSBG
+renewal/MS
+rennet/M
+rennin/M
+renormalization
+renounce/DSLG
+renouncement/M
+renovate/DSXGN
+renovation/M
+renovator/MS
+renown/MD
+rent/ZGMDRS
+rental/SM
+renter/M
+renunciation/SM
+reopen/SDG
+rep/SM
+repaint/GDS
+repairable/U
+repairer/MS
+repairman/M
+repairmen
+repaper
+reparable
+reparation/SM
+reparations/M
+repartee/M
+repatriate/DSXMGN
+repatriation/M
+repeat/SMDRZGB
+repeatability/U
+repeatable/U
+repeatably
+repeated/Y
+repeater/M
+repeating/M
+repel/S
+repelled
+repellent/SM
+repelling/Y
+repent/SDG
+repentance/M
+repentant/UY
+repercussion/S
+repertoire/MS
+repertory/SM
+repetition/MS
+repetitious/PY
+repetitiousness/M
+repetitive/YP
+repetitiveness/M
+rephotograph/GD
+replaceable
+replant/GSD
+replenish/DSGL
+replenishment/M
+replete/PDSGN
+repleteness/M
+repletion/M
+replica/SM
+replicable
+replicate/DSG
+replication/M
+replicator/S
+replug
+reply/XRN
+report/MRBZ
+reportage/M
+reported/Y
+reportorial
+reposeful
+repository/SM
+reprehend/DSG
+reprehensibility/M
+reprehensible
+reprehensibly
+reprehension/M
+represent/DGSB
+representable/U
+representative/PSM
+represented/U
+repression/SM
+repressive/YP
+reprieve/DSMG
+reprimand/GSMD
+reprisal/SM
+reprise/SMG
+reproach/BGMDS
+reproachful/PY
+reprobate/MS
+reproducibility
+reproducible/U
+reproducibly
+reprogrammable
+reprogramming
+reproving/Y
+reptile/SM
+reptilian/MS
+republic/S
+republicanism/M
+repudiate/XGNDS
+repudiation/M
+repudiator/MS
+repugnance/M
+repugnant
+repulsion/SM
+repulsive/PY
+repulsiveness/M
+repurchase/GDS
+reputability/M
+reputably/E
+reputation/MS
+repute/DSMGB
+reputed/Y
+request/GDR
+requested/U
+requiem/SM
+require/LDG
+requirement/SM
+requisite/MNXS
+requisition/GMD
+requital/M
+requite/DRSZG
+requited/U
+requiter/M
+reread/SG
+rerecord/GDS
+reredos
+reregistration
+rerouteing
+rerunning
+res/C
+resat
+rescind/SDG
+rescission/M
+rescue/DRSMZG
+rescuer/M
+reseal/B
+reselect
+reselection
+resemble/DSG
+resend/G
+resent/LSDG
+resentful/YP
+resentfulness/M
+resentment/SM
+reserpine/M
+reservation/SM
+reserved/UY
+reservedness/M
+reservist/SM
+reservoir/SM
+resetting
+reshipping
+reshow/G
+residence/SM
+residency/SM
+resident/MS
+residential
+residua
+residual/MS
+residuary
+residue/SM
+residuum/M
+resignal
+resignation/MS
+resigned/Y
+resilience/M
+resiliency/M
+resilient/Y
+resinous
+resiny
+resist/SMDRZGV
+resistance/MS
+resistant/U
+resistible
+resistive/Y
+resistivity
+resistless
+resistor/MS
+resitting
+resizing
+resold
+resole/DSG
+resolute/XPYTNR
+resoluteness/M
+resolvability
+resolvable/U
+resolve/M
+resolved/U
+resolvent
+resonance/SM
+resonant/Y
+resonate/GDS
+resonator/SM
+resorption/M
+resound/SGD
+resounding/Y
+resourceful/YP
+resourcefulness/M
+resp
+respecify
+respect/ESGVMD
+respectability/M
+respectable
+respectably
+respectful/EY
+respectfulness/M
+respective/Y
+respell/SGD
+respiration/M
+respirator/SM
+respiratory
+respire/DG
+resplendence/M
+resplendent/Y
+respond/SZGDR
+respondent/MS
+response/MS
+responsibility/SM
+responsible
+responsibly
+responsive/UPY
+responsiveness/UM
+rest/GVMDS
+restart/B
+restate/GDS
+restaurant/SM
+restaurateur/MS
+restful/YP
+restfuller
+restfullest
+restfulness/M
+restitution/M
+restive/YP
+restiveness/M
+restless/YP
+restlessness/M
+restoration/MS
+restorative/MS
+restorer/SM
+restrained/U
+restraint/MS
+restrict/SDGV
+restricted/U
+restriction/MS
+restrictive/PY
+restrictiveness/M
+restring/SG
+restroom/SM
+restructuring/MS
+resubstitute
+result/GSMD
+resultant/SM
+resume/DSMG
+resumption/SM
+resupply/DSG
+resurgence/MS
+resurgent
+resurrect/SGD
+resurrection/SM
+resuscitate/GNDS
+resuscitation/M
+resuscitator/SM
+resynchronization
+retailer/MS
+retain/SDRZG
+retainer/M
+retake/G
+retaliate/DSGNVX
+retaliation/M
+retaliatory
+retard/SMDRZG
+retardant/SM
+retardation/M
+retarder/M
+retch/DSG
+reteach/GS
+retention/MS
+retentive/PY
+retentiveness/M
+retentivity
+rethink/SGM
+rethought
+reticence/M
+reticent/Y
+reticular
+reticulated
+reticulation/SM
+reticule/S
+reticulum
+retina/SM
+retinal
+retinitis
+retinue/SM
+retiree/SM
+retirement/MS
+retort/GMD
+retrace/GDS
+retract/DBG
+retractile
+retraction/S
+retrain/DGS
+retread/D
+retrenchment/SM
+retribution/MS
+retributive
+retrieval/SM
+retrieve/DRSMZGB
+retriever/M
+retro/MS
+retroactive/Y
+retrofire/GDS
+retrofit/SM
+retrofitted
+retrofitting
+retrograde/DSG
+retrogress/DSGV
+retrogression/M
+retrorocket/SM
+retrospect/GVSMD
+retrospection/M
+retrospective/MYS
+retrovirus/MS
+retsina/M
+retuning
+returnable/MS
+returnee/SM
+rev/VM
+revamping/M
+revanchist
+reveal/BGJSD
+revealed/U
+revealing/Y
+reveille/M
+revel/JMDRSZG
+revelation/MS
+revelatory
+reveler/M
+revelry/SM
+revenge/MGDS
+revenuer/SM
+reverberant
+reverberate/DSXGN
+reverberation/M
+revere/DSG
+reverence/DSMG
+reverend/SM
+reverent/Y
+reverential/Y
+reverie/MS
+revers/M
+reversal/SM
+reverse/YR
+reversibility
+reversible
+reversibly
+revert/GSD
+revertible
+revetment/SM
+revile/DRSLZG
+revilement/M
+reviler/M
+revise/BXRZN
+revised/U
+reviser/M
+revision/M
+revisionary
+revisionism/M
+revisionist/MS
+revival/MS
+revivalism/M
+revivalist/SM
+revive/DRSG
+revivification/M
+revocable
+revoke/DRSZG
+revolt/GD
+revolting/Y
+revolution/SM
+revolutionary/SM
+revolutionist/SM
+revolutionize/DSG
+revolve/BZGDRS
+revolver/M
+revue/MS
+revulsion/M
+revved
+revving
+rewarded/U
+rewarding/U
+rewarm/GSD
+rewash/GDS
+reweave/GS
+rewedding
+rewind/MB
+rewound
+rewrite/M
+rhapsodic
+rhapsodical
+rhapsodize/DSG
+rhapsody/SM
+rhea/MS
+rhenium/M
+rheological
+rheology
+rheostat/SM
+rhesus/MS
+rhetoric/M
+rhetorical/Y
+rhetorician/MS
+rheum/M
+rheumatic/MS
+rheumatically
+rheumatism/M
+rheumatoid
+rheumy/TR
+rhinestone/SM
+rhinitis/M
+rhino/MS
+rhinoceros/MS
+rhizome/MS
+rho/SM
+rhodium/M
+rhododendron/SM
+rhomboid/SM
+rhomboidal
+rhombus/MS
+rhubarb/MS
+rhyme/MZGDRS
+rhymer/M
+rhymester/MS
+rhythm/SM
+rhythmic
+rhythmical/Y
+rial/MS
+rib/SM
+ribald
+ribaldry/M
+ribbed
+ribber/SM
+ribbing
+ribbon/SM
+ribcage
+riboflavin/M
+ribonucleic
+ribosomes
+rice/MZGDRS
+ricer/M
+rich/TMRSYP
+richness/M
+rick/GMDS
+rickets/M
+rickety/RT
+rickrack/M
+rickshaw/MS
+ricochet/GMDS
+ricotta/M
+rid/SR
+riddance/M
+ridden
+ridding
+riddle/DSMG
+ride's
+ride/CZGS
+rider/M
+riderless
+ridership/M
+ridge/MGDS
+ridgepole/SM
+ridgy/RT
+ridicule/MGDS
+ridiculous/PY
+ridiculousness/M
+riding/M
+rife/TR
+riff/GMDS
+riffle/DSMG
+riffraff/M
+rifle/MZGDRS
+rifleman/M
+riflemen
+rifler/M
+rifling/M
+rift/GMDS
+rig/SM
+rigatoni/M
+rigged
+rigger/SM
+rigging/M
+right/MDRYSPTG
+righteous/UP
+righteously
+righteousness/UM
+rightful/PY
+rightfulness/M
+rightism/M
+rightist/SM
+rightmost
+rightness/M
+righto
+rightsize/DSG
+rightward/S
+rigid/YP
+rigidify/S
+rigidity/SM
+rigidness/M
+rigmarole/MS
+rigor/MS
+rigorous/YP
+rigorousness/M
+rile/GDS
+rill/MS
+rim/SGMD
+rime/MS
+rimless
+rimmed
+rimming
+rind/MS
+ring/ZGMDRJ
+ringer/M
+ringgit/MS
+ringing/Y
+ringleader/MS
+ringlet/MS
+ringlike
+ringmaster/SM
+ringside/M
+ringworm/M
+rink/MS
+rinse/MGDS
+riot/ZGMDRS
+rioter/M
+rioting/M
+riotous/PY
+rip/SXTMNR
+riparian
+ripcord/MS
+ripe/YP
+ripen/DG
+ripened/U
+ripeness/M
+ripoff/SM
+riposte/MGDS
+ripped
+ripper/SM
+ripping
+ripple/DSMG
+ripply/TR
+ripsaw/SM
+ripstop
+riptide/MS
+rise/JMZGRS
+risen
+riser/M
+risibility/M
+risible
+rising/M
+risk/GMDS
+riskily
+riskiness/M
+risky/RPT
+risotto/MS
+risque
+rissole/S
+rite/MS
+ritual/SMY
+ritualism/M
+ritualistic
+ritualistically
+ritualized
+ritzy/RT
+riv/ZNR
+rival/MDSG
+rivaled/U
+rivalry/SM
+rive/CGDS
+river/M
+riverbank/SM
+riverbed/MS
+riverboat/SM
+riverfront
+riverside/MS
+rivet/MDRSZG
+riveter/M
+riveting/Y
+riviera/S
+rivulet/MS
+riyal/MS
+rm
+roach/GMDS
+road/IMS
+roadbed/SM
+roadblock/MDSG
+roadhouse/SM
+roadie/MS
+roadkill/M
+roadrunner/MS
+roadshow/SM
+roadside/SM
+roadsigns
+roadster/SM
+roadsweepers
+roadway/SM
+roadwork/SM
+roadworthy
+roam/ZGDRS
+roamer/M
+roaming/M
+roan/MS
+roar/ZGMDRS
+roarer/M
+roaring/M
+roast/ZGMDRSJ
+roaster/M
+roasting/M
+rob/S
+robbed
+robber/MS
+robbery/SM
+robbing
+robe's
+robe/EGDS
+robin/MS
+robot/MS
+robotic/S
+robotics/M
+robotize/GDS
+robust/RYPT
+robustness/M
+rock/ZGMDRS
+rockabilly/M
+rockbound
+rocker/M
+rockery/S
+rocket/MDSG
+rocketry/M
+rockfall/SM
+rockiness/M
+rocky/TRP
+rococo/M
+rod/SM
+rode
+rodent/MS
+rodeo/MS
+roe/SM
+roebuck/SM
+roentgen/MS
+roger/GDS
+rogue's
+rogue/KS
+roguery/M
+roguish/YP
+roguishness/M
+roil/GDS
+roister/ZGDRS
+roisterer/M
+role/MS
+roll/MDRZGJS
+rollback/SM
+rolled/A
+roller/M
+rollerblading
+rollerskating/M
+rollick/SDG
+rollicking/M
+rollmop/S
+rollover/SM
+romaine/MS
+roman/M
+romance/MZGDRS
+romancer/M
+romantic/MS
+romantically
+romanticism/M
+romanticist/MS
+romanticize/GDS
+romeo/MS
+romp/MDRZGS
+romper/M
+rondo/SM
+rood/MS
+roof/MDRZGS
+roofer/M
+roofgarden
+roofing/M
+roofless
+rooftop/SM
+rook/MDGS
+rookery/SM
+rookie/SM
+room/MDRZGS
+roomer/M
+roomette/SM
+roomful/SM
+roominess/M
+roommate/SM
+roomy/RTP
+roost/SMDRZG
+rooster/M
+root/MDRZGS
+rooter/M
+rootless/P
+rootlet/SM
+rootstock
+rope/MZGDRS
+roper/M
+ropey
+rosary/SM
+rose/MS
+roseate
+rosebud/SM
+rosebush/MS
+rosemary/M
+rosette/SM
+rosewater/M
+rosewood/MS
+rosily
+rosin/SMDG
+rosiness/M
+roster/SMG
+rostrum/MS
+rosy/RTP
+rot/SM
+rota/S
+rotary/SM
+rotate/DSGNBX
+rotation/M
+rotational/Y
+rotators
+rotatory
+rote/M
+rotgut/M
+rotisserie/SM
+rotogravure/SM
+rotor/SM
+rototiller/MS
+rotted
+rotten/TPRY
+rottenness/M
+rotter/S
+rotting
+rottweiler/S
+rotund/P
+rotunda/MS
+rotundity/M
+rotundness/M
+roue/MS
+rouge/DSMG
+rough/MDNRYXTGP
+roughage/M
+roughcast
+roughen/GD
+roughhouse/DSMG
+roughneck/MDSG
+roughness/M
+roughs
+roughshod
+roulette/M
+round/PSMDRYZTG
+roundabout/SM
+roundel/S
+roundelay/MS
+roundhouse/MS
+roundish
+roundness/M
+roundup/MS
+roundworm/SM
+rouse/DSG
+roust/SDG
+roustabout/SM
+rout/MRZS
+route's
+route/ADSG
+router/M
+routine/MYS
+routinize/GDS
+roux
+rove/ZGDRS
+rover/M
+row/SZGMDR
+rowan/S
+rowboat/MS
+rowdily
+rowdiness/M
+rowdy/PRSMT
+rowdyism/M
+rowel/SMDG
+rower/M
+rowing/M
+rowlock/S
+royal/SMY
+royalist/SM
+royalties/M
+royalty/SM
+rpm
+rps
+rt
+rte
+rub/SM
+rubato/SM
+rubbed
+rubber/SM
+rubberize/GDS
+rubberneck/SZGMDR
+rubbernecker/M
+rubbery/TR
+rubbing/S
+rubbish/MDSG
+rubbishy
+rubble/M
+rubdown/SM
+rube/MS
+rubella/M
+rubicund
+rubidium/M
+ruble/SM
+rubric/SM
+ruby/RSMT
+ruched
+ruck/DGS
+rucksack/MS
+ruckus/MS
+ruction/S
+rudder/SM
+rudderless
+ruddiness/M
+ruddy/RTP
+rude/YTRP
+rudeness/M
+rudiment/SM
+rudimentary
+rue/DSMG
+rueful/PY
+ruefulness/M
+ruff/MDYGS
+ruffian/MYS
+ruffle/DSMG
+ruffled/U
+ruffly/TR
+rug/SM
+rugby/M
+rugged/PTRY
+ruggedness/M
+rugger
+ruin/MDGS
+ruination/SM
+ruinous/Y
+rule/MZGJDRS
+rulebook/S
+ruler/M
+ruling/M
+rum/SM
+rumba/SMDG
+rumble/DSJMG
+rumbling/M
+rumbustious
+ruminant/MS
+ruminate/XGNVDS
+rumination/M
+ruminative/Y
+rummage/DSMG
+rummer
+rummest
+rummy/M
+rumor/SMDG
+rumormonger/MS
+rump/MYS
+rumple/DSMG
+rumply/RT
+rumpus/MS
+run/ASM
+runabout/MS
+runaround/SM
+runaway/MS
+rundown/SM
+rune/MS
+rung/MS
+runic
+runlet/SM
+runnable
+runnel/SM
+runner/SM
+running/M
+runny/RT
+runoff/SM
+runt/MS
+runty/RT
+runway/SM
+rupee/SM
+rupiah/M
+rupiahs
+rupture/MGDS
+rural/Y
+ruse/MS
+rush/MDRSZG
+rusher/M
+rushy/RT
+rusk/MS
+russet/SM
+rust/MDGS
+rustic/SM
+rustically
+rusticate/GDS
+rustication/M
+rusticity/M
+rustiness/M
+rustle/DRSJMZG
+rustler/M
+rustproof/SDG
+rusty/RPNT
+rut/SM
+rutabaga/SM
+ruthenium/M
+rutherfordium/M
+ruthless/PY
+ruthlessness/M
+rutted
+rutting
+rutty/RT
+rye/M
+s/NYXB
+sabbath
+sabbatical/MS
+saber/MS
+sable/MS
+sabot/MS
+sabotage/DSMG
+saboteur/SM
+sabra/MS
+sac/SM
+saccharides
+saccharin/M
+saccharine
+sacerdotal
+sachem/SM
+sachet/SM
+sack/GMDJS
+sackcloth/M
+sackful/MS
+sacking/M
+sacra
+sacral
+sacrament/MS
+sacramental
+sacred/YP
+sacredness/M
+sacrifice/DSMG
+sacrificial/Y
+sacrilege/MS
+sacrilegious/Y
+sacristan/MS
+sacristy/SM
+sacroiliac/SM
+sacrosanct/P
+sacrosanctness/M
+sacrum/M
+sad/PY
+sadden/SDG
+sadder
+saddest
+saddle's
+saddle/UDSG
+saddlebag/MS
+saddler/S
+saddlery
+sades
+sadhu/S
+sadism/M
+sadist/SM
+sadistic
+sadistically
+sadness/M
+sadomasochism/M
+sadomasochist/SM
+sadomasochistic
+safari/SGMD
+safe's
+safe/UYTPR
+safeguard/GSMD
+safekeeping/SM
+safeness/M
+safes
+safety/SM
+safflower/MS
+saffron/MS
+sag/SM
+saga/MS
+sagacious/Y
+sagacity/M
+sage/MYTRS
+sagebrush/M
+sagged
+sagging
+saggy/RT
+sago/M
+saguaro/MS
+sahib/MS
+said/U
+sail/GMDSJ
+sailboard/MRZGS
+sailboarder/M
+sailboarding/M
+sailboat/MS
+sailcloth/M
+sailfish/MS
+sailing/M
+sailor/SM
+sailplane/MS
+saint/MDYS
+sainthood/M
+saintlike
+saintliness/M
+saintly/PRT
+saith
+sake/MS
+salaam/SMDG
+salable/U
+salacious/YP
+salaciousness/M
+salacity/M
+salad/MS
+salamander/SM
+salami/SM
+salary/DSM
+sale/ABMS
+saleability
+saleroom/S
+salesclerk/MS
+salesgirl/SM
+saleslady/SM
+salesman/M
+salesmanship/M
+salesmen
+salespeople/M
+salesperson/SM
+salesroom/S
+saleswoman/M
+saleswomen
+salicylic
+salience/M
+salient/SMY
+saline/SM
+salinity/M
+saliva/M
+salivary
+salivate/XGNDS
+salivation/M
+sallow/RTP
+sallowness/M
+sally/DSMG
+salmon/SM
+salmonella/M
+salmonellae
+salon/MS
+saloon/SM
+salsa/MS
+salt's
+salt/CTGDS
+saltbox/MS
+saltcellar/SM
+salted/U
+salter
+saltine/SM
+saltiness/M
+saltpeter/M
+saltshaker/MS
+saltwater/M
+salty/RTP
+salubrious/I
+salubrity
+salutary
+salutation/MS
+salutatorian/SM
+salutatory
+salute/DSMG
+salvage/DSMG
+salvageable
+salvation/M
+salve/MZGDRS
+salver/M
+salvo/MS
+samarium/M
+samba/MDSG
+same/SP
+sameness/M
+samey
+samizdat/S
+samosa/S
+samovar/SM
+sampan/SM
+sample/DRSMZGJ
+sampler/M
+samurai/SM
+sanatorium/SM
+sanctification/M
+sanctify/NGDS
+sanctimonious/YP
+sanctimoniousness/M
+sanctimony/M
+sanction/GSMD
+sanctioned/U
+sanctity/M
+sanctuary/SM
+sanctum/SM
+sand/ZGMDRS
+sandal/SM
+sandalwood/M
+sandbag/SM
+sandbagged
+sandbagging
+sandbank/MS
+sandbar/SM
+sandblast/MDRSZG
+sandblaster/M
+sandbox/MS
+sandcastle/SM
+sander/M
+sandhog/SM
+sandiness/M
+sandlot/SM
+sandlotter/MS
+sandman/M
+sandmen
+sandpaper/MDGS
+sandpiper/MS
+sandpit/S
+sandstone/SM
+sandstorm/SM
+sandwich/MDSG
+sandy/RTP
+sane/IYTR
+saneness/M
+sang/S
+sangfroid/M
+sangria/M
+sanguinary
+sanguine/Y
+sanitarian/SM
+sanitarium/SM
+sanitary/IU
+sanitation/M
+sanitize/ZGDRS
+sanity/IM
+sank
+sans
+sanserif
+sap/SM
+sapience/M
+sapient
+sapless
+sapling/MS
+sapped
+sapper/S
+sapphire/SM
+sappiness/M
+sapping
+sappy/PRT
+saprophyte/MS
+saprophytic
+sapsucker/SM
+sapwood/M
+saran/M
+sarcasm/MS
+sarcastic
+sarcastically
+sarcoma/MS
+sarcophagi
+sarcophagus/M
+sardine/MS
+sardonic
+sardonically
+sarge/MS
+sari/MS
+sarky
+sarnie/S
+sarong/SM
+sarsaparilla/SM
+sartorial/Y
+sash/MS
+sashay/SGMD
+sass/GMDS
+sassafras/MS
+sassy/RT
+sat
+satanic
+satanical/Y
+satanism/M
+satanist/MS
+satay
+satchel/MS
+sate/GDS
+sateen/M
+satellite/DSMG
+satiable/I
+satiate/GNDS
+satiation/M
+satiety/M
+satin/MS
+satinwood/SM
+satiny
+satire/SM
+satiric
+satirical/Y
+satirist/SM
+satirize/DSG
+satisfaction/EM
+satisfactions
+satisfactorily/U
+satisfactory/U
+satisfiable/U
+satisfied/U
+satisfy/EDSG
+satisfying/U
+satisfyingly
+satori/M
+satrap/SM
+satsuma/S
+saturate/DSGN
+saturated/UC
+saturation/M
+saturnalia
+saturnine
+satyr/MS
+satyriasis/M
+satyric
+sauce/MZGDRS
+saucepan/SM
+saucer/M
+saucily
+sauciness/M
+saucy/RPT
+sauerkraut/M
+sauna/MDSG
+saunter/MDGS
+saurian
+sauropod/SM
+sausage/MS
+saute/MS
+sauteed
+sauteing
+savage/DRSMYTGP
+savageness/M
+savagery/SM
+savanna/MS
+savant/SM
+save/BJMZGDRS
+saved/U
+saveloy
+saver/M
+saving/M
+savings/M
+savior/SM
+savor/MDSG
+savoriness/M
+savory/PTRSM
+savoy/MS
+savvy/DRSMTG
+saw/SGMD
+sawbones/M
+sawbuck/MS
+sawdust/M
+sawfly/SM
+sawhorse/SM
+sawmill/MS
+sawtooth
+sawyer/SM
+sax/MS
+saxifrage/SM
+saxophone/MS
+saxophonist/MS
+say's
+say/USG
+saying/SM
+scab/MS
+scabbard/MS
+scabbed
+scabbiness/M
+scabbing
+scabby/PTR
+scabies/M
+scabrous
+scad/MS
+scaffold/SMG
+scaffolding/M
+scag/S
+scagged
+scagging
+scalability
+scalable
+scalar/S
+scalawag/MS
+scald/MDSG
+scale's
+scale/ACSDG
+scaled/U
+scaleless
+scalene
+scaliness/M
+scallion/MS
+scallop/GSMD
+scalp/MDRSZG
+scalpel/SM
+scalper/M
+scaly/RTP
+scam/MS
+scammed
+scamming
+scamp/MRSZ
+scamper/GMD
+scampi/M
+scan's
+scan/AS
+scandal/SM
+scandalize/GDS
+scandalmonger/SM
+scandalous/Y
+scandium/M
+scanned/A
+scanner/SM
+scanning/A
+scansion/M
+scant/CDSTG
+scanter
+scantily
+scantiness/M
+scantly
+scantness/M
+scanty/RSPT
+scape
+scapegoat/SMDG
+scapegrace/SM
+scapula/M
+scapulae
+scapular/SM
+scar/GMDS
+scarab/SM
+scarce/RYTP
+scarceness/M
+scarcity/SM
+scare/MS
+scarecrow/MS
+scaremonger/MSG
+scarf/MDSG
+scarification/M
+scarify/DSGN
+scarily
+scariness/M
+scarlatina/M
+scarlet/M
+scarp/MDRSZG
+scarper/DG
+scarred
+scarring
+scarves
+scary/RTP
+scat/MS
+scathe/DG
+scathed/U
+scathing/Y
+scatological
+scatology/M
+scatted
+scatter/ZGJSMDR
+scatterbrain/MDS
+scattering/M
+scatting
+scatty
+scavenge/ZGDRS
+scavenger/M
+scenario/MS
+scenarist/MS
+scene/MS
+scenery/M
+scenic
+scenically
+scent/CMS
+scented/U
+scenting
+scentless
+scepter/MDS
+sceptically
+sch
+schadenfreude
+schedule's
+schedule/ADSG
+scheduled/U
+scheduler/S
+schema
+schemata
+schematic/SM
+schematically
+schematize/GDS
+scheme/DRSMZG
+schemer/M
+scherzo/MS
+schilling/MS
+schism/SM
+schismatic/SM
+schist/M
+schizo/SM
+schizoid/MS
+schizophrenia/M
+schizophrenic/MS
+schizophrenically
+schlemiel/SM
+schlep/SM
+schlepped
+schlepping
+schlock/M
+schlocky/RT
+schmaltz/M
+schmaltzy/RT
+schmo/M
+schmoes
+schmooze/DRSZG
+schmuck/MS
+schnapps/M
+schnauzer/SM
+schnitzel/SM
+schnook/MS
+schnoz/MS
+schnozzle/SM
+scholar/MYS
+scholarship/MS
+scholastic
+scholastically
+scholasticism
+school/SGMD
+schoolbag/MS
+schoolbook/SM
+schoolboy/MS
+schoolchild/M
+schoolchildren
+schooldays
+schooled/U
+schoolfellow/MS
+schoolfriend
+schoolgirl/SM
+schoolhouse/MS
+schooling/M
+schoolkid/S
+schoolmarm/SM
+schoolmarmish
+schoolmaster/SM
+schoolmate/SM
+schoolmistress/MS
+schoolroom/SM
+schoolteacher/SM
+schoolwork/M
+schoolyard/SM
+schooner/SM
+schuss/GMDS
+schussboomer/SM
+schwa/MS
+sci
+sciatic
+sciatica/M
+science/FMS
+scientific/U
+scientifically/U
+scientist/SM
+scimitar/SM
+scintilla/MS
+scintillate/XDSGN
+scintillation/M
+scintillator/S
+scion/MS
+scissor/GDS
+scleroses
+sclerosis/M
+sclerotic
+scoff/MDRSZG
+scoffer/M
+scofflaw/MS
+scold/MDRSGJ
+scolding/M
+scoliosis/M
+sconce/SM
+scone/MS
+scoop/MDRSG
+scoopful/MS
+scoot/DRSZG
+scooter/M
+scope/MGDS
+scorbutic
+scorch/MDRSZG
+scorcher/M
+score/MZGDRS
+scoreboard/SM
+scorecard/MS
+scorekeeper/MS
+scoreless
+scoreline/S
+scorer/M
+scorn/MDRSZG
+scorner/M
+scornful/Y
+scorpion/MS
+scotch/MDSG
+scotchs
+scoundrel/MS
+scour/DRSZG
+scourer/M
+scourge/DSMG
+scout/MDRSZG
+scouting/M
+scoutmaster/SM
+scow/MS
+scowl/MDSG
+scrabble/MZGDRS
+scrabbler/M
+scrag/MS
+scraggly/RT
+scraggy/TR
+scram/S
+scramble's
+scramble/UGDS
+scrambler/MS
+scrammed
+scramming
+scrap/MDRSZGJ
+scrapbook/SM
+scrape/SM
+scraper/M
+scrapheap/SM
+scrapie
+scrapped
+scrapper/MS
+scrapping
+scrappy/TR
+scrapyard/SM
+scratch/GJMDS
+scratchcard/S
+scratched/U
+scratchily
+scratchiness/M
+scratchpad/S
+scratchy/RPT
+scrawl/SMDG
+scrawly/TR
+scrawniness/M
+scrawny/PTR
+scream/SMDRZG
+screamer/M
+screaming/Y
+scree/MDS
+screech/GMDS
+screechy/TR
+screed/S
+screen/SJMDG
+screening/M
+screenplay/SM
+screenwriter/MS
+screenwriting/M
+screw's
+screw/UDSG
+screwball/MS
+screwdriver/SM
+screwiness/M
+screwworm/SM
+screwy/PRT
+scribal
+scribble/JMZGDRS
+scribbler/M
+scribe's
+scribe/IKCGSD
+scrim/MS
+scrimmage/MGDS
+scrimp/SDG
+scrimshaw/MDGS
+scrip/MS
+script/FSMDG
+scripted/U
+scriptorium
+scriptural
+scripture/MS
+scriptwriter/MS
+scriptwriting
+scrivener/SM
+scrod/M
+scrofula/M
+scrofulous
+scrog/S
+scrogged
+scrogging
+scroll/GSBMD
+scrooge/MS
+scrota
+scrotal
+scrotum/M
+scrounge/DRSZG
+scrounger/M
+scroungy/TR
+scrub/MS
+scrubbed
+scrubber/SM
+scrubbing
+scrubby/RT
+scruff/SM
+scruffily
+scruffiness/M
+scruffy/RPT
+scrum/S
+scrumhalf
+scrumhalves
+scrummage/GS
+scrummed
+scrumming
+scrump/SGD
+scrumptious/Y
+scrumpy
+scrunch/MDSG
+scrunchy/SM
+scruple/MGDS
+scrupulosity/M
+scrupulous/UYP
+scrupulousness/UM
+scrutineer/S
+scrutinize/DSG
+scrutiny/SM
+scuba/MDSG
+scud/MS
+scudded
+scudding
+scuff/MDSG
+scuffle/MGDS
+scull/MDRSZG
+sculler/M
+scullery/SM
+scullion/SM
+sculpt/SGD
+sculptor/SM
+sculptress/MS
+sculptural
+sculpture/DSMG
+scum/MS
+scumbag/MS
+scummed
+scumming
+scummy/TR
+scupper/MDGS
+scurf/M
+scurfy/TR
+scurrility/M
+scurrilous/YP
+scurrilousness/M
+scurry/GDSMJ
+scurvily
+scurvy/TRM
+scutcheon/SM
+scuttle/MGDS
+scuttlebutt/M
+scuzzy/TR
+scythe/DSMG
+sea/SM
+seabed/SM
+seabird/MS
+seaboard/SM
+seaborne
+seacoast/SM
+seafarer/SM
+seafaring/M
+seafloor/SM
+seafood/M
+seafront/SM
+seagoing
+seagull/MS
+seahorse/MS
+seal's
+seal/AUSDG
+sealant/MS
+sealer/SM
+sealskin/M
+seam/GMDNS
+seamail
+seaman/M
+seamanship/M
+seamless/Y
+seamstress/MS
+seamy/RT
+seance/SM
+seaplane/SM
+seaport/MS
+sear/GMDS
+search/AZGMDRS
+searcher/AM
+searching/Y
+searchlight/SM
+searing/Y
+seascape/SM
+seashell/SM
+seashore/SM
+seasick/P
+seasickness/M
+seaside/MS
+season/SGMDBJ
+seasonable/U
+seasonably/U
+seasonal/Y
+seasonality
+seasoned/U
+seasoning/M
+seat's
+seat/UGDS
+seated/A
+seating/M
+seatmate/SM
+seawall/MS
+seaward/MS
+seawater/M
+seaway/SM
+seaweed/MS
+seaworthiness/M
+seaworthy/TRP
+sebaceous
+seborrhea/M
+sebum
+sec'y
+sec/SM
+secant/SM
+secateurs
+secede/DSG
+secession/MS
+secessionist/MS
+seclude/GDS
+seclusion/M
+seclusive
+second/SLZGMDRY
+secondarily
+secondary/SM
+seconder/M
+secondhand
+secondment/S
+secrecy/M
+secret/STGVMDRY
+secretarial
+secretariat/MS
+secretary/SM
+secretaryship/M
+secrete/XNS
+secretion/M
+secretive/YP
+secretiveness/M
+secretory
+sect/IMS
+sectarian/MS
+sectarianism/M
+sectary/SM
+section/AESM
+sectional/MS
+sectionalism/M
+sectioned
+sectioning
+sector/ESM
+sectoral
+sectored
+secular
+secularism/M
+secularist/SM
+secularization/M
+secularize/DSG
+secure/DRSYTG
+secured/U
+security/ISM
+secy
+sedan/MS
+sedate/DRSYTGNVP
+sedateness/M
+sedation/M
+sedative/SM
+sedentary
+sedge/MS
+sedgy/RT
+sediment/MS
+sedimentary
+sedimentation/M
+sedition/M
+seditious
+seduce/DRSZG
+seducer/M
+seduction/SM
+seductive/PY
+seductiveness/M
+seductress/MS
+sedulous/Y
+see/RSMZ
+seed's
+seed/AGDS
+seedbed/MS
+seedcase/MS
+seeded/U
+seeder/SM
+seediness/M
+seedless
+seedling/MS
+seedpod/MS
+seedy/RPT
+seeing/S
+seek/ZGRS
+seeker/M
+seem/GDS
+seeming/Y
+seemliness/UM
+seemly/URTP
+seen
+seep/GDS
+seepage/M
+seer/M
+seersucker/M
+seesaw/SMDG
+seethe/DSG
+segfault/S
+segment/GSMD
+segmental
+segmentation/M
+segmented/U
+segregate/CDSGN
+segregated/U
+segregation/CM
+segregationist/SM
+segue/MDS
+segueing
+seigneur/SM
+seignior/SM
+seine/MZGDRS
+seiner/M
+seismic
+seismically
+seismogram
+seismograph/ZMR
+seismographer/M
+seismographic
+seismographs
+seismography/M
+seismologic
+seismological
+seismologist/SM
+seismology/M
+seismometer/S
+seize/GDS
+seizure/MS
+seldom
+select/CSGDV
+selectable
+selected/UA
+selection/SM
+selective/Y
+selectivity/M
+selectman/M
+selectmen
+selectness/M
+selector/MS
+selenium/M
+selenographer/MS
+selenography/M
+selenology
+self/M
+selfish/UYP
+selfishness/UM
+selfless/YP
+selflessness/M
+selfsame
+sell's
+sell/AZGRS
+seller's
+sellotape/DSG
+sellout/MS
+seltzer/MS
+selvage/MS
+selves
+semantic/S
+semantically
+semanticist/SM
+semantics/M
+semaphore/DSMG
+semblance/ASM
+semen/M
+semester/SM
+semi/MS
+semiannual/Y
+semiarid
+semiautomatic/MS
+semibreve/S
+semicircle/SM
+semicircular
+semicolon/MS
+semiconducting
+semiconductor/SM
+semiconscious
+semidarkness/M
+semidetached
+semifinal/SM
+semifinalist/SM
+semigloss/S
+semimonthly/SM
+seminal
+seminar/MS
+seminarian/SM
+seminary/SM
+semiofficial
+semiotic/S
+semioticians
+semiotics/M
+semipermeable
+semiprecious
+semiprivate
+semipro/S
+semiprofessional/MS
+semiquaver/S
+semiretired
+semiskilled
+semisolid
+semisweet
+semitone/SM
+semitrailer/SM
+semitransparent
+semitropical
+semivowel/SM
+semiweekly/SM
+semiyearly
+semolina/M
+sempiternal
+sempstress/MS
+senate/SM
+senator/MS
+senatorial
+send/ZGRS
+sender/M
+sendoff/MS
+senescence/M
+senescent
+senile
+senility/M
+senior/SM
+seniority/M
+senna/M
+senor/MS
+senora/SM
+senorita/SM
+sensation/MS
+sensational/Y
+sensationalism/M
+sensationalist/MS
+sensationalistic
+sensationalize/GDS
+sense/MGDS
+senseless/PY
+senselessness/M
+sensibilities
+sensibility/IM
+sensible/PRT
+sensibleness/M
+sensibly/I
+sensitive/SPMY
+sensitiveness/M
+sensitivities
+sensitivity/IM
+sensitization/CM
+sensitize/CDSG
+sensitizers
+sensor/SM
+sensory
+sensual/FY
+sensualist/MS
+sensuality/M
+sensuous/YP
+sensuousness/M
+sent/FAU
+sentence/MGDS
+sentential
+sententious/Y
+sentience/IM
+sentient/I
+sentiment/SM
+sentimental/Y
+sentimentalism/M
+sentimentalist/MS
+sentimentality/M
+sentimentalization/M
+sentimentalize/GDS
+sentinel/MS
+sentry/SM
+sepal/MS
+separability/IM
+separable
+separably/I
+separate/PXMYGNVDS
+separateness/M
+separation/M
+separatism/M
+separatist/MS
+separator/MS
+sepia/M
+sepsis/M
+septa
+septet/SM
+septic
+septicemia/M
+septicemic
+septuagenarian/MS
+septum/M
+sepulcher/GMDS
+sepulchral
+seq
+sequel/SM
+sequence/MZGDRS
+sequencing/M
+sequent/F
+sequential/FY
+sequester/GSD
+sequestrate/XDSGN
+sequestration/M
+sequin/SMD
+sequoia/MS
+seraglio/MS
+serape/SM
+seraph/M
+seraphic
+seraphically
+seraphim's
+seraphs
+sere/TR
+serenade/MGDRS
+serendipitous/Y
+serendipity/M
+serene/RPYT
+sereneness/M
+serenity/M
+serf/MS
+serfdom/M
+serge/M
+sergeant/MS
+serial/SMY
+serialization/MS
+serialize/GDS
+series/M
+serif/MDS
+serigraph/M
+serigraphs
+serious/PY
+seriousness/M
+sermon/SM
+sermonize/GDS
+serology/M
+serotonin
+serous
+serpent/MS
+serpentine/M
+serrate/XND
+serration/M
+serried
+serum/MS
+servant/MS
+serve's/AF
+serve/FACGDS
+server/SM
+servery/S
+service/EMS
+serviceability/M
+serviceable/U
+serviced/U
+serviceman/M
+servicemen
+servicewoman/M
+servicewomen
+servicing
+serviette/MS
+servile/Y
+servility/M
+serving's
+servings
+servitor/MS
+servitude/M
+servo/MS
+servomechanism/SM
+servomotor/MS
+sesame/SM
+sesquicentennial/MS
+sessile
+session/MS
+set/AISM
+setback/MS
+setscrew/SM
+setsquare/S
+sett/BJZGRS
+settable/A
+settee/MS
+setter/M
+setting/M
+settle's
+settle/AUGDS
+settlement/AM
+settlements
+settler/SM
+setup/MS
+seven/MHS
+sevenfold
+sevenpence
+seventeen/SMH
+seventeenth/M
+seventeenths
+seventh/M
+sevenths
+seventieth/M
+seventieths
+seventy/SMH
+sever/ETGDS
+several/MY
+severance/SM
+severe/YPR
+severeness/M
+severity/M
+sew/ASGD
+sewage/M
+sewer/MS
+sewerage/M
+sewing/M
+sewn
+sex/GMDS
+sexagenarian/SM
+sexily
+sexiness/M
+sexism/M
+sexist/MS
+sexless
+sexologist/MS
+sexology/M
+sexpot/MS
+sextant/SM
+sextet/MS
+sexton/MS
+sextuplet/SM
+sexual/Y
+sexuality/SM
+sexy/PTR
+sf
+sh
+shabbily
+shabbiness/M
+shabby/PTR
+shack/MDSG
+shackle's
+shackle/UGDS
+shad/GMDSJ
+shade/MS
+shaded/U
+shadeless
+shadily
+shadiness/M
+shading/M
+shadow/SGMD
+shadowbox/GDS
+shadowless
+shadowy/RT
+shady/RPT
+shaft/MDSG
+shag/MS
+shagged
+shagginess/M
+shagging
+shaggy/TPR
+shah/M
+shahs
+shaikh
+shaikhs
+shakable/U
+shake/MZGRSB
+shakeable
+shakedown/SM
+shaken/U
+shakeout/MS
+shaker/M
+shakeup/MS
+shakily
+shakiness/M
+shaky/RPT
+shale/M
+shall
+shallot/MS
+shallow/TPMRYS
+shallowness/M
+shalom
+shalt
+sham/GMDS
+shaman/SM
+shamanic
+shamanism
+shamanistic
+shamble/MGDS
+shambles/M
+shambolic
+shame/MS
+shamefaced/Y
+shameful/YP
+shamefulness/M
+shameless/YP
+shamelessness/M
+shammed
+shamming
+shampoo/ZGMDRS
+shampooer/M
+shamrock/MS
+shan't
+shandy/S
+shanghai/DSG
+shank/MS
+shantung/M
+shanty/SM
+shantytown/SM
+shape's
+shape/AGDS
+shaped/U
+shapeless/PY
+shapelessness/M
+shapeliness/M
+shapely/PTR
+sharable/U
+shard/MS
+share/MZGDRSB
+shareable
+sharecrop/S
+sharecropped
+sharecropper/MS
+sharecropping
+shared/U
+shareholder/MS
+shareholding/S
+sharer/M
+shareware/MS
+sharia/M
+shariah
+shark/MDSG
+sharkskin/M
+sharp/MDNRYSPXZTG
+sharpen/ADGS
+sharpener/MS
+sharper/M
+sharpie/MS
+sharpish
+sharpness/M
+sharpshooter/SM
+sharpshooting/M
+shat
+shatter/GMDS
+shattering/Y
+shatterproof
+shave/MZGDRSJ
+shaven/U
+shaver/M
+shaving/M
+shawl/MS
+shay/MS
+she'd
+she'll
+she/DSM
+sheaf/M
+shear/MDRSZG
+shearer/M
+sheath/JM
+sheathe/UGDS
+sheathing/M
+sheaths
+sheave/SM
+shebang/MS
+shebeen/S
+shed/MS
+shedding
+sheen/M
+sheeny/TR
+sheep/M
+sheepdog/MS
+sheepfold/SM
+sheepherder/SM
+sheepish/YP
+sheepishness/M
+sheepskin/MS
+sheer/MDRSPTG
+sheerness/M
+sheet/MDSG
+sheeting/M
+sheetlike
+sheik/MS
+sheikdom/MS
+sheila/S
+shekel/SM
+shelf/M
+shell/MDRSG
+shellac/MS
+shellacked
+shellacking/SM
+shellfire/M
+shellfish/MS
+shelter/GMDS
+shelve/GDS
+shelving/M
+shenanigan/SM
+shepherd/SMDG
+shepherdess/MS
+sherbet/SM
+sheriff/SM
+sherry/SM
+shew/GDS
+shewn
+shh
+shiatsu/M
+shibboleth/M
+shibboleths
+shield/MDGS
+shielded/U
+shift/ZGMDRS
+shiftily
+shiftiness/M
+shiftless/PY
+shiftlessness/M
+shifty/RPT
+shill/GMDSJ
+shillelagh/M
+shillelaghs
+shilling/M
+shim/MS
+shimmed
+shimmer/SMDG
+shimmery
+shimming
+shimmy/DSMG
+shin/ZGMDRS
+shinbone/SM
+shindig/SM
+shine/MS
+shiner/M
+shingle/DSMG
+shinguard/M
+shininess/M
+shinned
+shinning
+shinny/DSG
+shinsplints/M
+shiny/TRP
+ship's
+ship/ALS
+shipboard/MS
+shipborne
+shipbuilder/MS
+shipbuilding/M
+shipload/SM
+shipmate/SM
+shipment/AM
+shipments
+shipowner/MS
+shippable
+shipped/A
+shipper/SM
+shipping/M
+shipshape
+shipwreck/GMDS
+shipwright/MS
+shipyard/SM
+shire/MS
+shirk/ZGDRS
+shirker/M
+shirr/GMDSJ
+shirring/M
+shirt/GMDS
+shirtfront/SM
+shirting/M
+shirtless
+shirtsleeve/MS
+shirttail/SM
+shirtwaist/SM
+shirty
+shit's
+shit/S!
+shitfaced/!
+shithead/S!
+shitload/!
+shitted/!
+shitting/!
+shitty/TR!
+shiv/ZMRS
+shiver/MDG
+shivering/Y
+shivery
+shoal/GMDS
+shoat/MS
+shock/ZGMDRS
+shocker/M
+shocking/Y
+shockproof
+shod/U
+shoddily
+shoddiness/M
+shoddy/PRMT
+shoe/MS
+shoebox
+shoehorn/GMDS
+shoeing
+shoelace/MS
+shoeless
+shoemaker/SM
+shoeshine/SM
+shoestring/MS
+shoetree/MS
+shogun/MS
+shogunate/M
+shone
+shoo/GDS
+shook
+shoot/ZGMRSJ
+shooter/M
+shooting/M
+shootout/MS
+shop/MS
+shopaholic/S
+shopfitter/S
+shopfitting
+shopfront/S
+shopkeeper/MS
+shopkeeping
+shoplift/DRZGS
+shoplifter/M
+shoplifting/M
+shoppe/MZGDRS
+shopper/M
+shopping/M
+shoptalk/M
+shopworn
+shore/MGDS
+shorebird/SM
+shoreline/MS
+shoreward
+shoring/M
+short/XTGMDNRYSP
+shortage/MS
+shortbread/M
+shortcake/MS
+shortchange/GDS
+shortcoming/MS
+shortcrust
+shortcut/MS
+shorten/JGD
+shortening/M
+shortfall/MS
+shorthand/MDS
+shorthorn/MS
+shortish
+shortlist/DSG
+shortness/M
+shortsighted/PY
+shortsightedness/M
+shortstop/MS
+shortwave/MS
+shorty/SM
+shot/MS
+shotgun/SM
+shotgunned
+shotgunning
+should
+shoulder/MDGS
+shouldn't
+shout/ZGMDRS
+shouter/M
+shove/MGDS
+shovel/MDRSG
+shovelful/SM
+show/JZGMDRS
+showbiz/M
+showboat/MDGS
+showcase/MGDS
+showdown/MS
+shower/MDG
+showerproof
+showery/TR
+showgirl/MS
+showground/S
+showily
+showiness/M
+showing/M
+showjumping
+showman/M
+showmanship/M
+showmen
+shown
+showoff/SM
+showpiece/SM
+showplace/SM
+showroom/MS
+showstopper/SM
+showstopping
+showtime
+showy/TRP
+shpt
+shrank
+shrapnel/M
+shred/MS
+shredded
+shredder/MS
+shredding
+shrew/MS
+shrewd/RYPT
+shrewdness/M
+shrewish
+shriek/MDRSZG
+shrift/M
+shrike/MS
+shrill/DRSPTG
+shrillness/M
+shrilly
+shrimp/MDRSZG
+shrine/MS
+shrink/MSBG
+shrinkage/M
+shrinking/Y
+shrive/GDS
+shrivel/SGD
+shriven
+shroud/GMDS
+shrub/MS
+shrubbery/SM
+shrubby/RT
+shrug/MS
+shrugged
+shrugging
+shrunk/N
+shtick/MS
+shuck/GMDS
+shucks/S
+shudder/MDSG
+shuffle/AMGDS
+shuffleboard/SM
+shuffler/SM
+shun/S
+shunned
+shunning
+shunt/MSDG
+shush/DSG
+shut/S
+shutdown/SM
+shuteye/M
+shutoff/SM
+shutout/SM
+shutter/SMDG
+shutterbug/MS
+shutting
+shuttle/DSMG
+shuttlecock/MDGS
+shy/TGDRSMY
+shyer
+shyest
+shyness/M
+shyster/SM
+sibilance
+sibilancy
+sibilant/SM
+sibling/SM
+sibyl/MS
+sibylline
+sic/S
+sick/PXTGDNRYS
+sickbay/S
+sickbed/SM
+sicken/DG
+sickening/Y
+sickie/MS
+sickish
+sickle/MS
+sickly/RT
+sickness/MS
+sicko/MS
+sickout/SM
+sickroom/MS
+side's
+side/AGDS
+sidearm/SM
+sideband/S
+sidebar/SM
+sideboard/SM
+sideburns/M
+sidecar/SM
+sidekick/SM
+sidelight/MS
+sideline/DSMG
+sidelong
+sideman/M
+sidemen
+sidepiece/MS
+sidereal
+sidesaddle/MS
+sideshow/MS
+sidesplitting
+sidestep/MS
+sidestepped
+sidestepping
+sidestroke/DSMG
+sideswipe/DSMG
+sidetrack/SMDG
+sidewalk/MS
+sidewall/MS
+sidewards
+sideways
+sidewinder/MS
+siding/MS
+sidle/MGDS
+siege/MS
+sienna/M
+sierra/MS
+siesta/MS
+sieve/MGDS
+sift/ZGDRS
+sifted/U
+sifter/M
+sigh/GMD
+sighs
+sight/GMDYSJ
+sighted/P
+sighting/M
+sightless/Y
+sightly/UTR
+sightread
+sightseeing/M
+sightseer/MS
+sigma/MS
+sigmoid
+sign's
+sign/AFCGDS
+signage/M
+signal/MDRYSZG
+signaler/M
+signalization/M
+signalize/GDS
+signalman/M
+signalmen
+signatory/SM
+signature/MS
+signboard/MS
+signed/U
+signer/CMS
+signet/MS
+significance/IM
+significances
+significant/IY
+signification/M
+signify/XNDRSG
+signing's/C
+signings
+signor/FMS
+signora/SM
+signore
+signori
+signorina/MS
+signorine
+signpost/GSMD
+silage/M
+silence/DRSMZG
+silencer/M
+silent/MRYST
+silhouette/DSMG
+silica/M
+silicate/MS
+siliceous
+silicon/SM
+silicone/M
+silicosis/M
+silk/MNS
+silkily
+silkiness/M
+silkscreen/SM
+silkworm/MS
+silky/TRP
+sill/MS
+silliness/M
+silly/TRSMP
+silo/MS
+silt/GMDS
+siltstone
+silty/TR
+silver/GMDS
+silverfish/MS
+silversmith/M
+silversmiths
+silverware/M
+silvery/RT
+simian/MS
+similar/Y
+similarity/ESM
+simile/MS
+similitude/EM
+simmer/GMDS
+simonize/DSG
+simony/M
+simpatico
+simper/GMDS
+simpering/Y
+simple/TRP
+simpleminded
+simpleness/M
+simpleton/SM
+simplex/S
+simplicity/SM
+simplification/M
+simplified/U
+simplify/XDRSNG
+simplistic
+simplistically
+simply
+simulacra
+simulacrum/S
+simulate/EDSGN
+simulation/EM
+simulations
+simulator/EMS
+simulcast/GMDS
+simultaneity/M
+simultaneous/Y
+sin/ASM
+since
+sincere/IYT
+sincerer
+sincerity/IM
+sine/MS
+sinecure/MS
+sinecurist
+sinew/MS
+sinewy
+sinful/PY
+sinfulness/M
+sing/BZGMDRYS
+singalong/S
+singe/MS
+singeing
+singer/M
+singing/M
+single/PMGDS
+singleness/M
+singles/M
+singlet/S
+singleton/SM
+singletree/SM
+singsong/SMDG
+singular/SMY
+singularity/SM
+singularization
+sinister/Y
+sinistral
+sink/BZGMRS
+sinkable/U
+sinker/M
+sinkhole/SM
+sinless
+sinned
+sinner/MS
+sinning
+sinology
+sinuosity/M
+sinuous/Y
+sinus/MS
+sinusitis/M
+sinusoid
+sinusoidal/Y
+sip/SM
+siphon/GMDS
+sipped
+sipper/SM
+sipping
+sir/SXMN
+sire/CMGDS
+siren/M
+sirloin/SM
+sirocco/SM
+sirrah
+sirree/M
+sis/MS
+sisal/M
+sissified
+sissy/RSMT
+sister/ASM
+sisterhood/MS
+sisterliness/M
+sisterly/P
+sit/ASG
+sitar/SM
+sitarist/MS
+sitcom/SM
+site/MJDS
+sitter/SM
+sitting/SM
+situate/DSXGN
+situation/M
+situational
+situationist
+six/MSH
+sixfold
+sixpence/MS
+sixpenny
+sixshooter/M
+sixteen/SMH
+sixteenth/M
+sixteenths
+sixth/MY
+sixths
+sixtieth/M
+sixtieths
+sixty/SMH
+size/MGBDRS
+sizing/M
+sizzle/DRSMZG
+ska/M
+skate/MZGDRS
+skateboard/ZGSMDR
+skateboarder/M
+skateboarding/M
+skater/M
+skating/M
+skedaddle/MGDS
+skeet/ZMR
+skein/MS
+skeletal
+skeleton/SM
+skeptic/SM
+skeptical/Y
+skepticism/M
+skerries
+sketch/MDRSZG
+sketchbook/S
+sketcher/M
+sketchily
+sketchiness/M
+sketchpad/S
+sketchy/RTP
+skew/MDRZGPS
+skewbald/S
+skewer/MDG
+ski/SZGMDR
+skibob/S
+skid/MS
+skidded
+skidding
+skidpan/S
+skier/M
+skiff/SM
+skiffle
+skiing/M
+skilfully
+skill's
+skill/CSD
+skilled/U
+skillet/SM
+skillful/UY
+skillfulness/M
+skim/MS
+skimmed
+skimmer/SM
+skimming
+skimp/SDG
+skimpily
+skimpiness/M
+skimpy/RTP
+skin/MS
+skincare/M
+skinflint/MS
+skinful
+skinhead/MS
+skinless
+skinned
+skinner/S
+skinniness/M
+skinning
+skinny/RMTP
+skint
+skintight
+skip/MS
+skipped
+skipper/SMDG
+skipping
+skirmish/ZGMDRS
+skirt/SMDG
+skit/MS
+skitter/GSD
+skittish/YP
+skittishness/M
+skittle/S
+skive/DRSZG
+skivvy/DSMG
+skoal/SM
+skua/S
+skulduggery/M
+skulk/SDRZG
+skulker/M
+skull/SM
+skullcap/MS
+skunk/SMDG
+sky/GSM
+skycap/SM
+skydive/DRSZG
+skydiver/M
+skydiving/M
+skyjack/JZGSDR
+skyjacker/M
+skyjacking/M
+skylark/SGMD
+skylight/MS
+skyline/SM
+skyrocket/GSMD
+skyscraper/SM
+skyward/S
+skywriter/SM
+skywriting/M
+slab/MS
+slabbed
+slabbing
+slack/PXZTGMDNRYS
+slacken/DG
+slacker/M
+slackness/M
+slacks/M
+slag/MS
+slagged
+slagging
+slagheap/S
+slain
+slake/GDS
+slalom/MSDG
+slam/MS
+slammed
+slammer/SM
+slamming
+slander/MZGDRS
+slanderer/M
+slanderous
+slang/MG
+slangy/RT
+slant/MSDG
+slanting/Y
+slantwise
+slap/MS
+slapdash
+slaphappy/RT
+slapped
+slapper/S
+slapping
+slapstick/M
+slash/MDRSZG
+slasher/M
+slat/MDGS
+slate/SM
+slather/SDG
+slatted
+slattern/SMY
+slaughter/MDRJZGS
+slaughterer/M
+slaughterhouse/SM
+slave/DRSMZG
+slaveholder/MS
+slaver/MDG
+slavery/M
+slavish/PY
+slavishness/M
+slaw/M
+slay/DRZGJS
+slayer/M
+slaying/M
+sleaze/SM
+sleazebag/S
+sleazeball/S
+sleazily
+sleaziness/M
+sleazy/PRT
+sled/MS
+sledded
+sledder/SM
+sledding
+sledge/DSMG
+sledgehammer/SMDG
+sleek/SDRYTGP
+sleekness/M
+sleep/SMRZG
+sleeper/M
+sleepily
+sleepiness/M
+sleepless/PY
+sleeplessness/M
+sleepover/SM
+sleepwalk/ZGSDR
+sleepwalker/M
+sleepwalking/M
+sleepwear/M
+sleepy/RPT
+sleepyhead/MS
+sleet/SMDG
+sleety/RT
+sleeve/DSM
+sleeveless
+sleigh/MDG
+sleighs
+sleight/SM
+slender/PRYT
+slenderize/DSG
+slenderness/M
+slept
+sleuth/MG
+sleuths
+slew/MDGS
+slice/DRSMZG
+sliced/U
+slicer/M
+slick/SMDRYZTGP
+slicker/M
+slickness/M
+slid
+slide/RSMZG
+slider/M
+slight/SMDRYTGP
+slighting/Y
+slightness/M
+slim/PS
+slime/SM
+sliminess/M
+slimline
+slimmed
+slimmer/S
+slimmest
+slimming/M
+slimness/M
+slimy/RTP
+sling/SMG
+slingback/S
+slingshot/SM
+slink/SG
+slinky/RT
+slip/MS
+slipcase/MS
+slipcover/MS
+slipknot/MS
+slippage/MS
+slipped
+slipper/SM
+slipperiness/M
+slippery/PRT
+slipping
+slippy
+slipshod
+slipstream/MS
+slipway/SM
+slit/MS
+slither/SGMD
+slithery
+slitted
+slitter
+slitting
+sliver/GSMD
+slob/MS
+slobbed
+slobber/MDSG
+slobbery
+slobbing
+sloe/MS
+slog/MS
+slogan/SM
+sloganeering
+slogged
+slogging
+sloop/SM
+slop/MDGS
+slope/SM
+slopped
+sloppily
+sloppiness/M
+slopping
+sloppy/PTR
+slops/M
+slosh/DSG
+slot/MS
+sloth/M
+slothful/PY
+slothfulness/M
+sloths
+slotted
+slotting
+slouch/ZGMDRS
+sloucher/M
+slouchy/TR
+slough/GMD
+sloughs
+sloven/SMY
+slovenliness/M
+slovenly/TPR
+slow/DRYTGSP
+slowcoach/S
+slowdown/SM
+slowish
+slowness/M
+slowpoke/SM
+sludge/M
+sludgy/RT
+slue/MGDS
+slug/MS
+sluggard/MS
+slugged
+slugger/SM
+slugging
+sluggish/YP
+sluggishness/M
+sluice/DSMG
+slum/MS
+slumber/GSMD
+slumberous
+slumlord/MS
+slummed
+slummer
+slumming
+slummy/RT
+slump/SMDG
+slung
+slunk
+slur/MS
+slurp/SMDG
+slurred
+slurring
+slurry/M
+slush/M
+slushiness/M
+slushy/RPT
+slut/MS
+sluttish
+slutty/RT
+sly/TRY
+slyness/M
+smack/SMDRZG
+smacker/M
+small/SMRTP
+smallholder/S
+smallholding/S
+smallish
+smallness/M
+smallpox/M
+smalltalk
+smarmy/RT
+smart/SMDNRYXTGP
+smarten/DG
+smartness/M
+smarts/M
+smarty/SM
+smartypants/M
+smash/MDRSZG
+smasher/M
+smashup/SM
+smattering/MS
+smear/SMDG
+smeary/RT
+smegma
+smell/SMDGB
+smelliness/M
+smelly/RPT
+smelt/SMDRZG
+smelter/M
+smidgen/MS
+smilax/M
+smile/DRSMG
+smiley/SM
+smiling/UY
+smirch/GMDS
+smirk/SMDG
+smite/SG
+smith/M
+smithereens/M
+smiths
+smithy/SM
+smitten
+smock/SMDG
+smocking/M
+smog/MS
+smoggy/RT
+smoke/DRSMZG
+smokehouse/MS
+smokeless
+smoker/M
+smokescreen/MS
+smokestack/SM
+smokey
+smokiness/M
+smoking/M
+smoky/RTP
+smolder/SGMD
+smooch/MDSG
+smoochy
+smooth/PDRYTG
+smoothie/MS
+smoothness/M
+smooths
+smorgasbord/SM
+smote
+smother/GSMD
+smudge/DSMG
+smudgy/TR
+smug/YP
+smugger
+smuggest
+smuggle/ZGDRS
+smuggler/M
+smuggling/M
+smugness/M
+smurf/S
+smut/MS
+smuttiness/M
+smutty/TRP
+snack/SMDG
+snaffle/DSMG
+snafu/SM
+snag/MS
+snagged
+snagging
+snail/SMDG
+snake/DSMG
+snakebite/MS
+snakelike
+snakeskin
+snaky/RT
+snap's
+snap/US
+snapdragon/SM
+snapped/U
+snapper/MS
+snappily
+snappiness/M
+snapping/U
+snappish/YP
+snappishness/M
+snappy/TRP
+snapshot/SM
+snare/DSMG
+snarf/SDG
+snark/S
+snarl's
+snarl/USDG
+snarling/Y
+snarly/TR
+snatch/ZGMDRS
+snatcher/M
+snazzily
+snazzy/TR
+sneak/SMDRZG
+sneaker/M
+sneakily
+sneakiness/M
+sneaking/Y
+sneaky/TRP
+sneer/SJMDG
+sneering/Y
+sneeze/DSMG
+snick/SDRZG
+snicker/MDG
+snide/RYT
+sniff/SMDRZG
+sniffer/M
+sniffle/DSMG
+sniffy/RT
+snifter/SM
+snip/MDRZGS
+snipe/SM
+sniper/M
+snipped
+snippet/SM
+snipping
+snippy/RT
+snips/M
+snit/MS
+snitch/MDSG
+snivel/SMDRZG
+sniveler/M
+snob/MS
+snobbery/M
+snobbish/PY
+snobbishness/M
+snobby/RT
+snog/S
+snogged
+snogging
+snood/SM
+snooker/MDSG
+snoop/SMDRZG
+snooper/M
+snoopy/TR
+snoot/SM
+snootily
+snootiness/M
+snooty/PTR
+snooze/DSMG
+snore/DRSMZG
+snorer/M
+snorkel/ZGMDRS
+snorkeler/M
+snorkeling/M
+snort/SMDRZG
+snorter/M
+snot/MS
+snottily
+snottiness/M
+snotty/TPR
+snout/SM
+snow/MDGS
+snowball/GSMD
+snowbank/SM
+snowbird/SM
+snowboard/MDRSZG
+snowboarder/M
+snowboarding/M
+snowbound
+snowdrift/SM
+snowdrop/SM
+snowfall/SM
+snowfield/SM
+snowflake/SM
+snowiness/M
+snowline
+snowman/M
+snowmen
+snowmobile/DSMG
+snowplough
+snowploughs
+snowplow/SGMD
+snowshed
+snowshoe/SM
+snowshoeing
+snowstorm/SM
+snowsuit/SM
+snowy/PRT
+snub/MS
+snubbed
+snubbing
+snuff/SMDRYZG
+snuffbox/MS
+snuffer/M
+snuffle/MGDS
+snuffly/RT
+snug/MYSP
+snugged
+snugger
+snuggest
+snugging
+snuggle/MGDS
+snugness/M
+so/M
+soak/MDGSJ
+soaking/M
+soap/MDGS
+soapbox/MS
+soapiness/M
+soapstone/M
+soapsuds/M
+soapy/RPT
+soar/MDGS
+soaring/Y
+sob/SM
+sobbed
+sobbing/Y
+sober/SDRYPTG
+soberness/M
+sobriety/IM
+sobriquet/SM
+soc
+soccer/M
+sociability/M
+sociable/SM
+sociably
+social/SMY
+socialism/M
+socialist/SM
+socialistic
+socialite/SM
+socialization/M
+socialize/DSG
+societal
+society/SM
+sociobiology
+sociocultural
+socioeconomic
+socioeconomically
+sociolinguistic/S
+sociolinguists
+sociological/Y
+sociologist/MS
+sociology/M
+sociopath/M
+sociopaths
+sociopolitical
+sock/MDGS
+socket/SM
+sockeye/SM
+sod/SM
+soda/MS
+sodded
+sodden/Y
+sodding
+sodium/M
+sodomite/MS
+sodomize/GDS
+sodomy/M
+soever
+sofa/MS
+soft/NRYXTP
+softback
+softball/MS
+softbound
+softcover
+soften/DRZG
+softener/M
+softhearted
+softness/M
+software/M
+softwood/SM
+softy/SM
+soggily
+sogginess/M
+soggy/RTP
+soigne
+soil/MDGS
+soiled/U
+soiree/SM
+sojourn/ZGMDRS
+sojourner/M
+sol/SM
+solace/DSMG
+solar
+solaria
+solarium/M
+sold/UR
+solder/ZGSMDR
+solderer/M
+soldier/MDYSG
+soldiery/M
+sole/FSDGM
+solecism/SM
+solely
+solemn/PTRY
+solemness/M
+solemnify/GDS
+solemnity/SM
+solemnization/M
+solemnize/DSG
+solemnness/M
+solenoid/MS
+solenoidal
+solicit/GDS
+solicitation/SM
+solicited/U
+solicitor/SM
+solicitous/YP
+solicitousness/M
+solicitude/M
+solid/PSMRYT
+solidarity/M
+solidi
+solidification/M
+solidify/DSNG
+solidity/M
+solidness/M
+solidus/M
+soliloquies
+soliloquize/GDS
+soliloquy/M
+solipsism/MS
+solipsist/S
+solipsistic
+solitaire/MS
+solitariness/M
+solitary/SMP
+solitude/SM
+solo/MDGS
+soloist/MS
+solstice/MS
+solubility/IM
+soluble/MS
+solute's
+solute/XN
+solutes
+solution's/EA
+solvable/IU
+solve/ARZBGSD
+solved/U
+solvency/IM
+solvent/IMS
+solver's
+somatic
+somber/PY
+somberness/M
+sombrero/MS
+some
+somebody/SM
+someday
+somehow
+someone/MS
+someplace
+somersault/MDSG
+somerset/SM
+somersetted
+somersetting
+something/SM
+sometime/S
+someway/S
+somewhat/S
+somewhere
+somnambulism/M
+somnambulist/SM
+somnolence/M
+somnolent
+son/SM
+sonar/SM
+sonata/SM
+sonatina/SM
+song/MS
+songbird/SM
+songbook/SM
+songfest/SM
+songster/MS
+songstress/MS
+songwriter/MS
+songwriting
+sonic
+sonically
+sonnet/SM
+sonny/SM
+sonogram/SM
+sonority/SM
+sonorous/PY
+sonorousness/M
+sonsofbitches
+soon/RT
+soonish
+soot/M
+sooth/MDRSZG
+soothe
+soother/M
+soothing/Y
+soothsayer/SM
+soothsaying/M
+sooty/RT
+sop/SM
+sophism/M
+sophist/MS
+sophistic
+sophistical
+sophisticate/DSMGN
+sophisticated/U
+sophistication/M
+sophistry/SM
+sophomore/MS
+sophomoric
+soporific/MS
+soporifically
+sopped
+sopping
+soppy/RT
+soprano/MS
+sorbet/SM
+sorcerer/MS
+sorceress/MS
+sorcery/M
+sordid/PY
+sordidness/M
+sore/MYTRSP
+sorehead/MS
+soreness/M
+sorghum/M
+sorority/SM
+sorrel/SM
+sorrily
+sorriness/M
+sorrow/SMDG
+sorrowful/PY
+sorrowfulness/M
+sorry/RTP
+sort/FASGDM
+sorta
+sortable
+sorted/U
+sorter/SM
+sortie/DSM
+sortieing
+sot/SM
+sottish
+sou'wester
+sou/SMH
+souffle/SM
+sough/MDG
+soughs
+sought/U
+souk/S
+soul/MDS
+soulful/YP
+soulfulness/M
+soulless/YP
+sound/JPSMDRYZTG
+soundbite/S
+soundboard/SM
+sounder/M
+sounding/M
+soundless/Y
+soundness/UM
+soundproof/DGS
+soundproofing/M
+soundtrack/SM
+soup/MDGS
+soupcon/MS
+soupy/RT
+sour/MDRYTGSP
+source/ADSMG
+sourceless
+sourdough/M
+sourdoughs
+sourish
+sourness/M
+sourpuss/MS
+sousaphone/MS
+souse/DSMG
+south/M
+southbound
+southeast/ZMR
+southeaster/MY
+southeastern
+southeastward/S
+southerly/SM
+southern/SZMR
+southerner/M
+southernmost
+southpaw/SM
+southward/MS
+southwest/MRZ
+southwester/MY
+southwestern
+southwestward/S
+souvenir/SM
+sovereign/SM
+sovereignty/M
+soviet/SM
+sow's
+sow/ASGD
+sower/SM
+sown/A
+soy/M
+soybean/MS
+sozzled
+spa/SM
+space/DRSMZGJ
+spacecraft/MS
+spaceflight/SM
+spaceman/M
+spacemen
+spaceport/SM
+spacer/M
+spaceship/SM
+spacesuit/SM
+spacewalk/SGMD
+spacewoman/M
+spacewomen
+spacey
+spacial
+spacier
+spaciest
+spaciness/M
+spacing/M
+spacious/PY
+spaciousness/M
+spade/DSMG
+spadeful/MS
+spadework/M
+spadices
+spadix/M
+spaghetti/M
+spake
+spam/S
+spamblock/S
+spammed
+spammer/MS
+spamming
+span/MS
+spandex/M
+spandrels
+spangle/DSMG
+spangly
+spaniel/SM
+spank/SMDRGJ
+spanking/M
+spanned/U
+spanner/SM
+spanning
+spar/MS
+spare/DRSMYTGP
+spareness/M
+spareribs/M
+sparing/UY
+spark/SMDYG
+sparkle/DRSMZG
+sparkler/M
+sparkling/Y
+sparky/RT
+sparred
+sparring
+sparrow/SM
+sparrowhawk/S
+sparse/RYTP
+sparseness/M
+sparsity/M
+spartan
+spasm/SM
+spasmodic
+spasmodically
+spastic/SM
+spat/MS
+spate/SM
+spathe/SM
+spatial/Y
+spatted
+spatter/SGMD
+spatting
+spatula/SM
+spavin/MD
+spawn/SMDG
+spay/DGS
+speak/SRZGBJ
+speakable/U
+speakeasy/SM
+speaker/M
+speakerphone/S
+spear/SMDG
+spearfish/GMDS
+spearhead/GMDS
+spearmint/M
+spec/MS
+special/SPMRY
+specialism/S
+specialist/MS
+specialization/MS
+specialize/GDS
+specialty/SM
+specie/SM
+species/M
+specif
+specifiable
+specifiably
+specific/PMS
+specifically
+specification/M
+specificity/M
+specified/UA
+specify/XNZDRSG
+specimen/SM
+specious/YP
+speciousness/M
+speck/SMDG
+speckle/MGDS
+specs/M
+spectacle/SM
+spectacles/M
+spectacular/SMY
+spectate/DSG
+spectator/SM
+specter/AMS
+spectra
+spectral
+spectrogram
+spectrograph
+spectrometer/SM
+spectrometric
+spectrometry
+spectrophotometer
+spectrophotometry
+spectroscope/SM
+spectroscopic
+spectroscopically
+spectroscopy/M
+spectrum/M
+specular
+speculate/XDSGNV
+speculation/M
+speculative/Y
+speculator/MS
+speculum
+sped
+speech/MS
+speechify/DSG
+speechless/PY
+speechlessness/M
+speechwriter/S
+speed/SMRZG
+speedboat/SM
+speeder/M
+speedily
+speediness/M
+speeding/M
+speedometer/MS
+speedster/SM
+speedup/MS
+speedway/SM
+speedwell/M
+speedy/TPR
+speleological
+speleologist/MS
+speleology/M
+spell/BJSMDRZG
+spellbind/RZGS
+spellbinder/M
+spellbound
+spellchecker/S
+spelldown/SM
+speller/M
+spelling/M
+spelunker/MS
+spelunking/M
+spend/BSRZG
+spender/M
+spending/M
+spendthrift/MS
+spent/U
+sperm/SM
+spermatozoa
+spermatozoon/M
+spermicidal
+spermicide/SM
+spew/MDRZGS
+spewer/M
+sphagnum/MS
+sphere/SM
+spherical/Y
+spheroid/SM
+spheroidal
+sphincter/MS
+sphinx/MS
+spic/S
+spice/DSMG
+spicily
+spiciness/M
+spicule/MS
+spicy/PRT
+spider/SM
+spiderweb/MS
+spidery/RT
+spiel/SMDG
+spiff/SDG
+spiffy/TR
+spigot/SM
+spike/DSMG
+spikiness/M
+spiky/RPT
+spill/SMDRG
+spillage/MS
+spillover/SM
+spillway/MS
+spin/MS
+spinach/M
+spinal/SMY
+spindle/MGDS
+spindly/TR
+spindrift
+spine/SM
+spineless/YP
+spinet/SM
+spinnaker/SM
+spinner/MS
+spinneret/SM
+spinney/S
+spinning/M
+spinster/SM
+spinsterhood/M
+spinsterish
+spiny/RT
+spiracle/SM
+spiral/SGMDY
+spire's
+spire/IFAS
+spirea/SM
+spirit's
+spirit/ISGD
+spirited/Y
+spiritless
+spiritual/MYS
+spiritualism/M
+spiritualist/MS
+spiritualistic
+spirituality/M
+spirituous
+spirochete/SM
+spiry/RT
+spit/MDGS
+spitball/SM
+spite/ASM
+spiteful/PY
+spitefuller
+spitefullest
+spitefulness/M
+spitfire/SM
+spitted
+spitting
+spittle/M
+spittoon/MS
+spiv/S
+splash/GMDS
+splashdown/MS
+splashily
+splashiness/M
+splashy/RTP
+splat/SM
+splatted
+splatter/GSMD
+splatting
+splay/SMDG
+splayfeet
+splayfoot/MD
+spleen/SM
+splendid/RYT
+splendor/MS
+splendorous
+splenetic
+splice/DRSMZG
+splicer/M
+spliff/S
+spline/S
+splint/SZGMDR
+splinter/MDG
+splintery
+split/SM
+splittable
+splitter/S
+splitting/MS
+splodge/S
+splosh/DSG
+splotch/MDSG
+splotchy/TR
+splurge/DSMG
+splutter/GMDS
+spoil's
+spoil/CSDRZG
+spoilage/M
+spoiled/U
+spoiler/CM
+spoilsport/MS
+spoke/SM
+spoken/U
+spokeshave/S
+spokesman/M
+spokesmen
+spokespeople
+spokesperson/SM
+spokeswoman/M
+spokeswomen
+spoliation/CM
+sponge/DRSMZG
+spongecake/M
+sponger/M
+sponginess/M
+spongy/RPT
+sponsor/MDGS
+sponsorship/MS
+spontaneity/M
+spontaneous/Y
+spoof/SMDG
+spook/SMDG
+spookiness/M
+spooky/RPT
+spool/SMDG
+spoon/SMDG
+spoonbill/MS
+spoonerism/MS
+spoonful/SM
+spoor/SMDG
+sporadic
+sporadically
+spore/DSMG
+sporran/S
+sport/SMDGV
+sportiness/M
+sporting/Y
+sportive/Y
+sportscast/MRZGS
+sportscaster/M
+sportsman/M
+sportsmanlike/U
+sportsmanship/M
+sportsmen
+sportspeople
+sportsperson
+sportswear/M
+sportswoman/M
+sportswomen
+sportswriter/SM
+sporty/TPR
+spot/CMS
+spotless/PY
+spotlessness/M
+spotlight/SGMD
+spotlit
+spotted
+spotter/MS
+spottily
+spottiness/M
+spotting
+spotty/TPR
+spousal/MS
+spouse/SM
+spout/SMDG
+sprain/GSMD
+sprang
+sprat/SM
+sprawl/GSMD
+spray's
+spray/ASDG
+sprayer/MS
+spread/ZGBSMR
+spreadeagled
+spreader/M
+spreadsheet/SM
+spree/DSM
+spreeing
+sprig/SM
+sprigged
+sprightliness/M
+sprightly/RPT
+spring/GSMR
+springboard/MS
+springbok/MS
+springily
+springiness/M
+springlike
+springtime/M
+springy/RPT
+sprinkle/DRSJMZG
+sprinkler/M
+sprinkling/M
+sprint/ZGSMDR
+sprinter/M
+sprite/SM
+spritz/ZGMDRS
+spritzer/M
+sprocket/MS
+sprog/S
+sprout/GSMD
+spruce/DRSPMYTG
+spruceness/M
+sprung
+spry/RYT
+spryness/M
+spud/MS
+spume/DSMG
+spumoni/M
+spumy/RT
+spun
+spunk/SM
+spunky/TR
+spur/MS
+spurge/M
+spurious/YP
+spuriousness/M
+spurn/SDG
+spurred
+spurring
+spurt/SMDG
+sputa
+sputnik/MS
+sputter/MDGS
+sputum/M
+spy/GDSM
+spyglass/MS
+spyhole
+spymaster/S
+sq
+sqq
+squab/SM
+squabble/MZGDRS
+squabbler/M
+squad/SM
+squadron/MS
+squalid/PTRY
+squalidness/M
+squall/SGMD
+squally/TR
+squalor/M
+squamous
+squander/GDS
+square/PDRSMYTG
+squareness/M
+squarish
+squash/GMDS
+squashy/TR
+squat/SMP
+squatness/M
+squatted
+squatter/MS
+squattest
+squatting
+squaw/SM
+squawk/SZGMDR
+squawker/M
+squeak/SZGMDR
+squeaker/M
+squeakily
+squeakiness/M
+squeaky/TRP
+squeal/SZGMDR
+squealer/M
+squeamish/PY
+squeamishness/M
+squeegee/MDS
+squeegeeing
+squeeze/BMZGDRS
+squeezebox/S
+squeezer/M
+squelch/GMDS
+squelchy/RT
+squib/SM
+squid/SM
+squidgy
+squiffy
+squiggle/DSMG
+squiggly/RT
+squint/STGMDR
+squire/DSMG
+squirm/SGMD
+squirmy/RT
+squirrel/SGMD
+squirt/SGMD
+squish/GMDS
+squishy/RT
+ssh
+st
+stab/MYS
+stabbed
+stabber/MS
+stabbing/MS
+stability/IM
+stabilizability
+stabilization/CM
+stabilize/CDSG
+stabilizer/MS
+stable/DRSMTG
+stableman/M
+stablemate/S
+stablemen
+stably/U
+staccato/MS
+stack/SMDRG
+stadium/MS
+staff's
+staff/ASDG
+staffer/MS
+staffing/M
+staffroom
+stag/MDGSJ
+stage/SM
+stagecoach/MS
+stagecraft/M
+stagehand/MS
+stagestruck
+stagflation/M
+stagger/MDGS
+staggering/Y
+staging/M
+stagnancy/M
+stagnant/Y
+stagnate/DSGN
+stagnation/M
+stagy/RT
+staid/PRYT
+staidness/M
+stain/SMDRG
+stained/U
+stainless/M
+stair/SM
+staircase/MS
+stairway/MS
+stairwell/SM
+stake/DSMG
+stakeholder/SM
+stakeout/SM
+stalactite/MS
+stalagmite/SM
+stale/DRSTGP
+stalemate/DSMG
+staleness/M
+stalk/SMDRJZG
+stalker/M
+stalking/M
+stall's
+stall/ISDG
+stallholder/S
+stallion/MS
+stalwart/MYS
+stamen/SM
+stamina/M
+stammer/ZGMDRS
+stammerer/M
+stammering/Y
+stamp/SMDRJZG
+stampede/MGDS
+stamper/M
+stance/ISM
+stanch/TGDRS
+stanchion/SM
+stand/SMRJZG
+standalone
+standard/MS
+standardization/SM
+standardize/GDS
+standby/M
+standbys
+standee/MS
+stander/M
+standing/M
+standoff/MS
+standoffish
+standout/MS
+standpipe/SM
+standpoint/MS
+standstill/SM
+stank
+stanza/SM
+stapes
+staph/M
+staphylococcal
+staphylococci
+staphylococcus/M
+staple/DRSMZG
+stapler/M
+star/MDRZGS
+starboard/M
+starch/GMDS
+starchily
+starchiness/M
+starchy/PTR
+stardom/M
+stardust/M
+stare/SM
+starer/M
+starfish/MS
+starfruit
+stargaze/DRSZG
+stargazer/M
+stark/RYPZT
+starkness/M
+starless
+starlet/MS
+starlight/M
+starling/SM
+starlit
+starred
+starring
+starry/TR
+starstruck
+start/ASMDG
+starter/MS
+startle/GDS
+startling/Y
+starvation/M
+starve/DSJG
+starveling/SM
+stash/MDSG
+stasis
+stat/MS
+state/DRSMYGNLX
+statecraft/M
+stated/U
+statehood/M
+statehouse/SM
+stateless/P
+statelessness/M
+stateliness/M
+stately/PRT
+statement/AMS
+statemented
+statementing
+stateroom/MS
+stateside
+statesman/M
+statesmanlike
+statesmanship/M
+statesmen
+stateswoman/M
+stateswomen
+statewide
+static/SM
+statical/Y
+station/MDRZG
+stationary
+stationer/M
+stationery/M
+stationmaster/S
+statistic/MS
+statistical/Y
+statistician/MS
+stator/S
+statuary/M
+statue/SM
+statuesque
+statuette/MS
+stature/MS
+status/MS
+statute/MS
+statutorily
+statutory
+staunch/PDRSYTG
+staunchness/M
+stave/DMG
+stay/MDRZGS
+std
+stdio
+stead/SM
+steadfast/YP
+steadfastness/M
+steadily/U
+steadiness/UM
+steady/TGPDRSM
+steak/SM
+steakhouse/SM
+steal/SMRHG
+stealth/M
+stealthily
+stealthiness/M
+stealthy/TRP
+steam/SMDRZG
+steamboat/MS
+steamer/M
+steamfitter/MS
+steamfitting/M
+steaminess/M
+steamroll/ZGDRS
+steamroller/MDG
+steamship/MS
+steamy/TPR
+steed/SM
+steel/SMDG
+steeliness/M
+steelmaker/S
+steelwork/RSZ
+steelworker/M
+steelworks/M
+steely/PTR
+steelyard/SM
+steep/SMDNRYPXTG
+steepen/GD
+steeple/MS
+steeplechase/MRS
+steeplejack/MS
+steepness/M
+steer/SMDBG
+steerage/M
+steering/M
+steersman/M
+steersmen
+stegosauri
+stegosaurus/MS
+stein/SM
+stellar
+stellated
+stem/MS
+stemless
+stemmed
+stemming
+stemware/M
+stench/MS
+stencil/GMDS
+steno/SM
+stenographer/MS
+stenographic
+stenography/M
+stentorian
+step/IMS
+stepbrother/MS
+stepchild/M
+stepchildren
+stepdaughter/MS
+stepfather/MS
+stepladder/MS
+stepmother/SM
+stepparent/SM
+steppe/DRSMZG
+stepper/M
+steppingstone/MS
+stepsister/SM
+stepson/MS
+stepwise
+steradians
+stereo/SM
+stereographic
+stereophonic
+stereoscope/MS
+stereoscopic
+stereoscopically
+stereoscopy
+stereotype/DSMG
+stereotypical/Y
+sterile
+sterility/M
+sterilization/MS
+sterilize/DRSZG
+sterilized/U
+sterilizer/M
+sterling/M
+stern/SMRYPT
+sternness/M
+sternum/MS
+steroid/MS
+steroidal
+stertorous
+stet/S
+stethoscope/SM
+stetson/MS
+stetted
+stetting
+stevedore/SM
+stew/MDGS
+steward/GMDS
+stewardess/MS
+stewardship/M
+stick/SMRZG
+sticker/M
+stickily
+stickiness/M
+sticking/U
+stickleback/MS
+stickler/MS
+stickpin/MS
+stickup/MS
+sticky/PTRSM
+stiff/SMDNRYPXTG
+stiffen/ZGDR
+stiffener/M
+stiffening/M
+stiffness/M
+stifle/DSJG
+stifling/Y
+stigma/SM
+stigmata
+stigmatic
+stigmatization/M
+stigmatize/DSG
+stile/SM
+stiletto/SM
+still's
+still/ITGSD
+stillbirth/M
+stillbirths
+stillborn
+stiller
+stillness/M
+stilt/SMD
+stilted/Y
+stimulant/SM
+stimulate/DSGNV
+stimulated/U
+stimulation/M
+stimulator
+stimulatory
+stimuli
+stimulus/M
+sting/ZGSMR
+stinger/M
+stingily
+stinginess/M
+stingray/SM
+stingy/RTP
+stink/ZGSMR
+stinkbug/SM
+stinker/M
+stinky/RT
+stint/GSMD
+stipend/SM
+stipendiary/S
+stipple/DSMG
+stippling/M
+stipulate/XDSGN
+stipulation/M
+stir/MS
+stirred/U
+stirrer/SM
+stirring/SY
+stirrup/SM
+stitch's
+stitch/ADSG
+stitchery/M
+stitching/M
+stoat/SM
+stochastic
+stock's
+stock/AGSD
+stockade/DSMG
+stockbreeder/MS
+stockbroker/SM
+stockbroking/M
+stockholder/SM
+stockily
+stockiness/M
+stockinette/M
+stocking/SMD
+stockist/S
+stockpile/MGDS
+stockpot/SM
+stockroom/MS
+stocktaking/M
+stocky/RTP
+stockyard/MS
+stodge
+stodgily
+stodginess/M
+stodgy/RTP
+stogy/SM
+stoic/SM
+stoical/Y
+stoicism/M
+stoke/DRSZG
+stoker/M
+stole/SM
+stolen
+stolid/RYTP
+stolidity/M
+stolidness/M
+stolon/MS
+stoma
+stomach/MDRZG
+stomachache/SM
+stomacher/M
+stomachs
+stomata
+stomp/GSMD
+stone/DSMG
+stoneless
+stonemason/MS
+stonewall/GSD
+stoneware/M
+stonewashed
+stonework/M
+stonily
+stoniness/M
+stonkered
+stonking
+stony/TRP
+stood
+stooge/MS
+stool/SM
+stoop/GSMD
+stop's
+stop/US
+stopcock/SM
+stopgap/SM
+stoplight/MS
+stopoff
+stopover/MS
+stoppable/U
+stoppage/MS
+stopped/U
+stopper/GSMD
+stopping/U
+stopple/DSMG
+stopwatch/MS
+storage/M
+store's
+store/ADSG
+storefront/SM
+storehouse/SM
+storekeeper/MS
+storeroom/SM
+stork/SM
+storm/ZGSMDR
+stormily
+storminess/M
+stormtroopers
+stormy/RPT
+story/DSM
+storyboard/SM
+storybook/SM
+storyline
+storyteller/SM
+storytelling/M
+stoup/SM
+stout/TSMRYP
+stouthearted
+stoutness/M
+stove/SM
+stovepipe/SM
+stow/DGS
+stowage/M
+stowaway/MS
+straddle/DRSMZG
+straddler/M
+strafe/MGDS
+straggle/DRSZG
+straggler/M
+straggly/TR
+straight/SXTPMNRY
+straightaway/SM
+straightedge/SM
+straighten/ZGDR
+straightener/M
+straightforward/SYP
+straightforwardness/M
+straightness/M
+straightway
+strain's
+strain/FADSG
+strainer/ASM
+strait/MNSX
+straiten/GD
+straitjacket/SMDG
+straitlaced
+strand/MDSG
+strange/PRYZT
+strangeness/M
+stranger/M
+strangle/ZGDRS
+stranglehold/SM
+strangler/M
+strangulate/DSGN
+strangulation/M
+strap's
+strap/US
+strapless/MS
+strapped/U
+strapping/M
+strata
+stratagem/SM
+strategic/S
+strategical/Y
+strategics/M
+strategist/MS
+strategy/SM
+strati
+stratification/M
+stratify/DSGN
+stratigraphic
+stratigraphical
+stratosphere/MS
+stratospheric
+stratospherically
+stratum/M
+stratus/M
+straw/GSMD
+strawberry/SM
+stray/GSMD
+streak/MDRSZG
+streaker/M
+streaky/TR
+stream/MDRSZG
+streamer/M
+streamline/GDS
+street/MS
+streetcar/MS
+streetlamp/S
+streetlight/MS
+streetwalker/MS
+streetwise
+strength/M
+strengthen/AGSD
+strengthener/MS
+strengths
+strenuous/PY
+strenuousness/M
+strep/M
+streptococcal
+streptococci
+streptococcus/M
+streptomycin/M
+stress/MDSG
+stressed/U
+stressful/P
+stretch/BZGMDRS
+stretchability
+stretchable/U
+stretcher/MDG
+stretchmarks
+stretchy/TRP
+strew/GSDH
+strewn
+stria/M
+striae
+striated
+striation/MS
+stricken
+strict/RYPT
+strictness/M
+stricture/SM
+stridden
+stride/MGRS
+stridency/M
+strident/Y
+strife/M
+strike/MZGRSJ
+strikebound
+strikebreaker/MS
+strikebreaking
+strikeout/MS
+striker/M
+striking/Y
+string/MDRSZG
+stringency/M
+stringent/Y
+stringer/M
+stringiness/M
+stringy/PTR
+strip/GSMD
+stripe/MS
+stripey
+stripling/MS
+stripped
+stripper/MS
+stripping
+striptease/MZGDRS
+stripteaser/M
+stripy/RT
+strive/GS
+striven
+strobe/MS
+stroboscope/MS
+stroboscopic
+strode
+stroke/MGDS
+stroll/MDRSZG
+stroller/M
+stromatolites
+strong/RYT
+strongbow
+strongbox/MS
+stronghold/MS
+strongish
+strongman/M
+strongmen
+strongroom/S
+strontium/M
+strop/SM
+strophe/SM
+strophic
+stropped
+stroppily
+stropping
+stroppy/TRP
+strove
+struck
+structural/Y
+structuralism
+structuralist/S
+structure's
+structure/AGDS
+structured/U
+structureless
+strudel/SM
+struggle/MGDS
+strum/SM
+strummed
+strumming
+strumpet/MS
+strung/UA
+strut/SM
+strutted
+strutter
+strutting
+strychnine/M
+stub/MS
+stubbed
+stubbing
+stubble/M
+stubbly/TR
+stubborn/RYPT
+stubbornness/M
+stubby/RT
+stucco/MDG
+stuccoes
+stuck/U
+stud/MYS
+studbook/MS
+studded
+studding/M
+student/SM
+studentship/S
+studied/U
+studiedly
+studier/S
+studio/MS
+studious/YP
+studiousness/M
+studly/RT
+study's
+study/AGDS
+stuff/GSMDR
+stuffily
+stuffiness/M
+stuffing/M
+stuffy/RPT
+stultification/M
+stultify/DSNG
+stumble/DRSMZG
+stumbler/M
+stumbling/Y
+stump/GSMD
+stumpy/TR
+stun/S
+stung
+stunk
+stunned
+stunner/S
+stunning/Y
+stunt/GSMD
+stuntman
+stuntmen
+stupefaction/M
+stupefy/DSG
+stupefying/Y
+stupendous/Y
+stupid/TMRYS
+stupidity/SM
+stupor/MS
+sturdily
+sturdiness/M
+sturdy/TRP
+sturgeon/SM
+stutter/MDRSZG
+stutterer/M
+sty/SM
+style's
+style/ADSG
+styli
+stylish/PY
+stylishness/M
+stylist/SM
+stylistic/S
+stylistically
+stylization
+stylize/DSG
+stylus/MS
+stymie/MDS
+stymieing
+styptic/SM
+styrene
+suasion/EM
+suave/RYTP
+suaveness/M
+suavity/M
+sub/SM
+subaltern/MS
+subaqua
+subarctic
+subarea/MS
+subatomic
+subbasement/MS
+subbed
+subbing
+subbranch/MS
+subcategory/SM
+subclass/S
+subclauses
+subcommittee/SM
+subcompact/SM
+subconscious/PMY
+subconsciousness/M
+subcontinent/SM
+subcontinental
+subcontract/MDSG
+subcontractor/SM
+subcultural
+subculture/SM
+subcutaneous/Y
+subdivide/GDS
+subdivision/MS
+subducted
+subduction
+subdue/DSG
+subdued/U
+subeditor/S
+subfamily/SM
+subfreezing
+subgroup/MS
+subharmonic/S
+subhead/GJMS
+subheading/M
+subhuman/MS
+subj
+subject/GVMDS
+subjection/M
+subjective/Y
+subjectivity/M
+subjoin/GDS
+subjugate/GNDS
+subjugation/M
+subjunctive/MS
+sublayer
+sublease/MGDS
+sublet/SM
+subletting
+sublieutenant/S
+sublimate/GNDS
+sublimation/M
+sublime/YTGDRS
+subliminal/Y
+sublimity/M
+sublunary
+submarginal
+submarine/MZRS
+submariner/M
+submerge/GDS
+submergence/M
+submerse/GNDS
+submersible/MS
+submersion/M
+submicroscopic
+submission's
+submission/AS
+submissive/PY
+submissiveness/M
+submit/AS
+submittable
+submitted/A
+submitter/S
+submitting/A
+subnormal
+suboptimal
+suborbital
+suborder/MS
+subordinate/MGNDS
+subordination/IM
+suborn/SGD
+subornation/M
+subplot/MS
+subpoena/GMDS
+subprofessional/SM
+subprogram/S
+subroutine/MS
+subscribe/AGDS
+subscribed/U
+subscriber/SM
+subscript/MS
+subscription/SM
+subsection/MS
+subsequent/Y
+subservience/M
+subservient/Y
+subset/SM
+subside/GDS
+subsidence/M
+subsidiarity
+subsidiary/SM
+subsidization/M
+subsidize/ZGDRS
+subsidized/U
+subsidizer/M
+subsidy/SM
+subsist/SDG
+subsistence/M
+subsoil/M
+subsonic
+subspace/S
+subspecies/M
+substance/SM
+substandard
+substantial/IY
+substantiate/XGNDS
+substantiated/U
+substantiation/FM
+substantive/SMY
+substation/MS
+substitute/MGNBXDS
+substituted/U
+substitution/M
+substrata
+substrate/MS
+substratum/M
+substructure/SM
+subsume/DSG
+subsurface/M
+subsystem/SM
+subteen/SM
+subtenancy/M
+subtenant/SM
+subtend/SDG
+subterfuge/SM
+subterranean
+subtext/SM
+subtitle/DSMG
+subtle/TR
+subtlety/SM
+subtly/U
+subtopic/SM
+subtotal/SGMD
+subtract/GVSD
+subtraction/SM
+subtractive/Y
+subtrahend/SM
+subtropic/S
+subtropical
+subtropics/M
+subtype/S
+subunit/S
+suburb/MS
+suburban/SM
+suburbanite/SM
+suburbanization
+suburbia/M
+subvention/SM
+subversion/M
+subversive/SPMY
+subversiveness/M
+subvert/SDG
+subway/MS
+subzero
+succeed/GDS
+success/VMS
+successful/UY
+succession/MS
+successive/Y
+successor/SM
+succinct/RYTP
+succinctness/M
+succor/SGMD
+succotash/M
+succubi
+succubus
+succulence/M
+succulency/M
+succulent/SM
+succumb/GDS
+such
+suchlike
+suck/MDRZGSB
+sucker/GMD
+suckle/DSJG
+suckling/M
+sucrose/M
+suction/SMDG
+sud/S
+sudden/PY
+suddenness/M
+suds/M
+sudsy/TR
+sue/DSG
+suede/M
+suet/M
+suety
+suffer/DRZGSJ
+sufferance/M
+sufferer/M
+suffering/M
+suffice/DSG
+sufficiency/IM
+sufficient/IY
+suffix/MDSG
+suffixation/M
+suffocate/GNDS
+suffocating/Y
+suffocation/M
+suffragan/MS
+suffrage/M
+suffragette/MS
+suffragist/MS
+suffuse/DSGN
+suffusion/M
+sugar/GSMD
+sugarcane/M
+sugarcoat/DGS
+sugarless
+sugarplum/MS
+sugary/RT
+suggest/ZGVSDR
+suggestibility/M
+suggestible
+suggestion/SM
+suggestive/PY
+suggestiveness/M
+sugillate
+suicidal/Y
+suicide/SM
+suit/BMDGS
+suitabilities
+suitability/UM
+suitable/UP
+suitableness/M
+suitably/U
+suitcase/SM
+suite/SM
+suited/U
+suiting/M
+suitor/MS
+sukiyaki/M
+sulfa/M
+sulfate/SM
+sulfide/SM
+sulfur/MDSG
+sulfuric
+sulfurous
+sulk/MDGS
+sulkily
+sulkiness/M
+sulky/TRSMP
+sullen/RYPT
+sullenness/M
+sullied/U
+sully/GDS
+sultan/MS
+sultana/SM
+sultanate/MS
+sultrily
+sultriness/M
+sultry/RPT
+sum/SM
+sumac/M
+summability
+summable
+summarily
+summarize/ZGDRS
+summary/SM
+summat
+summation/FMS
+summed
+summer/MDSG
+summerhouse/MS
+summertime/M
+summery/RT
+summing
+summit/MS
+summitry/M
+summon/JDRSZG
+summoner/M
+summons/GMDS
+sumo/M
+sump/MS
+sumptuous/PY
+sumptuousness/M
+sun/SM
+sunbath/ZGMDRS
+sunbathe
+sunbather/M
+sunbathing/M
+sunbaths
+sunbeam/SM
+sunbed/S
+sunbelt
+sunblock/MS
+sunbonnet/SM
+sunburn/SGMD
+sunburst/MS
+suncream
+sundae/MS
+sundeck/S
+sunder/DSG
+sundial/SM
+sundown/SM
+sundress/S
+sundries/M
+sundry/S
+sunfish/MS
+sunflower/MS
+sung/U
+sunglasses/M
+sunhat/S
+sunk/N
+sunlamp/SM
+sunless
+sunlight/M
+sunlit
+sunned
+sunniness/M
+sunning
+sunny/TRP
+sunrise/SM
+sunroof/SM
+sunscreen/MS
+sunset/MS
+sunshade/MS
+sunshine/M
+sunshiny
+sunspot/SM
+sunspots/S
+sunstroke/M
+suntan/MS
+suntanned
+suntanning
+suntrap/S
+sunup/M
+sup/SZMR
+super/M
+superabundance/SM
+superabundant
+superannuate/GNDS
+superannuation/M
+superb/RYT
+supercargo/M
+supercargoes
+supercharge/ZGDRS
+supercharger/M
+supercilious/PY
+superciliousness/M
+supercity/SM
+supercomputer/MS
+supercomputing
+superconducting
+superconductive
+superconductivity/M
+superconductor/SM
+supercooled
+supercooling
+superdense
+superego/MS
+supererogation/M
+supererogatory
+superficial/Y
+superficiality/M
+superfine
+superfix
+superfluity/SM
+superfluous/PY
+superfluousness/M
+superglue
+supergrass/S
+superheat/D
+superhero/MS
+superheroes
+superhighway/MS
+superhuman
+superimpose/DSG
+superimposition/M
+superintend/SGD
+superintendence/M
+superintendency/M
+superintendent/SM
+superior/MS
+superiority/M
+superlative/MYS
+superman/M
+supermarket/MS
+supermen
+supermodel/S
+supermom/MS
+supernal
+supernatant
+supernatural/YS
+supernova/MS
+supernovae
+supernumerary/SM
+superordinate
+superpose/GDS
+superposition/SM
+superpower/MS
+supersaturate/GNDS
+supersaturation/M
+superscribe/GDS
+superscript/MS
+superscription/M
+supersede/GDS
+supersonic
+supersonically
+superstar/MS
+superstate/S
+superstition/SM
+superstitious/Y
+superstore/SM
+superstructure/SM
+supertanker/SM
+superuser/S
+supervene/GDS
+supervention/M
+supervise/GNXDS
+supervised/U
+supervision/M
+supervisor/SM
+supervisory
+superwoman/M
+superwomen
+supine/Y
+supp/DRZG
+supper/M
+suppertime
+suppl
+supplant/SDG
+supple/TLPR
+supplement/GMDS
+supplemental
+supplementary
+supplementation/M
+suppleness/M
+suppliant/SM
+supplicant/MS
+supplicate/GDS
+supplication/M
+supplier/M
+supply/ZGXDRSMN
+support/MDRSBZGV
+supportability
+supportable/IU
+supported/U
+supporter/M
+suppose/GDS
+supposed/Y
+supposition/SM
+suppository/SM
+suppress/GVDS
+suppressant/MS
+suppressed/U
+suppressible
+suppression/M
+suppressor/MS
+suppurate/DSGN
+suppuration/M
+supra
+supranational
+supremacist/SM
+supremacy/M
+supremal
+supreme/YTR
+supremo/S
+supt
+surcease/DSMG
+surcharge/DSMG
+surcingle/SM
+surd
+sure/PYTR
+surefire
+surefooted
+sureness/M
+surety/SM
+surf/MDRZGS
+surface's
+surface/AGDS
+surfaced/U
+surfactant/S
+surfboard/MDGS
+surfeit/MDSG
+surfer/M
+surfing/M
+surge/DSMG
+surgeon/MS
+surgery/SM
+surgical/Y
+surlily
+surliness/M
+surly/PTR
+surmise/MGDS
+surmount/DGSB
+surmountable/I
+surname/MS
+surpass/GDS
+surpassed/U
+surplice/MS
+surplus/MS
+surplussed
+surplussing
+surprise/DSMGJ
+surprised/U
+surprising/UY
+surreal
+surrealism/M
+surrealist/SM
+surrealistic
+surrealistically
+surreality
+surrender/GMDS
+surreptitious/YP
+surreptitiousness/M
+surrey/MS
+surrogacy/M
+surrogate/SM
+surround/GSDJ
+surrounding/M
+surroundings/M
+surtax/MDSG
+surtitle/S
+surveillance/M
+survey's
+survey/ADGS
+surveying/M
+surveyor/SM
+survivability
+survivable/U
+survival/SM
+survivalist/MS
+survive/DSGB
+survivor/SM
+susceptibility/SM
+susceptible/I
+sushi/M
+suspect/SMDG
+suspected/U
+suspend/SDRZG
+suspender/M
+suspense/XMN
+suspenseful
+suspension/M
+suspicion/SM
+suspicious/Y
+suss/DSG
+sustain/SDBG
+sustainability
+sustainable/U
+sustainably
+sustenance/M
+sutler/MS
+suttee
+suture/MGDS
+suzerain/MS
+suzerainty/M
+svelte/TR
+swab/MS
+swabbed
+swabbing
+swaddle/DSG
+swag/MS
+swagged
+swagger/SMDRG
+swagging
+swain/SM
+swallow/GSMDR
+swallowtail/MS
+swam
+swami/SM
+swamp/GSMD
+swampland/MS
+swampy/RT
+swan/MS
+swank/TGSMDR
+swankily
+swankiness/M
+swanky/RPT
+swanned
+swanning
+swansong/S
+swap/MS
+swappable/U
+swapped
+swapper/S
+swapping
+sward/SM
+swarm/GSMD
+swarthy/TR
+swash/GMDS
+swashbuckler/SM
+swashbuckling/M
+swastika/SM
+swat/MS
+swatch/MS
+swath/GMDS
+swathe/M
+swaths
+swatted
+swatter/SMDG
+swatting
+sway/MDGS
+swayback/MD
+swayed/U
+swear/ZGSR
+swearer/M
+swearword/MS
+sweat/ZGSMDR
+sweatband/MS
+sweater/M
+sweatily
+sweatpants/M
+sweats/M
+sweatshirt/MS
+sweatshop/MS
+sweatsuit/S
+sweaty/RT
+swede/SM
+sweep/ZGSMRBJ
+sweeper/M
+sweeping/MY
+sweepings/M
+sweepstakes/M
+sweet/XTSMNRYP
+sweetbread/SM
+sweetbrier/SM
+sweetcorn
+sweetened/U
+sweetener/MS
+sweetening/M
+sweetheart/MS
+sweetie/SM
+sweetish
+sweetmeat/MS
+sweetness/M
+sweetshop
+swell/TGSMDRJ
+swellhead/MDS
+swelling/M
+swelter/SGMD
+swept
+sweptback
+swerve/MGDS
+swift/PTSMRY
+swiftness/M
+swig/MS
+swigged
+swigging
+swill/GSMD
+swim/MS
+swimmer/SM
+swimming/MY
+swimsuit/SM
+swimwear
+swindle/DRSMZG
+swindler/M
+swine/SM
+swineherd/SM
+swing/ZGSMR
+swingeing
+swinger/M
+swinish
+swipe/DSMG
+swirl/GSMD
+swirly/RT
+swish/TGMDRS
+swishy
+switch/MDRSZGB
+switchback/SM
+switchblade/MS
+switchboard/MS
+switcher/M
+switchgear
+switchover
+swivel/MDGS
+swiz
+swizz
+swizzle/DSG
+swollen
+swoon/SGMD
+swoop/SGMD
+swoosh/MDSG
+sword/SM
+swordfish/MS
+swordplay/M
+swordsman/M
+swordsmanship/M
+swordsmen
+swore
+sworn
+swot/S
+swotted
+swotting
+swum
+swung
+sybarite/SM
+sybaritic
+sycamore/MS
+sycophancy/M
+sycophant/SM
+sycophantic
+sycophantically
+syllabary
+syllabic
+syllabicate/DSGN
+syllabication/M
+syllabification/M
+syllabify/DSNG
+syllable/MS
+syllabub/S
+syllabus/MS
+syllogism/MS
+syllogistic
+sylph/M
+sylphic
+sylphlike
+sylphs
+sylvan
+symbiont
+symbioses
+symbiosis/M
+symbiotic
+symbiotically
+symbol/MS
+symbolic
+symbolical/Y
+symbolism/M
+symbolist
+symbolization/M
+symbolize/DSG
+symmetric
+symmetrical/Y
+symmetrization
+symmetrizing
+symmetry/SM
+sympathetic/U
+sympathetically/U
+sympathies/M
+sympathize/ZGDRS
+sympathizer/M
+sympathy/SM
+symphonic
+symphonists
+symphony/SM
+symposium/MS
+symptom/MS
+symptomatic
+symptomatically
+symptomless
+syn
+synagogal
+synagogue/SM
+synapse/MS
+synaptic
+sync/MDSG
+synchronicity
+synchronization/MS
+synchronize/ADSG
+synchronous/Y
+synchrony
+synchrotron
+syncopate/DSGN
+syncopation/M
+syncope/M
+syndicalism
+syndicalist/S
+syndicate/DSMGN
+syndication/M
+syndrome/SM
+synergism/M
+synergistic
+synergy/SM
+synfuel/MS
+synod/SM
+synonym/SM
+synonymic
+synonymous/Y
+synonymy/M
+synopses
+synopsis/M
+synopsizes
+synoptic
+syntactic
+syntactical/Y
+syntax/M
+syntheses
+synthesis/M
+synthesize/ZGDRS
+synthesizer/M
+synthetic/SM
+synthetically
+syphilis/M
+syphilitic/SM
+syringe/DSMG
+syrup/SM
+syrupy
+sysadmin/S
+sysop/S
+system/SM
+systematic/U
+systematical/Y
+systematization/M
+systematize/GDS
+systemic/MS
+systemically
+systole/SM
+systolic
+t/SDNXGBJ
+ta
+tab/SM
+tabbed
+tabbing
+tabbouleh/M
+tabby/SM
+tabernacle/SM
+tabla/MS
+table/MGDS
+tableau/M
+tableaux
+tablecloth/M
+tablecloths
+tableland/SM
+tablespoon/SM
+tablespoonful/MS
+tablet/SM
+tabletop/MS
+tableware/M
+tabloid/SM
+taboo/MDSG
+tabor/MS
+tabular
+tabulate/DSGNX
+tabulation/M
+tabulator/SM
+tachograph
+tachographs
+tachometer/SM
+tachycardia/M
+tachyon/S
+tacit/PY
+tacitness/M
+taciturn/Y
+taciturnity/M
+tack/ZGMDRS
+tacker/M
+tackiness/M
+tackle/DRSMZG
+tackler/M
+tacky/RTP
+taco/MS
+tact/FM
+tactful/YP
+tactfulness/M
+tactic/SM
+tactical/Y
+tactician/MS
+tactile
+tactility/M
+tactless/PY
+tactlessness/M
+tactual
+tad/SM
+tadpole/MS
+taffeta/M
+taffrail/SM
+taffy/SM
+tag/SM
+tagged/U
+tagger/SM
+tagging
+tagliatelle
+taiga/MS
+tail/ACSDMG
+tailback/MS
+tailboard/S
+tailbone/S
+tailcoat/MS
+tailgate/MZGDRS
+tailgater/M
+tailless/P
+taillight/MS
+tailor/SGBMD
+tailoring/M
+tailpiece/S
+tailpipe/SM
+tailplane
+tailspin/SM
+tailwind/SM
+taint/MDSG
+tainted/U
+take/AIMS
+takeaway/S
+taken/A
+takeoff/MS
+takeout/MS
+takeover/SM
+taker/MS
+taking/SM
+takings/M
+talc/M
+talcum/M
+tale/MS
+talebearer/SM
+talent/SMD
+talented/U
+talentless
+tali
+talisman/MS
+talk/ZGMDRS
+talkative/YP
+talkativeness/M
+talker/M
+talkie/RSMT
+talky
+tall/TRP
+tallboy/MS
+tallier/M
+tallish
+tallness/M
+tallow/M
+tallowy
+tally/DRSMZG
+tallyho/MDGS
+talon/MS
+talus/MS
+tam/SM
+tamale/SM
+tamarack/MS
+tamarind/MS
+tambourine/MS
+tame/BYZTGDRSP
+tamed/U
+tameness/M
+tamer/M
+tamoxifen
+tamp/ZGDRS
+tamper/ZGDR
+tamperer/M
+tampon/SM
+tan/SM
+tanager/MS
+tanbark/M
+tandem/SM
+tandoori/M
+tang/MS
+tangelo/MS
+tangent/MS
+tangential/Y
+tangerine/MS
+tangibility/IM
+tangible/IMS
+tangibleness/M
+tangibly/I
+tangle's
+tangle/UDSG
+tango/MDSG
+tangy/RT
+tank/ZGMDRS
+tankard/MS
+tanker/M
+tankful/MS
+tanned/U
+tanner/SM
+tannery/SM
+tannest
+tannin/SM
+tanning/M
+tansy/M
+tantalization/M
+tantalize/ZGDRS
+tantalizer/M
+tantalizing/Y
+tantalum/M
+tantamount
+tantra/M
+tantrum/SM
+tap/SZGMDR
+tapas
+tape/MS
+tapeline/MS
+taper/MDG
+tapestry/SM
+tapeworm/MS
+tapioca/M
+tapir/MS
+tapped/U
+tapper/MS
+tappet/MS
+tapping
+taproom/SM
+taproot/SM
+tar/SGMD
+taramasalata
+tarantella/SM
+tarantula/SM
+tarball/S
+tardily
+tardiness/M
+tardy/TPR
+tare/MS
+target/MDGS
+tariff/MS
+tarmac/MS
+tarmacadam
+tarmacked
+tarmacking
+tarn/MS
+tarnish/GMDS
+tarnished/U
+taro/MS
+tarot/MS
+tarp/MS
+tarpaulin/MS
+tarpon/MS
+tarragon/SM
+tarred
+tarring
+tarry/TGDRS
+tarsal/MS
+tarsi
+tarsus/M
+tart/PTGMDRYS
+tartan/MS
+tartar/MS
+tartaric
+tartness/M
+tarty/T
+task/GMDS
+taskmaster/MS
+taskmistress/MS
+tassel/MDSG
+taste/JMZGDRS
+tasted/U
+tasteful/EPY
+tastefulness/EM
+tasteless/PY
+tastelessness/M
+taster/M
+tastily
+tastiness/M
+tasting/M
+tasty/TRP
+tat/SZR
+tatami/MS
+tater/M
+tatted
+tatter/MDSG
+tatterdemalion/SM
+tattie
+tatting/M
+tattle/MZGDRS
+tattler/M
+tattletale/MS
+tattoo/MDRSZG
+tattooer/M
+tattooist/SM
+tatty/TRS
+tau/SM
+taught/UA
+taunt/ZGMDRS
+taunter/M
+taunting/Y
+taupe/M
+taut/PXTNRY
+tauten/DG
+tautness/M
+tautological/Y
+tautologous
+tautology/SM
+tavern/MS
+taverna/S
+tawdrily
+tawdriness/M
+tawdry/RTP
+tawny/TRM
+tax/BZGMDRS
+taxation/M
+taxed/U
+taxer/M
+taxi/GMDS
+taxicab/SM
+taxidermist/MS
+taxidermy/M
+taximeter/MS
+taxing/U
+taxiway/S
+taxman
+taxmen
+taxonomic
+taxonomist/MS
+taxonomy/SM
+taxpayer/MS
+taxpaying
+tbs
+tbsp
+tea/SM
+teabag/S
+teacake/SM
+teach/ZGRSBJ
+teachable/U
+teacher/M
+teaching/M
+teacloth
+teacup/MS
+teacupful/MS
+teak/MS
+teakettle/SM
+teal/MS
+tealeaves
+team/GMDS
+teammate/MS
+teamster/MS
+teamwork/M
+teapot/MS
+tear/GMDS
+tearaway/S
+teardrop/SM
+tearful/PY
+teargas/MS
+teargassed
+teargassing
+tearjerker/SM
+tearless
+tearoom/SM
+teary/TR
+tease/MZGDRS
+teasel/MS
+teaser/M
+teashop/S
+teasing/Y
+teaspoon/SM
+teaspoonful/MS
+teat/MS
+teatime/S
+tech/M
+techie/S
+technetium/M
+technical/Y
+technicality/SM
+technician/MS
+technicolor
+technique/SM
+techno
+technocracy/SM
+technocrat/MS
+technocratic
+technological/Y
+technologist/MS
+technology/SM
+technophiles
+technophobe/S
+technophobia
+technophobic
+techs
+tectonic/S
+tectonically
+tectonics/M
+ted/S
+teddy/S
+tedious/PY
+tediousness/M
+tedium/M
+tee/DSMH
+teeing
+teem/GDS
+teen/MS
+teenage/RZ
+teenager/M
+teeny/TR
+teenybopper/MS
+teeter/MDSG
+teethe/GDS
+teething/M
+teethmarks
+teetotal/RZ
+teetotaler/M
+teetotalism/M
+tektite/SM
+tel
+telecast/SZGMR
+telecaster/M
+telecommunication/SM
+telecommunications/M
+telecommute/DRSZG
+telecommuter/M
+telecommuting/M
+telecoms
+teleconference/MGDS
+teleconferencing/M
+telegenic
+telegram/MS
+telegraph/MDRZG
+telegrapher/M
+telegraphese
+telegraphic
+telegraphically
+telegraphist/SM
+telegraphs
+telegraphy/M
+telekinesis/M
+telekinetic
+telemarketer/SM
+telemarketing/M
+telemeter/SM
+telemetry/SM
+teleological
+teleology
+telepathic
+telepathically
+telepathy/M
+telephone/DRSMZG
+telephoner/M
+telephonic
+telephonist/S
+telephony/M
+telephoto/SM
+telephotography/M
+teleplay/MS
+teleprinter/SM
+teleprocessing/M
+teleprompter/SM
+telesales
+telescope/DSMG
+telescopic
+telescopically
+teletext/MS
+telethon/MS
+teletype/S
+teletypewriter/MS
+televangelism/M
+televangelist/SM
+televise/XGNDS
+television/M
+televisual
+teleworker/S
+teleworking
+telex/MDSG
+tell/AGS
+teller/SM
+telling/Y
+telltale/SM
+tellurium/M
+telly/SM
+telnet
+temblor/MS
+temerity/M
+temp/MDRZTGS
+temper/ESMD
+tempera/LSM
+temperament/MS
+temperamental/Y
+temperance/IM
+temperate/IY
+temperateness/M
+temperature/MS
+tempered/U
+tempering
+tempest/SM
+tempestuous/YP
+tempestuousness/M
+template's
+template/S
+temple/SM
+tempo/SM
+temporal/Y
+temporarily
+temporariness/M
+temporary/FSM
+temporize/ZGDRS
+temporizer/M
+tempt/SDRZG
+temptation/SM
+tempter/M
+tempting/Y
+temptress/MS
+tempura/M
+ten/BMH
+tenability/M
+tenable/U
+tenably
+tenacious/YP
+tenaciousness/M
+tenacity/M
+tenancy/SM
+tenant/SMDG
+tenanted/U
+tenantry/M
+tench
+tend/IFEDGS
+tended/U
+tendency/SM
+tendentious/YP
+tendentiousness/M
+tender/SMDRYTGP
+tenderfoot/SM
+tenderhearted/YP
+tenderheartedness/M
+tenderize/ZGDRS
+tenderizer/M
+tenderloin/SM
+tenderness/M
+tendinitis/M
+tendon/SM
+tendril/SM
+tenement/SM
+tenet/SM
+tenfold
+tenner/S
+tennis/M
+tenon/SM
+tenor/SM
+tenpin/SM
+tenpins/M
+tense/DRSMYTGNXP
+tenseness/M
+tensile
+tension/ESM
+tensional
+tensioned
+tensity/IM
+tensor/S
+tent/DGSM
+tentacle/DSM
+tentative/PY
+tentativeness/M
+tenterhook/MS
+tenth/MY
+tenths
+tenuity/M
+tenuous/PY
+tenuousness/M
+tenure/DSMG
+tepee/SM
+tepid/YP
+tepidity/M
+tepidness/M
+tequila/SM
+terabyte/MS
+terbium/M
+tercentenary/SM
+tercentennial/MS
+term/MDYGS
+termagant/MS
+terminable/IC
+terminal/MYS
+terminate/DSGNX
+terminated/U
+termination/CMS
+terminator/S
+termini
+terminological/Y
+terminology/SM
+terminus/M
+termite/SM
+tern/IMS
+ternary/SM
+terpsichorean
+terr
+terrace/DSMG
+terracotta/M
+terraform/D
+terrain/SM
+terrapin/MS
+terrarium/SM
+terrazzo/MS
+terrestrial/MYS
+terrible/P
+terribleness/M
+terribly
+terrier/M
+terrific
+terrifically
+terrify/GDS
+terrifying/Y
+terrine/S
+territorial/SMY
+territoriality
+territory/SM
+terror/SM
+terrorism/M
+terrorist/SM
+terrorize/DSG
+terry/RMZ
+terrycloth/M
+terse/RYTP
+terseness/M
+tertiary/S
+tessellate/XDSGN
+tessellation/M
+tesseral
+test's/AFK
+test/AKFCDGS
+testability
+testable/UF
+testament/MS
+testamentary
+testate/S
+testator/MS
+testatrices
+testatrix/M
+testbed/S
+testcard
+tested/U
+tester/KMS
+testes
+testicle/MS
+testicular
+testifier/M
+testify/ZGDRS
+testily
+testimonial/SM
+testimony/SM
+testiness/M
+testings
+testis/M
+testosterone/M
+testy/PRT
+tetanus/M
+tetchily
+tetchy/PRT
+tether/SMDG
+tethered/U
+tetra/SM
+tetrachloride
+tetracycline/M
+tetrahedral
+tetrahedron/SM
+tetrameter/MS
+text/FMS
+textbook/SM
+textile/MS
+textual/FY
+textural/Y
+texture/MDS
+textured/U
+thalami
+thalamus/M
+thalidomide/M
+thallium/M
+than
+thane/SM
+thank/SDG
+thankful/PY
+thankfuller
+thankfullest
+thankfulness/M
+thankless/PY
+thanklessness/M
+thanksgiving/MS
+that/M
+thatch/MDRSZG
+thatcher/M
+thatching/M
+thaumaturge
+thaw/MDGS
+the/JG
+theater/SM
+theatergoer/SM
+theatrical/YS
+theatricality/M
+theatricals/M
+theatrics/M
+thee/S
+theft/SM
+their/S
+theism/M
+theist/SM
+theistic
+them
+themas
+thematic
+thematically
+theme/DSM
+themselves
+then/M
+thence
+thenceforth
+thenceforward
+theocracy/SM
+theocratic
+theodolite/S
+theologian/SM
+theological/Y
+theologists
+theology/SM
+theorem/MS
+theoretic
+theoretical/Y
+theoretician/MS
+theorist/SM
+theorize/DSG
+theory/SM
+theosophic
+theosophical
+theosophist/MS
+theosophy/M
+therapeutic/S
+therapeutically
+therapeutics/M
+therapist/SM
+therapy/SM
+there/M
+thereabout/S
+thereafter
+thereat
+thereby
+therefor
+therefore
+therefrom
+therein
+thereof
+thereon
+thereto
+theretofore
+thereunder
+thereunto
+thereupon
+therewith
+therm/SM
+thermal/MYS
+thermionic
+thermistor/S
+thermochemical
+thermocouple/S
+thermodynamic/S
+thermodynamical/Y
+thermodynamics/M
+thermoelectric
+thermoluminescence
+thermometer/SM
+thermometric
+thermonuclear
+thermophile/S
+thermophilic
+thermoplastic/MS
+thermos/MS
+thermostat/MS
+thermostatic
+thermostatically
+thesauri
+thesaurus/MS
+these/S
+thesis/M
+thespian/SM
+theta/SM
+thew/MS
+they
+they'd
+they'll
+they're
+they've
+thiamine/M
+thick/PMNRYXT
+thicken/DRJZG
+thickener/M
+thickening/M
+thicket/MS
+thickheaded/M
+thickness/MS
+thicko/S
+thickset
+thief/M
+thieve/DSG
+thievery/M
+thieving/M
+thievish/P
+thigh/M
+thighbone/MS
+thighs
+thimble/MS
+thimbleful/MS
+thin/YSP
+thine
+thing/M
+thingamabob/SM
+thingamajig/SM
+thingumabob/S
+thingummy/S
+thingy/S
+think/SRBZG
+thinkable/U
+thinker/M
+thinking's
+thinned
+thinner/MS
+thinness/M
+thinnest
+thinning
+thinnish
+third/SMY
+thirst/SGMD
+thirstily
+thirstiness/M
+thirsty/TPR
+thirteen/SMH
+thirteenth/M
+thirteenths
+thirtieth/M
+thirtieths
+thirty/HSM
+this
+thistle/MS
+thistledown/M
+thither
+tho
+thole/SM
+thong/SM
+thoracic
+thorax/MS
+thorium/M
+thorn/SM
+thorniness/M
+thorny/PRT
+thorough/RYPT
+thoroughbred/MS
+thoroughfare/MS
+thoroughgoing
+thoroughness/M
+those
+thou/MS
+though
+thought/SM
+thoughtful/PY
+thoughtfulness/M
+thoughtless/PY
+thoughtlessness/M
+thousand/MHS
+thousandfold
+thousandth/M
+thousandths
+thrall/SMDG
+thralldom/M
+thrash/JMDRSZG
+thrasher/M
+thrashing/M
+thread/SMDRZG
+threadbare
+threader/M
+threadlike
+thready/TR
+threat/SMNX
+threaten/DG
+threatening/Y
+three/SM
+threefold
+threepence/M
+threepenny
+threescore/MS
+threesome/SM
+threnody/SM
+thresh/MDRSZG
+thresher/M
+threshold/SM
+threw
+thrice
+thrift/SM
+thriftily
+thriftiness/M
+thriftless
+thrifty/PTR
+thrill/SMDRZG
+thriller/M
+thrilling/Y
+thrive/DSG
+throat/SM
+throatily
+throatiness/M
+throaty/RTP
+throb/SM
+throbbed
+throbbing
+throe/SM
+thrombi
+thromboses
+thrombosis/M
+thrombotic
+thrombus/M
+throne's
+throne/CDS
+throng/GSMD
+throttle/DRSMZG
+throttler/M
+through
+throughout
+throughput/M
+throw/SMRZG
+throwaway/SM
+throwback/SM
+thrower/M
+thrown
+throwout
+thrum/SM
+thrummed
+thrumming
+thrush/MS
+thrust/ZGSMR
+thruway/MS
+thud/MS
+thudded
+thudding
+thug/MS
+thuggery/M
+thuggish
+thulium/M
+thumb/SMDG
+thumbnail/SM
+thumbprint/SM
+thumbscrew/SM
+thumbtack/SM
+thump/SMDG
+thumping/M
+thunder/ZGMDRS
+thunderbolt/MS
+thunderclap/MS
+thundercloud/SM
+thunderer/M
+thunderflashes
+thunderhead/MS
+thunderous/Y
+thundershower/SM
+thunderstorm/MS
+thunderstruck
+thundery
+thunk/S
+thus
+thwack/ZGSMDR
+thwacker/M
+thwart/GSMD
+thy
+thyme/M
+thymine/M
+thymus/MS
+thyristor/S
+thyroid/MS
+thyroidal
+thyself
+ti/MRZ
+tiara/SM
+tibia/M
+tibiae
+tibial
+tic/SM
+tick/MDRZGS
+ticker/M
+ticket/GSMD
+ticking/M
+tickle/DRSMZG
+tickler/M
+ticklish/PY
+ticklishness/M
+ticktacktoe/M
+ticktock/MS
+tidal/Y
+tidbit/SM
+tiddler/S
+tiddly
+tiddlywink/S
+tiddlywinks/M
+tide/MGJDS
+tideland/SM
+tideless
+tidemark/S
+tidewater/MS
+tideway/MS
+tidily/U
+tidiness/UM
+tidings/M
+tidy/DRSMTGP
+tie's
+tie/AUSD
+tieback/MS
+tiebreak/RSZ
+tiebreaker/M
+tiepin/S
+tier/MD
+tiff/MDGS
+tiger/SM
+tigerish
+tight/SNRYPXT
+tighten/ZGDR
+tightener/M
+tightfisted
+tightness/M
+tightrope/MS
+tights/M
+tightwad/MS
+tigress/MS
+til
+tilde/SM
+tile/MZGJDRS
+tiler/M
+tiling/M
+till's
+till/EDRZGS
+tillable
+tillage/M
+tiller/EM
+tilt/MDGS
+timber/SMD
+timberland/M
+timberline/SM
+timbre/SM
+timbrel/SM
+time/MYZGJDRS
+timebase
+timekeeper/MS
+timekeeping/M
+timeless/PY
+timelessness/M
+timeliness/UM
+timely/UPRT
+timeout/SM
+timepiece/MS
+timer/M
+timescale/S
+timeserver/MS
+timeserving/M
+timeshare/S
+timestamped
+timestamps
+timetable/DSMG
+timeworn
+timezone/S
+timid/RYTP
+timidity/M
+timidness/M
+timing/M
+timorous/YP
+timorousness/M
+timothy/M
+timpani/M
+timpanist/SM
+tin/SM
+tincture/MGDS
+tinder/M
+tinderbox/MS
+tine/MS
+tinfoil/M
+ting/MDYG
+tinge/SM
+tingeing
+tingle/DSMGJ
+tingling/M
+tingly/RT
+tininess/M
+tinker/ZGSMDR
+tinkerer/M
+tinkle/DSMG
+tinkly
+tinned
+tinnily
+tinniness/M
+tinning
+tinnitus/M
+tinny/PRT
+tinplate/M
+tinpot
+tinsel/GSMD
+tinsmith/M
+tinsmiths
+tint/MDGS
+tintinnabulation/SM
+tintype/MS
+tinware/M
+tiny/RTP
+tip/SM
+tipped
+tipper/SM
+tippet/SM
+tippex/GDS
+tipping
+tipple/DRSMZG
+tippler/M
+tipsily
+tipsiness/M
+tipster/MS
+tipsy/RPT
+tiptoe/DSM
+tiptoeing
+tiptop/SM
+tirade/SM
+tire's
+tire/AGDS
+tired/PRYT
+tiredness/M
+tireless/PY
+tirelessness/M
+tiresome/PY
+tiresomeness/M
+tissue/SM
+tit/SZMR
+titan/SM
+titanic
+titanically
+titanium/M
+titch/S
+titchy
+tithe/DRSMZG
+tither/M
+titian/M
+titillate/DSGN
+titillating/Y
+titillation/M
+titivate/DSGN
+titivation/M
+title/DSMG
+titled/UA
+titleholder/SM
+titling/A
+titlist/MS
+titmice
+titmouse/M
+titrated
+titration
+titter/SGMD
+tittle/SM
+titty/S
+titular
+tizz
+tizzy/SM
+tn
+tnpk
+to/IU
+toad/MS
+toadded
+toadding
+toadstool/MS
+toady/DSMG
+toadyism/M
+toast/SMDRZG
+toaster/M
+toastmaster/MS
+toastmistress/MS
+toasty/TRS
+tobacco/MS
+tobacconist/MS
+toboggan/ZGSMDR
+tobogganer/M
+tobogganing/M
+toccata/S
+tocsin/SM
+today/M
+toddle/DRSMZG
+toddler/M
+toddy/SM
+toe/DSM
+toecap/SM
+toeclip/S
+toehold/MS
+toeing
+toenail/MS
+toerag/S
+toff/S
+toffee/SM
+tofu/M
+tog/SM
+toga/MDS
+toge
+together/P
+togetherness/M
+togged
+togging
+toggle/DSMG
+togs/M
+toil/MDRZGS
+toiler/M
+toilet/MDGS
+toiletry/SM
+toilette/M
+toilsome
+toke/MGDS
+token/SM
+tokenism/M
+told/AU
+tole/M
+tolerable/I
+tolerably/I
+tolerance/IM
+tolerances
+tolerant/IY
+tolerate/GNDS
+toleration/M
+toll/MDGS
+tollbooth/M
+tollbooths
+tollgate/SM
+tollway/SM
+toluene/M
+tom/SM
+tomahawk/SGMD
+tomato/M
+tomatoes
+tomb/MDGS
+tombola/S
+tomboy/MS
+tomboyish
+tombstone/MS
+tomcat/MS
+tome/MS
+tomfoolery/SM
+tomographic
+tomography/M
+tomorrow/MS
+tomtit/MS
+ton/SM
+tonal/Y
+tonality/SM
+tone's
+tone/IZGDRS
+tonearm/SM
+toneless/Y
+toner/IM
+tong/MDGS
+tongue/MGDS
+tongueless
+tonic/SM
+tonight/M
+tonnage/SM
+tonne/SM
+tonsil/MS
+tonsillectomy/SM
+tonsillitis/M
+tonsorial
+tonsure/DSMG
+tony/RT
+too
+took/A
+tool's
+tool/ADGS
+toolbar
+toolbox/MS
+toolkit
+toolmaker/MS
+toolmaking
+toot/MDRZGS
+tooter/M
+tooth/MD
+toothache/MS
+toothbrush/MS
+toothily
+toothless
+toothmarks
+toothpaste/MS
+toothpick/SM
+toothsome
+toothy/RT
+tootle/GDS
+tootsie/S
+top/SM
+topaz/MS
+topcoat/SM
+topdressing/MS
+topee/S
+topflight
+topiary/M
+topic/SM
+topical/Y
+topicality/M
+topknot/SM
+topless
+topmast/SM
+topmost
+topnotch
+topographer/MS
+topographic
+topographical/Y
+topography/SM
+topological/Y
+topologist/S
+topology/S
+topped
+topper/MS
+topping/SM
+topple/GDS
+topsail/SM
+topside/SM
+topsoil/M
+topspin/M
+toque/SM
+tor/SM
+torch/GMDS
+torchbearer/MS
+torchlight/M
+torchlit
+tore
+toreador/MS
+tori
+torment/SMDG
+tormenting/Y
+tormentor/MS
+torn
+tornado/M
+tornadoes
+toroid
+toroidal
+torpedo/GMD
+torpedoes
+torpid/Y
+torpidity/M
+torpor/M
+torque/MGDS
+torrent/SM
+torrential
+torrid/RYPT
+torridity/M
+torridness/M
+tors/S
+torsion/SM
+torsional
+torso/SM
+tort's
+tort/EFAS
+torte/SM
+tortellini/SM
+tortilla/MS
+tortoise/MS
+tortoiseshell/MS
+tortoni/M
+tortuous/PY
+tortuousness/M
+torture/DRSMZG
+torturer/M
+torturous
+torus
+tosh
+toss/MDRSZG
+tossup/MS
+tot/SGMDR
+total/GSMDY
+totalitarian/MS
+totalitarianism/M
+totality/SM
+totalizator/MS
+totalizing
+tote/MS
+totem/SM
+totemic
+totted
+totter/ZGMDRS
+totterer/M
+totting
+toucan/MS
+touch/AGMDS
+touchdown/SM
+touche/BJ
+touched/U
+touchily
+touchiness/M
+touching/Y
+touchline/S
+touchpaper/S
+touchscreen/SM
+touchstone/MS
+touchy/RPT
+tough/XTGMDNRYP
+toughen/ZGDR
+toughener/M
+toughie/SM
+toughness/M
+toughs
+toupee/MS
+tour/CFSGDM
+tourer/S
+tourism/M
+tourist/MS
+touristic
+touristy
+tourmaline/M
+tournament/MS
+tourney/MS
+tourniquet/MS
+tousle/GDS
+tout/MDGS
+tow/SZGMDR
+toward/S
+towboat/MS
+towel/JGSMD
+towelette/SM
+toweling/M
+tower/GMD
+towhead/MDS
+towhee/MS
+towline/MS
+town/MS
+townee/S
+townhouse/MS
+townie/MS
+townsfolk/M
+township/MS
+townsman/M
+townsmen
+townspeople/M
+townswoman/M
+townswomen
+towpath/M
+towpaths
+towrope/SM
+toxemia/M
+toxic
+toxicity/SM
+toxicological
+toxicologist/SM
+toxicology/M
+toxin/SM
+toy/SGMD
+toyboy/S
+toymaker
+toyshop
+tr
+trace/JDRSMZG
+traceability
+traceable/U
+traceless
+tracer/M
+tracery/SM
+trachea/M
+tracheae
+tracheal
+tracheotomy/SM
+tracing/M
+track/ZGSMDR
+trackball/SM
+trackbed
+tracker/M
+trackless
+tracksuit/S
+trackway/S
+tract's
+tract/CEKFAS
+tractability/IM
+tractable/I
+tractably/I
+traction/FEACKM
+tractor/FCKMS
+trad
+trade/JDRSMZG
+trademark/SMDG
+trader/M
+tradesman/M
+tradesmen
+tradespeople/M
+tradeswoman/M
+tradeswomen
+trading/M
+tradition/MS
+traditional/Y
+traditionalism/M
+traditionalist/SM
+traduce/DRSZG
+traducer/M
+traffic/SM
+trafficked
+trafficker/SM
+trafficking/M
+tragedian/SM
+tragedienne/MS
+tragedy/SM
+tragic
+tragical/Y
+tragicomedy/SM
+tragicomic
+trail/ZGSMDR
+trailblazer/MS
+trailblazing/M
+trailer/M
+train/ZGSMDRBJ
+trained/U
+trainee/SM
+trainer/M
+training/M
+trainload/MS
+trainman/M
+trainmen
+trainspotter/S
+trainspotting
+traipse/DSMG
+trait/SM
+traitor/SM
+traitorous/Y
+trajectory/SM
+tram/MS
+tramcar/S
+tramlines
+trammed
+trammel/SGMD
+trammeled/U
+tramming
+tramp/ZGSMDR
+tramper/M
+trample/DRSMZG
+trampler/M
+trampoline/DSMG
+trampolinist
+tramway/S
+trance/MS
+tranche/S
+tranquil/RYT
+tranquility/M
+tranquilize/DRSZG
+tranquilizer/M
+tranquillize/DRSZG
+tranquillizer/M
+trans/I
+transact/DGS
+transaction/SM
+transactional
+transactor/MS
+transatlantic
+transceiver/SM
+transcend/SGD
+transcendence/M
+transcendent
+transcendental/SY
+transcendentalism/M
+transcendentalist/MS
+transcontinental
+transcribe/ZGDRS
+transcriber/M
+transcript/MS
+transcription/MS
+transcriptional
+transducer/SM
+transduction
+transect/DSG
+transept/MS
+transfer/MSB
+transferability
+transferal/MS
+transferee/S
+transference/M
+transferred
+transferring
+transfiguration/M
+transfigure/GDS
+transfinite/Y
+transfix/DSG
+transform/SMDRZGB
+transformation/MS
+transformational
+transformed/U
+transformer/M
+transfuse/DSGNX
+transfusion/M
+transgendered
+transgenders
+transgenic
+transgress/GVDS
+transgression/MS
+transgressor/SM
+transhipment
+transience/M
+transiency/M
+transient/SMY
+transistor/MS
+transistorize/DSG
+transit/SGMD
+transition/MDGS
+transitional/Y
+transitive/IMYS
+transitiveness/M
+transitivity/M
+transitory
+transl
+translatable/U
+translate/BXDSGN
+translated/U
+translation/M
+translational
+translator/MS
+transliterate/GNXDS
+transliteration/M
+translucence/M
+translucency/M
+translucent/Y
+transmigrate/DSGN
+transmigration/M
+transmissible
+transmission's
+transmission/AS
+transmissive
+transmit/AS
+transmittable
+transmittal/M
+transmittance/M
+transmitted/A
+transmitter/MS
+transmitting/A
+transmogrification/M
+transmogrify/NGDS
+transmutation/MS
+transmute/DSBG
+transnational/SM
+transoceanic
+transom/SM
+transonic
+transpacific
+transparency/SM
+transparent/Y
+transpiration/M
+transpire/DSG
+transplant/GMDS
+transplantation/M
+transpolar
+transponder/SM
+transport/SZGBMDR
+transportability
+transportable/U
+transportation/M
+transporter/M
+transpose/DSG
+transposition/SM
+transputer/S
+transsexual/MS
+transsexualism/M
+transship/LS
+transshipment/M
+transshipped
+transshipping
+transubstantiation/M
+transverse/SMY
+transvestism/M
+transvestite/MS
+trap/MS
+trapdoor/MS
+trapeze/SM
+trapezium/SM
+trapezoid/SM
+trapezoidal
+trappable/U
+trapped
+trapper/SM
+trapping/S
+trappings/M
+trapshooting/M
+trash/GMDS
+trashcan/MS
+trashiness/M
+trashy/RPT
+trauma/MS
+traumatic
+traumatically
+traumatize/GDS
+travail/SGMD
+travel/MDRSZGJ
+traveled/U
+traveler/M
+traveling/M
+travelogue/MS
+traversal/SM
+traverse/DSMG
+travesty/GDSM
+trawl/ZGSMDR
+trawler/M
+tray/MS
+treacherous/YP
+treacherousness/M
+treachery/SM
+treacle/M
+treacly
+tread/AGSM
+treader
+treadle/DSMG
+treadmill/MS
+treas
+treason/BM
+treasonous
+treasure/DRSMZG
+treasurer/M
+treasurership
+treasury/SM
+treat/AGSMD
+treatable/U
+treated/U
+treatise/SM
+treatment/MS
+treaty/SM
+treble/MGDS
+tree/MDS
+treeing
+treeless
+treelike
+treeline
+treetop/SM
+trefoil/SM
+trek/MS
+trekked
+trekker/SM
+trekking
+trellis/GMDS
+trematode/MS
+tremble/DSJMG
+trembling/Y
+tremendous/Y
+tremolo/SM
+tremor/MS
+tremulous/PY
+tremulousness/M
+trench's
+trench/ADSG
+trenchancy/M
+trenchant/Y
+trencher/MS
+trencherman/M
+trenchermen
+trend/GSMD
+trendily
+trendiness/M
+trendsetter/S
+trendsetting
+trendy/RSMPT
+trepanned
+trepidation/SM
+trespass/MDRSZG
+trespasser/M
+tress/EMS
+trestle/MS
+trews
+trey/MS
+triad/SM
+triadic
+triage/M
+trial/ASM
+trialed
+trialing
+trialled
+trialling
+triangle/SM
+triangulable
+triangular/Y
+triangulate/XDSGN
+triangulation/M
+triathlete/S
+triathlon/SM
+triatomic
+tribal/Y
+tribalism/M
+tribe/SM
+tribesman/M
+tribesmen
+tribeswoman/M
+tribeswomen
+tribulation/MS
+tribunal/SM
+tribune/MS
+tributary/SM
+tribute's
+tribute/FS
+trice/M
+tricentennial/SM
+triceps/MS
+triceratops/M
+trichina/M
+trichinae
+trichinosis/M
+trick/GSMD
+trickery/M
+trickily
+trickiness/M
+trickle/MGDS
+trickster/SM
+tricky/TRP
+tricolor/SM
+tricycle/SM
+trident/MS
+tried/U
+triennial/MYS
+trier/SM
+triffid/S
+trifle/MZGDRS
+trifler/M
+trifocals/M
+trig/M
+trigger/MDSG
+triggest
+triglyceride/SM
+trigonometric
+trigonometrical
+trigonometry/M
+trigram/S
+trike/SM
+trilateral/S
+trilby/SM
+trilingual
+trill/GSMD
+trillion/SMH
+trillionth/M
+trillionths
+trillium/M
+trilobite/SM
+trilogy/SM
+trim/PMYS
+trimaran/MS
+trimester/SM
+trimmed/U
+trimmer/SM
+trimmest
+trimming/SM
+trimmings/M
+trimness/M
+trimodal
+trimonthly
+trinitrotoluene/M
+trinity/SM
+trinket/SM
+trio/MS
+trip/MYS
+tripartite
+tripe/M
+triplane
+triple/MGDS
+triplet/SM
+triplex/MS
+triplicate/MGNDS
+tripod/MS
+tripodal
+tripos/S
+tripped
+tripper/SM
+tripping
+triptych/M
+triptychs
+tripwire/S
+trireme/SM
+trisect/SDG
+trisection/M
+trisector
+trite/FPYT
+triteness/FM
+triter
+tritium/M
+triumph/GMD
+triumphal
+triumphalism
+triumphalist
+triumphant/Y
+triumphs
+triumvir/MS
+triumvirate/SM
+trivalent
+trivet/MS
+trivia/M
+trivial/Y
+triviality/SM
+trivialization/SM
+trivialize/GDS
+trivium/M
+trochaic
+trochee/SM
+trod/AU
+trodden/AU
+troglodyte/SM
+troika/MS
+troll/SGMD
+trolley/SM
+trolleybus/MS
+trollish
+trollop/SM
+trombone/MS
+trombonist/MS
+tromp/SGD
+tron/S
+tronned
+tronning
+troop/SZGMDR
+trooper/M
+troopship/MS
+trope/SM
+trophy/SM
+tropic/MS
+tropical/Y
+tropics/M
+tropism/SM
+tropopause
+troposphere/MS
+tropospheric
+trot/MS
+troth/M
+trotted
+trotter/SM
+trotting
+troubadour/MS
+trouble/DSMG
+troubled/U
+troublemaker/SM
+troubleshoot/ZGDRS
+troubleshooter/M
+troubleshooting/M
+troubleshot
+troublesome/Y
+trough/M
+troughs
+trounce/DRSZG
+trouncer/M
+troupe/MZGDRS
+trouper/M
+trouser/SM
+trousers/M
+trousseau/M
+trousseaux
+trout/SM
+trove/SM
+trow/DSG
+trowel/MDSG
+troy/S
+truancy/M
+truant/GMDS
+truce/SM
+truck/SZGMDR
+trucker/M
+trucking/M
+truckle/MGDS
+truckload/SM
+truculence/M
+truculent/Y
+trudge/MGDS
+true/MTGDRS
+truelove/SM
+truffle/MS
+trug/S
+truism/MS
+truly/U
+trump/SGMD
+trumpery/M
+trumpet/ZGMDRS
+trumpeter/M
+truncate/GNXDS
+truncation/M
+truncheon/SM
+trundle/MZGDRS
+trundler/M
+trunk/SGM
+trunnion/S
+truss/GMDS
+trust/ESGMD
+trusted/U
+trustee/MS
+trusteeship/SM
+trustful/EY
+trustfulness/M
+trusting/Y
+trustworthiness/M
+trustworthy/PTR
+trusty/TRSM
+truth/UM
+truthful/UPY
+truthfulness/UM
+truths/U
+try's
+try/AGDS
+trying/Y
+tryout/SM
+tryst/SMDG
+tsarism
+tsarist/S
+tsetse/MS
+tsp
+tsunami/SM
+ttys
+tub/SZGMDR
+tuba/MS
+tubae
+tubal
+tubby/TR
+tube/MS
+tubeless/M
+tuber/M
+tubercle/SM
+tubercular
+tuberculin/M
+tuberculosis/M
+tuberculous
+tuberose/M
+tuberous
+tubful/MS
+tubing/M
+tubular
+tubule/MS
+tuck/MDRSZG
+tucker/MDG
+tuft/MDRSZG
+tufter/M
+tug/SM
+tugboat/MS
+tugged
+tugging
+tuition/IM
+tularemia/M
+tulip/SM
+tulle/M
+tum/S
+tumble/DRSMZG
+tumbledown
+tumbler/M
+tumbleweed/SM
+tumbling/M
+tumbrel/SM
+tumescence/M
+tumescent
+tumid
+tumidity/M
+tummy/SM
+tumor/SM
+tumorous
+tumult/SM
+tumultuous/Y
+tumulus
+tun/SZGMDRBJ
+tuna/MS
+tundra/SM
+tune/MS
+tuneful/YP
+tunefulness/M
+tuneless/Y
+tuner/M
+tuneup/SM
+tungsten/M
+tunic/SM
+tunnel/JSMDRZG
+tunneler/M
+tunny/SM
+tuppence/S
+tuppenny
+tuque/SM
+turban/SMD
+turbid
+turbidity/M
+turbine/SM
+turbo/SM
+turbocharge/ZGDRS
+turbocharger/M
+turbofan/SM
+turbojet/SM
+turboprop/SM
+turbot/SM
+turbulence/M
+turbulent/Y
+turd/MS
+tureen/SM
+turf/MDSG
+turfy/RT
+turgid/Y
+turgidity/M
+turkey/SM
+turmeric/SM
+turmoil/MS
+turn/AMDRSZG
+turnabout/SM
+turnaround/SM
+turnbuckle/SM
+turncoat/SM
+turned/U
+turner/AM
+turning/MS
+turnip/SM
+turnkey/MS
+turnoff/MS
+turnout/MS
+turnover/MS
+turnpike/MS
+turnstile/SM
+turntable/SM
+turpentine/M
+turpitude/M
+turps
+turquoise/SM
+turret/SMD
+turtle/SM
+turtledove/SM
+turtleneck/SMD
+tush/MS
+tusk/MDS
+tussle/DSMG
+tussock/MS
+tussocky
+tut/SM
+tutelage/M
+tutelary
+tutor/SMDG
+tutored/U
+tutorial/SM
+tutorship/M
+tutted
+tutti/SM
+tutting
+tutu/MS
+tux/MS
+tuxedo/SM
+twaddle/MZGDRS
+twaddler/M
+twain/M
+twang/SMDG
+twangy/RT
+twas
+twat/S
+tweak/SMDG
+twee/DP
+tweed/SM
+tweeds/M
+tweedy/RT
+tween
+tweet/SMDRZG
+tweeter/M
+tweezers/M
+twelfth/M
+twelfths
+twelve/SM
+twelvemonth/M
+twelvemonths
+twentieth/M
+twentieths
+twenty/SMH
+twerp/SM
+twice
+twiddle/MGDRS
+twiddly/RT
+twig/MS
+twigged
+twigging
+twiggy/TR
+twilight/M
+twilit
+twill/MD
+twin/MDRSZG
+twine/SM
+twiner/M
+twinge/DSMG
+twink/SY
+twinkle/MGJDS
+twinkling/M
+twinned
+twinning
+twinset/S
+twirl/SMDRZG
+twirler/M
+twirly/TR
+twist's
+twist/USDG
+twister/MS
+twisty/TR
+twit/MS
+twitch/GMDS
+twitchy/RT
+twitted
+twitter/MDSG
+twittery
+twitting
+twixt
+two/SM
+twofer/SM
+twofold
+twopence/SM
+twopenny
+twosome/SM
+twp
+tycoon/SM
+tying/AU
+tyke/MS
+tympani/M
+tympanist/MS
+tympanum/SM
+type's
+type/AGDS
+typecast/GS
+typed/U
+typeface/MS
+typeless
+typescript/MS
+typeset/S
+typesetter/SM
+typesetting/M
+typewrite/RSZG
+typewriter/M
+typewriting/M
+typewritten
+typewrote
+typhoid/M
+typhoon/MS
+typhus/M
+typical/UY
+typicality/M
+typification/M
+typify/NGDS
+typing/M
+typist/SM
+typo/MS
+typographer/MS
+typographic
+typographical/Y
+typography/M
+typological/Y
+typology/SM
+tyrannic
+tyrannical/Y
+tyrannicide
+tyrannize/GDS
+tyrannosaur/SM
+tyrannosaurus/MS
+tyrannous
+tyranny/SM
+tyrant/SM
+tyro/MS
+tyrosine
+u/S
+ubiquitous/Y
+ubiquity/M
+udder/SM
+ufologist/SM
+ufology/M
+ugh
+uglification
+ugliness/M
+ugly/RTP
+uh
+ukase/SM
+ukulele/SM
+ulcer/SM
+ulcerate/XDSGN
+ulceration/M
+ulcerous
+ulna/M
+ulnae
+ulnar
+ulster/MS
+ult
+ulterior
+ultimate/MY
+ultimatum/MS
+ultimo
+ultra/SM
+ultraconservative/SM
+ultrahigh
+ultralight/MS
+ultramarine/M
+ultramodern
+ultramontane
+ultrasonic/S
+ultrasonically
+ultrasound/MS
+ultraviolet/M
+ululate/DSGNX
+ululation/M
+um
+umbel/SM
+umber/M
+umbilical
+umbilici
+umbilicus/M
+umbra/SM
+umbrage/M
+umbrageous
+umbrella/SM
+umiak/SM
+umlaut/MS
+ump/SGMD
+umpire/MGDS
+umpteen/H
+unabridged/MS
+unacceptability
+unacceptable
+unaccommodating
+unaccountability
+unaccountably
+unadaptive
+unadventurous
+unaesthetic
+unalterably
+unambiguity
+unambitious
+unanimity/M
+unanimous/Y
+unapparent
+unappetizing
+unappreciative
+unassertive
+unassuming/Y
+unattainably
+unavailing/Y
+unaware/S
+unbeknown
+unbend/SG
+unbent
+unbiased/Y
+unbiassedly
+unbid
+unblinking/Y
+unbosom/DG
+unbound/D
+unbreakability
+unbreakable
+unbroken
+uncanny/T
+uncap/S
+uncaring
+uncatalogued
+unceasing/Y
+unchallengeable
+unchangeable
+uncharacteristic
+uncharismatic
+uncharitable
+unchaste/RT
+uncheckable
+uncial/M
+uncle/SM
+unclean/DRPT
+uncleanly/T
+unclear/DRT
+unclench/D
+uncollimated
+uncommon/T
+uncommunicative
+uncomplicated
+uncomprehending/Y
+uncompromisable
+uncompromising/Y
+unconditional/Y
+unconfused
+uncongenial
+unconscionably
+unconscious/M
+unconstitutional/Y
+uncontentious
+uncontrollably
+uncool
+uncooperative
+uncouth/YP
+uncreative
+uncross/B
+uncrushable
+unction/SM
+unctuous/YP
+unctuousness/M
+uncut
+undaunted/Y
+undead
+undecided/SM
+undemonstrative/Y
+undeniably
+under
+underachieve/ZGLDRS
+underachiever/M
+underact/SDG
+underage
+underarm/SM
+underbelly/SM
+underbid/S
+underbidding
+underbrush/M
+undercarriage/MS
+undercharge/DSMG
+underclass/MS
+underclassman/M
+underclassmen
+underclothes/M
+underclothing/M
+undercoat/JGSMD
+undercoating/M
+undercooked
+undercover
+undercurrent/SM
+undercut/SM
+undercutting
+underdeveloped
+underdevelopment/M
+underdog/SM
+underdone
+undereducated
+underemphasis
+underemployed
+underemployment/M
+underestimate/MGNXDS
+underestimation/M
+underexploited
+underexpose/DSG
+underexposure/MS
+underfed
+underfeed/SG
+underfloor
+underflow
+underfoot
+underframe
+underfund/GD
+underfur/M
+undergarment/SM
+undergo/G
+undergoes
+undergone
+undergrad/S
+undergraduate/MS
+underground/SM
+undergrowth/M
+underhand
+underhanded/YP
+underhandedness/M
+underinvestment
+underlain
+underlay/SM
+underlie/S
+underline/MGJDS
+underling/MS
+underlip/SM
+underloaded
+underlying
+undermanned
+undermentioned
+undermine/GDS
+undermost
+underneath/M
+underneaths
+undernourished
+undernourishment/M
+underpaid
+underpants/M
+underpart/MS
+underpass/MS
+underpay/GSL
+underpayment/MS
+underperformed
+underpin/S
+underpinned
+underpinning/SM
+underplay/DGS
+underpopulated
+underpopulation
+underpowered
+underpricing
+underprivileged
+underproduction/M
+underrate/GDS
+underrepresented
+underscore/DSMG
+undersea/S
+undersealed
+undersecretary/SM
+undersell/SG
+undersexed
+undershirt/SM
+undershoot/SG
+undershorts/M
+undershot
+underside/MS
+undersign/DSG
+undersigned/M
+undersized
+underskirt/SM
+undersold
+underspecification
+underspecified
+underspend/G
+underspent
+understaffed
+understand/RGSBJ
+understandability
+understandably
+understanding/MY
+understate/GDSL
+understatement/SM
+understocked
+understood
+understorey
+understory
+understrength
+understudy/DSMG
+undertake/ZGRSJ
+undertaken
+undertaker/M
+undertaking/M
+underthings/M
+undertone/MS
+undertook
+undertow/SM
+underused
+underusing
+underutilized
+undervaluation/M
+undervalue/GDS
+underwater
+underway
+underwear/M
+underweight/M
+underwent
+underwhelm/SDG
+underworld/SM
+underwrite/RSZG
+underwriter/M
+underwritten
+underwrote
+undesirable/SM
+undies/M
+undiscerning
+undisguised/Y
+undo
+undoubted/Y
+undramatic
+undrinkability
+undroppable
+undue
+undulant
+undulate/DSXGN
+undulation/M
+unearthliness/M
+unease/M
+uneasy/T
+uneatable
+uneconomic
+unemployed/M
+unending
+unenterprising
+unequal/DY
+unergonomic
+unerring/Y
+unessential
+uneven/RYPT
+unexacting
+unexceptionably
+unexcited
+unexciting
+unexpected/PY
+unexpectedness/M
+unfailing/Y
+unfair/PTRY
+unfaltering
+unfamiliar
+unfathomably
+unfed
+unfeeling/Y
+unfeminine
+unfetchable
+unfit/S
+unfitting
+unfix/GDS
+unflagging/Y
+unflappability/M
+unflappable
+unflappably
+unflattering
+unflinching/Y
+unforgettably
+unforgivably
+unfortunate/MS
+unfriendly/T
+unfrock/DG
+unfruitful
+unfulfillable
+unfunny
+unfussy
+ungainliness/M
+ungainly/RTP
+ungentle
+unglamorous
+ungodly/T
+ungraceful/Y
+ungrudging
+unguarded
+unguent/SM
+ungulate/MS
+unhandy/T
+unhappy/T
+unhealthful
+unhealthy/T
+unheroic
+unhistorical
+unholy/T
+unhurt
+unicameral
+unicellular
+unicorn/SM
+unicycle/SM
+unicyclist/S
+unideal
+unidirectional
+unifiable
+unification/AM
+unifier
+uniform/SMDRYTG
+uniformity/M
+unify/AGDSN
+unilateral/Y
+unilateralism
+unilateralist
+unimportance
+unimportant
+unimpressive
+uninhibited/Y
+uninstall/GSBD
+uninstaller/MS
+uninsured
+unintellectual
+unintelligent
+unintended
+uninteresting
+uninterrupted/Y
+unintuitive
+uninviting
+union/ASM
+unionism/M
+unionist/MS
+unipolar
+unique/YTRP
+uniqueness/M
+unisex/M
+unison/M
+unitary
+unite/AEGSD
+unitedly
+unities
+unitize/DSG
+unity/EM
+univalent
+univalve/SM
+universal/MYS
+universalism
+universality/M
+universalize/DSG
+universe/SM
+university/SM
+unixism/S
+unjam
+unkempt
+unkind/T
+unkindly/T
+unknightly
+unknowable/M
+unknown/SM
+unleaded/M
+unless
+unlike/PB
+unlikeable
+unlikely/T
+unlink/D
+unlit
+unlock/DSG
+unlovable
+unlovely/TR
+unloving
+unlucky/T
+unmanageably
+unmanly/T
+unmannerly
+unmarried
+unmeaning
+unmeetable
+unmelodious
+unmentionable/MS
+unmentionables/M
+unmet
+unmindful
+unmissable
+unmistakably
+unmistakeably
+unmnemonic
+unmoral
+unmovable
+unmusical/Y
+unnecessary
+unnerving/Y
+unobjectionable
+unobservable
+unobservant
+unoffensive
+unofficial/Y
+unoriginal
+unoriginality
+unorthodoxy
+unpack/Z
+unpeople
+unperceptive
+unpersuasive
+unphysical
+unpick/GDS
+unpin/S
+unpleasing
+unploughed
+unpoetical
+unpolitical
+unpopular
+unportable
+unpractical
+unprecedented/Y
+unprofessional/Y
+unpromising
+unpronounced
+unpropitious
+unpunctual
+unpunctuality
+unquestioning/Y
+unquiet/TR
+unraisable
+unread/B
+unreadability
+unready/TR
+unreal
+unreasoning
+unreceptive
+unregenerate
+unrelated
+unrelenting/Y
+unrelieved/Y
+unremarkable
+unremitting/Y
+unrepeated
+unreported
+unrepresentative
+unresisting/Y
+unrest/M
+unriddle
+unripe/TR
+unroll/GDS
+unromantic
+unruliness/M
+unruly/RTP
+unsafe/T
+unsaleable
+unsatisfactory/P
+unsavory
+unseal/B
+unsearchable
+unseasonal
+unseaworthiness
+unseeing/Y
+unseemly/T
+unseen/MS
+unselfconscious/Y
+unsellable
+unsentimental
+unset
+unshakably
+unshapely
+unshorn
+unshrinking
+unsighted
+unsightliness/M
+unsightly/TP
+unsociable
+unsocial
+unsophistication
+unsound/PRYT
+unspeakably
+unspecific
+unspectacular
+unsporting
+unstable/RT
+unstack/DG
+unstamped
+unsteady/PTR
+unstinting/Y
+unstoppably
+unstrapping
+unsubscribe/DGS
+unsubscriber/MS
+unsubstantial
+unsubtle
+unsure/P
+unsuspecting/Y
+unswerving/Y
+unsymmetrical
+untactful
+untenability
+unthinkably
+unthinking/Y
+unthoughtful
+untidy/PTR
+until
+untimely/T
+untiring/Y
+untouchable/SM
+untoward
+untrue/RT
+untrustworthy
+unusably
+unutterable
+unutterably
+unvarying/Y
+unwarrantable
+unwarrantably
+unwary/T
+unwed
+unwedge
+unwelcome/G
+unwell
+unwieldiness/M
+unwieldy/TRP
+unwind/B
+unwisdom
+unwise/RYT
+unworried
+unworthy/T
+unwound/D
+unwrapping
+unyielding
+up/SM
+upbeat/MS
+upbraid/SGD
+upbringing/MS
+upchuck/SGD
+upcoming
+upcountry/M
+updatability
+update/MGDRS
+updraft/MS
+upend/SGD
+upfront
+upgrade/MGDSBJ
+upgradeable
+upheaval/MS
+upheld
+uphill/MS
+uphold/ZGRS
+upholder/M
+upholster/ASDG
+upholsterer/SM
+upholstery/M
+upkeep/M
+upland/MS
+uplift/JSMDG
+upload/SDG
+upmarket
+upon
+upped
+upper/SM
+uppercase/M
+upperclassman/M
+upperclassmen
+upperclasswoman
+upperclasswomen
+uppercut/MS
+uppercutting
+uppermost
+upping
+uppish
+uppity
+upraise/DSG
+uprate/DG
+uprear/GSD
+upright/MYPS
+uprightness/M
+uprising/SM
+upriver
+uproar/SM
+uproarious/Y
+uproot/GSD
+upscale
+upset/SM
+upsetting
+upshot/SM
+upside/SM
+upsilon/MS
+upstage/GDS
+upstairs
+upstanding
+upstart/MDSG
+upstate/M
+upstream
+upstroke/SM
+upsurge/MGDS
+upswing/MS
+uptake/SM
+uptempo
+upthrust/GSM
+uptick/SM
+uptight
+uptown/M
+uptrend
+upturn/GSMD
+upward/SY
+upwelling
+upwind
+uracil/M
+uranium/M
+urban
+urbane/RYT
+urbanity/M
+urbanization/M
+urbanize/DSG
+urbanologist/SM
+urbanology/M
+urchin/SM
+urea/M
+uremia/M
+uremic
+ureter/SM
+urethane/M
+urethra/M
+urethrae
+urethral
+urethritis
+urge/MGDSJ
+urgency/M
+urgent/Y
+uric
+urinal/SM
+urinalyses
+urinalysis/M
+urinary
+urinate/GNDS
+urination/M
+urine/M
+urn/SM
+urogenital
+urological
+urologist/MS
+urology/M
+ursine
+urticaria/M
+usability/M
+usable/UA
+usage/SM
+use/AEDSMG
+used/U
+useful/PY
+usefulness/M
+useless/YP
+uselessness/M
+user/MS
+usher/SMDG
+usherette/SM
+usu
+usual's
+usual/UY
+usurer/SM
+usurious
+usurp/SDRZG
+usurpation/M
+usurper/M
+usury/M
+utensil/SM
+uteri
+uterine
+uterus/M
+utilitarian/MS
+utilitarianism/M
+utility/SM
+utilization/M
+utilize/GBDS
+utmost/M
+utopia/SM
+utter/SDRYTG
+utterance/SM
+uttermost/M
+uvula/SM
+uvular/MS
+uxorious
+v/AS
+vac/S
+vacancy/SM
+vacant/Y
+vacate/DSG
+vacation/ZGMDRS
+vacationer/M
+vacationist/MS
+vaccinate/GNDSX
+vaccination/M
+vaccine/SM
+vacillate/XGNDS
+vacillation/M
+vacuity/M
+vacuole/MS
+vacuous/YP
+vacuousness/M
+vacuum/GSMD
+vagabond/SMDG
+vagabondage/M
+vagarious
+vagary/SM
+vagina/M
+vaginae
+vaginal/Y
+vagrancy/M
+vagrant/MS
+vague/RYTP
+vagueness/M
+vain/RYT
+vainglorious/Y
+vainglory/M
+val
+valance/MS
+vale/MS
+valediction/SM
+valedictorian/SM
+valedictory/SM
+valence/MS
+valency/SM
+valentine/SM
+valet/SMDG
+valetudinarian/MS
+valetudinarianism/M
+valiance/M
+valiant/Y
+valid/Y
+validate/IGNDS
+validated/U
+validation/IM
+validations
+validity/IM
+validness/M
+valise/SM
+valley/SM
+valor/M
+valorous/Y
+valuable/MS
+valuate/DSG
+valuation/CAMS
+value's
+value/CAGSD
+valueless
+valuer/SM
+valve/DSMG
+valveless
+valvular
+vamoose/DSG
+vamp/AMDGS
+vampire/SM
+van/SM
+vanadium/M
+vandal/SM
+vandalism/M
+vandalize/DSG
+vane/MS
+vanguard/MS
+vanilla/SM
+vanish/JDSG
+vanishing/Y
+vanity/SM
+vanned
+vanning
+vanquish/ZGDRS
+vanquished/U
+vanquisher/M
+vantage/SM
+vapid/YP
+vapidity/M
+vapidness/M
+vapor/SM
+vaporization/M
+vaporize/DRSZG
+vaporizer/M
+vaporous
+vaporware/S
+vapory
+vaquero/MS
+var/S
+variability/IM
+variable/ISM
+variably/I
+variance/SM
+variant's
+variant/IS
+variate/NXS
+variation/M
+variational
+varicolored
+varicose
+varied/U
+variegate/DSGN
+variegation/M
+varietal/SM
+variety/SM
+various/Y
+varlet/SM
+varmint/MS
+varnish/GMDS
+varnished/U
+varsity/SM
+vary/DSG
+vascular
+vase/MS
+vasectomy/SM
+vasomotor
+vassal/SM
+vassalage/M
+vast/MRYTSP
+vastness/M
+vat/SM
+vatted
+vatting
+vaudeville/M
+vaudevillian/MS
+vault/SMDRZG
+vaulter/M
+vaulting/M
+vaunt/SMDG
+vb
+veal/M
+vector/SGMD
+vectorization
+vectorized
+veejay/SM
+veep/MS
+veer/MDGS
+veg/M
+vegan/SM
+vegeburger/S
+veges
+vegetable/SM
+vegetarian/SM
+vegetarianism/M
+vegetate/GNVDS
+vegetation/M
+vegetational
+vegged
+vegges
+veggie/SM
+veggieburger/S
+vegging
+vehemence/M
+vehemency/M
+vehement/Y
+vehicle/MS
+vehicular
+veil's
+veil/UDGS
+vein/MDGS
+vela
+velar/SM
+veld/MS
+vellum/M
+velocipede/MS
+velocity/SM
+velodrome/S
+velor
+velour's
+velum/M
+velvet/MS
+velveteen/MS
+velvety/TR
+venal/Y
+venality/M
+venation/M
+vend/DGS
+vendetta/SM
+vendible
+vendor/MS
+veneer/MDGS
+venerability/M
+venerable
+venerate/DSGN
+veneration/M
+venereal
+venetian
+vengeance/M
+vengeful/AY
+venial
+venireman/M
+veniremen
+venison/M
+venom/M
+venomous/Y
+venous
+vent's
+vent/DGS
+ventilate/GNDS
+ventilated/U
+ventilation/M
+ventilator/MS
+ventral/Y
+ventricle/SM
+ventricular
+ventriloquism/M
+ventriloquist/SM
+ventriloquy/M
+venture/DSMG
+venturesome/YP
+venturesomeness/M
+venturous/YP
+venturousness/M
+venue/ASM
+veracious/Y
+veracity/M
+veranda/SM
+verb/KMS
+verbal/MYS
+verbalization/M
+verbalize/GDS
+verbatim
+verbena/SM
+verbiage/MS
+verbose/YP
+verbosity/M
+verboten
+verdant/Y
+verdict/SM
+verdigris/MDSG
+verdure/M
+verge's
+verge/FDSG
+verger/MS
+verifiability
+verifiable/U
+verification/M
+verified/U
+verify/DRSNXZG
+verily
+verisimilitude/M
+veritable
+veritably
+verity/SM
+vermicelli/M
+vermiculite/M
+vermiform
+vermilion/M
+vermin/M
+verminous
+vermouth/M
+vernacular/SM
+vernal
+vernier/SM
+veronica/M
+verruca/SM
+verrucae
+versatile
+versatility/M
+verse/AFNGMSDX
+versed/U
+versicle
+versification/M
+versifier/M
+versify/NZGDRS
+version/AFIMS
+verso/SM
+versus
+vertebra/M
+vertebrae
+vertebral
+vertebrate/IMS
+vertex/MS
+vertical/MYS
+vertiginous
+vertigo/M
+verve/M
+very/RT
+vesicle/SM
+vesicular
+vesiculate
+vesper/MS
+vessel/MS
+vest's
+vest/ILDGS
+vestal/MS
+vestibular
+vestibule/MS
+vestige/SM
+vestigial/Y
+vesting/M
+vestment/IMS
+vestry/SM
+vestryman/M
+vestrymen
+vet/SM
+vetch/MS
+veteran/SM
+veterinarian/SM
+veterinary/SM
+veto/MDG
+vetoes
+vetted
+vetting
+vex/GDS
+vexation/SM
+vexatious/Y
+vhf
+vi
+via
+viability/M
+viable
+viably
+viaduct/SM
+vial/MS
+viand/SM
+vibe/MS
+vibes/M
+vibraharp/SM
+vibrancy/M
+vibrant/Y
+vibraphone/MS
+vibraphonist/MS
+vibrate/GNDSX
+vibration/M
+vibrational/Y
+vibrato/MS
+vibrator/SM
+vibratory
+viburnum/SM
+vicar/SM
+vicarage/SM
+vicarious/YP
+vicariousness/M
+vice/CMS
+viced
+vicegerent/SM
+vicennial
+viceregal
+viceroy/MS
+vichyssoise/M
+vicing
+vicinity/SM
+vicious/YP
+viciousness/M
+vicissitude/SM
+victim/MS
+victimization/M
+victimize/GDS
+victimless
+victor/MS
+victorious/Y
+victory/SM
+victual/SMDG
+vicuna/MS
+videlicet
+video/GSMD
+videocassette/SM
+videoconferencing
+videodisc/MS
+videodisk/MS
+videophone/MS
+videotape/DSMG
+videotex/S
+vie/DS
+view/AMDRBSZG
+viewer/AM
+viewership/M
+viewfinder/MS
+viewing/SM
+viewpoint/MS
+vigesimal
+vigil/SM
+vigilance/M
+vigilant/Y
+vigilante/SM
+vigilantism/M
+vigilantist/M
+vignette/DSMG
+vignettist/SM
+vigor/M
+vigorous/Y
+vii
+viii
+viking/MS
+vile/YTPR
+vileness/M
+vilification/M
+vilify/DSNG
+villa/SM
+village/RSMZ
+villager/M
+villain/SM
+villainous
+villainy/SM
+ville
+villein/SM
+villeinage/M
+villi
+villus/M
+vim/M
+vinaigrette/M
+vincible/I
+vindaloos
+vindicate/XDSGN
+vindication/M
+vindicator/MS
+vindictive/PY
+vindictiveness/M
+vine/MS
+vinegar/SM
+vinegary
+vineyard/MS
+vino/M
+vinous
+vintage/MS
+vintner/MS
+vinyl/SM
+viol/MBS
+viola/SM
+violable/I
+violate/GNDSX
+violation/M
+violator/SM
+violence/M
+violent/Y
+violet/MS
+violin/MS
+violincello/S
+violinist/SM
+violist/MS
+violoncellist/SM
+violoncello/SM
+viper/SM
+viperous
+virago/M
+viragoes
+viral
+vireo/SM
+virgin/MS
+virginal/SM
+virginity/M
+virgule/MS
+virile
+virility/M
+virologist/MS
+virology/M
+virtual/Y
+virtue/SM
+virtuosic
+virtuosity/M
+virtuoso/SM
+virtuous/YP
+virtuousness/M
+virulence/M
+virulent/Y
+virus/MS
+visa/MDSG
+visage/MS
+viscera
+visceral/Y
+viscid/I
+viscometer
+viscose/M
+viscosity/M
+viscount/SM
+viscountcy/SM
+viscountess/MS
+viscous
+viscus/M
+vise/ACMGDS
+visibility/ISM
+visible/I
+visibly/I
+vision/KGDSM
+visionary/SM
+visit's
+visit/ASGD
+visitable/U
+visitant/MS
+visitation/MS
+visited/U
+visitor/MS
+visor/SM
+vista/SM
+visual/SMY
+visualization/MS
+visualize/DRSZG
+visualizer/M
+vita/M
+vitae
+vital/SY
+vitality/M
+vitalization/AM
+vitalize/CAGSD
+vitals/M
+vitamin/MS
+vitiate/GNDS
+vitiation/M
+viticulture/M
+viticulturist/SM
+vitreous
+vitrifaction/M
+vitrification/M
+vitrify/GNDS
+vitrine/SM
+vitriol/M
+vitriolic
+vitriolically
+vittles/M
+vituperate/GNVDS
+vituperation/M
+viva/MS
+vivace
+vivacious/PY
+vivaciousness/M
+vivacity/M
+vivaria
+vivarium/SM
+vivid/RYTP
+vividness/M
+vivify/ADSG
+viviparous
+vivisect/DGS
+vivisection/M
+vivisectional
+vivisectionist/SM
+vixen/SM
+vixenish/Y
+viz
+vizier/SM
+vocab
+vocable/MS
+vocabulary/SM
+vocal/SMY
+vocalic
+vocalist/SM
+vocalization/MS
+vocalize/DSG
+vocation/FIKASM
+vocational/Y
+vocative/MS
+vociferate/DSGN
+vociferation/M
+vociferous/PY
+vociferousness/M
+vodka/SM
+voe/S
+vogue/SM
+voguish
+voice/IDSMG
+voiced/U
+voiceless/PY
+voicelessness/M
+void/MDSGB
+voila
+voile/M
+vol
+volatile/S
+volatility/M
+volatilize/DSG
+volcanic
+volcanically
+volcanism
+volcano/M
+volcanoes
+vole/MS
+volition/M
+volitional
+volley/GSMD
+volleyball/SM
+volt/AMS
+voltage/MS
+voltaic
+voltmeter/SM
+volubility/M
+voluble
+volubly
+volume/SM
+volumetric
+voluminous/PY
+voluminousness/M
+voluntarily/I
+voluntarism/M
+voluntary/SM
+volunteer/SGMD
+volunteerism/M
+voluptuary/SM
+voluptuous/PY
+voluptuousness/M
+volute/SM
+vomit/SMDG
+voodoo/GSMD
+voodooism/M
+voracious/PY
+voraciousness/M
+voracity/M
+vortex/MS
+vorticity
+votary/SM
+vote's
+vote/CGVDS
+voter/SM
+vouch/DRSZG
+voucher/M
+vouchsafe/DSG
+vow/SGMD
+vowel/SM
+voyage/MZGDRS
+voyager/M
+voyageur/SM
+voyeur/MS
+voyeurism/M
+voyeuristic
+vulcanism
+vulcanization/M
+vulcanize/GDS
+vulcanologist
+vulgar/RYT
+vulgarian/MS
+vulgarism/MS
+vulgarity/SM
+vulgarization/M
+vulgarize/ZGDRS
+vulgarizer/M
+vulnerabilities
+vulnerability/IM
+vulnerable/I
+vulnerably/I
+vulpine
+vulture/SM
+vulturous
+vulva/M
+vulvae
+vying
+w/DNXTGVJ
+wabbit/S
+wackes
+wackiness/M
+wacko/SM
+wacky/RPT
+wad/SZGMDR
+wadded
+wadding/M
+waddle/DSMG
+wade/MS
+wader/M
+waders/M
+wadge/S
+wadi/MS
+wafer/SM
+waffle/MZGDRS
+waffler/M
+waft/MDGS
+wag/SZGMDR
+wage/MS
+waged/U
+wager/ZGMDR
+wagerer/M
+wagged
+waggery/SM
+wagging
+waggish/YP
+waggishness/M
+waggle/MGDS
+waggly
+wagon/ZSMR
+wagoner/M
+wagtail/SM
+waif/MS
+wail/MDRZGS
+wailer/M
+wailing/M
+wain/MS
+wainscot/SMDGJ
+wainscoting/M
+wainwright/SM
+waist/SM
+waistband/MS
+waistcoat/MS
+waistline/MS
+wait/MDRZGS
+waiter/M
+waiting/M
+waitpeople
+waitperson/MS
+waitress/MS
+waitstaff/M
+waive/DRSZG
+waiver/M
+wake/MGJDS
+wakeful/PY
+wakefulness/M
+waken/GSD
+waldo/S
+waldoes
+wale/MGDS
+walk/BMDRZGS
+walkabout/S
+walkaway/MS
+walker/M
+walkies
+walking/M
+walkout/SM
+walkover/MS
+walkway/SM
+wall/MDGS
+wallaby/SM
+wallah
+wallahs
+wallboard/M
+wallchart
+wallet/MS
+walleye/DSM
+wallflower/MS
+wallop/MDSJG
+walloping/M
+wallow/MDSG
+wallpaper/GSMD
+wally/S
+walnut/MS
+walrus/MS
+waltz/ZGMDRS
+waltzer/M
+wampum/M
+wan/GPDY
+wand/MS
+wander/DRSJZG
+wanderer/M
+wanderings/M
+wanderlust/MS
+wane/MS
+wangle/MZGDRS
+wangler/M
+wank/DRZGS
+wanna
+wannabe/SM
+wannabee/S
+wanner
+wanness/M
+wannest
+want/MDGS
+wanted/U
+wanton/MDRYSPG
+wantonness/M
+wapiti/MS
+war/SGM
+warble/MZGDRS
+warbler/M
+warbonnet/SM
+ward/AMDGS
+warden/MS
+warder/MS
+wardress/S
+wardrobe/SM
+wardroom/SM
+wardship
+ware/MS
+warehouse/DSMG
+warehouseman
+warez/S
+warfare/M
+warhead/MS
+warhorse/SM
+warily/U
+wariness/UM
+warlike
+warlock/MS
+warlord/MS
+warm/PDRYHZTGS
+warmblooded
+warmer/M
+warmhearted/P
+warmheartedness/M
+warmish
+warmness/M
+warmonger/SMG
+warmongering/M
+warmth/M
+warn/JDGS
+warned/U
+warning/MY
+warp/MDGS
+warpaint
+warpath/M
+warpaths
+warplane/MS
+warrant/GMDS
+warranted/U
+warranty/DSMG
+warred
+warren/MS
+warring
+warrior/SM
+warship/SM
+wart/MS
+warthog/SM
+wartime/M
+warty/TR
+wary/UPRT
+was
+wash/BJMDRSZG
+washable/SM
+washbasin/SM
+washboard/SM
+washbowl/SM
+washcloth/M
+washcloths
+washday
+washed/U
+washer/M
+washerwoman/M
+washerwomen
+washing/M
+washout/MS
+washrag/MS
+washroom/MS
+washstand/SM
+washtub/MS
+washy/TR
+wasn't
+wasp/MS
+waspish/YP
+waspishness/M
+wassail/SMDG
+wast
+wastage/M
+waste/DRSMZG
+wastebasket/SM
+wasteful/PY
+wastefulness/M
+wasteland/SM
+wastepaper/M
+waster/M
+wastrel/SM
+watch/BZGMDRS
+watchable/U
+watchband/MS
+watchdog/SM
+watched/U
+watcher/M
+watchful/PY
+watchfulness/M
+watchmaker/MS
+watchmaking/M
+watchman/M
+watchmen
+watchstrap/S
+watchtower/MS
+watchword/MS
+water/GSMD
+waterbird/SM
+waterborne
+watercolor/MS
+watercolorists
+watercourse/MS
+watercraft/M
+watercress/M
+waterfall/SM
+waterfowl/SM
+waterfront/MS
+waterhole/SM
+wateriness/M
+waterless
+waterlily/SM
+waterline/MS
+waterlogged
+waterman
+watermark/MDSG
+watermelon/SM
+watermill/MS
+waterproof/SGMD
+waterproofing/M
+waters/M
+watershed/MS
+waterside/MS
+waterspout/MS
+watertight
+waterway/MS
+waterwheel/MS
+waterworks/M
+watery/PTR
+watt/MS
+wattage/M
+wattle/MGDS
+wave/MZGDRS
+waveband/S
+waveform/S
+wavefront
+waveguide/S
+wavelength/M
+wavelengths
+wavelet/SM
+wavelike
+waver/ZGMDR
+waverer/M
+wavering/UY
+wavily
+waviness/M
+wavy/PRT
+wax/GMDNS
+waxiness/M
+waxwing/SM
+waxwork/SM
+waxy/RPT
+way/SM
+waybill/SM
+wayfarer/MS
+wayfaring/SM
+waylaid
+waylay/RSZG
+waylayer/M
+wayleave/S
+waymarked
+wayside/SM
+wayward/PY
+waywardness/M
+wazoo/S
+we
+we'd
+we'll
+we're
+we've
+weak/PNRYXT
+weaken/DRZG
+weakener/M
+weakfish/MS
+weakish
+weakling/SM
+weakly/RT
+weakness/MS
+weal/MHS
+wealth/M
+wealthiness/M
+wealthy/TRP
+wean/DGS
+weanling
+weapon/MS
+weaponless
+weaponry/M
+wear/MRBJSZG
+wearable/U
+wearer/M
+wearied/U
+wearily
+weariness/M
+wearisome/Y
+weary/TGDRSP
+wearying/Y
+weasel/MDYSG
+weather/SMDG
+weatherboard/GS
+weathercock/SM
+weathering/M
+weatherization/M
+weatherize/DSG
+weatherman/M
+weathermen
+weatherperson/SM
+weatherproof/SGD
+weatherstrip/S
+weatherstripped
+weatherstripping/M
+weave/DRSMZG
+weaver/M
+weaving/M
+web/SM
+webbed
+webbing/M
+webfeet
+webfoot/M
+webmaster/MS
+webmistress/S
+website/SM
+wed/AS
+wedded/A
+wedder
+wedding/SM
+wedge/DSMG
+wedgie/MS
+wedlock/M
+wee/RSMT
+weed/MDRSZG
+weeder/M
+weedkiller/S
+weedless
+weeds/S
+weedy/TR
+weeing
+week/MYS
+weekday/SM
+weekend/SZGMDR
+weekly/SM
+weeknight/SM
+ween/DSG
+weenie/MTRS
+weensy/RT
+weeny
+weep/MRJSZG
+weeper/M
+weepy/TRSM
+weevil/MS
+weft/MS
+weigh's
+weigh/AGD
+weighbridge/S
+weighs/A
+weight/MDSJG
+weighted/U
+weightily
+weightiness/M
+weightless/YP
+weightlessness/M
+weightlifter/SM
+weightlifting/M
+weighty/PTR
+weir/MS
+weird/PTRY
+weirdie/MS
+weirdness/M
+weirdo/MS
+welcome/MGDS
+weld/MDRBSZG
+welder/M
+welfare/M
+welkin/M
+well/MDPSG
+wellhead/SM
+wellie
+wellington/MS
+wellness/M
+wellspring/MS
+welly/S
+welsh/ZGDRS
+welsher/M
+welt/MDRSZG
+welter/GMD
+welterweight/MS
+wen/M
+wench/MS
+wend/DSG
+went
+wept
+were
+weren't
+werewolf/M
+werewolves
+west/M
+westbound
+westerly/SM
+western/SZMR
+westerner/M
+westernization/M
+westernize/GDS
+westernmost
+westward/S
+wet/SMYP
+wetback/SM
+wetland/SM
+wetness/M
+wetsuit/S
+wettable
+wetter/SM
+wettest
+wetting
+wetware/S
+whack/SJZGMDR
+whacker/M
+whale/DRSMZG
+whaleboat/MS
+whalebone/M
+whaler/M
+whales/S
+whaling/M
+wham/MS
+whammed
+whamming
+whammy/SM
+wharf/SM
+wharves
+what/MS
+whatchamacallit/MS
+whatever
+whatnot/M
+whatshername
+whatshisname
+whatsit/S
+whatsoever
+wheal/SM
+wheat/MN
+wheatgerm
+wheatmeal
+whee
+wheedle/DRSZG
+wheedler/M
+wheel/SMDRZG
+wheelbarrow/MS
+wheelbase/SM
+wheelchair/SM
+wheelhouse/SM
+wheelie/SM
+wheelwright/SM
+wheeze/DSMG
+wheezily
+wheeziness/M
+wheezy/PRT
+whelk/SMD
+whelm/SDG
+whelp/SMDG
+when/MS
+whence
+whenever
+whensoever
+where/SM
+whereabouts/M
+whereas
+whereat
+whereby
+wherefore/MS
+wherein
+whereof
+whereon
+wheresoever
+whereto
+whereupon
+wherever
+wherewith
+wherewithal/M
+wherry/SM
+whet/S
+whether
+whetstone/SM
+whetted
+whetting
+whew
+whey/M
+which
+whichever
+whiff/SMDG
+whiffletree/MS
+while/DSMG
+whilom
+whilst
+whim/MS
+whimper/MDGS
+whimsical/Y
+whimsicality/M
+whimsy/SM
+whine/DRSMZG
+whiner/M
+whinge/DRSZG
+whingeing
+whinny/GDSM
+whiny/RT
+whip/MS
+whipcord/M
+whiplash/MS
+whipped
+whipper/MS
+whippersnapper/MS
+whippet/MS
+whipping/SM
+whippletree/MS
+whippoorwill/SM
+whipsaw/MDGS
+whir/MS
+whirl/SMDG
+whirligig/MS
+whirlpool/MS
+whirlwind/MS
+whirlybird/MS
+whirred
+whirring
+whisk/SMDRZG
+whisker/MD
+whiskery
+whiskey/MS
+whisper/JMDRSZG
+whisperer/M
+whist/M
+whistle/MZGDRS
+whistler/M
+whit/MDNRSXTGJ
+white/SPMY
+whitebait
+whiteboard/S
+whitecap/SM
+whitefish/MS
+whitehead/MS
+whiten/ZGDRJ
+whitener/M
+whiteness/M
+whitening/M
+whiteout/SM
+whitetail/MS
+whitewall/SM
+whitewash/GMDS
+whitewater/M
+whitey/SM
+whither
+whiting/M
+whitish
+whittle/ZGDRS
+whittler/M
+whiz/M
+whizkid/M
+whizzbang/MS
+whizzed
+whizzes
+whizzing
+who'd
+who'll
+who're
+who've
+who/M
+whoa
+whodunit/MS
+whoever
+whole/SMP
+wholefood/S
+wholegrain
+wholehearted/YP
+wholeheartedness/M
+wholemeal
+wholeness/M
+wholesale/MZGDRS
+wholesaler/M
+wholesome/UP
+wholesomely
+wholesomeness/UM
+wholewheat
+wholly
+whom
+whomever
+whomsoever
+whoop/SMDRZG
+whoopee/S
+whooper/M
+whoosh/MDSG
+whop/S
+whopped
+whopper/SM
+whopping
+whore/SMG
+whorehouse/SM
+whoreish
+whorish
+whorl/SMD
+whose
+whoso
+whosoever
+whup/S
+whupped
+whupping
+why'd
+why/M
+whys
+wick/MDRSZ
+wicked/TPRY
+wickedness/M
+wicker/M
+wickerwork/M
+wicket/SM
+wicketkeeper/S
+wicketkeeping
+wide/YTRSP
+widemouthed
+widen/SDRZG
+widener/M
+wideness/M
+widespread
+widget/S
+widow/SMDRZG
+widower/M
+widowhood/M
+width/M
+widths
+wield/SDRZG
+wielder/M
+wiener/SM
+wienie/SM
+wife/MY
+wifeless
+wifely/TR
+wig/SM
+wigeon/SM
+wigged
+wigging
+wiggle/DRSMZG
+wiggler/M
+wiggles/S
+wiggly/TR
+wight/SM
+wiglet/SM
+wigwag/SM
+wigwagged
+wigwagging
+wigwam/SM
+wiki/SM
+wild/MRYSTP
+wildcat/MS
+wildcatted
+wildcatter/MS
+wildcatting
+wildebeest/MS
+wilderness/MS
+wildfire/MS
+wildflower/SM
+wildfowl/M
+wildlife/M
+wildness/M
+wilds/M
+wile/MGDS
+wiliness/M
+will/MDS
+willful/PY
+willfulness/M
+willies/M
+willing/UTPY
+willinger
+willingness/UM
+williwaw/MS
+willow/SM
+willowy/TR
+willpower/M
+willy/S
+wilt/MDSG
+wily/RTP
+wimp/MDSG
+wimpish
+wimple/DSMG
+wimpy/RT
+win/SGMD
+wince/DSMG
+winch/MDSG
+wind's
+wind/UASG
+windbag/SM
+windblown
+windbreak/ZSMR
+windbreaker/M
+windburn/MD
+windcheater/S
+windchill/M
+winded
+winder/SM
+windfall/MS
+windflower/SM
+windily
+windiness/M
+winding/SM
+windjammer/MS
+windlass/MS
+windless
+windmill/MDGS
+window/SMDG
+windowless
+windowpane/SM
+windowsill/SM
+windpipe/MS
+windproof
+windrow/SM
+windscreen/SM
+windshield/MS
+windsock/MS
+windstorm/MS
+windsurf/ZGDRS
+windsurfer/M
+windsurfing/M
+windswept
+windup/SM
+windward/M
+windy/RTP
+wine/MS
+wineglass/MS
+winegrower/MS
+winemaker/MS
+winery/SM
+wineskin
+wing/MDRZG
+wingding/MS
+wingless
+winglike
+wingspan/MS
+wingspread/SM
+wingtip/SM
+wink/MDRSZG
+winker/M
+winkle/DSMG
+winnable
+winner/SM
+winning/MYS
+winnow/ZGSDR
+winnower/M
+wino/MS
+winsome/YTRP
+winsomeness/M
+winter/GSMD
+wintergreen/M
+winterize/GDS
+wintertime/M
+wintry/TR
+winy/RT
+wipe/MZGDRS
+wiper/M
+wire's
+wire/AGDS
+wired/S
+wirehair/MS
+wireless/MS
+wirer
+wiretap/MS
+wiretapped
+wiretapper/SM
+wiretapping/M
+wiriness/M
+wiring/M
+wiry/RTP
+wisdom/M
+wise/MYTGDRS
+wiseacre/SM
+wisecrack/GMDS
+wiseguy/S
+wisely/TR
+wish/MDRSZG
+wishbone/SM
+wisher/M
+wishful/Y
+wisp/MS
+wispy/RT
+wist
+wisteria/SM
+wistful/YP
+wistfulness/M
+wit/SM
+witch/MDSG
+witchcraft/M
+witchdoctor/S
+witchery/M
+with
+withal
+withdraw/SG
+withdrawal/MS
+withdrawn
+withdrew
+withe/DRSMZG
+wither/JGD
+withering/Y
+withers/M
+withheld
+withhold/SG
+withholding/M
+within/M
+without
+withstand/SG
+withstood
+witless/PY
+witlessness/M
+witness/MDSG
+wits/M
+witted
+witter/SGD
+witticism/SM
+wittily
+wittiness/M
+witting/UY
+witty/RPT
+wive/GDS
+wizard/SMY
+wizardry/M
+wizened
+wk/Y
+woad/M
+wobble/MGDRS
+wobbliness/M
+wobbly/RTP
+wodge/S
+woe/SM
+woebegone
+woeful/YP
+woefuller
+woefullest
+woefulness/M
+wog/S
+wok/SMN
+woke
+wold/MS
+wolf/MDSG
+wolfhound/SM
+wolfish/Y
+wolfram/M
+wolverine/SM
+wolves
+woman/M
+womanhood/M
+womanish
+womanize/DRSZG
+womanizer/M
+womankind/M
+womanlike/M
+womanliness/M
+womanly/RPT
+womb/MS
+wombat/MS
+womble/S
+women
+womenfolk/SM
+womenfolks/M
+won't
+won/M
+wonder/MDGLS
+wonderful/PY
+wonderfulness/M
+wondering/Y
+wonderland/MS
+wonderment/M
+wondrous/Y
+wonk/MS
+wonky/TR
+wont/MD
+wonted/U
+woo/SZGDR
+wood/MDNSG
+woodbine/M
+woodblock/MS
+woodcarver/MS
+woodcarving/SM
+woodchuck/MS
+woodcock/SM
+woodcraft/M
+woodcut/SM
+woodcutter/SM
+woodcutting/M
+wooden/RYTP
+woodenness/M
+woodiness/M
+woodland/SM
+woodlice
+woodlot/SM
+woodlouse
+woodman/M
+woodmen
+woodpecker/SM
+woodpile/SM
+woods/M
+woodshed/SM
+woodsiness/M
+woodsman/M
+woodsmen
+woodsmoke
+woodsy/RTP
+woodwind/MS
+woodwork/MRZG
+woodworker/M
+woodworking/M
+woodworm/S
+woody/TPRSM
+wooer/M
+woof/MDRSZG
+woofer/M
+wool/MNYSX
+woolen/M
+woolgathering/M
+wooliness
+woolliness/M
+woolly/RSMPT
+woozily
+wooziness/M
+woozy/TRP
+wop/S!
+word's
+word/AJDSG
+wordage/M
+wordbook/SM
+wordily
+wordiness/M
+wording's
+wordless/Y
+wordplay/M
+wordsmith
+wordsmiths
+wordy/TPR
+wore
+work's
+work/ADJSG
+workability/U
+workable/U
+workaday
+workaholic/SM
+workaround/S
+workbasket/S
+workbench/MS
+workbook/MS
+workday/SM
+worker/MS
+workfare/M
+workforce/SM
+workhorse/SM
+workhouse/SM
+working's
+workingman/M
+workingmen
+workings/M
+workingwoman/M
+workingwomen
+workload/MS
+workman/M
+workmanlike
+workmanship/M
+workmate/S
+workmen
+workout/SM
+workpeople
+workpiece/S
+workplace/MS
+workroom/MS
+works/M
+worksheet/MS
+workshop/MS
+workshy
+workspace
+workstation/MS
+worktable/MS
+worktop/S
+workup/MS
+workweek/SM
+world/SM
+worldlier
+worldliness/UM
+worldly/UTP
+worldview/SM
+worldwide
+worm/MDSG
+wormhole/MS
+wormwood/M
+wormy/TR
+worn/U
+worried/Y
+worrier/M
+worriment/M
+worrisome
+worry/ZGDRSMJ
+worrying/Y
+worrywart/SM
+worse/M
+worsen/DSG
+worship/ZGSMDR
+worshiper/M
+worshipful
+worst/SGMD
+worsted/M
+wort/M
+worth/M
+worthies
+worthily/U
+worthiness/UM
+worthless/YP
+worthlessness/M
+worthwhile
+worthy's
+worthy/UPRT
+wost
+wot
+wotcha
+would've
+would/S
+wouldn't
+wouldst
+wound/SGMDR
+wove/A
+woven/AU
+wow/SGMD
+wpm
+wrack/GSMD
+wraith/M
+wraiths
+wrangle/DRSMZGJ
+wrangler/M
+wrap's
+wrap/US
+wraparound/SM
+wrapped/U
+wrapper/SM
+wrapping/MS
+wrasse/MS
+wrath/M
+wrathful/Y
+wreak/SGD
+wreath/MDSG
+wreathe
+wreaths
+wreck/SZGMDR
+wreckage/M
+wrecker/M
+wren/MS
+wrench/MDSG
+wrest/SGMD
+wrestle/MZGDRS
+wrestler/M
+wrestling/M
+wretch/MS
+wretched/PTRY
+wretchedness/M
+wriggle/MZGDRS
+wriggler/M
+wriggly/RT
+wright/MS
+wring/SZGMR
+wringer/M
+wrinkle/MGDS
+wrinkled/U
+wrinkly/TRSM
+wrist/SM
+wristband/MS
+wristwatch/MS
+writ/MRSZ
+write/ASBJG
+writer/M
+writeup
+writhe/MGDS
+writing's
+written/AU
+wrong/STGMPDRY
+wrongdoer/SM
+wrongdoing/SM
+wrongful/PY
+wrongfulness/M
+wrongheaded/YP
+wrongheadedness/M
+wrongness/M
+wrote/A
+wroth
+wrought
+wrung
+wry/Y
+wryer
+wryest
+wryness/M
+wt
+wunderkind/S
+wurst/SM
+wuss/MS
+wussy/RSMT
+x
+xci
+xcii
+xciv
+xcix
+xcvi
+xcvii
+xenon/M
+xenophobe/MS
+xenophobia/M
+xenophobic
+xerographic
+xerography/M
+xerox/MDSG
+xi/SM
+xii
+xiii
+xiv
+xix
+xor
+xref/S
+xreffed
+xreffing
+xterm/M
+xv
+xvi
+xvii
+xviii
+xx
+xxi
+xxii
+xxiii
+xxiv
+xxix
+xxv
+xxvi
+xxvii
+xxviii
+xxx
+xxxi
+xxxii
+xxxiii
+xxxiv
+xxxix
+xxxv
+xxxvi
+xxxvii
+xxxviii
+xylem/M
+xylene
+xylophone/SM
+xylophonist/SM
+y
+y'all
+ya
+yacht/SMDG
+yachting/M
+yachtsman/M
+yachtsmen
+yachtswoman/M
+yachtswomen
+yahoo/SM
+yak/SM
+yakked
+yakking
+yam/SM
+yammer/SZGMDR
+yammerer/M
+yang/M
+yank/MDSG
+yap/SM
+yapped
+yapping
+yard/MS
+yardage/MS
+yardarm/MS
+yardman/M
+yardmaster/SM
+yardmen
+yardstick/MS
+yarmulke/SM
+yarn/MS
+yarrow/M
+yashmak/S
+yaw/SGMD
+yawl/MS
+yawn/MDRSZG
+yawner/M
+yawning/Y
+yaws/M
+yd
+ye/RST
+yea/SM
+yeah/M
+yeahs
+year/MYS
+yearbook/MS
+yearling/MS
+yearlong
+yearly/SM
+yearn/GSJD
+yearning/MY
+yeast/SM
+yeasty/RT
+yegg/MS
+yell/MDSG
+yellow/MDRTGPS
+yellowhammer/S
+yellowish
+yellowness/M
+yellowy
+yelp/MDSG
+yen/SM
+yeoman/M
+yeomanry/M
+yeomen
+yep/SM
+yes/MS
+yeshiva/SM
+yessed
+yessing
+yesterday/MS
+yesteryear/M
+yet
+yeti/MS
+yew/SM
+yid/S
+yield/JSGMD
+yikes
+yin/M
+yip/SM
+yipe
+yipped
+yippee
+yipping
+yo
+yob/S
+yobbo/S
+yodel/SMDRZG
+yodeler/M
+yoga/M
+yogi/MS
+yogic
+yogurt/SM
+yoke's
+yoke/UGDS
+yokel/SM
+yolk/MDS
+yon
+yonder
+yonks
+yore/M
+york/RZ
+you'd
+you'll
+you're
+you've
+you/SMH
+young/TMR
+youngish
+youngster/MS
+your/S
+yourself
+yourselves
+youth/M
+youthful/YP
+youthfulness/M
+youths
+yow
+yowl/MDSG
+yr/S
+ytterbium/M
+yttrium/M
+yuan/M
+yucca/SM
+yuck/MDSG
+yucky/TR
+yuk/SM
+yukked
+yukking
+yukky
+yule/M
+yuletide/M
+yum
+yummy/TR
+yup/SM
+yuppie/MS
+yuppify/GDS
+yurt/MS
+z/DNXTGJ
+zaniness/M
+zany/RSMPT
+zap/SM
+zapped
+zapper/MS
+zapping
+zappy
+zeal/M
+zealot/MS
+zealotry/M
+zealous/YP
+zealousness/M
+zebra/SM
+zebu/MS
+zed/SM
+zeitgeist/SM
+zenith/M
+zeniths
+zenned
+zenning
+zeolites
+zephyr/MS
+zeppelin/MS
+zero/MDHSG
+zeroes
+zest/MS
+zestful/YP
+zestfulness/M
+zesty/RT
+zeta/MS
+zeugma
+zigamorph
+zigamorphs
+zigzag/SM
+zigzagged
+zigzagging
+zilch/M
+zillion/MS
+zinc/MS
+zincked
+zincking
+zine/S
+zinfandel/M
+zing/MDRZG
+zinger/M
+zingy/RT
+zinnia/MS
+zip's
+zip/US
+zipped/U
+zipper/MDGS
+zipping/U
+zippy/TR
+zircon/MS
+zirconium/M
+zit/SM
+zither/MS
+zloty/SM
+zodiac/MS
+zodiacal
+zombie/MS
+zonal/Y
+zone's
+zone/AGDS
+zoning/M
+zonked
+zoo/SM
+zookeeper/SM
+zoological/Y
+zoologist/SM
+zoology/M
+zoom/MDSG
+zoophyte/SM
+zoophytic
+zorch/GDS
+zounds
+zucchini/MS
+zugzwang
+zwieback/M
+zydeco/M
+zygote/SM
+zygotic
+zymurgy/M
diff --git a/bundles/XO/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf b/bundles/XO/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
new file mode 100755
index 0000000..e83279f
--- /dev/null
+++ b/bundles/XO/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>{972ce4c6-7e08-4474-a285-3208198ce6fd}</em:id>
+ <em:version>3.5.3</em:version>
+
+ <!-- Target Application this theme can install into,
+ with minimum and maximum supported versions. -->
+ <em:targetApplication>
+ <Description>
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5.3</em:minVersion>
+ <em:maxVersion>3.5.3</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+
+ <!-- Front End MetaData -->
+ <em:name>Default</em:name>
+ <em:description>The default theme.</em:description>
+
+ <!-- EXTENSION AUTHORS!
+ DO NOT COPY THIS PROPERTY INTO YOUR INSTALL RDF FILES
+ It will cause users not to be informed of incompatibilities
+ with your extension when they are updated with Software Update
+ and your extension will become unavailable to them!
+ -->
+ <em:appManaged>true</em:appManaged>
+
+ <em:locked>true</em:locked>
+
+ <!-- Front End Integration Hooks (used by Theme Manager)-->
+ <em:creator>Mozilla</em:creator>
+ <em:contributor>Mozilla Contributors</em:contributor>
+
+ <em:internalName>classic/1.0</em:internalName>
+ </Description>
+
+</RDF>
diff --git a/bundles/XO/firefox b/bundles/XO/firefox
new file mode 100755
index 0000000..513dc48
--- /dev/null
+++ b/bundles/XO/firefox
@@ -0,0 +1,141 @@
+#!/bin/sh
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+##
+## Usage:
+##
+## $ mozilla [args]
+##
+## This script is meant to run the application binary from mozilla/dist/bin.
+##
+## The script will setup all the environment voodoo needed to make
+## the application binary to work.
+##
+
+#uncomment for debugging
+#set -x
+
+moz_libdir=/usr/local/lib/firefox-3.5.3
+
+# Use run-mozilla.sh in the current dir if it exists
+# If not, then start resolving symlinks until we find run-mozilla.sh
+found=0
+progname="$0"
+curdir=`dirname "$progname"`
+progbase=`basename "$progname"`
+run_moz="$curdir/run-mozilla.sh"
+if test -x "$run_moz"; then
+ dist_bin="$curdir"
+ found=1
+else
+ here=`/bin/pwd`
+ while [ -h "$progname" ]; do
+ bn=`basename "$progname"`
+ cd `dirname "$progname"`
+ progname=`/bin/ls -l "$bn" | sed -e 's/^.* -> //' `
+ progbase=`basename "$progname"`
+ if [ ! -x "$progname" ]; then
+ break
+ fi
+ curdir=`dirname "$progname"`
+ run_moz="$curdir/run-mozilla.sh"
+ if [ -x "$run_moz" ]; then
+ cd "$curdir"
+ dist_bin=`pwd`
+ run_moz="$dist_bin/run-mozilla.sh"
+ found=1
+ break
+ fi
+ done
+ cd "$here"
+fi
+if [ $found = 0 ]; then
+ # Check default compile-time libdir
+ if [ -x "$moz_libdir/run-mozilla.sh" ]; then
+ dist_bin="$moz_libdir"
+ run_moz="$moz_libdir/run-mozilla.sh"
+ else
+ echo "Cannot find Firefox runtime directory. Exiting."
+ exit 1
+ fi
+fi
+
+script_args=""
+debugging=0
+MOZILLA_BIN="${progbase}-bin"
+
+if [ "$OSTYPE" = "beos" ]; then
+ mimeset -F "$MOZILLA_BIN"
+fi
+
+pass_arg_count=0
+while [ $# -gt $pass_arg_count ]
+do
+ case "$1" in
+ -p | --pure | -pure)
+ MOZILLA_BIN="${MOZILLA_BIN}.pure"
+ shift
+ ;;
+ -g | --debug)
+ script_args="$script_args -g"
+ debugging=1
+ shift
+ ;;
+ -d | --debugger)
+ script_args="$script_args -d $2"
+ shift 2
+ ;;
+ *)
+ # Move the unrecognized argument to the end of the list.
+ arg="$1"
+ shift
+ set -- "$@" "$arg"
+ pass_arg_count=`expr $pass_arg_count + 1`
+ ;;
+ esac
+done
+
+if [ $debugging = 1 ]
+then
+ echo $dist_bin/run-mozilla.sh $script_args $dist_bin/$MOZILLA_BIN "$@"
+fi
+"$dist_bin/run-mozilla.sh" $script_args "$dist_bin/$MOZILLA_BIN" "$@"
+exitcode=$?
+
+exit $exitcode
+# EOF.
diff --git a/bundles/XO/firefox-bin b/bundles/XO/firefox-bin
new file mode 100755
index 0000000..58aaff5
--- /dev/null
+++ b/bundles/XO/firefox-bin
Binary files differ
diff --git a/bundles/foo b/bundles/XO/foo
index 1910281..1910281 100644
--- a/bundles/foo
+++ b/bundles/XO/foo
diff --git a/bundles/XO/foo~ b/bundles/XO/foo~
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/bundles/XO/foo~
diff --git a/bundles/XO/greprefs/all.js b/bundles/XO/greprefs/all.js
new file mode 100755
index 0000000..745d6b0
--- /dev/null
+++ b/bundles/XO/greprefs/all.js
@@ -0,0 +1,1497 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Benjamin Smedberg <bsmedberg@covad.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* The prefs in this file are shipped with the GRE and should apply to all
+ * embedding situations. Application-specific preferences belong somewhere else,
+ * for example xpfe/bootstrap/browser-prefs.js
+ *
+ * Platform-specific #ifdefs at the end of this file override the generic
+ * entries at the top.
+ */
+
+// SYNTAX HINTS: dashes are delimiters. Use underscores instead.
+// The first character after a period must be alphabetic.
+
+pref("keyword.URL", "http://www.google.com/search?ie=UTF-8&oe=utf-8&q=");
+pref("keyword.enabled", false);
+pref("general.useragent.locale", "chrome://global/locale/intl.properties");
+
+pref("general.config.obscure_value", 13); // for MCD .cfg files
+
+pref("general.warnOnAboutConfig", true);
+
+// maximum number of dated backups to keep at any time
+pref("browser.bookmarks.max_backups", 5);
+
+pref("browser.cache.disk.enable", true);
+pref("browser.cache.disk.capacity", 51200);
+pref("browser.cache.memory.enable", true);
+//pref("browser.cache.memory.capacity", -1);
+// -1 = determine dynamically, 0 = none, n = memory capacity in kilobytes
+pref("browser.cache.disk_cache_ssl", false);
+// 0 = once-per-session, 1 = each-time, 2 = never, 3 = when-appropriate/automatically
+pref("browser.cache.check_doc_frequency", 3);
+
+pref("browser.cache.offline.enable", true);
+// offline cache capacity in kilobytes
+pref("browser.cache.offline.capacity", 512000);
+
+// offline apps should be limited to this much data in global storage
+// (in kilobytes)
+pref("offline-apps.quota.max", 204800);
+
+// the user should be warned if offline app disk usage exceeds this amount
+// (in kilobytes)
+pref("offline-apps.quota.warn", 51200);
+
+// Fastback caching - if this pref is negative, then we calculate the number
+// of content viewers to cache based on the amount of available memory.
+pref("browser.sessionhistory.max_total_viewers", -1);
+
+pref("browser.display.use_document_fonts", 1); // 0 = never, 1 = quick, 2 = always
+pref("browser.display.use_document_colors", true);
+pref("browser.display.use_system_colors", false);
+pref("browser.display.foreground_color", "#000000");
+pref("browser.display.background_color", "#FFFFFF");
+pref("browser.display.force_inline_alttext", false); // true = force ALT text for missing images to be layed out inline
+// 0 = no external leading,
+// 1 = use external leading only when font provides,
+// 2 = add extra leading both internal leading and external leading are zero
+pref("browser.display.normal_lineheight_calc_control", 2);
+pref("browser.display.show_image_placeholders", true); // true = show image placeholders while image is loaded and when image is broken
+// min font device pixel size at which to turn on high quality
+pref("browser.display.auto_quality_min_font_size", 20);
+pref("browser.anchor_color", "#0000EE");
+pref("browser.active_color", "#EE0000");
+pref("browser.visited_color", "#551A8B");
+pref("browser.underline_anchors", true);
+pref("browser.blink_allowed", true);
+pref("browser.enable_automatic_image_resizing", false);
+
+// See http://whatwg.org/specs/web-apps/current-work/#ping
+pref("browser.send_pings", false);
+pref("browser.send_pings.max_per_link", 1); // limit the number of pings that are sent per link click
+pref("browser.send_pings.require_same_host", false); // only send pings to the same host if this is true
+
+pref("browser.display.use_focus_colors", false);
+pref("browser.display.focus_background_color", "#117722");
+pref("browser.display.focus_text_color", "#ffffff");
+pref("browser.display.focus_ring_width", 1);
+pref("browser.display.focus_ring_on_anything", false);
+// focus ring border style.
+// 0 = solid border, 1 = dotted border
+pref("browser.display.focus_ring_style", 1);
+
+pref("browser.helperApps.alwaysAsk.force", false);
+pref("browser.helperApps.neverAsk.saveToDisk", "");
+pref("browser.helperApps.neverAsk.openFile", "");
+
+// xxxbsmedberg: where should prefs for the toolkit go?
+pref("browser.chrome.toolbar_tips", true);
+// 0 = Pictures Only, 1 = Text Only, 2 = Pictures and Text
+pref("browser.chrome.toolbar_style", 2);
+// max image size for which it is placed in the tab icon for tabbrowser.
+// if 0, no images are used for tab icons for image documents.
+pref("browser.chrome.image_icons.max_size", 1024);
+
+pref("browser.triple_click_selects_paragraph", true);
+
+// When loading <video> or <audio>, check for Access-Control-Allow-Origin
+// header, and disallow the connection if not present or permitted.
+pref("media.enforce_same_site_origin", false);
+
+// Media cache size in kilobytes
+pref("media.cache_size", 51200);
+
+//@line 142 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+pref("media.ogg.enabled", true);
+//@line 145 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+pref("media.wave.enabled", true);
+//@line 147 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+// Whether to autostart a media element with an |autoplay| attribute
+pref("media.autoplay.enabled", true);
+
+// 0 = Off, 1 = Full, 2 = Tagged Images Only.
+// See eCMSMode in gfx/thebes/public/gfxPlatform.h
+pref("gfx.color_management.mode", 2);
+pref("gfx.color_management.display_profile", "");
+pref("gfx.color_management.rendering_intent", 0);
+
+pref("gfx.downloadable_fonts.enabled", true);
+
+pref("accessibility.browsewithcaret", false);
+pref("accessibility.warn_on_browsewithcaret", true);
+
+//@line 163 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+// Tab focus model bit field:
+// 1 focuses text controls, 2 focuses other form elements, 4 adds links.
+// Most users will want 1, 3, or 7.
+// On OS X, we use Full Keyboard Access system preference,
+// unless accessibility.tabfocus is set by the user.
+pref("accessibility.tabfocus", 7);
+pref("accessibility.tabfocus_applies_to_xul", false);
+
+// On OS X, we follow the "Click in the scrollbar to:" system preference
+// unless this preference was set manually
+pref("ui.scrollToClick", 0);
+
+//@line 179 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+pref("accessibility.usetexttospeech", "");
+pref("accessibility.usebrailledisplay", "");
+pref("accessibility.accesskeycausesactivation", true);
+
+// Type Ahead Find
+pref("accessibility.typeaheadfind", true);
+pref("accessibility.typeaheadfind.autostart", true);
+// casesensitive: controls the find bar's case-sensitivity
+// 0 - "never" (case-insensitive)
+// 1 - "always" (case-sensitive)
+// other - "auto" (case-sensitive for mixed-case input, insensitive otherwise)
+pref("accessibility.typeaheadfind.casesensitive", 0);
+pref("accessibility.typeaheadfind.linksonly", true);
+pref("accessibility.typeaheadfind.startlinksonly", false);
+pref("accessibility.typeaheadfind.timeout", 4000);
+pref("accessibility.typeaheadfind.enabletimeout", true);
+pref("accessibility.typeaheadfind.soundURL", "beep");
+pref("accessibility.typeaheadfind.enablesound", true);
+pref("accessibility.typeaheadfind.prefillwithselection", true);
+
+// use Mac OS X Appearance panel text smoothing setting when rendering text, disabled by default
+pref("gfx.use_text_smoothing_setting", false);
+
+pref("browser.history_expire_days", 9);
+
+// loading and rendering of framesets and iframes
+pref("browser.frames.enabled", true);
+
+// form submission
+pref("browser.forms.submit.backwards_compatible", true);
+
+// Number of characters to consider emphasizing for rich autocomplete results
+pref("toolkit.autocomplete.richBoundaryCutoff", 200);
+
+pref("toolkit.scrollbox.smoothScroll", true);
+pref("toolkit.scrollbox.scrollIncrement", 20);
+pref("toolkit.scrollbox.clickToScroll.scrollDelay", 150);
+
+// view source
+pref("view_source.syntax_highlight", true);
+pref("view_source.wrap_long_lines", false);
+pref("view_source.editor.external", false);
+pref("view_source.editor.path", "");
+// allows to add further arguments to the editor; use the %LINE% placeholder
+// for jumping to a specific line (e.g. "/line:%LINE%" or "--goto %LINE%")
+pref("view_source.editor.args", "");
+
+// dispatch left clicks only to content in browser (still allows clicks to chrome/xul)
+pref("nglayout.events.dispatchLeftClickOnly", true);
+
+// whether or not to draw images while dragging
+pref("nglayout.enable_drag_images", true);
+
+// whether or not to use xbl form controls
+pref("nglayout.debug.enable_xbl_forms", false);
+
+// scrollbar snapping region
+// 0 - off
+// 1 and higher - slider thickness multiple
+pref("slider.snapMultiplier", 0);
+
+// option to choose plug-in finder
+pref("application.use_ns_plugin_finder", false);
+
+// URI fixup prefs
+pref("browser.fixup.alternate.enabled", true);
+pref("browser.fixup.alternate.prefix", "www.");
+pref("browser.fixup.alternate.suffix", ".com");
+pref("browser.fixup.hide_user_pass", true);
+
+// Location Bar AutoComplete
+pref("browser.urlbar.autocomplete.enabled", true);
+
+// Print header customization
+// Use the following codes:
+// &T - Title
+// &U - Document URL
+// &D - Date/Time
+// &P - Page Number
+// &PT - Page Number "of" Page total
+// Set each header to a string containing zero or one of these codes
+// and the code will be replaced in that string by the corresponding data
+pref("print.print_headerleft", "&T");
+pref("print.print_headercenter", "");
+pref("print.print_headerright", "&U");
+pref("print.print_footerleft", "&PT");
+pref("print.print_footercenter", "");
+pref("print.print_footerright", "&D");
+pref("print.show_print_progress", true);
+
+// xxxbsmedberg: more toolkit prefs
+
+// When this is set to false each window has its own PrintSettings
+// and a change in one window does not affect the others
+pref("print.use_global_printsettings", true);
+
+// Save the Printings after each print job
+pref("print.save_print_settings", true);
+
+pref("print.whileInPrintPreview", true);
+
+// Cache old Presentation when going into Print Preview
+pref("print.always_cache_old_pres", false);
+
+// Enables you to specify the amount of the paper that is to be treated
+// as unwriteable. The print_edge_XXX and print_margin_XXX preferences
+// are treated as offsets that are added to this pref.
+// Default is "-1", which means "use the system default". (If there is
+// no system default, then the -1 is treated as if it were 0.)
+// This is used by both Printing and Print Preview.
+// Units are in 1/100ths of an inch.
+pref("print.print_unwriteable_margin_top", -1);
+pref("print.print_unwriteable_margin_left", -1);
+pref("print.print_unwriteable_margin_right", -1);
+pref("print.print_unwriteable_margin_bottom", -1);
+
+// Enables you to specify the gap from the edge of the paper's
+// unwriteable area to the margin.
+// This is used by both Printing and Print Preview
+// Units are in 1/100ths of an inch.
+pref("print.print_edge_top", 0);
+pref("print.print_edge_left", 0);
+pref("print.print_edge_right", 0);
+pref("print.print_edge_bottom", 0);
+
+// Pref used by the spellchecker extension to control the
+// maximum number of misspelled words that will be underlined
+// in a document.
+pref("extensions.spellcheck.inline.max-misspellings", 500);
+
+// Prefs used by libeditor. Prefs specific to seamonkey composer
+// belong in comm-central/editor/ui/composer.js
+
+pref("editor.use_custom_colors", false);
+pref("editor.htmlWrapColumn", 72);
+pref("editor.singleLine.pasteNewlines", 1);
+pref("editor.quotesPreformatted", false);
+pref("editor.use_css", true);
+pref("editor.css.default_length_unit", "px");
+pref("editor.resizing.preserve_ratio", true);
+pref("editor.positioning.offset", 0);
+
+
+// Default Capability Preferences: Security-Critical!
+// Editing these may create a security risk - be sure you know what you're doing
+//pref("capability.policy.default.barprop.visible.set", "UniversalBrowserWrite");
+
+pref("capability.policy.default_policynames", "mailnews");
+
+pref("capability.policy.default.DOMException.code", "allAccess");
+pref("capability.policy.default.DOMException.message", "allAccess");
+pref("capability.policy.default.DOMException.name", "allAccess");
+pref("capability.policy.default.DOMException.result", "allAccess");
+pref("capability.policy.default.DOMException.toString.get", "allAccess");
+
+pref("capability.policy.default.History.back.get", "allAccess");
+pref("capability.policy.default.History.current", "UniversalBrowserRead");
+pref("capability.policy.default.History.forward.get", "allAccess");
+pref("capability.policy.default.History.go.get", "allAccess");
+pref("capability.policy.default.History.item", "UniversalBrowserRead");
+pref("capability.policy.default.History.next", "UniversalBrowserRead");
+pref("capability.policy.default.History.previous", "UniversalBrowserRead");
+pref("capability.policy.default.History.toString", "UniversalBrowserRead");
+
+pref("capability.policy.default.Location.hash.set", "allAccess");
+pref("capability.policy.default.Location.href.set", "allAccess");
+pref("capability.policy.default.Location.replace.get", "allAccess");
+
+pref("capability.policy.default.Navigator.preference", "allAccess");
+pref("capability.policy.default.Navigator.preferenceinternal.get", "UniversalPreferencesRead");
+pref("capability.policy.default.Navigator.preferenceinternal.set", "UniversalPreferencesWrite");
+
+pref("capability.policy.default.Window.blur.get", "allAccess");
+pref("capability.policy.default.Window.close.get", "allAccess");
+pref("capability.policy.default.Window.closed.get", "allAccess");
+pref("capability.policy.default.Window.focus.get", "allAccess");
+pref("capability.policy.default.Window.frames.get", "allAccess");
+pref("capability.policy.default.Window.history.get", "allAccess");
+pref("capability.policy.default.Window.length.get", "allAccess");
+pref("capability.policy.default.Window.location", "allAccess");
+pref("capability.policy.default.Window.opener.get", "allAccess");
+pref("capability.policy.default.Window.parent.get", "allAccess");
+pref("capability.policy.default.Window.postMessage.get", "allAccess");
+pref("capability.policy.default.Window.self.get", "allAccess");
+pref("capability.policy.default.Window.top.get", "allAccess");
+pref("capability.policy.default.Window.window.get", "allAccess");
+
+pref("capability.policy.default.Selection.addSelectionListener", "UniversalXPConnect");
+pref("capability.policy.default.Selection.removeSelectionListener", "UniversalXPConnect");
+
+// Restrictions on the DOM for mail/news - see bugs 66938 and 84545
+pref("capability.policy.mailnews.sites", "mailbox: imap: news:");
+
+pref("capability.policy.mailnews.*.attributes.get", "noAccess");
+pref("capability.policy.mailnews.*.baseURI.get", "noAccess");
+pref("capability.policy.mailnews.*.data.get", "noAccess");
+pref("capability.policy.mailnews.*.getAttribute", "noAccess");
+pref("capability.policy.mailnews.HTMLDivElement.getAttribute", "sameOrigin");
+pref("capability.policy.mailnews.*.getAttributeNS", "noAccess");
+pref("capability.policy.mailnews.*.getAttributeNode", "noAccess");
+pref("capability.policy.mailnews.*.getAttributeNodeNS", "noAccess");
+pref("capability.policy.mailnews.*.getNamedItem", "noAccess");
+pref("capability.policy.mailnews.*.getNamedItemNS", "noAccess");
+pref("capability.policy.mailnews.*.host.get", "noAccess");
+pref("capability.policy.mailnews.*.hostname.get", "noAccess");
+pref("capability.policy.mailnews.*.href.get", "noAccess");
+pref("capability.policy.mailnews.*.innerHTML.get", "noAccess");
+pref("capability.policy.mailnews.*.lowSrc.get", "noAccess");
+pref("capability.policy.mailnews.*.nodeValue.get", "noAccess");
+pref("capability.policy.mailnews.*.pathname.get", "noAccess");
+pref("capability.policy.mailnews.*.protocol.get", "noAccess");
+pref("capability.policy.mailnews.*.src.get", "noAccess");
+pref("capability.policy.mailnews.*.substringData.get", "noAccess");
+pref("capability.policy.mailnews.*.text.get", "noAccess");
+pref("capability.policy.mailnews.*.textContent", "noAccess");
+pref("capability.policy.mailnews.*.title.get", "noAccess");
+pref("capability.policy.mailnews.*.wholeText", "noAccess");
+pref("capability.policy.mailnews.DOMException.toString", "noAccess");
+pref("capability.policy.mailnews.HTMLAnchorElement.toString", "noAccess");
+pref("capability.policy.mailnews.HTMLDocument.domain", "noAccess");
+pref("capability.policy.mailnews.HTMLDocument.URL", "noAccess");
+pref("capability.policy.mailnews.*.documentURI", "noAccess");
+pref("capability.policy.mailnews.Location.toString", "noAccess");
+pref("capability.policy.mailnews.Range.toString", "noAccess");
+pref("capability.policy.mailnews.Window.blur", "noAccess");
+pref("capability.policy.mailnews.Window.focus", "noAccess");
+pref("capability.policy.mailnews.Window.innerWidth.set", "noAccess");
+pref("capability.policy.mailnews.Window.innerHeight.set", "noAccess");
+pref("capability.policy.mailnews.Window.moveBy", "noAccess");
+pref("capability.policy.mailnews.Window.moveTo", "noAccess");
+pref("capability.policy.mailnews.Window.name.set", "noAccess");
+pref("capability.policy.mailnews.Window.outerHeight.set", "noAccess");
+pref("capability.policy.mailnews.Window.outerWidth.set", "noAccess");
+pref("capability.policy.mailnews.Window.resizeBy", "noAccess");
+pref("capability.policy.mailnews.Window.resizeTo", "noAccess");
+pref("capability.policy.mailnews.Window.screenX.set", "noAccess");
+pref("capability.policy.mailnews.Window.screenY.set", "noAccess");
+pref("capability.policy.mailnews.Window.sizeToContent", "noAccess");
+pref("capability.policy.mailnews.document.load", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.channel", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.getInterface", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.responseXML", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.responseText", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.status", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.statusText", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.abort", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.getAllResponseHeaders", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.getResponseHeader", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.open", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.send", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.setRequestHeader", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.readyState", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.overrideMimeType", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.onload", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.onerror", "noAccess");
+pref("capability.policy.mailnews.XMLHttpRequest.onreadystatechange", "noAccess");
+pref("capability.policy.mailnews.XMLSerializer.serializeToString", "noAccess");
+pref("capability.policy.mailnews.XMLSerializer.serializeToStream", "noAccess");
+pref("capability.policy.mailnews.DOMParser.parseFromString", "noAccess");
+pref("capability.policy.mailnews.DOMParser.parseFromStream", "noAccess");
+pref("capability.policy.mailnews.SOAPCall.transportURI", "noAccess");
+pref("capability.policy.mailnews.SOAPCall.verifySourceHeader", "noAccess");
+pref("capability.policy.mailnews.SOAPCall.invoke", "noAccess");
+pref("capability.policy.mailnews.SOAPCall.asyncInvoke", "noAccess");
+pref("capability.policy.mailnews.SOAPResponse.fault", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.styleURI", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.getAssociatedEncoding", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.setEncoder", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.getEncoder", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.setDecoder", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.setDecoder", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.getDecoder", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.defaultEncoder", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.defaultDecoder", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.schemaCollection", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.encode", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.decode", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.mapSchemaURI", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.unmapSchemaURI", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.getInternalSchemaURI", "noAccess");
+pref("capability.policy.mailnews.SOAPEncoding.getExternalSchemaURI", "noAccess");
+pref("capability.policy.mailnews.SOAPFault.element", "noAccess");
+pref("capability.policy.mailnews.SOAPFault.faultNamespaceURI", "noAccess");
+pref("capability.policy.mailnews.SOAPFault.faultCode", "noAccess");
+pref("capability.policy.mailnews.SOAPFault.faultString", "noAccess");
+pref("capability.policy.mailnews.SOAPFault.faultActor", "noAccess");
+pref("capability.policy.mailnews.SOAPFault.detail", "noAccess");
+pref("capability.policy.mailnews.SOAPHeaderBlock.actorURI", "noAccess");
+pref("capability.policy.mailnews.SOAPHeaderBlock.mustUnderstand", "noAccess");
+pref("capability.policy.mailnews.SOAPParameter", "noAccess");
+pref("capability.policy.mailnews.SOAPPropertyBagMutator.propertyBag", "noAccess");
+pref("capability.policy.mailnews.SOAPPropertyBagMutator.addProperty", "noAccess");
+pref("capability.policy.mailnews.SchemaLoader.load", "noAccess");
+pref("capability.policy.mailnews.SchemaLoader.loadAsync", "noAccess");
+pref("capability.policy.mailnews.SchemaLoader.processSchemaElement", "noAccess");
+pref("capability.policy.mailnews.SchemaLoader.onLoad", "noAccess");
+pref("capability.policy.mailnews.SchemaLoader.onError", "noAccess");
+pref("capability.policy.mailnews.WSDLLoader.load", "noAccess");
+pref("capability.policy.mailnews.WSDLLoader.loadAsync", "noAccess");
+pref("capability.policy.mailnews.WSDLLoader.onLoad", "noAccess");
+pref("capability.policy.mailnews.WSDLLoader.onError", "noAccess");
+pref("capability.policy.mailnews.WebServiceProxyFactory.createProxy", "noAccess");
+pref("capability.policy.mailnews.WebServiceProxyFactory.createProxyAsync", "noAccess");
+pref("capability.policy.mailnews.WebServiceProxyFactory.onLoad", "noAccess");
+pref("capability.policy.mailnews.WebServiceProxyFactory.onError", "noAccess");
+
+// XMLExtras
+pref("capability.policy.default.XMLHttpRequest.channel", "noAccess");
+pref("capability.policy.default.XMLHttpRequest.getInterface", "noAccess");
+pref("capability.policy.default.XMLHttpRequest.open-uri", "allAccess");
+pref("capability.policy.default.DOMParser.parseFromStream", "noAccess");
+
+// Clipboard
+pref("capability.policy.default.Clipboard.cutcopy", "noAccess");
+pref("capability.policy.default.Clipboard.paste", "noAccess");
+
+// Scripts & Windows prefs
+pref("dom.disable_image_src_set", false);
+pref("dom.disable_window_flip", false);
+pref("dom.disable_window_move_resize", false);
+pref("dom.disable_window_status_change", false);
+
+pref("dom.disable_window_open_feature.titlebar", false);
+pref("dom.disable_window_open_feature.close", false);
+pref("dom.disable_window_open_feature.toolbar", false);
+pref("dom.disable_window_open_feature.location", false);
+pref("dom.disable_window_open_feature.directories", false);
+pref("dom.disable_window_open_feature.personalbar", false);
+pref("dom.disable_window_open_feature.menubar", false);
+pref("dom.disable_window_open_feature.scrollbars", false);
+pref("dom.disable_window_open_feature.resizable", true);
+pref("dom.disable_window_open_feature.minimizable", false);
+pref("dom.disable_window_open_feature.status", true);
+
+pref("dom.allow_scripts_to_close_windows", false);
+
+pref("dom.disable_open_during_load", false);
+pref("dom.popup_maximum", 20);
+pref("dom.popup_allowed_events", "change click dblclick mouseup reset submit");
+pref("dom.disable_open_click_delay", 1000);
+
+pref("dom.storage.enabled", true);
+pref("dom.storage.default_quota", 5120);
+
+// Parsing perf prefs. For now just mimic what the old code did.
+pref("content.sink.event_probe_rate", 3);
+//@line 527 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+pref("content.sink.pending_event_mode", 0);
+//@line 529 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+// Disable popups from plugins by default
+// 0 = openAllowed
+// 1 = openControlled
+// 2 = openAbused
+pref("privacy.popups.disable_from_plugins", 2);
+
+pref("dom.event.contextmenu.enabled", true);
+
+pref("javascript.enabled", true);
+pref("javascript.allow.mailnews", false);
+pref("javascript.options.strict", false);
+pref("javascript.options.relimit", false);
+pref("javascript.options.jit.content", true);
+pref("javascript.options.jit.chrome", false);
+
+// advanced prefs
+pref("security.enable_java", true);
+pref("advanced.mailftp", false);
+pref("image.animation_mode", "normal");
+
+// Same-origin policy for file URIs, "false" is traditional
+pref("security.fileuri.strict_origin_policy", true);
+
+// If there is ever a security firedrill that requires
+// us to block certian ports global, this is the pref
+// to use. Is is a comma delimited list of port numbers
+// for example:
+// pref("network.security.ports.banned", "1,2,3,4,5");
+// prevents necko connecting to ports 1-5 unless the protocol
+// overrides.
+
+// Default action for unlisted external protocol handlers
+pref("network.protocol-handler.external-default", true); // OK to load
+pref("network.protocol-handler.warn-external-default", true); // warn before load
+
+// Prevent using external protocol handlers for these schemes
+pref("network.protocol-handler.external.hcp", false);
+pref("network.protocol-handler.external.vbscript", false);
+pref("network.protocol-handler.external.javascript", false);
+pref("network.protocol-handler.external.data", false);
+pref("network.protocol-handler.external.ms-help", false);
+pref("network.protocol-handler.external.shell", false);
+pref("network.protocol-handler.external.vnd.ms.radio", false);
+//@line 576 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+pref("network.protocol-handler.external.disk", false);
+pref("network.protocol-handler.external.disks", false);
+pref("network.protocol-handler.external.afp", false);
+pref("network.protocol-handler.external.moz-icon", false);
+
+// An exposed protocol handler is one that can be used in all contexts. A
+// non-exposed protocol handler is one that can only be used internally by the
+// application. For example, a non-exposed protocol would not be loaded by the
+// application in response to a link click or a X-remote openURL command.
+// Instead, it would be deferred to the system's external protocol handler.
+// Only internal/built-in protocol handlers can be marked as exposed.
+
+// This pref controls the default settings. Per protocol settings can be used
+// to override this value.
+pref("network.protocol-handler.expose-all", true);
+
+// Example: make IMAP an exposed protocol
+// pref("network.protocol-handler.expose.imap", true);
+
+pref("network.hosts.smtp_server", "mail");
+pref("network.hosts.pop_server", "mail");
+
+// <http>
+pref("network.http.version", "1.1"); // default
+// pref("network.http.version", "1.0"); // uncomment this out in case of problems
+// pref("network.http.version", "0.9"); // it'll work too if you're crazy
+// keep-alive option is effectively obsolete. Nevertheless it'll work with
+// some older 1.0 servers:
+
+pref("network.http.proxy.version", "1.1"); // default
+// pref("network.http.proxy.version", "1.0"); // uncomment this out in case of problems
+ // (required if using junkbuster proxy)
+
+// enable caching of http documents
+pref("network.http.use-cache", true);
+
+// this preference can be set to override the socket type used for normal
+// HTTP traffic. an empty value indicates the normal TCP/IP socket type.
+pref("network.http.default-socket-type", "");
+
+pref("network.http.keep-alive", true); // set it to false in case of problems
+pref("network.http.proxy.keep-alive", true);
+pref("network.http.keep-alive.timeout", 300);
+
+// limit the absolute number of http connections.
+pref("network.http.max-connections", 30);
+
+// limit the absolute number of http connections that can be established per
+// host. if a http proxy server is enabled, then the "server" is the proxy
+// server. Otherwise, "server" is the http origin server.
+pref("network.http.max-connections-per-server", 15);
+
+// if network.http.keep-alive is true, and if NOT connecting via a proxy, then
+// a new connection will only be attempted if the number of active persistent
+// connections to the server is less then max-persistent-connections-per-server.
+pref("network.http.max-persistent-connections-per-server", 6);
+
+// if network.http.keep-alive is true, and if connecting via a proxy, then a
+// new connection will only be attempted if the number of active persistent
+// connections to the proxy is less then max-persistent-connections-per-proxy.
+pref("network.http.max-persistent-connections-per-proxy", 8);
+
+// amount of time (in seconds) to suspend pending requests, before spawning a
+// new connection, once the limit on the number of persistent connections per
+// host has been reached. however, a new connection will not be created if
+// max-connections or max-connections-per-server has also been reached.
+pref("network.http.request.max-start-delay", 10);
+
+// Headers
+pref("network.http.accept.default", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+pref("network.http.sendRefererHeader", 2); // 0=don't send any, 1=send only on clicks, 2=send on image requests as well
+
+// Controls whether we send HTTPS referres to other HTTPS sites.
+// By default this is enabled for compatibility (see bug 141641)
+pref("network.http.sendSecureXSiteReferrer", true);
+
+// Maximum number of consecutive redirects before aborting.
+pref("network.http.redirection-limit", 20);
+
+// Enable http compression: comment this out in case of problems with 1.1
+// NOTE: support for "compress" has been disabled per bug 196406.
+pref("network.http.accept-encoding" ,"gzip,deflate");
+
+pref("network.http.pipelining" , false);
+pref("network.http.pipelining.ssl" , false); // disable pipelining over SSL
+pref("network.http.proxy.pipelining", false);
+
+// Max number of requests in the pipeline
+pref("network.http.pipelining.maxrequests" , 4);
+
+// Prompt for 307 redirects
+pref("network.http.prompt-temp-redirect", true);
+
+// </http>
+
+// If false, remote JAR files that are served with a content type other than
+// application/java-archive or application/x-jar will not be opened
+// by the jar channel.
+pref("network.jar.open-unsafe-types", false);
+
+// This preference controls whether or not internationalized domain names (IDN)
+// are handled. IDN requires a nsIIDNService implementation.
+pref("network.enableIDN", true);
+
+// This preference, if true, causes all UTF-8 domain names to be normalized to
+// punycode. The intention is to allow UTF-8 domain names as input, but never
+// generate them from punycode.
+pref("network.IDN_show_punycode", false);
+
+// TLDs with "network.IDN.whitelist.tld" explicitly set to true are treated as
+// IDN-safe. Otherwise, they're treated as unsafe and punycode will be used
+// for displaying them in the UI (e.g. URL bar). Note that these preferences
+// are referred to ONLY when "network.IDN_show_punycode" is false. In other
+// words, all IDNs will be shown in punycode if "network.IDN_show_punycode"
+// is true.
+
+// ccTLDs
+pref("network.IDN.whitelist.ac", true);
+pref("network.IDN.whitelist.ar", true);
+pref("network.IDN.whitelist.at", true);
+pref("network.IDN.whitelist.br", true);
+pref("network.IDN.whitelist.ch", true);
+pref("network.IDN.whitelist.cl", true);
+pref("network.IDN.whitelist.cn", true);
+pref("network.IDN.whitelist.de", true);
+pref("network.IDN.whitelist.dk", true);
+pref("network.IDN.whitelist.es", true);
+pref("network.IDN.whitelist.fi", true);
+pref("network.IDN.whitelist.gr", true);
+pref("network.IDN.whitelist.hu", true);
+pref("network.IDN.whitelist.io", true);
+pref("network.IDN.whitelist.ir", true);
+pref("network.IDN.whitelist.is", true);
+pref("network.IDN.whitelist.jp", true);
+pref("network.IDN.whitelist.kr", true);
+pref("network.IDN.whitelist.li", true);
+pref("network.IDN.whitelist.lt", true);
+pref("network.IDN.whitelist.no", true);
+pref("network.IDN.whitelist.pl", true);
+pref("network.IDN.whitelist.pr", true);
+pref("network.IDN.whitelist.se", true);
+pref("network.IDN.whitelist.sh", true);
+pref("network.IDN.whitelist.th", true);
+pref("network.IDN.whitelist.tm", true);
+pref("network.IDN.whitelist.tw", true);
+pref("network.IDN.whitelist.vn", true);
+
+// non-ccTLDs
+pref("network.IDN.whitelist.biz", true);
+pref("network.IDN.whitelist.cat", true);
+pref("network.IDN.whitelist.info", true);
+pref("network.IDN.whitelist.museum", true);
+pref("network.IDN.whitelist.org", true);
+
+// NOTE: Before these can be removed, one of bug 414812's tests must be updated
+// or it will likely fail! Please CC jwalden+bmo on the bug associated
+// with removing these so he can provide a patch to make the necessary
+// changes to avoid bustage.
+// ".test" localised TLDs for ICANN's top-level IDN trial
+pref("network.IDN.whitelist.xn--0zwm56d", true);
+pref("network.IDN.whitelist.xn--11b5bs3a9aj6g", true);
+pref("network.IDN.whitelist.xn--80akhbyknj4f", true);
+pref("network.IDN.whitelist.xn--9t4b11yi5a", true);
+pref("network.IDN.whitelist.xn--deba0ad", true);
+pref("network.IDN.whitelist.xn--g6w251d", true);
+pref("network.IDN.whitelist.xn--hgbk6aj7f53bba", true);
+pref("network.IDN.whitelist.xn--hlcj6aya9esc7a", true);
+pref("network.IDN.whitelist.xn--jxalpdlp", true);
+pref("network.IDN.whitelist.xn--kgbechtv", true);
+pref("network.IDN.whitelist.xn--zckzah", true);
+
+// If a domain includes any of the following characters, it may be a spoof
+// attempt and so we always display the domain name as punycode. This would
+// override the settings "network.IDN_show_punycode" and
+// "network.IDN.whitelist.*".
+pref("network.IDN.blacklist_chars", "\u0020\u00A0\u00BC\u00BD\u00BE\u01C3\u02D0\u0337\u0338\u0589\u05C3\u05F4\u0609\u060A\u066A\u06D4\u0701\u0702\u0703\u0704\u115F\u1160\u1735\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u200B\u2024\u2027\u2028\u2029\u202F\u2039\u203A\u2041\u2044\u2052\u205F\u2153\u2154\u2155\u2156\u2157\u2158\u2159\u215A\u215B\u215C\u215D\u215E\u215F\u2215\u2236\u23AE\u2571\u29F6\u29F8\u2AFB\u2AFD\u2FF0\u2FF1\u2FF2\u2FF3\u2FF4\u2FF5\u2FF6\u2FF7\u2FF8\u2FF9\u2FFA\u2FFB\u3000\u3002\u3014\u3015\u3033\u3164\u321D\u321E\u33AE\u33AF\u33C6\u33DF\uA789\uFE14\uFE15\uFE3F\uFE5D\uFE5E\uFEFF\uFF0E\uFF0F\uFF61\uFFA0\uFFF9\uFFFA\uFFFB\uFFFC\uFFFD");
+
+// This preference specifies a list of domains for which DNS lookups will be
+// IPv4 only. Works around broken DNS servers which can't handle IPv6 lookups
+// and/or allows the user to disable IPv6 on a per-domain basis. See bug 68796.
+pref("network.dns.ipv4OnlyDomains", "");
+
+// This preference can be used to turn off IPv6 name lookups. See bug 68796.
+pref("network.dns.disableIPv6", false);
+
+// This preference controls whether or not URLs with UTF-8 characters are
+// escaped. Set this preference to TRUE for strict RFC2396 conformance.
+pref("network.standard-url.escape-utf8", true);
+
+// This preference controls whether or not URLs are always encoded and sent as
+// UTF-8.
+pref("network.standard-url.encode-utf8", true);
+
+// This preference controls whether or not queries are encoded and sent as
+// UTF-8.
+pref("network.standard-url.encode-query-utf8", false);
+
+// Idle timeout for ftp control connections - 5 minute default
+pref("network.ftp.idleConnectionTimeout", 300);
+
+// directory listing format
+// 2: HTML
+// 3: XUL directory viewer
+// all other values are treated like 2
+pref("network.dir.format", 2);
+
+// enables the prefetch service (i.e., prefetching of <link rel="next"> URLs).
+pref("network.prefetch-next", true);
+
+
+// The following prefs pertain to the negotiate-auth extension (see bug 17578),
+// which provides transparent Kerberos or NTLM authentication using the SPNEGO
+// protocol. Each pref is a comma-separated list of keys, where each key has
+// the format:
+// [scheme "://"] [host [":" port]]
+// For example, "foo.com" would match "http://www.foo.com/bar", etc.
+
+// This list controls which URIs can use the negotiate-auth protocol. This
+// list should be limited to the servers you know you'll need to login to.
+pref("network.negotiate-auth.trusted-uris", "");
+// This list controls which URIs can support delegation.
+pref("network.negotiate-auth.delegation-uris", "");
+
+// Allow SPNEGO by default when challenged by a proxy server.
+pref("network.negotiate-auth.allow-proxies", true);
+
+// Path to a specific gssapi library
+pref("network.negotiate-auth.gsslib", "");
+
+// Specify if the gss lib comes standard with the OS
+pref("network.negotiate-auth.using-native-gsslib", true);
+
+//@line 814 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+// The following prefs are used to enable automatic use of the operating
+// system's NTLM implementation to silently authenticate the user with their
+// Window's domain logon. The trusted-uris pref follows the format of the
+// trusted-uris pref for negotiate authentication.
+pref("network.automatic-ntlm-auth.allow-proxies", true);
+pref("network.automatic-ntlm-auth.trusted-uris", "");
+
+// This preference controls whether or not the LM hash will be included in
+// response to a NTLM challenge. By default, this is disabled since servers
+// should almost never need the LM hash, and the LM hash is what makes NTLM
+// authentication less secure. See bug 250691 for further details.
+// NOTE: automatic-ntlm-auth which leverages the OS-provided NTLM
+// implementation will not be affected by this preference.
+pref("network.ntlm.send-lm-response", false);
+
+pref("permissions.default.image", 1); // 1-Accept, 2-Deny, 3-dontAcceptForeign
+
+//@line 834 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+pref("network.proxy.type", 5);
+//@line 841 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+pref("network.proxy.ftp", "");
+pref("network.proxy.ftp_port", 0);
+pref("network.proxy.gopher", "");
+pref("network.proxy.gopher_port", 0);
+pref("network.proxy.http", "");
+pref("network.proxy.http_port", 0);
+pref("network.proxy.ssl", "");
+pref("network.proxy.ssl_port", 0);
+pref("network.proxy.socks", "");
+pref("network.proxy.socks_port", 0);
+pref("network.proxy.socks_version", 5);
+pref("network.proxy.socks_remote_dns", false);
+pref("network.proxy.no_proxies_on", "localhost, 127.0.0.1");
+pref("network.proxy.failover_timeout", 1800); // 30 minutes
+pref("network.online", true); //online/offline
+pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
+pref("network.cookie.disableCookieForMailNews", true); // disable all cookies for mail
+pref("network.cookie.lifetimePolicy", 0); // accept normally, 1-askBeforeAccepting, 2-acceptForSession,3-acceptForNDays
+pref("network.cookie.alwaysAcceptSessionCookies", false);
+pref("network.cookie.prefsMigrated", false);
+pref("network.cookie.lifetime.days", 90);
+
+// The PAC file to load. Ignored unless network.proxy.type is 2.
+pref("network.proxy.autoconfig_url", "");
+
+// If we cannot load the PAC file, then try again (doubling from interval_min
+// until we reach interval_max or the PAC file is successfully loaded).
+pref("network.proxy.autoconfig_retry_interval_min", 5); // 5 seconds
+pref("network.proxy.autoconfig_retry_interval_max", 300); // 5 minutes
+
+pref("converter.html2txt.structs", true); // Output structured phrases (strong, em, code, sub, sup, b, i, u)
+pref("converter.html2txt.header_strategy", 1); // 0 = no indention; 1 = indention, increased with header level; 2 = numbering and slight indention
+
+pref("intl.accept_languages", "chrome://global/locale/intl.properties");
+pref("intl.accept_charsets", "iso-8859-1,*,utf-8");
+pref("intl.menuitems.alwaysappendaccesskeys","chrome://global/locale/intl.properties");
+pref("intl.menuitems.insertseparatorbeforeaccesskeys","chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.static", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more1", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more2", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more3", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more4", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.more5", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.unicode", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.mailedit", "chrome://global/locale/intl.properties");
+pref("intl.charsetmenu.browser.cache", "");
+pref("intl.charsetmenu.mailview.cache", "");
+pref("intl.charsetmenu.composer.cache", "");
+pref("intl.charsetmenu.browser.cache.size", 5);
+pref("intl.charset.detector", "chrome://global/locale/intl.properties");
+pref("intl.charset.default", "chrome://global-platform/locale/intl.properties");
+pref("intl.ellipsis", "chrome://global-platform/locale/intl.properties");
+pref("intl.locale.matchOS", false);
+// fallback charset list for Unicode conversion (converting from Unicode)
+// currently used for mail send only to handle symbol characters (e.g Euro, trademark, smartquotes)
+// for ISO-8859-1
+pref("intl.fallbackCharsetList.ISO-8859-1", "windows-1252");
+pref("font.language.group", "chrome://global/locale/intl.properties");
+
+pref("font.mathfont-family", "STIXNonUnicode, STIXSize1, STIXGeneral, Standard Symbols L, DejaVu Sans, Cambria Math");
+
+// Some CJK fonts have bad underline offset, their CJK character glyphs are overlapped (or adjoined) to its underline.
+// These fonts are ignored the underline offset, instead of it, the underline is lowered to bottom of its em descent.
+pref("font.blacklist.underline_offset", "FangSong,Gulim,GulimChe,MingLiU,MingLiU-ExtB,MingLiU_HKSCS,MingLiU-HKSCS-ExtB,MS Gothic,MS Mincho,MS PGothic,MS PMincho,MS UI Gothic,PMingLiU,PMingLiU-ExtB,SimHei,SimSun,SimSun-ExtB,Hei,Kai,Apple LiGothic,Apple LiSung,Osaka");
+
+pref("images.dither", "auto");
+pref("security.directory", "");
+
+pref("signed.applets.codebase_principal_support", false);
+pref("security.checkloaduri", true);
+pref("security.xpconnect.plugin.unrestricted", true);
+// security-sensitive dialogs should delay button enabling. In milliseconds.
+pref("security.dialog_enable_delay", 2000);
+
+// Modifier key prefs: default to Windows settings,
+// menu access key = alt, accelerator key = control.
+// Use 17 for Ctrl, 18 for Alt, 224 for Meta, 0 for none. Mac settings in macprefs.js
+pref("ui.key.accelKey", 17);
+pref("ui.key.menuAccessKey", 18);
+pref("ui.key.generalAccessKey", -1);
+
+// If generalAccessKey is -1, use the following two prefs instead.
+// Use 0 for disabled, 1 for Shift, 2 for Ctrl, 4 for Alt, 8 for Meta
+// (values can be combined, e.g. 5 for Alt+Shift)
+pref("ui.key.chromeAccess", 4);
+pref("ui.key.contentAccess", 5);
+
+pref("ui.key.menuAccessKeyFocuses", false); // overridden below
+pref("ui.key.saveLink.shift", true); // true = shift, false = meta
+
+// Middle-mouse handling
+pref("middlemouse.paste", false);
+pref("middlemouse.openNewWindow", true);
+pref("middlemouse.contentLoadURL", false);
+pref("middlemouse.scrollbarPosition", false);
+
+// Clipboard behavior
+pref("clipboard.autocopy", false);
+
+// mouse wheel scroll transaction period of time (in milliseconds)
+pref("mousewheel.transaction.timeout", 1500);
+// mouse wheel scroll transaction is held even if the mouse cursor is moved.
+pref("mousewheel.transaction.ignoremovedelay", 100);
+
+// Macbook touchpad two finger pixel scrolling
+pref("mousewheel.enable_pixel_scrolling", true);
+
+// 0=lines, 1=pages, 2=history , 3=text size
+pref("mousewheel.withnokey.action",0);
+pref("mousewheel.withnokey.numlines",1);
+pref("mousewheel.withnokey.sysnumlines",true);
+pref("mousewheel.withcontrolkey.action",0);
+pref("mousewheel.withcontrolkey.numlines",1);
+pref("mousewheel.withcontrolkey.sysnumlines",true);
+// mousewheel.withshiftkey, see the Mac note below.
+pref("mousewheel.withshiftkey.action",0);
+pref("mousewheel.withshiftkey.numlines",1);
+pref("mousewheel.withshiftkey.sysnumlines",true);
+pref("mousewheel.withaltkey.action",2);
+pref("mousewheel.withaltkey.numlines",1);
+pref("mousewheel.withaltkey.sysnumlines",false);
+pref("mousewheel.withmetakey.action",0);
+pref("mousewheel.withmetakey.numlines",1);
+pref("mousewheel.withmetakey.sysnumlines",true);
+
+// activate horizontal scrolling by default
+pref("mousewheel.horizscroll.withnokey.action",0);
+pref("mousewheel.horizscroll.withnokey.numlines",1);
+pref("mousewheel.horizscroll.withnokey.sysnumlines",true);
+pref("mousewheel.horizscroll.withcontrolkey.action",0);
+pref("mousewheel.horizscroll.withcontrolkey.numlines",1);
+pref("mousewheel.horizscroll.withcontrolkey.sysnumlines",true);
+pref("mousewheel.horizscroll.withshiftkey.action",0);
+pref("mousewheel.horizscroll.withshiftkey.numlines",1);
+pref("mousewheel.horizscroll.withshiftkey.sysnumlines",true);
+pref("mousewheel.horizscroll.withaltkey.action",2);
+pref("mousewheel.horizscroll.withaltkey.numlines",-1);
+pref("mousewheel.horizscroll.withaltkey.sysnumlines",false);
+pref("mousewheel.horizscroll.withmetakey.action",0);
+pref("mousewheel.horizscroll.withmetakey.numlines",1);
+pref("mousewheel.horizscroll.withmetakey.sysnumlines",true);
+
+pref("profile.confirm_automigration",true);
+// profile.migration_behavior determines how the profiles root is set
+// 0 - use NS_APP_USER_PROFILES_ROOT_DIR
+// 1 - create one based on the NS4.x profile root
+// 2 - use, if not empty, profile.migration_directory otherwise same as 0
+pref("profile.migration_behavior",0);
+pref("profile.migration_directory", "");
+
+// the amount of time (in seconds) that must elapse
+// before we think your mozilla profile is defunct
+// and you'd benefit from re-migrating from 4.x
+// see bug #137886 for more details
+//
+// if -1, we never think your profile is defunct
+// and users will never see the remigrate UI.
+pref("profile.seconds_until_defunct", -1);
+// We can show it anytime from menus
+pref("profile.manage_only_at_launch", false);
+
+pref("prefs.converted-to-utf8",false);
+
+// --------------------------------------------------
+// IBMBIDI
+// --------------------------------------------------
+//
+// ------------------
+// Text Direction
+// ------------------
+// 1 = directionLTRBidi *
+// 2 = directionRTLBidi
+pref("bidi.direction", 1);
+// ------------------
+// Text Type
+// ------------------
+// 1 = charsettexttypeBidi *
+// 2 = logicaltexttypeBidi
+// 3 = visualtexttypeBidi
+pref("bidi.texttype", 1);
+// ------------------
+// Controls Text Mode
+// ------------------
+// 1 = logicalcontrolstextmodeBidiCmd
+// 2 = visualcontrolstextmodeBidi <-- NO LONGER SUPPORTED
+// 3 = containercontrolstextmodeBidi *
+pref("bidi.controlstextmode", 1);
+// ------------------
+// Numeral Style
+// ------------------
+// 0 = nominalnumeralBidi *
+// 1 = regularcontextnumeralBidi
+// 2 = hindicontextnumeralBidi
+// 3 = arabicnumeralBidi
+// 4 = hindinumeralBidi
+// 5 = persiancontextnumeralBidi
+// 6 = persiannumeralBidi
+pref("bidi.numeral", 0);
+// ------------------
+// Support Mode
+// ------------------
+// 1 = mozillaBidisupport *
+// 2 = OsBidisupport
+// 3 = disableBidisupport
+pref("bidi.support", 1);
+// ------------------
+// Charset Mode
+// ------------------
+// 1 = doccharactersetBidi *
+// 2 = defaultcharactersetBidi
+pref("bidi.characterset", 1);
+// Whether delete and backspace should immediately delete characters not
+// visually adjacent to the caret, or adjust the visual position of the caret
+// on the first keypress and delete the character on a second keypress
+pref("bidi.edit.delete_immediately", false);
+
+// Bidi caret movement style:
+// 0 = logical
+// 1 = visual
+// 2 = visual, but logical during selection
+pref("bidi.edit.caret_movement_style", 2);
+
+// Setting this pref to |true| forces Bidi UI menu items and keyboard shortcuts
+// to be exposed, and enables the directional caret hook. By default, only
+// expose it for bidi-associated system locales.
+pref("bidi.browser.ui", false);
+
+// used for double-click word selection behavior. Win will override.
+pref("layout.word_select.eat_space_to_next_word", false);
+pref("layout.word_select.stop_at_punctuation", true);
+
+// controls caret style and word-delete during text selection
+// 0 = use platform default
+// 1 = caret moves and blinks as when there is no selection; word
+// delete deselects the selection and then deletes word (Windows default)
+// 2 = caret moves to selection edge and is not visible during selection;
+// word delete deletes the selection (Mac default)
+// 3 = caret moves and blinks as when there is no selection; word delete
+// deletes the selection (Unix default)
+pref("layout.selection.caret_style", 0);
+
+// pref to control whether or not to replace backslashes with Yen signs
+// in documents encoded in one of Japanese legacy encodings (EUC-JP,
+// Shift_JIS, ISO-2022-JP)
+pref("layout.enable_japanese_specific_transform", false);
+
+// pref to force frames to be resizable
+pref("layout.frames.force_resizability", false);
+
+// pref to report CSS errors to the error console
+pref("layout.css.report_errors", true);
+
+// Should the :visited selector ever match (otherwise :link matches instead)?
+pref("layout.css.visited_links_enabled", true);
+
+// Override DPI. A value of -1 means use the maximum of 96 and the system DPI.
+// A value of 0 means use the system DPI. A positive value is used as the DPI.
+// This sets the physical size of a device pixel and thus controls the
+// interpretation of physical units such as "pt".
+pref("layout.css.dpi", -1);
+
+// Set the number of device pixels per CSS pixel. A value <= 0 means choose
+// automatically based on the DPI. A positive value is used as-is. This effectively
+// controls the size of a CSS "px". This is only used for pixel-based
+// (screen) output devices.
+pref("layout.css.devPixelsPerPx", -1);
+
+// pref for which side vertical scrollbars should be on
+// 0 = end-side in UI direction
+// 1 = end-side in document/content direction
+// 2 = right
+// 3 = left
+pref("layout.scrollbar.side", 0);
+
+// pref to permit users to make verified SOAP calls by default
+pref("capability.policy.default.SOAPCall.invokeVerifySourceHeader", "allAccess");
+
+// if true, allow plug-ins to override internal imglib decoder mime types in full-page mode
+pref("plugin.override_internal_types", false);
+pref("plugin.expose_full_path", false); // if true navigator.plugins reveals full path
+
+// See bug 136985. Gives embedders a pref to hook into to show
+// a popup blocker if they choose.
+pref("browser.popups.showPopupBlocker", true);
+
+// Pref to control whether the viewmanager code does double-buffering or not
+// See http://bugzilla.mozilla.org/show_bug.cgi?id=169483 for further details...
+pref("viewmanager.do_doublebuffering", true);
+
+// which files will be selected for roaming by default.
+// See sroaming/content/prefs/all.js
+pref("roaming.default.files", "bookmarks.html,abook.mab,cookies.txt");
+// display some general warning to the user about making backups, security etc.
+pref("roaming.showInitialWarning", true);
+
+// whether use prefs from system
+pref("config.use_system_prefs", false);
+
+// if the system has enabled accessibility
+pref("config.use_system_prefs.accessibility", false);
+
+// enable single finger gesture input (win7+ tablets)
+pref("gestures.enable_single_finger_input", true);
+
+/*
+ * What are the entities that you want Mozilla to save using mnemonic
+ * names rather than numeric codes? E.g. If set, we'll output &nbsp;
+ * otherwise, we may output 0xa0 depending on the charset.
+ *
+ * "none" : don't use any entity names; only use numeric codes.
+ * "basic" : use entity names just for &nbsp; &amp; &lt; &gt; &quot; for
+ * interoperability/exchange with products that don't support more
+ * than that.
+ * "latin1" : use entity names for 8bit accented letters and other special
+ * symbols between 128 and 255.
+ * "html" : use entity names for 8bit accented letters, greek letters, and
+ * other special markup symbols as defined in HTML4.
+ */
+//pref("editor.encode_entity", "html");
+
+pref("editor.resizing.preserve_ratio", true);
+pref("editor.positioning.offset", 0);
+
+// Disable slow script warnings for chrome by default - bug 492410
+pref("dom.max_chrome_script_run_time", 0);
+pref("dom.max_script_run_time", 10);
+
+pref("svg.enabled", true);
+
+pref("font.minimum-size.ar", 0);
+pref("font.minimum-size.x-armn", 0);
+pref("font.minimum-size.x-beng", 0);
+pref("font.minimum-size.x-baltic", 0);
+pref("font.minimum-size.x-central-euro", 0);
+pref("font.minimum-size.zh-CN", 0);
+pref("font.minimum-size.zh-HK", 0);
+pref("font.minimum-size.zh-TW", 0);
+pref("font.minimum-size.x-cyrillic", 0);
+pref("font.minimum-size.x-devanagari", 0);
+pref("font.minimum-size.x-ethi", 0);
+pref("font.minimum-size.x-geor", 0);
+pref("font.minimum-size.el", 0);
+pref("font.minimum-size.x-gujr", 0);
+pref("font.minimum-size.x-guru", 0);
+pref("font.minimum-size.he", 0);
+pref("font.minimum-size.ja", 0);
+pref("font.minimum-size.x-knda", 0);
+pref("font.minimum-size.x-khmr", 0);
+pref("font.minimum-size.ko", 0);
+pref("font.minimum-size.x-mlym", 0);
+pref("font.minimum-size.x-orya", 0);
+pref("font.minimum-size.x-sinh", 0);
+pref("font.minimum-size.x-tamil", 0);
+pref("font.minimum-size.x-telu", 0);
+pref("font.minimum-size.th", 0);
+pref("font.minimum-size.tr", 0);
+pref("font.minimum-size.x-cans", 0);
+pref("font.minimum-size.x-western", 0);
+pref("font.minimum-size.x-unicode", 0);
+pref("font.minimum-size.x-user-def", 0);
+
+//@line 1582 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+//@line 1999 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+//@line 2200 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+//@line 2294 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+//@line 2297 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+// Handled differently under Mac/Windows
+pref("network.hosts.smtp_server", "localhost");
+pref("network.hosts.pop_server", "pop");
+pref("network.protocol-handler.warn-external.file", false);
+pref("browser.drag_out_of_frame_style", 1);
+pref("editor.singleLine.pasteNewlines", 0);
+
+// Middle-mouse handling
+pref("middlemouse.paste", true);
+pref("middlemouse.contentLoadURL", true);
+pref("middlemouse.openNewWindow", true);
+pref("middlemouse.scrollbarPosition", true);
+
+// Clipboard behavior
+pref("clipboard.autocopy", true);
+
+pref("browser.urlbar.clickSelectsAll", false);
+
+// Tab focus model bit field:
+// 1 focuses text controls, 2 focuses other form elements, 4 adds links.
+// Leave this at the default, 7, to match mozilla1.0-era user expectations.
+// pref("accessibility.tabfocus", 1);
+
+// autocomplete keyboard grab workaround
+pref("autocomplete.grab_during_popup", true);
+pref("autocomplete.ungrab_during_mode_switch", true);
+
+// Default to using the system filepicker if possible, but allow
+// toggling to use the XUL filepicker
+pref("ui.allow_platform_file_picker", true);
+
+// should NetworkManager be authoritative for online/offline status?
+pref("toolkit.networkmanager.disable", true);
+
+pref("helpers.global_mime_types_file", "/etc/mime.types");
+pref("helpers.global_mailcap_file", "/etc/mailcap");
+pref("helpers.private_mime_types_file", "~/.mime.types");
+pref("helpers.private_mailcap_file", "~/.mailcap");
+pref("java.global_java_version_file", "/etc/.java/versions");
+pref("java.private_java_version_file", "~/.java/versions");
+pref("java.default_java_location_solaris", "/usr/j2se");
+pref("java.default_java_location_others", "/usr/java");
+pref("java.java_plugin_library_name", "javaplugin_oji");
+pref("applications.telnet", "xterm -e telnet %h %p");
+pref("applications.tn3270", "xterm -e tn3270 %h");
+pref("applications.rlogin", "xterm -e rlogin %h");
+pref("applications.rlogin_with_user", "xterm -e rlogin %h -l %u");
+pref("print.print_command", "lpr ${MOZ_PRINTER_NAME:+-P\"$MOZ_PRINTER_NAME\"}");
+pref("print.printer_list", ""); // list of printers, separated by spaces
+pref("print.print_reversed", false);
+pref("print.print_color", true);
+pref("print.print_landscape", false);
+pref("print.print_paper_size", 0);
+
+// print_extra_margin enables platforms to specify an extra gap or margin
+// around the content of the page for Print Preview only
+pref("print.print_extra_margin", 0); // twips
+
+pref("font.allow_double_byte_special_chars", true);
+// font names
+
+pref("font.alias-list", "sans,sans-serif,serif,monospace");
+
+// ar
+
+pref("font.name.serif.el", "serif");
+pref("font.name.sans-serif.el", "sans-serif");
+pref("font.name.monospace.el", "monospace");
+
+pref("font.name.serif.he", "serif");
+pref("font.name.sans-serif.he", "sans-serif");
+pref("font.name.monospace.he", "monospace");
+
+pref("font.name.serif.ja", "serif");
+pref("font.name.sans-serif.ja", "sans-serif");
+pref("font.name.monospace.ja", "monospace");
+
+pref("font.name.serif.ko", "serif");
+pref("font.name.sans-serif.ko", "sans-serif");
+pref("font.name.monospace.ko", "monospace");
+
+pref("font.name.serif.th", "serif");
+pref("font.name.sans-serif.th", "sans-serif");
+pref("font.name.monospace.th", "monospace");
+
+pref("font.name.serif.tr", "serif");
+pref("font.name.sans-serif.tr", "sans-serif");
+pref("font.name.monospace.tr", "monospace");
+
+pref("font.name.serif.x-baltic", "serif");
+pref("font.name.sans-serif.x-baltic", "sans-serif");
+pref("font.name.monospace.x-baltic", "monospace");
+
+pref("font.name.serif.x-central-euro", "serif");
+pref("font.name.sans-serif.x-central-euro", "sans-serif");
+pref("font.name.monospace.x-central-euro", "monospace");
+
+pref("font.name.serif.x-cyrillic", "serif");
+pref("font.name.sans-serif.x-cyrillic", "sans-serif");
+pref("font.name.monospace.x-cyrillic", "monospace");
+
+pref("font.name.serif.x-unicode", "serif");
+pref("font.name.sans-serif.x-unicode", "sans-serif");
+pref("font.name.monospace.x-unicode", "monospace");
+
+pref("font.name.serif.x-user-def", "serif");
+pref("font.name.sans-serif.x-user-def", "sans-serif");
+pref("font.name.monospace.x-user-def", "monospace");
+
+pref("font.name.serif.x-western", "serif");
+pref("font.name.sans-serif.x-western", "sans-serif");
+pref("font.name.monospace.x-western", "monospace");
+
+pref("font.name.serif.zh-CN", "serif");
+pref("font.name.sans-serif.zh-CN", "sans-serif");
+pref("font.name.monospace.zh-CN", "monospace");
+
+// ming_uni.ttf (HKSCS-2001)
+// http://www.info.gov.hk/digital21/eng/hkscs/download/uime.exe
+pref("font.name.serif.zh-HK", "serif");
+pref("font.name.sans-serif.zh-HK", "sans-serif");
+pref("font.name.monospace.zh-HK", "monospace");
+
+// zh-TW
+
+pref("font.default.ar", "sans-serif");
+pref("font.size.variable.ar", 16);
+pref("font.size.fixed.ar", 12);
+
+pref("font.default.el", "serif");
+pref("font.size.variable.el", 16);
+pref("font.size.fixed.el", 12);
+
+pref("font.default.he", "sans-serif");
+pref("font.size.variable.he", 16);
+pref("font.size.fixed.he", 12);
+
+pref("font.default.ja", "sans-serif");
+pref("font.size.variable.ja", 16);
+pref("font.size.fixed.ja", 16);
+
+pref("font.default.ko", "sans-serif");
+pref("font.size.variable.ko", 16);
+pref("font.size.fixed.ko", 16);
+
+pref("font.default.th", "serif");
+pref("font.size.variable.th", 16);
+pref("font.size.fixed.th", 13);
+pref("font.minimum-size.th", 13);
+
+pref("font.default.tr", "serif");
+pref("font.size.variable.tr", 16);
+pref("font.size.fixed.tr", 12);
+
+pref("font.default.x-baltic", "serif");
+pref("font.size.variable.x-baltic", 16);
+pref("font.size.fixed.x-baltic", 12);
+
+pref("font.default.x-central-euro", "serif");
+pref("font.size.variable.x-central-euro", 16);
+pref("font.size.fixed.x-central-euro", 12);
+
+pref("font.default.x-cyrillic", "serif");
+pref("font.size.variable.x-cyrillic", 16);
+pref("font.size.fixed.x-cyrillic", 12);
+
+pref("font.default.x-unicode", "serif");
+pref("font.size.variable.x-unicode", 16);
+pref("font.size.fixed.x-unicode", 12);
+
+pref("font.default.x-user-def", "serif");
+pref("font.size.variable.x-user-def", 16);
+pref("font.size.fixed.x-user-def", 12);
+
+pref("font.default.x-western", "serif");
+pref("font.size.variable.x-western", 16);
+pref("font.size.fixed.x-western", 12);
+
+pref("font.default.zh-CN", "sans-serif");
+pref("font.size.variable.zh-CN", 16);
+pref("font.size.fixed.zh-CN", 16);
+
+pref("font.default.zh-TW", "sans-serif");
+pref("font.size.variable.zh-TW", 16);
+pref("font.size.fixed.zh-TW", 16);
+
+pref("font.default.zh-HK", "sans-serif");
+pref("font.size.variable.zh-HK", 16);
+pref("font.size.fixed.zh-HK", 16);
+
+pref("font.default.x-devanagari", "serif");
+pref("font.size.variable.x-devanagari", 16);
+pref("font.size.fixed.x-devanagari", 13);
+
+pref("font.default.x-tamil", "serif");
+pref("font.size.variable.x-tamil", 16);
+pref("font.size.fixed.x-tamil", 13);
+
+pref("font.default.x-armn", "serif");
+pref("font.size.variable.x-armn", 16);
+pref("font.size.fixed.x-armn", 13);
+
+pref("font.default.x-beng", "serif");
+pref("font.size.variable.x-beng", 16);
+pref("font.size.fixed.x-beng", 13);
+
+pref("font.default.x-cans", "serif");
+pref("font.size.variable.x-cans", 16);
+pref("font.size.fixed.x-cans", 13);
+
+pref("font.default.x-ethi", "serif");
+pref("font.size.variable.x-ethi", 16);
+pref("font.size.fixed.x-ethi", 13);
+
+pref("font.default.x-geor", "serif");
+pref("font.size.variable.x-geor", 16);
+pref("font.size.fixed.x-geor", 13);
+
+pref("font.default.x-gujr", "serif");
+pref("font.size.variable.x-gujr", 16);
+pref("font.size.fixed.x-gujr", 13);
+
+pref("font.default.x-guru", "serif");
+pref("font.size.variable.x-guru", 16);
+pref("font.size.fixed.x-guru", 13);
+
+pref("font.default.x-khmr", "serif");
+pref("font.size.variable.x-khmr", 16);
+pref("font.size.fixed.x-khmr", 13);
+
+pref("font.default.x-mlym", "serif");
+pref("font.size.variable.x-mlym", 16);
+pref("font.size.fixed.x-mlym", 13);
+
+pref("font.default.x-orya", "serif");
+pref("font.size.variable.x-orya", 16);
+pref("font.size.fixed.x-orya", 13);
+
+pref("font.default.x-telu", "serif");
+pref("font.size.variable.x-telu", 16);
+pref("font.size.fixed.x-telu", 13);
+
+pref("font.default.x-knda", "serif");
+pref("font.size.variable.x-knda", 16);
+pref("font.size.fixed.x-knda", 13);
+
+pref("font.default.x-sinh", "serif");
+pref("font.size.variable.x-sinh", 16);
+pref("font.size.fixed.x-sinh", 13);
+
+/* PostScript print module prefs */
+// pref("print.postscript.enabled", true);
+pref("print.postscript.paper_size", "letter");
+pref("print.postscript.orientation", "portrait");
+pref("print.postscript.print_command", "lpr ${MOZ_PRINTER_NAME:+-P\"$MOZ_PRINTER_NAME\"}");
+
+// On GTK2 platform, we should use topmost window level for the default window
+// level of <panel> element of XUL. GTK2 has only two window types. One is
+// normal top level window, other is popup window. The popup window is always
+// topmost window level, therefore, we are using normal top level window for
+// non-topmost panel, but it is pretty hacky. On some Window Managers, we have
+// 2 problems:
+// 1. The non-topmost panel steals focus from its parent window at showing.
+// 2. The parent of non-topmost panel is not activated when the panel is hidden.
+// So, we have no reasons we should use non-toplevel window for popup.
+pref("ui.panel.default_level_parent", true);
+
+//@line 2567 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+//@line 2635 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+//@line 2661 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+//@line 2681 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+//@line 2689 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+// Login Manager prefs
+pref("signon.rememberSignons", true);
+pref("signon.expireMasterPassword", false);
+pref("signon.SignonFileName", "signons.txt"); // obsolete
+pref("signon.SignonFileName2", "signons2.txt"); // obsolete
+pref("signon.SignonFileName3", "signons3.txt"); // obsolete
+pref("signon.autofillForms", true);
+pref("signon.debug", false); // logs to Error Console
+
+// Zoom prefs
+pref("browser.zoom.full", false);
+pref("zoom.minPercent", 30);
+pref("zoom.maxPercent", 300);
+pref("toolkit.zoomManager.zoomValues", ".3,.5,.67,.8,.9,1,1.1,1.2,1.33,1.5,1.7,2,2.4,3");
+
+// Image cache prefs
+// The maximum size, in bytes, of the decoded images we cache
+pref("image.cache.size", 5242880);
+// A weight, from 0-1000, to place on time when comparing to size.
+// Size is given a weight of 1000 - timeweight.
+pref("image.cache.timeweight", 500);
+
+//@line 2718 "/builds/moz2_slave/linux_build/build/modules/libpref/src/init/all.js"
+
+// Enable/Disable the geolocation API for content
+pref("geo.enabled", true);
diff --git a/bundles/XO/greprefs/security-prefs.js b/bundles/XO/greprefs/security-prefs.js
new file mode 100755
index 0000000..cc43f33
--- /dev/null
+++ b/bundles/XO/greprefs/security-prefs.js
@@ -0,0 +1,74 @@
+pref("general.useragent.security", "U");
+
+pref("security.enable_ssl2", false);
+pref("security.enable_ssl3", true);
+pref("security.enable_tls", true);
+pref("security.enable_tls_session_tickets", true);
+
+pref("security.ssl2.rc4_128", false);
+pref("security.ssl2.rc2_128", false);
+pref("security.ssl2.des_ede3_192", false);
+pref("security.ssl2.des_64", false);
+pref("security.ssl2.rc4_40", false);
+pref("security.ssl2.rc2_40", false);
+pref("security.ssl3.rsa_rc4_128_md5", true);
+pref("security.ssl3.rsa_rc4_128_sha", true);
+pref("security.ssl3.rsa_fips_des_ede3_sha", true);
+pref("security.ssl3.rsa_des_ede3_sha", true);
+pref("security.ssl3.rsa_fips_des_sha", false);
+pref("security.ssl3.rsa_des_sha", false);
+pref("security.ssl3.rsa_1024_rc4_56_sha", false);
+pref("security.ssl3.rsa_1024_des_cbc_sha", false);
+pref("security.ssl3.rsa_rc4_40_md5", false);
+pref("security.ssl3.rsa_rc2_40_md5", false);
+pref("security.ssl3.dhe_rsa_camellia_256_sha", true);
+pref("security.ssl3.dhe_dss_camellia_256_sha", true);
+pref("security.ssl3.rsa_camellia_256_sha", true);
+pref("security.ssl3.dhe_rsa_camellia_128_sha", true);
+pref("security.ssl3.dhe_dss_camellia_128_sha", true);
+pref("security.ssl3.rsa_camellia_128_sha", true);
+pref("security.ssl3.dhe_rsa_aes_256_sha", true);
+pref("security.ssl3.dhe_dss_aes_256_sha", true);
+pref("security.ssl3.rsa_aes_256_sha", true);
+pref("security.ssl3.ecdhe_ecdsa_aes_256_sha", true);
+pref("security.ssl3.ecdhe_ecdsa_aes_128_sha", true);
+pref("security.ssl3.ecdhe_ecdsa_des_ede3_sha", true);
+pref("security.ssl3.ecdhe_ecdsa_rc4_128_sha", true);
+pref("security.ssl3.ecdhe_ecdsa_null_sha", false);
+pref("security.ssl3.ecdhe_rsa_aes_256_sha", true);
+pref("security.ssl3.ecdhe_rsa_aes_128_sha", true);
+pref("security.ssl3.ecdhe_rsa_des_ede3_sha", true);
+pref("security.ssl3.ecdhe_rsa_rc4_128_sha", true);
+pref("security.ssl3.ecdhe_rsa_null_sha", false);
+pref("security.ssl3.ecdh_ecdsa_aes_256_sha", true);
+pref("security.ssl3.ecdh_ecdsa_aes_128_sha", true);
+pref("security.ssl3.ecdh_ecdsa_des_ede3_sha", true);
+pref("security.ssl3.ecdh_ecdsa_rc4_128_sha", true);
+pref("security.ssl3.ecdh_ecdsa_null_sha", false);
+pref("security.ssl3.ecdh_rsa_aes_256_sha", true);
+pref("security.ssl3.ecdh_rsa_aes_128_sha", true);
+pref("security.ssl3.ecdh_rsa_des_ede3_sha", true);
+pref("security.ssl3.ecdh_rsa_rc4_128_sha", true);
+pref("security.ssl3.ecdh_rsa_null_sha", false);
+pref("security.ssl3.dhe_rsa_aes_128_sha", true);
+pref("security.ssl3.dhe_dss_aes_128_sha", true);
+pref("security.ssl3.rsa_aes_128_sha", true);
+pref("security.ssl3.dhe_rsa_des_ede3_sha", true);
+pref("security.ssl3.dhe_dss_des_ede3_sha", true);
+pref("security.ssl3.dhe_rsa_des_sha", false);
+pref("security.ssl3.dhe_dss_des_sha", false);
+pref("security.ssl3.rsa_null_sha", false);
+pref("security.ssl3.rsa_null_md5", false);
+
+pref("security.default_personal_cert", "Ask Every Time");
+pref("security.remember_cert_checkbox_default_setting", true);
+pref("security.ask_for_password", 0);
+pref("security.password_lifetime", 30);
+pref("security.warn_entering_secure", false);
+pref("security.warn_entering_weak", true);
+pref("security.warn_leaving_secure", false);
+pref("security.warn_viewing_mixed", true);
+pref("security.warn_submit_insecure", false);
+
+pref("security.OCSP.enabled", 1);
+pref("security.OCSP.require", false);
diff --git a/bundles/XO/greprefs/xpinstall.js b/bundles/XO/greprefs/xpinstall.js
new file mode 100755
index 0000000..0642733
--- /dev/null
+++ b/bundles/XO/greprefs/xpinstall.js
@@ -0,0 +1,2 @@
+pref("xpinstall.enabled", true);
+pref("xpinstall.whitelist.required", true);
diff --git a/bundles/XO/icons/document.png b/bundles/XO/icons/document.png
new file mode 100755
index 0000000..92628bd
--- /dev/null
+++ b/bundles/XO/icons/document.png
Binary files differ
diff --git a/bundles/XO/icons/mozicon128.png b/bundles/XO/icons/mozicon128.png
new file mode 100755
index 0000000..f82ea67
--- /dev/null
+++ b/bundles/XO/icons/mozicon128.png
Binary files differ
diff --git a/bundles/XO/icons/mozicon16.xpm b/bundles/XO/icons/mozicon16.xpm
new file mode 100755
index 0000000..de6229b
--- /dev/null
+++ b/bundles/XO/icons/mozicon16.xpm
@@ -0,0 +1,191 @@
+/* XPM */
+static char * mozicon16_xpm[] = {
+"16 16 172 2",
+" c None",
+". c #8B93A9",
+"+ c #5E6882",
+"@ c #666F89",
+"# c #818C9B",
+"$ c #9A9D91",
+"% c #8D825A",
+"& c #898179",
+"* c #D57330",
+"= c #D29C70",
+"- c #6A7287",
+"; c #845033",
+"> c #D88533",
+", c #6CB6DD",
+"' c #6AAED8",
+") c #4578A2",
+"! c #65797D",
+"~ c #F4DA6B",
+"{ c #FFE26D",
+"] c #A88459",
+"^ c #DC7630",
+"/ c #F0B476",
+"( c #ED9029",
+"_ c #E68127",
+": c #ED9638",
+"< c #4F89AF",
+"[ c #69ACD4",
+"} c #689DBC",
+"| c #678A9C",
+"1 c #9A8C64",
+"2 c #FFDF68",
+"3 c #B88D49",
+"4 c #EBB47D",
+"5 c #DC742A",
+"6 c #EEAA64",
+"7 c #7C5B3C",
+"8 c #416989",
+"9 c #4D91BA",
+"0 c #7AB8D5",
+"a c #6093B5",
+"b c #417098",
+"c c #8E8C71",
+"d c #C0612B",
+"e c #E56A17",
+"f c #EE871E",
+"g c #EAA472",
+"h c #EAA576",
+"i c #45586D",
+"j c #3B769E",
+"k c #57A6D1",
+"l c #388CBF",
+"m c #2B6E9B",
+"n c #E9AC36",
+"o c #DB9C40",
+"p c #E36615",
+"q c #ED8119",
+"r c #EE8324",
+"s c #FBA159",
+"t c #8F6F5B",
+"u c #1C527D",
+"v c #256895",
+"w c #2A9CCE",
+"x c #3A9FCC",
+"y c #226690",
+"z c #226999",
+"A c #C89638",
+"B c #FFD85D",
+"C c #EAA83A",
+"D c #BC612E",
+"E c #D16628",
+"F c #504341",
+"G c #1F476B",
+"H c #256F9A",
+"I c #0688C5",
+"J c #174E78",
+"K c #204D72",
+"L c #B48135",
+"M c #E9B244",
+"N c #AB6049",
+"O c #EC7A19",
+"P c #D46B2C",
+"Q c #7E5134",
+"R c #254C6C",
+"S c #B15F22",
+"T c #7C543A",
+"U c #1D5C89",
+"V c #066EB1",
+"W c #124470",
+"X c #D59235",
+"Y c #FFDB60",
+"Z c #D79936",
+"` c #8B5E64",
+" . c #D14E14",
+".. c #E87715",
+"+. c #EE7E13",
+"@. c #E07D2E",
+"#. c #ED862D",
+"$. c #EFA056",
+"%. c #454958",
+"&. c #0A528F",
+"*. c #0A518A",
+"=. c #474F4F",
+"-. c #E1AD3C",
+";. c #FFD648",
+">. c #CA8734",
+",. c #AA979E",
+"'. c #944531",
+"). c #E3660E",
+"!. c #F0821D",
+"~. c #984922",
+"{. c #472F37",
+"]. c #0D4577",
+"^. c #176CA1",
+"/. c #164168",
+"(. c #D78933",
+"_. c #FDCF48",
+":. c #615C5E",
+"<. c #A2685F",
+"[. c #C54012",
+"}. c #E36A0F",
+"|. c #4A5762",
+"1. c #804D37",
+"2. c #FEA53D",
+"3. c #FFCD62",
+"4. c #83592C",
+"5. c #C7C3C2",
+"6. c #BA9B9A",
+"7. c #96352B",
+"8. c #C63509",
+"9. c #D95810",
+"0. c #E67115",
+"a. c #F4992D",
+"b. c #F5A22D",
+"c. c #FBBE3C",
+"d. c #C86F2D",
+"e. c #746C71",
+"f. c #986F75",
+"g. c #7E1316",
+"h. c #B91807",
+"i. c #CF3C09",
+"j. c #D5470E",
+"k. c #DE5E14",
+"l. c #E57121",
+"m. c #E37A26",
+"n. c #B36426",
+"o. c #494453",
+"p. c #C9C6C7",
+"q. c #856D7C",
+"r. c #572231",
+"s. c #83080B",
+"t. c #A70C07",
+"u. c #A8100A",
+"v. c #AA180C",
+"w. c #AF2210",
+"x. c #B41C0A",
+"y. c #4B2623",
+"z. c #484D62",
+"A. c #B7B4B6",
+"B. c #A69EA5",
+"C. c #705D70",
+"D. c #41324B",
+"E. c #251A3C",
+"F. c #1E193B",
+"G. c #322846",
+"H. c #43425C",
+"I. c #8E8A96",
+"J. c #B8B8BB",
+"K. c #A4A2A7",
+"L. c #96959D",
+"M. c #9B9CA7",
+"N. c #A0A1AA",
+"O. c #ACAEB6",
+" . + @ # $ % & ",
+" * = - ; > , ' ) ! ~ { ] ",
+" ^ / ( _ : ] < [ } | 1 { 2 3 ",
+"4 5 ( ( ( 6 7 8 9 0 a b c { 2 ",
+"d e ( ( f g h i j k k l m n 2 o ",
+"d p q f r s t u v w x y z A B C ",
+"D p q q E F G u H I y J K L B M ",
+"N p O O P Q R S T U V W R X Y Z ",
+"` ...+.r r @.#.$.%.&.*.=.-.;.>.",
+",.'.).O !.+.~.{.].^./.F (.{ _.:.",
+" <.[.}.r +.O F R |.1.2.B 3.4.5.",
+" 6.7.8.9.0...O a.a.a.b.c.d.e. ",
+" f.g.h.8.i.j.k.l.m._ n.o.p. ",
+" q.r.s.t.u.v.w.x.y.z.A. ",
+" B.C.D.E.F.G.H.I.J. ",
+" K.L.M.N.O. "};
diff --git a/bundles/XO/icons/mozicon50.xpm b/bundles/XO/icons/mozicon50.xpm
new file mode 100755
index 0000000..ce4a3cd
--- /dev/null
+++ b/bundles/XO/icons/mozicon50.xpm
@@ -0,0 +1,299 @@
+/* XPM */
+static char * default_xpm[] = {
+"48 48 248 2",
+" c None",
+". c #7980B8",
+"+ c #5269AA",
+"@ c #133988",
+"# c #155AA7",
+"$ c #1181BC",
+"% c #13508E",
+"& c #2773AF",
+"* c #6976B1",
+"= c #146CAB",
+"- c #1785C4",
+"; c #35A7E4",
+"> c #5988A8",
+", c #1A639C",
+"' c #618380",
+") c #7F896D",
+"! c #576768",
+"~ c #414E6D",
+"{ c #2882BB",
+"] c #36A2DD",
+"^ c #41AEE7",
+"/ c #2D8FCF",
+"( c #2A4D6F",
+"_ c #DDC563",
+": c #FDFA57",
+"< c #F7CC2C",
+"[ c #D0A634",
+"} c #EEB88A",
+"| c #E86918",
+"1 c #40A3DD",
+"2 c #296599",
+"3 c #23568D",
+"4 c #164778",
+"5 c #16395A",
+"6 c #072558",
+"7 c #2C3B4D",
+"8 c #9D8D2F",
+"9 c #F8D801",
+"0 c #FAE800",
+"a c #F6B704",
+"b c #FBD46D",
+"c c #A5A5C9",
+"d c #062C70",
+"e c #061646",
+"f c #0A2E62",
+"g c #123D74",
+"h c #6D6D6C",
+"i c #A99269",
+"j c #EDB16B",
+"k c #BABCA3",
+"l c #907241",
+"m c #B27A1C",
+"n c #F69B08",
+"o c #F6A706",
+"p c #F7A613",
+"q c #E15707",
+"r c #E58836",
+"s c #AE99A3",
+"t c #111A54",
+"u c #05122B",
+"v c #061538",
+"w c #142646",
+"x c #17334F",
+"y c #4F4B50",
+"z c #D28D3D",
+"A c #F0AC4C",
+"B c #756D57",
+"C c #CEA753",
+"D c #FDE55B",
+"E c #FEFA7A",
+"F c #F9E641",
+"G c #F9C617",
+"H c #FCD9A3",
+"I c #E98B66",
+"J c #D64804",
+"K c #E17B25",
+"L c #D86A27",
+"M c #685049",
+"N c #795B48",
+"O c #635B5B",
+"P c #E48529",
+"Q c #E99737",
+"R c #B8832E",
+"S c #214357",
+"T c #45402F",
+"U c #CB8F1C",
+"V c #FCF604",
+"W c #F7C603",
+"X c #FBE5B6",
+"Y c #E36743",
+"Z c #D63003",
+"` c #E99C4C",
+" . c #E17919",
+".. c #172B5B",
+"+. c #202A74",
+"@. c #0D223C",
+"#. c #7F5A1C",
+"$. c #FDE56F",
+"%. c #D15D41",
+"&. c #B83404",
+"*. c #D9782A",
+"=. c #E27A06",
+"-. c #277BC4",
+";. c #624B23",
+">. c #FBD659",
+",. c #F1E084",
+"'. c #DE7317",
+"). c #E99725",
+"!. c #F6B12B",
+"~. c #EEA716",
+"{. c #EB9515",
+"]. c #E68714",
+"^. c #CC590A",
+"/. c #192963",
+"(. c #66572F",
+"_. c #E9A603",
+":. c #AC320A",
+"<. c #8D564E",
+"[. c #4F6E8B",
+"}. c #4A9DC9",
+"|. c #FEFE92",
+"1. c #D95708",
+"2. c #4D2B18",
+"3. c #E79209",
+"4. c #FEFA86",
+"5. c #FDE6A6",
+"6. c #E6880C",
+"7. c #DA6917",
+"8. c #A4853C",
+"9. c #D47350",
+"0. c #CAAE8C",
+"a. c #D1B76B",
+"b. c #FCE424",
+"c. c #F08F0D",
+"d. c #FBEA3A",
+"e. c #0B345A",
+"f. c #836735",
+"g. c #AB8B53",
+"h. c #FEFD25",
+"i. c #B9571B",
+"j. c #C15822",
+"k. c #B66F38",
+"l. c #971703",
+"m. c #532725",
+"n. c #C09123",
+"o. c #FEFD39",
+"p. c #F9B517",
+"q. c #FAC94B",
+"r. c #A52504",
+"s. c #38313D",
+"t. c #9A8854",
+"u. c #FEFC17",
+"v. c #F9CA59",
+"w. c #D35B23",
+"x. c #B92707",
+"y. c #113A6F",
+"z. c #CC4621",
+"A. c #BE4910",
+"B. c #CD9750",
+"C. c #C12A11",
+"D. c #C8470A",
+"E. c #C63605",
+"F. c #A46F48",
+"G. c #C97A36",
+"H. c #89978D",
+"I. c #0F3C75",
+"J. c #A70209",
+"K. c #D35615",
+"L. c #E0650A",
+"M. c #BC7036",
+"N. c #0E3468",
+"O. c #9A1124",
+"P. c #25317F",
+"Q. c #FCDB47",
+"R. c #9B4967",
+"S. c #D77707",
+"T. c #CE5D15",
+"U. c #A84515",
+"V. c #342222",
+"W. c #0A2543",
+"X. c #A57736",
+"Y. c #F9D515",
+"Z. c #662817",
+"`. c #040B26",
+" + c #A06E32",
+".+ c #C19471",
+"++ c #970314",
+"@+ c #D04911",
+"#+ c #7E240E",
+"$+ c #2D212E",
+"%+ c #020935",
+"&+ c #6C4538",
+"*+ c #875F39",
+"=+ c #FFFE6A",
+"-+ c #883F67",
+";+ c #291B1D",
+">+ c #00071F",
+",+ c #5C393C",
+"'+ c #FEF2AE",
+")+ c #FEFD4E",
+"!+ c #CC9438",
+"~+ c #B50501",
+"{+ c #8B4B22",
+"]+ c #7D4224",
+"^+ c #FFFFC6",
+"/+ c #BF9E8E",
+"(+ c #762C5A",
+"_+ c #C93B10",
+":+ c #8B4E30",
+"<+ c #543C54",
+"[+ c #C66823",
+"}+ c #D29A1D",
+"|+ c #8E041A",
+"1+ c #BC652C",
+"2+ c #AE5B2C",
+"3+ c #AF9393",
+"4+ c #6E447E",
+"5+ c #C11E00",
+"6+ c #C32907",
+"7+ c #FAE217",
+"8+ c #650E41",
+"9+ c #DF7931",
+"0+ c #D86407",
+"a+ c #7B0727",
+"b+ c #DE9005",
+"c+ c #DC8505",
+"d+ c #EAB402",
+"e+ c #EDC602",
+"f+ c #A0776B",
+"g+ c #B9140C",
+"h+ c #C94617",
+"i+ c #D04F22",
+"j+ c #9C706E",
+"k+ c #91697A",
+"l+ c #850520",
+"m+ c #79495B",
+"n+ c #551D5F",
+"o+ c #655191",
+"p+ c #560D43",
+"q+ c #81142A",
+"r+ c #A81615",
+"s+ c #A8371E",
+"t+ c #8D362F",
+"u+ c #632C4A",
+"v+ c #563D7B",
+"w+ c #453786",
+"x+ c #471552",
+"y+ c #3C185B",
+" ",
+" ",
+" . + @ # # $ # % @ & * ",
+" + @ = $ $ $ - ; ; $ = = = = = @ > ",
+" + = $ $ $ $ $ $ ; ; ; - = # # , ' ) ! ~ ~ ",
+" + % = = = = & & & { ] ^ ^ ; / = , % ( ! ) _ : < [ } ",
+" | @ % % % % , , , , & & 1 ^ ^ ^ / & 2 3 4 5 6 6 7 8 9 0 a b ",
+" | | } c d 6 e f g 4 4 h i j k & / ^ ^ ^ ^ { & 2 3 ( l m m n n o a a p ",
+" q | r s t e u v w x y z A A i ( 3 / ^ ^ ^ 1 { & & & 2 ~ B C D E F G o n n H ",
+" I J | K L M N y x 7 O P Q Q R x S & 1 ^ ^ { { & & & { 2 3 ( 5 T U < V V W n p X b ",
+" Y Z J K j j j j j b ` .K Q y ..+./ ^ / & & { & { / ^ 1 & ( 5 w @.#.o 9 9 9 o A $. ",
+" %.&.*.j A j A A Q Q K =. . .4 & -.] ^ -.-.& / ; ^ ^ ^ ^ / 3 3 ( ..w ;.n W W a n >.,. ",
+" %.'.` ` A ).!.~.{.].=.=.'.^.y -.-.1 ^ ^ ] / ; ; ; ; ^ ^ 1 & 2 3 ( /.w (.n a _.o !.$. ",
+" *.Q Q Q ~.~.{.{.].]. .'.'.^.:.<.[.> }.}.; ; ; ; ; ; ; ; ^ ^ { 3 { 2 3 S m n _.n !.|.X ",
+" } P Q ~.{.{.{.].{.].]. . .'.1.:.J 1.q q 2.{ ] ; ; ; / ; ; ; ; 1 ] 1 1 { 2 S 3.n 3.n 4.5. ",
+" Q ).).{.{.6.].].].K ]. .'.7.7.&.1.J q K i / ] ; ; ; ; ] / ] ] ] ] ] ] / & 8.m n !.o : $. ",
+" Q ).].3.].].].].]. . .K '.K K 9.X X } 0.[.$ ] ] / ] ] { = , { / / / / / $ a.[ n $.a V b. ",
+" j Q {.{.3.c.].].].]. . .'.| K K ` } j h 5 % - ; / $ { / / , , , { / / / / & i E c.$.d.0 9 ",
+" Q ).].3.].].].].K . .'. .K K Q r I 7 e.% = / / - # , = { , , , , / / / -.3 f.E < $.D 9 W b ",
+"j Q ).].{.].].].].]. . .'.K P Q Q A g.f @ = / / ; / = , & , , , , , & / -., @ f.h.G $.4.9 W !. ",
+"` r ].{.{.6.].].].K .'. .P r Q ` A C @ # = - / / / = , , , , , , % { / { # % l 0 9 4.|.G a !. ",
+"` ).].3.].6.].c. . . .K L i.j.j.k.C b % # $ -./ / / -., , , , , 3 % , { = , & R 9 W E |.< o !. ",
+"j P ].3.].6.].K . .7.:.l.l.l.m.@.@.( @ # = -./ / / / / & , , 3 % % % % 4 ! & n.W G o.: p.n q. ",
+"j K ].c.6.]. . . .'.r.l.l.l.r.s.f f f @ # = -.-./ -./ / 3 , , 3 % % % % 4 a.t.o o W V u.p.!.v. ",
+"9.w.=.].]. . . . .7.l.l.r.r.x.N 4 @ @ # & -.-.-.-.{ -./ % 3 % % % @ % 4 y.C q.n n 9 0 V a >._ ",
+"9.z.'. .K . .'.7.A.r.r.x.&.&. .O # # 2 & -.-.-.-.-.-.{ & % % 4 % 4 4 @ 4 B.E n n 9 9 0 p 4.j ",
+" C.'.'. .K '.'.K D.:.&.&.E.E.7. .F.2 # # 2 h G.r A a.H.{ % 4 4 I.4 I.I., B.|.!.o W 9 9 q.|.j ",
+" J.7. .'.'.'.'.'.K.E.E.D.J J L.'.K 7.M.M.'.K '.K r A ,.H.4 4 y.N.y.N.N.3 [ |.q.a a W G 4.$. ",
+" O.K.'.'.L. .'.K '.D.Z J J q q '.'.K 7.'.'. . . .7.7.j g.I.y.f f 6 6 P.3 !.E Q.o < a >.|.>. ",
+" R.z.w.'.S.'.'.'.| 7.q q q q q &.A.7.'.K '.L T.A.U.V.u W.e.N.6 t e w X.O Y.h.G n v.p.4.|.C ",
+" x.L L.'.'.'.'. .7. .q q L.q K.l.l.l.r.r.:.:.Z.`.`.u e t t e e e + + +9 V W n b D 4.4..+ ",
+" ++L @+'.'.S.'. .'.'.'.L.L.L.L.D.l.l.r.#+Z.$+@.u %+v e e e %+e &+6.*+n 9 9 a q.4.: =+Q. ",
+" -+z.E. .'.'.S.L.'. .L. .7.'.L. .i.;+>+>+u w /.%+%+e e %+%+%+,+ .].c.a W W o '+)+o.)+!+ ",
+" J.~+7.'.'.'.'.'.'.S.L. .L.'. .7. .{+v %+/.t %+%+%+%+%+%+]+| L .c._._._.v.^+V u.b./+ ",
+" (+~+_+K 1.'.'. .'.'.S.'.'.S.L. .'.'.'.:+<+P.+.t %+%+m.[+'.'.'.'.6.3.3.~.|.4.V V }+ ",
+" |+~+@+7.7.'.K '.'.'.'.'.'.S.=.L.'.'.'.'.'.1+2+[+ . .'.'. . .'.=.=.=.d.E d.0 9 3+ ",
+" 4+~+5+K.6+7.K P 7. .'.'.'.'.'.'.'.'.'.'. .'.'.7.K 7.K 7. .7.L.L.S.7+o.: 9 9 R ",
+" 8+~+5+J 5+K.9+K C.1.'. . .'.'.L.'. .K K P r r r r r K 7.q 0+S.9 V h.Y.9 _. ",
+" a+~+6+Z ~+6+r 9+~+E.7.K K 7.K. .'.K K K K K K '.'.'.0+0+b+9 0 V V W a 3+ ",
+" ++~+E.6+~+~+z.r C.~+_+w.P 9+K.@+K.7.'.'. . .'.7.0+c+_.d+e+0 0 e+_.f+ ",
+" ++~+6+5+~+~+g+z.g+g+g+C.h+%.r L i+@+@+T.T.0+S.c+b+_.d+e+e+e+3.j+ ",
+" a+~+~+~+~+~+~+g+g+g+g+g+g+g+_+h+w._+D.^.^.0+S.c+b+d+d+_.'.k+ ",
+" 8+J.~+~+~+~+g+g+g+g+g+g+g+g+C.6+&.D.D.^.0+S.S.b+3.].2+ ",
+" l+~+~+~+g+~+g+g+g+g+g+g+C.C.6+_+D.D.^.0+S.S.[+m+ ",
+" n+a+~+g+g+g+g+g+g+g+g+g+C.6+E._+D.^.0+2+m+ ",
+" o+p+q+r+g+g+g+g+g+g+x.C.E.s+t+u+v+ ",
+" w+x+x+x+x+x+x+y+w+ ",
+" "};
diff --git a/bundles/XO/icons/updater.png b/bundles/XO/icons/updater.png
new file mode 100755
index 0000000..7b5e789
--- /dev/null
+++ b/bundles/XO/icons/updater.png
Binary files differ
diff --git a/bundles/XO/karma/AUTHORS b/bundles/XO/karma/AUTHORS
new file mode 100755
index 0000000..6dea4c3
--- /dev/null
+++ b/bundles/XO/karma/AUTHORS
@@ -0,0 +1,3 @@
+Bryan Berry <bryan@olenepal.org>
+Felipe Lopez Toledo <zer.subzero@gmail.com>
+Christoph Derndorfer <christoph@olpcnews.com>
diff --git a/bundles/XO/karma/COPYING b/bundles/XO/karma/COPYING
new file mode 100755
index 0000000..511860a
--- /dev/null
+++ b/bundles/XO/karma/COPYING
@@ -0,0 +1,25 @@
+Copyright (c) 2009 Bryan Willson Berry
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+This is the MIT license
+From http://www.opensource.org/licenses/mit-license.php \ No newline at end of file
diff --git a/bundles/XO/karma/assets/default/images/back.png b/bundles/XO/karma/assets/default/images/back.png
new file mode 100755
index 0000000..fbb0910
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/back.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/back_bw.png b/bundles/XO/karma/assets/default/images/back_bw.png
new file mode 100755
index 0000000..126380d
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/back_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/chakra_logo.png b/bundles/XO/karma/assets/default/images/chakra_logo.png
new file mode 100755
index 0000000..b7f9b3a
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/chakra_logo.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/chakra_logo_50x50.png b/bundles/XO/karma/assets/default/images/chakra_logo_50x50.png
new file mode 100755
index 0000000..0eadda2
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/chakra_logo_50x50.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/english.png b/bundles/XO/karma/assets/default/images/english.png
new file mode 100755
index 0000000..6a3eaab
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/english.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/exercise.png b/bundles/XO/karma/assets/default/images/exercise.png
new file mode 100755
index 0000000..ebb2ead
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/exercise.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/exercise_bw.png b/bundles/XO/karma/assets/default/images/exercise_bw.png
new file mode 100755
index 0000000..e2cf4f7
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/exercise_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/favicon.ico b/bundles/XO/karma/assets/default/images/favicon.ico
new file mode 100755
index 0000000..20bf7f1
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/favicon.ico
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/games.png b/bundles/XO/karma/assets/default/images/games.png
new file mode 100755
index 0000000..a7177f2
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/games.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/games_bw.png b/bundles/XO/karma/assets/default/images/games_bw.png
new file mode 100755
index 0000000..fd3c3cb
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/games_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/geography.png b/bundles/XO/karma/assets/default/images/geography.png
new file mode 100755
index 0000000..3a9a2dc
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/geography.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade1.png b/bundles/XO/karma/assets/default/images/grade1.png
new file mode 100755
index 0000000..2e27b65
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade1.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade1_bw.png b/bundles/XO/karma/assets/default/images/grade1_bw.png
new file mode 100755
index 0000000..0034ace
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade1_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade2.png b/bundles/XO/karma/assets/default/images/grade2.png
new file mode 100755
index 0000000..496d0d2
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade2.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade2_bw.png b/bundles/XO/karma/assets/default/images/grade2_bw.png
new file mode 100755
index 0000000..28eb7c0
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade2_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade3.png b/bundles/XO/karma/assets/default/images/grade3.png
new file mode 100755
index 0000000..8248bf0
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade3.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade3_bw.png b/bundles/XO/karma/assets/default/images/grade3_bw.png
new file mode 100755
index 0000000..0e8cd09
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade3_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade4.png b/bundles/XO/karma/assets/default/images/grade4.png
new file mode 100755
index 0000000..25ac532
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade4.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade4_bw.png b/bundles/XO/karma/assets/default/images/grade4_bw.png
new file mode 100755
index 0000000..c597442
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade4_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade5.png b/bundles/XO/karma/assets/default/images/grade5.png
new file mode 100755
index 0000000..1ad416a
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade5.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade5_bw.png b/bundles/XO/karma/assets/default/images/grade5_bw.png
new file mode 100755
index 0000000..a8a9d8a
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade5_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade6.png b/bundles/XO/karma/assets/default/images/grade6.png
new file mode 100755
index 0000000..26e6f9b
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade6.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade6_bw.png b/bundles/XO/karma/assets/default/images/grade6_bw.png
new file mode 100755
index 0000000..07e6e0d
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade6_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade7.png b/bundles/XO/karma/assets/default/images/grade7.png
new file mode 100755
index 0000000..333b61e
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade7.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade7_bw.png b/bundles/XO/karma/assets/default/images/grade7_bw.png
new file mode 100755
index 0000000..6ff1dd1
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade7_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade8.png b/bundles/XO/karma/assets/default/images/grade8.png
new file mode 100755
index 0000000..77542a7
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade8.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/grade8_bw.png b/bundles/XO/karma/assets/default/images/grade8_bw.png
new file mode 100755
index 0000000..15b3be7
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/grade8_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/health.png b/bundles/XO/karma/assets/default/images/health.png
new file mode 100755
index 0000000..305c8d0
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/health.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/help.png b/bundles/XO/karma/assets/default/images/help.png
new file mode 100755
index 0000000..9209167
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/help.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/help_50x50.png b/bundles/XO/karma/assets/default/images/help_50x50.png
new file mode 100755
index 0000000..ade47a7
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/help_50x50.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/history.png b/bundles/XO/karma/assets/default/images/history.png
new file mode 100755
index 0000000..79a79c0
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/history.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/karma_logo.png b/bundles/XO/karma/assets/default/images/karma_logo.png
new file mode 100755
index 0000000..fa04651
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/karma_logo.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/karma_logo_35x32.png b/bundles/XO/karma/assets/default/images/karma_logo_35x32.png
new file mode 100755
index 0000000..790ed88
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/karma_logo_35x32.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/karma_logo_50x46.png b/bundles/XO/karma/assets/default/images/karma_logo_50x46.png
new file mode 100755
index 0000000..19dfd91
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/karma_logo_50x46.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/karma_logo_54x50.png b/bundles/XO/karma/assets/default/images/karma_logo_54x50.png
new file mode 100755
index 0000000..6f6842d
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/karma_logo_54x50.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/mathematics.png b/bundles/XO/karma/assets/default/images/mathematics.png
new file mode 100755
index 0000000..e8a6ee2
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/mathematics.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_A.png b/bundles/XO/karma/assets/default/images/month_A.png
new file mode 100755
index 0000000..a8b02a4
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_A.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_B.png b/bundles/XO/karma/assets/default/images/month_B.png
new file mode 100755
index 0000000..908c64f
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_B.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_C.png b/bundles/XO/karma/assets/default/images/month_C.png
new file mode 100755
index 0000000..d4a0ae1
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_C.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_D.png b/bundles/XO/karma/assets/default/images/month_D.png
new file mode 100755
index 0000000..a8b1f28
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_D.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_E.png b/bundles/XO/karma/assets/default/images/month_E.png
new file mode 100755
index 0000000..3fa8a05
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_E.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_F.png b/bundles/XO/karma/assets/default/images/month_F.png
new file mode 100755
index 0000000..0daa502
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_F.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_G.png b/bundles/XO/karma/assets/default/images/month_G.png
new file mode 100755
index 0000000..77e2f7c
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_G.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_H.png b/bundles/XO/karma/assets/default/images/month_H.png
new file mode 100755
index 0000000..3a99b7c
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_H.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_I.png b/bundles/XO/karma/assets/default/images/month_I.png
new file mode 100755
index 0000000..4931ec1
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_I.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_J.png b/bundles/XO/karma/assets/default/images/month_J.png
new file mode 100755
index 0000000..ee11c0d
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_J.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_K.png b/bundles/XO/karma/assets/default/images/month_K.png
new file mode 100755
index 0000000..16a0dcc
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_K.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/month_L.png b/bundles/XO/karma/assets/default/images/month_L.png
new file mode 100755
index 0000000..2beef36
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/month_L.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/music.png b/bundles/XO/karma/assets/default/images/music.png
new file mode 100755
index 0000000..0530497
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/music.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/mystuff.png b/bundles/XO/karma/assets/default/images/mystuff.png
new file mode 100755
index 0000000..40d3dba
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/mystuff.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/nepali.png b/bundles/XO/karma/assets/default/images/nepali.png
new file mode 100755
index 0000000..08b82a7
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/nepali.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/olenepal_logo.gif b/bundles/XO/karma/assets/default/images/olenepal_logo.gif
new file mode 100755
index 0000000..e520424
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/olenepal_logo.gif
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/preview1.jpg b/bundles/XO/karma/assets/default/images/preview1.jpg
new file mode 100755
index 0000000..9801ffb
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/preview1.jpg
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/preview2.jpg b/bundles/XO/karma/assets/default/images/preview2.jpg
new file mode 100755
index 0000000..41762a2
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/preview2.jpg
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/preview3.jpg b/bundles/XO/karma/assets/default/images/preview3.jpg
new file mode 100755
index 0000000..385bef2
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/preview3.jpg
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/preview4.jpg b/bundles/XO/karma/assets/default/images/preview4.jpg
new file mode 100755
index 0000000..e75def8
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/preview4.jpg
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/profile.png b/bundles/XO/karma/assets/default/images/profile.png
new file mode 100755
index 0000000..16b5f9b
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/profile.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/resources.png b/bundles/XO/karma/assets/default/images/resources.png
new file mode 100755
index 0000000..473bedf
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/resources.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/resources_bw.png b/bundles/XO/karma/assets/default/images/resources_bw.png
new file mode 100755
index 0000000..4a1c27d
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/resources_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/science.png b/bundles/XO/karma/assets/default/images/science.png
new file mode 100755
index 0000000..7422dcb
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/science.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/tutorial.png b/bundles/XO/karma/assets/default/images/tutorial.png
new file mode 100755
index 0000000..6c2fc4a
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/tutorial.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/tutorial_bw.png b/bundles/XO/karma/assets/default/images/tutorial_bw.png
new file mode 100755
index 0000000..b25328b
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/tutorial_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-bg_flat_0_aaaaaa_40x100.png b/bundles/XO/karma/assets/default/images/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100755
index 0000000..5b5dab2
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-bg_flat_75_ffffff_40x100.png b/bundles/XO/karma/assets/default/images/ui-bg_flat_75_ffffff_40x100.png
new file mode 100755
index 0000000..ac8b229
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-bg_flat_75_ffffff_40x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-bg_glass_55_fbf9ee_1x400.png b/bundles/XO/karma/assets/default/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100755
index 0000000..ad3d634
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-bg_glass_55_fbf9ee_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-bg_glass_65_ffffff_1x400.png b/bundles/XO/karma/assets/default/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100755
index 0000000..42ccba2
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-bg_glass_65_ffffff_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-bg_glass_75_dadada_1x400.png b/bundles/XO/karma/assets/default/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100755
index 0000000..5a46b47
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-bg_glass_75_dadada_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-bg_glass_75_e6e6e6_1x400.png b/bundles/XO/karma/assets/default/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100755
index 0000000..86c2baa
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-bg_glass_75_e6e6e6_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-bg_glass_95_fef1ec_1x400.png b/bundles/XO/karma/assets/default/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100755
index 0000000..4443fdc
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/bundles/XO/karma/assets/default/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100755
index 0000000..7c9fa6c
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-icons_222222_256x240.png b/bundles/XO/karma/assets/default/images/ui-icons_222222_256x240.png
new file mode 100755
index 0000000..ee039dc
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-icons_222222_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-icons_2e83ff_256x240.png b/bundles/XO/karma/assets/default/images/ui-icons_2e83ff_256x240.png
new file mode 100755
index 0000000..45e8928
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-icons_454545_256x240.png b/bundles/XO/karma/assets/default/images/ui-icons_454545_256x240.png
new file mode 100755
index 0000000..7ec70d1
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-icons_454545_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-icons_888888_256x240.png b/bundles/XO/karma/assets/default/images/ui-icons_888888_256x240.png
new file mode 100755
index 0000000..5ba708c
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-icons_888888_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/ui-icons_cd0a0a_256x240.png b/bundles/XO/karma/assets/default/images/ui-icons_cd0a0a_256x240.png
new file mode 100755
index 0000000..7930a55
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/week1.png b/bundles/XO/karma/assets/default/images/week1.png
new file mode 100755
index 0000000..6776412
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/week1.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/week2.png b/bundles/XO/karma/assets/default/images/week2.png
new file mode 100755
index 0000000..7b73212
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/week2.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/week3.png b/bundles/XO/karma/assets/default/images/week3.png
new file mode 100755
index 0000000..4ab1f76
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/week3.png
Binary files differ
diff --git a/bundles/XO/karma/assets/default/images/week4.png b/bundles/XO/karma/assets/default/images/week4.png
new file mode 100755
index 0000000..448e403
--- /dev/null
+++ b/bundles/XO/karma/assets/default/images/week4.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/adding_up134x100.png b/bundles/XO/karma/assets/image/adding_up134x100.png
new file mode 100755
index 0000000..ba6e2db
--- /dev/null
+++ b/bundles/XO/karma/assets/image/adding_up134x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/alphabet_identification136x100.png b/bundles/XO/karma/assets/image/alphabet_identification136x100.png
new file mode 100755
index 0000000..dc24cc0
--- /dev/null
+++ b/bundles/XO/karma/assets/image/alphabet_identification136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/alphabet_puzzle136x100.png b/bundles/XO/karma/assets/image/alphabet_puzzle136x100.png
new file mode 100755
index 0000000..bba981b
--- /dev/null
+++ b/bundles/XO/karma/assets/image/alphabet_puzzle136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/arrows136x100.png b/bundles/XO/karma/assets/image/arrows136x100.png
new file mode 100755
index 0000000..fb68d5e
--- /dev/null
+++ b/bundles/XO/karma/assets/image/arrows136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/back.png b/bundles/XO/karma/assets/image/back.png
new file mode 100755
index 0000000..fbb0910
--- /dev/null
+++ b/bundles/XO/karma/assets/image/back.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/back_bw.png b/bundles/XO/karma/assets/image/back_bw.png
new file mode 100755
index 0000000..126380d
--- /dev/null
+++ b/bundles/XO/karma/assets/image/back_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/chakra_logo.png b/bundles/XO/karma/assets/image/chakra_logo.png
new file mode 100755
index 0000000..b7f9b3a
--- /dev/null
+++ b/bundles/XO/karma/assets/image/chakra_logo.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/chakra_logo_50x50.png b/bundles/XO/karma/assets/image/chakra_logo_50x50.png
new file mode 100755
index 0000000..0eadda2
--- /dev/null
+++ b/bundles/XO/karma/assets/image/chakra_logo_50x50.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/english.png b/bundles/XO/karma/assets/image/english.png
new file mode 100755
index 0000000..6a3eaab
--- /dev/null
+++ b/bundles/XO/karma/assets/image/english.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/english_colors136x100.png b/bundles/XO/karma/assets/image/english_colors136x100.png
new file mode 100755
index 0000000..1511fdd
--- /dev/null
+++ b/bundles/XO/karma/assets/image/english_colors136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/english_matching136x100.png b/bundles/XO/karma/assets/image/english_matching136x100.png
new file mode 100755
index 0000000..f05564c
--- /dev/null
+++ b/bundles/XO/karma/assets/image/english_matching136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/exercise.png b/bundles/XO/karma/assets/image/exercise.png
new file mode 100755
index 0000000..ebb2ead
--- /dev/null
+++ b/bundles/XO/karma/assets/image/exercise.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/exercise_bw.png b/bundles/XO/karma/assets/image/exercise_bw.png
new file mode 100755
index 0000000..e2cf4f7
--- /dev/null
+++ b/bundles/XO/karma/assets/image/exercise_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/favicon.ico b/bundles/XO/karma/assets/image/favicon.ico
new file mode 100755
index 0000000..20bf7f1
--- /dev/null
+++ b/bundles/XO/karma/assets/image/favicon.ico
Binary files differ
diff --git a/bundles/XO/karma/assets/image/games.png b/bundles/XO/karma/assets/image/games.png
new file mode 100755
index 0000000..a7177f2
--- /dev/null
+++ b/bundles/XO/karma/assets/image/games.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/games_bw.png b/bundles/XO/karma/assets/image/games_bw.png
new file mode 100755
index 0000000..fd3c3cb
--- /dev/null
+++ b/bundles/XO/karma/assets/image/games_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/geography.png b/bundles/XO/karma/assets/image/geography.png
new file mode 100755
index 0000000..3a9a2dc
--- /dev/null
+++ b/bundles/XO/karma/assets/image/geography.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade1.png b/bundles/XO/karma/assets/image/grade1.png
new file mode 100755
index 0000000..2e27b65
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade1.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade1_bw.png b/bundles/XO/karma/assets/image/grade1_bw.png
new file mode 100755
index 0000000..0034ace
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade1_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade2.png b/bundles/XO/karma/assets/image/grade2.png
new file mode 100755
index 0000000..496d0d2
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade2.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade2_bw.png b/bundles/XO/karma/assets/image/grade2_bw.png
new file mode 100755
index 0000000..28eb7c0
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade2_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade3.png b/bundles/XO/karma/assets/image/grade3.png
new file mode 100755
index 0000000..8248bf0
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade3.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade3_bw.png b/bundles/XO/karma/assets/image/grade3_bw.png
new file mode 100755
index 0000000..0e8cd09
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade3_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade4.png b/bundles/XO/karma/assets/image/grade4.png
new file mode 100755
index 0000000..25ac532
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade4.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade4_bw.png b/bundles/XO/karma/assets/image/grade4_bw.png
new file mode 100755
index 0000000..c597442
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade4_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade5.png b/bundles/XO/karma/assets/image/grade5.png
new file mode 100755
index 0000000..1ad416a
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade5.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade5_bw.png b/bundles/XO/karma/assets/image/grade5_bw.png
new file mode 100755
index 0000000..a8a9d8a
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade5_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade6.png b/bundles/XO/karma/assets/image/grade6.png
new file mode 100755
index 0000000..26e6f9b
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade6.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade6_bw.png b/bundles/XO/karma/assets/image/grade6_bw.png
new file mode 100755
index 0000000..07e6e0d
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade6_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade7.png b/bundles/XO/karma/assets/image/grade7.png
new file mode 100755
index 0000000..333b61e
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade7.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade7_bw.png b/bundles/XO/karma/assets/image/grade7_bw.png
new file mode 100755
index 0000000..6ff1dd1
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade7_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade8.png b/bundles/XO/karma/assets/image/grade8.png
new file mode 100755
index 0000000..77542a7
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade8.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/grade8_bw.png b/bundles/XO/karma/assets/image/grade8_bw.png
new file mode 100755
index 0000000..15b3be7
--- /dev/null
+++ b/bundles/XO/karma/assets/image/grade8_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/happyChimp120x125.png b/bundles/XO/karma/assets/image/happyChimp120x125.png
new file mode 100755
index 0000000..5e721c9
--- /dev/null
+++ b/bundles/XO/karma/assets/image/happyChimp120x125.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/health.png b/bundles/XO/karma/assets/image/health.png
new file mode 100755
index 0000000..305c8d0
--- /dev/null
+++ b/bundles/XO/karma/assets/image/health.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/help.png b/bundles/XO/karma/assets/image/help.png
new file mode 100755
index 0000000..9209167
--- /dev/null
+++ b/bundles/XO/karma/assets/image/help.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/help_50x50.png b/bundles/XO/karma/assets/image/help_50x50.png
new file mode 100755
index 0000000..ade47a7
--- /dev/null
+++ b/bundles/XO/karma/assets/image/help_50x50.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/history.png b/bundles/XO/karma/assets/image/history.png
new file mode 100755
index 0000000..79a79c0
--- /dev/null
+++ b/bundles/XO/karma/assets/image/history.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/karma-logo100x118.png b/bundles/XO/karma/assets/image/karma-logo100x118.png
new file mode 100755
index 0000000..f1acb08
--- /dev/null
+++ b/bundles/XO/karma/assets/image/karma-logo100x118.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/karma-logo50x59.png b/bundles/XO/karma/assets/image/karma-logo50x59.png
new file mode 100755
index 0000000..9259b37
--- /dev/null
+++ b/bundles/XO/karma/assets/image/karma-logo50x59.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/karma-logo80x94.png b/bundles/XO/karma/assets/image/karma-logo80x94.png
new file mode 100755
index 0000000..4af81a0
--- /dev/null
+++ b/bundles/XO/karma/assets/image/karma-logo80x94.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/karma_logo.png b/bundles/XO/karma/assets/image/karma_logo.png
new file mode 100755
index 0000000..dc8610a
--- /dev/null
+++ b/bundles/XO/karma/assets/image/karma_logo.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/karma_logo_35x32.png b/bundles/XO/karma/assets/image/karma_logo_35x32.png
new file mode 100755
index 0000000..790ed88
--- /dev/null
+++ b/bundles/XO/karma/assets/image/karma_logo_35x32.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/karma_logo_50x46.png b/bundles/XO/karma/assets/image/karma_logo_50x46.png
new file mode 100755
index 0000000..19dfd91
--- /dev/null
+++ b/bundles/XO/karma/assets/image/karma_logo_50x46.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/karma_logo_54x50.png b/bundles/XO/karma/assets/image/karma_logo_54x50.png
new file mode 100755
index 0000000..6f6842d
--- /dev/null
+++ b/bundles/XO/karma/assets/image/karma_logo_54x50.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/largest_number136x100.png b/bundles/XO/karma/assets/image/largest_number136x100.png
new file mode 100755
index 0000000..238270b
--- /dev/null
+++ b/bundles/XO/karma/assets/image/largest_number136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/mathematics.png b/bundles/XO/karma/assets/image/mathematics.png
new file mode 100755
index 0000000..e8a6ee2
--- /dev/null
+++ b/bundles/XO/karma/assets/image/mathematics.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/money_identification136x100.png b/bundles/XO/karma/assets/image/money_identification136x100.png
new file mode 100755
index 0000000..fbc546c
--- /dev/null
+++ b/bundles/XO/karma/assets/image/money_identification136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_A.png b/bundles/XO/karma/assets/image/month_A.png
new file mode 100755
index 0000000..a8b02a4
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_A.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_B.png b/bundles/XO/karma/assets/image/month_B.png
new file mode 100755
index 0000000..908c64f
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_B.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_C.png b/bundles/XO/karma/assets/image/month_C.png
new file mode 100755
index 0000000..d4a0ae1
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_C.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_D.png b/bundles/XO/karma/assets/image/month_D.png
new file mode 100755
index 0000000..a8b1f28
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_D.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_E.png b/bundles/XO/karma/assets/image/month_E.png
new file mode 100755
index 0000000..3fa8a05
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_E.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_F.png b/bundles/XO/karma/assets/image/month_F.png
new file mode 100755
index 0000000..0daa502
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_F.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_G.png b/bundles/XO/karma/assets/image/month_G.png
new file mode 100755
index 0000000..77e2f7c
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_G.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_H.png b/bundles/XO/karma/assets/image/month_H.png
new file mode 100755
index 0000000..3a99b7c
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_H.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_I.png b/bundles/XO/karma/assets/image/month_I.png
new file mode 100755
index 0000000..4931ec1
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_I.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_J.png b/bundles/XO/karma/assets/image/month_J.png
new file mode 100755
index 0000000..ee11c0d
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_J.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_K.png b/bundles/XO/karma/assets/image/month_K.png
new file mode 100755
index 0000000..16a0dcc
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_K.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/month_L.png b/bundles/XO/karma/assets/image/month_L.png
new file mode 100755
index 0000000..2beef36
--- /dev/null
+++ b/bundles/XO/karma/assets/image/month_L.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/mountains.png b/bundles/XO/karma/assets/image/mountains.png
new file mode 100755
index 0000000..103513f
--- /dev/null
+++ b/bundles/XO/karma/assets/image/mountains.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/music.png b/bundles/XO/karma/assets/image/music.png
new file mode 100755
index 0000000..0530497
--- /dev/null
+++ b/bundles/XO/karma/assets/image/music.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/mystuff.png b/bundles/XO/karma/assets/image/mystuff.png
new file mode 100755
index 0000000..40d3dba
--- /dev/null
+++ b/bundles/XO/karma/assets/image/mystuff.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/nepali.png b/bundles/XO/karma/assets/image/nepali.png
new file mode 100755
index 0000000..08b82a7
--- /dev/null
+++ b/bundles/XO/karma/assets/image/nepali.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/numeric_puzzle136x100.png b/bundles/XO/karma/assets/image/numeric_puzzle136x100.png
new file mode 100755
index 0000000..9cb4484
--- /dev/null
+++ b/bundles/XO/karma/assets/image/numeric_puzzle136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/olenepal_logo.gif b/bundles/XO/karma/assets/image/olenepal_logo.gif
new file mode 100755
index 0000000..e520424
--- /dev/null
+++ b/bundles/XO/karma/assets/image/olenepal_logo.gif
Binary files differ
diff --git a/bundles/XO/karma/assets/image/preview1.jpg b/bundles/XO/karma/assets/image/preview1.jpg
new file mode 100755
index 0000000..9801ffb
--- /dev/null
+++ b/bundles/XO/karma/assets/image/preview1.jpg
Binary files differ
diff --git a/bundles/XO/karma/assets/image/preview2.jpg b/bundles/XO/karma/assets/image/preview2.jpg
new file mode 100755
index 0000000..41762a2
--- /dev/null
+++ b/bundles/XO/karma/assets/image/preview2.jpg
Binary files differ
diff --git a/bundles/XO/karma/assets/image/preview3.jpg b/bundles/XO/karma/assets/image/preview3.jpg
new file mode 100755
index 0000000..385bef2
--- /dev/null
+++ b/bundles/XO/karma/assets/image/preview3.jpg
Binary files differ
diff --git a/bundles/XO/karma/assets/image/preview4.jpg b/bundles/XO/karma/assets/image/preview4.jpg
new file mode 100755
index 0000000..e75def8
--- /dev/null
+++ b/bundles/XO/karma/assets/image/preview4.jpg
Binary files differ
diff --git a/bundles/XO/karma/assets/image/profile.png b/bundles/XO/karma/assets/image/profile.png
new file mode 100755
index 0000000..16b5f9b
--- /dev/null
+++ b/bundles/XO/karma/assets/image/profile.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/quads136x100.png b/bundles/XO/karma/assets/image/quads136x100.png
new file mode 100755
index 0000000..8647c60
--- /dev/null
+++ b/bundles/XO/karma/assets/image/quads136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/resources.png b/bundles/XO/karma/assets/image/resources.png
new file mode 100755
index 0000000..473bedf
--- /dev/null
+++ b/bundles/XO/karma/assets/image/resources.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/resources_bw.png b/bundles/XO/karma/assets/image/resources_bw.png
new file mode 100755
index 0000000..4a1c27d
--- /dev/null
+++ b/bundles/XO/karma/assets/image/resources_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/science.png b/bundles/XO/karma/assets/image/science.png
new file mode 100755
index 0000000..7422dcb
--- /dev/null
+++ b/bundles/XO/karma/assets/image/science.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/screenConozco136x100.png b/bundles/XO/karma/assets/image/screenConozco136x100.png
new file mode 100755
index 0000000..19526e1
--- /dev/null
+++ b/bundles/XO/karma/assets/image/screenConozco136x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/screenConozco162x100.png b/bundles/XO/karma/assets/image/screenConozco162x100.png
new file mode 100755
index 0000000..aa2f6d5
--- /dev/null
+++ b/bundles/XO/karma/assets/image/screenConozco162x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/tutorial.png b/bundles/XO/karma/assets/image/tutorial.png
new file mode 100755
index 0000000..6c2fc4a
--- /dev/null
+++ b/bundles/XO/karma/assets/image/tutorial.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/tutorial_bw.png b/bundles/XO/karma/assets/image/tutorial_bw.png
new file mode 100755
index 0000000..b25328b
--- /dev/null
+++ b/bundles/XO/karma/assets/image/tutorial_bw.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-bg_flat_0_aaaaaa_40x100.png b/bundles/XO/karma/assets/image/ui-bg_flat_0_aaaaaa_40x100.png
new file mode 100755
index 0000000..5b5dab2
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-bg_flat_0_aaaaaa_40x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-bg_flat_75_ffffff_40x100.png b/bundles/XO/karma/assets/image/ui-bg_flat_75_ffffff_40x100.png
new file mode 100755
index 0000000..ac8b229
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-bg_flat_75_ffffff_40x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-bg_glass_55_fbf9ee_1x400.png b/bundles/XO/karma/assets/image/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100755
index 0000000..ad3d634
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-bg_glass_55_fbf9ee_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-bg_glass_65_ffffff_1x400.png b/bundles/XO/karma/assets/image/ui-bg_glass_65_ffffff_1x400.png
new file mode 100755
index 0000000..42ccba2
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-bg_glass_65_ffffff_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-bg_glass_75_dadada_1x400.png b/bundles/XO/karma/assets/image/ui-bg_glass_75_dadada_1x400.png
new file mode 100755
index 0000000..5a46b47
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-bg_glass_75_dadada_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-bg_glass_75_e6e6e6_1x400.png b/bundles/XO/karma/assets/image/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100755
index 0000000..86c2baa
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-bg_glass_75_e6e6e6_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-bg_glass_95_fef1ec_1x400.png b/bundles/XO/karma/assets/image/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100755
index 0000000..4443fdc
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-bg_highlight-soft_75_cccccc_1x100.png b/bundles/XO/karma/assets/image/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100755
index 0000000..7c9fa6c
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-bg_highlight-soft_75_cccccc_1x100.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-icons_222222_256x240.png b/bundles/XO/karma/assets/image/ui-icons_222222_256x240.png
new file mode 100755
index 0000000..ee039dc
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-icons_222222_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-icons_2e83ff_256x240.png b/bundles/XO/karma/assets/image/ui-icons_2e83ff_256x240.png
new file mode 100755
index 0000000..45e8928
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-icons_454545_256x240.png b/bundles/XO/karma/assets/image/ui-icons_454545_256x240.png
new file mode 100755
index 0000000..7ec70d1
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-icons_454545_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-icons_888888_256x240.png b/bundles/XO/karma/assets/image/ui-icons_888888_256x240.png
new file mode 100755
index 0000000..5ba708c
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-icons_888888_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/ui-icons_cd0a0a_256x240.png b/bundles/XO/karma/assets/image/ui-icons_cd0a0a_256x240.png
new file mode 100755
index 0000000..7930a55
--- /dev/null
+++ b/bundles/XO/karma/assets/image/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/web-bg.png b/bundles/XO/karma/assets/image/web-bg.png
new file mode 100755
index 0000000..aede98f
--- /dev/null
+++ b/bundles/XO/karma/assets/image/web-bg.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/web-bg.svg b/bundles/XO/karma/assets/image/web-bg.svg
new file mode 100755
index 0000000..b625fb9
--- /dev/null
+++ b/bundles/XO/karma/assets/image/web-bg.svg
@@ -0,0 +1,651 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="492.19226"
+ height="110"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="web-bg.svg">
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="277.5"
+ inkscape:cy="-30.887888"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer2"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1" />
+ <defs
+ id="defs4" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ transform="translate(-97.5,-292.47158)">
+ <g
+ transform="matrix(0.99499977,0.09987717,-0.09987717,0.99499977,320.05685,277.09819)"
+ inkscape:label="Layer 1"
+ id="layer1-2-3">
+ <g
+ id="g2039-0"
+ transform="matrix(2.101543,0,0,2.101543,-20.51805,-62.14422)">
+ <path
+ style="fill:#e4e4e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 25.484419,57.339597 c -0.843126,-0.007 -1.153942,0.849347 -2.132163,1.827567 -0.306469,0.30647 -0.676877,0.541502 -1.015315,0.812253 -0.573587,0.45887 -0.999205,1.061522 -1.421442,1.624505 -0.493396,0.657861 -1.128722,1.128722 -1.726036,1.726036 -0.882369,0.882369 -2.12819,1.469228 -3.147478,2.233694 -0.756451,0.567338 -0.958015,0.393056 -1.421442,1.31991 -0.287559,0.575118 -1.41051,1.407777 -1.827568,1.9291 -0.493868,0.617335 -0.440065,0.947722 -1.015315,1.522973 -0.524955,0.524954 -0.829105,0.287742 -0.101532,1.015315 0.279084,0.279084 0.676877,0.406127 1.015316,0.60919 0.733388,0.440033 1.490393,0.835236 2.335225,1.116847 1.280354,0.426784 2.645607,0.346364 3.959731,0.609189 0.169219,0.03384 0.338438,0.06769 0.507658,0.101532 0.878576,0.175715 2.546303,0.793265 3.355653,0.590927 0.686013,-0.171503 3.217253,0.71839 4.928299,-0.321577 1.982335,-0.67292 5.483473,-1.593634 7.495073,-1.146612 1.106214,0.245826 2.132607,0.708941 2.395122,-0.341117 0.121425,-0.485699 -0.01423,-1.145304 -0.203063,-1.522973 -0.291362,-0.582723 -0.854109,-0.573553 -1.015316,-1.218379 -0.183179,-0.732717 0.23914,-1.261151 0.406126,-1.929099 0.284047,-1.136187 -0.07236,-1.667977 1.319911,-1.31991 0.771576,0.192894 1.407656,0.319386 2.132162,0.609189 1.974578,0.789831 4.097064,0.812252 6.193425,0.812252 1.437363,0 2.912756,-1.02929 4.365856,-1.31991 0.761687,-0.152337 3.313295,-2.143577 3.782598,-2.260902 0.543488,-0.135872 1.94541,2.469094 1.598574,3.682344 1.29682,0.324205 2.05854,1.011754 3.24901,1.726036 0.921993,0.553196 2.173988,0.812253 3.24901,0.812253 1.999216,0 3.734648,-0.09603 5.787298,-0.60919 1.247305,-0.311826 1.624505,-0.193148 1.624505,-1.421441 0,-0.867362 -0.606794,-1.419047 -1.218379,-2.030631 -0.538554,-0.538554 -1.000113,-1.130829 -1.522973,-1.522974 -0.512447,-0.384335 -0.869381,-1.129571 -1.116847,-1.624504 -0.338265,-0.67653 -0.662946,-1.325892 -1.015316,-2.030631 -0.333719,-0.667438 -0.701535,-0.957661 -1.31991,-1.421442 -0.778467,-0.58385 -1.258684,-1.353242 -1.726036,-2.132163 -0.682242,-1.13707 -1.608096,-2.649563 -2.132163,-3.95973 -0.05621,-0.140529 -0.135375,-0.270751 -0.203063,-0.406126 -0.272751,-0.545503 -0.63008,-1.036207 -1.015315,-1.421442 -0.746683,-0.746683 -1.564639,-0.22258 -2.132163,0.203063 -1.45229,1.089218 -1.911754,1.099502 -3.045946,2.233694 -0.66201,0.66201 -1.564634,1.707827 -1.9291,2.436757 -0.423924,0.84785 -0.98834,0.419614 -1.624505,0.101532 -0.613995,-0.306998 -1.035124,-0.674812 -1.624504,-1.116847 -0.693766,-0.520324 -1.433007,-1.433007 -2.030631,-2.030631 -0.633044,-0.633044 -1.42104,-1.31991 -2.335226,-1.31991 -1.24006,0 -2.4622,-1.971505 -3.045946,-2.944415 -0.523862,-0.873103 -1.490853,-1.522973 -2.538289,-1.522973 -1.295372,0 -2.506223,1.617155 -3.655136,2.335225 -0.930051,0.581282 -1.39337,0.663237 -1.726036,1.827568 -0.208123,0.728428 -0.624395,1.279201 -0.812253,2.030631 -0.180754,0.723016 -0.492196,1.492051 -0.812252,2.132163 -0.342266,0.684531 -0.704921,1.003715 -1.015316,1.624504 -0.359527,0.719054 -1.530992,1.975856 -2.233694,1.624505 -0.589142,-0.294571 -0.994918,-0.771457 -1.31991,-1.421441 -0.158488,-0.316977 -1.306963,-0.769777 -1.522973,-0.913784 z"
+ id="path2166-4"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
+ <path
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 25.687482,56.93347 c -0.03384,0.06769 -0.06769,0.135376 -0.101532,0.203063 -0.625349,1.250699 -2.202358,1.288575 -3.045946,2.132163 -0.169219,0.169219 -0.338438,0.338439 -0.507658,0.507658 -0.777416,0.777416 -1.231932,2.044184 -2.132162,2.944415 -0.500234,0.500233 -1.14971,0.947382 -1.827568,1.116847 -0.5974,0.14935 -1.34856,0.73937 -1.827568,1.218378 -0.679462,0.679463 -1.266186,1.266186 -1.827568,1.827568 -0.624635,0.624635 -1.403885,1.382892 -2.132163,1.9291 -0.390457,0.292843 -0.707731,1.307953 -0.812252,1.726036 -0.12508,0.500319 -0.46621,0.985274 0.203063,1.31991 0.691718,0.345859 1.320765,0.508513 1.9291,1.116847 0.599514,0.599515 1.095764,0.649414 1.827568,1.015316 0.621546,0.310773 1.841136,0.304594 2.538288,0.304594 0.720531,0 1.476756,0.304595 2.233694,0.304595 1.351655,0 1.819729,0.439615 2.944415,-0.203063 0.30663,-0.175217 0.307493,-1.102359 0.203063,-1.624505 -0.131065,-0.655326 -0.304594,-1.254521 -0.304594,-1.929099 0,-0.718547 0.06673,-1.247452 0.203063,-1.9291 0.146742,-0.73371 0.529207,-1.304576 0.710721,-2.030631 0.208002,-0.832008 0.828169,-1.672256 1.116847,-2.538288 0.24709,-0.741271 0.435595,-1.437787 0.609189,-2.132163 0.168788,-0.675154 0.203063,-1.526781 0.203063,-2.233694 0,-0.643033 0,-1.286066 0,-1.9291 0,-0.545527 -0.08581,-0.530596 -0.203063,-1.116847 z"
+ id="path2168-9" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 38.378926,48.201757 c -0.171127,0.586617 0.315343,1.784573 0.101531,2.63982 -0.221006,0.884024 -1.116847,1.000333 -1.116847,2.030631 0,0.761947 -0.304594,1.375387 -0.304594,2.132163 0,0.769563 0.660654,1.475707 0.812252,2.233694 0.151746,0.758728 0.01011,1.807338 -0.304595,2.436757 -0.390112,0.780226 -0.447244,1.60521 -0.812252,2.335226 -0.279077,0.558155 -0.687991,1.560355 -0.812252,1.726036 -0.33613,0.448173 0.460184,1.021902 0.71072,1.522973 0.208447,0.416895 0.203063,0.971521 0.203063,1.522974 0,0.724502 -0.246633,1.189595 -0.406126,1.827568 -0.174785,0.699139 0.01438,2.271451 -0.527197,1.72987 C 35.481714,69.898554 34.428144,68.925698 33.950617,68.44817 33.4268,67.924354 33.587922,67.213606 33.40388,66.477436 33.252398,65.871508 32.806127,65.447192 32.549993,64.934924 32.233196,64.301331 32.010638,63.706468 31.373249,63.228426 30.69153,62.717138 30.322063,62.033911 29.748744,61.603922 29.113871,61.127767 28.83496,60.318279 28.83496,59.573291 c 0,-0.687404 1.15136,-1.252892 1.624505,-1.726037 0.624908,-0.624908 0.70829,-1.58904 1.522973,-2.132162 0.615203,-0.410135 0.870192,-1.305013 1.015316,-2.030631 0.171576,-0.857885 0.723672,-1.853471 1.116847,-2.63982 0.06769,-0.135376 0.135375,-0.270751 0.203063,-0.406127 0.225847,-0.451695 1.538359,-0.618421 2.030631,-0.913784 0.747508,-0.448505 1.719357,-0.744789 2.030631,-1.522973 z"
+ id="path2170-3" />
+ <path
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 58.076046,52.364551 c -0.07402,0.430513 -0.467973,1.426083 -0.609189,2.132162 -0.164612,0.823062 -0.313905,1.661747 -0.507658,2.436757 -0.170841,0.683367 -0.239076,1.362431 -0.406126,2.030631 -0.179637,0.718548 0.424763,1.412447 0.812252,1.9291 0.519747,0.692995 0.501506,1.792182 0.203064,2.538289 -0.307068,0.767668 -0.248565,1.750478 -0.406127,2.538288 -0.125224,0.62612 0.05189,1.369554 -0.406126,1.827568 -0.112917,0.112918 -0.259577,-1.55123 -0.406126,-1.624505 -0.725185,-0.362592 -0.729788,-1.802306 -0.812252,-2.132162 -0.207784,-0.831136 -0.879003,-1.351879 -1.218379,-2.030631 -0.389725,-0.779451 -1.155155,-1.294994 -1.522973,-2.030631 -0.421412,-0.842824 -1.449648,-1.229672 -1.624505,-1.9291 -0.03384,-0.135375 -0.06769,-0.27075 -0.101532,-0.406126 -0.125189,-0.500757 0.856853,-1.466042 1.116847,-1.726036 1.011873,-1.011872 2.937684,-2.445242 4.061262,-3.147478 0.573181,-0.358238 1.058897,-0.252392 1.827568,-0.406126 z"
+ id="path2172-8"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+ <path
+ id="path1737-2"
+ d="m 37.688417,47.315712 -0.71875,0.8125 c -0.38602,0.45665 -1.39051,1.29725 -2.25,1.84375 -1.73431,1.10273 -1.9925,1.43503 -2.40625,3.28125 -0.41819,1.86601 -1.20261,3.39879 -2.5625,4.9375 l -1.21875,1.375 -1.125,-1.3125 c -0.62651,-0.71175 -1.28441,-1.28125 -1.46875,-1.28125 -1.25379,0 -4.82321,2.77532 -5.21875,4.0625 -0.27779,0.90392 -2.06599,2.5764 -3.1875,3 -1.8206,0.68763 -2.28988,0.98857 -3.1875,1.9375 -1.05225,1.11239 -3.59375,4.62873 -3.59375,4.96875 -10e-6,0.68315 0.819,0.03545 1.84375,-1.46875 1.84761,-2.71206 3.05427,-3.91514 4.5625,-4.46875 1.87299,-0.68751 2.99701,-1.58592 4.21875,-3.375 1.21274,-1.77592 1.96371,-2.4807 3.40625,-3.28125 l 1.03125,-0.59375 0.6875,0.78125 c 0.37531,0.41898 1.02524,1.27565 1.4375,1.90625 0.41225,0.6306 1.52648,1.91575 2.5,2.875 1.39241,1.372 1.86875,2.03741 2.15625,3.09375 0.60667,2.22915 1.3704,3.32811 2.9375,4.21875 0.9082,0.51616 1.4375,0.99682 1.4375,1.3125 -1e-5,0.27412 0.08736,0.58735 0.1875,0.6875 0.36809,0.3681 0.625,0.14605 0.625,-0.5 -1e-5,-0.79158 -0.53613,-1.33225 -1.90625,-2.03125 -1.1445,-0.58387 -2.46874,-2.3998 -2.46875,-3.375 -1e-5,-1.03552 -0.79476,-2.35565 -2.25,-3.71875 -0.74458,-0.69743 -1.57883,-1.58969 -1.875,-2 l -0.53125,-0.75 1.40625,-1.4375 c 1.39188,-1.42342 2.97575,-4.22457 3,-5.28125 0.02578,-1.1241 0.6984,-2.05067 2.15625,-2.96875 0.8262,-0.52031 1.67734,-1.10944 1.875,-1.28125 0.62359,-0.54204 0.60293,-0.12978 -0.0625,2.09375 -0.35602,1.18958 -0.71034,2.78014 -0.8125,3.53125 -0.16309,1.19898 -0.112,1.48658 0.5,2.3125 0.86439,1.16655 0.8469,1.32928 -0.03125,3.6875 -1.41928,3.81145 -1.44888,4.15262 -0.5625,3.8125 0.23124,-0.08874 0.48653,-0.4221 0.5625,-0.75 0.07594,-0.3279 0.45347,-1.43269 0.84375,-2.46875 0.85104,-2.25918 0.88211,-3.27823 0.15625,-4.46875 -0.776,-1.27274 -0.63937,-3.64892 0.3125,-5.125 0.10243,-0.15886 0.27152,-0.93871 0.375,-1.71875 0.16263,-1.22609 0.28874,-1.40625 0.8125,-1.40625 0.82127,0 1.70373,0.8059 1.9375,1.78125 0.28276,1.17981 0.54183,1.42067 2.875,2.59375 2.31324,1.16308 4.875,3.41208 4.875,4.28125 -1e-5,0.38999 0.45674,0.76886 1.53125,1.3125 1.08841,0.55069 1.53684,0.96175 1.65625,1.46875 0.22158,0.94095 1.38165,2.46875 1.875,2.46875 0.62512,0 0.4857,-0.70545 -0.25,-1.1875 -0.40391,-0.26465 -0.73657,-0.80371 -0.84375,-1.375 -0.13031,-0.69457 -0.3891,-1.05593 -0.96875,-1.3125 -1.0027,-0.44384 -0.99515,-0.6542 0.09375,-1.875 0.48749,-0.54654 1.41829,-1.63836 2.09375,-2.40625 0.7279,-0.82751 1.48006,-1.40626 1.8125,-1.40625 0.30848,0 0.69724,-0.13474 0.875,-0.3125 0.58494,-0.58494 0.59452,-0.06168 0.03125,1.03125 -0.42435,0.82336 -0.52348,1.44551 -0.4375,2.65625 0.08956,1.26153 0.01501,1.71445 -0.40625,2.25 -0.52673,0.66961 -0.53284,0.67089 0.21875,1.65625 0.95555,1.25281 1.20948,3.64442 0.5625,5.375 -0.23675,0.63325 -0.45543,1.46819 -0.5,1.84375 -0.09647,0.81279 0.40444,1.19623 0.53125,0.40625 0.04822,-0.30044 0.34601,-1.20897 0.65625,-2 0.6898,-1.75885 0.57496,-3.80067 -0.28125,-5.53125 -0.34674,-0.70081 -0.48241,-1.29716 -0.34375,-1.46875 0.12902,-0.15966 0.28705,-1.24258 0.34375,-2.40625 0.09086,-1.86494 0.19075,-2.22202 0.84375,-2.875 l 0.75,-0.71875 0.75,0.5625 c 0.59493,0.44222 0.8463,0.96429 1.15625,2.4375 0.36574,1.73851 0.51236,1.9969 2.125,3.59375 0.95518,0.94584 1.82381,1.71874 1.9375,1.71875 0.25734,0 0.99476,1.66956 1.375,3.125 0.19524,0.74733 0.78198,1.57603 1.8125,2.59375 0.83021,0.81991 1.5,1.65084 1.5,1.84375 -1e-5,0.19291 0.23081,0.34375 0.53125,0.34375 0.90995,0 0.65303,-0.57035 -1.15625,-2.4375 -1.38398,-1.42823 -1.83008,-2.1147 -2.21875,-3.40625 -0.41612,-1.38275 -0.80466,-1.92313 -2.65625,-3.75 -1.18696,-1.1711 -2.176,-2.35409 -2.1875,-2.625 -0.02356,-0.55517 -0.1424,-1.22954 -0.375,-2.15625 -0.23819,-0.94898 -2.79423,-3.37499 -3.5625,-3.375 -0.35553,0 -0.69894,0.11681 -0.78125,0.25 -0.08232,0.13319 -0.56537,0.313 -1.0625,0.40625 -1.06959,0.20066 -2.66384,1.60689 -4.28125,3.78125 -1.1611,1.56092 -1.65626,1.90751 -1.65625,1.1875 -1e-5,-0.74607 -3.5926,-3.71722 -5.625,-4.65625 -1.82273,-0.84215 -2.00786,-1.01442 -2.3125,-2.03125 -0.41516,-1.38567 -1.08354,-1.97661 -2.96875,-2.625 l -1.46875,-0.5 z m -12.28125,11.28125 c -0.12939,0 -0.12994,0.52943 -0.03125,1.1875 0.27519,1.83519 -0.33347,4.17054 -1.375,5.34375 -0.48702,0.54859 -0.98162,1.23081 -1.09375,1.53125 -0.38544,1.03278 -0.65955,3.45228 -0.5,4.25 0.10841,0.5421 0.30867,0.8125 0.65625,0.8125 0.54077,0 0.60057,-0.35223 0.25,-1.25 -0.33045,-0.84625 0.36191,-3.20331 1.3125,-4.53125 0.47232,-0.65983 1.05452,-1.8114 1.28125,-2.5625 0.71319,-2.36269 0.4468,-4.78124 -0.5,-4.78125 z"
+ style="fill:#5c2700;fill-opacity:1" />
+ </g>
+ </g>
+ <g
+ transform="matrix(1.5504908,0.06199384,-0.15563686,0.90821954,404.6331,287.63856)"
+ inkscape:label="Layer 1"
+ id="layer1-2-3-0">
+ <g
+ id="g2039-0-8"
+ transform="matrix(2.101543,0,0,2.101543,-20.51805,-62.14422)">
+ <path
+ style="fill:#e4e4e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 25.484419,57.339597 c -0.843126,-0.007 -1.153942,0.849347 -2.132163,1.827567 -0.306469,0.30647 -0.676877,0.541502 -1.015315,0.812253 -0.573587,0.45887 -0.999205,1.061522 -1.421442,1.624505 -0.493396,0.657861 -1.128722,1.128722 -1.726036,1.726036 -0.882369,0.882369 -2.12819,1.469228 -3.147478,2.233694 -0.756451,0.567338 -0.958015,0.393056 -1.421442,1.31991 -0.287559,0.575118 -1.41051,1.407777 -1.827568,1.9291 -0.493868,0.617335 -0.440065,0.947722 -1.015315,1.522973 -0.524955,0.524954 -0.829105,0.287742 -0.101532,1.015315 0.279084,0.279084 0.676877,0.406127 1.015316,0.60919 0.733388,0.440033 1.490393,0.835236 2.335225,1.116847 1.280354,0.426784 2.645607,0.346364 3.959731,0.609189 0.169219,0.03384 0.338438,0.06769 0.507658,0.101532 0.878576,0.175715 2.546303,0.793265 3.355653,0.590927 0.686013,-0.171503 3.217253,0.71839 4.928299,-0.321577 1.982335,-0.67292 5.483473,-1.593634 7.495073,-1.146612 1.106214,0.245826 2.132607,0.708941 2.395122,-0.341117 0.121425,-0.485699 -0.01423,-1.145304 -0.203063,-1.522973 -0.291362,-0.582723 -0.854109,-0.573553 -1.015316,-1.218379 -0.183179,-0.732717 0.23914,-1.261151 0.406126,-1.929099 0.284047,-1.136187 -0.07236,-1.667977 1.319911,-1.31991 0.771576,0.192894 1.407656,0.319386 2.132162,0.609189 1.974578,0.789831 4.097064,0.812252 6.193425,0.812252 1.437363,0 2.912756,-1.02929 4.365856,-1.31991 0.761687,-0.152337 3.313295,-2.143577 3.782598,-2.260902 0.543488,-0.135872 1.94541,2.469094 1.598574,3.682344 1.29682,0.324205 2.05854,1.011754 3.24901,1.726036 0.921993,0.553196 2.173988,0.812253 3.24901,0.812253 1.999216,0 3.734648,-0.09603 5.787298,-0.60919 1.247305,-0.311826 1.624505,-0.193148 1.624505,-1.421441 0,-0.867362 -0.606794,-1.419047 -1.218379,-2.030631 -0.538554,-0.538554 -1.000113,-1.130829 -1.522973,-1.522974 -0.512447,-0.384335 -0.869381,-1.129571 -1.116847,-1.624504 -0.338265,-0.67653 -0.662946,-1.325892 -1.015316,-2.030631 -0.333719,-0.667438 -0.701535,-0.957661 -1.31991,-1.421442 -0.778467,-0.58385 -1.258684,-1.353242 -1.726036,-2.132163 -0.682242,-1.13707 -1.608096,-2.649563 -2.132163,-3.95973 -0.05621,-0.140529 -0.135375,-0.270751 -0.203063,-0.406126 -0.272751,-0.545503 -0.63008,-1.036207 -1.015315,-1.421442 -0.746683,-0.746683 -1.564639,-0.22258 -2.132163,0.203063 -1.45229,1.089218 -1.911754,1.099502 -3.045946,2.233694 -0.66201,0.66201 -1.564634,1.707827 -1.9291,2.436757 -0.423924,0.84785 -0.98834,0.419614 -1.624505,0.101532 -0.613995,-0.306998 -1.035124,-0.674812 -1.624504,-1.116847 -0.693766,-0.520324 -1.433007,-1.433007 -2.030631,-2.030631 -0.633044,-0.633044 -1.42104,-1.31991 -2.335226,-1.31991 -1.24006,0 -2.4622,-1.971505 -3.045946,-2.944415 -0.523862,-0.873103 -1.490853,-1.522973 -2.538289,-1.522973 -1.295372,0 -2.506223,1.617155 -3.655136,2.335225 -0.930051,0.581282 -1.39337,0.663237 -1.726036,1.827568 -0.208123,0.728428 -0.624395,1.279201 -0.812253,2.030631 -0.180754,0.723016 -0.492196,1.492051 -0.812252,2.132163 -0.342266,0.684531 -0.704921,1.003715 -1.015316,1.624504 -0.359527,0.719054 -1.530992,1.975856 -2.233694,1.624505 -0.589142,-0.294571 -0.994918,-0.771457 -1.31991,-1.421441 -0.158488,-0.316977 -1.306963,-0.769777 -1.522973,-0.913784 z"
+ id="path2166-4-4"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
+ <path
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 25.687482,56.93347 c -0.03384,0.06769 -0.06769,0.135376 -0.101532,0.203063 -0.625349,1.250699 -2.202358,1.288575 -3.045946,2.132163 -0.169219,0.169219 -0.338438,0.338439 -0.507658,0.507658 -0.777416,0.777416 -1.231932,2.044184 -2.132162,2.944415 -0.500234,0.500233 -1.14971,0.947382 -1.827568,1.116847 -0.5974,0.14935 -1.34856,0.73937 -1.827568,1.218378 -0.679462,0.679463 -1.266186,1.266186 -1.827568,1.827568 -0.624635,0.624635 -1.403885,1.382892 -2.132163,1.9291 -0.390457,0.292843 -0.707731,1.307953 -0.812252,1.726036 -0.12508,0.500319 -0.46621,0.985274 0.203063,1.31991 0.691718,0.345859 1.320765,0.508513 1.9291,1.116847 0.599514,0.599515 1.095764,0.649414 1.827568,1.015316 0.621546,0.310773 1.841136,0.304594 2.538288,0.304594 0.720531,0 1.476756,0.304595 2.233694,0.304595 1.351655,0 1.819729,0.439615 2.944415,-0.203063 0.30663,-0.175217 0.307493,-1.102359 0.203063,-1.624505 -0.131065,-0.655326 -0.304594,-1.254521 -0.304594,-1.929099 0,-0.718547 0.06673,-1.247452 0.203063,-1.9291 0.146742,-0.73371 0.529207,-1.304576 0.710721,-2.030631 0.208002,-0.832008 0.828169,-1.672256 1.116847,-2.538288 0.24709,-0.741271 0.435595,-1.437787 0.609189,-2.132163 0.168788,-0.675154 0.203063,-1.526781 0.203063,-2.233694 0,-0.643033 0,-1.286066 0,-1.9291 0,-0.545527 -0.08581,-0.530596 -0.203063,-1.116847 z"
+ id="path2168-9-4" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 38.378926,48.201757 c -0.171127,0.586617 0.315343,1.784573 0.101531,2.63982 -0.221006,0.884024 -1.116847,1.000333 -1.116847,2.030631 0,0.761947 -0.304594,1.375387 -0.304594,2.132163 0,0.769563 0.660654,1.475707 0.812252,2.233694 0.151746,0.758728 0.01011,1.807338 -0.304595,2.436757 -0.390112,0.780226 -0.447244,1.60521 -0.812252,2.335226 -0.279077,0.558155 -0.687991,1.560355 -0.812252,1.726036 -0.33613,0.448173 0.460184,1.021902 0.71072,1.522973 0.208447,0.416895 0.203063,0.971521 0.203063,1.522974 0,0.724502 -0.246633,1.189595 -0.406126,1.827568 -0.174785,0.699139 0.01438,2.271451 -0.527197,1.72987 C 35.481714,69.898554 34.428144,68.925698 33.950617,68.44817 33.4268,67.924354 33.587922,67.213606 33.40388,66.477436 33.252398,65.871508 32.806127,65.447192 32.549993,64.934924 32.233196,64.301331 32.010638,63.706468 31.373249,63.228426 30.69153,62.717138 30.322063,62.033911 29.748744,61.603922 29.113871,61.127767 28.83496,60.318279 28.83496,59.573291 c 0,-0.687404 1.15136,-1.252892 1.624505,-1.726037 0.624908,-0.624908 0.70829,-1.58904 1.522973,-2.132162 0.615203,-0.410135 0.870192,-1.305013 1.015316,-2.030631 0.171576,-0.857885 0.723672,-1.853471 1.116847,-2.63982 0.06769,-0.135376 0.135375,-0.270751 0.203063,-0.406127 0.225847,-0.451695 1.538359,-0.618421 2.030631,-0.913784 0.747508,-0.448505 1.719357,-0.744789 2.030631,-1.522973 z"
+ id="path2170-3-6" />
+ <path
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 58.076046,52.364551 c -0.07402,0.430513 -0.467973,1.426083 -0.609189,2.132162 -0.164612,0.823062 -0.313905,1.661747 -0.507658,2.436757 -0.170841,0.683367 -0.239076,1.362431 -0.406126,2.030631 -0.179637,0.718548 0.424763,1.412447 0.812252,1.9291 0.519747,0.692995 0.501506,1.792182 0.203064,2.538289 -0.307068,0.767668 -0.248565,1.750478 -0.406127,2.538288 -0.125224,0.62612 0.05189,1.369554 -0.406126,1.827568 -0.112917,0.112918 -0.259577,-1.55123 -0.406126,-1.624505 -0.725185,-0.362592 -0.729788,-1.802306 -0.812252,-2.132162 -0.207784,-0.831136 -0.879003,-1.351879 -1.218379,-2.030631 -0.389725,-0.779451 -1.155155,-1.294994 -1.522973,-2.030631 -0.421412,-0.842824 -1.449648,-1.229672 -1.624505,-1.9291 -0.03384,-0.135375 -0.06769,-0.27075 -0.101532,-0.406126 -0.125189,-0.500757 0.856853,-1.466042 1.116847,-1.726036 1.011873,-1.011872 2.937684,-2.445242 4.061262,-3.147478 0.573181,-0.358238 1.058897,-0.252392 1.827568,-0.406126 z"
+ id="path2172-8-2"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+ <path
+ id="path1737-2-1"
+ d="m 37.688417,47.315712 -0.71875,0.8125 c -0.38602,0.45665 -1.39051,1.29725 -2.25,1.84375 -1.73431,1.10273 -1.9925,1.43503 -2.40625,3.28125 -0.41819,1.86601 -1.20261,3.39879 -2.5625,4.9375 l -1.21875,1.375 -1.125,-1.3125 c -0.62651,-0.71175 -1.28441,-1.28125 -1.46875,-1.28125 -1.25379,0 -4.82321,2.77532 -5.21875,4.0625 -0.27779,0.90392 -2.06599,2.5764 -3.1875,3 -1.8206,0.68763 -2.28988,0.98857 -3.1875,1.9375 -1.05225,1.11239 -3.59375,4.62873 -3.59375,4.96875 -10e-6,0.68315 0.819,0.03545 1.84375,-1.46875 1.84761,-2.71206 3.05427,-3.91514 4.5625,-4.46875 1.87299,-0.68751 2.99701,-1.58592 4.21875,-3.375 1.21274,-1.77592 1.96371,-2.4807 3.40625,-3.28125 l 1.03125,-0.59375 0.6875,0.78125 c 0.37531,0.41898 1.02524,1.27565 1.4375,1.90625 0.41225,0.6306 1.52648,1.91575 2.5,2.875 1.39241,1.372 1.86875,2.03741 2.15625,3.09375 0.60667,2.22915 1.3704,3.32811 2.9375,4.21875 0.9082,0.51616 1.4375,0.99682 1.4375,1.3125 -1e-5,0.27412 0.08736,0.58735 0.1875,0.6875 0.36809,0.3681 0.625,0.14605 0.625,-0.5 -1e-5,-0.79158 -0.53613,-1.33225 -1.90625,-2.03125 -1.1445,-0.58387 -2.46874,-2.3998 -2.46875,-3.375 -1e-5,-1.03552 -0.79476,-2.35565 -2.25,-3.71875 -0.74458,-0.69743 -1.57883,-1.58969 -1.875,-2 l -0.53125,-0.75 1.40625,-1.4375 c 1.39188,-1.42342 2.97575,-4.22457 3,-5.28125 0.02578,-1.1241 0.6984,-2.05067 2.15625,-2.96875 0.8262,-0.52031 1.67734,-1.10944 1.875,-1.28125 0.62359,-0.54204 0.60293,-0.12978 -0.0625,2.09375 -0.35602,1.18958 -0.71034,2.78014 -0.8125,3.53125 -0.16309,1.19898 -0.112,1.48658 0.5,2.3125 0.86439,1.16655 0.8469,1.32928 -0.03125,3.6875 -1.41928,3.81145 -1.44888,4.15262 -0.5625,3.8125 0.23124,-0.08874 0.48653,-0.4221 0.5625,-0.75 0.07594,-0.3279 0.45347,-1.43269 0.84375,-2.46875 0.85104,-2.25918 0.88211,-3.27823 0.15625,-4.46875 -0.776,-1.27274 -0.63937,-3.64892 0.3125,-5.125 0.10243,-0.15886 0.27152,-0.93871 0.375,-1.71875 0.16263,-1.22609 0.28874,-1.40625 0.8125,-1.40625 0.82127,0 1.70373,0.8059 1.9375,1.78125 0.28276,1.17981 0.54183,1.42067 2.875,2.59375 2.31324,1.16308 4.875,3.41208 4.875,4.28125 -1e-5,0.38999 0.45674,0.76886 1.53125,1.3125 1.08841,0.55069 1.53684,0.96175 1.65625,1.46875 0.22158,0.94095 1.38165,2.46875 1.875,2.46875 0.62512,0 0.4857,-0.70545 -0.25,-1.1875 -0.40391,-0.26465 -0.73657,-0.80371 -0.84375,-1.375 -0.13031,-0.69457 -0.3891,-1.05593 -0.96875,-1.3125 -1.0027,-0.44384 -0.99515,-0.6542 0.09375,-1.875 0.48749,-0.54654 1.41829,-1.63836 2.09375,-2.40625 0.7279,-0.82751 1.48006,-1.40626 1.8125,-1.40625 0.30848,0 0.69724,-0.13474 0.875,-0.3125 0.58494,-0.58494 0.59452,-0.06168 0.03125,1.03125 -0.42435,0.82336 -0.52348,1.44551 -0.4375,2.65625 0.08956,1.26153 0.01501,1.71445 -0.40625,2.25 -0.52673,0.66961 -0.53284,0.67089 0.21875,1.65625 0.95555,1.25281 1.20948,3.64442 0.5625,5.375 -0.23675,0.63325 -0.45543,1.46819 -0.5,1.84375 -0.09647,0.81279 0.40444,1.19623 0.53125,0.40625 0.04822,-0.30044 0.34601,-1.20897 0.65625,-2 0.6898,-1.75885 0.57496,-3.80067 -0.28125,-5.53125 -0.34674,-0.70081 -0.48241,-1.29716 -0.34375,-1.46875 0.12902,-0.15966 0.28705,-1.24258 0.34375,-2.40625 0.09086,-1.86494 0.19075,-2.22202 0.84375,-2.875 l 0.75,-0.71875 0.75,0.5625 c 0.59493,0.44222 0.8463,0.96429 1.15625,2.4375 0.36574,1.73851 0.51236,1.9969 2.125,3.59375 0.95518,0.94584 1.82381,1.71874 1.9375,1.71875 0.25734,0 0.99476,1.66956 1.375,3.125 0.19524,0.74733 0.78198,1.57603 1.8125,2.59375 0.83021,0.81991 1.5,1.65084 1.5,1.84375 -1e-5,0.19291 0.23081,0.34375 0.53125,0.34375 0.90995,0 0.65303,-0.57035 -1.15625,-2.4375 -1.38398,-1.42823 -1.83008,-2.1147 -2.21875,-3.40625 -0.41612,-1.38275 -0.80466,-1.92313 -2.65625,-3.75 -1.18696,-1.1711 -2.176,-2.35409 -2.1875,-2.625 -0.02356,-0.55517 -0.1424,-1.22954 -0.375,-2.15625 -0.23819,-0.94898 -2.79423,-3.37499 -3.5625,-3.375 -0.35553,0 -0.69894,0.11681 -0.78125,0.25 -0.08232,0.13319 -0.56537,0.313 -1.0625,0.40625 -1.06959,0.20066 -2.66384,1.60689 -4.28125,3.78125 -1.1611,1.56092 -1.65626,1.90751 -1.65625,1.1875 -1e-5,-0.74607 -3.5926,-3.71722 -5.625,-4.65625 -1.82273,-0.84215 -2.00786,-1.01442 -2.3125,-2.03125 -0.41516,-1.38567 -1.08354,-1.97661 -2.96875,-2.625 l -1.46875,-0.5 z m -12.28125,11.28125 c -0.12939,0 -0.12994,0.52943 -0.03125,1.1875 0.27519,1.83519 -0.33347,4.17054 -1.375,5.34375 -0.48702,0.54859 -0.98162,1.23081 -1.09375,1.53125 -0.38544,1.03278 -0.65955,3.45228 -0.5,4.25 0.10841,0.5421 0.30867,0.8125 0.65625,0.8125 0.54077,0 0.60057,-0.35223 0.25,-1.25 -0.33045,-0.84625 0.36191,-3.20331 1.3125,-4.53125 0.47232,-0.65983 1.05452,-1.8114 1.28125,-2.5625 0.71319,-2.36269 0.4468,-4.78124 -0.5,-4.78125 z"
+ style="fill:#5c2700;fill-opacity:1" />
+ </g>
+ </g>
+ <image
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMUAAAC2CAYAAABpjkmfAAAABmJLR0QA/wD/AP+gvaeTAAAAB3RJ
+TUUH2AofETodKzgQbQAAIABJREFUeJzsvXmQJcl93/fJrKp39t099+zOzM7uAlgscQoQTgI8ROsg
+JEKXJVkWGbJkKUKHIyxbEbIjHGH7D/+hP/yH7bBFSaakECleIolLEImDBLAAAezi2l0s9p5z5+iZ
+vt9VV6b/yMx6WfXqdb+eQ4TJyYjqfq9eVVZWZn7zd/8SHpQH5UF5UB6UB+VBeVAelAflQXlQHpQH
+5UG5Z0X8EX32g/LDW/QfdAPu98QUUz7/p3j2g/L/z1IFxUHf73m5HxNTeP9Fzbnqcx+A40FxRdd8
+1pXPdf/vaQnvUT1VIBx0VO/Zr84H5Q9X2W8iV4HgvqvKOf+3g+o8dLkXoKhOeOn9lzXfp4Gjrt4H
+5Q9fmTaB6wChGQNCVQ7/t4PqPlS5G1DUgUECgfc/qJyrA8YDVuqPdqljiaogyL3/ufe9ChK/njsu
+dwqKKhiCyhFWDnfOXetTlAcU449GOSyF8IGQef/9ow4kBz3vwHInoKijDG7yR97R8D6733zqUcdK
+VZ/zoPzhK3WTtY5lcpPdASC1R+J9doe01wjuAdU4LCj8Fb4KhoY9mpWj4f3uqEYdK1X3rAflD185
+CBQ+y1QFQ+z9d0dgfxf2ehhTjPsOiqrw7CiAA0LLHm17uO8OHD7V8NmoB9Tij06ZBgj3363yjkpU
+ATGyx9Aekf0eU55H7n4x5Zn7lllB4T/QUYiIMRgcEDpA1/7vMAaHTzGq1OIgueIBMP5wlP0A4T77
+grNPJRwgHBgGQN/+d/OpurBW1bkzl1lAUSdQO0D4QOgCc97hwNEGmhG030Fw6gziyDJioY1oVZ4x
+UfQDQPyhK+IAgdv+riWoBJ3swc411M1vkb+6BVsYMPQZL7RugZ0GikPLF7NMOh8Qjl1y1KGDAcA8
+sGCPeXvMAZ0PEDz6QYK3nEc+HN07Y+GD8kesaNA30Ve/S/7Mp8m+PjQA2bXHnj36GEriWKqUsWaq
+avCbWg4CRZVlcvJDG0MJHBgW7bFkvy/8MYLzf57gA8eQq/U1C6L5eZqrK7RPHKextEjY7SJbLWQQ
+mGukLK4VUiKkbY4QCGnOgfnsrhXC/I4QCCFBmlcUUhb1IIR5cSnN9cVzsPXJcT3S1uO1AyGQUqLt
+87SgqEfY9mgBomirfabXNvcsGUi0xryDkCAo6nbv4N5b2HfRXl1CSsM415xDCO+8bSN+G2w/Cvts
+MO+LPeeeB6YdRX+Ye937F+Mgxu0Q9ne8z+NrXVsgj2PSXo90a5vBG9e4/fVvcvOLv0fv9QtTJ+UQ
+vff75J/7d2RfUAYcO4zB0cOwVSPGmiofGAeWg0Dhq10jxhTCAcIBYQlYBpabsPK3aHzkncg311Ue
+drt0z51l+W1P0jl+jHB+ARmFmPGSxSBpO1ClCWEnqxsEpDeBvYldTCQLCuEBCeHV455hJ7YBizeJ
+3fWMP4vKhDIPpAxENwGFB64CcOM6q+cEbiKW6y4DXaC1ngQZFBOu+A2893czYgyS6mfXTuG1TyDQ
+6FKbBf494wmO91/gzcDK+eL7PiXd3eX6f/htnv/f/in9Cxdrr7mFvvDPSf/la6gLlMHRY0wxEsY2
+jZmoxX6tq2ObfEAUQABWgJUV5PF/RPix4zXUIWi1WH7H21h559tprq4iAiMbFSt+ddUqrUqyPCml
+LE0+IS1FEN4q5IGlOqn8c/7qpyl/H0/y8So9XvkpfneroF9fLZDsaloCYjGxpPe/DIbx/WbiTwVF
+9T1de2192jR0cuL7IBVjELnP2ryhd44ySKaAAg/A1fMzF63ZfvY5nv67/5Dt778w8XOM7v8y+f/5
+ZbLvApuUgTFgzEZlzEgtgn1+q4LCaZp8tskBY2UJefyfEH38KHKlWlH3zBke+nM/zdJb30rQ7SCl
+dDTZ9rM/aVznu0Z4g166VnurvR1I8CaFXz/jOor/MK7aH+Dx67s6x2MqxgOL117XXPfcUpvFuC6v
+XcVyJLznVj77E0iMGzYenqIt/nuLYv6WAFPqH/c743t8yjXuNLwH1IBifF3RvBL4p4DFP3dQEYLW
+8WM88jf/BvPnznLjC7+LzrLi5xDR+BHke/fgwkXUBmVrd9UN5K4phc82OTliDsMyOeqwBqxFcPR/
+ovmXTiLWSpVLycq738mRD76foNH0VnSBHsVkoxE6y9BKIbQek3cJjoVyPHqZCpjv5cluV1pZXbnL
+5xFGHnDtc3X6/K8o8fTgs0EFCOSYUrleHrNMlOQhd33Bi2s9ZnW8NtS1A3vtBDVyddcB0e8vWZ6Q
+2rJowl/NXd3Fe42BqN05t+J7/SO8thYygxhTFr+9xTsLLPUZ9z9CIKMIEYXIZpOg20V2OuO2e2V0
+4ya/+yd+mt6lS6XzCbr3f5H+z8+jXmRMMfYYyxczU4tpoHBUwtkjHIVw1GHVHkeBtb9F9FPvJ3iy
+XIPg6Ec+xNq73gWB6dR0Z5d0e4e83y8NshsAd994oMedTvXauglS+c3/PlMdBzzPb6+/Kt99Hd65
+Ga+dZI/q+6H82wH94/X/Ydo8MY41106Ob00dxT0ggoBgcZHGkTWiI2vIRqPon6zX58s/85fY+OYz
++GUbfemfEP8PCdxkrJ1y8kVMWbaYWqaxTw4UVUpRFbCXnyR49C8SfkRUAHb0Qx9g9d3vAq2Ib64z
+uHyFdHsHFccTD5o+oSvX+df6dRw0Qe6kjinX+u013yuTua7+A+uwRQqcXCEEOArla5MmwFOts6be
+qc+rtqsOoIepo9r/1TqmnJ8EIaA1ajQi3dgkuXYdNRwh2y1ko4FsNDjzl/8CVz/5GZKNjaK+FmLp
+JDJ9mvwHlH2jfKfBA1koOeW8oAyMOgt2B+j8ecL3VwGx8PhjrL7rnWTbO+z+4CVGN9cNH6hNW7TW
+5rPW48+V86XiXzetjup1pdv14evwnl1bR+l5TNRRun+WOgxjU7CYIgiNMiIIEEGACMOSalfgjWzN
+u9X2Heamaf1QV8f+733Au1WuLfXPvnVUXiHPiW/cYO9b32H46mvoLEO2WvzYZ36ToNMpXfs25MeP
+G9beuRbt50FRW/ajFFUwOENdYZd4Enn+TxK+z78xmpvj1J/+k8Trtxitr4NSB66+xeeJ81UBbsbV
+vu66GVbK2utmXjmnrOCzrL7CyD5CSkQQIMMIEQYEYYSMImQYIsMQEdhrnHxi7xdCFBNr+upbpmL7
+9cO0Ourfe586plDfAymG/VutA63J93qk67cI5udprK6w8s63c+lXfr2oS0L4CMH8l8m/wdiB0Anf
+M1GKOguzqBxValF4wv4owRPVm1ff825G12+QD4elAfOFOVe01kWH+IJb+fyYnJbIsv0+UYf/vOKN
+7HXV+2ufN72O2raXrjXr90x1eH1STFwZIIMQ2YgQUcMYMcMAISRo4/ipshytcnSWGeWEMiuusCuv
+/y7+u030vzYtnXptzflqH0ztZ8rjOW38CwoxtQ4rkjvQ2/tVktB/7nnaj57n2I9/lLX3vZfbX/9m
+Ue1DiA9Q9rXzqcSBZT+3CweIaTETjceQZ0uVzc8TNBpk/X7RAQdNkMMCo9TZ7vfDAIPKBLkTcPnP
+15rDAsMHqKuvoACNiMbS0phdisKxtkcpVJqh8xyVpugsQyUJKI1SCqHU+Hk1oD+o72YBxkQdhwVG
+Xf/v+7wyMIo6lGL4yqsg4N3/+z/lt9//keKdQuh8CHnuKdQ25Rgef7GfSi2mgaKOUvjUInoYubKA
+6Po3tddWCwpxJ6tvddIfCIxqHX4HzwKMyv13Ba5S+2cEhnu+MMK0jEKCKEI0Gpz8Ez9OY2GBdDAk
+6fWIt7YZbW2hhyMDiCQmH8UEjQZ5kiKyFJVloDTk+WzAKDWKiQXiMH3n9/+hgVHT/zMBAxi+8hqd
+Nz9O9+wZ+hcvFXV9kPCjT5E8RxkQM1GLOpnCB4IvXDsv2Hlg4V3Ix95G8Lh/4+KbHkOGYamz/BYc
+yNdP4X/9u/x+nKijwr/PIkdMrWPWNvttt/8neOZ96pBWPpBBQHN1hYVHz9M+cYJ4e4dobRXRakGr
+Sbi8RPvkCRpHjxB2O8a2E0iEDBCBlUmEKM/xWdvsf69p68x1VPr/wOdV+qbou9rxn7SGu0/5zi7h
+4iLrX36q+E1C9jvkv8M4GMnZKQ70g5qFUtRRDLmKWPRvCNptZBRNsBeHZkuYXEVmpRjVlcar4OBV
+r1qH3/7DUJ0q/6xnoxgaIJC0jh5l6W1PorUmTdPiyPMcrTVSSqLjx2ieOE62vcPw4iXSnV3UYEAm
+A3IxQgqBylJQujCM7t/mSfniUH03A3t8IMWoslE14z+NYqgkodFu45cmYpX6QLYDKcU0Qdv99wHh
+/ktAthFN/6YgCvd9Mft2hwNGtY6i/tmAsR+4ZgJGzfMPN0HE5BBU6tDaTFy0Itne4fbTz5Ds7bH6
+vveilCLLsgIYSimEEIRhSBiGRIsLLL7z7cTXb9C/cAEZhaQ9gRLGFqSyFOtgNe6/QwBjFuXELMCY
+6P9ZgVHb//XACJpj4x5AYDgcf+76gNgXGHcSeec/aNxepYqGl16sZvUtv+RswKgOUKGMmBUYnvbC
+r2AWYOynOZkJGOjpANVGY6SUIsgVKs8ZXrtO/41rhGurKKVI05QkSciyrABFEATkeU6z2aR1+hSt
+lRW2n30OrbU12Wqk1iidWdCV3/9QwJjSB7MCY5bxPwgYtQD1njdav0WlVAFR93stC3UQKKromkqC
+8jgpsRqlF9tvkh0WGN51RTkEMPYnz4eow2v/oYHhT1CtQSl0rsizjCBNydOUvddfZ2l1BadmzfOc
+LMvQWpNlGWEY4hsZm90OK+95N1vf/i6JvoVWmlwphFZopSYE79q+mwUYlf4/LDAm+v+wwMDjFLx3
+2Hn1Nfyi6+ftTGWaRbta6io1PWgPnSbGuc91vNbFKli8pPvszlfLftfWnq/ervevwz5jJuvvrHXU
+PL/e+sv+dSiFzjOyOEElCdlej2wwKNXtKIpjqeI4Jo5jkiQhTVNEo8Hy299GMDdH2GoiowhkMA5E
+qnu3av9jhnS6tXlK3/n1H9CXdX1Xuse1Zd86KNWx99rrjOdjUaZRiH3Lfm4e0z6XAOJ/yfr9ccNh
+dmBUQXInwKjef0hg+M+/p+Aqfae2Dq3sam7tD9lohIoT0q3tQjvl2zUcMLIsI0mSAhRZlhHOdVl+
+4i2IVpMgaiDDoPBM3u/dJgEyOzAmJvlhgVF5/p0Ao/f6695ELeqqLuYzUYv9KMWBFVT5qazXr50g
+hwJG5f7DAqOOAh0KGHXtP2wdNffvCwylDKXIcmNjSFNUHBOv30ZKSRAEBEFQ4qmVUgVL5Y48z1FK
+0T51kubyErIRIQNrEbdjNPNErem72msPBNchgXHQ/KkBRrx+i3SvV7zjzHzSlDIr+1RbqqDI+73J
+ieOVQwGj5v5DAeOgDp5y7awTZOY6atvPRB2qoBYZKknJ45hkawOhVAGKIAhM/La9TymFkzeUUsWh
+ge7DDyOiaGwZdzEih3nv6hAcBhhTxm9WYBy0uPnfd1+/cBBJOBROqoL2tLprAVg9mfcHaD1F8wNl
+4XIWYdjeU1xXtX1M1HGAqvYObAfTBPtZ21ycnxDsJ4VvbamFzlJjtR4lZLu7hAsLBSjyPEfY+l1d
+1QOgubRUgMEY9XR5js/aZs1Y8D6EcqJcx50oJw6YP97zBleuTrZlsszMRt1TSqFGI+OsNmVFrVsB
+Ds3aHLCC7Ecx9lvBDsUmVJ89ax2uH6Y9WxmVrM4yVJwYanF7gyAICjWsoxZVr9Nqu4JW01i8hY0F
+r1Knmr5zk660Egozutq1fb/2z0gF6p5/IMXYh4L0r14dt3fi18OXWUBRK2i7LiwdWqNG8URHTRWc
+quUQwNif/2T2Okq3HwIY92SCVG831EJlOTqJ0XHM6Np1hMYY66KoMNxVWSofLOPAJLeyTl98imuD
+oPhPYP87J8XAJYoQE+2t6/+D3/uAxa1y7dT5Y88P37hWquduwXFXycnqHq6GQ4J22zTe+10zRQc9
+jT06pNV7kj06pNXbWymLgblD457/253YMHSWodIUNYrJe32yrU0aq6uF7KC1LuLMfSoipSzOqzRD
+a2u0o2aCWjBgDxmGaGnc110/SCkKCiNwk1YV7+i/a6kPbF8exB5N9GXlfv/aqfMHGFy9VhoLr9wR
+Pu4LKPyyn4xRCwz73avg8Ma9O7Gc1/G+lXc4NLjss2cGhnXjMNQiQ8cx+XBI/7ULrB49SrPZtI8W
+JXA0Gg2iKCpRi2wwQGW5oTq5Gq+6gBQ2cUAYIoPA5N0K7WEpBEIU1F+rHJ1r64Wr0Cofg6Sufw60
+nB8gz0wZ/7r5k2xuoYZje869YJ/uOo1ltRF6FJdW+urqOyswZl1996/Ds3weFhjedf7zDw0ud7jf
+/fprgKGUMpM2zciTBDEcMlq/RXJ7w3jNCpONJM9zwHjZRlFUsFaOWoxu3UanKTo3ExnrhuOeG0SR
+0U61mohGg6DRQDScXSMYj5lSSKUM5UpSqwTIUHmGsMDcr3+8Abxzq3e1fm/+DN94Y/xeTFCKOyr3
+nFLo4bA8KWpW3xJomAEYB6y++9dRcQlw9x/wvKmDCwcD1AOSdPdW68AAZAIYSqGFQKsclSTkoxFh
+v8/Oc89x7Mc+agL3pUQ5XzMoyRlCCFSW0b94iTyOzWS2AMLJG2FojHutNrLTgnYb2WoRdNoEnS5B
+q0EQhOa+NEH3R6R7uwSjmMzGy5BolNZFxN+BrGbN+M0MjMr4+/NndOPm5By4y3J3oBA1oIjjWqqw
+3wpSXGt/O3CiTqEgBwLjAPbooDbXsmd1ABXCgEGIyXy1DpCV+31gOGFbyAwxHJGGIdzaYPt7z7H2
+nneXbBVOsPZZp63v/4Bkd5c8SYxqN88NayaloQ7NJrLTQc51EZ0OzRPHaRxZQzQahSeukJKmFe6j
+KEIoxej6Dbaff4EM0LmJ9CvAOQsw/P713n9WYNSN/2h9vfh8r8BxzykFylhkRRQB0yfZvp1zJyv4
+geDaP3LvsMCYClDLi2thAod8zQ6OOOY5heBb1wfK/FFZhggk+XCICAL2XnoZGUWsvvPtxX3C+y+E
+oHfxEtvff4FsMCAfjcYx3WjTnigi6LaR3S5ycYnOo+cQ7TZJmpIPBoWcEgRBMeEdizZ/7ixCCDa/
+9R10mpk4cdsnddT3Ttijfa+tkS/i9VvF9+J27q7cJSh0bQNUHJvsE/b7gcCYlT3ab6LWdfAhgeE/
+/1DAqNahtaGiUjJ39mHS3V0TMopAa4XOA1SeI3LPpuOzk1qbsNIsI7cUx7Vl+7nnyXZ2WH3XO2iu
+jDOUqiRh8/nvs/Piy2T9PtnQ+E/pLDXVCgmWbZKdLnJ+ju7j58nDkGQ4JMuywiLuQODc1H1WrbW6
+iggDm/Ba4LRT1XIoYBww/vsBI7llXMb9eXK35d5TCoAkga4N3z6AlaoVvPdjjw5ibex3v8wKjDvR
+XtWetwmgRRCQD0e8+e/8bV7/d79K2je+YSrLEVbtiksbiqEuJXZKA1mGEpBj6ta5Yu/V1+hfvUpr
+eYVwfg6VpsQbG8bgZ+WQ3ArFOlc2AUKEbBm2iW6H1sMPkYdh4WXr1L1u5fcpRakrshRsUmk7IKBB
+M6X/75I9Ouja0c31Hy6ZgmmNsFkAJ20HhwAGTGePZgBGtY5DA8N/FvtfO3HefZSCbDhEpSmP/62f
+4+JvfpL49gY6y8jTFBUH5GliWBGVI5Q2wHDtVaCxxjwdE2gTd6HSlGA0Iuv1jQpV68LLVlvNkLFT
+WIoVBohmA9lpI+e6hMtLyMUFYs+71mmznHbL/+8vUvHWNs7+ofVYq1UHDH/8D8seuev88a9em8cx
+2e5uccm9AsddgWJaagSdxJMs0AGr737AqGWP7gAY5WffWUiru796bVFH0X7z/kJKtl58idM/9ZOc
+/2v/Odd/78vsvPwqIk3IwxCRhOQ20bTKcpOmxr6j1hqhBdpOWJVQgELFYSGraIFht5SyE3Xs5ySC
+0Gis2h1kp4vodmmcPEnqhbm6+G8Yg8L3zvWNgsMbN8FGCGLtH2OL8xRgVMdgRvaoVEfN/fEU1ulu
+qcX9oRRJsg9fPxt7VHyvqWNW8jy1jkOwR9V21YGkNLjaTE40aGXeY+eFFzn5Yx9BRhGnfvLHaR8/
+xsa3v0s+GpH1B4gwNMK0TFFZbu/XOGFcYIChtEYoZWSRPBtvXlNdjS0YRRgimw1Eu4Oc6yDnuzRO
+nkAFktSGtzojoGOZnIXcPxwwsr090r2eMSw6QNj7x5N6OjDuhD2qrcPen25tl4TsKjjutNy1TFFb
+kqTcOftMsqKDatij4vt+dbjvU8jz/nXMaNyzLFGhZrWTzghVojQKZnV3wDDu4CpJ2Hn5VZaeeDMA
+S299gsbqKre++QxyZ4dgMCSLItLhEJEkRuuU2dXbZ0889afO8/KGNDBO6x8GyDBANpuITpdgrouc
+n6dx9Khhm+K4oBAOFI5COFA4Vawfy9G/+gbK2j50nhtq4cALhwOGu3bccYcDBpBub5ufKANBsM/c
+nKHcE0ox0YA0tSRVzASM2gl+GGAcoL3Yv44pxj3HSwtvrwgpkYHbWsxNSNMLJVA6m4RNMaOVYvPZ
+51l8y5vMaaVoHlnj+E/+GNvPPU//8hXD8/cHqNGIbDg01mxrX9C5Kvqi1F/W0FdyEQ8Dk5y51TJq
+1/k5gqVFgrVVwmNHGVUAAWWWyXc6dBZyIQQqSRhcvUYWx9ay7Vw+LFAnqO/swLhT416yueUtaqV/
+d1XuAhSGrNciUilQuXUXOAQw3P3TBOxZ69iPPautw5Mv7AQZe4har1EZjBMdF1RCmhxLaMMquZVd
+QLF5pHUHH23cpnfpMp2HTqO1cecgCFh6x9tpnzrF9vd/QLK1Rd4fGLeLOEbFsQk6KvyXFEI7ecUt
+JMI69NnEzFbLFHa7iG4HubBIeGSV6MSJkmBdxzY56tBoNGg0GiUr+d6Fi0ZpEMcoF4/vuXnUskeH
+BYY/nt74T7s23dnGO22wxN2XeyZoVxuj0gzdHCcgPFDGmCZ4jys4HDDsdf79xbU1dfj76iGl2Vkn
+tEJqFJqEx1Foo9lMiGdJM+W0P3kOWW4ng61PKXSWsfG979E+dRKly9FycmmRlff/cYZvvEHvtdfJ
+e33UYEgej9BJSp7YSegSQ2j7JgKbg9YY5WQjMh7KrRZyroucmyM8eoToyBqJlybHF6ydvOCzTFVA
+5MMRexcvGWNgko5dRzz3kf3kBr//ZwZGpY469jjd3CzLFGVO/I7LHYPCsdPTkKnTFJpN28LJCw8F
+jFnZoxm1F1WB27FHOggIGyEiCgkaTWSzaTYKabXN56bZMMTtGyGFoFBLWjCoNCUfxSbW2kbJAehc
+Ed/eZO/CBbpnzwKQ53kp81/z1Emax44xunaN/uWrBIO+MYSOEmOvcJNR5eO2u/0rnENfu43stpFz
+czSOH4dOm9gmN/DT5Lj3doBw1KHZbBYslAPF9osvkfUH1pcqKcA/m5rVUov9lBMH1lE//tn2NhSU
+SJTAIdykuINyf4x3gExjct2xE9Vc7bNRcAfA8L+73w8DDO97ISu4CW73W5OtFkG7RdjpIDsdgk4b
+2Wkjmi2i+Tmaa6tECwuIKDSJBlSOSlKy3R7pzjZqODLJjwcjdGImc6EgzXK2nn2e9qlThQyg9Tin
+E1iXilMnWTl1knhjg/j6OtnOzphlsZofJ8sgpUnX3zCJmUW7TePIEYLFBTKlSEajon7lsTtOhvAB
+4VzQnSwBMLh+g/4bb5APh+Sj2BgFnYzjZJqafj5I8PbHblZgVClIurPrjf0kOO603DEoDtwSJs28
+5FsUFGM/8nooYFTrqNFeTaMYAoyLgrcXRNBqEc11CTodxFyXcH6OoNshXFyk/dBpmkfWCNptNJRW
+Wlc6jnKkKenmJqMrbzC6cZN8ODS+YFqjVE4+GLL97HMsv+udOMOYkzH8GAkpJXJpibnVVchy0t1d
+sl6PfDAk6/eNTCIAGRjv1jmzeaJst0mzjNjaIHz3DR8QTsvkU4gqKPLRiO1nnyfrD4zbSBIb13Ff
+8K/0/2GBMb798Ma9vNZwNwbHnZZ7TCnGHSWyBLwXcy9VfdH/ZMY9T5tEaFPeN5uE7RZBt0MwN0e0
+sEAwP0cwP0fj2DHap08RLC6ggUwpMmt/KfWBx4IVGpxjx2ifOoUexfReepnBpcuoODaGuTynf+kK
+rWPHaJ08Uc7CYalGrXXZAjXyVlkoZ/TI8txorqy84qtc69SuPoVoNpsljZPOcja+/R2S3V2ywdC6
+jiSWOqp9tYfFGHAwMO7UuEeWmT6tzLxxLZMuKrOWu5Mp/BesFGmNTe5a86HMxggwsQN1LBAcHhje
+cybaa1mlYpegVouwaynC4gLRwgJyYY726dO0zzyEaLXI85zEqpd94PkTwK30BRUSgjzPzYobhSy9
+6x3MnTvL5jPfIt3dQ6gc0pSt7z3L0bk5wrlucb+jGE7OqKNI1cnng6p6+AD2Y7mdUD0NEALB5vPP
+M7p+k6zfJx8NDfuWlvPSHqTgOCww9hOwq8DIbJ6nohpvjvjf76TcH4s2ILK8fMJfEaYJU+5SJge/
+jj2C6cDQMFatWmE0aDYJ2m0jJ8zNES7MEy4tEiwu0j51kvaZhxGdtlmt47hk2HJHwdrYmAY3kd1q
+DZRWaq01zeUljn30R9n42jdItjZRaQb9ARtPP8ORD3+w8Ej1i6+dcpO7SqX85wMT17o6fQ1TEAQF
+m+T+l4x0CLa+/332Xr9ovG0HVg2bpIXNxR/3mTR/jCf3zMCo1lGh+tnu7gQQ/HbdTblvgrZQRnAs
+gQFK0Wale72JXnROHXmuyB4wCQw/wMepVIN2G9luE851CRbmCZeWCBcXaRw7Svex84hOx6grR6Na
+gdStsO5zEUcAhZrTGcVgvIK7OhqNBkc++D5u/u6XbQBQit7c4tZXvsqRD3+oAIZ7nhO8gRLlqHqu
+VikClNk/zuvHAAAgAElEQVQuP+uHkxecytVRjCJACdh67nl2X3mFrNcn7ffHgPDd3GEqBZ+q4PDG
+77DA8AHursl6vYlr/V64m9xNd8k+TQeFzDOk1oU7dGmi288+MKZ1bMGeoBFMplkpBkkIpMAYDG12
+CtloFGGW4VyXcHGBaNF4iEZrq3QfPU+4vGR48TiesPK6lXWalRfMpAzDkMTKG3XsTzExWy3W3vMu
+bn75q2RJQj5IidOUm1/6Msc+/EEa7faEM141JaYQogQMn4oVfe9RM99/qS5NTuHsl+fc+tZ36F++
+TNYzFCKPY7OnnmfXKHf94TR/ExzAYYFhPwMom7e49Hzv892U++IlC0BWdRQrU4Yqu+A0VT4FKFMM
+MMKTk2bc1rmA8FK1RGab3aDZLLQywfw80dIi4eIi4fIynUcfoXn8GJlSjOJ4Ql3pO8b5LIY/kXxZ
+ws/aVxWaXYZwV1/z2DFaR4/Qv2TYkixJUOkNrv/25zn2kQ8TrSwXk7kuT6wD3DRWyQeVT+F8YPjA
+FkKQ7e1x+5lvMVq/ZTVNpm3OpV1rhTNElnyt/O+WApQm6UEaKb/sd23N+Xxvb6zEoR4cd1ruG6UQ
+KkcqhbZkWVeAMY098jVH7jnmgyje2AwmNk+RlRnCyBjdmk3Ctgm3DOfmLBCM3NA9f47mqZMoIRh5
+1t2qU5wviFaNWf5kyuOYpN9HWNA4QPjygNMmuc9BELD4ljfTv3LVXDOKyUZmVb76H/4ja+96J4tv
+fUsJmC7LeJ1GqdTnohyv7VOcuqRpaE3v9QtsPfd9sl7PaK6GI/IkLrx1BcLaVJzF36a/kRJ/aMxC
+xXiMKwtbMbZUgOGoRYW9OggYmU2lVKUOP9QyBQBZVsRq+xSj+M4kZZhQzXnP0lYzIqU0BrcgMO4Y
+zYaxQHfahJ0uwfyc2b54cYFgYZ72ww/TPvswOgxJvJW3zinO18g4rYzPd2ulGFy+ws4rrxJvbIIA
+2ekw96bHaBw/XoDHyQRVYAC0jqwhWy3E7p6xUntpMm/9/jfoX7nC6nv/GM3VVcIwLLRZPpWoyhI+
+pagqBJwMVIqLuLnO9vdfYLi+boAwGqGsylUrZSZ+YNL4yzAc+4I5T1yXNE0r8y83LC4amyvKegnr
+McXQzKCR2k/zZH/XWqO9XE/+fPoD1T4daLyDImAGxpqTKt9ZFZpLL0/5ZSUYt+ggNF6ljYig00G2
+O4WxLZibJ1icJ1hYoHP2LO2HTqGjyBiyrHXXX21hbMxybJIDhK+ZkVISb2xy86mvMbxxk3w0NJbd
+QBJ1u+zEMcuttmmDvd6BYGIiBwHdUydIbt9GW00XSiEsD5/FI0Y3bzH/2CMsPfEEjZVltNaleGmf
+UlTVxW7i+1RNSglaM7h+g92XX2F444axPcQJKk5QWVpMQhFGxhvYJksjCu2ut56jZMFCYb1ljcu8
+zo0PGMo4MaosNU6MKneoMM+paJMOa9zLhqMfUu2T2L8RUquxraJCHt3qIaFk3Cvq9s4ZsUGabBRB
+gGw2CNtGXgjn5wmWFgkXFwjmFwhXlmifOUPzxHFDGdLUDL7n6jAthqDRaNBqtQrrrs8y7b7yKje/
+9BTJzg5pv2/8m1RuA4RGhEqx88IPWHrvHysJ4j7/70/k5vKKSY+vtdmPIs0AAwqVJMaFfNBn9+XX
+6J48wdxj55k7fYqo1ZoAQ9V46QveAki2dxhcu07/0iXi7R3y2Dr2JSZZmnbuGkGAiELjbdtoGOfH
+KEI0QuOOHgYYj2Ijywlpx0xh/LGUMs6QuclZhcugnmXGL8w5TGpdBFLNasMoaa8ARqN9tU93U+4r
++yRUbue1x196wtiBmgp7rniWEMjA+Cg5eSFaXSZcXWXusUdpPnSKYHmZXGuSND3Quuv4byc/OEBU
+ZYjN7z3L+le/TrK9Tbq3ZzQzibHYyyg0kWhhSLC1aVSFVr3qq22roAjnutYF3WiTVJqglTbsVJra
+BAQxYWtI1u/Ru3KFsNWisbJM+8QJGktLNObnCKyTotIackWemvvS3V2SrR2GN42riUrTIh7csWxm
+gTIRembyR4TtFrrRIGi2oBkRzi8QLcwRdDoQBKX9LoRd3LSd9DpNyXp98p1t1DA2W74laaHWFWky
+jtqzsSKub2YBhi975jUyxb0Cx30z3gEI6yNjXsQCo2D6xpO9RCEsdSgoiHctQiDDgPbaKgtvfhPz
+b3oTnUcfITp6hEyIYqsr5xFaNYD5PPg0624VELe+/k1uPf0tks1N0r0eaa+HGsVmUglB0IgQQhKM
+jH9QuruHWF0psTOld8NMgqDVGq/oWqNy414OmBiK1MoZw1Ex8dNGw6z6V64at/YwNHvaCWHTzeiC
+PUHZhAeZSWSg3Qpu2RghBETGwi9bLWS7g2i3EK0WzSNrRMvLyE4bbUGbefX63r8Fe9YwcRyNpUWC
+Mw9BmpFtbTG6dh01GKJGI+OWMRoZUAoBeWYCsdxC5cZ6BlWt9iiFPw/d738gMsUsD5UqQ2lVkFy0
+Rgv/BUQBmgLpFe0D9px5UY0IAlbf/W7O/exfRzQbZFlGHMfkNqLMD8avgqFqkKsDhC9DbH7vWW59
+42nizU2S7R2jrrQCKVoZHhuNbDZQSQZpTtYf0Fhb3b/vfLWmG1YnnCpFrhTSgsRQjdgGONkgojAo
+rPTOao9beLRfl/lv0mba36RA2LgQ2W4hOsbvS87P0Tx+gmh1GSVEYYx0CgNnlHT9WLWL+IbCwr5z
+9AhLJ46TbW0zuHCRbHePXEqT7SVOUAKTUE15C6CezbinhiNzutyLPwQyBSD3IVYFpQBAeQK11WAI
+isF0FGQCIO6/A0aWs/7lrxCvr/Pof/P3kJ1OaYB8obZq/fXdHny2yQfFWIZ4jRtfeop4Y9OwTb0e
+2XBk+H+Vg9ImBiMMbAoajdLKrMoVquQb2Iq2Oh8iF7GHHvsVKWWTFJhAHpFJlDAGycLVPZAF+yUK
+UHjAgHE+KXvIMEAGJu5CdI2WTnTnaJ4+SePYUZQQxBW7iO9C4vq32p9VFxhnC8myzPTr0iKL73w7
+w4uXGb3xBqIfkAuBiIXZ8zvLTHqfCtj2A0ZiA4zsZfdUrrhrO8V+RdqU7W5yjzVNxginjYLVapo8
+R0FzYXEPWlsPU5MGXicJw2vXufzLv8bD/+V/URoQ99k3qNUZt/woM99dWgjB4No1rv3O54g3N4h3
+tk2GPxd15gTFYmU22iTnY4WnOq36TfmTKI9js4pb6mAyf+hxOn5hlhx0XsQtqDwvKINye0mYl/K0
+QR4w3DOFIGg2jeau3TaUYXGBYHmZ7qOPoJtNYi//00F+V3WCvetb5xCZZVnJdtNoNOg+dp7G8hK7
+L7xo2mZHONegdVYkay4J1u557nOuuPDrv0E26BPYV60Dx92Uu7Zo7+djIt2mIRX5QQifPRpbS90L
+6mJ8xxqpYp+Egtce0n/tda5/6tMc/7M/PbHDj2/99QetKkdU09hnvT5vfPZ3GN3eIN3eIdvbIx8O
+CkAY4dDbKUhIEBIZGW1N0OnUyi8+YAGyQd/U5ewXjkowngQlgFhXjNwCQwsBIhsb0Xwq5Prb2XMa
+ESIKkG3j9yWXFmmeOE7r7BmjlBiNSoCoWsxd8bVddd9dyk2fUldtQY0jayy/7Um2nn2ukFO0pYzK
+k4l8+cLN9GRnl5f/5b+id/ESR6Tdx89DxL0Cx32lFE4fXb5xUsAea5qwbJJdJXGrkEZrm+8oTU1k
+23BItrNL/8WX2TvzLHNvf1tJ7er7CrkyLdKssPJqzRu//TuMrt8g3bYUom8BUUpvOeZWRGRzKzXN
+Xg/BXJeksuNQlZIJIUi2d0yqmIICqjErVaeFswY1oDCuFX3sPrvV15MxZCBtmGqHcGmBYHmJ5ulT
+NB86TeIFIk2jDv6kd+fq/rvip9706/KpZWNlmaUn3sLO89+3YbvWzmGF+DpV7e6rr/HKv/63pHt7
+ds7o0hysA8edlvuqkpXaS9Pu3QMU6SGBsd+TO681joIUQrqdCDo3O/yoQZ8sDEk2W9z68ldpnTxJ
+Y3Vlghd2gqJz8JumaRJCcOupr9F79TUjQ+zukg8GxgcoMxuUGEWBY0kgCEPrY9VCdjsES0uGfRoO
+i8nhu1w4KiGEIL69Md5pyFl/fRmoDhiV81bfPQaGa59j22QAUYOg0yFYmCdYXKT58Gmap08XWjrn
+WzVNZqiqln0NWvX6uvN+//sLRPP4Mdo72+QXLiFtcjfniavzvGTcu/6lr3DlU58p9Y9LiTGhfboH
+wsV9830CEM7KaQfMv9YfVKoAcQNc1G9XRpVDhlHnDUcIGZBGIUGrwc3f/jyn/spfpGH3WKiqYp0c
+MU312nvtdTae+RbplgcIK1i7SDPHBzt7iWg2CDttwrl5grl5WqdPkqbpBJXw/Y1MVFtmcsqmYwrk
+sglWLbcHAsP1oytu8lq2KbD5n4LFBRonT9A8dapIqlz1/RpXJyb+V5UZdVo9/3egtDD5htI0TZFS
+Mv/ooyS3N40RMbX2C5uUQSuFimMu/Nq/Z/O7z07OrUqf/HBon8QMoLDsU5kClKqYdBQUYvzCVdYL
+TCLiVKOEAUcWhiSNBuLKZba/8TRLH3z/hNXaTdCq6rXwU9rb48bnPm9sEbu7NtpsZA1N1m3aE1qR
+kqDRIOp0CRcWCJcWaRw9Qri0RGxtJEAJEH6mveH6Lc/XKCuE9+rkmspKmcrLAqh9nmmfKDJ8BHMd
+wsV5wiNrtM4+XOR+cuCtAqLqGuL/N00aA6IKqKos5VgooFDxlrx1m03mzj9C2uuj7QYzQgZopRlc
+u8Zrv/jLjNZvTcwBJ8fWyRD3Ahx3Z7wTB4DC08GXKIMtZb5xzELBeLNCc3v5N6UUMk1RUiIGPfIo
+JG002Hr6GTrnzhAdPz4BiqoKtshYoRTX/+PnzL5y2zukeyY5gE6SIoGwUw4gzGQL3VZYi/MEy4uE
+y0t0Hztv4jK8FDK+itKfbIM3rhmLdWL2j8ATRif4aa8PDgSGMDsoCWkB0ekgu3PI+Xk65x8hU6o2
+qbKpanpi5SAo5+9ygKhqqqYJ5w4cPjCcdqp9/Bj9CxdQoxEiDCCBm1/5Klc+81ljD6ot2gjZdlb8
+0GifZnEIlHrMPpWQrMdCknsRXQHGWH1bNu4Vk0Apw36MJFnYQzYiso0m65/7PKf/2l8lst65QRCU
+2KdqftSNr3+D3iuvkG5tk+/toQYDdBxbpzY15qutY1zQaBJ2O4TLS0QrKzRWV+k+/hiq0SC1gUru
+eX4IqM9C9S5eMv5NNtO4iVegoEiun/x4hKKU2ErKwLD3uwCroNshXJijc+4cOopKWqaqd7DvYl4N
+QnKg8AVop9Rw9fnp/KdRDPdcX9MVBAHtEydItnfJh0Mu/Mqvs/ns82O2uoZbkHjKminguJtyF5RC
+IQgOZJ9w9gddWf381d8Kh5OyBMU5UXy1n5SyG5oI5FCS2Qzb8uo1Nr/6NdZ+/MeKSekmqR9FJ4Rg
+cOkyt5/6GsmWr2kyaVyE8rQmhSNii2B+jmh5mXBtlcaxo7TOP0Jw5AhxMg5WchOtDhDJ1hbJ1lYh
+qyAEJjuhfX9hhneClaKiaarKHli2QkqjEeu0jfC/vEx4ZJW4Rqg2l5cNbtUMgVUlgc82ufqcjJCm
+qR2aSS1WleXyWa/WsWNc/+LvcfmTn2F44yYyDFByP2X/JOukPcbpoMX6oHJ/Be3SCuaTtzFv7vTs
+ThtVMrhByYO2+M6YipDnqDhBBkOy3T1Eo8nOM99m7pFHaJ87W4DCd0OQUpL3+lz/D58l2doi3d4m
+7/XMPhFJOlaNBoFxn240CLsdRLdLtLREdGSV8MhR2o8+QvPMmE/3qUTV5cFRpt6Vqzb9JYVsIoQg
+zzLj7+UWEq3tfhPGEOeoSJ1xq1hVhdlnL2i2kO0Wwdwc7bNnyLz48Wn5n6YpIVy7fTD6NggXVVjV
+UsFkIgX/Pv97NNeld+my8YR2GRilnKhv2jz0i74HUsX9C0d1v3nqwuK8FBCMXRSEM0aBNVhhEwlT
+G9JYeoYyPkJ5EiP6ffIgJG1E3PzsZzn3X/1Nwm63mKhAof259unPMLp+nXRnh6xvAEGWGA0Xotho
+XbbbhN02cn6eaHmFcHWZYG2Nzpsep3HyRJGS0k804K+8vsrXBSiJMCRoNAg7HVQUofKcUCsTqJOb
+jRtVZvbEK+wj2mio/JRAvuwhhDBBWGFovFu7XaLVVYKFeeMb5hnmqm30k6H5SQ18OchfrBxL6tif
+Ut9qXcSrVw197r8PCHfdwqPn2XnxZeNYaCl5Cfg1c0tXvt+rcn8phVvxoMQiFSuP78sjBWjb8Sov
+XDqM94MuVKETK4czqCUpuRwhg5BsKyIOQq79+m/w8N/46wTh+DWFENz4/Bfpvfgi6eYW2e4uamgE
+a5UZ1xAZhSbQpm1YkGhpiXBlhWBlmXBtjc4Tb0YuLhZp7avCdZVKuFU2vnWLXGlEu0WgF6DTsiko
+lfEvVIo8y6yBMkEniUl9b4OAyHJzLfXu1DIIEM0mQbuDaLdpnT45kTLT9b0fQ+KCqupcXnSSMlxf
+Z3jjpglZTVOCRkRjaZnm0TUaq6vQaBR9W40dKbwXarRXrmit6Z4+ReAAEQRFIFMdnRCV/1Vw/AHK
+FHbS79ME4/ukrZxgeOdCPpCSsNM2/LQFBlBk71ZpBlmG9CycdVTHnNaIzBj1cuuDlMqA3eee5+Yn
+P83Jv/DxYlA2vv4NNp/6qjHQ7eyYDN+xSYgstC4yjQfdLsHikskLtbJMuLJC86GHaD92nkwIYpvw
+wBcw6wDhVtE8z+mt30J02gQCRKeDzHNjS2g0DLXMc7KdXfJ+HzUckfX7yOHIbP87HJELk5sWlZeB
+oU1aH8M6NZDtJuH8POHiIkNPuHaT05evqlTCt+7vvfY6uy+/Yp6fpEVWDyElwxs3CS60CBfmWXjL
+m4gWFwFK8sI0L+W60lhZNkknXLzGPlTCzL0aw533/YdXpoBiIjthyLltmEEMefR//Cfc+M3fYvTG
+NZACpUwkmraBNkUEl4339XX3xTOccc2mUsyKABjF+he+SNbrceJjf4bBxUtc/ZVfI+/1yXp7JpO2
+3W9Og9HatBoEc/OEK8uEqysEa0doHD9K+7HHCFZXSJKk2Bprv52AfDBorcmGQzJl0u43jh8l7M4Z
+122Pkrj79WhEfP0Ge99/gXhjkyCKSMMQ4fbGTrHAMH1qiKxl+RoNZKtN89QJ8hrfI18JUPUSLvzG
+4pj1bz5jwm77A/J4RJ56oBDC+Hk1m+SDARu9HvNvepzWQ6fJsqyIK3fsVBUMombCB+12kZGlcFOZ
+ARgwHRx3Wu5v5B1Yl3Bdut4MDqByNr/6NZ78Z/83tz71aW781ifsoGfoJEYMR6gwsOxDBnmGVuXI
+veJZzs8pTdFCkIEJ1oljbn3hi9z+0pdBa1SWmXxGwxEqHqFTE4FmQjEjgu4c4fIy4ZE1GqdPs/Du
+dyHXVsmyjJFddatqTSg7/fmsgpM10jhBHlkz2wjnOZnWxnjnsTQ+n985/wjzj55n97nn2f7ecyaG
+wrKgGQKVaCNnWNFSSozTX6OBaDZorK6Q1sSUVKlE1bKvRjE3v/IUw/Vbhl0aDK362MZwG37NvEcj
+QsUxQZax8+LLaBtD4frIOQdWWaj6ySJKsd8l58YaClNnm7hXVu37G3mHsy3AWDXrqTqFYO+ZZ9j9
+9nc49vGfYfnDH+bqL/wCvZdeNvsyNAbkg4g8GJINh2jBOA281cqYKu2H3KyebiPKPM9QSYqMIiPY
+g93Z00a2pem4Q6UkaDZMEuPVFbpPvIWF97+PDIo94urSzPgg8D/7QTlKKXJts3okyQRrUdVYOZfr
+ZrPJ4jveTmN5mVtf+opxBXGeukqZvfFwKmATXy2skC1bLZM+vyJcVwHhg0InCTef+iqDGzdJd/fK
+lv3MBCoZAAqQATKzqTQ1iCCg/8qrLCzMlzRXzsWjSi38BcSwgfWT/6CyHzjutNzfbB5OSBbCWe3s
+1l/jQ2vN1Z//eebe8mYaa6uc+0f/LRu/+3usf+Yz5K0eWbNp0tgEgfFHsv5CRuvCWB2J/WxXb6U1
+Is/NhorWhRq3YupxQI8GRBgSNhoErTbB/AKNkydZ/MD7SZQqHOemuUX4xf1eBx5ft1+nffEpRdXl
+vXP2DGtJwq2vfM1QP5sAQLgJKW1GRLs9cPPYMZQHuDr2rgoIIQS3v/1dBtdvkO7skvZ65EPjiuJc
+5l2f50Ig5HjjFjQmxrvZYHDpMu1Hz5dcRKrsm3+A1VqpfJyr1me5pvT1NO2TA8cfiEyxX/G1A4W3
+owWGthPXqVLJUtKNTd741/+GM3//7yGkZO0nfpy5N7+Z67/8ywwvXiS18QAikOSDAcRivBFhodXC
+gkMX9gvXycLjUSfsH9Ik+RJRaFw3FuaYf/uPoKQktY5z1Y0TYVJodN/dxA8sm1R1c6gCwrEXfiyC
+b0F2mqKFt7yZ+MZNtp+3uV2TlDxXkGN4p8Dq+BsNwsWFCRVsVZaosk39K1fZu3SZdK9n0mb2B+RJ
+bOU5Cy43jsIK92C0djIgHw1Jr/TYuXSZ0ydPlCa9e77/2V8IwGzqWOyQpDxuYIZ5dq9Vs3claEtM
+vPzUawQTLBPObz7LEKkZXDUasfP1b7D9zney9MEPANA6dZIz/+Dvs/5bn2D7m980mokgIA0ChOyT
+xwnY7a4mnQ3HfCw5xfa6jqK45JvOeCiC0PDsrRay0yVcXZ2QHepcq9133/3BTWzfNuLe3en33YTw
+owOBEuj8dJvuWHnvexhcvoJyGzJmqaHEMiAIIpsyNCTodkgrAm6VSviGTBUnbH77u2R7e2SDAelw
+UDgrusQCxfuCYXWUMv0oBL3LV9i7eAnZ7bDw1reSbG0hVyfj1H1qVXUfGa6vF1sRT1CLurlVas/4
+870o94VSgIdYX8Byn3MFwurjRyN0s4kaDrj2i79E++wZmqdOmTqiiON/+S/RPHWK9c9+1qyEYUQW
+SMRej1xoZIrJVFEx7o2pk43D0Mp6oI+1GmMvXI2MGgTNptnSa2GexGYfr4v1Lr1njTwBlKy8fhyF
+oxhOO+M71pku0sVvDhRRFJFlGc1uh/k3P254/Tg2Gjqw7KFEhBFBo4VsNlGjUYl18i36VePc7uuv
+E29vm/Q0g4GJbHTaJjeW3hg6YPSvXGXjmW+TbG/TOnaMuUcfQamcfBQXoaU+pXJ94feJ+z68fsPK
+eVkp/c2s8+yHQqYAE+ixn4eK1cEUSQkKx0CtDTDS1AQMDQeofoN8Z5ur/+L/5ew//u+Mig4zSZY+
+8H6aJ05w/Vd+xbhdhCFCSERPkjM0e9ZkmS/Vl3ylfNcIUUj/5lqJRgppXQwiGsvL9qf9Ywbw6neD
+7K/Gftr+qpep70zn/IWg7BbhrMXVeOfFtz5B7+VXDbVw9wpB0Gggw5BgYb5gE/0JWWc/kVKi05Tt
+F14k6/dJB0b9qtLYxja4SENRAsbg6lXWv/E0g2vXjWV+rmsUGUEIYYi2mQz9PvOphH84S3//0hW7
+0WRabEc8jX3aT+P0BypTzPJQ6TROnkrWLuFjvj9Nzfa4VkiML13kxr/7ZU7+3M+WBrd55mFO/9d/
+m+u/+EuMLl1CBOOEXPlggALTmQJDFbBJEXAUQxctKQbYyiFCmug+KQOipYWi/fuSb48v9tkSn2f3
+WRR3jwOFc+H2qUvVT8hREAegMAxpzM/TOXWSrD8gynJyawswuaFCornuhBq2bkK6FXrvwkWyvT2T
+l2k0QsVJkSNq3F8mZ0v/8hVuP/MtBteum3otS2oCmtxOssat/qA2VF3pk50dq44fs1D7+j3Zhe1e
+q2Phnli0pxdN2fvV3jSOk8iVkSukRA0H5LshWRSx9/TTbJ47y8pHP1rWsS8scPJnf5abv/Zr9F56
+GSElie3YzAJDZFnBSvmp+0vWdFekHFOUwIAkaHfG7zdFr17VFgVBUFJx+l6mvpuHD4qq56k7nF3D
+B0ZVhds9d5bRzXXQChkEZkXvdIz2rNsp7q9rr59sWQjB3muvmck48jaNt14EAuNhsP3Ky2w++5xJ
+KD2u1FDXyCRTC7odk7VxYZ5gbo60shNUHZVwbdhxVvOR03YdLGgbClZMtHsKjvtr0RZjvt2PsBtr
+f1zAUIIeCVQQkkcNskaT25/8FK2HH6Z97lxZddlpc/Sv/hXkb32CvWefBQSJZZtybKhqNt5FaVyU
+14bxZBRYZYE2LisyCidsD+6/ryatCq5Vh7oqlQCjqUmHQ6S9ztXle486OcO1z6cYTpvUOnGcaHHB
+GPKsFzDNBqJj9vyusyBXQ2IBk+Rta9tu8hibfrNxJHm/z9YLL7L1g5eKFJXVOl1e38ju/xGtLDP3
++KOFJd231VRZS789W997znoXxGVh+4BSAKEGHHdT7qvxzv3u8/QTPL9S6AwQCbkcQDjehejmv/1F
+Tv3Df4Ccmyvr3MOQI3/+44gwZPc730EAsTcPCoqBM49YSoMDp2WvFEY9rLWxZ+Q5JFkphqBkYKqw
+TD4Y/KTMLl7DeeT2X3mVvZdfIdm0K20jonXqJHNPPknUbE4E6vhgccDwVbuNbpdjH/0Ig4sX2X35
+VfJ4BFEDObdA0IjGqWN8rR9MvNfg6hs2z2ti1LxZxmj9Fhvfe5ad1173JmZ5lN2eILLZNN64y0s0
+jhwhXFuhc+5cyR/MPdeXZ1z/CCGINzbM5vWWUuRJMk7CPKX4OcJK8sU9krTv0ni3P/skwZB4Ya/U
+uj7CTmt0liPjGB0EZMEuIgqJ32hw61d/lWM/93OF5sZpgqSUrH7spxFodr/zXTSaxK72GXZSWCc/
+V6rgNG4LysZiZ5Ck5Hu7JbaoEEgrQmt1/+mJHUaFoPfyK2z+/tdJt7YMv56mhu1oNFC9PsnWDssf
++XBt7IKvpq1zrIsWF1h6x9tZfPKt9K9cYe+1C+Q2S7grddZ2nyUcXr9h3O6HQ3ZffpmN73zPbCbj
+MuwB0d4AACAASURBVHC4fvNnmVNKNJsE3Q6N1RWax47SOHaUpbe9DdFuFVse+BlNfKrqq2NvffMZ
+k7TaWs+dPLOfPOHPuvsBjvu7aYt1HTcNthuBwBgg7n5nhc5y5GiEkpI8DKAR0XvueZpf/CJLP/mT
+41r1eEutlZ/+abTS7H3nuwitSZTJn5Rb7ZJziXAq2lIn2t8DpRBZhhqNSG/eKGKICwc5T+jzWQAf
+GL7LtUoS1r/wRfovvUS6u0fuBjxXJqlAo4mKjcp379nn6b7rHSUAVtXAvsGvoB55blzig4Du2bM0
+T5xg+8LFwtu4NE4VbRQY283wxg22nvs+t5/5NoOrV4m3dyblrnJFiECarRC6bZorBhCtkyfoPnKO
+7pseM1sfVJwQq2xTwVbmOTe/9BWTuLo/GGuf9tE8FWPnfYZJcPzQyhQIUZuRwy1WToPqBDqE8d/X
+cmQS8YYReaPJ1he+SOP0aVqPPw6MBVPH16587GOoJGHwvBrHJ2hjOVdWkBcVHtVppIT1IVJxDKMR
+2bUbMBgQWsG5mtDLZ5v8zV2KiL69Hjc//Rn6Fy+S7ewU7hI6SWz6FknQapqM20HI6NIl2m96HBnI
+EqVwxacY/qRO9/aIe33ap0+Z80FA56HTjEYxejQssZs+hSnYsDxn7+VXDbVI05K8N20sZRBAo0HU
+7dJYXqZ5/Cjt06doPXyalQ+8jxwKTZkbHx8QvlZOCMHmc8/Tv3addG/P5MqagXWCegv2D5H26YBG
+OIWTv0K5ewo+fVyPUwOqODGDEIbkUYRsNtn4zd/i+N/9O4j5eVOPN8BBELD65/6sEQizzGbIUGTK
+xmK41O+6wosKYahUoRoekPf2GLzwAt33vKfku+SE02rKTX/1S9bXufGJTxHfuGHzR+2RD/tjL180
+CCNnICSy1SYf9Elu3UKePAFQUt8Wfeb1X8E+BiGD9XU0mtbJkzg3DM2kbcWXS4r3iSKCVrPwTJWO
+vaK8EtvGWLVrg3BujsbKEs3jx2k9dJr2mYdZ+/CHEHPdIsakSlXrEkagFJc/9RnjZ7W3Zzaf9Lcm
+PqBU23ivDHdwF9sNC2G0NuKAo1iBrIrN/++fd9ofs4FkDomdpDs7pBu3Sa5fZ+M3fqO04pcszs0m
+Rz7+MzROn6K5dsQEB7U7ZtvgMDAykJNnvHYAiDyH1OSnVXt77H3jm4jRiCiKaLVaxWYu7r8fpeYo
+RLq5ZeNC3iDZ2CDZ2iTf2yW3VmI9GqFHsRFsRyPzrOEAPRySrK+X1KTTbBf+ZxmFhgV645rZHqCi
+vvXdUtxR+l1r2idOmICqKDTBVU4QF+Pgf7eDVNhs0pibo2kB0T7zEJ2zZ1j98AdpnDxRSr8Jk9o5
+d7hn3P7Wt+m9fpFkZ6eIa1EHGO38Yv1qJxblu2Wd4O724C6xUHVH4aznAcAdehownByQZ8bZbDBA
+7e6Rb9xm+NLLbH/xi8XkgbEDXpZliIUFVj/+ccJjR03Gjfl5wlbL7uEWjDvMB4Z1GtRpCqMRem+P
+7PYG2195qpAZWq0W7Xa7BAqfSqh+n5uf+ATx9RukG5tkW9uoXs+AIY6N5d7q/0Vu0uuTGbd2Faek
+29u1KmD3uW7lFEFgqFuSMLpxs1DXVvflqMojPmDmHnuUoNkgaDQIQrO/XdVZL7CAiOa6RCvLNE+c
+oHPmYTrnzrL60R+lde5sKeNglW2qhrkGQYDOMi5/8jPEW9sku7vGxnQIKgFOAzVW2NSB407L/Q8y
+8j4DE6tACTzunKMGSYIOJKrfR+02Ue1Net/4Bs2zZ2k88siEZkYIQXTyJCs/9VPc/tQnzUTPM5TK
+7X4PqhCwCyph2SfSDDUaku31kK0t+t/6Np3z52k//lhJ+1Q1QpHn3Pzkp4ivXCHb3CTb3iLrGzCo
+NC0B3ikXpLLpIfPctG84nNDLVydHVVBGSvI4NhvJpBkLx45O3b3JB4t/zfzjjxJ1Omb/wGbT7l8R
+FC79LstgtDBHuLxSUIjW2TOs/OiHaD1yrog1qYa7OkWEb+l3rOH1z32R3oWLJFtbxt/Ks2TPQiVs
+j9j54zwV7l3epztnn2Y4dG5yMxXqT//3g1gppzWKExiNUHs9su1t1PY2u5//PIxGBcXw061kWUb7
+R56k+453EK6sEC0uEnY6BE3jQSrlmHcuPSvLDDAGfbLtHfKNDTY//Wn0rdvTs5QLwc43n2Z04YJJ
+ubmzQ97vo0dDVDKCfKxJqSomhDYDqpQGTZENb2LyTx0AweDCRQaXr9C/chntsU9VauE+Vz1/m2tr
+tE6eIGi3CVqtgmKIIECGIVG7TWNhnuaRI7RPn6b9yFlaj5xj7Sd+vAQIP5eUnxChTlU9vHGDy5/+
+jDEc7u6S9XvGteQQVML0kygtyKJCOe6m3BX75Bow7SDP0cMBurdn/tuIuNIkKckUZbAUcRdJgh6N
+UP0+c0/+CHqvx95TT5XYqJKjXZ6z9BM/QevMwwRLSwRzc8YFIoqsv44n93gslHFQTAzrs7VF+sYb
+3PjFX0JtbZViENwAxzdvsvl7v0dye4N8e4e8t4caDsHGlZMrs4OqVhQrm78YyMCk+5GycE2paoyK
+fq7IGkIII5eMRuT9IelgUPRDndapKm8oSzVX3v0uovk5wnaLsNlENo23cNTt0lhapHHsGK2HTtM5
+f47OY+c5+qf/M6LTJ2cCRLW/0JqLv/SrjG6uk2xu2b0/Rsa9JM+sUXW24psVp4HjTsv9lSnwePg0
+NcDY3UH19tA2zT3WE9NdVwKGsvsV2EwdDAb0fv9rrP7MnyN+5VWSS5dKvkU+e6CjiJWPfYxodZVw
+cZFgrotsNo213PHtUGi/nJaKJEaPRmS7u6QbmySXL3Pt//lnDF56qWzlznNu/9YnSG/dJt8xydT0
+wABCW+o4SQ0LG7uZJNJsoEgYoIWcyO9a2+feIqDipHDky/d6E6CpAsR3J3EgWXjrE4TdDlG3Q9hp
+E3XaRPNzxkp9/JiRH86fp/OWN3H0z/wpxPLyhAzh3qcuGYKvgr3+uS+w+d3vkWxsjKlqkhg2UvvO
+o+N+mlaq9og6cNxpuQuLtuHiZlLJVk/lzqUiJgezj0Jo3I5lFJl8UO4GpzK1wEjfuMb2Jz7J8p/6
+k+z9/tdZPHWqZGDz3QsaR48y//73oT7/BUNprG+NzMt5kHBhslKisxw1GiEFKDSpNpTq2s//czqP
+v4nF974HpGT7q1+l/+KLRrvU2zM7gNoBLuQDz3rv+sHlNNJ5Tj4ckuz1aDcaZsPMfSjEhD+WpaAq
+idFakW9vES4v1Xrlwpha+NGAWmtax4/ROXWS+OZNovk5FBAGgUndf+I4zdMP0X3izSz96IdQYVja
+08LVK2V5u7SqMkJKye7Lr3Dp3/8m8a1bJm+v3WXWpQ+tzTC/T0xdXiy7ZXXs3bJOcB+CjKr6banH
+mK82emzRziHJzQ5F9noRmD2bCUNEs4lUChWG6MGAvWeeofMjT9I6fZr4Bz8geuKJiZXROdbNf+AD
+DF54ATXoo4dDdByTpanZpNIJdkKYlcUZELPMqE+VNknZkhQ5HNDb2aH3nW+bTH3W4JePbBRcPA7d
+LDyDlTJ7ebvVfBRbGwUEKyu0HjlPc22NxskTEyrVcjeWh1prbUNSE0Nxo5Dk1i2ajz5aUgRU3UOK
+eyvnF976BHuvvEoUx4iW2TY4PLJG8/Rpum9/G4t//D2kSpVS+7gFxfcSdpo6n3USQpDs7PLav/gF
+4pvrJBtGlhhnds8LbmG/UgVI1f/Jn3t3K2jf1z3vXPFJ3IEAseyMVjk6zg3bNByiggC5t4fa2yOM
+Y9Z/4V9x+n/9Xxi89BKNc+cIGo2SZ6ZLsRI0myz/1E+xsbFB3usRDAcGfC6pmHLkzLYu97aX0hql
+7F7UoxF5FJr9E8CeG6IGQ9JBn3wwNJPeOdjFsdmAvtRh1mdocZGoa/efW1wgPHqMpJI2Z0zFXPPK
+qlITeZcYCiUlw1deY/nDHy6i9KYBrGrYA2ifOkVzeQnQhEoh5xcIjqyx9P730f2RJwvXDR8MjiLV
+pd70lRE6SXjt5/8lvQsXDZXY3jbaRJvZvfBHO0TRGI/oom+8OeS+B38Q7NOY/5v2G2itkN6mwj4Q
+DgUQrDo1TdHDIWp3h2y9wfr/8X9y/B//9/SffZbme987IVu4wJzWY4/RPHOG0eXLRpDuD8j2ekYo
+1rqwpDt2R6lxsoPCgdHj5XWuxkH2bmMXFxjjvYf039GzCgedNmJxkXBlmfYjj0C7VWwJVs3wUY3s
+K2IyRiPUcEjW74PWDC9cJFu/RbS6Ugi/vgyxn92jsbZGtLICjQgdhIiFBZZ+9MO0Hz1f5IV11Lfa
+JkcRHLvk2yNQitd+4d+w9e3vkKyvk25tF8K1c1OXWk+dB/sVrQVCTDJY98KifV/DUU3RHhDEnQFE
+a0CZfaXTBD00mqjkyhX6Tz9NcPo0DIdImzPW8c9SysKxb/EnfoLe00+TSYlOE3S/h+r1zIqldOl5
+RfFN8y7xQQUcaD2hdq17FyklRCY/bfj/tXfmMZJc933/vKo+pmdmd47d2SVnL9Ikl0vSXGml8LJI
+kYIPIJASOLIdRA7gJEgE5Q8HEIz8ESDIf7aSwEEcB4ksSJYFRY4om6ZjS0pEkRbFiKIkrsilqNXh
+XV5L7jG7O1f39Fnnyx+vXvWr6uqe6ukZcpXtH1Do7up6Va9evW/9jvc7Znar5Md79lD5+bsyy2yZ
+/lamjqA3f31dyeStFoHnYSNZe/pp9n/kH/WUODN1kfTEBlRanPk92FNThKUS8488TDFapdZ9N7O3
+Jxb2Un5NccocKXnjTx9l5dnn6Fy+jLO6FuXt7UAU/23WtdtsHvTOqm6brN+j0I6Eo3Y7KlITfASA
+RNYotZ7gQrtF2GpSe+LrHPj3n6B18SLWzTf3cAs9MYoHDzJ5110Ea+sE6+uE5Sayox5QKM1Fo26P
+tfk4OmHXXwrjbZti/1n3EpfuLZdVsrX5PRT27qV45AjW/Dyu4yRMm9CrYKeB4Vy9iux0uh64nsfG
+yReYfeABiocPJc7leV78ps+KBrQKNsXZGQrMMPv+h7DnZuOXiR7L9Eq7ea50nARhyLkvfokrT31D
+AWJFW5vMLCHhwJfIZgAJSQJiu/QJGHVFu/vi7H9Mn/1bAUhsiYoycstmE1nfoP3ii9i3364mqKFw
+myJUoVBg98MP03r5h6q4+kZNcZYonLMLimyLRyz76jf4oBuV3Q8hRFx3wZqcpDA3h71vH4Ub9jN9
+z9/BMwqpmDpAGhCmCAXgXr6sMna02yohs+MgbJvLf/bnHPmdj1OKMoFrMOj0O2knRlAOmKXZGXbf
+ew/27t1x0gStOyS4ipGFI2sjCHjj819g+Zlv0bm8hLuygl+rEja7lWbNF0keIGTt76dTiNS+rdBo
+nEIMvnheGTE3QKSM/Yak6yprUqtF/dln2ffII3Tq9TieQE8uM5Rz4uhRinv34l+5gj1RISw1kY6D
+FUXpZd9B4o7z3VfcaZUQQZRKiMmoJNjCAsUb9lM5fhxmZ/FSWcFVs15dwpycQgicixcJO21l/Wo2
+Y1eZ9t+eYfnxv+SGf/yb8bFmSh3t+m6uykvPZf4XHqAwMxNzBTPYyVT40xwrkb6n1eKNz36O1e89
+T+fKFdyVVbyqcvgLnQ4EvlrI1CIive+SvAAJDSkkS5R6R0ChO9Hv4rFRZ8hzbgoQKSOvVmWSDNtt
+vNVV3LfewlpcVNafsJuNz1yoolRi+j0n1KJfpUJQKhEaosRmPTPv21xq6tdaCBGX2irMzVBYWKBw
+4yKFw4eZiKw6aUAk2hqgMLkEYUjn0hLSiVb62y0IQ9zARxQKrD39DJUjR5h96MFYrzKj4MxUmUII
+KocPY0d6SM+1SJqEs1bWAToXL/HaH32K+tlXcK4u46x2RSY6uvSyjLi5MY4mV02N9iCAhNF5lM6Z
+fEKD5mUe2rlcskJ0RSu5NfRmAiShW3jgqBVo57XXKB882G0bWZHSSmz5zjuxnnpK+fuUishCQSUT
+02/FXP0C088mEyCWqipkVSrYu6Yp7F2gsLhI8dABph98H4Ftx1wiHUCkhq9XbNIT0ltdVesTnY4S
+SaL1D+H7eJaFVbBZ+sIXsEolZu6/ryczoXk+v9HAnpiIr6m5g5m9L2h3CCKzs99oKIXZD5i++SYm
+bryB5W89y/kvfonO5ctqHSIqvRy02rFjpF6g607wqLjnFgGiVza0xJIFjq3SjnIKYRwYD8Y2AMTk
+FqHjYDkOztmzlB9+OPq7W785nYWvdOgQxelpgqlJrPIEIkrHGfp+bA2Jurl1gFiWWp2vVLB37cJe
+2EthcZHS4UNM3nMP1r59tNvthC6h+52W380w1Tib3vnzikO4al1E6joekbXIFUq0uPSZPwbPZf6R
+RxJ9jkUeYOmxx+mcP09hZjdWqQSoPFiBpzI4Bi2VyUPXoZtYvJHZ976H6TuO4V5d5sx//H1qL/0g
+KnCpCuH4jUZU6sDpKtU9ItPoAAlJ1dQ2wHFNik+ILnLBuJntAIhUjnYEilsIx8FfXiZsNtWEhIS/
+jylC2ZOTFA8dwl1awq5MEJZLyLYNXlRLwbi3oQGiZfGCjTVRxt61C2thL8XFg9iHDlK+805KdxyL
+K5WaYlOW7K7FnXTysM5rr6s1lihWg6gkGL5PiFJCXSAMfC5+6tO0z57lxo98hOLsbLevYcjSXzxO
+9XvPdy1YOmGBrWp1iGJRRdvt2sXsffcy/wv3M3nTTbira7z12c9x9etP4W3U8DbqKqQ0qmcR6OyF
+erW6jz/XqABR9XkznEFSc29Y2rEY7XAAWkcGiHawi7lFB+l0kBsbiLm5ZD/CZN6kQqHA5PHjdH7y
+E+zJSfxSCatYRLouVhj5CqX6kgsgkZUJ2445hLWwh8KBAxQOH6J07BgTD9yP4/ux/1A6/ju9aJeV
+1Q+g9dOfKj8ux1FFZ3wfEUSVjWS02itRk9JxufLXX6X63HeZe+B+Jm+9lcBxWH/uOZqvvKoqFemE
+zXoRM1pknL33XvZ/6O8y/+CDCMui+uJLLD32OCv/91mVfaPdJmi1ut91n3T+KO3ykueRMjxAQikT
+xp7tMMfCDlZHDQf8Z9JWASIiS5T0PSzXRXQ6BOtrWHv2xG9VvZJr5lQKw5DSrbdiT08jpqawKxVl
+2tWTIggG9iUTIBoQhQLCEJnsxQMUbjqCfdttTD7yMB7EgEgv1qnTZAPCFJ+85WXcpctIzSki8QRt
+VpZSxZ+EIX4QqEpDzSZhrYpz4YLK9xql9YnDYrVLiraO2DalhX3462tc+cr/5q0//hydCxe6tSo8
+P/b3CqJClYHrdgOFDK/XrYnK+QASRJpmlvVpFNr5mncMK5+TCyBCKtcPnZpGdjqEKysUjt6ekL/T
+nCIIAkqLixQPHyZYWSFcX1cr250OIrKhxwt1m/RFRG4gwrKQxSJ2pYK1W/kN2TcuYh85QvHobUz+
+0i/h23ZPrbzMMUuZYdPm2PYrr6gQ3U7klRu9lc0YFL0WEEYxImG7Q1Cuq5xQUVyDDAI1ySPdQfp+
+ZNFRpYfDVhvn4gXVRnv2osQuGYlrgeerUgqaM2gHSykHv0SGoEEACWT3+QAJcFyTOoUpPuUdmOy3
+cJ9JGU0A4fsI10O02wRLlymlLDWmH1Q8IQsFph54APf115Vtvl5X6W2iwPkwxfYz+xIp1CJK+2JP
+TmLNzGDv3Yu9uIh9+BDF22+n8oEP4Nt2XBEp7fSXRWYytnSG7sbLPyRoNZVO4blddwlzcTHsup8E
+vo9wXWTbVnHdekU+ilXRGb5D3UaPm+2qNR/bVq79ZrswVBxDJxrQ7cPBri7bDZAgBYhhX8L9aGSH
+wP56gzaiitwDs7mYYgJExivcOA6y3cZ7802mInOibduJUlpm6nvbtinffTelAweQGxsqQCgqaKiV
+7TAMkxwDIOIMlhDdCTMxgahMYs/NYi/sw1pcxDp4gOKxY1QefBBPiJ5qSP1CTtNcIp2lMKjXaf3k
+p4TNltKhPD+O7BPGgMXuKRE3lUFU2MZYe4g5iXFs/FfkqiGCQN2zNl5Ew54Q17QDY3dSJMyjOwmQ
+nYqpGN3No89/XZ0iQy7U7RkBIHRT4uB7yFYLsVFDrq9j7d6dyS08z6NQKKgU+KUSU7/8y/jLyxSb
+DSWfB2qYg04HK7Ktazdy7dOi6+dZ5TJMTGBNT2PNzGDt309hcRGxuEjpxAmKd9+NGwS4RmB/2kEv
+OZbZPkVmwH/z9I8I6hvIKGUOnqcU7NSkjAdKg89U5vXzMXy3sprGMfKmL4/RRhsk+nKGtwEggbGA
+p0mkPrdCWweFNVh8ymZn2wuQmFO4ykFQNhqEly5iz80lrDV6ZVtzCQ2Y8l13MXHi3SrYJQxBQBgt
+uml5PTbTCuX6TbEIpRLW9DRMTWHv2YPYuxfrxhsRi4tU3vc+xA034ETcQXOoLA/YNGlQZKWYFEKw
+8fz3lP6jQ3lTawDJk5kD2HvdhFt76vAE5zAAHHPozPai5/nsNECikjKZCvY7AopBK9qDXDy2EyBE
+Fijhe9BxkM0Gzo9/zOTxdyVrQ4fdqqWu6yY8Pic/+CGCRlPJ24UC4cQEolYjbHeQnosdyvhtKUsl
+FQU4NYXYvRtrfh6xsIBYWKBw7Bil48cJSiWcVL3tPHHXaVfsdLJmd2mJzpkzhPU6YbuJ0Eq2diAc
+eIHUADLERNx0jUG3l8b+twcggezOnPRLeBTa1nDUBGfI0cORAWKsVdDpQKOBf+YMotOJJ5hp7dEK
+t7lqXCqVmPrwh2l+9atQqRDs3o1VqxE2GhBlz9YKtZiowPQ0TE8j5ucRc3NYBw9Seve7kfPzuL6P
+H4lL6VQzA8ctJTqlQWFZFo3vfJewtkHYaCi3jiinlZAhZnDmpuLHEADJS+8UQJReoaLs9FX0f6Nk
+5Bi9OmrGf0E8FCBNvWO7ASKNnE2dDjSayGqV4NVXKdx1V0L80JMzXWMuDEOKxSKVX/1V7B+8hHPq
+FGK9imxFHrRBoMyRhQJUKoipadi1i8KRI9hHj8L8vHL/jmIiTNeNPHmMNDjTeoTJ6YJmk9qzzyqf
+o2Y3DkQYOs+mvliZF089gDxtNqHBAFF7txMgoYRCrFd0wTEK7Qin6LdwtyMA0XZz14FGA7FRwz15
+ksnjxxPxyumYZTN+IY65ePcJJo/dgXfuHP7Fi4Rra0q3EAKmp7H278Patx8xP48sl5UC3QcMeRN7
+mRzCzLlqik71kyfxV1cJ6yp/FqmA/97Jc60CRO3dToD4CEo9ekU6vG04GolT9AtHHeTioWnbAKJF
+qCjvrLWxgXfmb5FLSxT37UuAQkegpYu86yiz2KX6llso3HqrstZErg+q6FE35tk3HPqyTK15uYS5
+JpGul2dZFrLTofa1JwhrNQWKjhNnweh1srv+AOJLgenoNBqPULQjKW7yungkGmkaFiAS9cb0PESn
+jazVoLqO89y3qfzGP4xFkbRrhQmMLJcK6Io2ZiRfOtteOmWM9mEaeLuGn1M6q54pOgkhqD/7LN7S
+EkGtptL06JX3MIzHoJ8h4noASGi8XM1RH6V/O1LzztQp8lBikLcAkNhj1nEIG02stTXckyeZeOQD
+lObnE64eOqcq0CNK6bQ4QEIZT2fZS2feS+dVGkQaECYQzXoXZka9oF6n+sQTBNV1ZH1DpfOPCpto
+LjHQEMHOA2RUGhUgvqQbbGR2bQRU7Ijv09CcwqAtASQWoRysVlNxi9UVnCe+RuW3/klCtzDFJnMC
+63xRprlWf6Ynvum3lFd3MM+puVE6zWS6sEn1y1/Gv3yZsKoy6tExQjp7FNh3BiDmW3tU2gpAPOP4
+9Dm2Stvu+xQY/20nmx0IkGi9QuWc7SDqdeTqKt6pF5l46CGKR27qkfsHWYnSIZdZekIeMSmL0gt0
+pmJtZtVzzpyh/swzBGtrhBsbcXbD9Aq2KUZejwBJ5xbUv0YxyW65rUUqtX60Bcb39AJf1vF5t0R7
+YWx6n5RK1nZVTidZrSKXr9L6i8ewg6DvG9nMXK4pSzxKA2ArHMIERDrvaqlU6nrDui5rjz6Kv7qq
+0vE0GsoMa6xg94yLMCpLpcZr0HMYfJxypTGfdbp9zxb1QQN2O7bsPkqI+ufL3hf0KC/j0bKOi95N
+WZ6k0entAUjf9vFEkGp1V1ck2tggXF0jOHsW58mvJ9I66i0d0ZbmDsOYVjcj09FvUCJiIQTrjz+O
+9+qrBKuriku0lBlWBIFyl+8zRvG4XGcA8Y3nlgYHW9B+8ohPMuu71edippIt0AxPs0Nh7MfYn68T
+yfNmtY+Ubs9FtFtQrUKlgvvUk5SOHqV429HMSd4vecB2kJl8oB8gzFpwzW9/m8Y3/gZ/+Sphtaq4
+nunnlPO6pkIaj9c7JGIJiGtb74SI5UmYNM6vr8kWAAFb4xRy0MUCBr2htoeD9J432q9jLDwPnA6y
+vkG4tgqXl2h+/vNY1fUekcVMDpYlSg1LWelgTLNruqCkCQjvjTeofvGL+FeuKF2irnQJFTehXTpG
+eLu+Qxykp/02c5CQ5PlGpTSnSE942Wd/FpsCujpFenGu982zQxxEB/C4LsJuQ7VKWCphlc7R/JPP
+Mv3b/4pSqdy9j2jian8lM0fSVsUnMz3NZsXotdgULC+z+kefxF+6RLCygqzVlIt4xCW6nrCjWePf
+aQ7S034bOEjCAhWdL+NcmRJPFm3r4p1GjgZMPGBvN0CkVOKG46jQyrU1hG0Tnj5N508+S+WjH0OU
+FTDM+GftLNgvXLRfYFD6dzpQyCxoklX2KlheZuUP/jPu668TXL1KWK3FJli9UBe7fyfGYgwQgEAK
+QmQi3U3adpL/bNucYNk39vcdsB0ESPfByriGHVHEWRh5unovfB+KRSb/2T+Hcjkh83ueF4Mjq/Ru
+2gxrWpXMLe3YZ4IinbIyWF5m9b/8Ae7ZswRXrxCsrRPWN9SahBHotPkkfXsB0rd9Zh93HiCBCDhZ
+pwAAC1xJREFUBFtsUYlI0SBQZJ1/4DWVf7uifg9vJwGSaB8BQ0Q1LYSwCKNJ7H3nOZrtNpMf/RjW
+5GRP+Ge6img6YZkmExRmQmKzuk8aHGYknffqq1Q/82nc117DjwAhGxvQ6cZfp5XrfG/xnQdIrvaZ
+fdwZgKQdA41T5RabNPUDRT+9IutCMQVGGdc8D2/HAaKzBLquCshHKWVSSvBP0mq1mPzoxygtLMRg
+0BkFdQjpIGCkdQdzUS4rWCjO9C0l7We+Se3PvoR/+bLSIdYiV45Wy3D4C7vhlhmTcgyQaL9QeoU5
+9wZYkDYFxmbiUz9AyCxOFYpsJL+jANHJB1y3+yCkSvHi+T7N//AJKr/1TymeOBFP3CBa7Eunxkkr
+3v3iqs3v6ZSXYaPOxqOP0nnuOfzlqwSr3XLDMio3HOsR5J+U1zNAIOktK9QWz1Vjy0V51yl6tvQg
+SHK6jDMcQNKjsiWARIFIAuJAfqmzC7ouzf/+Xym//2Emfu3XsSan4gltgsH0mzK9XM1Jn05Hk0iM
+HIZ0Tj5P/bHH8C9cIFhdUavVtQ1kq6l0iIzCiJljNAZIz++ALoeQycOGAgRkg6KHK0RbaG5pTqFN
+scNQvodn0CgAiYKRdNIwGSU9CKNctO4TX8P70Wkm/sGvUb73PmSUmt7MRwv0WKBMfcIUpWJ9Q0qc
+06dpffmv8c6ewV9fI1yvEtQ2onjrrtmVaMV6qDG6hgEydPvMPuYHiAeUo++6aAHZ3GIgUPJyijC9
+Wd2i90BSyc77tkhfZMcBEolSOkWLCAIV6+w4BK0WVqNB+1OfxH3ia0x88EMUT7wHMTERAwNIcAqz
+qg+QsEDJeh3n1CnaT38D79wbhLUICBsbyCiCTi3M+cksf6OM0TUGkMxT5m2f2cf+ABGAJwXlpPyu
+52saEANpkKKdxSmCaPPToFCVZTZHdR7aUYCYCcB0orDARzgOYbuN1WjgVasEb7yOtbBA+cGHKBx/
+F4Wbfw5RKmV6yopIiQ+uXsF95RW8H76Me/qHUaKBOmG9obhCs6k4Q1RXIsEd5HAjNQZIcq4JS+CH
+3YIw9L7Mc4tRm5lk9QkDY/MBvw0d817jpXbU872mASKlqojqyW4mPM9DRhxDNBqRQ+Eq7QsXsL76
+FZiapnDLLdgHDmDNzsHkJML3CTZqhJcu4b3+GmGtpkoat1rKitRqqRxNLcUVQsdReoNOYhZ5vHaL
+xWxtEl7vALGQFPbfgL+01D1eyg5qrgb0ilEDKQ+n0KDwUWKbB3jLUNcdDSUgjbJNhsLxdgCkLw0C
+iJRIGYAMkWEQA0N4qpZe2GjAxIQSn6JP581ziFIpkXCYIFAJhl1XJSp2nDjhs3SioiqeG9eRUHEf
+/dPUd/s4Bsim7aPP4m23Eq5XAXAllAU4QtZJgqIbmbUJbaZom5xCg8IFnJdDlvSBoe5dlAaGer3b
+6bcBILmoH0CiNDlSehCq1P4UHBWs1CoSFooKCMWiSrWvK6rqN4BW2H2lG+jMgtL3FPeJgCAjq1IC
+DJsg+3oASGbTIQBiLy5S/rlbaD75JAJwEJSRbCDO0wuKXGJUHk5hik0e4ADO0yEXPElgC+xAoEoq
++T7BwcNYF95C1Ovxia55gOiJaugZqtCkSqIs7YLKIGjbSGElEhWrtYswNqXGAIjEowQQsvyXck6G
+/18Bkvnsco6JvbhI+d578V46hXaFcSVIAaeQ30LN1ywRaiDl1SkSXAJo+9A6J1k6Jjhork8Uzr+J
+9773U3jhJKyu9B/YaxIghnyvJ3jkOxVn7RZR0UjjembBFGl87weEvpNq6Lfl9QuQ0u23U7zzToJa
+Df+t84nDNqRo/b4ffAs1X4fWK+wB/4los6LjbBSIinqbBfGIzd1mogLhuggZ4t9zH8ISWAYwhLEl
+fkdfYp0kcZzYtH2e77mOM/ohtJ6kN/3WD/yIE0SWI12sxFCchZH0OOv6ufabfRn6vnrHbNgxMsck
+HavQ9znmuEdz/Wjofgmwd++ifN99FG+6CSFDnO98V6X9MY49i/zKY1I+A7SANl1w5OIW/UBh9ktn
+xzSBUQAK35NU/0WBeyahYnbeXl+HuTnCm24mPHAAq9PBatRzDNjOAWToSZIGCHQBEnOCEGR2zPTA
+e8xxXL8xuV4BYk1OUrrjDsrvfS9iehoEON//PuHKcqJPEoJPB/zuGeRlFCgckmLUpjw4D6fQmwZG
+DJAQ7CmB97DF8fQg2EuXkHv3ImfnCA8eIjhwEGFZiHYLS1fhHDhg1yhABpyru1/02T8GSP/jMgBS
+KKhSy3fcQfnECew9e0AIhJR4L79M8NZbPX06j/w/vyuDvwKaQIcuKLQItSmJTf7TACiiVtArwDSw
+G5gF5oD5l8t8/A7B7WkIimIR9977kQv7gC5ExUYNa20N6huIVgvpeVi+3wPhfr9794uBxw/6nve4
+zNeLzNNH0Wf/4N/D7k/3ZdDrsCvYbe3eB/ZlwJgMai+KRWSxCKUy1swMYmYGa25O6XNm4yDAeeEF
+gosXe87hQvXjvv+bL8B5oI7iFB2G5BSDQAFd0akAlIAJYBKYQgFjBph7l8Xhp4v8212CXeaNK/QK
+gjt/Hu+2o4kT9+tZvwHve1zPgZsDZND+vMdl7d/ua2y5LzJ/exMgg4/ZWl9yP8e+RxjVl9bX8V56
+iaBazTpH+L/C8F9/Igy/SRIQDr3K9kAaJD51e5UctTQ35IrEPSd540M29xQii5Z5kL18FevKFeTM
+DLJSSZw0/Tj6sdx+nUqLWMn/+4tYg66X57jN2m/HNbbcl5SINVyfRY5jhuhL4qybt888znXxTv8I
+/wc/UN7EGW2+D3/4b4LgKyTFpqEUbE15QZH13ST5Y0ltBc79ouA9RUFRd1r3xOq0Kbx5DqtWg2IR
+OTUVz+QxQK4/gORqX63i/fgneKdeRK6tYprt9TMFwlNS/rd/GQR/igKEVq6zzLG5qN88y+qrtj4V
+6YpSFZQoNa23v29xyyeL/PYNgkPQy4bjC05MEOzbj5zfQzA3BxMVZKmUmNFjEWsH+3INiViEoUoc
+7Tgqb+7KKnJ1BdloDLyOC/UnQ/l7/y4M/4YuIEzlesdAoY8z9YsCSvEu09UztK4xNQcz/6PEh3/F
+4oO2AlDPDWVdWIJypzAWx9Jth1ZA08fJ9P58AMlznZ1W0jc77yhKeq7j4u/5+7VpX6RUPmMZ/RjQ
+Xl6Eb/4nP/jDbyqlWq9HpAFhunfkpryg0Mem1ytKdLmG5hyT0Wflfpv9v2fz9+4RPDQlmN3sZk1x
+q99xg9rnn5TRQ039kR65rSiLuSZkxgnDnr8GT7ysPgwL3MQxMtdkzPid7Oew4Oj7X8ZLIwD3Enz7
+ryT/8zNBcJouEEwdQptfh3LtMGkYUEA3QVx6Ic8Eh8lBykC5AhO/U+Cuhy3edRiOzAgWyoKpfhcx
+J+cob8bM3yNyin7AyaJc/Q23xjG2dC1yjm3PGOX53Z+7D7xWdhsJEAjZacLqeijePCPlqc+H4fOv
+QhUFAA0EEww+SQ4xNCDUnQx/vN76uX+UjK1ofGoA6QVAK3W+rfZpTD+blMaJuZme2XrTE981Ns/Y
+TO6wZUDA8MnQzIuYFzYdB/UNaBBoQNjGpkE1BsSY0tKnOZ8SgW10HVPN3/r/NBi2BAjY+iQ0rWsW
+vZwjazPdRAZZW8fAuD6on1qYBkY68jO9mWDoVc22QKNOQJGxWZts6eO3qy9j+tmltAqkJ3gaHFlb
+Gkwj03ZNxCxwmCDp999O9GVMP3uUpYenuYb5mbVtG233RMxatOwnKvVb1BzT9UVZEzrLyp0Fgm0F
+g6admoT9uMCYO4xpEG2HVXdkersn5RgEYxqWdhQAYxrTmMY0pjGNaUxjGtOYxjSmMY1pTGMa05jG
+NKZ3lP4f2RKl8XZiML0AAAAASUVORK5CYII=
+"
+ width="74"
+ height="77"
+ id="image4290"
+ x="97.5"
+ y="291.35947" />
+ </g>
+ <g
+ inkscape:label="Layer2"
+ id="layer2"
+ inkscape:groupmode="layer"
+ transform="translate(-97.5,-292.47158)">
+ <g
+ transform="matrix(1.3025696,0,0,1,177.07252,285.53243)"
+ inkscape:label="Layer 1"
+ id="layer1-2">
+ <g
+ id="g2039"
+ transform="matrix(2.101543,0,0,2.101543,-20.51805,-62.14422)">
+ <path
+ style="fill:#e4e4e4;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 25.484419,57.339597 c -0.843126,-0.007 -1.153942,0.849347 -2.132163,1.827567 -0.306469,0.30647 -0.676877,0.541502 -1.015315,0.812253 -0.573587,0.45887 -0.999205,1.061522 -1.421442,1.624505 -0.493396,0.657861 -1.128722,1.128722 -1.726036,1.726036 -0.882369,0.882369 -2.12819,1.469228 -3.147478,2.233694 -0.756451,0.567338 -0.958015,0.393056 -1.421442,1.31991 -0.287559,0.575118 -1.41051,1.407777 -1.827568,1.9291 -0.493868,0.617335 -0.440065,0.947722 -1.015315,1.522973 -0.524955,0.524954 -0.829105,0.287742 -0.101532,1.015315 0.279084,0.279084 0.676877,0.406127 1.015316,0.60919 0.733388,0.440033 1.490393,0.835236 2.335225,1.116847 1.280354,0.426784 2.645607,0.346364 3.959731,0.609189 0.169219,0.03384 0.338438,0.06769 0.507658,0.101532 0.878576,0.175715 2.546303,0.793265 3.355653,0.590927 0.686013,-0.171503 3.217253,0.71839 4.928299,-0.321577 1.982335,-0.67292 5.483473,-1.593634 7.495073,-1.146612 1.106214,0.245826 2.132607,0.708941 2.395122,-0.341117 0.121425,-0.485699 -0.01423,-1.145304 -0.203063,-1.522973 -0.291362,-0.582723 -0.854109,-0.573553 -1.015316,-1.218379 -0.183179,-0.732717 0.23914,-1.261151 0.406126,-1.929099 0.284047,-1.136187 -0.07236,-1.667977 1.319911,-1.31991 0.771576,0.192894 1.407656,0.319386 2.132162,0.609189 1.974578,0.789831 4.097064,0.812252 6.193425,0.812252 1.437363,0 2.912756,-1.02929 4.365856,-1.31991 0.761687,-0.152337 3.313295,-2.143577 3.782598,-2.260902 0.543488,-0.135872 1.94541,2.469094 1.598574,3.682344 1.29682,0.324205 2.05854,1.011754 3.24901,1.726036 0.921993,0.553196 2.173988,0.812253 3.24901,0.812253 1.999216,0 3.734648,-0.09603 5.787298,-0.60919 1.247305,-0.311826 1.624505,-0.193148 1.624505,-1.421441 0,-0.867362 -0.606794,-1.419047 -1.218379,-2.030631 -0.538554,-0.538554 -1.000113,-1.130829 -1.522973,-1.522974 -0.512447,-0.384335 -0.869381,-1.129571 -1.116847,-1.624504 -0.338265,-0.67653 -0.662946,-1.325892 -1.015316,-2.030631 -0.333719,-0.667438 -0.701535,-0.957661 -1.31991,-1.421442 -0.778467,-0.58385 -1.258684,-1.353242 -1.726036,-2.132163 -0.682242,-1.13707 -1.608096,-2.649563 -2.132163,-3.95973 -0.05621,-0.140529 -0.135375,-0.270751 -0.203063,-0.406126 -0.272751,-0.545503 -0.63008,-1.036207 -1.015315,-1.421442 -0.746683,-0.746683 -1.564639,-0.22258 -2.132163,0.203063 -1.45229,1.089218 -1.911754,1.099502 -3.045946,2.233694 -0.66201,0.66201 -1.564634,1.707827 -1.9291,2.436757 -0.423924,0.84785 -0.98834,0.419614 -1.624505,0.101532 -0.613995,-0.306998 -1.035124,-0.674812 -1.624504,-1.116847 -0.693766,-0.520324 -1.433007,-1.433007 -2.030631,-2.030631 -0.633044,-0.633044 -1.42104,-1.31991 -2.335226,-1.31991 -1.24006,0 -2.4622,-1.971505 -3.045946,-2.944415 -0.523862,-0.873103 -1.490853,-1.522973 -2.538289,-1.522973 -1.295372,0 -2.506223,1.617155 -3.655136,2.335225 -0.930051,0.581282 -1.39337,0.663237 -1.726036,1.827568 -0.208123,0.728428 -0.624395,1.279201 -0.812253,2.030631 -0.180754,0.723016 -0.492196,1.492051 -0.812252,2.132163 -0.342266,0.684531 -0.704921,1.003715 -1.015316,1.624504 -0.359527,0.719054 -1.530992,1.975856 -2.233694,1.624505 -0.589142,-0.294571 -0.994918,-0.771457 -1.31991,-1.421441 -0.158488,-0.316977 -1.306963,-0.769777 -1.522973,-0.913784 z"
+ id="path2166"
+ sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
+ <path
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 25.687482,56.93347 c -0.03384,0.06769 -0.06769,0.135376 -0.101532,0.203063 -0.625349,1.250699 -2.202358,1.288575 -3.045946,2.132163 -0.169219,0.169219 -0.338438,0.338439 -0.507658,0.507658 -0.777416,0.777416 -1.231932,2.044184 -2.132162,2.944415 -0.500234,0.500233 -1.14971,0.947382 -1.827568,1.116847 -0.5974,0.14935 -1.34856,0.73937 -1.827568,1.218378 -0.679462,0.679463 -1.266186,1.266186 -1.827568,1.827568 -0.624635,0.624635 -1.403885,1.382892 -2.132163,1.9291 -0.390457,0.292843 -0.707731,1.307953 -0.812252,1.726036 -0.12508,0.500319 -0.46621,0.985274 0.203063,1.31991 0.691718,0.345859 1.320765,0.508513 1.9291,1.116847 0.599514,0.599515 1.095764,0.649414 1.827568,1.015316 0.621546,0.310773 1.841136,0.304594 2.538288,0.304594 0.720531,0 1.476756,0.304595 2.233694,0.304595 1.351655,0 1.819729,0.439615 2.944415,-0.203063 0.30663,-0.175217 0.307493,-1.102359 0.203063,-1.624505 -0.131065,-0.655326 -0.304594,-1.254521 -0.304594,-1.929099 0,-0.718547 0.06673,-1.247452 0.203063,-1.9291 0.146742,-0.73371 0.529207,-1.304576 0.710721,-2.030631 0.208002,-0.832008 0.828169,-1.672256 1.116847,-2.538288 0.24709,-0.741271 0.435595,-1.437787 0.609189,-2.132163 0.168788,-0.675154 0.203063,-1.526781 0.203063,-2.233694 0,-0.643033 0,-1.286066 0,-1.9291 0,-0.545527 -0.08581,-0.530596 -0.203063,-1.116847 z"
+ id="path2168" />
+ <path
+ sodipodi:nodetypes="ccccccccccccccccccccccccc"
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 38.378926,48.201757 c -0.171127,0.586617 0.315343,1.784573 0.101531,2.63982 -0.221006,0.884024 -1.116847,1.000333 -1.116847,2.030631 0,0.761947 -0.304594,1.375387 -0.304594,2.132163 0,0.769563 0.660654,1.475707 0.812252,2.233694 0.151746,0.758728 0.01011,1.807338 -0.304595,2.436757 -0.390112,0.780226 -0.447244,1.60521 -0.812252,2.335226 -0.279077,0.558155 -0.687991,1.560355 -0.812252,1.726036 -0.33613,0.448173 0.460184,1.021902 0.71072,1.522973 0.208447,0.416895 0.203063,0.971521 0.203063,1.522974 0,0.724502 -0.246633,1.189595 -0.406126,1.827568 -0.174785,0.699139 0.01438,2.271451 -0.527197,1.72987 C 35.481714,69.898554 34.428144,68.925698 33.950617,68.44817 33.4268,67.924354 33.587922,67.213606 33.40388,66.477436 33.252398,65.871508 32.806127,65.447192 32.549993,64.934924 32.233196,64.301331 32.010638,63.706468 31.373249,63.228426 30.69153,62.717138 30.322063,62.033911 29.748744,61.603922 29.113871,61.127767 28.83496,60.318279 28.83496,59.573291 c 0,-0.687404 1.15136,-1.252892 1.624505,-1.726037 0.624908,-0.624908 0.70829,-1.58904 1.522973,-2.132162 0.615203,-0.410135 0.870192,-1.305013 1.015316,-2.030631 0.171576,-0.857885 0.723672,-1.853471 1.116847,-2.63982 0.06769,-0.135376 0.135375,-0.270751 0.203063,-0.406127 0.225847,-0.451695 1.538359,-0.618421 2.030631,-0.913784 0.747508,-0.448505 1.719357,-0.744789 2.030631,-1.522973 z"
+ id="path2170" />
+ <path
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 58.076046,52.364551 c -0.07402,0.430513 -0.467973,1.426083 -0.609189,2.132162 -0.164612,0.823062 -0.313905,1.661747 -0.507658,2.436757 -0.170841,0.683367 -0.239076,1.362431 -0.406126,2.030631 -0.179637,0.718548 0.424763,1.412447 0.812252,1.9291 0.519747,0.692995 0.501506,1.792182 0.203064,2.538289 -0.307068,0.767668 -0.248565,1.750478 -0.406127,2.538288 -0.125224,0.62612 0.05189,1.369554 -0.406126,1.827568 -0.112917,0.112918 -0.259577,-1.55123 -0.406126,-1.624505 -0.725185,-0.362592 -0.729788,-1.802306 -0.812252,-2.132162 -0.207784,-0.831136 -0.879003,-1.351879 -1.218379,-2.030631 -0.389725,-0.779451 -1.155155,-1.294994 -1.522973,-2.030631 -0.421412,-0.842824 -1.449648,-1.229672 -1.624505,-1.9291 -0.03384,-0.135375 -0.06769,-0.27075 -0.101532,-0.406126 -0.125189,-0.500757 0.856853,-1.466042 1.116847,-1.726036 1.011873,-1.011872 2.937684,-2.445242 4.061262,-3.147478 0.573181,-0.358238 1.058897,-0.252392 1.827568,-0.406126 z"
+ id="path2172"
+ sodipodi:nodetypes="ccccccccccccccccc" />
+ <path
+ id="path1737"
+ d="m 37.688417,47.315712 -0.71875,0.8125 c -0.38602,0.45665 -1.39051,1.29725 -2.25,1.84375 -1.73431,1.10273 -1.9925,1.43503 -2.40625,3.28125 -0.41819,1.86601 -1.20261,3.39879 -2.5625,4.9375 l -1.21875,1.375 -1.125,-1.3125 c -0.62651,-0.71175 -1.28441,-1.28125 -1.46875,-1.28125 -1.25379,0 -4.82321,2.77532 -5.21875,4.0625 -0.27779,0.90392 -2.06599,2.5764 -3.1875,3 -1.8206,0.68763 -2.28988,0.98857 -3.1875,1.9375 -1.05225,1.11239 -3.59375,4.62873 -3.59375,4.96875 -10e-6,0.68315 0.819,0.03545 1.84375,-1.46875 1.84761,-2.71206 3.05427,-3.91514 4.5625,-4.46875 1.87299,-0.68751 2.99701,-1.58592 4.21875,-3.375 1.21274,-1.77592 1.96371,-2.4807 3.40625,-3.28125 l 1.03125,-0.59375 0.6875,0.78125 c 0.37531,0.41898 1.02524,1.27565 1.4375,1.90625 0.41225,0.6306 1.52648,1.91575 2.5,2.875 1.39241,1.372 1.86875,2.03741 2.15625,3.09375 0.60667,2.22915 1.3704,3.32811 2.9375,4.21875 0.9082,0.51616 1.4375,0.99682 1.4375,1.3125 -1e-5,0.27412 0.08736,0.58735 0.1875,0.6875 0.36809,0.3681 0.625,0.14605 0.625,-0.5 -1e-5,-0.79158 -0.53613,-1.33225 -1.90625,-2.03125 -1.1445,-0.58387 -2.46874,-2.3998 -2.46875,-3.375 -1e-5,-1.03552 -0.79476,-2.35565 -2.25,-3.71875 -0.74458,-0.69743 -1.57883,-1.58969 -1.875,-2 l -0.53125,-0.75 1.40625,-1.4375 c 1.39188,-1.42342 2.97575,-4.22457 3,-5.28125 0.02578,-1.1241 0.6984,-2.05067 2.15625,-2.96875 0.8262,-0.52031 1.67734,-1.10944 1.875,-1.28125 0.62359,-0.54204 0.60293,-0.12978 -0.0625,2.09375 -0.35602,1.18958 -0.71034,2.78014 -0.8125,3.53125 -0.16309,1.19898 -0.112,1.48658 0.5,2.3125 0.86439,1.16655 0.8469,1.32928 -0.03125,3.6875 -1.41928,3.81145 -1.44888,4.15262 -0.5625,3.8125 0.23124,-0.08874 0.48653,-0.4221 0.5625,-0.75 0.07594,-0.3279 0.45347,-1.43269 0.84375,-2.46875 0.85104,-2.25918 0.88211,-3.27823 0.15625,-4.46875 -0.776,-1.27274 -0.63937,-3.64892 0.3125,-5.125 0.10243,-0.15886 0.27152,-0.93871 0.375,-1.71875 0.16263,-1.22609 0.28874,-1.40625 0.8125,-1.40625 0.82127,0 1.70373,0.8059 1.9375,1.78125 0.28276,1.17981 0.54183,1.42067 2.875,2.59375 2.31324,1.16308 4.875,3.41208 4.875,4.28125 -1e-5,0.38999 0.45674,0.76886 1.53125,1.3125 1.08841,0.55069 1.53684,0.96175 1.65625,1.46875 0.22158,0.94095 1.38165,2.46875 1.875,2.46875 0.62512,0 0.4857,-0.70545 -0.25,-1.1875 -0.40391,-0.26465 -0.73657,-0.80371 -0.84375,-1.375 -0.13031,-0.69457 -0.3891,-1.05593 -0.96875,-1.3125 -1.0027,-0.44384 -0.99515,-0.6542 0.09375,-1.875 0.48749,-0.54654 1.41829,-1.63836 2.09375,-2.40625 0.7279,-0.82751 1.48006,-1.40626 1.8125,-1.40625 0.30848,0 0.69724,-0.13474 0.875,-0.3125 0.58494,-0.58494 0.59452,-0.06168 0.03125,1.03125 -0.42435,0.82336 -0.52348,1.44551 -0.4375,2.65625 0.08956,1.26153 0.01501,1.71445 -0.40625,2.25 -0.52673,0.66961 -0.53284,0.67089 0.21875,1.65625 0.95555,1.25281 1.20948,3.64442 0.5625,5.375 -0.23675,0.63325 -0.45543,1.46819 -0.5,1.84375 -0.09647,0.81279 0.40444,1.19623 0.53125,0.40625 0.04822,-0.30044 0.34601,-1.20897 0.65625,-2 0.6898,-1.75885 0.57496,-3.80067 -0.28125,-5.53125 -0.34674,-0.70081 -0.48241,-1.29716 -0.34375,-1.46875 0.12902,-0.15966 0.28705,-1.24258 0.34375,-2.40625 0.09086,-1.86494 0.19075,-2.22202 0.84375,-2.875 l 0.75,-0.71875 0.75,0.5625 c 0.59493,0.44222 0.8463,0.96429 1.15625,2.4375 0.36574,1.73851 0.51236,1.9969 2.125,3.59375 0.95518,0.94584 1.82381,1.71874 1.9375,1.71875 0.25734,0 0.99476,1.66956 1.375,3.125 0.19524,0.74733 0.78198,1.57603 1.8125,2.59375 0.83021,0.81991 1.5,1.65084 1.5,1.84375 -1e-5,0.19291 0.23081,0.34375 0.53125,0.34375 0.90995,0 0.65303,-0.57035 -1.15625,-2.4375 -1.38398,-1.42823 -1.83008,-2.1147 -2.21875,-3.40625 -0.41612,-1.38275 -0.80466,-1.92313 -2.65625,-3.75 -1.18696,-1.1711 -2.176,-2.35409 -2.1875,-2.625 -0.02356,-0.55517 -0.1424,-1.22954 -0.375,-2.15625 -0.23819,-0.94898 -2.79423,-3.37499 -3.5625,-3.375 -0.35553,0 -0.69894,0.11681 -0.78125,0.25 -0.08232,0.13319 -0.56537,0.313 -1.0625,0.40625 -1.06959,0.20066 -2.66384,1.60689 -4.28125,3.78125 -1.1611,1.56092 -1.65626,1.90751 -1.65625,1.1875 -1e-5,-0.74607 -3.5926,-3.71722 -5.625,-4.65625 -1.82273,-0.84215 -2.00786,-1.01442 -2.3125,-2.03125 -0.41516,-1.38567 -1.08354,-1.97661 -2.96875,-2.625 l -1.46875,-0.5 z m -12.28125,11.28125 c -0.12939,0 -0.12994,0.52943 -0.03125,1.1875 0.27519,1.83519 -0.33347,4.17054 -1.375,5.34375 -0.48702,0.54859 -0.98162,1.23081 -1.09375,1.53125 -0.38544,1.03278 -0.65955,3.45228 -0.5,4.25 0.10841,0.5421 0.30867,0.8125 0.65625,0.8125 0.54077,0 0.60057,-0.35223 0.25,-1.25 -0.33045,-0.84625 0.36191,-3.20331 1.3125,-4.53125 0.47232,-0.65983 1.05452,-1.8114 1.28125,-2.5625 0.71319,-2.36269 0.4468,-4.78124 -0.5,-4.78125 z"
+ style="fill:#5c2700;fill-opacity:1" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/bundles/XO/karma/assets/image/week1.png b/bundles/XO/karma/assets/image/week1.png
new file mode 100755
index 0000000..6776412
--- /dev/null
+++ b/bundles/XO/karma/assets/image/week1.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/week2.png b/bundles/XO/karma/assets/image/week2.png
new file mode 100755
index 0000000..7b73212
--- /dev/null
+++ b/bundles/XO/karma/assets/image/week2.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/week3.png b/bundles/XO/karma/assets/image/week3.png
new file mode 100755
index 0000000..4ab1f76
--- /dev/null
+++ b/bundles/XO/karma/assets/image/week3.png
Binary files differ
diff --git a/bundles/XO/karma/assets/image/week4.png b/bundles/XO/karma/assets/image/week4.png
new file mode 100755
index 0000000..448e403
--- /dev/null
+++ b/bundles/XO/karma/assets/image/week4.png
Binary files differ
diff --git a/bundles/XO/karma/css/chakra.css b/bundles/XO/karma/css/chakra.css
new file mode 100755
index 0000000..7e2362f
--- /dev/null
+++ b/bundles/XO/karma/css/chakra.css
@@ -0,0 +1,229 @@
+/* ====================================== */
+/* ====== CHAKRA CSS TEMPLATE FILE ====== */
+/* ====================================== */
+
+/* ====================================== */
+/* ========= MAIN PROPERTIES ============ */
+body
+{
+ background: #D8D8D8;
+ margin: 0 auto;
+ width: 640px;
+ min-width: 640px;
+ padding: 0;
+ font-family: "Georgia", serif;
+}
+
+img
+{
+ border: none;
+}
+
+.selected {
+ background: #FFFFFF;
+}
+
+/* ====================================== */
+/* ========== HTML ELEMENTS ============= */
+h1 { }
+h2 { }
+h3 { }
+h4 { }
+h5 { }
+h6 { }
+p { }
+span { }
+
+/* ====================================== */
+/* ========== HTML 5 ELEMENTS =========== */
+header, footer, aside, nav, article, section {
+ display: block;
+}
+
+/* ====================================== */
+/* =========== NAVIGATION BAR =========== */
+#navigation
+{
+ display: block;
+ width: 100%;
+ background: #6E6E6E;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+}
+ #knavbar {
+ display: table;
+ width: 640px;
+ margin: 0 auto;
+ }
+
+#curriculum
+{
+ padding: 5px;
+ background: #ccc;
+ margin: 10px;
+ display: block;
+ width: auto;
+ text-align: right;
+ display: none;
+ /* How about putting 'Link to subject curriculum' in the help section ? */
+}
+
+.topNav {
+ width: 30px;
+ height: 30px;
+ padding: 5px;
+}
+
+.floatLeft {
+ float: left;
+}
+.floatRight {
+ float: right;
+}
+.inline {
+ display: inline;
+}
+
+/* ====================================== */
+/* =========== MIDDLE SECTION =========== */
+#middle
+{
+ display: block;
+ padding: .5em 0 .5em 0;
+ background: #BDBDBD;
+}
+
+#middle header {
+ text-align: center;
+ font-size: 1.0em;
+ margin: 5px 0 5px 0;
+ padding-bottom: 2px;
+ font-weight: bold;
+}
+
+ .middleRow ul {
+ display: table;
+ margin: 0 auto;
+ padding: 0;
+ background: #BDBDBD;
+ }
+ .middleRow ul li {
+ display: table-cell;
+ text-align: center;
+ margin: 0;
+ border: 3px solid #BDBDBD;
+ }
+ .middleRow ul li a {
+ display: block;
+ text-decoration: none;
+ font-weight: bold;
+ color: #000;
+ padding: 0.4em;
+ }
+ .middleRow ul li a img {
+ width: 120px;
+ }
+ .middleRow ul li:hover {
+ text-decoration: underline;
+ border: 3px solid #424242;
+ }
+
+/* ====================================== */
+/* ============ ADMIN SECTION =========== */
+#admin {
+ display: block;
+ background: #4080c0;
+ width: 100%;
+ margin: 0 auto;
+}
+
+#admin ul {
+ display: table;
+ list-style: none;
+ margin: 0 auto;
+ padding: .5em 0 .5em 0;
+}
+
+#admin ul li {
+ display: table-cell;
+ text-align: center;
+ padding: 0.2em 2em 0.2em 2em;
+}
+
+#admin ul li a
+{
+ display: block;
+ text-decoration: none;
+ font-weight: bold;
+ color: #000000;
+}
+#admin ul li a:hover {
+ text-decoration: underline;
+}
+#admin p {
+ line-height: 0;
+}
+
+#admin img
+{
+ height: 50px;
+ width: auto;
+}
+
+/* ====================================== */
+/* ====== INDIVIDUAL GRADE SECTION ====== */
+#monthSelect {
+ text-align: center;
+ font-size: 1.0em;
+ font-weight: bold;
+ padding: 5px 0 5px 0;
+}
+
+.monthList {
+ /* */
+ border-top: 1px solid #666;
+ text-align: center;
+ padding: 5px 0 5px 0;
+}
+
+.lessonList {
+ padding: 1em;
+ margin: 5px 0 5px 0;
+ height: 500px;
+ border-top: 1px dashed #666;
+}
+
+ .lessonName {
+ text-decoration: none;
+ text-align: center;
+ font-weight: bold;
+ font-size: 1.1em;
+ margin-bottom: 1em;
+ }
+ .lessonList img {
+ display: block;
+ margin: 0 auto;
+ padding: 5px;
+ border: 1px solid #aaa;
+ background: #ddd;
+ }
+
+.lesson {
+ width: 300px;
+ height: 250px;
+ float: left;
+}
+
+.preview{
+ width: 250px;
+}
+
+.menuSelectType {
+ margin: 0;
+ padding: 0;
+ text-align: center;
+}
+.menuSelectType li {
+ list-style: none;
+ display: inline;
+}
diff --git a/bundles/XO/karma/css/demos.css b/bundles/XO/karma/css/demos.css
new file mode 100755
index 0000000..b005b7d
--- /dev/null
+++ b/bundles/XO/karma/css/demos.css
@@ -0,0 +1,451 @@
+body {
+ font-size: 62.5%;
+}
+
+table {
+ font-size: 1em;
+}
+
+/ Site
+/ Site
+ -------------------------------- /
+ -------------------------------- /
+
+body {
+ font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
+}
+
+/ Layout
+/ Layout
+ -------------------------------- /
+ -------------------------------- /
+
+.layout-grid {
+ width: 960px;
+}
+
+.layout-grid td {
+ vertical-align: top;
+}
+
+.layout-grid td.left-nav {
+ width: 140px;
+}
+
+.layout-grid td.normal {
+ border-left: 1px solid #eee;
+ padding: 20px 24px;
+ font-family: "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
+}
+
+.layout-grid td.demos {
+ background: url('/../assets/default/../assets/default/../assets/default/images/demos_bg.jpg') no-repeat;
+ background: url('/../assets/default/../assets/default/../assets/default/images/demos_bg.jpg') no-repeat;
+ background: url('/../assets/default/../assets/default/../assets/default/images/demos_bg.jpg') no-repeat;
+ background: url('/../assets/default/../assets/default/../assets/default/images/demos_bg.jpg') no-repeat;
+ height: 337px;
+ overflow: hidden;
+}
+
+/ Normal
+/ Normal
+ -------------------------------- /
+ -------------------------------- /
+
+.normal h3,
+.normal h4 {
+ margin: 0;
+ font-weight: normal;
+}
+
+.normal h3 {
+ padding: 0 0 9px;
+ font-size: 1.8em;
+}
+
+.normal h4 {
+ padding-bottom: 21px;
+ border-bottom: 1px dashed #999;
+ font-size: 1.2em;
+ font-weight: bold;
+}
+
+.normal p {
+ font-size: 1.2em;
+}
+
+/ Demos /
+/ Demos /
+/ Demos /
+/ Demos /
+
+.demos-nav, .demos-nav dt, .demos-nav dd, .demos-nav ul, .demos-nav li {
+ margin: 0;
+ padding: 0
+}
+
+.demos-nav {
+ float: left;
+ width: 170px;
+ font-size: 1.3em;
+}
+
+.demos-nav dt,
+.demos-nav h4 {
+ margin: 0;
+ padding: 0;
+ font: normal 1.1em "Trebuchet MS", "Helvetica", "Arial", "Verdana", "sans-serif";
+ color: #e87b10;
+}
+
+.demos-nav dt,
+.demos-nav h4 {
+ margin-top: 1.5em;
+ margin-bottom: 0;
+ padding-left: 8px;
+ padding-bottom:5px;
+ line-height: 1.2em;
+ border-bottom: 1px solid #F4F4F4;
+}
+
+.demos-nav dd a,
+.demos-nav li a {
+ border-bottom: 1px solid #F4F4F4;
+ display:block;
+ padding: 4px 3px 4px 8px;
+ font-size: 90%;
+ text-decoration: none;
+ color: #555 ;
+ margin:2px 0;
+ height:13px;
+}
+
+.demos-nav dd a:hover,
+.demos-nav dd a:focus,
+.demos-nav dd a:hover,
+.demos-nav dd a:focus {
+ background: #f3f3f3;
+ color:#000;
+ -moz-border-radius: 5px; -webkit-border-radius: 5px;
+}
+ .demos-nav dd a.selected {
+ background: #555;
+ color:#ffffff;
+ -moz-border-radius: 5px; -webkit-border-radius: 5px;
+}
+
+
+/ new styles for demo pages, added by Filament 12.29.08
+/ new styles for demo pages, added by Filament 12.29.08
+eventually we should convert the font sizes to ems -- using px for now to minimize style conflicts
+/
+/
+
+.normal h3.demo-header { font-size:32px; padding:0 0 5px; border-bottom:1px solid #eee; text-transform: capitalize; }
+.normal h4.demo-subheader { font-size:10px; text-transform: uppercase; color:#999; padding:8px 0 3px; border:0; margin:0; }
+.normal a:link,
+.normal a:visited { color:#1b75bb; text-decoration:none; }
+.normal a:hover,
+.normal a:active { color:#0b559b; }
+
+#demo-config { padding:20px 0 0; }
+
+#demo-frame { float:left; width:540px; height:380px; border:1px solid #ddd; overflow: auto; position: relative; }
+#demo-frame h3, #demo-frame h4 { padding: 0; font-weight: bold; font-size: 1em; }
+
+#demo-config-menu { float:right; width:180px; }
+#demo-config-menu h4 { font-size:13px; color:#666; font-weight:normal; border:0; padding-left:18px; }
+
+#demo-config-menu ul { list-style: none; padding: 0; margin: 0; }
+
+#demo-config-menu li { font-size:12px; padding:0 0 0 10px; margin:3px 0; zoom: 1; }
+
+#demo-config-menu li a:link,
+#demo-config-menu li a:visited { display:block; padding:1px 8px 4px; border-bottom:1px dotted #b3b3b3; }
+ html #demo-config-menu li a:link,
+ html #demo-config-menu li a:link,
+ html #demo-config-menu li a:visited { padding:1px 8px 2px; }
+ html #demo-config-menu li a:visited { padding:1px 8px 2px; }
+#demo-config-menu li a:hover,
+#demo-config-menu li a:active { background-color:#f6f6f6; }
+
+#demo-config-menu li.demo-config-on { background: url(../assets/default/../assets/default/../assets/default/images/demo-config-on-tile.gif) repeat-x left center; }
+#demo-config-menu li.demo-config-on { background: url(../assets/default/../assets/default/../assets/default/images/demo-config-on-tile.gif) repeat-x left center; }
+#demo-config-menu li.demo-config-on { background: url(../assets/default/../assets/default/../assets/default/images/demo-config-on-tile.gif) repeat-x left center; }
+#demo-config-menu li.demo-config-on { background: url(../assets/default/../assets/default/../assets/default/images/demo-config-on-tile.gif) repeat-x left center; }
+
+#demo-config-menu li.demo-config-on a:link,
+#demo-config-menu li.demo-config-on a:visited,
+#demo-config-menu li.demo-config-on a:hover,
+#demo-config-menu li.demo-config-on a:active { background: url(../assets/default/../assets/default/../assets/default/images/demo-config-on.gif) no-repeat left; padding-left:18px; color:#fff; border:0; margin-left:-10px; margin-top: 0px; margin-bottom: 0px; }
+#demo-config-menu li.demo-config-on a:active { background: url(../assets/default/../assets/default/../assets/default/images/demo-config-on.gif) no-repeat left; padding-left:18px; color:#fff; border:0; margin-left:-10px; margin-top: 0px; margin-bottom: 0px; }
+#demo-config-menu li.demo-config-on a:active { background: url(../assets/default/../assets/default/../assets/default/images/demo-config-on.gif) no-repeat left; padding-left:18px; color:#fff; border:0; margin-left:-10px; margin-top: 0px; margin-bottom: 0px; }
+#demo-config-menu li.demo-config-on a:active { background: url(../assets/default/../assets/default/../assets/default/images/demo-config-on.gif) no-repeat left; padding-left:18px; color:#fff; border:0; margin-left:-10px; margin-top: 0px; margin-bottom: 0px; }
+
+#demo-source, #demo-notes {
+ clear: both;
+ padding: 20px 0 0;
+ font-size: 1.3em;
+}
+
+#demo-notes { width:520px; color:#333; font-size: 1em; }
+#demo-notes p code, .demo-description p code { padding: 0; font-weight: bold; }
+#demo-source pre, #demo-source code { padding: 0; }
+code, pre { padding:8px 0 8px 20px ; font-size: 1.2em; line-height:130%; }
+
+#demo-source a:link,
+#demo-source a:visited,
+#demo-source a:hover,
+#demo-source a:active { font-size:12px; padding-left:13px; background-position: left center; background-repeat: no-repeat; }
+
+#demo-source a.source-open:link,
+#demo-source a.source-open:visited,
+#demo-source a.source-open:hover,
+#demo-source a.source-open:active { background-image: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-open.gif); }
+#demo-source a.source-open:active { background-image: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-open.gif); }
+#demo-source a.source-open:active { background-image: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-open.gif); }
+#demo-source a.source-open:active { background-image: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-open.gif); }
+
+#demo-source a.source-closed:link,
+#demo-source a.source-closed:visited,
+#demo-source a.source-closed:hover,
+#demo-source a.source-closed:active { background-image: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-closed.gif); }
+#demo-source a.source-closed:active { background-image: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-closed.gif); }
+#demo-source a.source-closed:active { background-image: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-closed.gif); }
+#demo-source a.source-closed:active { background-image: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-closed.gif); }
+
+div.demo {
+ padding:12px;
+ font-family: "Trebuchet MS", "Arial", "Helvetica", "Verdana", "sans-serif";
+ -moz-box-align:center;
+ width:70%;
+ margin-left: 10%;
+ margin-right:10%;
+ padding:12px;
+}
+
+div.demo h3.docs { clear:left; font-size:12px; font-weight:normal; padding:0 0 1em; margin:0; }
+
+div.demo-description {
+ clear:both;
+ padding:12px;
+ font-family: "Trebuchet MS", "Arial", "Helvetica", "Verdana", "sans-serif";
+ font-size: 1.3em;
+ line-height: 1.4em;
+}
+
+.ui-draggable, .ui-droppable {
+ background-position: top left;
+}
+
+.left-nav .demos-nav {
+ padding-right: 10px;
+}
+
+#demo-link { font-size:11px; padding-top: 6px; clear: both; overflow: hidden; }
+#demo-link a span.ui-icon { float:left; margin-right:3px; }
+
+/ Component containers
+/ Component containers
+----------------------------------/
+----------------------------------/
+#widget-docs .ui-widget { font-family: Trebuchet MS,Verdana,Arial,sans-serif; font-size: 1em; }
+#widget-docs .ui-widget input, #widget-docs .ui-widget select, #widget-docs .ui-widget textarea, #widget-docs .ui-widget button { font-family: Trebuchet MS,Verdana,Arial,sans-serif; font-size: 1em; }
+#widget-docs .ui-widget-header { border: 1px solid #ffffff; background: #464646 url(../assets/default/../assets/default/../assets/default/images/464646_40x100_textures_01_flat_100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+#widget-docs .ui-widget-header { border: 1px solid #ffffff; background: #464646 url(../assets/default/../assets/default/../assets/default/images/464646_40x100_textures_01_flat_100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+#widget-docs .ui-widget-header { border: 1px solid #ffffff; background: #464646 url(../assets/default/../assets/default/../assets/default/images/464646_40x100_textures_01_flat_100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+#widget-docs .ui-widget-header { border: 1px solid #ffffff; background: #464646 url(../assets/default/../assets/default/../assets/default/images/464646_40x100_textures_01_flat_100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }
+#widget-docs .ui-widget-header a { color: #ffffff; }
+#widget-docs .ui-widget-content { border: 1px solid #ffffff; background: #ffffff url(../assets/default/../assets/default/../assets/default/images/ffffff_40x100_textures_01_flat_75.png) 50% 50% repeat-x; color: #222222; }
+#widget-docs .ui-widget-content { border: 1px solid #ffffff; background: #ffffff url(../assets/default/../assets/default/../assets/default/images/ffffff_40x100_textures_01_flat_75.png) 50% 50% repeat-x; color: #222222; }
+#widget-docs .ui-widget-content { border: 1px solid #ffffff; background: #ffffff url(../assets/default/../assets/default/../assets/default/images/ffffff_40x100_textures_01_flat_75.png) 50% 50% repeat-x; color: #222222; }
+#widget-docs .ui-widget-content { border: 1px solid #ffffff; background: #ffffff url(../assets/default/../assets/default/../assets/default/images/ffffff_40x100_textures_01_flat_75.png) 50% 50% repeat-x; color: #222222; }
+#widget-docs .ui-widget-content a { color: #222222; }
+
+/ Interaction states
+/ Interaction states
+----------------------------------/
+----------------------------------/
+#widget-docs .ui-state-default, #widget-docs .ui-widget-content #widget-docs .ui-state-default { border: 1px solid #666666; background: #555555 url(../assets/default/../assets/default/../assets/default/images/555555_40x100_textures_03_highlight_soft_75.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+#widget-docs .ui-state-default, #widget-docs .ui-widget-content #widget-docs .ui-state-default { border: 1px solid #666666; background: #555555 url(../assets/default/../assets/default/../assets/default/images/555555_40x100_textures_03_highlight_soft_75.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+#widget-docs .ui-state-default, #widget-docs .ui-widget-content #widget-docs .ui-state-default { border: 1px solid #666666; background: #555555 url(../assets/default/../assets/default/../assets/default/images/555555_40x100_textures_03_highlight_soft_75.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+#widget-docs .ui-state-default, #widget-docs .ui-widget-content #widget-docs .ui-state-default { border: 1px solid #666666; background: #555555 url(../assets/default/../assets/default/../assets/default/images/555555_40x100_textures_03_highlight_soft_75.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+#widget-docs .ui-state-default a { color: #ffffff; text-decoration: none; outline: none; }
+#widget-docs .ui-state-hover, #widget-docs .ui-widget-content #widget-docs .ui-state-hover, #widget-docs .ui-state-focus, #widget-docs .ui-widget-content #widget-docs .ui-state-focus { border: 1px solid #666666; background: #444444 url(../assets/default/../assets/default/../assets/default/images/444444_40x100_textures_03_highlight_soft_60.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+#widget-docs .ui-state-hover, #widget-docs .ui-widget-content #widget-docs .ui-state-hover, #widget-docs .ui-state-focus, #widget-docs .ui-widget-content #widget-docs .ui-state-focus { border: 1px solid #666666; background: #444444 url(../assets/default/../assets/default/../assets/default/images/444444_40x100_textures_03_highlight_soft_60.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+#widget-docs .ui-state-hover, #widget-docs .ui-widget-content #widget-docs .ui-state-hover, #widget-docs .ui-state-focus, #widget-docs .ui-widget-content #widget-docs .ui-state-focus { border: 1px solid #666666; background: #444444 url(../assets/default/../assets/default/../assets/default/images/444444_40x100_textures_03_highlight_soft_60.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+#widget-docs .ui-state-hover, #widget-docs .ui-widget-content #widget-docs .ui-state-hover, #widget-docs .ui-state-focus, #widget-docs .ui-widget-content #widget-docs .ui-state-focus { border: 1px solid #666666; background: #444444 url(../assets/default/../assets/default/../assets/default/images/444444_40x100_textures_03_highlight_soft_60.png) 50% 50% repeat-x; font-weight: normal; color: #ffffff; outline: none; }
+#widget-docs .ui-state-hover a { color: #ffffff; text-decoration: none; outline: none; }
+#widget-docs .ui-state-active, #widget-docs .ui-widget-content #widget-docs .ui-state-active { border: 1px solid #666666; background: #ffffff url(../assets/default/../assets/default/../assets/default/images/ffffff_40x100_textures_01_flat_65.png) 50% 50% repeat-x; font-weight: normal; color: #F6921E; outline: none; }
+#widget-docs .ui-state-active, #widget-docs .ui-widget-content #widget-docs .ui-state-active { border: 1px solid #666666; background: #ffffff url(../assets/default/../assets/default/../assets/default/images/ffffff_40x100_textures_01_flat_65.png) 50% 50% repeat-x; font-weight: normal; color: #F6921E; outline: none; }
+#widget-docs .ui-state-active, #widget-docs .ui-widget-content #widget-docs .ui-state-active { border: 1px solid #666666; background: #ffffff url(../assets/default/../assets/default/../assets/default/images/ffffff_40x100_textures_01_flat_65.png) 50% 50% repeat-x; font-weight: normal; color: #F6921E; outline: none; }
+#widget-docs .ui-state-active, #widget-docs .ui-widget-content #widget-docs .ui-state-active { border: 1px solid #666666; background: #ffffff url(../assets/default/../assets/default/../assets/default/images/ffffff_40x100_textures_01_flat_65.png) 50% 50% repeat-x; font-weight: normal; color: #F6921E; outline: none; }
+#widget-docs .ui-state-active a { color: #F6921E; outline: none; text-decoration: none; }
+
+/ Interaction Cues
+/ Interaction Cues
+----------------------------------/
+----------------------------------/
+#widget-docs .ui-state-highlight, #widget-docs .ui-widget-content #widget-docs .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(../assets/default/../assets/default/../assets/default/images/fbf9ee_40x100_textures_02_glass_55.png) 50% 50% repeat-x; color: #363636; }
+#widget-docs .ui-state-highlight, #widget-docs .ui-widget-content #widget-docs .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(../assets/default/../assets/default/../assets/default/images/fbf9ee_40x100_textures_02_glass_55.png) 50% 50% repeat-x; color: #363636; }
+#widget-docs .ui-state-highlight, #widget-docs .ui-widget-content #widget-docs .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(../assets/default/../assets/default/../assets/default/images/fbf9ee_40x100_textures_02_glass_55.png) 50% 50% repeat-x; color: #363636; }
+#widget-docs .ui-state-highlight, #widget-docs .ui-widget-content #widget-docs .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(../assets/default/../assets/default/../assets/default/images/fbf9ee_40x100_textures_02_glass_55.png) 50% 50% repeat-x; color: #363636; }
+#widget-docs .ui-state-error, #widget-docs .ui-widget-content #widget-docs .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(../assets/default/../assets/default/../assets/default/images/fef1ec_40x100_textures_05_inset_soft_95.png) 50% bottom repeat-x; color: #cd0a0a; }
+#widget-docs .ui-state-error, #widget-docs .ui-widget-content #widget-docs .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(../assets/default/../assets/default/../assets/default/images/fef1ec_40x100_textures_05_inset_soft_95.png) 50% bottom repeat-x; color: #cd0a0a; }
+#widget-docs .ui-state-error, #widget-docs .ui-widget-content #widget-docs .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(../assets/default/../assets/default/../assets/default/images/fef1ec_40x100_textures_05_inset_soft_95.png) 50% bottom repeat-x; color: #cd0a0a; }
+#widget-docs .ui-state-error, #widget-docs .ui-widget-content #widget-docs .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(../assets/default/../assets/default/../assets/default/images/fef1ec_40x100_textures_05_inset_soft_95.png) 50% bottom repeat-x; color: #cd0a0a; }
+#widget-docs .ui-state-error-text, #widget-docs .ui-widget-content #widget-docs .ui-state-error-text { color: #cd0a0a; }
+#widget-docs .ui-state-disabled, #widget-docs .ui-widget-content #widget-docs .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+#widget-docs .ui-priority-primary, #widget-docs .ui-widget-content #widget-docs .ui-priority-primary { font-weight: bold; }
+#widget-docs .ui-priority-secondary, #widget-docs .ui-widget-content #widget-docs .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+
+/ Icons
+/ Icons
+----------------------------------/
+----------------------------------/
+
+/ states and images /
+/ states and images /
+/ states and images /
+/ states and images /
+#demo-frame-wrapper .ui-icon, #widget-docs .ui-icon { width: 16px; height: 16px; background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#demo-frame-wrapper .ui-icon, #widget-docs .ui-icon { width: 16px; height: 16px; background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#demo-frame-wrapper .ui-icon, #widget-docs .ui-icon { width: 16px; height: 16px; background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#demo-frame-wrapper .ui-icon, #widget-docs .ui-icon { width: 16px; height: 16px; background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-widget-content .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-widget-content .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-widget-content .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-widget-content .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-widget-header .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-widget-header .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-widget-header .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-widget-header .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/222222_256x240_icons_icons.png); }
+#widget-docs .ui-state-default .ui-icon { background-image: url(../assets/default/../assets/default/../assets/default/images/888888_256x240_icons_icons.png); }
+#widget-docs .ui-state-default .ui-icon { background-image: url(../assets/default/../assets/default/../assets/default/images/888888_256x240_icons_icons.png); }
+#widget-docs .ui-state-default .ui-icon { background-image: url(../assets/default/../assets/default/../assets/default/images/888888_256x240_icons_icons.png); }
+#widget-docs .ui-state-default .ui-icon { background-image: url(../assets/default/../assets/default/../assets/default/images/888888_256x240_icons_icons.png); }
+#widget-docs .ui-state-hover .ui-icon, #widget-docs .ui-state-focus .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/454545_256x240_icons_icons.png); }
+#widget-docs .ui-state-hover .ui-icon, #widget-docs .ui-state-focus .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/454545_256x240_icons_icons.png); }
+#widget-docs .ui-state-hover .ui-icon, #widget-docs .ui-state-focus .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/454545_256x240_icons_icons.png); }
+#widget-docs .ui-state-hover .ui-icon, #widget-docs .ui-state-focus .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/454545_256x240_icons_icons.png); }
+#widget-docs .ui-state-active .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/454545_256x240_icons_icons.png); }
+#widget-docs .ui-state-active .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/454545_256x240_icons_icons.png); }
+#widget-docs .ui-state-active .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/454545_256x240_icons_icons.png); }
+#widget-docs .ui-state-active .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/454545_256x240_icons_icons.png); }
+#widget-docs .ui-state-highlight .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/2e83ff_256x240_icons_icons.png); }
+#widget-docs .ui-state-highlight .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/2e83ff_256x240_icons_icons.png); }
+#widget-docs .ui-state-highlight .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/2e83ff_256x240_icons_icons.png); }
+#widget-docs .ui-state-highlight .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/2e83ff_256x240_icons_icons.png); }
+#widget-docs .ui-state-error .ui-icon, #widget-docs .ui-state-error-text .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/cd0a0a_256x240_icons_icons.png); }
+#widget-docs .ui-state-error .ui-icon, #widget-docs .ui-state-error-text .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/cd0a0a_256x240_icons_icons.png); }
+#widget-docs .ui-state-error .ui-icon, #widget-docs .ui-state-error-text .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/cd0a0a_256x240_icons_icons.png); }
+#widget-docs .ui-state-error .ui-icon, #widget-docs .ui-state-error-text .ui-icon {background-image: url(../assets/default/../assets/default/../assets/default/images/cd0a0a_256x240_icons_icons.png); }
+
+
+/ Misc visuals
+/ Misc visuals
+----------------------------------/
+----------------------------------/
+
+/ Corner radius /
+/ Corner radius /
+/ Corner radius /
+/ Corner radius /
+#widget-docs .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; }
+#widget-docs .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
+#widget-docs .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
+#widget-docs .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
+#widget-docs .ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; }
+#widget-docs .ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
+#widget-docs .ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; }
+#widget-docs .ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; }
+#widget-docs .ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; }
+
+/ Overlays /
+/ Overlays /
+/ Overlays /
+/ Overlays /
+#widget-docs .ui-widget-overlay { background: #aaaaaa url(../assets/default/../assets/default/../assets/default/images/aaaaaa_40x100_textures_01_flat_0.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+#widget-docs .ui-widget-overlay { background: #aaaaaa url(../assets/default/../assets/default/../assets/default/images/aaaaaa_40x100_textures_01_flat_0.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+#widget-docs .ui-widget-overlay { background: #aaaaaa url(../assets/default/../assets/default/../assets/default/images/aaaaaa_40x100_textures_01_flat_0.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+#widget-docs .ui-widget-overlay { background: #aaaaaa url(../assets/default/../assets/default/../assets/default/images/aaaaaa_40x100_textures_01_flat_0.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); }
+#widget-docs .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(../assets/default/../assets/default/../assets/default/images/aaaaaa_40x100_textures_01_flat_0.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }
+#widget-docs .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(../assets/default/../assets/default/../assets/default/images/aaaaaa_40x100_textures_01_flat_0.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }
+#widget-docs .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(../assets/default/../assets/default/../assets/default/images/aaaaaa_40x100_textures_01_flat_0.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }
+#widget-docs .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(../assets/default/../assets/default/../assets/default/images/aaaaaa_40x100_textures_01_flat_0.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }
+
+/
+/
+----------------------------------/
+----------------------------------/
+
+#widget-docs { margin:20px 0 0; border: none; }
+
+#widget-docs h2, #widget-docs h3, #widget-docs h4, #widget-docs p, #widget-docs ul, #widget-docs code { margin:0; padding:0; }
+#widget-docs code { display:block; color:#444; font-size:.9em; margin:0 0 1em; }
+#widget-docs code strong { color:#000; }
+#widget-docs p { margin:0 3em 1.2em 0; }
+#widget-docs p.intro { font-size:13px; color:#666; line-height:1.3; }
+#widget-docs ul { list-style-type: none; }
+
+#widget-docs h2 { font-size:16px; margin:1.2em 0 .5em; }
+#widget-docs h3 { font-size:14px; color:#e6820E; margin:1.5em 0 .5em; }
+.normal #widget-docs h4 { font-size:12px; color:#000; border:0; margin:0 0 .5em; }
+
+#docs-overview-main { width:400px; }
+#docs-overview-sidebar { float:right; width:200px; }
+#docs-overview-sidebar a span { color:#666; }
+#widget-docs #docs-overview-main p { margin-right:0; }
+#widget-docs #docs-overview-sidebar h4 { padding-left:0; }
+
+.docs-list-header { float:left; width:100%; margin:10px 0 0; border-bottom:1px solid #eee; }
+#widget-docs .docs-list-header h2 { float:left; margin:0; }
+#widget-docs .docs-list-header p { float:right; margin:5px 0; font-size:11px; }
+
+.docs-list { float:left; width:100%; padding:0 0 10px; }
+.docs-list .param-header { float:left; clear:left; width:100%; padding:8px 0; border-top:1px solid #eee; }
+#widget-docs .param-header h3, #widget-docs .param-header p { margin:0; float:left; }
+#widget-docs .param-header h3 { width:50%; }
+#widget-docs .param-header h3 span { background: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-closed.gif) no-repeat left; padding-left:13px; }
+#widget-docs .param-header h3 span { background: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-closed.gif) no-repeat left; padding-left:13px; }
+#widget-docs .param-header h3 span { background: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-closed.gif) no-repeat left; padding-left:13px; }
+#widget-docs .param-header h3 span { background: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-closed.gif) no-repeat left; padding-left:13px; }
+#widget-docs .param-open .param-header h3 span { background: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-open.gif) no-repeat left; }
+#widget-docs .param-open .param-header h3 span { background: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-open.gif) no-repeat left; }
+#widget-docs .param-open .param-header h3 span { background: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-open.gif) no-repeat left; }
+#widget-docs .param-open .param-header h3 span { background: url(../assets/default/../assets/default/../assets/default/images/demo-spindown-open.gif) no-repeat left; }
+#widget-docs .param-header p { width:24%; }
+#widget-docs .param-header p.param-type span { background: url(../assets/default/../assets/default/../assets/default/images/icon-docs-info.gif) no-repeat left; cursor:pointer; border-bottom:1px dashed #ccc; padding-left:15px; }
+#widget-docs .param-header p.param-type span { background: url(../assets/default/../assets/default/../assets/default/images/icon-docs-info.gif) no-repeat left; cursor:pointer; border-bottom:1px dashed #ccc; padding-left:15px; }
+#widget-docs .param-header p.param-type span { background: url(../assets/default/../assets/default/../assets/default/images/icon-docs-info.gif) no-repeat left; cursor:pointer; border-bottom:1px dashed #ccc; padding-left:15px; }
+#widget-docs .param-header p.param-type span { background: url(../assets/default/../assets/default/../assets/default/images/icon-docs-info.gif) no-repeat left; cursor:pointer; border-bottom:1px dashed #ccc; padding-left:15px; }
+
+.param-details { padding-left:13px; }
+.param-args { margin:0 0 1.5em; border-top:1px dotted #ccc;}
+.param-args td { padding:3px 30px 3px 5px; border-bottom:1px dotted #ccc; }
+
+
+/ overrides for ui-tab styles /
+/ overrides for ui-tab styles /
+/ overrides for ui-tab styles /
+/ overrides for ui-tab styles /
+#widget-docs ul.ui-tabs-nav { padding:0 0 0 8px; }
+#widget-docs .ui-tabs-nav li { margin:5px 5px 0 0; }
+
+#widget-docs .ui-tabs-nav li a:link,
+#widget-docs .ui-tabs-nav li a:visited,
+#widget-docs .ui-tabs-nav li a:hover,
+#widget-docs .ui-tabs-nav li a:active { font-size:14px; padding:4px 1.2em 3px; color:#fff; }
+
+#widget-docs .ui-tabs-nav li.ui-tabs-selected a:link,
+#widget-docs .ui-tabs-nav li.ui-tabs-selected a:visited,
+#widget-docs .ui-tabs-nav li.ui-tabs-selected a:hover,
+#widget-docs .ui-tabs-nav li.ui-tabs-selected a:active { color:#e6820E; }
+
+#widget-docs .ui-tabs-panel { padding:20px 9px; font-size:12px; line-height:1.4; color:#000; }
+
+#widget-docs .ui-widget-content a:link,
+#widget-docs .ui-widget-content a:visited { color:#1b75bb; text-decoration:none; }
+#widget-docs .ui-widget-content a:hover,
+#widget-docs .ui-widget-content a:active { color:#0b559b; }
+
diff --git a/bundles/XO/karma/css/intro.css b/bundles/XO/karma/css/intro.css
new file mode 100755
index 0000000..5bda019
--- /dev/null
+++ b/bundles/XO/karma/css/intro.css
@@ -0,0 +1,94 @@
+body {
+padding-left:15%;
+width:60%;
+}
+#header {
+background-color:transparent;
+height:140px;
+position:relative;
+width:100%;
+}
+#headerBg1 {
+/*background-image:url(../assets/image/karma-logo80x94.png);
+background-repeat:no-repeat;*/
+/*height:120px;*/
+display:inline;
+float:left;
+}
+#headerBg2{
+display:inline;
+float:left;
+margin-left: 10%;
+}
+
+#header ul {
+-moz-border-radius-bottomleft:5px;
+-moz-border-radius-bottomright:5px;
+-moz-border-radius-topleft:5px;
+-moz-border-radius-topright:5px;
+-webkit-border-bottom-left-radius:5px;
+-webkit-border-bottom-right-radius:5px;
+-webkit-border-top-left-radius:5px;
+-webkit-border-top-right-radius:5px;
+background-color:#EEF7FB;
+border:1px solid black;
+/*bottom:0;
+position:absolute;*/
+width:95%;
+float:left;
+}
+#header ul li {
+display:inline;
+list-style-type:none;
+padding:5px;
+}
+#header ul li a {
+text-decoration:none;
+}
+#intro {
+float:left;
+padding-top:40px;
+width:100%;
+}
+#introText {
+display:inline;
+float:left;
+width:70%;
+}
+#introText a {
+text-decoration:none;
+}
+#monkeyHolder {
+display:inline;
+float:right;
+width:20%;
+}
+#demos {
+float:left;
+width:100%;
+}
+#demos .imgs {
+margin-left:auto;
+margin-right:auto;
+width:95%;
+}
+#demos img {
+-moz-border-radius-bottomleft:5px;
+-moz-border-radius-bottomright:5px;
+-moz-border-radius-topleft:5px;
+-moz-border-radius-topright:5px;
+-webkit-border-bottom-left-radius:5px;
+-webkit-border-bottom-right-radius:5px;
+-webkit-border-top-left-radius:5px;
+-webkit-border-top-right-radius:5px;
+border:1px solid black;
+margin:10px;
+padding-left:10px;
+padding-right:10px;
+}
+#footer {
+float:left;
+font-size:smaller;
+padding-top:50px;
+width:100%;
+} \ No newline at end of file
diff --git a/bundles/XO/karma/css/karma.css b/bundles/XO/karma/css/karma.css
new file mode 100755
index 0000000..bce5ee2
--- /dev/null
+++ b/bundles/XO/karma/css/karma.css
@@ -0,0 +1,21 @@
+/**
+karma loader
+**/
+@media screen {
+ #karma-loader{
+ position:fixed;
+ top:0;
+ left:0;
+ padding: 2px 2px 1px 5px;
+ font-family: arial;
+ font-size: 12px;
+ background: #0066cc;
+ color: #ffffff;
+
+ }
+ #karma-loader.status{
+
+ left:110px;
+
+ }
+}
diff --git a/bundles/XO/karma/css/qunit.css b/bundles/XO/karma/css/qunit.css
new file mode 100755
index 0000000..4542933
--- /dev/null
+++ b/bundles/XO/karma/css/qunit.css
@@ -0,0 +1,17 @@
+h1#qunit-header { padding: 15px; font-size: large; background-color: #06b; color: white; font-family: 'trebuchet ms', verdana, arial; margin: 0; }
+h1#qunit-header a { color: white; }
+
+h2#qunit-banner { height: 2em; border-bottom: 1px solid white; background-color: #eee; margin: 0; font-family: 'trebuchet ms', verdana, arial; }
+h2#qunit-banner.pass { background-color: green; }
+h2#qunit-banner.fail { background-color: red; }
+
+h2#qunit-userAgent { padding: 10px; background-color: #eee; color: black; margin: 0; font-size: small; font-weight: normal; font-family: 'trebuchet ms', verdana, arial; font-size: 10pt; }
+
+div#qunit-testrunner-toolbar { background: #eee; border-top: 1px solid black; padding: 10px; font-family: 'trebuchet ms', verdana, arial; margin: 0; font-size: 10pt; }
+
+ol#qunit-tests { font-family: 'trebuchet ms', verdana, arial; font-size: 10pt; }
+ol#qunit-tests li strong { cursor:pointer; }
+ol#qunit-tests .pass { color: green; }
+ol#qunit-tests .fail { color: red; }
+
+p#qunit-testresult { margin-left: 1em; font-size: 10pt; font-family: 'trebuchet ms', verdana, arial; }
diff --git a/bundles/XO/karma/css/ui.all.css b/bundles/XO/karma/css/ui.all.css
new file mode 100755
index 0000000..543e4c3
--- /dev/null
+++ b/bundles/XO/karma/css/ui.all.css
@@ -0,0 +1,2 @@
+@import "ui.base.css";
+@import "ui.theme.css";
diff --git a/bundles/XO/karma/css/ui.base.css b/bundles/XO/karma/css/ui.base.css
new file mode 100755
index 0000000..ba53841
--- /dev/null
+++ b/bundles/XO/karma/css/ui.base.css
@@ -0,0 +1,2 @@
+@import url("ui.core.css");
+@import url("ui.tabs.css"); \ No newline at end of file
diff --git a/bundles/XO/karma/css/ui.core.css b/bundles/XO/karma/css/ui.core.css
new file mode 100755
index 0000000..c2f18f2
--- /dev/null
+++ b/bundles/XO/karma/css/ui.core.css
@@ -0,0 +1,37 @@
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+*/
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden { display: none; }
+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }
+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }
+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
+.ui-helper-clearfix { display: inline-block; }
+/* required comment for clearfix to work in Opera \*/
+* html .ui-helper-clearfix { height:1%; }
+.ui-helper-clearfix { display:block; }
+/* end clearfix */
+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled { cursor: default !important; }
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } \ No newline at end of file
diff --git a/bundles/XO/karma/css/ui.tabs.css b/bundles/XO/karma/css/ui.tabs.css
new file mode 100755
index 0000000..3ca6b9a
--- /dev/null
+++ b/bundles/XO/karma/css/ui.tabs.css
@@ -0,0 +1,11 @@
+/* Tabs
+----------------------------------*/
+.ui-tabs { padding: .2em; zoom: 1; }
+.ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; }
+.ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; }
+.ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; }
+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }
+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; }
+.ui-tabs .ui-tabs-hide { display: none !important; }
diff --git a/bundles/XO/karma/css/ui.theme.css b/bundles/XO/karma/css/ui.theme.css
new file mode 100755
index 0000000..6e40c73
--- /dev/null
+++ b/bundles/XO/karma/css/ui.theme.css
@@ -0,0 +1,245 @@
+
+
+/*
+* jQuery UI CSS Framework
+* Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.
+* To view and modify this theme, visit http://jqueryui.com/themeroller/
+*/
+
+
+/* Component containers
+----------------------------------*/
+.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; }
+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; }
+.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(../assets/default/images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; }
+.ui-widget-content a { color: #222222/*{fcContent}*/; }
+.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(../assets/default/images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; }
+.ui-widget-header a { color: #222222/*{fcHeader}*/; }
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(../assets/default/images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; outline: none; }
+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; outline: none; }
+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(../assets/default/images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; outline: none; }
+.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; outline: none; }
+.ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(../assets/default/images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; outline: none; }
+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; outline: none; text-decoration: none; }
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(../assets/default/images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; }
+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636/*{fcHighlight}*/; }
+.ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(../assets/default/images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; }
+.ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a/*{fcError}*/; }
+.ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a/*{fcError}*/; }
+.ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }
+.ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; }
+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon { width: 16px; height: 16px; background-image: url(../assets/default/images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
+.ui-widget-content .ui-icon {background-image: url(../assets/default/images/ui-icons_222222_256x240.png)/*{iconsContent}*/; }
+.ui-widget-header .ui-icon {background-image: url(../assets/default/images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; }
+.ui-state-default .ui-icon { background-image: url(../assets/default/images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; }
+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(../assets/default/images/ui-icons_454545_256x240.png)/*{iconsHover}*/; }
+.ui-state-active .ui-icon {background-image: url(../assets/default/images/ui-icons_454545_256x240.png)/*{iconsActive}*/; }
+.ui-state-highlight .ui-icon {background-image: url(../assets/default/images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; }
+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(../assets/default/images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; }
+
+/* positioning */
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-off { background-position: -96px -144px; }
+.ui-icon-radio-on { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; }
+.ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; }
+.ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; }
+.ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; }
+.ui-corner-top { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; }
+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; }
+.ui-corner-right { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; }
+.ui-corner-left { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; }
+.ui-corner-all { -moz-border-radius: 4px/*{cornerRadius}*/; -webkit-border-radius: 4px/*{cornerRadius}*/; }
+
+/* Overlays */
+.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(../assets/default/images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; }
+.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(../assets/default/images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; } \ No newline at end of file
diff --git a/bundles/XO/karma/index.html b/bundles/XO/karma/index.html
new file mode 100755
index 0000000..8a5a2c5
--- /dev/null
+++ b/bundles/XO/karma/index.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Karma.js Learn.Teach.Everything</title>
+<meta name="keywords" content="karma javascript html5 sugar sugarlabs gsoc ole nepal"/>
+<meta charset="UTF-8"/>
+<link type="image/ico" rel="icon" href="assets/default/image/favicon.ico" />
+<link rel="stylesheet" href="css/intro.css" type="text/css"/>
+
+
+</head>
+<body>
+ <div id="header">
+ <div>
+ <div id="headerBg1">
+ <img src="assets/image/karma-logo80x94.png" alt="karma logo"/>
+ </div>
+ <div id="headerBg2">
+ <img src="assets/image/mountains.png" alt="image of mountains"/>
+ </div>
+ </div>
+ <ul>
+ <li><a href="http://karmaeducation.org">home</a></li>
+ <li><a href="http://karmaeducation.org">blog</a></li>
+ <li><a href="http://git.sugarlabs.org/projects/karma/repos/mainline">code</a></li>
+ <li><a href="http://karma.sugarlabs.org/docs/index.html">docs</a></li>
+ <li><a href="http://git.sugarlabs.org/projects/karma/repos/mainline/blobs/raw/5f93619d5dc78c6fbd9251064f95aa82a25eab70/js/karma.js">download</a></li>
+ <li><a href="http://wiki.sugarlabs.org/go/Karma">about</a></li>
+ </ul>
+ </div>
+ <div id="intro">
+ <div id="introText">
+ The <strong><a href="http://karmaeducation.org">Karma Project</a></strong>
+ aims to create high-quality open-source educational software
+ using openweb technologies. <br /><br />
+ <a href="http://git.sugarlabs.org/projects/karma/repos/mainline/blobs/raw/5f93619d5dc78c6fbd9251064f95aa82a25eab70/js/karma.js">karma.js</a> is a javascript library for manipulating <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/">HTML 5</a> and <a href="http://wiki.svg.org/">SVG</a>.
+ </div>
+ <div id="monkeyHolder">
+ <img src="assets/image/happyChimp120x125.png" alt="image of chimp"></img>
+ </div>
+ </div>
+ <div id="demos">
+ <div>Try out the demos and see the <a href="http://karmaeducation.org/2009/12/14/an-introduction-to-karma-js/">tutorials</a></div>
+ <div class="imgs">
+ <a href="examples/adding_up_to_10_svg/index.html">
+ <img src="assets/image/adding_up134x100.png" alt="adding up to 10" />
+ </a>
+ <a href="examples/quadrilaterals/index.html">
+ <img src="assets/image/quads136x100.png" alt="quadrilaterals" />
+ </a>
+ <a href="examples/Conozco-Uruguay/index.html">
+ <img src="assets/image/screenConozco136x100.png" alt="Conozco a Uruguay" />
+ </a>
+ </div>
+ <div class="imgs">
+ <a href="examples/English_Alphabet_Puzzle_Solving/index.html"><img src="assets/image/alphabet_identification136x100.png" alt="" />
+ </a>
+ <a href="examples/English_Animal_Identification/index.html"><img src="assets/image/alphabet_puzzle136x100.png" alt="" />
+ </a> <a href="examples/English_Direction_of_Arrows/index.html"><img src="assets/image/arrows136x100.png" alt="" />
+ </a>
+ </div>
+ <div class="imgs">
+ <a href="examples/English_Color_Identification/index.html"><img src="assets/image/english_colors136x100.png" alt="" />
+ </a>
+ <a href="examples/English_Matching_Words_and_Objects/index.html"><img src="assets/image/english_matching136x100.png" alt="" />
+ </a> <a href="examples/Math_Largest_Number_Identification/index.html"><img src="assets/image/largest_number136x100.png" alt="" />
+ </a>
+ </div>
+ <div class="imgs">
+ <a href="examples/Math_Money_Identification/index.html"><img src="assets/image/money_identification136x100.png" alt="" />
+ </a>
+ <a href="examples/Math_Numeric_Puzzle_Solving/index.html"><img src="assets/image/numeric_puzzle136x100.png" alt="" /></a>
+ </div>
+ </div>
+ <div id="footer">
+ Karma.js is licensed under the
+ <a href="http://www.opensource.org/licenses/mit-license.php"> MIT License</a>. Karma is a sub-project of <a href="http://sugarlabs.org">SugarLabs</a>. <br />
+ Copyright (c) 2009 Bryan Willson Berry
+ </div>
+
+
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/js/jquery-1.3.2.min.js b/bundles/XO/karma/js/jquery-1.3.2.min.js
new file mode 100755
index 0000000..b1ae21d
--- /dev/null
+++ b/bundles/XO/karma/js/jquery-1.3.2.min.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML=' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file
diff --git a/bundles/XO/karma/js/jquery.jgrowl_minimized.js b/bundles/XO/karma/js/jquery.jgrowl_minimized.js
new file mode 100755
index 0000000..09ddc88
--- /dev/null
+++ b/bundles/XO/karma/js/jquery.jgrowl_minimized.js
@@ -0,0 +1,4 @@
+
+(function($){$.jGrowl=function(m,o){if($('#jGrowl').size()==0)$('<div id="jGrowl"></div>').addClass($.jGrowl.defaults.position).appendTo('body');$('#jGrowl').jGrowl(m,o);};$.fn.jGrowl=function(m,o){if($.isFunction(this.each)){var args=arguments;return this.each(function(){var self=this;if($(this).data('jGrowl.instance')==undefined){$(this).data('jGrowl.instance',new $.fn.jGrowl());$(this).data('jGrowl.instance').startup(this);}
+if($.isFunction($(this).data('jGrowl.instance')[m])){$(this).data('jGrowl.instance')[m].apply($(this).data('jGrowl.instance'),$.makeArray(args).slice(1));}else{$(this).data('jGrowl.instance').create(m,o);}});};};$.extend($.fn.jGrowl.prototype,{defaults:{pool:0,header:'',group:'',sticky:false,position:'top-right',glue:'after',theme:'default',corners:'10px',check:250,life:3000,speed:'normal',easing:'swing',closer:true,closeTemplate:'&times;',closerTemplate:'<div>[ close all ]</div>',log:function(e,m,o){},beforeOpen:function(e,m,o){},open:function(e,m,o){},beforeClose:function(e,m,o){},close:function(e,m,o){},animateOpen:{opacity:'show'},animateClose:{opacity:'hide'}},notifications:[],element:null,interval:null,create:function(message,o){var o=$.extend({},this.defaults,o);this.notifications[this.notifications.length]={message:message,options:o};o.log.apply(this.element,[this.element,message,o]);},render:function(notification){var self=this;var message=notification.message;var o=notification.options;var notification=$('<div class="jGrowl-notification'+((o.group!=undefined&&o.group!='')?' '+o.group:'')+'"><div class="close">'+o.closeTemplate+'</div><div class="header">'+o.header+'</div><div class="message">'+message+'</div></div>').data("jGrowl",o).addClass(o.theme).children('div.close').bind("click.jGrowl",function(){$(this).parent().trigger('jGrowl.close');}).parent();(o.glue=='after')?$('div.jGrowl-notification:last',this.element).after(notification):$('div.jGrowl-notification:first',this.element).before(notification);$(notification).bind("mouseover.jGrowl",function(){$(this).data("jGrowl").pause=true;}).bind("mouseout.jGrowl",function(){$(this).data("jGrowl").pause=false;}).bind('jGrowl.beforeOpen',function(){o.beforeOpen.apply(self.element,[self.element,message,o]);}).bind('jGrowl.open',function(){o.open.apply(self.element,[self.element,message,o]);}).bind('jGrowl.beforeClose',function(){o.beforeClose.apply(self.element,[self.element,message,o]);}).bind('jGrowl.close',function(){$(this).trigger('jGrowl.beforeClose').animate(o.animateClose,o.speed,o.easing,function(){$(this).remove();o.close.apply(self.element,[self.element,message,o]);});}).trigger('jGrowl.beforeOpen').animate(o.animateOpen,o.speed,o.easing,function(){$(this).data("jGrowl").created=new Date();}).trigger('jGrowl.open');if($.fn.corner!=undefined)$(notification).corner(o.corners);if($('div.jGrowl-notification:parent',this.element).size()>1&&$('div.jGrowl-closer',this.element).size()==0&&this.defaults.closer!=false){$(this.defaults.closerTemplate).addClass('jGrowl-closer').addClass(this.defaults.theme).appendTo(this.element).animate(this.defaults.animateOpen,this.defaults.speed,this.defaults.easing).bind("click.jGrowl",function(){$(this).siblings().children('div.close').trigger("click.jGrowl");if($.isFunction(self.defaults.closer))self.defaults.closer.apply($(this).parent()[0],[$(this).parent()[0]]);});};},update:function(){$(this.element).find('div.jGrowl-notification:parent').each(function(){if($(this).data("jGrowl")!=undefined&&$(this).data("jGrowl").created!=undefined&&($(this).data("jGrowl").created.getTime()+$(this).data("jGrowl").life)<(new Date()).getTime()&&$(this).data("jGrowl").sticky!=true&&($(this).data("jGrowl").pause==undefined||$(this).data("jGrowl").pause!=true)){$(this).trigger('jGrowl.close');}});if(this.notifications.length>0&&(this.defaults.pool==0||$(this.element).find('div.jGrowl-notification:parent').size()<this.defaults.pool)){this.render(this.notifications.shift());}
+if($(this.element).find('div.jGrowl-notification:parent').size()<2){$(this.element).find('div.jGrowl-closer').animate(this.defaults.animateClose,this.defaults.speed,this.defaults.easing,function(){$(this).remove();});};},startup:function(e){this.element=$(e).addClass('jGrowl').append('<div class="jGrowl-notification"></div>');this.interval=setInterval(function(){jQuery(e).data('jGrowl.instance').update();},this.defaults.check);if($.browser.msie&&parseInt($.browser.version)<7&&!window["XMLHttpRequest"])$(this.element).addClass('ie6');},shutdown:function(){$(this.element).removeClass('jGrowl').find('div.jGrowl-notification').remove();clearInterval(this.interval);}});$.jGrowl.defaults=$.fn.jGrowl.prototype.defaults;})(jQuery); \ No newline at end of file
diff --git a/bundles/XO/karma/js/jquery.svg.js b/bundles/XO/karma/js/jquery.svg.js
new file mode 100755
index 0000000..3d13d94
--- /dev/null
+++ b/bundles/XO/karma/js/jquery.svg.js
@@ -0,0 +1,1325 @@
+/* http://keith-wood.name/svg.html
+ SVG for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+/* SVG manager.
+ Use the singleton instance of this class, $.svg,
+ to interact with the SVG functionality. */
+function SVGManager() {
+ this._settings = []; // Settings to be remembered per SVG object
+ this._extensions = []; // List of SVG extensions added to SVGWrapper
+ // for each entry [0] is extension name, [1] is extension class (function)
+ // the function takes one parameter - the SVGWrapper instance
+ this.regional = []; // Localisations, indexed by language, '' for default (English)
+ this.regional[''] = {errorLoadingText: 'Error loading',
+ notSupportedText: 'This browser does not support SVG'};
+ this.local = this.regional['']; // Current localisation
+ this._uuid = new Date().getTime();
+ this._renesis = detectActiveX('RenesisX.RenesisCtrl');
+}
+
+/* Determine whether a given ActiveX control is available.
+ @param classId (string) the ID for the ActiveX control
+ @return (boolean) true if found, false if not */
+function detectActiveX(classId) {
+ try {
+ return !!(window.ActiveXObject && new ActiveXObject(classId));
+ }
+ catch (e) {
+ return false;
+ }
+}
+
+var PROP_NAME = 'svgwrapper';
+
+$.extend(SVGManager.prototype, {
+ /* Class name added to elements to indicate already configured with SVG. */
+ markerClassName: 'hasSVG',
+
+ /* SVG namespace. */
+ svgNS: 'http://www.w3.org/2000/svg',
+ /* XLink namespace. */
+ xlinkNS: 'http://www.w3.org/1999/xlink',
+
+ /* SVG wrapper class. */
+ _wrapperClass: SVGWrapper,
+
+ /* Camel-case versions of attribute names containing dashes or are reserved words. */
+ _attrNames: {class_: 'class', in_: 'in',
+ alignmentBaseline: 'alignment-baseline', baselineShift: 'baseline-shift',
+ clipPath: 'clip-path', clipRule: 'clip-rule',
+ colorInterpolation: 'color-interpolation',
+ colorInterpolationFilters: 'color-interpolation-filters',
+ colorRendering: 'color-rendering', dominantBaseline: 'dominant-baseline',
+ enableBackground: 'enable-background', fillOpacity: 'fill-opacity',
+ fillRule: 'fill-rule', floodColor: 'flood-color',
+ floodOpacity: 'flood-opacity', fontFamily: 'font-family',
+ fontSize: 'font-size', fontSizeAdjust: 'font-size-adjust',
+ fontStretch: 'font-stretch', fontStyle: 'font-style',
+ fontVariant: 'font-variant', fontWeight: 'font-weight',
+ glyphOrientationHorizontal: 'glyph-orientation-horizontal',
+ glyphOrientationVertical: 'glyph-orientation-vertical',
+ horizAdvX: 'horiz-adv-x', horizOriginX: 'horiz-origin-x',
+ imageRendering: 'image-rendering', letterSpacing: 'letter-spacing',
+ lightingColor: 'lighting-color', markerEnd: 'marker-end',
+ markerMid: 'marker-mid', markerStart: 'marker-start',
+ stopColor: 'stop-color', stopOpacity: 'stop-opacity',
+ strikethroughPosition: 'strikethrough-position',
+ strikethroughThickness: 'strikethrough-thickness',
+ strokeDashArray: 'stroke-dasharray', strokeDashOffset: 'stroke-dashoffset',
+ strokeLineCap: 'stroke-linecap', strokeLineJoin: 'stroke-linejoin',
+ strokeMiterLimit: 'stroke-miterlimit', strokeOpacity: 'stroke-opacity',
+ strokeWidth: 'stroke-width', textAnchor: 'text-anchor',
+ textDecoration: 'text-decoration', textRendering: 'text-rendering',
+ underlinePosition: 'underline-position', underlineThickness: 'underline-thickness',
+ vertAdvY: 'vert-adv-y', vertOriginY: 'vert-origin-y',
+ wordSpacing: 'word-spacing', writingMode: 'writing-mode'},
+
+ /* Add the SVG object to its container. */
+ _attachSVG: function(container, settings) {
+ if ($(container).hasClass(this.markerClassName)) {
+ return;
+ }
+ if (typeof settings == 'string') {
+ settings = {loadURL: settings};
+ }
+ else if (typeof settings == 'function') {
+ settings = {onLoad: settings};
+ }
+ $(container).addClass(this.markerClassName);
+ try {
+ var svg = document.createElementNS(this.svgNS, 'svg');
+ svg.setAttribute('version', '1.1');
+ svg.setAttribute('width', container.clientWidth);
+ svg.setAttribute('height', container.clientHeight);
+ container.appendChild(svg);
+ this._afterLoad(container, svg, settings);
+ }
+ catch (e) {
+ if ($.browser.msie) {
+ if (!container.id) {
+ container.id = 'svg' + (this._uuid++);
+ }
+ this._settings[container.id] = settings;
+ container.innerHTML = '<embed type="image/svg+xml" width="100%" ' +
+ 'height="100%" src="' + (settings.initPath || '') + 'blank.svg"/>';
+ }
+ else {
+ container.innerHTML = '<p class="svg_error">' +
+ this.local.notSupportedText + '</p>';
+ }
+ }
+ },
+
+ /* SVG callback after loading - register SVG root. */
+ _registerSVG: function() {
+ for (var i = 0; i < document.embeds.length; i++) { // Check all
+ var container = document.embeds[i].parentNode;
+ if (!$(container).hasClass($.svg.markerClassName) || // Not SVG
+ $.data(container, PROP_NAME)) { // Already done
+ continue;
+ }
+ var svg = null;
+ try {
+ svg = document.embeds[i].getSVGDocument();
+ }
+ catch(e) {
+ setTimeout($.svg._registerSVG, 250); // Renesis takes longer to load
+ return;
+ }
+ svg = (svg ? svg.documentElement : null);
+ if (svg) {
+ $.svg._afterLoad(container, svg);
+ }
+ }
+ },
+
+ /* Post-processing once loaded. */
+ _afterLoad: function(container, svg, settings) {
+ var settings = settings || this._settings[container.id];
+ this._settings[container.id] = null;
+ var wrapper = new this._wrapperClass(svg, container);
+ $.data(container, PROP_NAME, wrapper);
+ try {
+ if (settings.loadURL) { // Load URL
+ wrapper.load(settings.loadURL, settings);
+ }
+ if (settings.settings) { // Additional settings
+ wrapper.configure(settings.settings);
+ }
+ if (settings.onLoad && !settings.loadURL) { // Onload callback
+ settings.onLoad.apply(container, [wrapper]);
+ }
+ }
+ catch (e) {
+ alert(e);
+ }
+ },
+
+ /* Return the SVG wrapper created for a given container.
+ @param container (string) selector for the container or
+ (element) the container for the SVG object or
+ jQuery collection - first entry is the container
+ @return (SVGWrapper) the corresponding SVG wrapper element, or null if not attached */
+ _getSVG: function(container) {
+ container = (typeof container == 'string' ? $(container)[0] :
+ (container.jquery ? container[0] : container));
+ return $.data(container, PROP_NAME);
+ },
+
+ /* Remove the SVG functionality from a div.
+ @param container (element) the container for the SVG object */
+ _destroySVG: function(container) {
+ var $container = $(container);
+ if (!$container.hasClass(this.markerClassName)) {
+ return;
+ }
+ $container.removeClass(this.markerClassName).empty();
+ $.removeData(container, PROP_NAME);
+ },
+
+ /* Extend the SVGWrapper object with an embedded class.
+ The constructor function must take a single parameter that is
+ a reference to the owning SVG root object. This allows the
+ extension to access the basic SVG functionality.
+ @param name (string) the name of the SVGWrapper attribute to access the new class
+ @param extClass (function) the extension class constructor */
+ addExtension: function(name, extClass) {
+ this._extensions.push([name, extClass]);
+ }
+});
+
+/* The main SVG interface, which encapsulates the SVG element.
+ Obtain a reference from $().svg('get') */
+function SVGWrapper(svg, container) {
+ this._svg = svg; // The SVG root node
+ this._container = container; // The containing div
+ for (var i = 0; i < $.svg._extensions.length; i++) {
+ var extension = $.svg._extensions[i];
+ this[extension[0]] = new extension[1](this);
+ }
+}
+
+$.extend(SVGWrapper.prototype, {
+
+ /* Retrieve the width of the SVG object. */
+ _width: function() {
+ return this._container.clientWidth;
+ },
+
+ /* Retrieve the height of the SVG object. */
+ _height: function() {
+ return this._container.clientHeight;
+ },
+
+ /* Retrieve the root SVG element.
+ @return the top-level SVG element */
+ root: function() {
+ return this._svg;
+ },
+
+ /* Configure the SVG root.
+ @param settings (object) additional settings for the root
+ @param clear (boolean) true to remove existing attributes first,
+ false to add to what is already there (optional)
+ @return (SVGWrapper) this root */
+ configure: function(settings, clear) {
+ if (clear) {
+ for (var i = this._svg.attributes.length - 1; i >= 0; i--) {
+ var attr = this._svg.attributes.item(i);
+ if (!(attr.nodeName == 'onload' || attr.nodeName == 'version' ||
+ attr.nodeName.substring(0, 5) == 'xmlns')) {
+ this._svg.attributes.removeNamedItem(attr.nodeName);
+ }
+ }
+ }
+ for (var attrName in settings) {
+ this._svg.setAttribute(attrName, settings[attrName]);
+ }
+ return this;
+ },
+
+ /* Locate a specific element in the SVG document.
+ @param id (string) the element's identifier
+ @return (element) the element reference, or null if not found */
+ getElementById: function(id) {
+ return this._svg.ownerDocument.getElementById(id);
+ },
+
+ /* Change the attributes for a SVG node.
+ @param element (SVG element) the node to change
+ @param settings (object) the new settings
+ @return (SVGWrapper) this root */
+ change: function(element, settings) {
+ if (element) {
+ for (var name in settings) {
+ if (settings[name] == null) {
+ element.removeAttribute(name);
+ }
+ else {
+ element.setAttribute(name, settings[name]);
+ }
+ }
+ }
+ return this;
+ },
+
+ /* Check for parent being absent and adjust arguments accordingly. */
+ _args: function(values, names, optSettings) {
+ names.splice(0, 0, 'parent');
+ names.splice(names.length, 0, 'settings');
+ var args = {};
+ var offset = 0;
+ if (values[0] != null && (typeof values[0] != 'object' || !values[0].nodeName)) {
+ args['parent'] = null;
+ offset = 1;
+ }
+ for (var i = 0; i < values.length; i++) {
+ args[names[i + offset]] = values[i];
+ }
+ if (optSettings) {
+ $.each(optSettings, function(i, value) {
+ if (typeof args[value] == 'object') {
+ args.settings = args[value];
+ args[value] = null;
+ }
+ });
+ }
+ return args;
+ },
+
+ /* Add a title.
+ @param parent (element) the parent node for the new title (optional)
+ @param text (string) the text of the title
+ @param settings (object) additional settings for the title (optional)
+ @return (element) the new title node */
+ title: function(parent, text, settings) {
+ var args = this._args(arguments, ['text']);
+ var node = this._makeNode(args.parent, 'title', args.settings || {});
+ node.appendChild(this._svg.ownerDocument.createTextNode(args.text));
+ return node;
+ },
+
+ /* Add a description.
+ @param parent (element) the parent node for the new description (optional)
+ @param text (string) the text of the description
+ @param settings (object) additional settings for the description (optional)
+ @return (element) the new description node */
+ describe: function(parent, text, settings) {
+ var args = this._args(arguments, ['text']);
+ var node = this._makeNode(args.parent, 'desc', args.settings || {});
+ node.appendChild(this._svg.ownerDocument.createTextNode(args.text));
+ return node;
+ },
+
+ /* Add a definitions node.
+ @param parent (element) the parent node for the new definitions (optional)
+ @param id (string) the ID of this definitions (optional)
+ @param settings (object) additional settings for the definitions (optional)
+ @return (element) the new definitions node */
+ defs: function(parent, id, settings) {
+ var args = this._args(arguments, ['id'], ['id']);
+ return this._makeNode(args.parent, 'defs', $.extend(
+ (args.id ? {id: args.id} : {}), args.settings || {}));
+ },
+
+ /* Add a symbol definition.
+ @param parent (element) the parent node for the new symbol (optional)
+ @param id (string) the ID of this symbol
+ @param x1 (number) the left coordinate for this symbol
+ @param y1 (number) the top coordinate for this symbol
+ @param x2 (number) the right coordinate for this symbol
+ @param y2 (number) the bottom coordinate for this symbol
+ @param settings (object) additional settings for the symbol (optional)
+ @return (element) the new symbol node */
+ symbol: function(parent, id, x1, y1, x2, y2, settings) {
+ var args = this._args(arguments, ['id', 'x1', 'y1', 'x2', 'y2']);
+ return this._makeNode(args.parent, 'symbol', $.extend(
+ {id: args.id, viewBox: args.x1 + ' ' + args.y1 + ' ' + args.x2 + ' ' + args.y2},
+ args.settings || {}));
+ },
+
+ /* Add a marker definition.
+ @param parent (element) the parent node for the new marker (optional)
+ @param id (string) the ID of this marker
+ @param refX (number) the x-coordinate for the reference point
+ @param refY (number) the y-coordinate for the reference point
+ @param mWidth (number) the marker viewport width
+ @param mHeight (number) the marker viewport height
+ @param orient (string or int) 'auto' or angle (degrees) (optional)
+ @param settings (object) additional settings for the marker (optional)
+ @return (element) the new marker node */
+ marker: function(parent, id, refX, refY, mWidth, mHeight, orient, settings) {
+ var args = this._args(arguments, ['id', 'refX', 'refY',
+ 'mWidth', 'mHeight', 'orient'], ['orient']);
+ return this._makeNode(args.parent, 'marker', $.extend(
+ {id: args.id, refX: args.refX, refY: args.refY, markerWidth: args.mWidth,
+ markerHeight: args.mHeight, orient: args.orient || 'auto'}, args.settings || {}));
+ },
+
+ /* Add a style node.
+ @param parent (element) the parent node for the new node (optional)
+ @param styles (string) the CSS styles
+ @param settings (object) additional settings for the node (optional)
+ @return (element) the new style node */
+ style: function(parent, styles, settings) {
+ var args = this._args(arguments, ['styles']);
+ var node = this._makeNode(args.parent, 'style', $.extend(
+ {type: 'text/css'}, args.settings || {}));
+ node.appendChild(this._svg.ownerDocument.createTextNode(args.styles));
+ if ($.browser.opera) {
+ $('head').append('<style type="text/css">' + args.styles + '</style>');
+ }
+ return node;
+ },
+
+ /* Add a script node.
+ @param parent (element) the parent node for the new node (optional)
+ @param script (string) the JavaScript code
+ @param type (string) the MIME type for the code (optional, default 'text/javascript')
+ @param settings (object) additional settings for the node (optional)
+ @return (element) the new script node */
+ script: function(parent, script, type, settings) {
+ var args = this._args(arguments, ['script', 'type'], ['type']);
+ var node = this._makeNode(args.parent, 'script', $.extend(
+ {type: args.type || 'text/javascript'}, args.settings || {}));
+ node.appendChild(this._svg.ownerDocument.createTextNode(this._escapeXML(args.script)));
+ if (!$.browser.mozilla) {
+ $.globalEval(args.script);
+ }
+ return node;
+ },
+
+ /* Add a linear gradient definition.
+ Specify all of x1, y1, x2, y2 or none of them.
+ @param parent (element) the parent node for the new gradient (optional)
+ @param id (string) the ID for this gradient
+ @param stops (string[][]) the gradient stops, each entry is
+ [0] is offset (0.0-1.0 or 0%-100%), [1] is colour,
+ [2] is opacity (optional)
+ @param x1 (number) the x-coordinate of the gradient start (optional)
+ @param y1 (number) the y-coordinate of the gradient start (optional)
+ @param x2 (number) the x-coordinate of the gradient end (optional)
+ @param y2 (number) the y-coordinate of the gradient end (optional)
+ @param settings (object) additional settings for the gradient (optional)
+ @return (element) the new gradient node */
+ linearGradient: function(parent, id, stops, x1, y1, x2, y2, settings) {
+ var args = this._args(arguments,
+ ['id', 'stops', 'x1', 'y1', 'x2', 'y2'], ['x1']);
+ var sets = $.extend({id: args.id},
+ (args.x1 != null ? {x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2} : {}));
+ return this._gradient(args.parent, 'linearGradient',
+ $.extend(sets, args.settings || {}), args.stops);
+ },
+
+ /* Add a radial gradient definition.
+ Specify all of cx, cy, r, fx, fy or none of them.
+ @param parent (element) the parent node for the new gradient (optional)
+ @param id (string) the ID for this gradient
+ @param stops (string[][]) the gradient stops, each entry
+ [0] is offset, [1] is colour, [2] is opacity (optional)
+ @param cx (number) the x-coordinate of the largest circle centre (optional)
+ @param cy (number) the y-coordinate of the largest circle centre (optional)
+ @param r (number) the radius of the largest circle (optional)
+ @param fx (number) the x-coordinate of the gradient focus (optional)
+ @param fy (number) the y-coordinate of the gradient focus (optional)
+ @param settings (object) additional settings for the gradient (optional)
+ @return (element) the new gradient node */
+ radialGradient: function(parent, id, stops, cx, cy, r, fx, fy, settings) {
+ var args = this._args(arguments,
+ ['id', 'stops', 'cx', 'cy', 'r', 'fx', 'fy'], ['cx']);
+ var sets = $.extend({id: args.id}, (args.cx != null ?
+ {cx: args.cx, cy: args.cy, r: args.r, fx: args.fx, fy: args.fy} : {}));
+ return this._gradient(args.parent, 'radialGradient',
+ $.extend(sets, args.settings || {}), args.stops);
+ },
+
+ /* Add a gradient node. */
+ _gradient: function(parent, name, settings, stops) {
+ var node = this._makeNode(parent, name, settings);
+ for (var i = 0; i < stops.length; i++) {
+ var stop = stops[i];
+ this._makeNode(node, 'stop', $.extend(
+ {offset: stop[0], stopColor: stop[1]},
+ (stop[2] != null ? {stopOpacity: stop[2]} : {})));
+ }
+ return node;
+ },
+
+ /* Add a pattern definition.
+ Specify all of vx, vy, xwidth, vheight or none of them.
+ @param parent (element) the parent node for the new pattern (optional)
+ @param id (string) the ID for this pattern
+ @param x (number) the x-coordinate for the left edge of the pattern
+ @param y (number) the y-coordinate for the top edge of the pattern
+ @param width (number) the width of the pattern
+ @param height (number) the height of the pattern
+ @param vx (number) the minimum x-coordinate for view box (optional)
+ @param vy (number) the minimum y-coordinate for the view box (optional)
+ @param vwidth (number) the width of the view box (optional)
+ @param vheight (number) the height of the view box (optional)
+ @param settings (object) additional settings for the pattern (optional)
+ @return (element) the new pattern node */
+ pattern: function(parent, id, x, y, width, height, vx, vy, vwidth, vheight, settings) {
+ var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height',
+ 'vx', 'vy', 'vwidth', 'vheight'], ['vx']);
+ var sets = $.extend({id: args.id, x: args.x, y: args.y,
+ width: args.width, height: args.height}, (args.vx != null ?
+ {viewBox: args.vx + ' ' + args.vy + ' ' + args.vwidth + ' ' + args.vheight} : {}));
+ return this._makeNode(args.parent, 'pattern', $.extend(sets, args.settings || {}));
+ },
+
+ /* Add a mask definition.
+ @param parent (element) the parent node for the new mask (optional)
+ @param id (string) the ID for this mask
+ @param x (number) the x-coordinate for the left edge of the mask
+ @param y (number) the y-coordinate for the top edge of the mask
+ @param width (number) the width of the mask
+ @param height (number) the height of the mask
+ @param settings (object) additional settings for the mask (optional)
+ @return (element) the new mask node */
+ mask: function(parent, id, x, y, width, height, settings) {
+ var args = this._args(arguments, ['id', 'x', 'y', 'width', 'height']);
+ return this._makeNode(args.parent, 'mask', $.extend(
+ {id: args.id, x: args.x, y: args.y, width: args.width, height: args.height},
+ args.settings || {}));
+ },
+
+ /* Create a new path object.
+ @return (SVGPath) a new path object */
+ createPath: function() {
+ return new SVGPath();
+ },
+
+ /* Create a new text object.
+ @return (SVGText) a new text object */
+ createText: function() {
+ return new SVGText();
+ },
+
+ /* Add an embedded SVG element.
+ Specify all of vx, vy, vwidth, vheight or none of them.
+ @param parent (element) the parent node for the new node (optional)
+ @param x (number) the x-coordinate for the left edge of the node
+ @param y (number) the y-coordinate for the top edge of the node
+ @param width (number) the width of the node
+ @param height (number) the height of the node
+ @param vx (number) the minimum x-coordinate for view box (optional)
+ @param vy (number) the minimum y-coordinate for the view box (optional)
+ @param vwidth (number) the width of the view box (optional)
+ @param vheight (number) the height of the view box (optional)
+ @param settings (object) additional settings for the node (optional)
+ @return (element) the new node */
+ svg: function(parent, x, y, width, height, vx, vy, vwidth, vheight, settings) {
+ var args = this._args(arguments, ['x', 'y', 'width', 'height',
+ 'vx', 'vy', 'vwidth', 'vheight'], ['vx']);
+ var sets = $.extend({x: args.x, y: args.y, width: args.width, height: args.height},
+ (args.vx != null ? {viewBox: args.vx + ' ' + args.vy + ' ' +
+ args.vwidth + ' ' + args.vheight} : {}));
+ return this._makeNode(args.parent, 'svg', $.extend(sets, args.settings || {}));
+ },
+
+ /* Create a group.
+ @param parent (element) the parent node for the new group (optional)
+ @param id (string) the ID of this group (optional)
+ @param settings (object) additional settings for the group (optional)
+ @return (element) the new group node */
+ group: function(parent, id, settings) {
+ var args = this._args(arguments, ['id'], ['id']);
+ return this._makeNode(args.parent, 'g', $.extend({id: args.id}, args.settings || {}));
+ },
+
+ /* Add a usage reference.
+ Specify all of x, y, width, height or none of them.
+ @param parent (element) the parent node for the new node (optional)
+ @param x (number) the x-coordinate for the left edge of the node (optional)
+ @param y (number) the y-coordinate for the top edge of the node (optional)
+ @param width (number) the width of the node (optional)
+ @param height (number) the height of the node (optional)
+ @param ref (string) the ID of the definition node
+ @param settings (object) additional settings for the node (optional)
+ @return (element) the new node */
+ use: function(parent, x, y, width, height, ref, settings) {
+ var args = this._args(arguments, ['x', 'y', 'width', 'height', 'ref']);
+ if (typeof args.x == 'string') {
+ args.ref = args.x;
+ args.settings = args.y;
+ args.x = args.y = args.width = args.height = null;
+ }
+ var node = this._makeNode(args.parent, 'use', $.extend(
+ {x: args.x, y: args.y, width: args.width, height: args.height},
+ args.settings || {}));
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+ return node;
+ },
+
+ /* Add a link, which applies to all child elements.
+ @param parent (element) the parent node for the new link (optional)
+ @param ref (string) the target URL
+ @param settings (object) additional settings for the link (optional)
+ @return (element) the new link node */
+ link: function(parent, ref, settings) {
+ var args = this._args(arguments, ['ref']);
+ var node = this._makeNode(args.parent, 'a', args.settings);
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+ return node;
+ },
+
+ /* Add an image.
+ @param parent (element) the parent node for the new image (optional)
+ @param x (number) the x-coordinate for the left edge of the image
+ @param y (number) the y-coordinate for the top edge of the image
+ @param width (number) the width of the image
+ @param height (number) the height of the image
+ @param ref (string) the path to the image
+ @param settings (object) additional settings for the image (optional)
+ @return (element) the new image node */
+ image: function(parent, x, y, width, height, ref, settings) {
+ var args = this._args(arguments, ['x', 'y', 'width', 'height', 'ref']);
+ var node = this._makeNode(args.parent, 'image', $.extend(
+ {x: args.x, y: args.y, width: args.width, height: args.height},
+ args.settings || {}));
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.ref);
+ return node;
+ },
+
+ /* Draw a path.
+ @param parent (element) the parent node for the new shape (optional)
+ @param path (string or SVGPath) the path to draw
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ path: function(parent, path, settings) {
+ var args = this._args(arguments, ['path']);
+ return this._makeNode(args.parent, 'path', $.extend(
+ {d: (args.path.path ? args.path.path() : args.path)}, args.settings || {}));
+ },
+
+ /* Draw a rectangle.
+ Specify both of rx and ry or neither.
+ @param parent (element) the parent node for the new shape (optional)
+ @param x (number) the x-coordinate for the left edge of the rectangle
+ @param y (number) the y-coordinate for the top edge of the rectangle
+ @param width (number) the width of the rectangle
+ @param height (number) the height of the rectangle
+ @param rx (number) the x-radius of the ellipse for the rounded corners (optional)
+ @param ry (number) the y-radius of the ellipse for the rounded corners (optional)
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ rect: function(parent, x, y, width, height, rx, ry, settings) {
+ var args = this._args(arguments, ['x', 'y', 'width', 'height', 'rx', 'ry'], ['rx']);
+ return this._makeNode(args.parent, 'rect', $.extend(
+ {x: args.x, y: args.y, width: args.width, height: args.height},
+ (args.rx ? {rx: args.rx, ry: args.ry} : {}), args.settings || {}));
+ },
+
+ /* Draw a circle.
+ @param parent (element) the parent node for the new shape (optional)
+ @param cx (number) the x-coordinate for the centre of the circle
+ @param cy (number) the y-coordinate for the centre of the circle
+ @param r (number) the radius of the circle
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ circle: function(parent, cx, cy, r, settings) {
+ var args = this._args(arguments, ['cx', 'cy', 'r']);
+ return this._makeNode(args.parent, 'circle', $.extend(
+ {cx: args.cx, cy: args.cy, r: args.r}, args.settings || {}));
+ },
+
+ /* Draw an ellipse.
+ @param parent (element) the parent node for the new shape (optional)
+ @param cx (number) the x-coordinate for the centre of the ellipse
+ @param cy (number) the y-coordinate for the centre of the ellipse
+ @param rx (number) the x-radius of the ellipse
+ @param ry (number) the y-radius of the ellipse
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ ellipse: function(parent, cx, cy, rx, ry, settings) {
+ var args = this._args(arguments, ['cx', 'cy', 'rx', 'ry']);
+ return this._makeNode(args.parent, 'ellipse', $.extend(
+ {cx: args.cx, cy: args.cy, rx: args.rx, ry: args.ry}, args.settings || {}));
+ },
+
+ /* Draw a line.
+ @param parent (element) the parent node for the new shape (optional)
+ @param x1 (number) the x-coordinate for the start of the line
+ @param y1 (number) the y-coordinate for the start of the line
+ @param x2 (number) the x-coordinate for the end of the line
+ @param y2 (number) the y-coordinate for the end of the line
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ line: function(parent, x1, y1, x2, y2, settings) {
+ var args = this._args(arguments, ['x1', 'y1', 'x2', 'y2']);
+ return this._makeNode(args.parent, 'line', $.extend(
+ {x1: args.x1, y1: args.y1, x2: args.x2, y2: args.y2}, args.settings || {}));
+ },
+
+ /* Draw a polygonal line.
+ @param parent (element) the parent node for the new shape (optional)
+ @param points (number[][]) the x-/y-coordinates for the points on the line
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ polyline: function(parent, points, settings) {
+ var args = this._args(arguments, ['points']);
+ return this._poly(args.parent, 'polyline', args.points, args.settings);
+ },
+
+ /* Draw a polygonal shape.
+ @param parent (element) the parent node for the new shape (optional)
+ @param points (number[][]) the x-/y-coordinates for the points on the shape
+ @param settings (object) additional settings for the shape (optional)
+ @return (element) the new shape node */
+ polygon: function(parent, points, settings) {
+ var args = this._args(arguments, ['points']);
+ return this._poly(args.parent, 'polygon', args.points, args.settings);
+ },
+
+ /* Draw a polygonal line or shape. */
+ _poly: function(parent, name, points, settings) {
+ var ps = '';
+ for (var i = 0; i < points.length; i++) {
+ ps += points[i].join() + ' ';
+ }
+ return this._makeNode(parent, name, $.extend(
+ {points: $.trim(ps)}, settings || {}));
+ },
+
+ /* Draw text.
+ Specify both of x and y or neither of them.
+ @param parent (element) the parent node for the text (optional)
+ @param x (number or number[]) the x-coordinate(s) for the text (optional)
+ @param y (number or number[]) the y-coordinate(s) for the text (optional)
+ @param value (string) the text content or
+ (SVGText) text with spans and references
+ @param settings (object) additional settings for the text (optional)
+ @return (element) the new text node */
+ text: function(parent, x, y, value, settings) {
+ var args = this._args(arguments, ['x', 'y', 'value']);
+ if (typeof args.x == 'string' && arguments.length < 4) {
+ args.value = args.x;
+ args.settings = args.y;
+ args.x = args.y = null;
+ }
+ return this._text(args.parent, 'text', args.value, $.extend(
+ {x: (args.x && isArray(args.x) ? args.x.join(' ') : args.x),
+ y: (args.y && isArray(args.y) ? args.y.join(' ') : args.y)},
+ args.settings || {}));
+ },
+
+ /* Draw text along a path.
+ @param parent (element) the parent node for the text (optional)
+ @param path (string) the ID of the path
+ @param value (string) the text content or
+ (SVGText) text with spans and references
+ @param settings (object) additional settings for the text (optional)
+ @return (element) the new text node */
+ textpath: function(parent, path, value, settings) {
+ var args = this._args(arguments, ['path', 'value']);
+ var node = this._text(args.parent, 'textPath', args.value, args.settings || {});
+ node.setAttributeNS($.svg.xlinkNS, 'href', args.path);
+ return node;
+ },
+
+ /* Draw text. */
+ _text: function(parent, name, value, settings) {
+ var node = this._makeNode(parent, name, settings);
+ if (typeof value == 'string') {
+ node.appendChild(node.ownerDocument.createTextNode(value));
+ }
+ else {
+ for (var i = 0; i < value._parts.length; i++) {
+ var part = value._parts[i];
+ if (part[0] == 'tspan') {
+ var child = this._makeNode(node, part[0], part[2]);
+ child.appendChild(node.ownerDocument.createTextNode(part[1]));
+ node.appendChild(child);
+ }
+ else if (part[0] == 'tref') {
+ var child = this._makeNode(node, part[0], part[2]);
+ child.setAttributeNS($.svg.xlinkNS, 'href', part[1]);
+ node.appendChild(child);
+ }
+ else if (part[0] == 'textpath') {
+ var set = $.extend({}, part[2]);
+ set.href = null;
+ var child = this._makeNode(node, part[0], set);
+ child.setAttributeNS($.svg.xlinkNS, 'href', part[2].href);
+ child.appendChild(node.ownerDocument.createTextNode(part[1]));
+ node.appendChild(child);
+ }
+ else { // straight text
+ node.appendChild(node.ownerDocument.createTextNode(part[1]));
+ }
+ }
+ }
+ return node;
+ },
+
+ /* Add a custom SVG element.
+ @param parent (element) the parent node for the new element (optional)
+ @param name (string) the name of the element
+ @param settings (object) additional settings for the element (optional)
+ @return (element) the new title node */
+ other: function(parent, name, settings) {
+ var args = this._args(arguments, ['name']);
+ return this._makeNode(args.parent, args.name, args.settings || {});
+ },
+
+ /* Create a shape node with the given settings. */
+ _makeNode: function(parent, name, settings) {
+ parent = parent || this._svg;
+ var node = this._svg.ownerDocument.createElementNS($.svg.svgNS, name);
+ for (var name in settings) {
+ var value = settings[name];
+ if (value != null && value != null &&
+ (typeof value != 'string' || value != '')) {
+ node.setAttribute($.svg._attrNames[name] || name, value);
+ }
+ }
+ parent.appendChild(node);
+ return node;
+ },
+
+ /* Add an existing SVG node to the diagram.
+ @param parent (element) the parent node for the new node (optional)
+ @param node (element) the new node to add or
+ (string) the jQuery selector for the node or
+ (jQuery collection) set of nodes to add
+ @return (SVGWrapper) this wrapper */
+ add: function(parent, node) {
+ var args = this._args(arguments, ['node']);
+ var svg = this;
+ args.parent = args.parent || this._svg;
+ try {
+ if ($.svg._renesis) {
+ throw 'Force traversal';
+ }
+ args.parent.appendChild(args.node.cloneNode(true));
+ }
+ catch (e) {
+ args.node = (args.node.jquery ? args.node : $(args.node));
+ args.node.each(function() {
+ var child = svg._cloneAsSVG(this);
+ if (child) {
+ args.parent.appendChild(child);
+ }
+ });
+ }
+ return this;
+ },
+
+ /* SVG nodes must belong to the SVG namespace, so clone and ensure this is so. */
+ _cloneAsSVG: function(node) {
+ var newNode = null;
+ if (node.nodeType == 1) { // element
+ newNode = this._svg.ownerDocument.createElementNS(
+ $.svg.svgNS, this._checkName(node.nodeName));
+ for (var i = 0; i < node.attributes.length; i++) {
+ var attr = node.attributes.item(i);
+ if (attr.nodeName != 'xmlns' && attr.nodeValue) {
+ if (attr.prefix == 'xlink') {
+ newNode.setAttributeNS($.svg.xlinkNS, attr.localName, attr.nodeValue);
+ }
+ else {
+ newNode.setAttribute(this._checkName(attr.nodeName), attr.nodeValue);
+ }
+ }
+ }
+ for (var i = 0; i < node.childNodes.length; i++) {
+ var child = this._cloneAsSVG(node.childNodes[i]);
+ if (child) {
+ newNode.appendChild(child);
+ }
+ }
+ }
+ else if (node.nodeType == 3) { // text
+ if ($.trim(node.nodeValue)) {
+ newNode = this._svg.ownerDocument.createTextNode(node.nodeValue);
+ }
+ }
+ else if (node.nodeType == 4) { // CDATA
+ if ($.trim(node.nodeValue)) {
+ try {
+ newNode = this._svg.ownerDocument.createCDATASection(node.nodeValue);
+ }
+ catch (e) {
+ newNode = this._svg.ownerDocument.createTextNode(
+ node.nodeValue.replace(/&/g, '&amp;').
+ replace(/</g, '&lt;').replace(/>/g, '&gt;'));
+ }
+ }
+ }
+ return newNode;
+ },
+
+ /* Node names must be lower case and without SVG namespace prefix. */
+ _checkName: function(name) {
+ name = (name.substring(0, 1) >= 'A' && name.substring(0, 1) <= 'Z' ?
+ name.toLowerCase() : name);
+ return (name.substring(0, 4) == 'svg:' ? name.substring(4) : name);
+ },
+
+ /* Load an external SVG document.
+ @param url (string) the location of the SVG document or
+ the actual SVG content
+ @param settings (boolean) see addTo below or
+ (function) see onLoad below or
+ (object) additional settings for the load with attributes below:
+ addTo (boolean) true to add to what's already there,
+ or false to clear the canvas first
+ changeSize (boolean) true to allow the canvas size to change,
+ or false to retain the original
+ onLoad (function) callback after the document has loaded,
+ 'this' is the container, receives SVG object and
+ optional error message as a parameter
+ @return (SVGWrapper) this root */
+ load: function(url, settings) {
+ settings = (typeof settings == 'boolean'? {addTo: settings} :
+ (typeof settings == 'function'? {onLoad: settings} : settings || {}));
+ if (!settings.addTo) {
+ this.clear(false);
+ }
+ var size = [this._svg.getAttribute('width'), this._svg.getAttribute('height')];
+ var wrapper = this;
+ // Report a problem with the load
+ var reportError = function(message) {
+ message = $.svg.local.errorLoadingText + ': ' + message;
+ if (settings.onLoad) {
+ settings.onLoad.apply(wrapper._container, [wrapper, message]);
+ }
+ else {
+ wrapper.text(null, 10, 20, message);
+ }
+ };
+ // Create a DOM from SVG content
+ var loadXML4IE = function(data) {
+ var xml = new ActiveXObject('Microsoft.XMLDOM');
+ xml.validateOnParse = false;
+ xml.resolveExternals = false;
+ xml.async = false;
+ xml.loadXML(data);
+ if (xml.parseError.errorCode != 0) {
+ reportError(xml.parseError.reason);
+ return null;
+ }
+ return xml;
+ };
+ // Load the SVG DOM
+ var loadSVG = function(data) {
+ if (!data) {
+ return;
+ }
+ if (data.documentElement.nodeName != 'svg') {
+ var errors = data.getElementsByTagName('parsererror');
+ var messages = (errors.length ? errors[0].getElementsByTagName('div') : []); // Safari
+ reportError(!errors.length ? '???' :
+ (messages.length ? messages[0] : errors[0]).firstChild.nodeValue);
+ return;
+ }
+ var attrs = {};
+ for (var i = 0; i < data.documentElement.attributes.length; i++) {
+ var attr = data.documentElement.attributes.item(i);
+ if (!(attr.nodeName == 'version' || attr.nodeName.substring(0, 5) == 'xmlns')) {
+ attrs[attr.nodeName] = attr.nodeValue;
+ }
+ }
+ wrapper.configure(attrs, true);
+ var nodes = data.documentElement.childNodes;
+ for (var i = 0; i < nodes.length; i++) {
+ try {
+ if ($.svg._renesis) {
+ throw 'Force traversal';
+ }
+ wrapper._svg.appendChild(nodes[i].cloneNode(true));
+ }
+ catch (e) {
+ wrapper.add(null, nodes[i]);
+ }
+ }
+ if (!settings.changeSize) {
+ wrapper.configure({width: size[0], height: size[1]});
+ }
+ if (settings.onLoad) {
+ settings.onLoad.apply(wrapper._container, [wrapper]);
+ }
+ };
+ if (url.match('<svg')) { // Inline SVG
+ loadSVG($.browser.msie ? loadXML4IE(url) :
+ new DOMParser().parseFromString(url, 'text/xml'));
+ }
+ else { // Remote SVG
+ $.ajax({url: url, dataType: ($.browser.msie ? 'text' : 'xml'),
+ success: function(xml) {
+ loadSVG($.browser.msie ? loadXML4IE(xml) : xml);
+ }, error: function(http, message, exc) {
+ reportError(message + (exc ? ' ' + exc.message : ''));
+ }});
+ }
+ return this;
+ },
+
+ /* Delete a specified node.
+ @param node (element) the drawing node to remove
+ @return (SVGWrapper) this root */
+ remove: function(node) {
+ node.parentNode.removeChild(node);
+ return this;
+ },
+
+ /* Delete everything in the current document.
+ @param attrsToo (boolean) true to clear any root attributes as well,
+ false to leave them (optional)
+ @return (SVGWrapper) this root */
+ clear: function(attrsToo) {
+ if (attrsToo) {
+ this.configure({}, true);
+ }
+ while (this._svg.firstChild) {
+ this._svg.removeChild(this._svg.firstChild);
+ }
+ return this;
+ },
+
+ /* Serialise the current diagram into an SVG text document.
+ @param node (SVG element) the starting node (optional)
+ @return (string) the SVG as text */
+ toSVG: function(node) {
+ node = node || this._svg;
+ return (typeof XMLSerializer == 'undefined' ? this._toSVG(node) :
+ new XMLSerializer().serializeToString(node));
+ },
+
+ /* Serialise one node in the SVG hierarchy. */
+ _toSVG: function(node) {
+ var svgDoc = '';
+ if (!node) {
+ return svgDoc;
+ }
+ if (node.nodeType == 3) { // Text
+ svgDoc = node.nodeValue;
+ }
+ else if (node.nodeType == 4) { // CDATA
+ svgDoc = '<![CDATA[' + node.nodeValue + ']]>';
+ }
+ else { // Element
+ svgDoc = '<' + node.nodeName;
+ if (node.attributes) {
+ for (var i = 0; i < node.attributes.length; i++) {
+ var attr = node.attributes.item(i);
+ if (!($.trim(attr.nodeValue) == '' || attr.nodeValue.match(/^\[object/) ||
+ attr.nodeValue.match(/^function/))) {
+ svgDoc += ' ' + (attr.namespaceURI == $.svg.xlinkNS ? 'xlink:' : '') +
+ attr.nodeName + '="' + attr.nodeValue + '"';
+ }
+ }
+ }
+ if (node.firstChild) {
+ svgDoc += '>';
+ var child = node.firstChild;
+ while (child) {
+ svgDoc += this._toSVG(child);
+ child = child.nextSibling;
+ }
+ svgDoc += '</' + node.nodeName + '>';
+ }
+ else {
+ svgDoc += '/>';
+ }
+ }
+ return svgDoc;
+ },
+
+ /* Escape reserved characters in XML. */
+ _escapeXML: function(text) {
+ text = text.replace(/&/g, '&amp;');
+ text = text.replace(/</g, '&lt;');
+ text = text.replace(/>/g, '&gt;');
+ return text;
+ }
+});
+
+/* Helper to generate an SVG path.
+ Obtain an instance from the SVGWrapper object.
+ String calls together to generate the path and use its value:
+ var path = root.createPath();
+ root.path(null, path.move(100, 100).line(300, 100).line(200, 300).close(), {fill: 'red'});
+ or
+ root.path(null, path.move(100, 100).line([[300, 100], [200, 300]]).close(), {fill: 'red'}); */
+function SVGPath() {
+ this._path = '';
+}
+
+$.extend(SVGPath.prototype, {
+ /* Prepare to create a new path.
+ @return (SVGPath) this path */
+ reset: function() {
+ this._path = '';
+ return this;
+ },
+
+ /* Move the pointer to a position.
+ @param x (number) x-coordinate to move to or
+ (number[][]) x-/y-coordinates to move to
+ @param y (number) y-coordinate to move to (omitted if x is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ move: function(x, y, relative) {
+ relative = (isArray(x) ? y : relative);
+ return this._coords((relative ? 'm' : 'M'), x, y);
+ },
+
+ /* Draw a line to a position.
+ @param x (number) x-coordinate to move to or
+ (number[][]) x-/y-coordinates to move to
+ @param y (number) y-coordinate to move to (omitted if x is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ line: function(x, y, relative) {
+ relative = (isArray(x) ? y : relative);
+ return this._coords((relative ? 'l' : 'L'), x, y);
+ },
+
+ /* Draw a horizontal line to a position.
+ @param x (number) x-coordinate to draw to or
+ (number[]) x-coordinates to draw to
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ horiz: function(x, relative) {
+ this._path += (relative ? 'h' : 'H') + (isArray(x) ? x.join(' ') : x);
+ return this;
+ },
+
+ /* Draw a vertical line to a position.
+ @param y (number) y-coordinate to draw to or
+ (number[]) y-coordinates to draw to
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ vert: function(y, relative) {
+ this._path += (relative ? 'v' : 'V') + (isArray(y) ? y.join(' ') : y);
+ return this;
+ },
+
+ /* Draw a cubic Bézier curve.
+ @param x1 (number) x-coordinate of beginning control point or
+ (number[][]) x-/y-coordinates of control and end points to draw to
+ @param y1 (number) y-coordinate of beginning control point (omitted if x1 is array)
+ @param x2 (number) x-coordinate of ending control point (omitted if x1 is array)
+ @param y2 (number) y-coordinate of ending control point (omitted if x1 is array)
+ @param x (number) x-coordinate of curve end (omitted if x1 is array)
+ @param y (number) y-coordinate of curve end (omitted if x1 is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ curveC: function(x1, y1, x2, y2, x, y, relative) {
+ relative = (isArray(x1) ? y1 : relative);
+ return this._coords((relative ? 'c' : 'C'), x1, y1, x2, y2, x, y);
+ },
+
+ /* Continue a cubic Bézier curve.
+ Starting control point is the reflection of the previous end control point.
+ @param x2 (number) x-coordinate of ending control point or
+ (number[][]) x-/y-coordinates of control and end points to draw to
+ @param y2 (number) y-coordinate of ending control point (omitted if x2 is array)
+ @param x (number) x-coordinate of curve end (omitted if x2 is array)
+ @param y (number) y-coordinate of curve end (omitted if x2 is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ smoothC: function(x2, y2, x, y, relative) {
+ relative = (isArray(x2) ? y2 : relative);
+ return this._coords((relative ? 's' : 'S'), x2, y2, x, y);
+ },
+
+ /* Draw a quadratic Bézier curve.
+ @param x1 (number) x-coordinate of control point or
+ (number[][]) x-/y-coordinates of control and end points to draw to
+ @param y1 (number) y-coordinate of control point (omitted if x1 is array)
+ @param x (number) x-coordinate of curve end (omitted if x1 is array)
+ @param y (number) y-coordinate of curve end (omitted if x1 is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ curveQ: function(x1, y1, x, y, relative) {
+ relative = (isArray(x1) ? y1 : relative);
+ return this._coords((relative ? 'q' : 'Q'), x1, y1, x, y);
+ },
+
+ /* Continue a quadratic Bézier curve.
+ Control point is the reflection of the previous control point.
+ @param x (number) x-coordinate of curve end or
+ (number[][]) x-/y-coordinates of points to draw to
+ @param y (number) y-coordinate of curve end (omitted if x is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ smoothQ: function(x, y, relative) {
+ relative = (isArray(x) ? y : relative);
+ return this._coords((relative ? 't' : 'T'), x, y);
+ },
+
+ /* Generate a path command with (a list of) coordinates. */
+ _coords: function(cmd, x1, y1, x2, y2, x3, y3) {
+ if (isArray(x1)) {
+ for (var i = 0; i < x1.length; i++) {
+ var cs = x1[i];
+ this._path += (i == 0 ? cmd : ' ') + cs[0] + ',' + cs[1] +
+ (cs.length < 4 ? '' : ' ' + cs[2] + ',' + cs[3] +
+ (cs.length < 6 ? '': ' ' + cs[4] + ',' + cs[5]));
+ }
+ }
+ else {
+ this._path += cmd + x1 + ',' + y1 +
+ (x2 == null ? '' : ' ' + x2 + ',' + y2 +
+ (x3 == null ? '' : ' ' + x3 + ',' + y3));
+ }
+ return this;
+ },
+
+ /* Draw an arc to a position.
+ @param rx (number) x-radius of arc or
+ (number/boolean[][]) x-/y-coordinates and flags for points to draw to
+ @param ry (number) y-radius of arc (omitted if rx is array)
+ @param xRotate (number) x-axis rotation (degrees, clockwise) (omitted if rx is array)
+ @param large (boolean) true to draw the large part of the arc,
+ false to draw the small part (omitted if rx is array)
+ @param clockwise (boolean) true to draw the clockwise arc,
+ false to draw the anti-clockwise arc (omitted if rx is array)
+ @param x (number) x-coordinate of arc end (omitted if rx is array)
+ @param y (number) y-coordinate of arc end (omitted if rx is array)
+ @param relative (boolean) true for coordinates relative to the current point,
+ false for coordinates being absolute
+ @return (SVGPath) this path */
+ arc: function(rx, ry, xRotate, large, clockwise, x, y, relative) {
+ relative = (isArray(rx) ? ry : relative);
+ this._path += (relative ? 'a' : 'A');
+ if (isArray(rx)) {
+ for (var i = 0; i < rx.length; i++) {
+ var cs = rx[i];
+ this._path += (i == 0 ? '' : ' ') + cs[0] + ',' + cs[1] + ' ' +
+ cs[2] + ' ' + (cs[3] ? '1' : '0') + ',' +
+ (cs[4] ? '1' : '0') + ' ' + cs[5] + ',' + cs[6];
+ }
+ }
+ else {
+ this._path += rx + ',' + ry + ' ' + xRotate + ' ' +
+ (large ? '1' : '0') + ',' + (clockwise ? '1' : '0') + ' ' + x + ',' + y;
+ }
+ return this;
+ },
+
+ /* Close the current path.
+ @return (SVGPath) this path */
+ close: function() {
+ this._path += 'z';
+ return this;
+ },
+
+ /* Return the string rendering of the specified path.
+ @return (string) stringified path */
+ path: function() {
+ return this._path;
+ }
+});
+
+SVGPath.prototype.moveTo = SVGPath.prototype.move;
+SVGPath.prototype.lineTo = SVGPath.prototype.line;
+SVGPath.prototype.horizTo = SVGPath.prototype.horiz;
+SVGPath.prototype.vertTo = SVGPath.prototype.vert;
+SVGPath.prototype.curveCTo = SVGPath.prototype.curveC;
+SVGPath.prototype.smoothCTo = SVGPath.prototype.smoothC;
+SVGPath.prototype.curveQTo = SVGPath.prototype.curveQ;
+SVGPath.prototype.smoothQTo = SVGPath.prototype.smoothQ;
+SVGPath.prototype.arcTo = SVGPath.prototype.arc;
+
+/* Helper to generate an SVG text object.
+ Obtain an instance from the SVGWrapper object.
+ String calls together to generate the text and use its value:
+ var text = root.createText();
+ root.text(null, x, y, text.string('This is ').
+ span('red', {fill: 'red'}).string('!'), {fill: 'blue'}); */
+function SVGText() {
+ this._parts = []; // The components of the text object
+}
+
+$.extend(SVGText.prototype, {
+ /* Prepare to create a new text object.
+ @return (SVGText) this text */
+ reset: function() {
+ this._parts = [];
+ return this;
+ },
+
+ /* Add a straight string value.
+ @param value (string) the actual text
+ @return (SVGText) this text object */
+ string: function(value) {
+ this._parts[this._parts.length] = ['text', value];
+ return this;
+ },
+
+ /* Add a separate text span that has its own settings.
+ @param value (string) the actual text
+ @param settings (object) the settings for this text
+ @return (SVGText) this text object */
+ span: function(value, settings) {
+ this._parts[this._parts.length] = ['tspan', value, settings];
+ return this;
+ },
+
+ /* Add a reference to a previously defined text string.
+ @param id (string) the ID of the actual text
+ @param settings (object) the settings for this text
+ @return (SVGText) this text object */
+ ref: function(id, settings) {
+ this._parts[this._parts.length] = ['tref', id, settings];
+ return this;
+ },
+
+ /* Add text drawn along a path.
+ @param id (string) the ID of the path
+ @param value (string) the actual text
+ @param settings (object) the settings for this text
+ @return (SVGText) this text object */
+ path: function(id, value, settings) {
+ this._parts[this._parts.length] = ['textpath', value,
+ $.extend({href: id}, settings || {})];
+ return this;
+ }
+});
+
+/* Attach the SVG functionality to a jQuery selection.
+ @param command (string) the command to run (optional, default 'attach')
+ @param options (object) the new settings to use for these SVG instances
+ @return jQuery (object) for chaining further calls */
+$.fn.svg = function(options) {
+ var otherArgs = Array.prototype.slice.call(arguments, 1);
+ if (typeof options == 'string' && options == 'get') {
+ return $.svg['_' + options + 'SVG'].apply($.svg, [this[0]].concat(otherArgs));
+ }
+ return this.each(function() {
+ if (typeof options == 'string') {
+ $.svg['_' + options + 'SVG'].apply($.svg, [this].concat(otherArgs));
+ }
+ else {
+ $.svg._attachSVG(this, options || {});
+ }
+ });
+};
+
+/* Determine whether an object is an array. */
+function isArray(a) {
+ return (a && a.constructor == Array);
+}
+
+// Singleton primary SVG interface
+$.svg = new SVGManager();
+
+})(jQuery);
diff --git a/bundles/XO/karma/js/jquery.svg.pack.js b/bundles/XO/karma/js/jquery.svg.pack.js
new file mode 100755
index 0000000..4727218
--- /dev/null
+++ b/bundles/XO/karma/js/jquery.svg.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+ SVG for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(9($){9 2f(){7.1U=[];7.1V=[];7.2g=[];7.2g[\'\']={2Q:\'4d 4e\',2R:\'4f 1s 4g 4h 4i 2h\'};7.2i=7.2g[\'\'];7.2S=1d 4j().4k();7.2j=2T(\'4l.4m\')}9 2T(a){1t{u!!(4n.2k&&1d 2k(a))}1u(e){u 1H}}8 p=\'4o\';$.G(2f.R,{1C:\'4p\',1W:\'2U://2V.2W.2X/4q/B\',1h:\'2U://2V.2W.2X/4r/2l\',2Y:2m,2Z:{4s:\'30\',4t:\'1X\',4u:\'4v-2n\',4w:\'2n-4x\',4y:\'31-19\',4z:\'31-32\',4A:\'1D-33\',4B:\'1D-33-4C\',4D:\'1D-2o\',4E:\'4F-2n\',4G:\'4H-4I\',4J:\'34-1Y\',4K:\'34-32\',4L:\'35-1D\',4M:\'35-1Y\',4N:\'1v-4O\',4P:\'1v-36\',4Q:\'1v-36-4R\',4S:\'1v-4T\',4U:\'1v-1I\',4V:\'1v-4W\',4X:\'1v-4Y\',4Z:\'37-38-50\',51:\'37-38-52\',53:\'1Z-39-x\',54:\'1Z-3a-x\',55:\'21-2o\',56:\'57-3b\',58:\'59-1D\',5a:\'1J-5b\',5c:\'1J-5d\',5e:\'1J-5f\',3c:\'2p-1D\',3d:\'2p-1Y\',5g:\'3e-3f\',5h:\'3e-3g\',5i:\'1w-5j\',5k:\'1w-5l\',5m:\'1w-5n\',5o:\'1w-5p\',5q:\'1w-5r\',5s:\'1w-1Y\',5t:\'1w-P\',5u:\'13-5v\',5w:\'13-5x\',5y:\'13-2o\',5z:\'3h-3f\',5A:\'3h-3g\',5B:\'22-39-y\',5C:\'22-3a-y\',5D:\'5E-3b\',5F:\'5G-5H\'},3i:9(a,b){w($(a).2q(7.1C)){u}w(16 b==\'1i\'){b={23:b}}Y w(16 b==\'9\'){b={1l:b}}$(a).5I(7.1C);1t{8 c=24.2r(7.1W,\'B\');c.1x(\'2s\',\'1.1\');c.1x(\'P\',a.3j);c.1x(\'U\',a.3k);a.11(c);7.2t(a,c,b)}1u(e){w($.1s.25){w(!a.D){a.D=\'B\'+(7.2S++)}7.1U[a.D]=b;a.3l=\'<5J 1y="21/B+2u" P="3m%" \'+\'U="3m%" 5K="\'+(b.5L||\'\')+\'5M.B"/>\'}Y{a.3l=\'<p 30="5N">\'+7.2i.2R+\'</p>\'}}},3n:9(){12(8 i=0;i<24.2v.N;i++){8 a=24.2v[i].3o;w(!$(a).2q($.B.1C)||$.2w(a,p)){5O}8 b=W;1t{b=24.2v[i].5P()}1u(e){5Q($.B.3n,5R);u}b=(b?b.1K:W);w(b){$.B.2t(a,b)}}},2t:9(a,b,c){8 c=c||7.1U[a.D];7.1U[a.D]=W;8 d=1d 7.2Y(b,a);$.2w(a,p,d);1t{w(c.23){d.3p(c.23,c)}w(c.E){d.1L(c.E)}w(c.1l&&!c.23){c.1l.1M(a,[d])}}1u(e){5S(e)}},5T:9(a){a=(16 a==\'1i\'?$(a)[0]:(a.3q?a[0]:a));u $.2w(a,p)},5U:9(a){8 b=$(a);w(!b.2q(7.1C)){u}b.5V(7.1C).5W();$.5X(a,p)},5Y:9(a,b){7.1V.5Z([a,b])}});9 2m(a,b){7.O=a;7.1N=b;12(8 i=0;i<$.B.1V.N;i++){8 c=$.B.1V[i];7[c[0]]=1d c[1](7)}}$.G(2m.R,{60:9(){u 7.1N.3j},61:9(){u 7.1N.3k},62:9(){u 7.O},1L:9(a,b){w(b){12(8 i=7.O.1e.N-1;i>=0;i--){8 c=7.O.1e.26(i);w(!(c.15==\'63\'||c.15==\'2s\'||c.15.1E(0,5)==\'2x\')){7.O.1e.64(c.15)}}}12(8 d 1X a){7.O.1x(d,a[d])}u 7},3r:9(a){u 7.O.17.3r(a)},65:9(a,b){w(a){12(8 c 1X b){w(b[c]==W){a.66(c)}Y{a.1x(c,b[c])}}}u 7},J:9(b,c,d){c.3s(0,0,\'F\');c.3s(c.N,0,\'E\');8 e={};8 f=0;w(b[0]!=W&&(16 b[0]!=\'2y\'||!b[0].15)){e[\'F\']=W;f=1}12(8 i=0;i<b.N;i++){e[c[i+f]]=b[i]}w(d){$.2z(d,9(i,a){w(16 e[a]==\'2y\'){e.E=e[a];e[a]=W}})}u e},3t:9(a,b,c){8 d=7.J(I,[\'13\']);8 e=7.K(d.F,\'3t\',d.E||{});e.11(7.O.17.1f(d.13));u e},67:9(a,b,c){8 d=7.J(I,[\'13\']);8 e=7.K(d.F,\'68\',d.E||{});e.11(7.O.17.1f(d.13));u e},3u:9(a,b,c){8 d=7.J(I,[\'D\'],[\'D\']);u 7.K(d.F,\'3u\',$.G((d.D?{D:d.D}:{}),d.E||{}))},3v:9(a,b,c,d,e,f,g){8 h=7.J(I,[\'D\',\'1g\',\'1m\',\'1n\',\'1o\']);u 7.K(h.F,\'3v\',$.G({D:h.D,2A:h.1g+\' \'+h.1m+\' \'+h.1n+\' \'+h.1o},h.E||{}))},1J:9(a,b,c,d,e,f,g,h){8 i=7.J(I,[\'D\',\'2B\',\'2C\',\'3w\',\'3x\',\'27\'],[\'27\']);u 7.K(i.F,\'1J\',$.G({D:i.D,2B:i.2B,2C:i.2C,69:i.3w,6a:i.3x,27:i.27||\'6b\'},i.E||{}))},1I:9(a,b,c){8 d=7.J(I,[\'2D\']);8 e=7.K(d.F,\'1I\',$.G({1y:\'13/3y\'},d.E||{}));e.11(7.O.17.1f(d.2D));w($.1s.6c){$(\'6d\').6e(\'<1I 1y="13/3y">\'+d.2D+\'</1I>\')}u e},1O:9(a,b,c,d){8 e=7.J(I,[\'1O\',\'1y\'],[\'1y\']);8 f=7.K(e.F,\'1O\',$.G({1y:e.1y||\'13/6f\'},e.E||{}));f.11(7.O.17.1f(7.3z(e.1O)));w(!$.1s.6g){$.6h(e.1O)}u f},3A:9(a,b,c,d,e,f,g,h){8 i=7.J(I,[\'D\',\'28\',\'1g\',\'1m\',\'1n\',\'1o\'],[\'1g\']);8 j=$.G({D:i.D},(i.1g!=W?{1g:i.1g,1m:i.1m,1n:i.1n,1o:i.1o}:{}));u 7.2E(i.F,\'3A\',$.G(j,i.E||{}),i.28)},3B:9(a,b,c,d,e,r,f,g,h){8 i=7.J(I,[\'D\',\'28\',\'1b\',\'1j\',\'r\',\'2F\',\'2G\'],[\'1b\']);8 j=$.G({D:i.D},(i.1b!=W?{1b:i.1b,1j:i.1j,r:i.r,2F:i.2F,2G:i.2G}:{}));u 7.2E(i.F,\'3B\',$.G(j,i.E||{}),i.28)},2E:9(a,b,c,d){8 e=7.K(a,b,c);12(8 i=0;i<d.N;i++){8 f=d[i];7.K(e,\'2p\',$.G({6i:f[0],3c:f[1]},(f[2]!=W?{3d:f[2]}:{})))}u e},3C:9(a,b,x,y,c,d,e,f,g,h,i){8 j=7.J(I,[\'D\',\'x\',\'y\',\'P\',\'U\',\'1p\',\'29\',\'2a\',\'2b\'],[\'1p\']);8 k=$.G({D:j.D,x:j.x,y:j.y,P:j.P,U:j.U},(j.1p!=W?{2A:j.1p+\' \'+j.29+\' \'+j.2a+\' \'+j.2b}:{}));u 7.K(j.F,\'3C\',$.G(k,j.E||{}))},3D:9(a,b,x,y,c,d,e){8 f=7.J(I,[\'D\',\'x\',\'y\',\'P\',\'U\']);u 7.K(f.F,\'3D\',$.G({D:f.D,x:f.x,y:f.y,P:f.P,U:f.U},f.E||{}))},6j:9(){u 1d X()},6k:9(){u 1d 2H()},B:9(a,x,y,b,c,d,e,f,g,h){8 i=7.J(I,[\'x\',\'y\',\'P\',\'U\',\'1p\',\'29\',\'2a\',\'2b\'],[\'1p\']);8 j=$.G({x:i.x,y:i.y,P:i.P,U:i.U},(i.1p!=W?{2A:i.1p+\' \'+i.29+\' \'+i.2a+\' \'+i.2b}:{}));u 7.K(i.F,\'B\',$.G(j,i.E||{}))},6l:9(a,b,c){8 d=7.J(I,[\'D\'],[\'D\']);u 7.K(d.F,\'g\',$.G({D:d.D},d.E||{}))},3E:9(a,x,y,b,c,d,e){8 f=7.J(I,[\'x\',\'y\',\'P\',\'U\',\'1q\']);w(16 f.x==\'1i\'){f.1q=f.x;f.E=f.y;f.x=f.y=f.P=f.U=W}8 g=7.K(f.F,\'3E\',$.G({x:f.x,y:f.y,P:f.P,U:f.U},f.E||{}));g.1z($.B.1h,\'1k\',f.1q);u g},6m:9(a,b,c){8 d=7.J(I,[\'1q\']);8 e=7.K(d.F,\'a\',d.E);e.1z($.B.1h,\'1k\',d.1q);u e},21:9(a,x,y,b,c,d,e){8 f=7.J(I,[\'x\',\'y\',\'P\',\'U\',\'1q\']);8 g=7.K(f.F,\'21\',$.G({x:f.x,y:f.y,P:f.P,U:f.U},f.E||{}));g.1z($.B.1h,\'1k\',f.1q);u g},19:9(a,b,c){8 d=7.J(I,[\'19\']);u 7.K(d.F,\'19\',$.G({d:(d.19.19?d.19.19():d.19)},d.E||{}))},3F:9(a,x,y,b,c,d,e,f){8 g=7.J(I,[\'x\',\'y\',\'P\',\'U\',\'1r\',\'1F\'],[\'1r\']);u 7.K(g.F,\'3F\',$.G({x:g.x,y:g.y,P:g.P,U:g.U},(g.1r?{1r:g.1r,1F:g.1F}:{}),g.E||{}))},3G:9(a,b,c,r,d){8 e=7.J(I,[\'1b\',\'1j\',\'r\']);u 7.K(e.F,\'3G\',$.G({1b:e.1b,1j:e.1j,r:e.r},e.E||{}))},3H:9(a,b,c,d,e,f){8 g=7.J(I,[\'1b\',\'1j\',\'1r\',\'1F\']);u 7.K(g.F,\'3H\',$.G({1b:g.1b,1j:g.1j,1r:g.1r,1F:g.1F},g.E||{}))},2c:9(a,b,c,d,e,f){8 g=7.J(I,[\'1g\',\'1m\',\'1n\',\'1o\']);u 7.K(g.F,\'2c\',$.G({1g:g.1g,1m:g.1m,1n:g.1n,1o:g.1o},g.E||{}))},3I:9(a,b,c){8 d=7.J(I,[\'1P\']);u 7.2I(d.F,\'3I\',d.1P,d.E)},3J:9(a,b,c){8 d=7.J(I,[\'1P\']);u 7.2I(d.F,\'3J\',d.1P,d.E)},2I:9(a,b,c,d){8 e=\'\';12(8 i=0;i<c.N;i++){e+=c[i].1Q()+\' \'}u 7.K(a,b,$.G({1P:$.2d(e)},d||{}))},13:9(a,x,y,b,c){8 d=7.J(I,[\'x\',\'y\',\'1R\']);w(16 d.x==\'1i\'&&I.N<4){d.1R=d.x;d.E=d.y;d.x=d.y=W}u 7.2J(d.F,\'13\',d.1R,$.G({x:(d.x&&18(d.x)?d.x.1Q(\' \'):d.x),y:(d.y&&18(d.y)?d.y.1Q(\' \'):d.y)},d.E||{}))},2K:9(a,b,c,d){8 e=7.J(I,[\'19\',\'1R\']);8 f=7.2J(e.F,\'6n\',e.1R,e.E||{});f.1z($.B.1h,\'1k\',e.19);u f},2J:9(a,b,c,d){8 e=7.K(a,b,d);w(16 c==\'1i\'){e.11(e.17.1f(c))}Y{12(8 i=0;i<c.1a.N;i++){8 f=c.1a[i];w(f[0]==\'3K\'){8 g=7.K(e,f[0],f[2]);g.11(e.17.1f(f[1]));e.11(g)}Y w(f[0]==\'3L\'){8 g=7.K(e,f[0],f[2]);g.1z($.B.1h,\'1k\',f[1]);e.11(g)}Y w(f[0]==\'2K\'){8 h=$.G({},f[2]);h.1k=W;8 g=7.K(e,f[0],h);g.1z($.B.1h,\'1k\',f[2].1k);g.11(e.17.1f(f[1]));e.11(g)}Y{e.11(e.17.1f(f[1]))}}}u e},6o:9(a,b,c){8 d=7.J(I,[\'3M\']);u 7.K(d.F,d.3M,d.E||{})},K:9(a,b,c){a=a||7.O;8 d=7.O.17.2r($.B.1W,b);12(8 b 1X c){8 e=c[b];w(e!=W&&e!=W&&(16 e!=\'1i\'||e!=\'\')){d.1x($.B.2Z[b]||b,e)}}a.11(d);u d},3N:9(b,c){8 d=7.J(I,[\'1A\']);8 f=7;d.F=d.F||7.O;1t{w($.B.2j){3O\'3P 3Q\';}d.F.11(d.1A.3R(2e))}1u(e){d.1A=(d.1A.3q?d.1A:$(d.1A));d.1A.2z(9(){8 a=f.2L(7);w(a){d.F.11(a)}})}u 7},2L:9(a){8 b=W;w(a.1S==1){b=7.O.17.2r($.B.1W,7.2M(a.15));12(8 i=0;i<a.1e.N;i++){8 c=a.1e.26(i);w(c.15!=\'2x\'&&c.14){w(c.6p==\'2l\'){b.1z($.B.1h,c.6q,c.14)}Y{b.1x(7.2M(c.15),c.14)}}}12(8 i=0;i<a.2N.N;i++){8 d=7.2L(a.2N[i]);w(d){b.11(d)}}}Y w(a.1S==3){w($.2d(a.14)){b=7.O.17.1f(a.14)}}Y w(a.1S==4){w($.2d(a.14)){1t{b=7.O.17.6r(a.14)}1u(e){b=7.O.17.1f(a.14.1G(/&/g,\'&3S;\').1G(/</g,\'&3T;\').1G(/>/g,\'&3U;\'))}}}u b},2M:9(a){a=(a.1E(0,1)>=\'A\'&&a.1E(0,1)<=\'Z\'?a.6s():a);u(a.1E(0,4)==\'B:\'?a.1E(4):a)},3p:9(h,j){j=(16 j==\'6t\'?{3V:j}:(16 j==\'9\'?{1l:j}:j||{}));w(!j.3V){7.3W(1H)}8 k=[7.O.3X(\'P\'),7.O.3X(\'U\')];8 l=7;8 m=9(a){a=$.B.2i.2Q+\': \'+a;w(j.1l){j.1l.1M(l.1N,[l,a])}Y{l.13(W,10,20,a)}};8 n=9(a){8 b=1d 2k(\'6u.6v\');b.6w=1H;b.6x=1H;b.6y=1H;b.6z(a);w(b.3Y.6A!=0){m(b.3Y.6B);u W}u b};8 o=9(a){w(!a){u}w(a.1K.15!=\'B\'){8 b=a.3Z(\'6C\');8 c=(b.N?b[0].3Z(\'6D\'):[]);m(!b.N?\'???\':(c.N?c[0]:b[0]).1T.14);u}8 d={};12(8 i=0;i<a.1K.1e.N;i++){8 f=a.1K.1e.26(i);w(!(f.15==\'2s\'||f.15.1E(0,5)==\'2x\')){d[f.15]=f.14}}l.1L(d,2e);8 g=a.1K.2N;12(8 i=0;i<g.N;i++){1t{w($.B.2j){3O\'3P 3Q\';}l.O.11(g[i].3R(2e))}1u(e){l.3N(W,g[i])}}w(!j.6E){l.1L({P:k[0],U:k[1]})}w(j.1l){j.1l.1M(l.1N,[l])}};w(h.2O(\'<B\')){o($.1s.25?n(h):1d 6F().6G(h,\'13/2u\'))}Y{$.6H({6I:h,6J:($.1s.25?\'13\':\'2u\'),6K:9(a){o($.1s.25?n(a):a)},6L:9(a,b,c){m(b+(c?\' \'+c.6M:\'\'))}})}u 7},6N:9(a){a.3o.40(a);u 7},3W:9(a){w(a){7.1L({},2e)}41(7.O.1T){7.O.40(7.O.1T)}u 7},6O:9(a){a=a||7.O;u(16 42==\'6P\'?7.2P(a):1d 42().6Q(a))},2P:9(a){8 b=\'\';w(!a){u b}w(a.1S==3){b=a.14}Y w(a.1S==4){b=\'<![6R[\'+a.14+\']]>\'}Y{b=\'<\'+a.15;w(a.1e){12(8 i=0;i<a.1e.N;i++){8 c=a.1e.26(i);w(!($.2d(c.14)==\'\'||c.14.2O(/^\\[2y/)||c.14.2O(/^9/))){b+=\' \'+(c.6S==$.B.1h?\'2l:\':\'\')+c.15+\'="\'+c.14+\'"\'}}}w(a.1T){b+=\'>\';8 d=a.1T;41(d){b+=7.2P(d);d=d.6T}b+=\'</\'+a.15+\'>\'}Y{b+=\'/>\'}}u b},3z:9(a){a=a.1G(/&/g,\'&3S;\');a=a.1G(/</g,\'&3T;\');a=a.1G(/>/g,\'&3U;\');u a}});9 X(){7.1c=\'\'}$.G(X.R,{43:9(){7.1c=\'\';u 7},44:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'m\':\'M\'),x,y)},2c:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'l\':\'L\'),x,y)},1Z:9(x,a){7.1c+=(a?\'h\':\'H\')+(18(x)?x.1Q(\' \'):x);u 7},22:9(y,a){7.1c+=(a?\'v\':\'V\')+(18(y)?y.1Q(\' \'):y);u 7},45:9(a,b,c,d,x,y,e){e=(18(a)?b:e);u 7.1B((e?\'c\':\'C\'),a,b,c,d,x,y)},46:9(a,b,x,y,c){c=(18(a)?b:c);u 7.1B((c?\'s\':\'S\'),a,b,x,y)},47:9(a,b,x,y,c){c=(18(a)?b:c);u 7.1B((c?\'q\':\'Q\'),a,b,x,y)},48:9(x,y,a){a=(18(x)?y:a);u 7.1B((a?\'t\':\'T\'),x,y)},1B:9(a,b,c,d,e,f,g){w(18(b)){12(8 i=0;i<b.N;i++){8 h=b[i];7.1c+=(i==0?a:\' \')+h[0]+\',\'+h[1]+(h.N<4?\'\':\' \'+h[2]+\',\'+h[3]+(h.N<6?\'\':\' \'+h[4]+\',\'+h[5]))}}Y{7.1c+=a+b+\',\'+c+(d==W?\'\':\' \'+d+\',\'+e+(f==W?\'\':\' \'+f+\',\'+g))}u 7},49:9(a,b,c,d,e,x,y,f){f=(18(a)?b:f);7.1c+=(f?\'a\':\'A\');w(18(a)){12(8 i=0;i<a.N;i++){8 g=a[i];7.1c+=(i==0?\'\':\' \')+g[0]+\',\'+g[1]+\' \'+g[2]+\' \'+(g[3]?\'1\':\'0\')+\',\'+(g[4]?\'1\':\'0\')+\' \'+g[5]+\',\'+g[6]}}Y{7.1c+=a+\',\'+b+\' \'+c+\' \'+(d?\'1\':\'0\')+\',\'+(e?\'1\':\'0\')+\' \'+x+\',\'+y}u 7},6U:9(){7.1c+=\'z\';u 7},19:9(){u 7.1c}});X.R.6V=X.R.44;X.R.6W=X.R.2c;X.R.6X=X.R.1Z;X.R.6Y=X.R.22;X.R.6Z=X.R.45;X.R.70=X.R.46;X.R.71=X.R.47;X.R.72=X.R.48;X.R.73=X.R.49;9 2H(){7.1a=[]}$.G(2H.R,{43:9(){7.1a=[];u 7},1i:9(a){7.1a[7.1a.N]=[\'13\',a];u 7},74:9(a,b){7.1a[7.1a.N]=[\'3K\',a,b];u 7},1q:9(a,b){7.1a[7.1a.N]=[\'3L\',a,b];u 7},19:9(a,b,c){7.1a[7.1a.N]=[\'2K\',b,$.G({1k:a},c||{})];u 7}});$.75.B=9(a){8 b=4a.R.76.77(I,1);w(16 a==\'1i\'&&a==\'78\'){u $.B[\'4b\'+a+\'2h\'].1M($.B,[7[0]].4c(b))}u 7.2z(9(){w(16 a==\'1i\'){$.B[\'4b\'+a+\'2h\'].1M($.B,[7].4c(b))}Y{$.B.3i(7,a||{})}})};9 18(a){u(a&&a.79==4a)}$.B=1d 2f()})(7a);',62,445,'|||||||this|var|function|||||||||||||||||||||return||if|||||svg||id|settings|parent|extend||arguments|_args|_makeNode|||length|_svg|width||prototype|||height||null|SVGPath|else|||appendChild|for|text|nodeValue|nodeName|typeof|ownerDocument|isArray|path|_parts|cx|_path|new|attributes|createTextNode|x1|xlinkNS|string|cy|href|onLoad|y1|x2|y2|vx|ref|rx|browser|try|catch|font|stroke|setAttribute|type|setAttributeNS|node|_coords|markerClassName|color|substring|ry|replace|false|style|marker|documentElement|configure|apply|_container|script|points|join|value|nodeType|firstChild|_settings|_extensions|svgNS|in|opacity|horiz||image|vert|loadURL|document|msie|item|orient|stops|vy|vwidth|vheight|line|trim|true|SVGManager|regional|SVG|local|_renesis|ActiveXObject|xlink|SVGWrapper|baseline|rendering|stop|hasClass|createElementNS|version|_afterLoad|xml|embeds|data|xmlns|object|each|viewBox|refX|refY|styles|_gradient|fx|fy|SVGText|_poly|_text|textpath|_cloneAsSVG|_checkName|childNodes|match|_toSVG|errorLoadingText|notSupportedText|_uuid|detectActiveX|http|www|w3|org|_wrapperClass|_attrNames|class|clip|rule|interpolation|fill|flood|size|glyph|orientation|adv|origin|spacing|stopColor|stopOpacity|strikethrough|position|thickness|underline|_attachSVG|clientWidth|clientHeight|innerHTML|100|_registerSVG|parentNode|load|jquery|getElementById|splice|title|defs|symbol|mWidth|mHeight|css|_escapeXML|linearGradient|radialGradient|pattern|mask|use|rect|circle|ellipse|polyline|polygon|tspan|tref|name|add|throw|Force|traversal|cloneNode|amp|lt|gt|addTo|clear|getAttribute|parseError|getElementsByTagName|removeChild|while|XMLSerializer|reset|move|curveC|smoothC|curveQ|smoothQ|arc|Array|_|concat|Error|loading|This|does|not|support|Date|getTime|RenesisX|RenesisCtrl|window|svgwrapper|hasSVG|2000|1999|class_|in_|alignmentBaseline|alignment|baselineShift|shift|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|filters|colorRendering|dominantBaseline|dominant|enableBackground|enable|background|fillOpacity|fillRule|floodColor|floodOpacity|fontFamily|family|fontSize|fontSizeAdjust|adjust|fontStretch|stretch|fontStyle|fontVariant|variant|fontWeight|weight|glyphOrientationHorizontal|horizontal|glyphOrientationVertical|vertical|horizAdvX|horizOriginX|imageRendering|letterSpacing|letter|lightingColor|lighting|markerEnd|end|markerMid|mid|markerStart|start|strikethroughPosition|strikethroughThickness|strokeDashArray|dasharray|strokeDashOffset|dashoffset|strokeLineCap|linecap|strokeLineJoin|linejoin|strokeMiterLimit|miterlimit|strokeOpacity|strokeWidth|textAnchor|anchor|textDecoration|decoration|textRendering|underlinePosition|underlineThickness|vertAdvY|vertOriginY|wordSpacing|word|writingMode|writing|mode|addClass|embed|src|initPath|blank|svg_error|continue|getSVGDocument|setTimeout|250|alert|_getSVG|_destroySVG|removeClass|empty|removeData|addExtension|push|_width|_height|root|onload|removeNamedItem|change|removeAttribute|describe|desc|markerWidth|markerHeight|auto|opera|head|append|javascript|mozilla|globalEval|offset|createPath|createText|group|link|textPath|other|prefix|localName|createCDATASection|toLowerCase|boolean|Microsoft|XMLDOM|validateOnParse|resolveExternals|async|loadXML|errorCode|reason|parsererror|div|changeSize|DOMParser|parseFromString|ajax|url|dataType|success|error|message|remove|toSVG|undefined|serializeToString|CDATA|namespaceURI|nextSibling|close|moveTo|lineTo|horizTo|vertTo|curveCTo|smoothCTo|curveQTo|smoothQTo|arcTo|span|fn|slice|call|get|constructor|jQuery'.split('|'),0,{})) \ No newline at end of file
diff --git a/bundles/XO/karma/js/jquery.svgdom.js b/bundles/XO/karma/js/jquery.svgdom.js
new file mode 100755
index 0000000..e350298
--- /dev/null
+++ b/bundles/XO/karma/js/jquery.svgdom.js
@@ -0,0 +1,356 @@
+/* http://keith-wood.name/svg.html
+ SVG/jQuery DOM compatibility for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+
+(function($) { // Hide scope, no $ conflict
+
+/* Support adding class names to SVG nodes. */
+var origAddClass = $.fn.addClass;
+
+$.fn.addClass = function(classNames) {
+ classNames = classNames || '';
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ var node = this;
+ $.each(classNames.split(/\s+/), function(i, className) {
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
+ if ($.inArray(className, classes.split(/\s+/)) == -1) {
+ classes += (classes ? ' ' : '') + className;
+ (node.className ? node.className.baseVal = classes :
+ node.setAttribute('class', classes));
+ }
+ });
+ }
+ else {
+ origAddClass.apply($(this), [classNames]);
+ }
+ });
+};
+
+/* Support removing class names from SVG nodes. */
+var origRemoveClass = $.fn.removeClass;
+
+$.fn.removeClass = function(classNames) {
+ classNames = classNames || '';
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ var node = this;
+ $.each(classNames.split(/\s+/), function(i, className) {
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
+ classes = $.grep(classes.split(/\s+/), function(n, i) { return n != className; }).
+ join(' ');
+ (node.className ? node.className.baseVal = classes :
+ node.setAttribute('class', classes));
+ });
+ }
+ else {
+ origRemoveClass.apply($(this), [classNames]);
+ }
+ });
+};
+
+/* Support toggling class names on SVG nodes. */
+var origToggleClass = $.fn.toggleClass;
+
+$.fn.toggleClass = function(className, state) {
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ if (typeof state !== 'boolean') {
+ state = !$(this).hasClass(className);
+ }
+ $(this)[(state ? 'add' : 'remove') + 'Class'](className);
+ }
+ else {
+ origToggleClass.apply($(this), [className, state]);
+ }
+ });
+};
+
+/* Support checking class names on SVG nodes. */
+var origHasClass = $.fn.hasClass;
+
+$.fn.hasClass = function(className) {
+ className = className || '';
+ var found = false;
+ this.each(function() {
+ if (isSVGElem(this)) {
+ var classes = (this.className ? this.className.baseVal :
+ this.getAttribute('class')).split(/\s+/);
+ found = ($.inArray(className, classes) > -1);
+ }
+ else {
+ found = (origHasClass.apply($(this), [className]));
+ }
+ return !found;
+ });
+ return found;
+};
+
+/* Support attributes on SVG nodes. */
+var origAttr = $.fn.attr;
+
+//BWB: is this what i need to do for css?
+$.fn.attr = function(name, value, type) {
+ if (typeof name === 'string' && value === undefined) {
+ var val = origAttr.apply(this, [name, value, type]);
+ return (val && val.baseVal ? val.baseVal.valueAsString : val);
+ }
+ var options = name;
+ if (typeof name === 'string') {
+ options = {};
+ options[name] = value;
+ }
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ for (var n in options) {
+ this.setAttribute(n,
+ (typeof options[n] == 'function' ? options[n]() : options[n]));
+ }
+ }
+ else {
+ origAttr.apply($(this), [name, value, type]);
+ }
+ });
+};
+
+// BWB attempting to patch css manipulation of SVG
+//support manipulation of css styles
+var origCss = $.fn.css;
+
+$.fn.css = function(name, value, type) {
+ var revAttrName = function(name){
+ for (var jsName in $.svg._attrNames){
+ if ($.svg._attrNames[jsName] === name){
+ return jsName;
+ }
+ }
+ return name;
+ };
+
+ if (typeof name === 'string' && value === undefined) {
+ var val = origCss.apply(this, [name, value, type]);
+ return (val && val.baseVal ? val.baseVal.valueAsString : val);
+ }
+ var options = name;
+ if (typeof name === 'string') {
+ options = {};
+ options[name] = value;
+ }
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ for (var n in options) {
+ //if Firefox
+ if (this.style.MozBinding === "") {
+ var jsName = revAttrName(n);
+ console.log(jsName);
+ this.style[jsName] = options[n];
+ (typeof options[n] === 'function' ? options[n]() : options[n]);
+ } else {
+ this.style.setProperty(n,
+ typeof options[n] == 'function' ? options[n]() : options[n]);
+ }
+ }
+ }
+ else {
+ origCss.apply($(this), [name, value, type]);
+ }
+ });
+};
+
+
+/* Support removing attributes on SVG nodes. */
+var origRemoveAttr = $.fn.removeAttr;
+
+$.fn.removeAttr = function(name) {
+ return this.each(function() {
+ if (isSVGElem(this)) {
+ (this[name] && this[name].baseVal ? this[name].baseVal.value = '' :
+ this.setAttribute(name, ''));
+ }
+ else {
+ origRemoveAttr.apply($(this), [name]);
+ }
+ });
+};
+
+/* Update Sizzle selectors. */
+var origRelativeNext = $.expr.relative['+'];
+var origRelativeChild = $.expr.relative['>'];
+var origRelativeDescendant = $.expr.relative[''];
+var origRelativeSiblings = $.expr.relative['~'];
+var origFindId = $.expr.find.ID;
+var origFindTag = $.expr.find.TAG;
+var origPreFilterClass = $.expr.preFilter.CLASS;
+var origFilterClass = $.expr.filter.CLASS;
+var origFilterAttr = $.expr.filter.ATTR;
+
+/* Determine if any nodes are SVG nodes. */
+function anySVG(checkSet) {
+ for (var i = 0; i < checkSet.length; i++) {
+ if (checkSet[i].nodeType == 1 && checkSet[i].namespaceURI == $.svg.svgNS) {
+ return true;
+ }
+ }
+ return false;
+}
+
+$.expr.relative['+'] = function(checkSet, part, isXML) {
+ origRelativeNext(checkSet, part, isXML || anySVG(checkSet));
+};
+
+$.expr.relative['>'] = function(checkSet, part, isXML) {
+ origRelativeChild(checkSet, part, isXML || anySVG(checkSet));
+};
+
+$.expr.relative[''] = function(checkSet, part, isXML) {
+ origRelativeDescendant(checkSet, part, isXML || anySVG(checkSet));
+};
+
+$.expr.relative['~'] = function(checkSet, part, isXML) {
+ origRelativeSiblings(checkSet, part, isXML || anySVG(checkSet));
+};
+
+$.expr.find.ID = function(match, context, isXML) {
+ return (isSVGElem(context) ?
+ [context.ownerDocument.getElementById(match[1])] :
+ origFindId(match, context, isXML));
+};
+
+var div = document.createElement('div');
+div.appendChild(document.createComment(''));
+if (div.getElementsByTagName('*').length > 0) { // Make sure no comments are found
+ $.expr.find.TAG = function(match, context) {
+ var results = context.getElementsByTagName(match[1]);
+ if (match[1] === '*') { // Filter out possible comments
+ var tmp = [];
+ for (var i = 0; results[i] || results.item(i); i++) {
+ if ((results[i] || results.item(i)).nodeType === 1) {
+ tmp.push(results[i] || results.item(i));
+ }
+ }
+ results = tmp;
+ }
+ return results;
+ };
+}
+
+$.expr.preFilter.CLASS = function(match, curLoop, inplace, result, not, isXML) {
+ match = ' ' + match[1].replace(/\\/g, '') + ' ';
+ if (isXML) {
+ return match;
+ }
+ for (var i = 0, elem = {}; elem != null; i++) {
+ elem = curLoop[i];
+ if (!elem) {
+ try {
+ elem = curLoop.item(i);
+ }
+ catch (e) {
+ // Ignore
+ }
+ }
+ if (elem) {
+ var className = (!isSVGElem(elem) ? elem.className :
+ (elem.className ? elem.className.baseVal : '') || elem.getAttribute('class'));
+ if (not ^ (className && (' ' + className + ' ').indexOf(match) > -1)) {
+ if (!inplace)
+ result.push(elem);
+ }
+ else if (inplace) {
+ curLoop[i] = false;
+ }
+ }
+ }
+ return false;
+};
+
+$.expr.filter.CLASS = function(elem, match) {
+ var className = (!isSVGElem(elem) ? elem.className :
+ (elem.className ? elem.className.baseVal : elem.getAttribute('class')));
+ return (' ' + className + ' ').indexOf(match) > -1;
+};
+
+$.expr.filter.ATTR = function(elem, match) {
+ var handler = null;
+ if (isSVGElem(elem)) {
+ handler = match[1];
+ $.expr.attrHandle[handler] = function(elem){
+ var attr = elem.getAttribute(handler);
+ return attr && attr.baseVal || attr;
+ };
+ }
+ var filter = origFilterAttr(elem, match);
+ if (handler) {
+ $.expr.attrHandle[handler] = null;
+ }
+ return filter;
+};
+
+/*
+ Change Sizzle initialisation (line 1425) in jQuery v1.3.2 base code...
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] || set.item(i) ); // Here
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] || set.item(i) ); // Here
+ }
+ }
+ }
+ }
+
+ Change fallback makeArray (line 2076) implementation in jQuery Sizzle...
+
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] || array.item(i) ); // Here
+ }
+ }
+*/
+
+/*
+ Events management requires changes to jQuery v1.3.2 base code...
+
+ In $.event.add (line 2437)...
+
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
+ // Bind the global event handler to the element
+ try { // Here
+ elem.addEventListener(type, handle, false);
+ }
+ catch(e) {
+ if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ In $.event.remove (line 2521)...
+
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
+ try { // Here
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ }
+ catch (e) {
+ if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ }
+*/
+
+/* Does this node belong to SVG? */
+function isSVGElem(node) {
+ return (node.nodeType == 1 && node.namespaceURI == $.svg.svgNS);
+}
+
+})(jQuery);
diff --git a/bundles/XO/karma/js/jquery.svgdom.pack.js b/bundles/XO/karma/js/jquery.svgdom.pack.js
new file mode 100755
index 0000000..be88a52
--- /dev/null
+++ b/bundles/XO/karma/js/jquery.svgdom.pack.js
@@ -0,0 +1,7 @@
+/* http://keith-wood.name/svg.html
+ SVG/jQuery DOM compatibility for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(4($){2 j=$.9.W;$.9.W=4(d){d=d||\'\';7 3.D(4(){5(C(3)){2 c=3;$.D(d.J(/\\s+/),4(i,a){2 b=(c.8?c.8.A:c.I(\'F\'));5($.X(a,b.J(/\\s+/))==-1){b+=(b?\' \':\'\')+a;(c.8?c.8.A=b:c.L(\'F\',b))}})}G{j.H($(3),[d])}})};2 k=$.9.Y;$.9.Y=4(d){d=d||\'\';7 3.D(4(){5(C(3)){2 c=3;$.D(d.J(/\\s+/),4(i,a){2 b=(c.8?c.8.A:c.I(\'F\'));b=$.1g(b.J(/\\s+/),4(n,i){7 n!=a}).1h(\' \');(c.8?c.8.A=b:c.L(\'F\',b))})}G{k.H($(3),[d])}})};2 l=$.9.Z;$.9.Z=4(a,b){7 3.D(4(){5(C(3)){5(M b!==\'1i\'){b=!$(3).T(a)}$(3)[(b?\'1j\':\'1k\')+\'1l\'](a)}G{l.H($(3),[a,b])}})};2 m=$.9.T;$.9.T=4(b){b=b||\'\';2 c=N;3.D(4(){5(C(3)){2 a=(3.8?3.8.A:3.I(\'F\')).J(/\\s+/);c=($.X(b,a)>-1)}G{c=(m.H($(3),[b]))}7!c});7 c};2 o=$.9.10;$.9.10=4(a,b,c){5(M a===\'11\'&&b===1m){2 d=o.H(3,[a,b,c]);7(d&&d.A?d.A.1n:d)}2 e=a;5(M a===\'11\'){e={};e[a]=b}7 3.D(4(){5(C(3)){O(2 n 1o e){3.L(n,(M e[n]==\'4\'?e[n]():e[n]))}}G{o.H($(3),[a,b,c])}})};2 p=$.9.12;$.9.12=4(a){7 3.D(4(){5(C(3)){(3[a]&&3[a].A?3[a].A.1p=\'\':3.L(a,\'\'))}G{p.H($(3),[a])}})};2 q=$.6.E[\'+\'];2 r=$.6.E[\'>\'];2 s=$.6.E[\'\'];2 t=$.6.E[\'~\'];2 u=$.6.P.13;2 v=$.6.P.14;2 w=$.6.15.Q;2 x=$.6.R.Q;2 y=$.6.R.16;4 K(a){O(2 i=0;i<a.17;i++){5(a[i].U==1&&a[i].18==$.19.1a){7 1q}}7 N}$.6.E[\'+\']=4(a,b,c){q(a,b,c||K(a))};$.6.E[\'>\']=4(a,b,c){r(a,b,c||K(a))};$.6.E[\'\']=4(a,b,c){s(a,b,c||K(a))};$.6.E[\'~\']=4(a,b,c){t(a,b,c||K(a))};$.6.P.13=4(a,b,c){7(C(b)?[b.1r.1s(a[1])]:u(a,b,c))};2 z=1b.1t(\'1u\');z.1v(1b.1w(\'\'));5(z.1c(\'*\').17>0){$.6.P.14=4(a,b){2 c=b.1c(a[1]);5(a[1]===\'*\'){2 d=[];O(2 i=0;c[i]||c.S(i);i++){5((c[i]||c.S(i)).U===1){d.1d(c[i]||c.S(i))}}c=d}7 c}}$.6.15.Q=4(a,b,c,d,f,g){a=\' \'+a[1].1x(/\\\\/g,\'\')+\' \';5(g){7 a}O(2 i=0,B={};B!=V;i++){B=b[i];5(!B){1y{B=b.S(i)}1z(e){}}5(B){2 h=(!C(B)?B.8:(B.8?B.8.A:\'\')||B.I(\'F\'));5(f^(h&&(\' \'+h+\' \').1e(a)>-1)){5(!c)d.1d(B)}G 5(c){b[i]=N}}}7 N};$.6.R.Q=4(a,b){2 c=(!C(a)?a.8:(a.8?a.8.A:a.I(\'F\')));7(\' \'+c+\' \').1e(b)>-1};$.6.R.16=4(c,d){2 e=V;5(C(c)){e=d[1];$.6.1f[e]=4(a){2 b=a.I(e);7 b&&b.A||b}}2 f=y(c,d);5(e){$.6.1f[e]=V}7 f};4 C(a){7(a.U==1&&a.18==$.19.1a)}})(1A);',62,99,'||var|this|function|if|expr|return|className|fn|||||||||||||||||||||||||||baseVal|elem|isSVGElem|each|relative|class|else|apply|getAttribute|split|anySVG|setAttribute|typeof|false|for|find|CLASS|filter|item|hasClass|nodeType|null|addClass|inArray|removeClass|toggleClass|attr|string|removeAttr|ID|TAG|preFilter|ATTR|length|namespaceURI|svg|svgNS|document|getElementsByTagName|push|indexOf|attrHandle|grep|join|boolean|add|remove|Class|undefined|valueAsString|in|value|true|ownerDocument|getElementById|createElement|div|appendChild|createComment|replace|try|catch|jQuery'.split('|'),0,{})) \ No newline at end of file
diff --git a/bundles/XO/karma/js/karma.js b/bundles/XO/karma/js/karma.js
new file mode 100755
index 0000000..97530d7
--- /dev/null
+++ b/bundles/XO/karma/js/karma.js
@@ -0,0 +1,1650 @@
+/* Documentation Note:
+ * Public methods and properties are commented with /** some text *\/
+ * and private methods and properties are commented with //
+ *
+ * Please leave it that way to keep this documentation sane
+ */
+
+
+/*
+* Karma Framework
+* http://karmaeducation.org
+*
+* Copyright (c) 2009
+* Bryan W Berry bryan@olenepal.org
+* Felipe LĂłpez Toledo zer.subzero@gmail.com
+*
+* Under MIT License:
+* Permission is hereby granted, free of charge, to any person
+* obtaining a copy of this software and associated documentation
+* files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following
+* conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+* @fileOverview Contains karma library
+* @author Bryan Berry <bryan@olenepal.org>
+* @author Felipe Lopez Toledo <zer.subzero@gmail.com>
+*/
+
+
+//common.js modules use exports object
+if(!this.exports) {
+ exports = {};
+}
+
+
+
+/** Karma is the namespace for the Karma library and Karma() is the constructor
+ * function for the Karma library object Karma.karma.
+ * Karma() checks if the current document type is set to HTML 5, throws
+ * an error if not. Otherwise, initializes the karma object and returns
+ * a reference to that object.
+ * @namespace Global namespace for Karma library
+ * @param {Object} [options={}] options for intializing Karma library
+ * @param {String} [options.locale=''] sets current locale Not Yet Implemented
+ * @param {Array} [options.image=[]] array of images to be converted into a collection
+ * @param {Array} [options.audio=[]] array of audio to be converted into a collection
+ * @param {Array} [options.video=[]] NYI array of videos to be converted into a collection
+ * @param {Array} [options.svg=[]] array of SVG elements to be
+ * converted into a collection. Each SVG element must already exist in the html document
+ * @param {Array} [options.canvas=[]] array of canvas elements
+ * to be converted into a collection. Each canvas element must already exist in the
+ * html document and width and height of each element must be set as attributes
+ * @throws {Error} if the document type declaration is not set to HTML 5, e.g.
+ * <!DOCTYPE html>
+ * @throws {Error} If any of the initialization parameters are invalid values
+ * @returns {Object} Karma.karma -- reference to the initialized Karma library
+ * @example
+ *
+ * var k = Karma({
+ * image: [
+ * {name: "ninja", file: "ninja.png"},
+ * {name: "cowboy", file: "cowboy.png"}
+ * ],
+ * audio: [
+ * {name: "woosh", file: "woosh.ogg"},
+ * {name: "yeehaw", file: "yeehaw.ogg"}
+ * ],
+ * video: [ //Not Yet Implemented
+ * {name: "attack", file: "attack.ogv"},
+ * {name: "ride", file: "ride.ogv"}
+ * ]
+ * canvas: [
+ * {name: "ninja", domId: "ninjaCanvas"},
+ * {name: "cowboy", domId: "cowboyCanvas"}
+ * ],
+ * svg: [
+ * {name: "ninja", domId: "ninjaSvg"},
+ * {name: "cowboy", domId: "cowboySvg"}
+ * ],
+ * });
+ * Next, call the ready function with a callback to your program code
+ *
+ * k.ready(function () { ... your application code . . . }
+ *
+ * after that you can access each asset like so
+ * k.image.ninja;
+ * k.svg.cowboy;
+ * k.audio.yeehaw.play();
+ * k.canvas.ninja.drawImage(k.image.ninja, 0, 0);
+ *
+ */
+var Karma = exports.Karma = function (options) {
+ Karma._isHtml5(document.doctype.nodeName);
+
+ if ( Karma.karma._initialized === true ) {
+ return Karma.karma;
+ } else {
+ return Karma.karma._init(options);
+ }
+};
+
+
+//helper functions
+
+/**This emulates the Object.create method in ecmascript 5 spec
+ * This isn't a full implementation as it doesn't support an all of Object.create's features
+ * This has the same functionality as Crockford's beget method
+ * and this primary building block for prototypal inheritance in
+ * this library
+ * @param {Object} parent that the new object's prototype should point to
+ * @returns {Object} a new object whose prototype is parent
+ * @example
+ *
+ * var ninja = { weapon : "sword" };
+ * var ninja1 = Karma.create(ninja);
+ * ninja1.weapon === "sword"
+ */
+Karma.create = function (parent){
+ function F () {};
+ F.prototype = parent;
+ return new F();
+};
+
+/** Returns a shallow copy of the passed in object
+ * @param {Object} target to be copied
+ * @returns {Object} a shallow copy of target
+ */
+Karma.clone = function (target){
+ var copy = {};
+ for ( var i in target ) {
+ if(target.hasOwnProperty(i)){
+ copy[i] = target[i];
+ }
+ }
+ return copy;
+};
+
+/** Extends properties of the target object with those of
+ * the source object
+ * @param {Object} target object to be extended
+ * @param {Object} source whose properties will extend target
+ * @returns {Object} target extended by source
+ */
+Karma.objectPlus = function (target, source){
+ for ( var i in source){
+ if (source.hasOwnProperty(i)){
+ target[i] = source[i];
+ }
+ }
+ return target;
+};
+
+/** Creates a new object that is a prototype of the first argument
+ * then extends it with the properties of the second argument
+ * @param {Object} parent1 will be prototype of returned object
+ * @param {Object} parent2 will extend properties of returned object
+ * @returns {Object} object that whose prototype is parent1 and has
+ * been extended with properties of parent2
+ */
+Karma.copyObjectPlus = function (parent1, parent2){
+ function F () {};
+ F.prototype = parent1;
+ var G = new F();
+ return Karma.objectPlus(G, parent2);
+};
+
+
+//Throws big ugly error if doctype isn't html5
+Karma._isHtml5 = function (doctype){
+ var regex = new RegExp('^html$', 'i');
+ if(!regex.test(doctype)){
+ var errorMsg = "ERROR: The doctype must be set to <!DOCTYPE html> " +
+ "in order to use Karma. Karma require you use html5";
+ var errorElem = document.createElement('div');
+ errorElem.setAttribute('id', 'errorDoctype');
+ errorElem.innerText = errorMsg;
+ document.body.appendChild(errorElem);
+ throw new Error(errorMsg);
+ }
+};
+
+
+/** Stores global settings for the Karma library
+ * @class This object stores the global settings for the Karma library
+ */
+Karma.karma = {
+ /** This is the global locale as passed to Karma(),
+ * such as "en", "es_SP"
+ * @property {string} locale This is the global locale as passed to Karma()
+ * @default undefined
+ */
+ locale : undefined,
+ /** Collection of images with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ image : {},
+ /** Collection of audio files with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ audio : {},
+ /** Collection of html 5 canvases with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ canvas : {},
+ /** Collection of svgs with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ svg : {},
+ /** Collection of videos with special helper
+ * methods added to each reference
+ * @type object
+ * @default empty object
+ */
+ video : {},
+ _localized : false,
+ _assetPath : "assets/",
+ _localePath : "",
+ _initialized : false,
+ _statusDiv: undefined,
+ _loaderDiv : undefined,
+ _counters : { total : 0, errors : 0, loaded : 0},
+
+ //This constructs the Karma.karma object per values provided by the user
+ _init: function(options) {
+ this._initialized = true;
+
+ //set up message that show count of assets loaded
+ //and has an ordered list to append error messages to
+ var _statusDiv = this._statusDiv = document.createElement('div');
+ this._loaderDiv = this._loaderDiv = document.createElement('div');
+ var errorList = document.createElement('ol');
+
+ _statusDiv.setAttribute('id', 'karma-status');
+ _statusDiv.setAttribute('style', 'position:absolute;');
+ _statusDiv.innerHTML = 'Karma is loading ...';
+ this._loaderDiv.setAttribute('id', 'karma-loader');
+ this._loaderDiv.setAttribute('class', 'status');
+ errorList.setAttribute('id', 'errorList');
+
+ _statusDiv.appendChild(this._loaderDiv);
+ this._statusDiv.appendChild(errorList);
+ document.body.appendChild(_statusDiv);
+
+ //regular expression that matches the name of aprivate property
+ // the karma object
+ var regexPrivate = new RegExp('^_.*');
+
+ for ( var option in options ) {
+ if (options.hasOwnProperty(option)){
+ if (option === "image" || option === "audio" || option ===
+ "svg" || option === "video" || option === "canvas"){
+
+ if(!(options[option] instanceof Array)){
+ throw new Error("" + option + " must be an array");
+ } else if (options[option].length === 0){
+ continue;
+ }
+ } else if (regexPrivate.test(option)){
+ //don't overwrite a private property of karma object
+ continue;
+ }
+
+ switch (option){
+ case "locale":
+
+ if (this._isValidLocale(options[option])){
+ this.locale = this._normalizeLocale(options[option]);
+ this._localized = true;
+ this._localePath = Karma._computeLocalePath(this.locale);
+ } else {
+ throw new Error("locale provided to karma._init() is invalid");
+ }
+
+ break;
+ case "image":
+ options[option]._type = 'image';
+ Karma._makeCollection(options[option], 'image');
+ break;
+ case "audio":
+ options[option]._type = 'audio';
+ Karma._makeCollection(options[option], 'audio');
+ break;
+ case "video":
+ options[option]._type = 'video';
+ Karma._makeCollection(options[option], 'video');
+ break;
+ case "svg":
+ options[option]._type = 'svg';
+ Karma._makeCollection(options[option], 'svg');
+ break;
+ case "canvas":
+ options[option]._type = 'canvas';
+ Karma._makeCollection(options[option], 'canvas');
+ break;
+ }
+ }
+ }
+
+
+
+ return this;
+ },
+
+ /** Waits until all assets loaded(ready), then calls callback cb
+ * @param {Function} [cb] callback function
+ * @returns this
+ * @throws {Error} if Karma.karma is not initialized with the
+ * Karma({ options }) function
+ * @example
+ *
+ * var k = Karma({ . . . your assets here . . . });
+ * k.ready(function(){ .. your code here . . .});
+ *
+ * your code will not be called until all assets have been loaded
+ * into collections
+ *
+ */
+ ready : function( cb ) {
+ var that = this;
+ if (Karma.karma._initialized !== true){
+ throw new Error("Karma.karma not initialized");
+ }
+
+ if (this._counters.loaded !== this._counters.total){
+ setTimeout(function(){ that.ready(cb);}, 5);
+ } else if (cb) {
+ //hide the "Karma is loading..." message
+ this._statusDiv.setAttribute('style', 'display:none;');
+
+ cb();
+ } else if (!cb) {
+ //hide the "Karma is loading..." message
+ this._statusDiv.setAttribute('style', 'display:none;');
+
+ //if no options passed, show it works message
+ this._showStarterMessage();
+ }
+
+
+
+
+ return this;
+ },
+
+ //Display Apache-like "It works" message if no options
+ _showStarterMessage : function (){
+ var starterMsg = document.createElement('div');
+ starterMsg.setAttribute('id', 'starterMsg');
+ starterMsg.innerHTML = "<h1>It Works</h1>";
+ document.body.appendChild(starterMsg);
+ },
+
+ //Updates visible counter of how many assets are loaded
+ _updateStatus : function (errorMsg) {
+ var loaded = this._counters.loaded;
+ var total = this._counters.total;
+ var errors = this._counters.errors;
+ this._loaderDiv.innerHTML = "Loaded " + loaded + " / " + total +
+ "" + (errors > 0 ? " Errors [ " + errors +" ]" : '');
+ if (errorMsg) {
+ var liError = document.createElement('li');
+ liError.innerHTML = errorMsg;
+ var errorList = document.getElementById('errorList');
+ errorList.appendChild(liError);
+ }
+ },
+
+ //matches 2 letter country code then optionally
+ //a dash or underscore followed by a country or language identifier
+ //i currently only allow a language identifier 2-3 chars long
+ _isValidLocale : function (locale) {
+ var localeRegex = new RegExp('^[a-zA-Z][a-zA-Z]([-_][a-zA-z]{2,3})?$');
+ return localeRegex.test(locale);
+ },
+
+ _normalizeLocale : function(locale) {
+ var lang = "";
+ var country = "";
+ var divider = "";
+
+ lang = locale.slice(0, 2).toLowerCase();
+ divider = "_";
+ country = locale.slice(3, 6).toUpperCase();
+
+ return locale.length > 2 ? "" + lang + divider + country : lang;
+ },
+
+ // Below are geometry and math helper methods
+
+ /**
+ * Converts a value from degrees to radians.
+ * @param {Number} angle The angle in degrees
+ * @returns {Number} The angle in radians
+ */
+ radians : function( angle ){
+ return ( angle / 180 ) * Math.PI;
+ },
+ /**
+ * Gets the square of the Euclidian (ordinary) distance between 2 points.
+ * @param {Object} Point No. 0
+ * @param {Number} Point0.x
+ * @param {Number} Point0.y
+ * @param {Object} Point No. 1
+ * @param {Number} Point1.x
+ * @param {Number} Point1.y
+ * @returns {Number} The square of the Euclidian distance
+ * @example
+ *
+ * p0 = {x:0, y:1};
+ * p1 = {x:50, y:70};
+ * var d = distance2(p0, p1);
+ *
+ */
+ distance2 : function ( p0, p1 ) {
+ return (p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p1.y) * (p1.y - p1.y);
+ },
+ /**
+ * Gets the Euclidian (ordinary) distance between 2 points.<br>
+ * <b>Warning:</b> It's slower than distance2 function
+ * @param {Object} Point No. 0
+ * @param {Number} Point0.x
+ * @param {Number} Point0.y
+ * @param {Object} Point No. 1
+ * @param {Number} Point1.x
+ * @param {Number} Point1.y
+ * @returns {Number} The Euclidian distance
+ * @example
+ *
+ * p0 = {x:0, y:1};
+ * p1 = {x:50, y:70};
+ * var d = distance2(p0, p1);
+ *
+ */
+ distance : function ( p0, p1 ) {
+ return Math.sqrt( this.distance2( p0, p1 ) );
+ },
+ /** Returns a random number within the range provided
+ * @param {Number} lower limit of the range, lowest number that can be returned
+ * @param {Number} upper limit of the range, highest number that can be returned
+ * @returns {Number} number that is >= lower and <= upper
+ * @example
+ *
+ * var num = rand(0, 10);
+ *
+ * //num could be 0, 1, 2, 3 ... or 10
+ *
+ */
+ rand : function ( lower, upper ){
+ return Math.round( Math.random() * (upper - lower) + lower );
+ }
+
+};
+
+//Helper functions for creating assets
+
+Karma._isLocalized = function (boolLocalized) {
+ if (typeof boolLocalized === "boolean" ) {
+ if(boolLocalized === true &&
+ Karma.karma.locale === undefined){
+ throw new Error("You cannot localize a media asset" +
+ " if the global locale for Karma isn't set");
+ } else {
+ return boolLocalized;
+ }
+ } else if (typeof boolLocalized === undefined){
+ return false;
+ } else{
+ throw new Error("This is not a valid value for the localized option");
+ }
+};
+
+Karma._computeLocalePath = function(locale) {
+ return Karma.karma._assetPath + locale + "/";
+};
+
+
+
+
+Karma._makeCollection = function (configs, type){
+ var makeAsset = function (config){
+ var asset = undefined;
+ var target = undefined;
+ switch(type){
+ case "image":
+ target = Karma.kImage;
+ break;
+ case "audio":
+ target = Karma.kAudio;
+ break;
+ case "video":
+ target = Karma.kVideo;
+ break;
+ case "svg":
+ target = Karma.kSvg;
+ break;
+ case "canvas":
+ target = Karma.kCanvas;
+ break;
+ }
+
+ asset = Karma.create(target)._init(config);
+ Karma.karma[type][config.name] = asset;
+ };
+
+ configs.forEach(function(config){ makeAsset(config);});
+};
+
+
+
+
+
+//Prototype objects for assets
+
+
+/** Prototype object for images
+ * @class This object is the prototype for images submitted to Karma in the
+ * Karma() method
+ * @ throws {Error} if the image asset is set to be localized but
+ * the global locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ * @example
+ * kImage is the prototype object for images. This 'media' asset is loaded
+ * in a distinctly different way from the canvas or svg assets.
+ *
+ */
+Karma.kImage =
+ {
+ /** file location of image
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** media object
+ * @type Image
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this image
+ _localized : false,
+ _type : "image",
+ //initializes kImage instance with values provided by user
+ _init : function (image) {
+ image._localized = image._localized || false;
+ Karma.karma._counters.total++;
+
+ if (image.name === undefined || image.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = image.name;
+ this.file = image.file;
+ }
+
+ this.media = new Image();
+
+ if(Karma._isLocalized(image._localized)){
+ this._localized = image._localized;
+ this._path = Karma.karma._localePath + "image/";
+ } else {
+ this._path = Karma.karma._assetPath + "image/";
+ }
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the image is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+
+ that.media.addEventListener(
+ "load",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+ }
+
+};
+
+/** Prototype object for audio files
+ * @class This object is the prototype for audio files submitted to Karma in the
+ * Karma() method
+ * @ throws {Error} if the individual audio asset is set to be localized but
+ * the globale locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ * @example
+ * kAudio is the prototype object for audio
+ * The audio assets are loaded in a distinctly different way
+ * from the canvas or svg assets. They also have distinctly different
+ * helper methods
+ *
+ * You initialize the kAudio assets by passing an array of objects
+ */
+Karma.kAudio = {
+ /** file location of asset
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** Media object. You can access the src, autobuffer, autoplay, loop, and
+ * controls attributes
+ * via the media property of kAudio. Read more about the properties of the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#media-element-attributes">HTML 5 media element</a>
+ * @type Audio
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this asset
+ _localized : false,
+ _type : "audio",
+ //initializes kAudio instance with values provided by user
+ _init : function (audio) {
+ audio._localized = audio._localized || false;
+ Karma.karma._counters.total++;
+
+ if (audio.name === undefined || audio.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = audio.name;
+ this.file = audio.file;
+ }
+
+ this.media = new Audio();
+
+ if(Karma._isLocalized(audio._localized)){
+ this._localized = audio._localized;
+ this._path = Karma.karma._localePath + "audio/";
+ } else {
+ this._path = Karma.karma._assetPath + "audio/";
+ }
+
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+ if (this._type === "audio"){
+ this.media.autobuffer = true;
+ this.media.load();
+ }
+
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the asset is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+ //'canplaythrough' event is a Browser Hack recommended by chromium devs
+ //http://code.google.com/p/chromium/issues/detail?id=20251&q=loading%20audio&colspec=ID%20Stars%20Pri%20Area%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS#c4
+
+ that.media.addEventListener(
+ "canplaythrough",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ },
+ /** Plays the audio file */
+ play : function () {
+ this.media.play();
+ }
+
+};
+
+/** NYI:Prototype object for Video files
+ * @class Not Yet Implemented:This object is the prototype for video files submitted
+ * to Karma in the Karma() method
+ * @ throws {Error} if the individual video asset is set to be localized but
+ * the globale locale is not set on the Karma.karma object
+ * @ throws {Error} if the name and file properties are not supplied
+ */
+Karma.kVideo = {
+ /** file location of asset
+ * @type String
+ * @default ""
+ */
+ file : "",
+ /** media object
+ * @type Video
+ * @default undefined
+ */
+ media : undefined,
+ //actual path to the file
+ _path : "",
+ //if using localized version of this asset
+ _localized : false,
+ _type : "video",
+ //initializes kVideo instance with values provided by user
+ _init : function (video) {
+ //Not Yet Implemented
+ Karma.karma._counters.errors++;
+ throw new Error("Video is not Yet Implemented");
+
+ video._localized = video._localized || false;
+ Karma.karma._counters.total++;
+
+ if (video.name === undefined || video.file === undefined){
+ throw new Error("properties name and file have to be defined");
+ } else {
+ this.name = video.name;
+ this.file = video.file;
+ }
+
+ this.media = new Video();
+
+ if(Karma._isLocalized(video._localized)){
+ this._localized = video._localized;
+ this._path = Karma.karma._localePath + "video/";
+ } else {
+ this._path = Karma.karma._assetPath + "video/";
+ }
+
+
+ //IMPORTANT: This one magic line loads the file
+ this.media.src = this.src = this._path + this.file;
+
+ //add event handlers
+ this._addEventHandlers();
+
+ return this;
+ },
+ //Adds event handlers to update the counters when
+ //the asset is successfully or unsuccessfully loaded
+ _addEventHandlers : function () {
+ var that = this;
+ //'canplaythrough' event is a Browser Hack recommended by chromium devs
+ //http://code.google.com/p/chromium/issues/detail?id=20251&q=loading%20audio&colspec=ID%20Stars%20Pri%20Area%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS#c4
+
+ that.media.addEventListener(
+ "canplaythrough",
+ function (e) {
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";}, false);
+
+ that.media.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.media.addEventListener(
+ "abort",
+ function (e) {
+ Karma.karma._counters.total++;
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ }
+
+};
+
+
+
+/** Prototype object for each canvas element submitted to Karma in the
+ * Karma() method
+ * @throws {Error} if the name and domId for the canvas element are not specified
+ * @thows {Error} if the supplied domId does not match an element in the DOM
+ * @class This object is the prototype for each canvas element submitted to Karma in the
+ * Karma() method
+ */
+Karma.kCanvas = {
+ /** Name of the canvas, used internally by karma.js
+ * @type String
+ * @default ''
+ */
+ name : '',
+ /** Width of canvas element
+ * @type Number
+ * @default 0
+ */
+ width: 0,
+ /** Height of canvas element
+ * @type Number
+ * @default 0
+ */
+ height: 0,
+ /** Whether canvas is visible
+ * @type boolean
+ * @default true
+ */
+ visible: true,
+ /** Element ID for canvas element in html document. This value is read-only
+ * @type String
+ * @default undefined
+ */
+ domId: undefined,
+ /** Reference to the DOM element
+ * @type DOMElement
+ * @default undefined
+ * @example
+ * //You can access all properties and methods of the underlying DOM element
+ * //using the 'node' property
+ * Karma.karma.canvas.someCanvas.node.dispatchEvent( ... some event ...);
+ * var stuff = Karma.karma.canvas.someCanvas.node.innerHTML;
+ *
+ */
+ node: undefined,
+ /** The 2 Dimensional Rendering context property for this canvas
+ * @type 2DRenderingContext
+ * @default undefined
+ * @example
+ * //Almost all of the context attributes and methods are wrapped in helper functions
+ * //but you can also access them directly using the ctx property
+ * Karma.karma.canvas.someCanvas.ctx.drawImage(someImage, x, y);
+ * Karma.karma.canvas.someCanvas.ctx.fillStyle = "#ffffff";
+ */
+ ctx: undefined,
+
+ //initializes object with values provides by user
+ _init: function (config) {
+ for (var option in config){
+ if (config.hasOwnProperty(option)){
+ switch (option){
+ case "name":
+ this.name = config[option];
+ break;
+ case "domId":
+ this.domId = config[option];
+ break;
+ case "width":
+ if(!this.height){
+ throw new Error("If you specify a width you must also" +
+ "specify a height");
+ }
+ this.width = config[option];
+ break;
+ case "height":
+ if(!this.width){
+ throw new Error("If you specify a height you must also" +
+ "specify a width");
+ }
+ this.height = parseInt(config.option, 10);
+ break;
+ case "fps":
+ this.fps = parseInt(config.option, 10);
+ break;
+ }
+ }
+ }
+
+ if(this.domId && document.getElementById(this.domId)){
+ this.node = document.getElementById(this.domId);
+ this.ctx = this.node.getContext('2d');
+ } else {
+ throw new Error('you must specify a valid domId that' +
+ 'is in your html page');
+ }
+
+ if(!config.height && !config.width){
+ this.width = parseInt(this.node.getAttribute('width'), 10);
+ this.height = parseInt(this.node.getAttribute('height'), 10);
+ }
+
+ return this;
+ },
+ /** Clear area of canvas element specified by parameters, if no
+ * parameters supplied, clears entire canvas
+ * @param {Number} [x=0] x coordinate, defaults to zero if left blank
+ * @param {Number} [y=0] y coordinate, defaults to zero if left blank
+ * @param {Number} [width=0] width of area to be cleared, defaults
+ * entire width of canvas
+ * @param {Number} [height=0] height of area to be cleared, defaults
+ * entire height of canvas
+ * @returns this
+ * @example
+ *
+ * k.canvas.ninja.clear();
+ * // clears the entire ninja canvas
+ *
+ * k.canvas.ninja.clear(0, 10, 20, 30);
+ * //clears a specific portion of the ninja canvas
+ *
+ */
+ clear : function ( x, y, width, height ) {
+ var that = this;
+ that.ctx.clearRect(
+ x || 0,
+ y || 0,
+ width || that.width,
+ height || that.height
+ );
+ return that;
+ },
+
+ /** The globalAlpha attribute gives an alpha value that is applied to shapes
+ * and images before they are composited onto the canvas
+ * @param {Number} number in the range from 0.0 to 1.0
+ * @returns this
+ */
+ globalAlpha : function (attribute){
+ var name = 'globalAlpha';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the globalCompositeOperation attribute, which sets how shapes and images
+ * are drawn onto the existing bitmap, once they have had globalAlpha and the
+ * current transformation matrix applied.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} globalCompositeOperation source-atop,
+ * source-in, source-out,
+ * source-over, destination-atop, destination-in, destination-out, destination-over,
+ * lighter
+ * @returns this
+ */
+ globalCompositeOperation: function (attribute){
+ var name = ' globalCompositeOperation';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the lineWidth attribute which gives the width of lines, in coordinate space
+ * units.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {Number} lineWidth
+ * @returns this
+ */
+ lineWidth: function (attribute){
+ var name = 'lineWidth';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** The lineCap attribute defines the type of endings that UAs will place on
+ * the end of lines.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} type butt, round, square
+ * @returns this
+ */
+ lineCap: function (attribute){
+ var name = 'lineCap';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** The lineJoin attribute defines the type of corners that UAs will place
+ * where two lines meet. The three valid values are bevel, round, and miter.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} type
+ * @returns this
+ */
+ lineJoin: function (attribute){
+ var name = 'lineJoin';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the miter limit
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {Number} number
+ * @returns this
+ */
+ miterLimit: function (attribute){
+ var name = 'miterLimit';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** Sets the font property and takes the same syntax as setting the font property
+ * in CSS
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String}
+ * @returns this
+ */
+ font: function (attribute){
+ var name = 'font';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Changes the text alignment. The possible values are start, end, left, right,
+ * and center. The default is start. Other values are ignored.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {string} alignment
+ * @returns this
+ */
+ textAlign: function (attribute){
+ var name = 'textAlign';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Changes the baseline alignment. If the value is one of top, hanging, middle,
+ * alphabetic, ideographic, or bottom, then the value must be changed to the new value.
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param {String} alignment
+ * @returns this
+ */
+ textBaseline: function (attribute){
+ var name = 'textBaseline';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Save the current state of the context
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ save : function ( ){
+ var name = 'save';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Restore the saved context
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ restore : function ( ){
+ var name = 'restore';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Perform a scale transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ scale : function ( ){
+ var name = 'scale';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Perform a rotation transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ rotate : function ( ){
+ var name = 'rotate';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Performa a translation transformation
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ translate : function ( ){
+ var name = 'translate';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Transform the identity matrix
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ transform : function ( ){
+ var name = 'transform';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Set the transform
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ setTransform : function ( ){
+ var name = 'setTransform';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Clear a rectangular area
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ clearRect : function ( ){
+ var name = 'clearRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Fill a rectangular area
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillRect : function ( ){
+ var name = 'fillRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Draw the outline of the rectangle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeRect : function ( ){
+ var name = 'strokeRect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Begin a path
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ beginPath : function ( ){
+ var name = 'beginPath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** End a path
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ closePath : function ( ){
+ var name = 'closePath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Move to specified coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ moveTo : function ( ){
+ var name = 'moveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+
+ /** Draw a line to the given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ lineTo : function ( ){
+ var name = 'lineTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Draw a quadratic curve to given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ quadraticCurveTo : function ( ){
+ var name = 'quadraticCurveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Draw a bezier curve to given coordinates
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ bezierCurveTo : function ( ){
+ var name = 'bezierCurveTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Draw an arc to the given points
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ arcTo : function ( ){
+ var name = 'arcTo';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Create an arc
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ arc : function ( ){
+ var name = 'arc';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Create a rectangle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ rect : function ( ){
+ var name = 'rect';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** fill in the current subpaths with the current fillstyle
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fill : function ( ){
+ var name = 'fill';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** Stroke the subpaths
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ stroke : function ( ){
+ var name = 'stroke';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ clip : function ( ){
+ var name = 'clip';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillText : function ( ){
+ var name = 'fillText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeText : function ( ){
+ var name = 'strokeText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ measureText : function ( ){
+ var name = 'measureText';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ isPointInPath : function ( ){
+ var name = 'isPointInPath';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+ /** Sets the stroke style
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ strokeStyle: function (attribute){
+ var name = 'strokeStyle';
+ this.ctx[name] = attribute;
+ return this;
+ },
+
+ /** Sets the fill style
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ fillStyle: function (attribute){
+ var name = 'fillStyle';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createLinearGradient : function ( ){
+ var name = 'createLinearGradient';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createRadialGradient : function ( ){
+ var name = 'createRadialGradient';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createPattern : function ( ){
+ var name = 'createPattern';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowOffsetX: function (attribute){
+ var name = 'shadowOffsetX';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowOffsetY: function (attribute){
+ var name = 'shadowOffsetY';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowBlur: function (attribute){
+ var name = 'shadowBlur';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ shadowColor: function (attribute){
+ var name = 'shadowColor';
+ this.ctx[name] = attribute;
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ drawImage : function ( ){
+ var name = 'drawImage';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ getImageData : function ( ){
+ var name = 'getImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ putImageData : function ( ){
+ var name = 'putImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ createImageData : function ( ){
+ var name = 'createImageData';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+ /** description
+ * For full details see <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-globalcompositeoperation">W3C docs</a>
+ * @param
+ * @returns this
+ */
+ drawWindow : function ( ){
+ var name = 'drawWindow';
+ this.ctx[name].apply(this.ctx, arguments);
+ return this;
+ },
+
+
+
+
+};
+
+
+/** Prototype object for each svg element submitted to Karma in the
+ * Karma() method
+ * @throws {Error} if the name and domId for the svg element are not specified
+ * @thows {Error} if the supplied domId does not match an element in the DOM
+ * @class This object is the prototype for each svg element submitted to Karma in the
+ * Karma() method
+ */
+Karma.kSvg = {
+ /** name of instance, used internally
+ * @typeof string
+ * @default ""
+ */
+ name : "",
+ /** width of element
+ * @type number
+ * @default 0
+ */
+ width: 0,
+ /** height of element
+ * @type number
+ * @default 0
+ */
+ height: 0,
+ /** Status of element, either "loaded" or "error"
+ * @type string
+ * @default ""
+ */
+ status: "",
+ /** Whether canvas is visible. This value is read-only
+ * @type boolean
+ * @default true
+ */
+ visible: true,
+ /** Element ID for canvas element in html document.
+ * @type String
+ * @default undefined
+ */
+ domId: undefined,
+ /** Reference to the DOM element.
+ * @type DOMElement
+ * @default undefined
+ * @example
+ * //You can access all properties and methods of the underlying DOM element
+ * //using the 'node' property
+ * Karma.karma.svg.someSvg.node.dispatchEvent;
+ * Karma.karma.svg.someSvg.node.addEvenListener(...);
+ */
+ node: undefined,
+ /** Reference to the SVGDocument. You can use the this.doc to manipulate
+ * the SVG document
+ * @type SVGDocument
+ * @default undefined
+ * @example
+ * var myElem = Karma.karma.svg.someSvg.doc.getElementById('foobar');
+ * Karma.karma.svg.someSvg.doc.createElement(...);
+ * Karma.karma.svg.someSvg.doc.removeChild(someNode);
+ *
+ */
+ doc: undefined,
+ /** Reference to the root element of the SVG Document
+ * @type DocumentElement
+ * @default undefined
+ * @example
+ * // The root element is equivalent to "document" in a regular html document
+ * // The root attribute is used frequently with the jQuery SVG plugin for CSS selectors
+ * $('#someId', Karma.karma.svg.someSvg.root).css(.. manipulate css attributes ...);
+ */
+ root: undefined,
+ _localized : undefined,
+ _init: function (config) {
+ Karma.karma._counters.total++;
+
+ for (var option in config){
+ if (config.hasOwnProperty(option)){
+ switch (option){
+ case "name":
+ this.name = config[option];
+ break;
+ case "domId":
+ this.domId = config[option];
+ break;
+ case "width":
+ if(!this.height){
+ throw new Error("If you specify a width you must also" +
+ "specify a height");
+ }
+ this.width = parseInt(config[option], 10);
+ break;
+ case "height":
+ if(!this.width){
+ throw new Error("If you specify a height you must also" +
+ "specify a width");
+ }
+ this.height = config[option];
+ break;
+ }
+ }
+ }
+
+ if(this.domId && document.getElementById(this.domId)){
+ this.node = document.getElementById(this.domId);
+ } else {
+ throw new Error('you must specify a valid domId that' +
+ 'is in your html page');
+ }
+
+ if(!config.height && !config.width){
+ this.width = parseInt(this.node.getAttribute('width'), 10);
+ this.height = parseInt(this.node.getAttribute('height'), 10);
+ }
+
+ var that = this;
+ that._addEventHandlers();
+
+ return this;
+
+
+ },
+ _addEventHandlers : function () {
+ var that = this;
+ that.doc = that.node.getSVGDocument();
+ that.node.addEventListener(
+ "load",
+ function (e) {
+ that.doc = that.node.getSVGDocument();
+ that.root = that.doc.documentElement;
+ Karma.karma._counters.loaded++;
+ Karma.karma._updateStatus();
+ that.status = "loaded";
+ }, false);
+
+ that.node.addEventListener(
+ "error",
+ function (e) {
+ Karma.karma._counters.loaded--;
+ Karma.karma._counters.errors++;
+ that.status = "error";
+ var errorMsg = "Error: " + that._type.toUpperCase() +
+ " " + that.name + " cannot be loaded.";
+ Karma.karma._updateStatus(errorMsg);
+ },
+ false);
+ that.node.addEventListener(
+ "abort",
+ function (e) {
+ that.status = "aborted";
+ var errorMsg = "ABORT: " + that._type.toUpperCase() +
+ " " + that.name + " loading was aborted.";
+ Karma.karma._updateStatus(errorMsg);
+
+ }, false);
+
+ }
+};
diff --git a/bundles/XO/karma/js/knavbar.js b/bundles/XO/karma/js/knavbar.js
new file mode 100755
index 0000000..e7d343f
--- /dev/null
+++ b/bundles/XO/karma/js/knavbar.js
@@ -0,0 +1,13 @@
+//This code loads in html for knavbar into a <section>
+//tag with the id="navigation"
+$(document).ready(function(){
+
+ //updates the links in knavbar
+ //specific to the context
+ var modify = function(){
+
+ };
+
+ var foo = $('#navigation').load('chakra/kfoo.html #knavbar', modify);
+ var x = 0;
+}); \ No newline at end of file
diff --git a/bundles/XO/karma/js/qunit.js b/bundles/XO/karma/js/qunit.js
new file mode 100755
index 0000000..b7ee538
--- /dev/null
+++ b/bundles/XO/karma/js/qunit.js
@@ -0,0 +1,1027 @@
+/*
+ * QUnit - A JavaScript Unit Testing Framework
+ *
+ * http://docs.jquery.com/QUnit
+ *
+ * Copyright (c) 2009 John Resig, Jörn Zaefferer
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ */
+
+(function(window) {
+
+var QUnit = {
+
+ // Initialize the configuration options
+ init: function() {
+ config = {
+ stats: { all: 0, bad: 0 },
+ moduleStats: { all: 0, bad: 0 },
+ started: +new Date,
+ blocking: false,
+ autorun: false,
+ assertions: [],
+ filters: [],
+ queue: []
+ };
+
+ var tests = id("qunit-tests"),
+ banner = id("qunit-banner"),
+ result = id("qunit-testresult");
+
+ if ( tests ) {
+ tests.innerHTML = "";
+ }
+
+ if ( banner ) {
+ banner.className = "";
+ }
+
+ if ( result ) {
+ result.parentNode.removeChild( result );
+ }
+ },
+
+ // call on start of module test to prepend name to all tests
+ module: function(name, testEnvironment) {
+ config.currentModule = name;
+
+ synchronize(function() {
+ if ( config.currentModule ) {
+ QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
+ }
+
+ config.currentModule = name;
+ config.moduleTestEnvironment = testEnvironment;
+ config.moduleStats = { all: 0, bad: 0 };
+
+ QUnit.moduleStart( name, testEnvironment );
+ });
+ },
+
+ asyncTest: function(testName, expected, callback) {
+ if ( arguments.length === 2 ) {
+ callback = expected;
+ expected = 0;
+ }
+
+ QUnit.test(testName, expected, callback, true);
+ },
+
+ test: function(testName, expected, callback, async) {
+ var name = testName, testEnvironment, testEnvironmentArg;
+
+ if ( arguments.length === 2 ) {
+ callback = expected;
+ expected = null;
+ }
+ // is 2nd argument a testEnvironment?
+ if ( expected && typeof expected === 'object') {
+ testEnvironmentArg = expected;
+ expected = null;
+ }
+
+ if ( config.currentModule ) {
+ name = config.currentModule + " module: " + name;
+ }
+
+ if ( !validTest(name) ) {
+ return;
+ }
+
+ synchronize(function() {
+ QUnit.testStart( testName );
+
+ testEnvironment = extend({
+ setup: function() {},
+ teardown: function() {}
+ }, config.moduleTestEnvironment);
+ if (testEnvironmentArg) {
+ extend(testEnvironment,testEnvironmentArg);
+ }
+
+ // allow utility functions to access the current test environment
+ QUnit.current_testEnvironment = testEnvironment;
+
+ config.assertions = [];
+ config.expected = null;
+
+ if ( arguments.length >= 3 ) {
+ config.expected = callback;
+ callback = arguments[2];
+ }
+
+ try {
+ if ( !config.pollution ) {
+ saveGlobal();
+ }
+
+ testEnvironment.setup.call(testEnvironment);
+ } catch(e) {
+ QUnit.ok( false, "Setup failed on " + name + ": " + e.message );
+ }
+
+ if ( async ) {
+ QUnit.stop();
+ }
+
+ try {
+ callback.call(testEnvironment);
+ } catch(e) {
+ fail("Test " + name + " died, exception and test follows", e, callback);
+ QUnit.ok( false, "Died on test #" + (config.assertions.length + 1) + ": " + e.message );
+ // else next test will carry the responsibility
+ saveGlobal();
+
+ // Restart the tests if they're blocking
+ if ( config.blocking ) {
+ start();
+ }
+ }
+ });
+
+ synchronize(function() {
+ try {
+ checkPollution();
+ testEnvironment.teardown.call(testEnvironment);
+ } catch(e) {
+ QUnit.ok( false, "Teardown failed on " + name + ": " + e.message );
+ }
+
+ try {
+ QUnit.reset();
+ } catch(e) {
+ fail("reset() failed, following Test " + name + ", exception and reset fn follows", e, reset);
+ }
+
+ if ( config.expected && config.expected != config.assertions.length ) {
+ QUnit.ok( false, "Expected " + config.expected + " assertions, but " + config.assertions.length + " were run" );
+ }
+
+ var good = 0, bad = 0,
+ tests = id("qunit-tests");
+
+ config.stats.all += config.assertions.length;
+ config.moduleStats.all += config.assertions.length;
+
+ if ( tests ) {
+ var ol = document.createElement("ol");
+ ol.style.display = "none";
+
+ for ( var i = 0; i < config.assertions.length; i++ ) {
+ var assertion = config.assertions[i];
+
+ var li = document.createElement("li");
+ li.className = assertion.result ? "pass" : "fail";
+ li.innerHTML = assertion.message || "(no message)";
+ ol.appendChild( li );
+
+ if ( assertion.result ) {
+ good++;
+ } else {
+ bad++;
+ config.stats.bad++;
+ config.moduleStats.bad++;
+ }
+ }
+
+ var b = document.createElement("strong");
+ b.innerHTML = name + " <b style='color:black;'>(<b class='fail'>" + bad + "</b>, <b class='pass'>" + good + "</b>, " + config.assertions.length + ")</b>";
+
+ addEvent(b, "click", function() {
+ var next = b.nextSibling, display = next.style.display;
+ next.style.display = display === "none" ? "block" : "none";
+ });
+
+ addEvent(b, "dblclick", function(e) {
+ var target = (e || window.event).target;
+ if ( target.nodeName.toLowerCase() === "strong" ) {
+ var text = "", node = target.firstChild;
+
+ while ( node.nodeType === 3 ) {
+ text += node.nodeValue;
+ node = node.nextSibling;
+ }
+
+ text = text.replace(/(^\s*|\s*$)/g, "");
+
+ if ( window.location ) {
+ window.location.href = window.location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent(text);
+ }
+ }
+ });
+
+ var li = document.createElement("li");
+ li.className = bad ? "fail" : "pass";
+ li.appendChild( b );
+ li.appendChild( ol );
+ tests.appendChild( li );
+
+ if ( bad ) {
+ var toolbar = id("qunit-testrunner-toolbar");
+ if ( toolbar ) {
+ toolbar.style.display = "block";
+ id("qunit-filter-pass").disabled = null;
+ id("qunit-filter-missing").disabled = null;
+ }
+ }
+
+ } else {
+ for ( var i = 0; i < config.assertions.length; i++ ) {
+ if ( !config.assertions[i].result ) {
+ bad++;
+ config.stats.bad++;
+ config.moduleStats.bad++;
+ }
+ }
+ }
+
+ QUnit.testDone( testName, bad, config.assertions.length );
+
+ if ( !window.setTimeout && !config.queue.length ) {
+ done();
+ }
+ });
+
+ if ( window.setTimeout && !config.doneTimer ) {
+ config.doneTimer = window.setTimeout(function(){
+ if ( !config.queue.length ) {
+ done();
+ } else {
+ synchronize( done );
+ }
+ }, 13);
+ }
+ },
+
+ /**
+ * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
+ */
+ expect: function(asserts) {
+ config.expected = asserts;
+ },
+
+ /**
+ * Asserts true.
+ * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+ */
+ ok: function(a, msg) {
+ QUnit.log(a, msg);
+
+ config.assertions.push({
+ result: !!a,
+ message: msg
+ });
+ },
+
+ /**
+ * Checks that the first two arguments are equal, with an optional message.
+ * Prints out both actual and expected values.
+ *
+ * Prefered to ok( actual == expected, message )
+ *
+ * @example equals( format("Received {0} bytes.", 2), "Received 2 bytes." );
+ *
+ * @param Object actual
+ * @param Object expected
+ * @param String message (optional)
+ */
+ equals: function(actual, expected, message) {
+ push(expected == actual, actual, expected, message);
+ },
+
+ same: function(a, b, message) {
+ push(QUnit.equiv(a, b), a, b, message);
+ },
+
+ start: function() {
+ // A slight delay, to avoid any current callbacks
+ if ( window.setTimeout ) {
+ window.setTimeout(function() {
+ if ( config.timeout ) {
+ clearTimeout(config.timeout);
+ }
+
+ config.blocking = false;
+ process();
+ }, 13);
+ } else {
+ config.blocking = false;
+ process();
+ }
+ },
+
+ stop: function(timeout) {
+ config.blocking = true;
+
+ if ( timeout && window.setTimeout ) {
+ config.timeout = window.setTimeout(function() {
+ QUnit.ok( false, "Test timed out" );
+ QUnit.start();
+ }, timeout);
+ }
+ },
+
+ /**
+ * Resets the test setup. Useful for tests that modify the DOM.
+ */
+ reset: function() {
+ if ( window.jQuery ) {
+ jQuery("#main").html( config.fixture );
+ jQuery.event.global = {};
+ jQuery.ajaxSettings = extend({}, config.ajaxSettings);
+ }
+ },
+
+ /**
+ * Trigger an event on an element.
+ *
+ * @example triggerEvent( document.body, "click" );
+ *
+ * @param DOMElement elem
+ * @param String type
+ */
+ triggerEvent: function( elem, type, event ) {
+ if ( document.createEvent ) {
+ event = document.createEvent("MouseEvents");
+ event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
+ 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ elem.dispatchEvent( event );
+
+ } else if ( elem.fireEvent ) {
+ elem.fireEvent("on"+type);
+ }
+ },
+
+ // Safe object type checking
+ is: function( type, obj ) {
+ return Object.prototype.toString.call( obj ) === "[object "+ type +"]";
+ },
+
+ // Logging callbacks
+ done: function(failures, total) {},
+ log: function(result, message) {},
+ testStart: function(name) {},
+ testDone: function(name, failures, total) {},
+ moduleStart: function(name, testEnvironment) {},
+ moduleDone: function(name, failures, total) {}
+};
+
+// Maintain internal state
+var config = {
+ // The queue of tests to run
+ queue: [],
+
+ // block until document ready
+ blocking: true
+};
+
+// Load paramaters
+(function() {
+ var location = window.location || { search: "", protocol: "file:" },
+ GETParams = location.search.slice(1).split('&');
+
+ for ( var i = 0; i < GETParams.length; i++ ) {
+ GETParams[i] = decodeURIComponent( GETParams[i] );
+ if ( GETParams[i] === "noglobals" ) {
+ GETParams.splice( i, 1 );
+ i--;
+ config.noglobals = true;
+ } else if ( GETParams[i].search('=') > -1 ) {
+ GETParams.splice( i, 1 );
+ i--;
+ }
+ }
+
+ // restrict modules/tests by get parameters
+ config.filters = GETParams;
+
+ // Figure out if we're running the tests from a server or not
+ QUnit.isLocal = !!(location.protocol === 'file:');
+})();
+
+// Expose the API as global variables, unless an 'exports'
+// object exists, in that case we assume we're in CommonJS
+if ( typeof exports === "undefined" || typeof require === "undefined" ) {
+ extend(window, QUnit);
+ window.QUnit = QUnit;
+} else {
+ extend(exports, QUnit);
+ exports.QUnit = QUnit;
+}
+
+if ( typeof document === "undefined" || document.readyState === "complete" ) {
+ config.autorun = true;
+}
+
+addEvent(window, "load", function() {
+ // Initialize the config, saving the execution queue
+ var oldconfig = extend({}, config);
+ QUnit.init();
+ extend(config, oldconfig);
+
+ config.blocking = false;
+
+ var userAgent = id("qunit-userAgent");
+ if ( userAgent ) {
+ userAgent.innerHTML = navigator.userAgent;
+ }
+
+ var toolbar = id("qunit-testrunner-toolbar");
+ if ( toolbar ) {
+ toolbar.style.display = "none";
+
+ var filter = document.createElement("input");
+ filter.type = "checkbox";
+ filter.id = "qunit-filter-pass";
+ filter.disabled = true;
+ addEvent( filter, "click", function() {
+ var li = document.getElementsByTagName("li");
+ for ( var i = 0; i < li.length; i++ ) {
+ if ( li[i].className.indexOf("pass") > -1 ) {
+ li[i].style.display = filter.checked ? "none" : "block";
+ }
+ }
+ });
+ toolbar.appendChild( filter );
+
+ var label = document.createElement("label");
+ label.setAttribute("for", "qunit-filter-pass");
+ label.innerHTML = "Hide passed tests";
+ toolbar.appendChild( label );
+
+ var missing = document.createElement("input");
+ missing.type = "checkbox";
+ missing.id = "qunit-filter-missing";
+ missing.disabled = true;
+ addEvent( missing, "click", function() {
+ var li = document.getElementsByTagName("li");
+ for ( var i = 0; i < li.length; i++ ) {
+ if ( li[i].className.indexOf("fail") > -1 && li[i].innerHTML.indexOf('missing test - untested code is broken code') > - 1 ) {
+ li[i].parentNode.parentNode.style.display = missing.checked ? "none" : "block";
+ }
+ }
+ });
+ toolbar.appendChild( missing );
+
+ label = document.createElement("label");
+ label.setAttribute("for", "qunit-filter-missing");
+ label.innerHTML = "Hide missing tests (untested code is broken code)";
+ toolbar.appendChild( label );
+ }
+
+ var main = id('main');
+ if ( main ) {
+ config.fixture = main.innerHTML;
+ }
+
+ if ( window.jQuery ) {
+ config.ajaxSettings = window.jQuery.ajaxSettings;
+ }
+
+ QUnit.start();
+});
+
+function done() {
+ if ( config.doneTimer && window.clearTimeout ) {
+ window.clearTimeout( config.doneTimer );
+ config.doneTimer = null;
+ }
+
+ if ( config.queue.length ) {
+ config.doneTimer = window.setTimeout(function(){
+ if ( !config.queue.length ) {
+ done();
+ } else {
+ synchronize( done );
+ }
+ }, 13);
+
+ return;
+ }
+
+ config.autorun = true;
+
+ // Log the last module results
+ if ( config.currentModule ) {
+ QUnit.moduleDone( config.currentModule, config.moduleStats.bad, config.moduleStats.all );
+ }
+
+ var banner = id("qunit-banner"),
+ tests = id("qunit-tests"),
+ html = ['Tests completed in ',
+ +new Date - config.started, ' milliseconds.<br/>',
+ '<span class="bad">', config.stats.all - config.stats.bad, '</span> tests of <span class="all">', config.stats.all, '</span> passed, ', config.stats.bad,' failed.'].join('');
+
+ if ( banner ) {
+ banner.className += " " + (config.stats.bad ? "fail" : "pass");
+ }
+
+ if ( tests ) {
+ var result = id("qunit-testresult");
+
+ if ( !result ) {
+ result = document.createElement("p");
+ result.id = "qunit-testresult";
+ result.className = "result";
+ tests.parentNode.insertBefore( result, tests.nextSibling );
+ }
+
+ result.innerHTML = html;
+ }
+
+ QUnit.done( config.stats.bad, config.stats.all );
+}
+
+function validTest( name ) {
+ var i = config.filters.length,
+ run = false;
+
+ if ( !i ) {
+ return true;
+ }
+
+ while ( i-- ) {
+ var filter = config.filters[i],
+ not = filter.charAt(0) == '!';
+
+ if ( not ) {
+ filter = filter.slice(1);
+ }
+
+ if ( name.indexOf(filter) !== -1 ) {
+ return !not;
+ }
+
+ if ( not ) {
+ run = true;
+ }
+ }
+
+ return run;
+}
+
+function push(result, actual, expected, message) {
+ message = message || (result ? "okay" : "failed");
+ QUnit.ok( result, result ? message + ": " + expected : message + ", expected: " + QUnit.jsDump.parse(expected) + " result: " + QUnit.jsDump.parse(actual) );
+}
+
+function synchronize( callback ) {
+ config.queue.push( callback );
+
+ if ( config.autorun && !config.blocking ) {
+ process();
+ }
+}
+
+function process() {
+ while ( config.queue.length && !config.blocking ) {
+ config.queue.shift()();
+ }
+}
+
+function saveGlobal() {
+ config.pollution = [];
+
+ if ( config.noglobals ) {
+ for ( var key in window ) {
+ config.pollution.push( key );
+ }
+ }
+}
+
+function checkPollution( name ) {
+ var old = config.pollution;
+ saveGlobal();
+
+ var newGlobals = diff( old, config.pollution );
+ if ( newGlobals.length > 0 ) {
+ ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
+ config.expected++;
+ }
+
+ var deletedGlobals = diff( config.pollution, old );
+ if ( deletedGlobals.length > 0 ) {
+ ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
+ config.expected++;
+ }
+}
+
+// returns a new Array with the elements that are in a but not in b
+function diff( a, b ) {
+ var result = a.slice();
+ for ( var i = 0; i < result.length; i++ ) {
+ for ( var j = 0; j < b.length; j++ ) {
+ if ( result[i] === b[j] ) {
+ result.splice(i, 1);
+ i--;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+function fail(message, exception, callback) {
+ if ( typeof console !== "undefined" && console.error && console.warn ) {
+ console.error(message);
+ console.error(exception);
+ console.warn(callback.toString());
+
+ } else if ( window.opera && opera.postError ) {
+ opera.postError(message, exception, callback.toString);
+ }
+}
+
+function extend(a, b) {
+ for ( var prop in b ) {
+ a[prop] = b[prop];
+ }
+
+ return a;
+}
+
+function addEvent(elem, type, fn) {
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, fn, false );
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, fn );
+ } else {
+ fn();
+ }
+}
+
+function id(name) {
+ return !!(typeof document !== "undefined" && document && document.getElementById) &&
+ document.getElementById( name );
+}
+
+// Test for equality any JavaScript type.
+// Discussions and reference: http://philrathe.com/articles/equiv
+// Test suites: http://philrathe.com/tests/equiv
+// Author: Philippe Rathé <prathe@gmail.com>
+QUnit.equiv = function () {
+
+ var innerEquiv; // the real equiv function
+ var callers = []; // stack to decide between skip/abort functions
+
+
+ // Determine what is o.
+ function hoozit(o) {
+ if (QUnit.is("String", o)) {
+ return "string";
+
+ } else if (QUnit.is("Boolean", o)) {
+ return "boolean";
+
+ } else if (QUnit.is("Number", o)) {
+
+ if (isNaN(o)) {
+ return "nan";
+ } else {
+ return "number";
+ }
+
+ } else if (typeof o === "undefined") {
+ return "undefined";
+
+ // consider: typeof null === object
+ } else if (o === null) {
+ return "null";
+
+ // consider: typeof [] === object
+ } else if (QUnit.is( "Array", o)) {
+ return "array";
+
+ // consider: typeof new Date() === object
+ } else if (QUnit.is( "Date", o)) {
+ return "date";
+
+ // consider: /./ instanceof Object;
+ // /./ instanceof RegExp;
+ // typeof /./ === "function"; // => false in IE and Opera,
+ // true in FF and Safari
+ } else if (QUnit.is( "RegExp", o)) {
+ return "regexp";
+
+ } else if (typeof o === "object") {
+ return "object";
+
+ } else if (QUnit.is( "Function", o)) {
+ return "function";
+ } else {
+ return undefined;
+ }
+ }
+
+ // Call the o related callback with the given arguments.
+ function bindCallbacks(o, callbacks, args) {
+ var prop = hoozit(o);
+ if (prop) {
+ if (hoozit(callbacks[prop]) === "function") {
+ return callbacks[prop].apply(callbacks, args);
+ } else {
+ return callbacks[prop]; // or undefined
+ }
+ }
+ }
+
+ var callbacks = function () {
+
+ // for string, boolean, number and null
+ function useStrictEquality(b, a) {
+ if (b instanceof a.constructor || a instanceof b.constructor) {
+ // to catch short annotaion VS 'new' annotation of a declaration
+ // e.g. var i = 1;
+ // var j = new Number(1);
+ return a == b;
+ } else {
+ return a === b;
+ }
+ }
+
+ return {
+ "string": useStrictEquality,
+ "boolean": useStrictEquality,
+ "number": useStrictEquality,
+ "null": useStrictEquality,
+ "undefined": useStrictEquality,
+
+ "nan": function (b) {
+ return isNaN(b);
+ },
+
+ "date": function (b, a) {
+ return hoozit(b) === "date" && a.valueOf() === b.valueOf();
+ },
+
+ "regexp": function (b, a) {
+ return hoozit(b) === "regexp" &&
+ a.source === b.source && // the regex itself
+ a.global === b.global && // and its modifers (gmi) ...
+ a.ignoreCase === b.ignoreCase &&
+ a.multiline === b.multiline;
+ },
+
+ // - skip when the property is a method of an instance (OOP)
+ // - abort otherwise,
+ // initial === would have catch identical references anyway
+ "function": function () {
+ var caller = callers[callers.length - 1];
+ return caller !== Object &&
+ typeof caller !== "undefined";
+ },
+
+ "array": function (b, a) {
+ var i;
+ var len;
+
+ // b could be an object literal here
+ if ( ! (hoozit(b) === "array")) {
+ return false;
+ }
+
+ len = a.length;
+ if (len !== b.length) { // safe and faster
+ return false;
+ }
+ for (i = 0; i < len; i++) {
+ if ( ! innerEquiv(a[i], b[i])) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "object": function (b, a) {
+ var i;
+ var eq = true; // unless we can proove it
+ var aProperties = [], bProperties = []; // collection of strings
+
+ // comparing constructors is more strict than using instanceof
+ if ( a.constructor !== b.constructor) {
+ return false;
+ }
+
+ // stack constructor before traversing properties
+ callers.push(a.constructor);
+
+ for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
+
+ aProperties.push(i); // collect a's properties
+
+ if ( ! innerEquiv(a[i], b[i])) {
+ eq = false;
+ }
+ }
+
+ callers.pop(); // unstack, we are done
+
+ for (i in b) {
+ bProperties.push(i); // collect b's properties
+ }
+
+ // Ensures identical properties name
+ return eq && innerEquiv(aProperties.sort(), bProperties.sort());
+ }
+ };
+ }();
+
+ innerEquiv = function () { // can take multiple arguments
+ var args = Array.prototype.slice.apply(arguments);
+ if (args.length < 2) {
+ return true; // end transition
+ }
+
+ return (function (a, b) {
+ if (a === b) {
+ return true; // catch the most you can
+ } else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || hoozit(a) !== hoozit(b)) {
+ return false; // don't lose time with error prone cases
+ } else {
+ return bindCallbacks(a, callbacks, [b, a]);
+ }
+
+ // apply transition with (1..n) arguments
+ })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
+ };
+
+ return innerEquiv;
+
+}();
+
+/**
+ * jsDump
+ * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
+ * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)
+ * Date: 5/15/2008
+ * @projectDescription Advanced and extensible data dumping for Javascript.
+ * @version 1.0.0
+ * @author Ariel Flesler
+ * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
+ */
+QUnit.jsDump = (function() {
+ function quote( str ) {
+ return '"' + str.toString().replace(/"/g, '\\"') + '"';
+ };
+ function literal( o ) {
+ return o + '';
+ };
+ function join( pre, arr, post ) {
+ var s = jsDump.separator(),
+ base = jsDump.indent(),
+ inner = jsDump.indent(1);
+ if ( arr.join )
+ arr = arr.join( ',' + s + inner );
+ if ( !arr )
+ return pre + post;
+ return [ pre, inner + arr, base + post ].join(s);
+ };
+ function array( arr ) {
+ var i = arr.length, ret = Array(i);
+ this.up();
+ while ( i-- )
+ ret[i] = this.parse( arr[i] );
+ this.down();
+ return join( '[', ret, ']' );
+ };
+
+ var reName = /^function (\w+)/;
+
+ var jsDump = {
+ parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance
+ var parser = this.parsers[ type || this.typeOf(obj) ];
+ type = typeof parser;
+
+ return type == 'function' ? parser.call( this, obj ) :
+ type == 'string' ? parser :
+ this.parsers.error;
+ },
+ typeOf:function( obj ) {
+ var type;
+ if ( obj === null ) {
+ type = "null";
+ } else if (typeof obj === "undefined") {
+ type = "undefined";
+ } else if (QUnit.is("RegExp", obj)) {
+ type = "regexp";
+ } else if (QUnit.is("Date", obj)) {
+ type = "date";
+ } else if (QUnit.is("Function", obj)) {
+ type = "function";
+ } else if (QUnit.is("Array", obj)) {
+ type = "array";
+ } else if (QUnit.is("Window", obj) || QUnit.is("global", obj)) {
+ type = "window";
+ } else if (QUnit.is("HTMLDocument", obj)) {
+ type = "document";
+ } else if (QUnit.is("HTMLCollection", obj) || QUnit.is("NodeList", obj)) {
+ type = "nodelist";
+ } else if (/^\[object HTML/.test(Object.prototype.toString.call( obj ))) {
+ type = "node";
+ } else {
+ type = typeof obj;
+ }
+ return type;
+ },
+ separator:function() {
+ return this.multiline ? this.HTML ? '<br />' : '\n' : this.HTML ? '&nbsp;' : ' ';
+ },
+ indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
+ if ( !this.multiline )
+ return '';
+ var chr = this.indentChar;
+ if ( this.HTML )
+ chr = chr.replace(/\t/g,' ').replace(/ /g,'&nbsp;');
+ return Array( this._depth_ + (extra||0) ).join(chr);
+ },
+ up:function( a ) {
+ this._depth_ += a || 1;
+ },
+ down:function( a ) {
+ this._depth_ -= a || 1;
+ },
+ setParser:function( name, parser ) {
+ this.parsers[name] = parser;
+ },
+ // The next 3 are exposed so you can use them
+ quote:quote,
+ literal:literal,
+ join:join,
+ //
+ _depth_: 1,
+ // This is the list of parsers, to modify them, use jsDump.setParser
+ parsers:{
+ window: '[Window]',
+ document: '[Document]',
+ error:'[ERROR]', //when no parser is found, shouldn't happen
+ unknown: '[Unknown]',
+ 'null':'null',
+ undefined:'undefined',
+ 'function':function( fn ) {
+ var ret = 'function',
+ name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
+ if ( name )
+ ret += ' ' + name;
+ ret += '(';
+
+ ret = [ ret, this.parse( fn, 'functionArgs' ), '){'].join('');
+ return join( ret, this.parse(fn,'functionCode'), '}' );
+ },
+ array: array,
+ nodelist: array,
+ arguments: array,
+ object:function( map ) {
+ var ret = [ ];
+ this.up();
+ for ( var key in map )
+ ret.push( this.parse(key,'key') + ': ' + this.parse(map[key]) );
+ this.down();
+ return join( '{', ret, '}' );
+ },
+ node:function( node ) {
+ var open = this.HTML ? '&lt;' : '<',
+ close = this.HTML ? '&gt;' : '>';
+
+ var tag = node.nodeName.toLowerCase(),
+ ret = open + tag;
+
+ for ( var a in this.DOMAttrs ) {
+ var val = node[this.DOMAttrs[a]];
+ if ( val )
+ ret += ' ' + a + '=' + this.parse( val, 'attribute' );
+ }
+ return ret + close + open + '/' + tag + close;
+ },
+ functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function
+ var l = fn.length;
+ if ( !l ) return '';
+
+ var args = Array(l);
+ while ( l-- )
+ args[l] = String.fromCharCode(97+l);//97 is 'a'
+ return ' ' + args.join(', ') + ' ';
+ },
+ key:quote, //object calls it internally, the key part of an item in a map
+ functionCode:'[code]', //function calls it internally, it's the content of the function
+ attribute:quote, //node calls it internally, it's an html attribute value
+ string:quote,
+ date:quote,
+ regexp:literal, //regex
+ number:literal,
+ 'boolean':literal
+ },
+ DOMAttrs:{//attributes to dump from nodes, name=>realName
+ id:'id',
+ name:'name',
+ 'class':'className'
+ },
+ HTML:true,//if true, entities are escaped ( <, >, \t, space and \n )
+ indentChar:' ',//indentation unit
+ multiline:true //if true, items in a collection, are separated by a \n, else just a space.
+ };
+
+ return jsDump;
+})();
+
+})(this);
diff --git a/bundles/XO/karma/js/raphael-min.js b/bundles/XO/karma/js/raphael-min.js
new file mode 100755
index 0000000..eac42bb
--- /dev/null
+++ b/bundles/XO/karma/js/raphael-min.js
@@ -0,0 +1,7 @@
+/*
+ * Raphael 1.0 RC1.4 - JavaScript Vector Library
+ *
+ * Copyright (c) 2008 - 2009 Dmitry Baranovskiy (http://raphaeljs.com)
+ * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
+ */
+window.Raphael=(function(){var Y=/[, ]+/,g=document,L=window,P={was:"Raphael" in window,is:window.Raphael},f=function(){return l.apply(f,arguments);},b={},q={"clip-rect":"0 0 10e9 10e9",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},u={"clip-rect":"csv",cx:"number",cy:"number",fill:"colour","fill-opacity":"number","font-size":"number",height:"number",opacity:"number",path:"path",r:"number",rotation:"csv",rx:"number",ry:"number",scale:"csv",stroke:"colour","stroke-opacity":"number","stroke-width":"number",translation:"csv",width:"number",x:"number",y:"number"},v=["click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup"];f.version="1.0 RC1.4";f.type=(window.SVGAngle||document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML");f.svg=!(f.vml=f.type=="VML");f.idGenerator=0;f.fn={};f.is=function(i,e){e=(e+"").toLowerCase();if(e=="undefined"&&typeof i=="undefined"){return true;}if(i==null&&e=="null"){return true;}return Object.prototype.toString.call(i).replace(/^\[object\s+|\]$/gi,"").toLowerCase()==e;};f.setWindow=function(e){L=e;g=L.document;};f.hsb2rgb=X(function(af,ad,aj){if(f.is(af,"object")&&"h" in af&&"s" in af&&"b" in af){aj=af.b;ad=af.s;af=af.h;}var aa,ab,ak;if(aj==0){return{r:0,g:0,b:0,hex:"#000"};}if(af>1||ad>1||aj>1){af/=255;ad/=255;aj/=255;}var ac=Math.floor(af*6),ag=(af*6)-ac,Z=aj*(1-ad),R=aj*(1-(ad*ag)),al=aj*(1-(ad*(1-ag)));aa=[aj,R,Z,Z,al,aj,aj][ac];ab=[al,aj,aj,R,Z,Z,al][ac];ak=[Z,Z,al,aj,aj,R,Z][ac];aa*=255;ab*=255;ak*=255;var ah={r:aa,g:ab,b:ak},e=Math.round(aa).toString(16),ae=Math.round(ab).toString(16),ai=Math.round(ak).toString(16);if(e.length==1){e="0"+e;}if(ae.length==1){ae="0"+ae;}if(ai.length==1){ai="0"+ai;}ah.hex="#"+e+ae+ai;return ah;},f);f.rgb2hsb=X(function(e,i,ad){if(f.is(e,"object")&&"r" in e&&"g" in e&&"b" in e){ad=e.b;i=e.g;e=e.r;}if(f.is(e,"string")){var af=f.getRGB(e);e=af.r;i=af.g;ad=af.b;}if(e>1||i>1||ad>1){e/=255;i/=255;ad/=255;}var ac=Math.max(e,i,ad),R=Math.min(e,i,ad),aa,Z,ab=ac;if(R==ac){return{h:0,s:0,b:ac};}else{var ae=(ac-R);Z=ae/ac;if(e==ac){aa=(i-ad)/ae;}else{if(i==ac){aa=2+((ad-e)/ae);}else{aa=4+((e-i)/ae);}}aa/=6;if(aa<0){aa+=1;}if(aa>1){aa-=1;}}return{h:aa,s:Z,b:ab};},f);f._path2string=function(){var Z="",ac;for(var R=0,aa=this.length;R<aa;R++){for(var e=0,ab=this[R].length;e<ab;e++){Z+=this[R][e];e&&e!=ab-1&&(Z+=",");}R!=aa-1&&(Z+="\n");}return Z.replace(/,(?=-)/g,"");};function X(Z,i,e){function R(){var aa=Array.prototype.splice.call(arguments,0,arguments.length),ab=aa.join("\u25ba");R.cache=R.cache||{};R.count=R.count||[];if(ab in R.cache){return e?e(R.cache[ab]):R.cache[ab];}if(R.count.length>1000){delete R.cache[R.count.unshift()];}R.count.push(ab);R.cache[ab]=Z.apply(i,aa);return e?e(R.cache[ab]):R.cache[ab];}return R;}f.getRGB=X(function(e){var af={aliceblue:"#f0f8ff",amethyst:"#96c",antiquewhite:"#faebd7",aqua:"#0ff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000",blanchedalmond:"#ffebcd",blue:"#00f",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#0ff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#f0f",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#789",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#0f0",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#f0f",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#f00",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#fff",whitesmoke:"#f5f5f5",yellow:"#ff0",yellowgreen:"#9acd32"},ab;if((e+"").toLowerCase() in af){e=af[e.toString().toLowerCase()];}if(!e){return{r:0,g:0,b:0,hex:"#000"};}if(e=="none"){return{r:-1,g:-1,b:-1,hex:"none"};}var R,Z,ae,ac=(e+"").match(/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgb\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|rgb\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\)|hs[bl]\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hs[bl]\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i);if(ac){if(ac[2]){ae=parseInt(ac[2].substring(5),16);Z=parseInt(ac[2].substring(3,5),16);R=parseInt(ac[2].substring(1,3),16);}if(ac[3]){ae=parseInt(ac[3].substring(3)+ac[3].substring(3),16);Z=parseInt(ac[3].substring(2,3)+ac[3].substring(2,3),16);R=parseInt(ac[3].substring(1,2)+ac[3].substring(1,2),16);}if(ac[4]){ac=ac[4].split(/\s*,\s*/);R=parseFloat(ac[0]);Z=parseFloat(ac[1]);ae=parseFloat(ac[2]);}if(ac[5]){ac=ac[5].split(/\s*,\s*/);R=parseFloat(ac[0])*2.55;Z=parseFloat(ac[1])*2.55;ae=parseFloat(ac[2])*2.55;}if(ac[6]){ac=ac[6].split(/\s*,\s*/);R=parseFloat(ac[0]);Z=parseFloat(ac[1]);ae=parseFloat(ac[2]);return f.hsb2rgb(R,Z,ae);}if(ac[7]){ac=ac[7].split(/\s*,\s*/);R=parseFloat(ac[0])*2.55;Z=parseFloat(ac[1])*2.55;ae=parseFloat(ac[2])*2.55;return f.hsb2rgb(R,Z,ae);}ac={r:R,g:Z,b:ae};var i=Math.round(R).toString(16),aa=Math.round(Z).toString(16),ad=Math.round(ae).toString(16);(i.length==1)&&(i="0"+i);(aa.length==1)&&(aa="0"+aa);(ad.length==1)&&(ad="0"+ad);ac.hex="#"+i+aa+ad;ab=ac;}else{ab={r:-1,g:-1,b:-1,hex:"none"};}return ab;},f);f.getColor=function(i){var R=this.getColor.start=this.getColor.start||{h:0,s:1,b:i||0.75},e=this.hsb2rgb(R.h,R.s,R.b);R.h+=0.075;if(R.h>1){R.h=0;R.s-=0.2;if(R.s<=0){this.getColor.start={h:0,s:1,b:R.b};}}return e.hex;};f.getColor.reset=function(){delete this.start;};f.parsePathString=X(function(e){if(!e){return null;}var R={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},i=[];if(f.is(e,"array")&&f.is(e[0],"array")){i=t(e);}if(!i.length){(e+"").replace(/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,function(aa,Z,ad){var ac=[],ab=Z.toLowerCase();ad.replace(/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,function(af,ae){ae&&ac.push(+ae);});while(ac.length>=R[ab]){i.push([Z].concat(ac.splice(0,R[ab])));if(!R[ab]){break;}}});}i.toString=f._path2string;return i;});var C=X(function(ag){if(!ag){return{x:0,y:0,width:0,height:0};}ag=O(ag);var ad=0,ac=0,Z=[],R=[];for(var aa=0,af=ag.length;aa<af;aa++){if(ag[aa][0]=="M"){ad=ag[aa][1];ac=ag[aa][2];Z.push(ad);R.push(ac);}else{var ab=J(ad,ac,ag[aa][1],ag[aa][2],ag[aa][3],ag[aa][4],ag[aa][5],ag[aa][6]);Z=Z.concat(ab.min.x,ab.max.x);R=R.concat(ab.min.y,ab.max.y);}}var e=Math.min.apply(0,Z),ae=Math.min.apply(0,R);return{x:e,y:ae,width:Math.max.apply(0,Z)-e,height:Math.max.apply(0,R)-ae};}),t=function(ac){var Z=[];if(!f.is(ac,"array")||!f.is(ac&&ac[0],"array")){ac=f.parsePathString(ac);}for(var R=0,aa=ac.length;R<aa;R++){Z[R]=[];for(var e=0,ab=ac[R].length;e<ab;e++){Z[R][e]=ac[R][e];}}Z.toString=f._path2string;return Z;},c=X(function(aa){if(!f.is(aa,"array")||!f.is(aa&&aa[0],"array")){aa=f.parsePathString(aa);}var ag=[],ai=0,ah=0,al=0,ak=0,Z=0;if(aa[0][0]=="M"){ai=aa[0][1];ah=aa[0][2];al=ai;ak=ah;Z++;ag.push(["M",ai,ah]);}for(var ad=Z,am=aa.length;ad<am;ad++){var e=ag[ad]=[],aj=aa[ad];if(aj[0]!=aj[0].toLowerCase()){e[0]=aj[0].toLowerCase();switch(e[0]){case"a":e[1]=aj[1];e[2]=aj[2];e[3]=aj[3];e[4]=aj[4];e[5]=aj[5];e[6]=+(aj[6]-ai).toFixed(3);e[7]=+(aj[7]-ah).toFixed(3);break;case"v":e[1]=+(aj[1]-ah).toFixed(3);break;case"m":al=aj[1];ak=aj[2];default:for(var ac=1,ae=aj.length;ac<ae;ac++){e[ac]=+(aj[ac]-((ac%2)?ai:ah)).toFixed(3);}}}else{e=ag[ad]=[];if(aj[0]=="m"){al=aj[1]+ai;ak=aj[2]+ah;}for(var ab=0,R=aj.length;ab<R;ab++){ag[ad][ab]=aj[ab];}}var af=ag[ad].length;switch(ag[ad][0]){case"z":ai=al;ah=ak;break;case"h":ai+=+ag[ad][af-1];break;case"v":ah+=+ag[ad][af-1];break;default:ai+=+ag[ad][af-2];ah+=+ag[ad][af-1];}}ag.toString=f._path2string;return ag;},0,t),w=X(function(aa){if(!f.is(aa,"array")||!f.is(aa&&aa[0],"array")){aa=f.parsePathString(aa);}var af=[],ah=0,ag=0,ak=0,aj=0,Z=0;if(aa[0][0]=="M"){ah=+aa[0][1];ag=+aa[0][2];ak=ah;aj=ag;Z++;af[0]=["M",ah,ag];}for(var ad=Z,al=aa.length;ad<al;ad++){var e=af[ad]=[],ai=aa[ad];if(ai[0]!=(ai[0]+"").toUpperCase()){e[0]=(ai[0]+"").toUpperCase();switch(e[0]){case"A":e[1]=ai[1];e[2]=ai[2];e[3]=ai[3];e[4]=ai[4];e[5]=ai[5];e[6]=+(ai[6]+ah);e[7]=+(ai[7]+ag);break;case"V":e[1]=+ai[1]+ag;break;case"H":e[1]=+ai[1]+ah;break;case"M":ak=+ai[1]+ah;aj=+ai[2]+ag;default:for(var ac=1,ae=ai.length;ac<ae;ac++){e[ac]=+ai[ac]+((ac%2)?ah:ag);}}}else{for(var ab=0,R=ai.length;ab<R;ab++){af[ad][ab]=ai[ab];}}switch(e[0]){case"Z":ah=ak;ag=aj;break;case"H":ah=e[1];break;case"V":ag=e[1];break;default:ah=af[ad][af[ad].length-2];ag=af[ad][af[ad].length-1];}}af.toString=f._path2string;return af;},null,t),d=function(i,Z,e,R){return[i,Z,e,R,e,R];},x=function(i,Z,ab,aa,e,R){return[2/3*i+1/3*ab,2/3*Z+1/3*aa,2/3*i+1/3*e,2/3*Z+1/3*R,e,R];},r=function(ak,aP,au,ar,al,af,aa,aj,aO,am){var aq=Math.PI*120/180,e=Math.PI/180*(+al||0),ay=[],av,aL=X(function(aQ,aT,i){var aS=aQ*Math.cos(i)-aT*Math.sin(i),aR=aQ*Math.sin(i)+aT*Math.cos(i);return{x:aS,y:aR};});if(!am){av=aL(ak,aP,-e);ak=av.x;aP=av.y;av=aL(aj,aO,-e);aj=av.x;aO=av.y;var R=Math.cos(Math.PI/180*al),ah=Math.sin(Math.PI/180*al),aA=(ak-aj)/2,az=(aP-aO)/2;au=Math.max(au,Math.abs(aA));ar=Math.max(ar,Math.abs(az));var Z=au*au,aD=ar*ar,aF=(af==aa?-1:1)*Math.sqrt(Math.abs((Z*aD-Z*az*az-aD*aA*aA)/(Z*az*az+aD*aA*aA))),ao=aF*au*az/ar+(ak+aj)/2,an=aF*-ar*aA/au+(aP+aO)/2,ae=Math.asin((aP-an)/ar),ad=Math.asin((aO-an)/ar);ae=ak<ao?Math.PI-ae:ae;ad=aj<ao?Math.PI-ad:ad;ae<0&&(ae=Math.PI*2+ae);ad<0&&(ad=Math.PI*2+ad);if(aa&&ae>ad){ae=ae-Math.PI*2;}if(!aa&&ad>ae){ad=ad-Math.PI*2;}}else{ae=am[0];ad=am[1];ao=am[2];an=am[3];}var ai=ad-ae;if(Math.abs(ai)>aq){var ap=ad,at=aj,ag=aO;ad=ae+aq*(aa&&ad>ae?1:-1);aj=ao+au*Math.cos(ad);aO=an+ar*Math.sin(ad);ay=r(aj,aO,au,ar,al,0,aa,at,ag,[ad,ap,ao,an]);}ai=ad-ae;var ac=Math.cos(ae),aN=Math.sin(ae),ab=Math.cos(ad),aM=Math.sin(ad),aB=Math.tan(ai/4),aE=4/3*au*aB,aC=4/3*ar*aB,aK=[ak,aP],aJ=[ak+aE*aN,aP-aC*ac],aI=[aj+aE*aM,aO-aC*ab],aG=[aj,aO];aJ[0]=2*aK[0]-aJ[0];aJ[1]=2*aK[1]-aJ[1];if(am){return[aJ,aI,aG].concat(ay);}else{ay=[aJ,aI,aG].concat(ay).join(",").split(",");var aw=[];for(var aH=0,ax=ay.length;aH<ax;aH++){aw[aH]=aH%2?aL(ay[aH-1],ay[aH],e).y:aL(ay[aH],ay[aH+1],e).x;}return aw;}},A=X(function(i,e,ao,am,ab,aa,ad,ac,ai){var ag=Math.pow(1-ai,3)*i+Math.pow(1-ai,2)*3*ai*ao+(1-ai)*3*ai*ai*ab+Math.pow(ai,3)*ad,ae=Math.pow(1-ai,3)*e+Math.pow(1-ai,2)*3*ai*am+(1-ai)*3*ai*ai*aa+Math.pow(ai,3)*ac,ak=i+2*ai*(ao-i)+ai*ai*(ab-2*ao+i),aj=e+2*ai*(am-e)+ai*ai*(aa-2*am+e),an=ao+2*ai*(ab-ao)+ai*ai*(ad-2*ab+ao),al=am+2*ai*(aa-am)+ai*ai*(ac-2*aa+am),ah=(1-ai)*i+ai*ao,af=(1-ai)*e+ai*am,Z=(1-ai)*ab+ai*ad,R=(1-ai)*aa+ai*ac;return{x:ag,y:ae,m:{x:ak,y:aj},n:{x:an,y:al},start:{x:ah,y:af},end:{x:Z,y:R}};}),J=X(function(i,e,Z,R,am,al,ai,af){var ak=(am-2*Z+i)-(ai-2*am+Z),ah=2*(Z-i)-2*(am-Z),ae=i-Z,ac=(-ah+Math.sqrt(ah*ah-4*ak*ae))/2/ak,aa=(-ah-Math.sqrt(ah*ah-4*ak*ae))/2/ak,ag=[e,af],aj=[i,ai],ad=A(i,e,Z,R,am,al,ai,af,ac>0&&ac<1?ac:0),ab=A(i,e,Z,R,am,al,ai,af,aa>0&&aa<1?aa:0);aj=aj.concat(ad.x,ab.x);ag=ag.concat(ad.y,ab.y);ak=(al-2*R+e)-(af-2*al+R);ah=2*(R-e)-2*(al-R);ae=e-R;ac=(-ah+Math.sqrt(ah*ah-4*ak*ae))/2/ak;aa=(-ah-Math.sqrt(ah*ah-4*ak*ae))/2/ak;ad=A(i,e,Z,R,am,al,ai,af,ac>0&&ac<1?ac:0);ab=A(i,e,Z,R,am,al,ai,af,aa>0&&aa<1?aa:0);aj=aj.concat(ad.x,ab.x);ag=ag.concat(ad.y,ab.y);return{min:{x:Math.min.apply(Math,aj),y:Math.min.apply(Math,ag)},max:{x:Math.max.apply(Math,aj),y:Math.max.apply(Math,ag)}};}),O=X(function(al,ag){var aa=w(al),ah=ag&&w(ag),ai={x:0,y:0,bx:0,by:0,X:0,Y:0},e={x:0,y:0,bx:0,by:0,X:0,Y:0},ac=function(am,an){var i,ao;if(!am){return["C",an.x,an.y,an.x,an.y,an.x,an.y];}switch(am[0]){case"M":an.X=am[1];an.Y=am[2];break;case"A":am=["C"].concat(r.apply(0,[an.x,an.y].concat(am.slice(1))));break;case"S":i=an.x+(an.x-(an.bx||an.x));ao=an.y+(an.y-(an.by||an.y));am=["C",i,ao].concat(am.slice(1));break;case"T":i=an.x+(an.x-(an.bx||an.x));ao=an.y+(an.y-(an.by||an.y));am=["C"].concat(x(an.x,an.y,i,ao,am[1],am[2]));break;case"Q":am=["C"].concat(x(an.x,an.y,am[1],am[2],am[3],am[4]));break;case"L":am=["C"].concat(d(an.x,an.y,am[1],am[2]));break;case"H":am=["C"].concat(d(an.x,an.y,am[1],an.y));break;case"V":am=["C"].concat(d(an.x,an.y,an.x,am[1]));break;case"Z":am=["C"].concat(d(an.x,an.y,an.X,an.Y));break;}return am;},R=function(am,an){if(am[an].length>7){am[an].shift();var ao=am[an];while(ao.length){am.splice(an++,0,["C"].concat(ao.splice(0,6)));}am.splice(an,1);aj=Math.max(aa.length,ah&&ah.length||0);}},Z=function(aq,ap,an,am,ao){if(aq&&ap&&aq[ao][0]=="M"&&ap[ao][0]!="M"){ap.splice(ao,0,["M",am.x,am.y]);an.bx=0;an.by=0;an.x=aq[ao][1];an.y=aq[ao][2];aj=Math.max(aa.length,ah&&ah.length||0);}};for(var ae=0,aj=Math.max(aa.length,ah&&ah.length||0);ae<aj;ae++){aa[ae]=ac(aa[ae],ai);R(aa,ae);ah&&(ah[ae]=ac(ah[ae],e));ah&&R(ah,ae);Z(aa,ah,ai,e,ae);Z(ah,aa,e,ai,ae);var ad=aa[ae],ak=ah&&ah[ae],ab=ad.length,af=ah&&ak.length;ai.bx=ad[ab-4]||0;ai.by=ad[ab-3]||0;ai.x=ad[ab-2];ai.y=ad[ab-1];e.bx=ah&&(ak[af-4]||0);e.by=ah&&(ak[af-3]||0);e.x=ah&&ak[af-2];e.y=ah&&ak[af-1];}return ah?[aa,ah]:aa;},null,t),n=X(function(ah){if(f.is(ah,"string")){ah=ah.split(/\s*\-\s*/);var Z=ah.shift();if(Z.toLowerCase()=="v"){Z=90;}else{if(Z.toLowerCase()=="h"){Z=0;}else{Z=parseFloat(Z);}}Z=-Z;var af={angle:Z,type:"linear",dots:[],vector:[0,0,Math.cos(Z*Math.PI/180).toFixed(3),Math.sin(Z*Math.PI/180).toFixed(3)]},ag=1/(Math.max(Math.abs(af.vector[2]),Math.abs(af.vector[3]))||1);af.vector[2]*=ag;af.vector[3]*=ag;if(af.vector[2]<0){af.vector[0]=-af.vector[2];af.vector[2]=0;}if(af.vector[3]<0){af.vector[1]=-af.vector[3];af.vector[3]=0;}af.vector[0]=af.vector[0];af.vector[1]=af.vector[1];af.vector[2]=af.vector[2];af.vector[3]=af.vector[3];for(var ac=0,ai=ah.length;ac<ai;ac++){var e={},ae=ah[ac].match(/^([^:]*):?([\d\.]*)/);e.color=f.getRGB(ae[1]).hex;ae[2]&&(e.offset=ae[2]+"%");af.dots.push(e);}for(var ac=1,ai=af.dots.length-1;ac<ai;ac++){if(!af.dots[ac].offset){var R=parseFloat(af.dots[ac-1].offset||0),aa=false;for(var ab=ac+1;ab<ai;ab++){if(af.dots[ab].offset){aa=af.dots[ab].offset;break;}}if(!aa){aa=100;ab=ai;}aa=parseFloat(aa);var ad=(aa-R)/(ab-ac+1);for(;ac<ab;ac++){R+=ad;af.dots[ac].offset=R+"%";}}}return af;}else{return ah;}}),G=function(){var R,i,aa,Z,e;if(f.is(arguments[0],"string")||f.is(arguments[0],"object")){if(f.is(arguments[0],"string")){R=g.getElementById(arguments[0]);}else{R=arguments[0];}if(R.tagName){if(arguments[1]==null){return{container:R,width:R.style.pixelWidth||R.offsetWidth,height:R.style.pixelHeight||R.offsetHeight};}else{return{container:R,width:arguments[1],height:arguments[2]};}}}else{if(f.is(arguments[0],"number")&&arguments.length>3){return{container:1,x:arguments[0],y:arguments[1],width:arguments[2],height:arguments[3]};}}},a=function(e,R){var i=this;for(var Z in R){if(R.hasOwnProperty(Z)&&!(Z in e)){switch(typeof R[Z]){case"function":(function(aa){e[Z]=e===i?aa:function(){return aa.apply(i,arguments);};})(R[Z]);break;case"object":e[Z]=e[Z]||{};a.call(this,e[Z],R[Z]);break;default:e[Z]=R[Z];break;}}}};if(f.svg){b.svgns="http://www.w3.org/2000/svg";b.xlink="http://www.w3.org/1999/xlink";var N=function(e){return +e+(Math.floor(e)==e)*0.5;};var z=function(ab){for(var R=0,Z=ab.length;R<Z;R++){if(ab[R][0].toLowerCase()!="a"){for(var e=1,aa=ab[R].length;e<aa;e++){ab[R][e]=N(ab[R][e]);}}else{ab[R][6]=N(ab[R][6]);ab[R][7]=N(ab[R][7]);}}return ab;};var B=function(R,e){if(e){for(var i in e){if(e.hasOwnProperty(i)){R.setAttribute(i,e[i]);}}}else{return g.createElementNS(b.svgns,R);}};f.toString=function(){return"Your browser supports SVG.\nYou are running Rapha\u00ebl "+this.version;};var W=function(e,Z){var i=B("path");Z.canvas&&Z.canvas.appendChild(i);var R=new m(i,Z);R.type="path";F(R,{fill:"none",stroke:"#000",path:e});return R;};var M=function(ad,ab,ae){ab=n(ab);var aa=B((ab.type||"linear")+"Gradient");aa.id="r"+(f.idGenerator++).toString(36);if(ab.vector&&ab.vector.length){B(aa,{x1:ab.vector[0],y1:ab.vector[1],x2:ab.vector[2],y2:ab.vector[3]});}ae.defs.appendChild(aa);var ac=true;for(var R=0,Z=ab.dots.length;R<Z;R++){var e=B("stop");if(ab.dots[R].offset){ac=false;}B(e,{offset:ab.dots[R].offset?ab.dots[R].offset:(R==0)?"0%":"100%","stop-color":f.getRGB(ab.dots[R].color).hex||"#fff"});aa.appendChild(e);}if(ac&&ab.dots[Z-1].opacity!=null){B(e,{"stop-opacity":ab.dots[Z-1].opacity});}B(ad,{fill:"url(#"+aa.id+")",opacity:1,"fill-opacity":1});ad.style.fill="";ad.style.opacity=1;ad.style.fillOpacity=1;};var s=function(i){var e=i.getBBox();B(i.pattern,{patternTransform:f.format("translate({0},{1})",e.x,e.y)});};var F=function(ah,aq){var ak={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},am=ah.node,ai=ah.attrs,ae=ah.attr("rotation"),ab=function(ay,ax){ax=ak[(ax+"").toLowerCase()];if(ax){var av=ay.attrs["stroke-width"]||"1",at={round:av,square:av,butt:0}[ay.attrs["stroke-linecap"]||aq["stroke-linecap"]]||0,aw=[];var au=ax.length;while(au--){aw[au]=ax[au]*av+((au%2)?1:-1)*at;}B(am,{"stroke-dasharray":aw.join(",")});}};parseFloat(ae)&&ah.rotate(0,true);for(var al in aq){if(aq.hasOwnProperty(al)){if(!(al in q)){continue;}var aj=aq[al];ai[al]=aj;switch(al){case"href":case"title":case"target":var ao=am.parentNode;if(ao.tagName.toLowerCase()!="a"){var Z=B("a");ao.insertBefore(Z,am);Z.appendChild(am);ao=Z;}ao.setAttributeNS(ah.paper.xlink,al,aj);break;case"clip-rect":var i=(aj+"").split(Y);if(i.length==4){ah.clip&&ah.clip.parentNode.parentNode.removeChild(ah.clip.parentNode);var R=B("clipPath"),an=B("rect");R.id="r"+(f.idGenerator++).toString(36);B(an,{x:i[0],y:i[1],width:i[2],height:i[3]});R.appendChild(an);ah.paper.defs.appendChild(R);B(am,{"clip-path":"url(#"+R.id+")"});ah.clip=an;}if(!aj){var ap=g.getElementById(am.getAttribute("clip-path").replace(/(^url\(#|\)$)/g,""));ap&&ap.parentNode.removeChild(ap);B(am,{"clip-path":""});delete ah.clip;}break;case"path":if(aj&&ah.type=="path"){ai.path=z(w(aj));B(am,{d:ai.path});}case"width":am.setAttribute(al,aj);if(ai.fx){al="x";aj=ai.x;}else{break;}case"x":if(ai.fx){aj=-ai.x-(ai.width||0);}case"rx":if(al=="rx"&&ah.type=="rect"){break;}case"cx":am.setAttribute(al,aj);ah.pattern&&s(ah);break;case"height":am.setAttribute(al,aj);if(ai.fy){al="y";aj=ai.y;}else{break;}case"y":if(ai.fy){aj=-ai.y-(ai.height||0);}case"ry":if(al=="ry"&&ah.type=="rect"){break;}case"cy":am.setAttribute(al,aj);ah.pattern&&s(ah);break;case"r":if(ah.type=="rect"){B(am,{rx:aj,ry:aj});}else{am.setAttribute(al,aj);}break;case"src":if(ah.type=="image"){am.setAttributeNS(ah.paper.xlink,"href",aj);}break;case"stroke-width":am.style.strokeWidth=aj;am.setAttribute(al,aj);if(ai["stroke-dasharray"]){ab(ah,ai["stroke-dasharray"]);}break;case"stroke-dasharray":ab(ah,aj);break;case"rotation":ae=aj;ah.rotate(aj,true);break;case"translation":var ac=(aj+"").split(Y);ah.translate((+ac[0]+1||2)-1,(+ac[1]+1||2)-1);break;case"scale":var ac=(aj+"").split(Y);ah.scale(+ac[0]||1,+ac[1]||+ac[0]||1,+ac[2]||null,+ac[3]||null);break;case"fill":var aa=(aj+"").match(/^url\(['"]?([^\)]+)['"]?\)$/i);if(aa){var R=B("pattern"),ag=B("image");R.id="r"+(f.idGenerator++).toString(36);B(R,{x:0,y:0,patternUnits:"userSpaceOnUse"});B(ag,{x:0,y:0});ag.setAttributeNS(ah.paper.xlink,"href",aa[1]);R.appendChild(ag);var ar=g.createElement("img");ar.style.position="absolute";ar.style.top="-9999em";ar.style.left="-9999em";ar.onload=function(){B(R,{width:this.offsetWidth,height:this.offsetHeight});B(ag,{width:this.offsetWidth,height:this.offsetHeight});g.body.removeChild(this);b.safari();};g.body.appendChild(ar);ar.src=aa[1];ah.paper.defs.appendChild(R);am.style.fill="url(#"+R.id+")";B(am,{fill:"url(#"+R.id+")"});ah.pattern=R;ah.pattern&&s(ah);break;}delete aq.gradient;delete ai.gradient;if(!f.is(ai.opacity,"undefined")&&f.is(aq.opacity,"undefined")){am.style.opacity=ai.opacity;B(am,{opacity:ai.opacity});}if(!f.is(ai["fill-opacity"],"undefined")&&f.is(aq["fill-opacity"],"undefined")){am.style.fillOpacity=ai["fill-opacity"];B(am,{"fill-opacity":ai["fill-opacity"]});}case"stroke":am.style[al]=f.getRGB(aj).hex;am.setAttribute(al,f.getRGB(aj).hex);break;case"gradient":M(am,aj,ah.paper);break;case"opacity":case"fill-opacity":if(ai.gradient){var e=g.getElementById(am.getAttribute("fill").replace(/^url\(#|\)$/g,""));if(e){var ad=e.getElementsByTagName("stop");ad[ad.length-1].setAttribute("stop-opacity",aj);}break;}default:al=="font-size"&&(aj=parseInt(aj,10)+"px");var af=al.replace(/(\-.)/g,function(at){return at.substring(1).toUpperCase();});am.style[af]=aj;am.setAttribute(al,aj);break;}}}T(ah,aq);parseInt(ae,10)&&ah.rotate(ae,true);};var K=1.2;var T=function(e,aa){if(e.type!="text"||!("text" in aa||"font" in aa||"font-size" in aa||"x" in aa||"y" in aa)){return;}var af=e.attrs,R=e.node,ah=R.firstChild?parseInt(g.defaultView.getComputedStyle(R.firstChild,"").getPropertyValue("font-size"),10):10;if("text" in aa){while(R.firstChild){R.removeChild(R.firstChild);}var Z=(aa.text+"").split("\n");for(var ab=0,ag=Z.length;ab<ag;ab++){var ad=B("tspan");ab&&B(ad,{dy:ah*K,x:af.x});ad.appendChild(g.createTextNode(Z[ab]));R.appendChild(ad);}}else{var Z=R.getElementsByTagName("tspan");for(var ab=0,ag=Z.length;ab<ag;ab++){ab&&B(Z[ab],{dy:ah*K,x:af.x});}}B(R,{y:af.y});var ac=e.getBBox(),ae=af.y-(ac.y+ac.height/2);ae&&B(R,{y:af.y+ae});};var m=function(i,e){var Z=0,R=0;this[0]=i;this.node=i;this.paper=e;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};};m.prototype.rotate=function(i,e,Z){if(i==null){if(this._.rt.cx){return[this._.rt.deg,this._.rt.cx,this._.rt.cy].join(" ");}return this._.rt.deg;}var R=this.getBBox();i=(i+"").split(Y);if(i.length-1){e=parseFloat(i[1]);Z=parseFloat(i[2]);}i=parseFloat(i[0]);if(e!=null){this._.rt.deg=i;}else{this._.rt.deg+=i;}(Z==null)&&(e=null);this._.rt.cx=e;this._.rt.cy=Z;e=e==null?R.x+R.width/2:e;Z=Z==null?R.y+R.height/2:Z;if(this._.rt.deg){this.transformations[0]=f.format("rotate({0} {1} {2})",this._.rt.deg,e,Z);this.clip&&B(this.clip,{transform:f.format("rotate({0} {1} {2})",-this._.rt.deg,e,Z)});}else{this.transformations[0]="";this.clip&&B(this.clip,{transform:""});}B(this.node,{transform:this.transformations.join(" ")});return this;};m.prototype.hide=function(){this.node.style.display="none";return this;};m.prototype.show=function(){this.node.style.display="block";return this;};m.prototype.remove=function(){this.node.parentNode.removeChild(this.node);};m.prototype.getBBox=function(){if(this.type=="path"){return C(this.attrs.path);}if(this.node.style.display=="none"){this.show();var Z=true;}var ad={};try{ad=this.node.getBBox();}catch(ab){}finally{ad=ad||{};}if(this.type=="text"){ad={x:ad.x,y:Infinity,width:ad.width,height:0};for(var R=0,aa=this.node.getNumberOfChars();R<aa;R++){var ac=this.node.getExtentOfChar(R);(ac.y<ad.y)&&(ad.y=ac.y);(ac.y+ac.height-ad.y>ad.height)&&(ad.height=ac.y+ac.height-ad.y);}}Z&&this.hide();return ad;};m.prototype.attr=function(){if(arguments.length==1&&f.is(arguments[0],"string")){if(arguments[0]=="translation"){return this.translate();}if(arguments[0]=="rotation"){return this.rotate();}if(arguments[0]=="scale"){return this.scale();}return this.attrs[arguments[0]];}if(arguments.length==1&&f.is(arguments[0],"array")){var e={};for(var i in arguments[0]){if(arguments[0].hasOwnProperty(i)){e[arguments[0][i]]=this.attrs[arguments[0][i]];}}return e;}if(arguments.length==2){var R={};R[arguments[0]]=arguments[1];F(this,R);}else{if(arguments.length==1&&f.is(arguments[0],"object")){F(this,arguments[0]);}}return this;};m.prototype.toFront=function(){this.node.parentNode.appendChild(this.node);return this;};m.prototype.toBack=function(){if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);}return this;};m.prototype.insertAfter=function(e){if(e.node.nextSibling){e.node.parentNode.insertBefore(this.node,e.node.nextSibling);}else{e.node.parentNode.appendChild(this.node);}return this;};m.prototype.insertBefore=function(e){var i=e.node;i.parentNode.insertBefore(this.node,i);return this;};m.prototype.blur=function(e){if(e!="none"){var i=B("filter"),R=B("feGaussianBlur");i.id="r"+(f.idGenerator++).toString(36);B(R,{stdDeviation:+e||1.5});i.appendChild(R);this.paper.defs.appendChild(i);this._blur=i;B(this.node,{filter:"url(#"+i.id+")"});}else{if(this._blur){this._blur.parentNode.removeChild(this._blur);delete this._blur;}this.node.removeAttribute("filter");}};var D=function(i,e,ab,aa){e=N(e);ab=N(ab);var Z=B("circle");i.canvas&&i.canvas.appendChild(Z);var R=new m(Z,i);R.attrs={cx:e,cy:ab,r:aa,fill:"none",stroke:"#000"};R.type="circle";B(Z,R.attrs);return R;};var I=function(R,e,ad,i,ab,ac){e=N(e);ad=N(ad);var aa=B("rect");R.canvas&&R.canvas.appendChild(aa);var Z=new m(aa,R);Z.attrs={x:e,y:ad,width:i,height:ab,r:ac||0,rx:ac||0,ry:ac||0,fill:"none",stroke:"#000"};Z.type="rect";B(aa,Z.attrs);return Z;};var h=function(i,e,ac,ab,aa){e=N(e);ac=N(ac);var Z=B("ellipse");i.canvas&&i.canvas.appendChild(Z);var R=new m(Z,i);R.attrs={cx:e,cy:ac,rx:ab,ry:aa,fill:"none",stroke:"#000"};R.type="ellipse";B(Z,R.attrs);return R;};var p=function(R,ac,e,ad,i,ab){var aa=B("image");B(aa,{x:e,y:ad,width:i,height:ab,preserveAspectRatio:"none"});aa.setAttributeNS(R.xlink,"href",ac);R.canvas&&R.canvas.appendChild(aa);var Z=new m(aa,R);Z.attrs={x:e,y:ad,width:i,height:ab,src:ac};Z.type="image";return Z;};var H=function(i,e,ab,aa){var Z=B("text");B(Z,{x:e,y:ab,"text-anchor":"middle"});i.canvas&&i.canvas.appendChild(Z);var R=new m(Z,i);R.attrs={x:e,y:ab,"text-anchor":"middle",text:aa,font:q.font,stroke:"none",fill:"#000"};R.type="text";F(R,R.attrs);return R;};var E=function(i,e){this.width=i||this.width;this.height=e||this.height;this.canvas.setAttribute("width",this.width);this.canvas.setAttribute("height",this.height);return this;};var l=function(){var aa=G.apply(null,arguments),R=aa.container,ac=aa.x,ab=aa.y,Z=aa.width,ad=aa.height;if(!R){throw new Error("SVG container not found.");}b.canvas=B("svg");var e=b.canvas,ae=e.style;e.setAttribute("width",Z||512);b.width=Z||512;e.setAttribute("height",ad||342);b.height=ad||342;if(R==1){g.body.appendChild(e);ae.position="absolute";ae.left=ac+"px";ae.top=ab+"px";}else{if(R.firstChild){R.insertBefore(e,R.firstChild);}else{R.appendChild(e);}}R={canvas:e,clear:function(){while(this.canvas.firstChild){this.canvas.removeChild(this.canvas.firstChild);}this.desc=B("desc");this.defs=B("defs");this.desc.appendChild(g.createTextNode("Created with Rapha\u00ebl"));this.canvas.appendChild(this.desc);this.canvas.appendChild(this.defs);}};for(var i in b){if(b.hasOwnProperty(i)){if(i!="create"){R[i]=b[i];}}}a.call(R,R,f.fn);R.clear();R.raphael=f;return R;};b.remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);};if({"Apple Computer, Inc.":1,"Google Inc.":1}[navigator.vendor]){b.safari=function(){var e=this.rect(-99,-99,this.width+99,this.height+99);setTimeout(function(){e.remove();});};}else{b.safari=function(){};}}if(f.vml){var y=function(ac){var aa=O(ac);for(var R=0,Z=aa.length;R<Z;R++){aa[R][0]=(aa[R][0]+"").toLowerCase();aa[R][0]=="z"&&(aa[R][0]="x");for(var e=1,ab=aa[R].length;e<ab;e++){aa[R][e]=Math.round(aa[R][e]);}}return(aa+"");};f.toString=function(){return"Your browser doesn\u2019t support SVG. Assuming it is Internet Explorer and falling down to VML.\nYou are running Rapha\u00ebl "+this.version;};var W=function(e,ab){var Z=V("group"),ac=Z.style;ac.position="absolute";ac.left=0;ac.top=0;ac.width=ab.width+"px";ac.height=ab.height+"px";Z.coordsize=ab.coordsize;Z.coordorigin=ab.coordorigin;var R=V("shape"),i=R.style;i.width=ab.width+"px";i.height=ab.height+"px";R.path="";R.coordsize=this.coordsize;R.coordorigin=this.coordorigin;Z.appendChild(R);var aa=new m(R,Z,ab);aa.isAbsolute=true;aa.type="path";aa.path=[];aa.Path="";if(e){aa.attrs.path=f.parsePathString(e);aa.node.path=y(aa.attrs.path);}F(aa,{fill:"none",stroke:"#000"});aa.setBox();ab.canvas.appendChild(Z);return aa;};var F=function(af,aj){af.attrs=af.attrs||{};var ah=af.node,ak=af.attrs,ac=ah.style,Z,ao=af;for(var ad in aj){if(aj.hasOwnProperty(ad)){ak[ad]=aj[ad];}}aj.href&&(ah.href=aj.href);aj.title&&(ah.title=aj.title);aj.target&&(ah.target=aj.target);if(aj.path&&af.type=="path"){ak.path=f.parsePathString(aj.path);ah.path=y(ak.path);}if(aj.rotation!=null){af.rotate(aj.rotation,true);}if(aj.translation){Z=(aj.translation+"").split(Y);af.translate(Z[0],Z[1]);}if(aj.scale){Z=(aj.scale+"").split(Y);af.scale(+Z[0]||1,+Z[1]||+Z[0]||1,+Z[2]||null,+Z[3]||null);}if("clip-rect" in aj){var e=(aj["clip-rect"]+"").split(Y);if(e.length==4){e[2]=+e[2]+(+e[0]);e[3]=+e[3]+(+e[1]);var ae=ah.clipRect||g.createElement("div"),an=ae.style,ab=ah.parentNode;an.clip=f.format("rect({0}px {2}px {3}px {1}px)",e);if(!ah.clipRect){an.position="absolute";an.top=0;an.left=0;an.width=af.paper.width+"px";an.height=af.paper.height+"px";ab.parentNode.insertBefore(ae,ab);ae.appendChild(ab);ah.clipRect=ae;}}if(!aj["clip-rect"]){ah.clipRect&&(ah.clipRect.style.clip="");}}if(af.type=="image"&&aj.src){ah.src=aj.src;}if(af.type=="image"&&aj.opacity){ah.filterOpacity=" progid:DXImageTransform.Microsoft.Alpha(opacity="+(aj.opacity*100)+")";ac.filter=(ah.filterMatrix||"")+(ah.filterOpacity||"");}aj.font&&(ac.font=aj.font);aj["font-family"]&&(ac.fontFamily='"'+aj["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,"")+'"');aj["font-size"]&&(ac.fontSize=aj["font-size"]);aj["font-weight"]&&(ac.fontWeight=aj["font-weight"]);aj["font-style"]&&(ac.fontStyle=aj["font-style"]);if(aj.opacity!=null||aj["stroke-width"]!=null||aj.fill!=null||aj.stroke!=null||aj["stroke-width"]!=null||aj["stroke-opacity"]!=null||aj["fill-opacity"]!=null||aj["stroke-dasharray"]!=null||aj["stroke-miterlimit"]!=null||aj["stroke-linejoin"]!=null||aj["stroke-linecap"]!=null){ah=af.shape||ah;var ai=(ah.getElementsByTagName("fill")&&ah.getElementsByTagName("fill")[0]),al=false;!ai&&(al=ai=V("fill"));if("fill-opacity" in aj||"opacity" in aj){var i=((+ak["fill-opacity"]+1||2)-1)*((+ak.opacity+1||2)-1);i<0&&(i=0);i>1&&(i=1);ai.opacity=i;}aj.fill&&(ai.on=true);if(ai.on==null||aj.fill=="none"){ai.on=false;}if(ai.on&&aj.fill){var R=aj.fill.match(/^url\(([^\)]+)\)$/i);if(R){ai.src=R[1];ai.type="tile";}else{ai.color=f.getRGB(aj.fill).hex;ai.src="";ai.type="solid";}}al&&ah.appendChild(ai);var aa=(ah.getElementsByTagName("stroke")&&ah.getElementsByTagName("stroke")[0]),am=false;!aa&&(am=aa=V("stroke"));if((aj.stroke&&aj.stroke!="none")||aj["stroke-width"]||aj["stroke-opacity"]!=null||aj["stroke-dasharray"]||aj["stroke-miterlimit"]||aj["stroke-linejoin"]||aj["stroke-linecap"]){aa.on=true;}(aj.stroke=="none"||aa.on==null||aj.stroke==0||aj["stroke-width"]==0)&&(aa.on=false);aa.on&&aj.stroke&&(aa.color=f.getRGB(aj.stroke).hex);var i=((+ak["stroke-opacity"]+1||2)-1)*((+ak.opacity+1||2)-1);i<0&&(i=0);i>1&&(i=1);aa.opacity=i;aj["stroke-linejoin"]&&(aa.joinstyle=aj["stroke-linejoin"]||"miter");aa.miterlimit=aj["stroke-miterlimit"]||8;aj["stroke-linecap"]&&(aa.endcap={butt:"flat",square:"square",round:"round"}[aj["stroke-linecap"]]||"miter");aj["stroke-width"]&&(aa.weight=(parseFloat(aj["stroke-width"])||1)*12/16);if(aj["stroke-dasharray"]){var ag={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};aa.dashstyle=ag[aj["stroke-dasharray"]]||"";}am&&ah.appendChild(aa);}if(ao.type=="text"){var ac=b.span.style;ak.font&&(ac.font=ak.font);ak["font-family"]&&(ac.fontFamily=ak["font-family"]);ak["font-size"]&&(ac.fontSize=ak["font-size"]);ak["font-weight"]&&(ac.fontWeight=ak["font-weight"]);ak["font-style"]&&(ac.fontStyle=ak["font-style"]);b.span.innerHTML=ao.node.string.replace(/</g,"&#60;").replace(/&/g,"&#38;").replace(/\n/g,"<br>");ao.W=ak.w=b.span.offsetWidth;ao.H=ak.h=b.span.offsetHeight;ao.X=ak.x;ao.Y=ak.y+Math.round(ao.H/2);switch(ak["text-anchor"]){case"start":ao.node.style["v-text-align"]="left";ao.bbx=Math.round(ao.W/2);break;case"end":ao.node.style["v-text-align"]="right";ao.bbx=-Math.round(ao.W/2);break;default:ao.node.style["v-text-align"]="center";break;}}};var o=function(i,e,aa,Z){var R=Math.round(Math.atan((parseFloat(aa)-parseFloat(i))/(parseFloat(Z)-parseFloat(e)))*57.29)||0;if(!R&&parseFloat(i)<parseFloat(e)){R=180;}R-=180;if(R<0){R+=360;}return R;};var M=function(ad,ac){ac=n(ac);ad.attrs=ad.attrs||{};var R=ad.attrs,ab=ad.node.getElementsByTagName("fill");ad.attrs.gradient=ac;ad=ad.shape||ad.node;if(ab.length){ab=ab[0];}else{ab=V("fill");}if(ac.dots.length){ab.on=true;ab.method="none";ab.type=((ac.type+"").toLowerCase()=="radial")?"gradientTitle":"gradient";if(!f.is(ac.dots[0].color,"undefined")){ab.color=f.getRGB(ac.dots[0].color).hex;}if(!f.is(ac.dots[ac.dots.length-1].color,"undefined")){ab.color2=f.getRGB(ac.dots[ac.dots.length-1].color).hex;}var ae=[];for(var Z=0,aa=ac.dots.length;Z<aa;Z++){if(ac.dots[Z].offset){ae.push(ac.dots[Z].offset+" "+f.getRGB(ac.dots[Z].color).hex);}}var e=f.is(ac.dots[ac.dots.length-1].opacity,"undefined")?(f.is(R.opacity,"undefined")?1:R.opacity):ac.dots[ac.dots.length-1].opacity;if(ae.length){ab.colors.value=ae.join(",");e=f.is(R.opacity,"undefined")?1:R.opacity;}else{ab.colors&&(ab.colors.value="0% "+ab.color);}ab.opacity=e;if(!f.is(ac.angle,"undefined")){ab.angle=(-ac.angle+270)%360;}else{if(ac.vector){ab.angle=o.apply(null,ac.vector);}}if((ac.type+"").toLowerCase()=="radial"){ab.focus="100%";ab.focusposition="0.5 0.5";}}};var m=function(aa,ac,e){var ab=0,R=0,i=0,Z=1;this[0]=aa;this.node=aa;this.X=0;this.Y=0;this.attrs={};this.Group=ac;this.paper=e;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};};m.prototype.rotate=function(i,e,R){if(i==null){if(this._.rt.cx){return[this._.rt.deg,this._.rt.cx,this._.rt.cy].join(" ");}return this._.rt.deg;}i=(i+"").split(Y);if(i.length-1){e=parseFloat(i[1]);R=parseFloat(i[2]);}i=parseFloat(i[0]);if(e!=null){this._.rt.deg=i;}else{this._.rt.deg+=i;}(R==null)&&(e=null);this._.rt.cx=e;this._.rt.cy=R;this.setBox(this.attrs,e,R);this.Group.style.rotation=this._.rt.deg;return this;};m.prototype.setBox=function(ab,ac,aa){var R=this.Group.style,ad=(this.shape&&this.shape.style)||this.node.style;ab=ab||{};for(var ae in ab){if(ab.hasOwnProperty(ae)){this.attrs[ae]=ab[ae];}}ac=ac||this._.rt.cx;aa=aa||this._.rt.cy;var ah=this.attrs,ak,aj,al,ag;switch(this.type){case"circle":ak=ah.cx-ah.r;aj=ah.cy-ah.r;al=ag=ah.r*2;break;case"ellipse":ak=ah.cx-ah.rx;aj=ah.cy-ah.ry;al=ah.rx*2;ag=ah.ry*2;break;case"rect":case"image":ak=ah.x;aj=ah.y;al=ah.width||0;ag=ah.height||0;break;case"text":this.textpath.v=["m",Math.round(ah.x),", ",Math.round(ah.y-2),"l",Math.round(ah.x)+1,", ",Math.round(ah.y-2)].join("");ak=ah.x-Math.round(this.W/2);aj=ah.y-this.H/2;al=this.W;ag=this.H;break;case"path":if(!this.attrs.path){ak=0;aj=0;al=this.paper.width;ag=this.paper.height;}else{var af=C(this.attrs.path);ak=af.x;aj=af.y;al=af.width;ag=af.height;}break;default:ak=0;aj=0;al=this.paper.width;ag=this.paper.height;break;}ac=(ac==null)?ak+al/2:ac;aa=(aa==null)?aj+ag/2:aa;var Z=ac-this.paper.width/2,ai=aa-this.paper.height/2;if(this.type=="path"||this.type=="text"){(R.left!=Z+"px")&&(R.left=Z+"px");(R.top!=ai+"px")&&(R.top=ai+"px");this.X=this.type=="text"?ak:-Z;this.Y=this.type=="text"?aj:-ai;this.W=al;this.H=ag;(ad.left!=-Z+"px")&&(ad.left=-Z+"px");(ad.top!=-ai+"px")&&(ad.top=-ai+"px");}else{(R.left!=Z+"px")&&(R.left=Z+"px");(R.top!=ai+"px")&&(R.top=ai+"px");this.X=ak;this.Y=aj;this.W=al;this.H=ag;(R.width!=this.paper.width+"px")&&(R.width=this.paper.width+"px");(R.height!=this.paper.height+"px")&&(R.height=this.paper.height+"px");(ad.left!=ak-Z+"px")&&(ad.left=ak-Z+"px");(ad.top!=aj-ai+"px")&&(ad.top=aj-ai+"px");(ad.width!=al+"px")&&(ad.width=al+"px");(ad.height!=ag+"px")&&(ad.height=ag+"px");var am=(+ab.r||0)/(Math.min(al,ag));if(this.type=="rect"&&this.arcsize!=am&&(am||this.arcsize)){var e=V(am?"roundrect":"rect");e.arcsize=am;this.Group.appendChild(e);this.node.parentNode.removeChild(this.node);this.node=e;this.arcsize=am;F(this,this.attrs);this.setBox(this.attrs);}}};m.prototype.hide=function(){this.Group.style.display="none";return this;};m.prototype.show=function(){this.Group.style.display="block";return this;};m.prototype.getBBox=function(){if(this.type=="path"){return C(this.attrs.path);}return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H};};m.prototype.remove=function(){this[0].parentNode.removeChild(this[0]);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);};m.prototype.attr=function(){if(arguments.length==1&&f.is(arguments[0],"string")){if(arguments[0]=="translation"){return this.translate();}if(arguments[0]=="rotation"){return this.rotate();}if(arguments[0]=="scale"){return this.scale();}return this.attrs[arguments[0]];}if(this.attrs&&arguments.length==1&&f.is(arguments[0],"array")){var e={};for(var R=0,Z=arguments[0].length;R<Z;R++){e[arguments[0][R]]=this.attrs[arguments[0][R]];}return e;}var aa;if(arguments.length==2){aa={};aa[arguments[0]]=arguments[1];}if(arguments.length==1&&f.is(arguments[0],"object")){aa=arguments[0];}if(aa){if(aa.gradient){M(this,aa.gradient);}if(aa.text&&this.type=="text"){this.node.string=aa.text;}F(this,aa);this.setBox(this.attrs);}return this;};m.prototype.toFront=function(){this.Group.parentNode.appendChild(this.Group);return this;};m.prototype.toBack=function(){if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);}return this;};m.prototype.insertAfter=function(e){if(e.Group.nextSibling){e.Group.parentNode.insertBefore(this.Group,e.Group.nextSibling);}else{e.Group.parentNode.appendChild(this.Group);}return this;};m.prototype.insertBefore=function(e){e.Group.parentNode.insertBefore(this.Group,e.Group);return this;};m.prototype.blur=function(e){var i=this.node.style,R=i.filter;R=R.replace(/progid:DXImageTransform\.Microsoft\.Blur\(pixelradius\=[^\)]+\)/g,"");if(e!="none"){i.filter=R+" progid:DXImageTransform.Microsoft.Blur(pixelradius="+(+e||1.5)+")";i.margin=f.format("-{0}px 0 0 -{0}px",Math.round(+e||1.5));}else{i.filter=R;i.margin=0;}};var D=function(i,ae,ad,e){var aa=V("group"),Z=aa.style,R=V("oval"),ac=R.style;Z.position="absolute";Z.left=0;Z.top=0;Z.width=i.width+"px";Z.height=i.height+"px";aa.coordsize=i.coordsize;aa.coordorigin=i.coordorigin;aa.appendChild(R);var ab=new m(R,aa,i);ab.type="circle";F(ab,{stroke:"#000",fill:"none"});ab.attrs.cx=ae;ab.attrs.cy=ad;ab.attrs.r=e;ab.setBox({x:ae-e,y:ad-e,width:e*2,height:e*2});i.canvas.appendChild(aa);return ab;};var I=function(i,ae,ad,af,aa,e){var ab=V("group"),Z=ab.style,R=V(e?"roundrect":"rect"),ag=(+e||0)/(Math.min(af,aa));R.arcsize=ag;Z.position="absolute";Z.left=0;Z.top=0;Z.width=i.width+"px";Z.height=i.height+"px";ab.coordsize=i.coordsize;ab.coordorigin=i.coordorigin;ab.appendChild(R);var ac=new m(R,ab,i);ac.type="rect";F(ac,{stroke:"#000"});ac.arcsize=ag;ac.setBox({x:ae,y:ad,width:af,height:aa,r:+e});i.canvas.appendChild(ab);return ac;};var h=function(e,af,ae,R,i){var ab=V("group"),aa=ab.style,Z=V("oval"),ad=Z.style;aa.position="absolute";aa.left=0;aa.top=0;aa.width=e.width+"px";aa.height=e.height+"px";ab.coordsize=e.coordsize;ab.coordorigin=e.coordorigin;ab.appendChild(Z);var ac=new m(Z,ab,e);ac.type="ellipse";F(ac,{stroke:"#000"});ac.attrs.cx=af;ac.attrs.cy=ae;ac.attrs.rx=R;ac.attrs.ry=i;ac.setBox({x:af-R,y:ae-i,width:R*2,height:i*2});e.canvas.appendChild(ab);return ac;};var p=function(i,e,af,ae,ag,aa){var ab=V("group"),Z=ab.style,R=V("image"),ad=R.style;Z.position="absolute";Z.left=0;Z.top=0;Z.width=i.width+"px";Z.height=i.height+"px";ab.coordsize=i.coordsize;ab.coordorigin=i.coordorigin;R.src=e;ab.appendChild(R);var ac=new m(R,ab,i);ac.type="image";ac.attrs.src=e;ac.attrs.x=af;ac.attrs.y=ae;ac.attrs.w=ag;ac.attrs.h=aa;ac.setBox({x:af,y:ae,width:ag,height:aa});i.canvas.appendChild(ab);return ac;};var H=function(i,af,ae,ag){var ab=V("group"),aa=ab.style,Z=V("shape"),ad=Z.style,ah=V("path"),e=ah.style,R=V("textpath");aa.position="absolute";aa.left=0;aa.top=0;aa.width=i.width+"px";aa.height=i.height+"px";ab.coordsize=i.coordsize;ab.coordorigin=i.coordorigin;ah.v=["m",Math.round(af),", ",Math.round(ae),"l",Math.round(af)+1,", ",Math.round(ae)].join("");ah.textpathok=true;ad.width=i.width;ad.height=i.height;aa.position="absolute";aa.left=0;aa.top=0;aa.width=i.width;aa.height=i.height;R.string=ag;R.on=true;Z.appendChild(R);Z.appendChild(ah);ab.appendChild(Z);var ac=new m(R,ab,i);ac.shape=Z;ac.textpath=ah;ac.type="text";ac.attrs.text=ag;ac.attrs.x=af;ac.attrs.y=ae;ac.attrs.w=1;ac.attrs.h=1;F(ac,{font:q.font,stroke:"none",fill:"#000"});ac.setBox();i.canvas.appendChild(ab);return ac;};var E=function(R,e){var i=this.canvas.style;this.width=parseFloat(R||this.width);this.height=parseFloat(e||this.height);i.width=this.width+"px";i.height=this.height+"px";i.clip="rect(0 "+this.width+"px "+this.height+"px 0)";this.coordsize=this.width+" "+this.height;return this;};g.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!g.namespaces.rvml&&g.namespaces.add("rvml","urn:schemas-microsoft-com:vml");var V=function(e){return g.createElement("<rvml:"+e+' class="rvml">');};}catch(U){var V=function(e){return g.createElement("<"+e+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');};}var l=function(){var Z=G.apply(null,arguments),i=Z.container,ae=Z.height,af,R=Z.width,ad=Z.x,ac=Z.y;if(!i){throw new Error("VML container not found.");}var ab=b.canvas=g.createElement("div"),aa=ab.style;R=parseFloat(R)||"512px";ae=parseFloat(ae)||"342px";b.width=R;b.height=ae;b.coordsize=R+" "+ae;b.coordorigin="0 0";b.span=g.createElement("span");af=b.span.style;ab.appendChild(b.span);af.position="absolute";af.left="-99999px";af.top="-99999px";af.padding=0;af.margin=0;af.lineHeight=1;af.display="inline";aa.width=R+"px";aa.height=ae+"px";aa.position="absolute";aa.clip="rect(0 "+R+"px "+ae+"px 0)";if(i==1){g.body.appendChild(ab);aa.left=ad+"px";aa.top=ac+"px";i={style:{width:R,height:ae}};}else{i.style.width=R;i.style.height=ae;if(i.firstChild){i.insertBefore(ab,i.firstChild);}else{i.appendChild(ab);}}for(var e in b){if(b.hasOwnProperty(e)){i[e]=b[e];}}a.call(i,i,f.fn);i.clear=function(){while(ab.firstChild){ab.removeChild(ab.firstChild);}};i.raphael=f;return i;};b.remove=function(){this.canvas.parentNode.removeChild(this.canvas);};b.safari=function(){};}var j=(function(){if(g.addEventListener){return function(aa,R,i,e){var Z=function(ab){return i.call(e,ab);};aa.addEventListener(R,Z,false);return function(){aa.removeEventListener(R,Z,false);return true;};};}else{if(g.attachEvent){return function(ab,Z,R,i){var aa=function(ac){return R.call(i,ac||L.event);};ab.attachEvent("on"+Z,aa);var e=function(){ab.detachEvent("on"+Z,aa);return true;};if(Z=="mouseover"){ab.attachEvent("onmouseenter",aa);return function(){ab.detachEvent("onmouseenter",aa);return e();};}else{if(Z=="mouseout"){ab.attachEvent("onmouseleave",aa);return function(){ab.detachEvent("onmouseleave",aa);return e();};}}return e;};}}})();for(var Q=v.length;Q--;){(function(e){m.prototype[e]=function(i){if(f.is(i,"function")){this.events=this.events||{};this.events[e]=this.events[e]||{};this.events[e][i]=this.events[e][i]||[];this.events[e][i].push(j(this.shape||this.node,e,i,this));}return this;};m.prototype["un"+e]=function(i){this.events&&this.events[e]&&this.events[e][i]&&this.events[e][i].length&&this.events[e][i].shift()()&&!this.events[e][i].length&&delete this.events[e][i];};})(v[Q]);}b.circle=function(e,R,i){return D(this,e,R,i);};b.rect=function(e,aa,i,R,Z){return I(this,e,aa,i,R,Z);};b.ellipse=function(e,Z,R,i){return h(this,e,Z,R,i);};b.path=function(e){e&&!f.is(e,"string")&&!f.is(e[0],"array")&&(e+="");return W(f.format.apply(f,arguments),this);};b.image=function(Z,e,aa,i,R){return p(this,Z,e,aa,i,R);};b.text=function(e,R,i){return H(this,e,R,i);};b.set=function(e){arguments.length>1&&(e=Array.prototype.splice.call(arguments,0,arguments.length));return new k(e);};b.setSize=E;m.prototype.stop=function(){clearTimeout(this.animation_in_progress);return this;};m.prototype.scale=function(aj,ai,Z,R){if(aj==null&&ai==null){return{x:this._.sx,y:this._.sy,toString:function(){return this.x+" "+this.y;}};}ai=ai||aj;!+ai&&(ai=aj);var an,al,am,ak,aA=this.attrs;if(aj!=0){var ah=this.getBBox(),ae=ah.x+ah.width/2,ab=ah.y+ah.height/2,az=aj/this._.sx,ay=ai/this._.sy;Z=(+Z||Z==0)?Z:ae;R=(+R||R==0)?R:ab;var ag=Math.round(aj/Math.abs(aj)),ad=Math.round(ai/Math.abs(ai)),aq=this.node.style,aC=Z+(ae-Z)*ag*az,aB=R+(ab-R)*ad*ay;switch(this.type){case"rect":case"image":var af=aA.width*ag*az,ap=aA.height*ad*ay,ac=aC-af/2,aa=aB-ap/2;this.attr({width:af,height:ap,x:ac,y:aa});break;case"circle":case"ellipse":this.attr({rx:aA.rx*az,ry:aA.ry*ay,r:aA.r*az,cx:aC,cy:aB});break;case"path":var at=c(aA.path),au=true;for(var aw=0,ao=at.length;aw<ao;aw++){var ar=at[aw];if(ar[0].toUpperCase()=="M"&&au){continue;}else{au=false;}if(f.svg&&ar[0].toUpperCase()=="A"){ar[at[aw].length-2]*=az;ar[at[aw].length-1]*=ay;ar[1]*=az;ar[2]*=ay;ar[5]=+(ag+ad?!!+ar[5]:!+ar[5]);}else{for(var av=1,ax=ar.length;av<ax;av++){ar[av]*=(av%2)?az:ay;}}}var e=C(at),an=aC-e.x-e.width/2,al=aB-e.y-e.height/2;at=c(at);at[0][1]+=an;at[0][2]+=al;this.attr({path:at.join(" ")});break;}if(this.type in {text:1,image:1}&&(ag!=1||ad!=1)){if(this.transformations){this.transformations[2]="scale(".concat(ag,",",ad,")");this.node.setAttribute("transform",this.transformations.join(" "));an=(ag==-1)?-aA.x-(af||0):aA.x;al=(ad==-1)?-aA.y-(ap||0):aA.y;this.attr({x:an,y:al});aA.fx=ag-1;aA.fy=ad-1;}else{this.node.filterMatrix=" progid:DXImageTransform.Microsoft.Matrix(M11=".concat(ag,", M12=0, M21=0, M22=",ad,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");aq.filter=(this.node.filterMatrix||"")+(this.node.filterOpacity||"");}}else{if(this.transformations){this.transformations[2]="";this.node.setAttribute("transform",this.transformations.join(" "));aA.fx=0;aA.fy=0;}else{this.node.filterMatrix="";aq.filter=(this.node.filterMatrix||"")+(this.node.filterOpacity||"");}}aA.scale=[aj,ai,Z,R].join(" ");this._.sx=aj;this._.sy=ai;}return this;};f.easing_formulas={linear:function(e){return e;},"<":function(e){return Math.pow(e,3);},">":function(e){return Math.pow(e-1,3)+1;},"<>":function(e){e=e*2;if(e<1){return Math.pow(e,3)/2;}e-=2;return(Math.pow(e,3)+2)/2;},backIn:function(i){var e=1.70158;return i*i*((e+1)*i-e);},backOut:function(i){i=i-1;var e=1.70158;return i*i*((e+1)*i+e)+1;},elastic:function(R){if(R==0||R==1){return R;}var i=0.3,e=i/4;return Math.pow(2,-10*R)*Math.sin((R-e)*(2*Math.PI)/i)+1;},bounce:function(Z){var i=7.5625,R=2.75,e;if(Z<(1/R)){e=i*Z*Z;}else{if(Z<(2/R)){Z-=(1.5/R);e=i*Z*Z+0.75;}else{if(Z<(2.5/R)){Z-=(2.25/R);e=i*Z*Z+0.9375;}else{Z-=(2.625/R);e=i*Z*Z+0.984375;}}}return e;}};m.prototype.animate=function(at,aj,ai,aa){clearTimeout(this.animation_in_progress);if(f.is(ai,"function")||!ai){aa=ai||null;}var am={},R={},ag={},af={x:0,y:0};for(var ak in at){if(at.hasOwnProperty(ak)){if(ak in u){am[ak]=this.attr(ak);(am[ak]==null)&&(am[ak]=q[ak]);R[ak]=at[ak];switch(u[ak]){case"number":ag[ak]=(R[ak]-am[ak])/aj;break;case"colour":am[ak]=f.getRGB(am[ak]);var al=f.getRGB(R[ak]);ag[ak]={r:(al.r-am[ak].r)/aj,g:(al.g-am[ak].g)/aj,b:(al.b-am[ak].b)/aj};break;case"path":var ab=O(am[ak],R[ak]);am[ak]=ab[0];R[ak]=ab[1];ag[ak]=[];for(var ao=0,ae=am[ak].length;ao<ae;ao++){ag[ak][ao]=[0];for(var an=1,aq=am[ak][ao].length;an<aq;an++){ag[ak][ao][an]=(R[ak][ao][an]-am[ak][ao][an])/aj;}}break;case"csv":var e=(at[ak]+"").split(Y),ad=(am[ak]+"").split(Y);switch(ak){case"translation":am[ak]=[0,0];ag[ak]=[e[0]/aj,e[1]/aj];break;case"rotation":am[ak]=(ad[1]==e[1]&&ad[2]==e[2])?ad:[0,e[1],e[2]];ag[ak]=[(e[0]-am[ak][0])/aj,0,0];break;case"scale":at[ak]=e;am[ak]=(am[ak]+"").split(Y);ag[ak]=[(e[0]-am[ak][0])/aj,(e[1]-am[ak][1])/aj,0,0];break;case"clip-rect":am[ak]=(am[ak]+"").split(Y);ag[ak]=[];var ao=4;while(ao--){ag[ak][ao]=(e[ao]-am[ak][ao])/aj;}break;}R[ak]=e;}}}}var Z=+new Date,ah=0,ar=function(i){return +i>255?255:+i;},ac=this;(function ap(){var av=new Date-Z,aD={},au;if(av<aj){var aB=f.easing_formulas[ai]?f.easing_formulas[ai](av/aj):av/aj;for(var az in am){if(am.hasOwnProperty(az)){switch(u[az]){case"number":au=+am[az]+aB*aj*ag[az];break;case"colour":au="rgb("+[ar(Math.round(am[az].r+aB*aj*ag[az].r)),ar(Math.round(am[az].g+aB*aj*ag[az].g)),ar(Math.round(am[az].b+aB*aj*ag[az].b))].join(",")+")";break;case"path":au=[];for(var ax=0,aE=am[az].length;ax<aE;ax++){au[ax]=[am[az][ax][0]];for(var aw=1,ay=am[az][ax].length;aw<ay;aw++){au[ax][aw]=+am[az][ax][aw]+aB*aj*ag[az][ax][aw];}au[ax]=au[ax].join(" ");}au=au.join(" ");break;case"csv":switch(az){case"translation":var aC=ag[az][0]*(av-ah),aA=ag[az][1]*(av-ah);af.x+=aC;af.y+=aA;au=[aC,aA].join(" ");break;case"rotation":au=+am[az][0]+aB*aj*ag[az][0];am[az][1]&&(au+=","+am[az][1]+","+am[az][2]);break;case"scale":au=[+am[az][0]+aB*aj*ag[az][0],+am[az][1]+aB*aj*ag[az][1],(2 in at[az]?at[az][2]:""),(3 in at[az]?at[az][3]:"")].join(" ");break;case"clip-rect":au=[];var ax=4;while(ax--){au[ax]=+am[az][ax]+aB*aj*ag[az][ax];}break;}break;}aD[az]=au;}}ac.attr(aD);ac.animation_in_progress=setTimeout(ap);f.svg&&b.safari();}else{(af.x||af.y)&&ac.translate(-af.x,-af.y);ac.attr(at);clearTimeout(ac.animation_in_progress);f.svg&&b.safari();(f.is(aa,"function"))&&aa.call(ac);}ah=av;})();return this;};m.prototype.translate=function(e,R){if(e==null){return{x:this._.tx,y:this._.ty};}this._.tx+=+e;this._.ty+=+R;switch(this.type){case"circle":case"ellipse":this.attr({cx:+e+this.attrs.cx,cy:+R+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+e+this.attrs.x,y:+R+this.attrs.y});break;case"path":var i=c(this.attrs.path);i[0][1]+=+e;i[0][2]+=+R;this.attr({path:i});break;}return this;};var k=function(e){this.items=[];this.length=0;if(e){for(var R=0,Z=e.length;R<Z;R++){if(e[R]&&(e[R].constructor==m||e[R].constructor==k)){this[this.items.length]=this.items[this.items.length]=e[R];this.length++;}}}};k.prototype.push=function(){var aa,e;for(var R=0,Z=arguments.length;R<Z;R++){aa=arguments[R];if(aa&&(aa.constructor==m||aa.constructor==k)){e=this.items.length;this[e]=this.items[e]=aa;this.length++;}}return this;};k.prototype.pop=function(){delete this[this.length--];return this.items.pop();};for(var S in m.prototype){if(m.prototype.hasOwnProperty(S)){k.prototype[S]=(function(e){return function(){for(var R=0,Z=this.items.length;R<Z;R++){this.items[R][e].apply(this.items[R],arguments);}return this;};})(S);}}k.prototype.attr=function(R,ac){if(R&&f.is(R,"array")&&f.is(R[0],"object")){for(var e=0,ab=R.length;e<ab;e++){this.items[e].attr(R[e]);}}else{for(var Z=0,aa=this.items.length;Z<aa;Z++){this.items[Z].attr.apply(this.items[Z],arguments);}}return this;};k.prototype.getBBox=function(){var e=[],ac=[],R=[],aa=[];for(var Z=this.items.length;Z--;){var ab=this.items[Z].getBBox();e.push(ab.x);ac.push(ab.y);R.push(ab.x+ab.width);aa.push(ab.y+ab.height);}e=Math.min.apply(Math,e);ac=Math.min.apply(Math,ac);return{x:e,y:ac,width:Math.max.apply(Math,R)-e,height:Math.max.apply(Math,aa)-ac};};f.registerFont=function(i){if(!i.face){return i;}this.fonts=this.fonts||{};var Z={w:i.w,face:{},glyphs:{}},R=i.face["font-family"];for(var ac in i.face){if(i.face.hasOwnProperty(ac)){Z.face[ac]=i.face[ac];}}if(this.fonts[R]){this.fonts[R].push(Z);}else{this.fonts[R]=[Z];}if(!i.svg){Z.face["units-per-em"]=parseInt(i.face["units-per-em"],10);for(var aa in i.glyphs){if(i.glyphs.hasOwnProperty(aa)){var ab=i.glyphs[aa];Z.glyphs[aa]={w:ab.w,k:{},d:ab.d&&"M"+ab.d.replace(/[mlcxtrv]/g,function(ad){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[ad]||"M";})+"z"};if(ab.k){for(var e in ab.k){if(ab.khasOwnProperty(e)){Z.glyphs[aa].k[e]=ab.k[e];}}}}}}return i;};b.getFont=function(ae,af,R,aa){aa=aa||"normal";R=R||"normal";af=+af||{normal:400,bold:700,lighter:300,bolder:800}[af]||400;var ab=f.fonts[ae];if(!ab){var Z=new RegExp("(^|\\s)"+ae.replace(/[^\w\d\s+!~.:_-]/g,"")+"(\\s|$)","i");for(var e in f.fonts){if(f.fonts.hasOwnProperty(e)){if(Z.test(e)){ab=f.fonts[e];break;}}}}var ac;if(ab){for(var ad=0,ag=ab.length;ad<ag;ad++){ac=ab[ad];if(ac.face["font-weight"]==af&&(ac.face["font-style"]==R||!ac.face["font-style"])&&ac.face["font-stretch"]==aa){break;}}}return ac;};b.print=function(ag,af,ad,R,ak){var ab=this.set(),ae=(ad+"").split(""),e=0,aj="",aa;f.is(R,"string")&&(R=this.getFont(R));if(R){aa=(ak||16)/R.face["units-per-em"];for(var ac=0,ah=ae.length;ac<ah;ac++){var Z=ac&&R.glyphs[ae[ac-1]]||{},ai=R.glyphs[ae[ac]];e+=ac?(Z.w||R.w)+(Z.k&&Z.k[ae[ac]]||0):0;ai&&ai.d&&ab.push(this.path(ai.d).attr({fill:"#000",stroke:"none",translation:[e,0]}));}ab.scale(aa,aa,0,af).translate(ag,(ak||16)/2);}return ab;};f.format=function(i){var e=f.is(arguments[1],"array")?[0].concat(arguments[1]):arguments;i&&f.is(i,"string")&&e.length-1&&(i=i.replace(/\{(\d+)\}/g,function(Z,R){return e[++R]==null?"":e[R];}));return i;};f.ninja=function(){var R=window.Raphael,i;if(P.was){window.Raphael=P.is;}else{try{delete window.Raphael;}catch(Z){window.Raphael=i;}}return R;};f.el=m.prototype;return f;})(); \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/audio/correct.ogg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/Uruguay_departments_blank.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/Uruguay_departments_blank.svg
new file mode 100755
index 0000000..5f9d64a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/Uruguay_departments_blank.svg
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ version="1.0"
+ width="903.70679"
+ height="1004.3277"
+ id="svg2925">
+ <defs
+ id="defs2928" />
+ <path
+ d="M 263.12758,0.50636519 C 260.24976,0.51869919 257.57901,1.9163032 255.43066,3.7448832 C 252.71869,2.4726002 250.09107,0.22398419 246.92047,1.3051032 C 242.15788,1.5170012 236.84274,0.58864619 232.77556,3.6577482 C 230.07986,4.9720362 227.55787,1.5292252 225.006,2.7718752 C 222.27586,5.4764392 218.24144,7.5914202 217.04767,11.45633 C 217.19257,13.630062 216.20508,16.193288 213.86726,16.582773 C 212.47319,17.411376 209.65936,18.067807 210.59968,20.28601 C 210.17371,24.133106 211.2211,28.384305 209.71383,31.9621 C 206.20417,34.488978 204.15513,39.284818 199.75139,40.414195 C 196.91158,40.376283 195.61143,35.957084 192.44655,37.42256 C 190.52744,37.747056 188.82764,41.131597 187.25107,38.778808 C 185.06828,36.449274 181.9205,34.457688 178.70827,35.79604 C 175.13164,36.380886 172.78295,39.346747 170.60471,41.910012 C 168.36541,43.14692 166.51954,40.585514 166.0011,38.744107 C 163.39625,36.162909 159.25151,36.677056 156.02412,35.549158 C 154.61579,36.819163 153.30198,39.650618 150.92675,38.453657 C 147.41133,37.500731 141.95328,37.879254 140.57218,33.574098 C 140.25924,31.55791 142.11394,29.6277 141.47258,27.416558 C 140.83177,23.214611 136.02146,21.915003 132.6284,20.63455 C 129.13784,19.571322 123.49098,19.779209 122.41906,24.047338 C 122.51186,26.58226 124.71863,28.605116 125.0846,31.171254 C 127.15716,37.431176 126.3142,44.719496 122.01117,49.836156 C 117.36722,58.085884 110.13084,64.368048 103.20581,70.679085 C 97.032331,76.236825 88.403221,79.45357 84.849371,87.539707 C 81.147041,91.344365 82.341701,97.226282 81.741561,102.07673 C 81.634761,106.59544 82.696141,111.97393 87.172971,114.07231 C 89.266071,115.30251 89.872671,117.71083 89.728931,119.98298 C 90.061671,123.09793 92.015731,125.61074 94.216361,127.66538 C 96.037131,130.77012 95.425141,134.64953 97.334631,137.78511 C 98.272201,139.8701 99.074731,143.10082 101.57929,143.69822 C 102.60442,143.26342 105.38921,143.09022 104.09166,144.94716 C 102.93762,147.75702 100.73336,150.64638 101.8552,153.82041 C 102.6679,159.78205 100.83249,166.84429 105.15183,171.74117 C 108.2925,175.78928 112.8132,178.75941 117.96811,179.17032 C 121.70855,179.8527 125.50294,180.17606 129.25918,180.75964 C 130.24067,183.3817 126.54977,183.05849 125.03311,183.43178 C 123.11985,184.06695 120.23673,184.36313 119.38388,182.05215 C 117.44827,180.06673 113.54551,181.68306 113.93685,184.6499 C 113.57516,186.77564 112.28607,182.51137 111.33841,181.7617 C 109.78704,179.109 106.69344,178.61216 103.87385,178.92331 C 99.226371,178.92982 94.417351,178.74421 89.874161,179.06051 C 87.862291,180.86225 86.880151,184.27887 88.930171,186.45246 C 90.845931,193.13177 87.982981,200.56739 91.152141,206.95823 C 92.093611,211.16389 87.790681,213.94818 87.114881,217.86463 C 85.885511,221.35227 87.560731,225.35313 91.050461,226.7524 C 93.266381,227.90066 95.892231,228.47339 97.614631,230.42659 C 95.205191,232.53432 97.765151,236.00464 100.17059,236.64222 C 102.05977,237.97227 99.840631,241.05106 98.050301,239.4015 C 95.702161,236.69768 92.939311,232.46671 88.755901,233.56345 C 85.593251,234.99996 87.342731,239.03286 86.635621,241.66701 C 86.471521,245.19016 83.599511,248.49597 79.854651,248.04425 C 77.729121,247.91778 75.659391,248.69746 74.669081,250.64191 C 71.630881,253.80074 67.747771,257.20055 68.088591,262.01081 C 67.707291,266.64481 67.591901,272.84047 62.557311,274.93806 C 58.649711,277.09473 52.672861,279.2348 52.841781,284.61004 C 52.810551,290.20023 57.650011,294.04821 62.354001,296.09734 C 66.811821,298.59247 70.821941,303.20861 69.862151,308.68835 C 70.135031,314.66625 69.077521,320.54439 66.623611,325.98464 C 63.468491,334.88768 62.556711,344.96864 57.038761,352.88031 C 53.042311,357.02816 46.753531,356.24628 41.746591,357.91962 C 37.741681,360.70366 34.940811,365.0594 32.452191,369.14551 C 30.712931,371.87891 31.914371,375.10649 34.107761,377.10384 C 39.742111,382.86416 42.009111,390.99654 42.574351,398.85855 C 43.014021,404.96631 41.384951,410.96805 38.537101,416.31459 C 36.353521,422.06064 35.518271,429.36784 40.163621,434.16275 C 43.865621,438.81087 49.654551,441.87958 51.897801,447.55251 C 52.797031,451.35532 52.434781,455.60857 52.159201,459.30119 C 44.412321,467.36952 37.947091,477.33526 36.006831,488.50192 C 34.585211,498.31272 39.916991,507.332 42.298451,516.62152 C 46.482411,529.74308 45.909921,543.92038 49.777511,557.1393 C 53.409021,565.37019 62.555821,570.45557 64.227421,579.63467 C 64.231511,587.1182 60.817121,594.05889 59.856131,601.38938 C 58.957681,606.51612 54.622631,609.89645 51.360491,613.55923 C 47.819781,616.81 43.558491,620.17689 38.566141,620.47194 C 31.426881,620.14697 24.233991,619.79805 17.101891,620.03627 C 13.149491,621.67083 10.615561,625.94751 11.292891,630.21652 C 10.922411,640.5504 14.650491,650.599 13.892441,660.91708 C 13.432131,664.59223 10.913401,667.9015 7.3863606,669.02064 C 4.1543206,671.74376 4.0950706,676.4458 3.1602906,680.2756 C 2.7739606,682.90122 4.1646406,686.16843 7.2120906,686.0991 C 10.681361,687.43958 9.9378106,692.11021 8.4174306,694.69642 C 6.0834206,699.06302 2.4369506,702.87939 1.3885406,707.81026 C -0.1932694,714.18162 0.4149506,721.09725 2.5939306,727.27041 C 3.7320806,730.45713 2.6095506,733.67736 1.6499506,736.69549 C 0.7493606,743.6418 2.3848106,750.61032 2.5635406,757.56351 C 2.9553906,763.83732 2.9711906,770.32583 5.8469706,776.02242 C 7.5432006,781.97195 7.6192306,788.90116 12.498281,793.36228 C 16.769331,797.50563 23.315191,799.1296 26.512471,804.31225 C 26.944141,807.5026 27.317271,811.41024 30.811131,812.77889 C 33.702241,814.32125 35.485511,817.01551 36.765351,819.90941 C 39.219171,822.76735 40.920921,826.33375 41.107601,830.22039 C 41.718151,832.451 41.059501,836.31352 44.215421,836.61029 C 49.448121,837.46565 54.681101,838.13717 59.885171,839.31147 C 62.722011,840.02566 64.991471,842.53858 64.721191,845.57069 C 64.878631,848.35102 66.867501,850.40741 69.212801,851.62093 C 77.468641,857.81597 83.932291,865.83662 90.309831,873.84598 C 93.604881,876.94004 95.904131,880.8626 96.641641,885.3478 C 98.451591,891.21493 100.50416,897.53527 105.23896,901.64204 C 110.46548,902.75667 115.40815,899.7788 120.62844,899.85036 C 130.10669,898.83202 139.28695,896.35446 148.03675,892.66714 C 150.36402,891.79472 153.65888,890.46915 155.25445,893.20449 C 158.97658,896.98541 165.33553,897.51793 169.38482,893.98871 C 171.41328,892.19684 173.81188,890.46399 176.70416,891.34561 C 179.69798,891.82214 182.79697,891.02459 185.66457,891.25848 C 192.21586,893.07131 199.17941,891.90305 205.90889,892.22658 C 210.60911,892.36214 215.52306,891.64369 219.87186,893.72396 C 223.72239,895.25595 228.82297,894.99599 231.3959,898.7085 C 235.29504,902.84367 238.02559,907.79219 240.80648,912.69369 C 243.63857,917.51028 249.18765,919.2422 253.49775,922.42846 C 257.5343,924.96411 261.55437,928.06793 263.22922,932.69115 C 264.2266,935.12182 266.49085,936.38042 268.86897,936.94273 C 280.23848,943.39016 292.88133,947.09872 305.7511,949.31943 C 311.79817,949.692 316.22793,954.17576 320.07028,958.36697 C 326.11819,958.32111 332.37088,956.94707 338.31056,958.01843 C 340.27325,959.57041 343.01585,959.64556 345.17972,960.90839 C 345.45233,964.46224 342.09579,967.89931 343.91624,971.27745 C 347.71179,974.19334 352.45552,975.66915 355.7666,979.25033 C 358.00734,980.94214 359.83959,983.65383 362.49054,984.56556 C 366.82945,984.38827 372.00526,986.5811 375.63338,983.43281 C 377.2019,982.47716 378.9842,982.09753 380.80339,981.87888 C 379.70354,983.76374 379.68156,986.93438 382.25564,987.51361 C 387.86853,989.67251 393.49368,985.85372 398.98556,984.9286 C 405.12242,983.13237 411.91151,983.10528 417.57436,980.10713 C 422.3054,976.63832 426.21978,971.76773 431.65119,969.46807 C 437.07355,968.63975 442.04089,966.11567 446.51773,963.01417 C 450.53788,960.41792 455.50248,962.26351 459.88451,960.99459 C 463.38502,960.53884 466.43428,958.25414 470.08772,958.94787 C 474.75198,959.49713 479.43101,960.19323 484.00028,961.14075 C 488.90298,962.78191 493.52671,965.57027 498.81323,965.54109 C 506.44291,966.35542 514.31117,964.51438 521.80237,966.3253 C 527.0083,968.12675 530.19781,972.75805 532.38925,977.56572 C 534.1444,981.01139 536.91566,984.75294 541.14634,984.79792 C 549.76159,986.04607 557.73173,981.02458 566.3718,981.58425 C 569.12271,981.8207 572.68405,981.88078 574.49,984.11534 C 575.3745,985.89555 574.731,989.57994 577.69945,989.25631 C 581.95939,989.30529 588.07557,989.11318 589.88385,993.88901 C 590.16012,995.86579 588.69965,999.45988 591.65559,999.97388 C 595.70521,1000.6243 597.70211,995.90831 600.45623,993.85996 C 604.06366,990.60274 609.04081,990.0718 613.62811,989.50321 C 620.55541,987.51496 626.10956,982.70269 632.82857,980.14255 C 642.11898,975.88204 651.11201,970.97302 660.28697,966.53601 C 673.65646,961.38468 686.11672,954.07547 699.05894,947.91022 C 703.0427,947.16392 706.28031,943.46875 705.55554,939.31341 C 704.63144,935.87323 701.82579,932.83256 698.4976,931.57294 C 696.33879,931.23188 693.67139,931.3871 697.0599,929.71406 C 700.06445,927.4768 704.06876,925.17263 704.75682,921.21837 C 703.74234,919.60979 705.24794,918.22716 706.84806,918.64791 C 708.83172,918.45194 709.02132,921.04183 707.73391,922.07522 C 705.39906,925.72026 708.02199,929.85891 709.05548,933.41727 C 709.59739,936.03216 706.73318,938.85445 708.51813,941.17229 C 711.79756,943.02266 715.35773,940.00784 718.8291,940.15571 C 722.00806,939.6376 725.86306,941.1596 728.57372,939.052 C 729.99242,935.80166 726.62566,931.12105 730.78114,929.04602 C 739.11032,921.96011 746.87175,914.17601 754.3233,906.24458 C 762.31579,899.30817 771.6153,893.94535 781.05804,889.18174 C 785.90046,887.36603 792.4131,885.67096 793.59093,879.84379 C 794.33866,876.05786 790.03285,872.58654 792.38559,868.95192 C 794.43705,863.66113 794.72601,857.7418 798.07069,852.96248 C 800.76639,848.70899 802.9792,843.85495 806.69023,840.44423 C 810.93307,837.1739 816.2899,835.13253 819.13859,830.35344 C 822.06711,826.17602 825.27693,822.12562 829.85136,819.66441 C 831.58342,818.25036 834.04485,817.04223 834.95101,814.94272 C 834.52472,808.68675 836.2974,802.50918 839.00281,796.97841 C 840.26996,790.38222 838.58294,782.93443 842.5463,777.03899 C 846.17753,769.56667 851.5048,762.95914 856.53145,756.46063 C 858.37531,754.24912 861.57696,752.13762 861.70146,749.0832 C 859.56895,747.13849 855.60772,748.52034 853.78672,745.97539 C 851.59222,743.33917 853.68476,739.43525 851.97138,736.73908 C 849.41482,735.44284 846.32861,737.31468 843.56288,736.8843 C 840.79709,736.85438 836.47947,736.83737 836.31613,733.23913 C 835.75158,729.11288 837.34725,724.97376 836.38876,720.85146 C 836.46023,717.11284 836.80204,713.37644 835.76701,709.75957 C 835.47085,705.10708 833.26324,701.01378 830.72499,697.17979 C 827.53979,691.6071 828.30932,684.6627 830.33286,678.82335 C 831.40506,676.85893 833.30218,674.47501 831.48016,672.30272 C 830.25195,670.24741 826.69489,669.91741 827.07982,666.9294 C 827.15138,663.31834 829.71245,660.66562 831.55275,657.79477 C 833.11365,655.5307 831.47314,652.68731 828.98229,652.05836 C 825.8576,651.03249 822.13217,649.73587 821.16918,646.20581 C 819.69825,643.21655 819.32703,639.85686 819.10699,636.56287 C 822.42908,637.7158 825.45399,634.10204 824.45127,630.98623 C 824.74813,627.88307 822.11256,624.84482 822.95543,621.92419 C 825.17651,620.31835 824.87904,617.56963 824.69813,615.20025 C 825.62733,616.2883 827.19832,619.15144 828.90965,617.45126 C 830.9376,615.35961 831.13598,612.17558 833.22286,610.07383 C 837.02952,604.60849 842.46995,600.28153 845.36367,594.17167 C 848.70063,590.70347 853.96726,592.4622 858.2306,591.9788 C 862.82506,591.87163 867.50372,592.93868 872.01243,592.70492 C 874.2199,591.41979 873.84979,587.94052 871.62035,586.80879 C 869.93295,586.08726 869.86789,583.71036 871.67844,583.14912 C 873.84752,581.70965 877.76817,580.26391 876.34014,576.94799 C 876.66804,575.0266 879.2649,575.3197 879.96537,573.54061 C 881.66262,572.06271 883.1711,569.92356 882.33795,567.581 C 882.43424,562.77696 879.82544,558.3669 879.31727,553.74103 C 880.39124,551.43825 883.45978,551.77308 885.31504,550.4299 C 889.87664,548.63529 893.08051,543.73296 898.21102,543.60433 C 900.9446,543.20393 901.04288,540.11851 901.07198,537.9551 C 901.20688,534.97559 902.50894,532.2541 903.20676,529.44491 C 902.64027,526.37418 899.57539,524.38439 897.04922,522.90979 C 894.24217,522.10471 891.51013,520.92483 889.41039,518.94512 C 884.72415,516.43856 878.55536,519.59541 874.42317,515.47427 C 870.26611,512.44262 864.54415,512.58213 860.99011,508.5722 C 856.89211,504.24557 855.72571,497.42784 850.27227,494.22783 C 843.37922,490.14485 837.35649,484.4379 833.15022,477.59959 C 830.50954,472.20563 824.08637,468.95203 823.68174,462.44628 C 822.62403,458.10872 823.2001,453.64722 823.72514,449.32426 C 822.95417,444.96574 819.72399,441.29362 819.48248,436.70496 C 819.08487,433.68296 816.92234,431.42347 814.59047,429.63173 C 811.68095,427.05905 812.15231,422.79997 810.01999,419.79396 C 807.80509,416.14053 806.64496,412.02711 806.58859,407.78989 C 806.40349,405.21903 804.7371,402.44275 801.83971,402.41656 C 798.73217,401.64209 794.37501,402.76364 792.54531,399.43945 C 789.2925,396.05004 784.33933,393.13376 784.22394,387.85049 C 783.33354,385.26973 780.35055,384.09492 778.57299,382.18921 C 774.55735,378.58458 769.26646,377.1666 764.06671,376.42129 C 761.25711,376.07232 760.20066,373.38243 758.80957,371.36746 C 757.02555,369.15255 754.03475,369.06867 752.00407,367.16805 C 749.63307,365.47892 745.93013,364.98051 744.02566,367.69326 C 742.41713,369.3449 740.97542,371.21806 738.85565,372.23881 C 728.50699,361.32316 715.43567,353.39998 704.50992,343.19381 C 699.11517,337.01742 695.71165,328.64677 687.88168,325.01164 C 686.61499,324.11534 684.38531,324.21537 683.72824,323.10919 C 683.70231,316.49176 683.67094,309.87434 683.64111,303.25693 C 677.09144,298.45983 670.22101,293.83106 664.86349,287.71786 C 663.27633,284.62869 662.49676,280.39978 658.77859,279.14958 C 654.45743,277.71415 649.28687,279.07362 645.47598,276.02724 C 637.40109,271.8486 627.8847,277.54383 619.68402,273.52937 C 615.43215,271.66771 612.58407,267.89967 610.17176,264.0607 C 608.80957,261.69914 606.20811,261.18845 603.91258,260.40103 C 599.37524,257.94866 597.75276,252.51685 593.81942,249.36393 C 590.44602,245.80708 588.15114,240.38838 582.82591,239.4015 C 578.85827,239.06254 578.08428,244.15474 577.37177,247.00886 C 577.08615,248.9845 575.57679,251.95666 573.15393,250.7 C 567.86685,248.15016 566.20803,240.87223 560.14177,239.45959 C 555.67711,237.25734 549.0871,237.36359 546.79557,232.24191 C 544.37763,227.57005 544.74977,221.82477 542.42432,217.1966 C 539.9495,214.15368 535.72803,213.77884 532.47638,211.92493 C 533.21133,206.91674 535.25499,201.24046 531.7793,196.74892 C 528.36974,190.9897 521.21468,188.11446 519.14473,181.47125 C 517.78774,177.4693 514.14383,175.27953 510.64909,173.39674 C 508.1204,171.46113 507.71387,167.93145 505.31931,165.80147 C 502.11297,161.83048 497.36711,159.61409 493.09136,157.10249 C 490.17138,154.63627 486.98215,151.61259 482.86752,152.5279 C 479.55267,152.79099 477.43792,156.00681 477.37802,159.17921 C 476.4627,163.83262 476.38119,168.62141 475.92577,173.35317 C 472.05613,172.72752 467.81538,170.2126 464.20613,173.00463 C 459.18474,176.29791 459.00327,183.0292 455.65236,187.48356 C 452.80646,189.90661 448.45119,189.89743 446.35796,193.35065 C 444.97337,195.16159 444.1418,197.24834 443.25014,199.30488 C 438.95836,198.98572 434.61945,201.25136 430.4413,200.21979 C 425.46888,197.95284 419.80148,199.81474 414.51014,199.74055 C 415.01668,189.20353 415.66399,178.61677 416.63042,168.13959 C 417.44326,164.22099 421.55097,161.65062 420.95813,157.3639 C 420.69379,151.89345 419.72857,145.80141 414.98936,142.33311 C 410.26329,138.12218 403.60306,135.46435 401.25107,129.19025 C 399.30612,123.26461 395.78596,117.93463 390.69193,114.29215 C 386.70427,112.5377 387.93735,107.62929 385.78463,104.64721 C 383.81501,102.59702 380.23364,102.09601 379.71423,98.838212 C 378.44224,96.041588 375.44805,94.327208 372.5982,93.82795 C 366.77921,87.066367 358.26461,83.679501 351.07586,78.710027 C 347.71059,74.81006 346.63044,69.194388 342.02832,66.35138 C 334.27121,60.144468 324.44288,55.818729 319.14553,47.019985 C 317.78386,45.060358 316.56941,42.949098 315.11813,41.08223 C 312.14825,40.966631 309.04675,41.564544 306.21582,40.370627 C 309.47959,36.48324 308.10774,30.321555 303.81726,27.794403 C 297.21033,22.363908 289.17951,19.098273 281.94874,14.694848 C 278.73121,12.091397 280.18899,6.8566172 276.32851,4.7178902 C 272.4494,2.2439052 267.80016,0.37667619 263.12758,0.50636519 z "
+ style="opacity:1;fill:black;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3748" />
+ <path
+ d="M 671.68907,784.05338 C 667.11631,785.8156 665.42668,791.03775 665.02326,795.54066 C 664.77254,799.24062 663.86536,803.64194 659.92584,805.14005 C 653.65296,808.1216 645.99753,806.20338 639.87029,809.55489 C 637.19006,811.12607 636.83121,814.3608 636.10894,817.063 C 634.71878,819.96894 631.37228,821.41176 629.6755,823.94667 C 629.34657,827.15649 630.33493,831.27767 627.0469,833.27011 C 625.86814,834.38995 623.88406,834.90797 624.11336,836.94433 C 623.23559,842.12298 623.83889,847.64153 622.28352,852.64313 C 620.85302,854.45475 617.45847,854.54244 617.27328,857.37746 C 615.79282,862.80372 615.26783,868.48859 613.94761,873.91861 C 612.3986,876.86062 608.39151,876.83404 606.41045,879.39357 C 604.92279,880.81199 603.81373,883.02164 601.38567,882.13835 C 597.01093,881.28062 594.47351,886.07834 590.39211,886.26274 C 586.31154,886.76993 581.70412,887.70532 579.50024,891.54893 C 576.88948,894.79653 575.03465,900.19314 570.20584,900.55288 C 566.03957,900.35672 561.32703,898.89783 557.6584,901.72918 C 550.67719,905.7392 545.46865,911.92862 539.17128,916.77449 C 532.83329,920.99935 524.852,921.47499 517.50422,922.25707 C 514.36643,922.67541 510.91955,921.27158 507.9624,922.49635 C 506.42111,924.22562 508.43985,926.59542 509.18229,928.27631 C 510.45088,930.74964 513.42151,931.09953 515.05198,933.27563 C 517.45858,934.93658 515.50862,938.32588 515.73196,940.82375 C 515.33895,943.46475 514.62523,946.67848 517.12612,948.54972 C 519.63877,951.07222 522.0377,953.91802 522.28159,957.66989 C 523.03518,960.04359 521.78657,963.59336 524.70687,964.77137 C 529.09996,966.79899 532.13788,970.71872 533.91413,975.08235 C 535.67333,979.04534 539.17969,983.11141 543.9637,982.53241 C 551.4785,981.7133 558.68148,978.81842 566.34285,979.17769 C 570.28651,979.34695 575.90484,979.49561 577.36545,983.98466 C 577.71748,985.64557 579.04383,987.3761 580.90894,986.70035 C 585.24459,986.43797 590.65184,988.41326 592.1784,992.77075 C 592.65288,994.5675 592.30243,996.49408 592.41076,998.34738 C 596.41112,994.6835 599.58989,989.53904 605.19056,988.31237 C 608.96952,987.09304 613.18811,987.62519 616.77952,985.64023 C 629.34276,978.11469 643.32967,972.96778 655.94668,965.46845 C 658.13383,963.67626 661.73448,963.87614 663.48388,961.76524 C 662.71816,959.27546 660.718,956.62019 662.53989,954.03922 C 663.92517,951.73152 666.60401,949.61927 665.6913,946.54561 C 664.33543,942.10168 662.19349,937.8843 662.38058,933.11251 C 662.22044,926.77201 663.3281,920.36245 666.64978,914.87206 C 668.6748,911.21286 668.89926,906.42861 666.22861,903.0217 C 664.19248,899.55313 666.86931,894.5065 663.3914,891.59707 C 661.39528,889.35345 662.99829,885.84017 662.54765,883.05329 C 662.60569,880.91804 662.57665,878.76025 662.91748,876.64884 C 665.19247,876.12436 667.78082,876.96978 669.96091,876.00985 C 670.50984,868.90182 672.53783,861.77948 671.80525,854.63273 C 670.30964,844.81023 670.68778,834.53141 673.12682,824.89065 C 674.19005,821.33899 677.58297,818.53361 676.534,814.53674 C 676.26298,809.45056 676.66371,804.22265 676.00543,799.21841 C 674.47497,795.2629 672.25026,791.32644 673.21395,786.92884 C 673.3108,785.82346 673.26107,783.93005 671.68907,784.05338 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3746" />
+ <path
+ d="M 364.66892,940.69307 C 362.25604,941.25087 358.90365,942.21735 358.23543,944.91909 C 358.99157,948.78282 360.30571,953.6846 356.9284,956.75495 C 354.61377,959.46283 351.55675,961.36758 348.59249,963.21749 C 347.44467,965.10672 345.50893,967.17472 345.78967,969.49121 C 349.70465,971.80166 353.97757,973.8263 357.20426,977.13251 C 359.68526,979.23997 362.04543,982.5787 365.75808,981.95151 C 368.34104,981.79676 371.22286,983.75468 373.48405,981.67556 C 375.95548,980.12572 379.64731,978.62333 382.34278,980.2669 C 383.85823,981.74825 382.03281,985.3725 384.60829,985.71282 C 391.00488,985.2672 396.85054,982.23639 403.2114,981.36155 C 405.61075,980.45707 408.81574,980.79023 410.76333,979.06151 C 411.04839,975.5381 408.01818,972.4881 408.20737,968.89576 C 408.08966,965.36352 407.8237,961.60612 409.87744,958.5267 C 410.93449,956.76564 411.14092,953.2735 408.30901,953.2986 C 405.19803,953.11866 401.80948,952.67922 399.78432,949.97292 C 396.9868,947.69092 395.9343,942.87093 391.7679,942.5374 C 387.24236,943.64646 385.95667,949.31962 381.70379,950.91691 C 378.89544,952.43854 376.1771,950.30957 374.52967,948.14309 C 372.88675,946.66691 372.70239,944.26997 370.6086,943.13285 C 368.9212,941.84218 366.87485,940.63121 364.66892,940.69307 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3744" />
+ <path
+ d="M 474.74947,838.81771 C 463.00186,838.81459 452.9975,845.73567 442.87256,850.7552 C 437.40261,852.46082 432.87527,848.13948 428.23388,846.108 C 424.86303,844.74656 420.80226,844.80051 417.35655,845.5271 C 412.61092,848.20022 409.05535,853.05989 403.66181,854.63273 C 401.02931,855.44023 398.87263,857.62442 398.82584,860.45623 C 397.09736,863.81955 397.86809,868.4819 394.07696,870.59294 C 388.86805,874.38622 381.69096,872.4968 376.57788,869.37686 C 374.13717,867.84045 371.56174,866.90315 368.64808,867.39316 C 364.42257,867.24644 360.0707,867.32391 356.333,869.50377 C 352.08606,871.2238 352.80085,876.5295 352.42643,880.23588 C 352.23152,883.18034 351.04281,885.872 351.37746,888.93465 C 351.19436,893.2631 351.69816,897.72534 351.21653,901.9706 C 349.60878,906.3893 346.30857,909.96987 341.92668,911.72066 C 339.79501,912.66655 337.13477,914.28484 337.84584,917.06494 C 338.03986,921.20573 340.45268,924.84398 340.16944,929.06052 C 340.83687,932.64584 345.42072,932.40047 347.77923,934.33221 C 351.48978,936.78338 355.28148,939.65433 357.01554,943.93156 C 360.27257,939.97949 366.59142,938.7669 370.66669,942.07268 C 373.75721,944.74408 375.30236,950.11034 379.87395,950.53932 C 383.60965,949.99277 385.82381,946.34509 388.07919,943.6847 C 389.46967,941.92211 392.60881,941.60499 394.65786,942.50836 C 397.54985,944.15077 397.96615,948.19021 400.77185,950.0746 C 403.32567,953.08134 407.50959,952.10766 410.80688,953.16787 C 413.13768,956.58733 409.18468,960.13923 408.99159,963.69671 C 408.08859,968.8914 410.11677,974.08497 412.40435,978.61134 C 414.37165,980.23442 416.27709,977.2275 417.88284,976.37966 C 422.46317,973.27775 426.11182,968.25487 431.5886,966.77548 C 437.4549,966.48438 441.96398,962.45865 447.01149,960.06608 C 452.38231,957.67482 458.65389,959.88861 463.92084,957.00009 C 467.30186,955.62615 470.9521,955.78787 474.29925,957.00186 C 479.82365,957.94129 485.44876,958.19596 490.5354,960.8503 C 499.85792,964.76942 510.29478,962.80895 520.11678,963.12789 C 523.36387,963.9978 521.25121,959.9789 521.49737,958.1927 C 521.22672,953.33178 517.46527,949.82101 514.32326,946.51657 C 514.71738,942.26945 515.07726,938.01916 515.39792,933.76581 C 510.5876,931.83825 506.47339,927.75545 506.30684,922.32208 C 505.89621,918.67268 507.45744,914.51674 504.76745,911.43021 C 501.05889,906.12566 495.8426,901.61365 492.93837,895.92157 C 493.26512,889.19549 495.23846,882.66688 495.32783,875.89367 C 491.22941,871.79972 487.9898,866.88089 486.68696,861.18236 C 484.60562,853.80609 482.87161,846.25788 480.9651,838.80321 C 478.89328,838.81353 476.82096,838.78234 474.74947,838.81771 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3742" />
+ <path
+ d="M 317.57241,764.15756 C 311.61303,765.54294 308.26439,771.62598 302.54165,773.69882 C 297.57003,776.44541 290.63561,774.7575 286.81376,779.53686 C 282.63541,784.13359 280.34815,791.33564 273.97587,793.40587 C 266.7273,793.58651 259.60147,791.36715 252.42262,790.41689 C 247.05989,789.51347 241.71877,788.47366 236.31905,787.93087 C 238.0907,791.17722 239.35172,794.56735 239.71731,798.22734 C 240.78054,803.66187 247.63781,804.72116 250.17351,809.03208 C 250.33802,812.54616 251.91342,816.199 255.16925,817.97794 C 257.294,819.71019 259.47047,822.33572 259.30814,825.12301 C 254.82917,830.47608 249.26308,835.17379 242.73799,837.78663 C 239.20273,838.32757 235.82235,840.22274 233.16764,842.55001 C 232.00649,845.27202 231.38363,848.65792 232.18011,851.56846 C 233.2235,854.09608 235.74191,855.68849 236.8854,858.06004 C 237.37429,861.79007 232.65831,863.49295 232.79707,867.23125 C 232.13898,870.7482 232.85916,874.65622 231.96769,877.96493 C 228.41765,881.97514 223.84062,885.18673 220.96874,889.661 C 220.337,892.30963 224.099,892.3363 225.76735,892.74033 C 228.87154,892.88556 231.65042,894.35245 233.3236,896.98564 C 236.59342,900.92461 239.96055,904.80358 241.8521,909.55683 C 243.24161,912.10851 244.99569,914.45633 247.73178,915.57467 C 252.80801,919.06937 258.39701,922.25702 262.93877,926.43197 C 263.57074,927.54665 264.21884,928.54092 264.84124,929.62692 C 265.17147,932.15937 267.25485,934.03586 269.70625,934.36126 C 282.43911,941.85171 297.0837,945.14406 311.48751,947.72196 C 315.13997,949.6848 318.29733,952.46308 321.01427,955.57861 C 326.93926,955.34736 332.86422,955.11305 338.78982,954.89607 C 340.93148,957.251 344.30289,957.07993 346.76265,958.7736 C 348.15574,959.53435 347.84703,962.57348 350.04474,961.48929 C 353.19846,959.57869 356.42297,956.96794 358.04666,953.54546 C 359.06858,948.85169 357.10072,944.10207 354.16913,940.46071 C 350.85307,936.25564 345.78488,933.81675 340.88106,931.93598 C 338.4266,930.3859 339.55461,926.83043 338.67364,924.41332 C 337.97033,920.87508 335.46038,916.2633 338.47033,913.15841 C 342.00629,910.46777 346.98813,909.35375 348.89748,904.86604 C 351.76555,898.52554 350.15831,891.19491 350.39913,884.44898 C 350.78982,881.15561 346.69694,879.9722 344.96186,877.63637 C 341.76301,874.34634 337.44873,870.46119 337.93297,865.42293 C 339.0819,862.15855 343.94663,862.70896 344.99091,859.26539 C 346.51365,855.90439 344.38933,852.46351 344.41001,849.09964 C 345.1852,845.89567 347.18029,842.31017 345.16174,839.09993 C 343.88148,835.41266 340.2318,831.67408 342.42045,827.62088 C 343.69912,823.85391 346.46974,820.47804 347.0386,816.56924 C 347.54914,809.85915 345.99112,803.32667 344.42037,796.89374 C 342.69709,789.71953 342.16257,782.01229 338.6591,775.44152 C 336.84683,773.97937 334.26419,773.60508 332.4707,772.05548 C 327.72403,769.42484 323.36519,765.70503 318.15331,764.14301 C 317.95962,764.14492 317.76546,764.13488 317.57241,764.15756 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3740" />
+ <path
+ d="M 819.76048,626.12117 C 815.94438,626.63999 813.70276,630.07111 812.354,633.30983 C 810.7345,635.45322 808.1059,632.54825 806.35623,631.98826 C 803.58785,630.82628 801.35055,634.00989 798.55763,633.96332 C 795.64035,633.84064 792.75495,635.62558 792.24036,638.61052 C 791.61211,642.06 790.75711,646.25889 787.43339,648.10824 C 784.9358,648.6086 781.7355,646.58228 780.31383,649.5399 C 776.93578,652.729 774.3979,657.05489 770.47111,659.43579 C 768.03528,660.15104 764.44839,659.73721 763.50031,662.76146 C 761.93629,667.35308 762.76828,673.38571 758.01081,676.26739 C 756.10852,677.23303 753.62701,677.12605 752.37608,679.20093 C 749.93806,682.14921 746.69966,685.95076 742.3846,684.76303 C 739.46755,684.17869 736.75586,685.74145 735.3993,688.29202 C 732.11359,692.00011 726.44688,690.73891 722.90995,694.07197 C 720.68575,696.22037 720.55693,699.9978 717.88516,701.94317 C 715.66227,704.87634 711.2174,705.2998 709.88324,708.95751 C 708.69811,711.41072 707.49695,714.56724 704.96014,715.82668 C 701.54774,716.3665 697.93334,716.00727 694.44585,716.11713 C 691.29244,722.18981 690.52277,729.20676 691.8535,735.89761 C 691.97484,739.46824 693.27694,743.24558 692.34006,746.74506 C 690.03635,751.52726 684.95682,755.10068 685.07881,760.87547 C 684.40339,764.8051 685.24369,769.77426 681.53639,772.39649 C 678.22577,774.92368 675.03705,778.19313 674.62261,782.61563 C 674.22165,786.59805 672.63412,790.87608 674.82142,794.58162 C 676.40221,797.99452 677.48747,801.49907 676.9898,805.29978 C 676.6993,810.16349 677.58938,815.24832 676.36531,819.98205 C 672.21462,825.90755 672.34334,833.61944 671.90897,840.58931 C 671.46716,846.72343 672.58374,852.7983 672.69114,858.90235 C 672.11405,864.99311 671.72462,871.16961 670.5999,877.17165 C 668.09613,877.49538 665.56508,877.33751 663.0482,877.37497 C 663.19868,881.64519 662.76077,886.11742 663.25152,890.27095 C 665.1676,892.23444 666.85161,894.57435 666.29701,897.47406 C 666.09867,900.14523 666.36235,902.88958 668.31985,904.86604 C 669.00131,907.25005 669.48978,910.12797 668.78814,912.46389 C 666.27587,917.38304 663.29329,922.26827 663.44233,927.984 C 662.58515,933.45798 663.79793,938.88089 665.74734,943.95698 C 666.45692,946.62513 667.80591,950.15942 664.95063,952.10775 C 663.32373,953.76323 661.79564,956.03529 663.09175,958.35243 C 663.67478,959.78683 664.23175,963.08309 666.41328,961.50212 C 677.44481,956.11457 688.26619,950.19106 699.26732,944.81746 C 703.30624,944.52868 704.31506,938.37598 701.00639,936.33641 C 699.62218,934.52043 697.40384,933.9952 695.25911,934.49194 C 693.33823,934.02666 692.5477,931.40782 692.39815,929.7576 C 693.99614,927.32312 697.484,927.24547 699.29636,924.90709 C 700.7297,923.26737 704.07652,921.55028 700.99547,919.83876 C 699.68975,918.80806 700.29486,916.48427 702.11373,916.67285 C 705.11549,916.2263 708.81685,915.0047 711.11768,917.80561 C 713.38551,919.29504 710.9132,921.78226 710.04301,923.32416 C 708.81852,924.83938 708.84287,926.90975 710.13015,928.3344 C 712.10693,931.41145 711.65591,935.09375 711.03356,938.52589 C 710.51452,940.78453 713.5628,938.17038 714.93707,938.02093 C 718.61816,937.25809 722.49137,937.66481 726.25012,937.55621 C 726.7424,934.49101 724.94468,930.30481 727.93473,928.14563 C 735.79598,921.29245 743.54184,914.39233 750.41556,906.47806 C 757.646,899.0114 766.95471,894.0889 775.72826,888.74606 C 780.51492,886.00719 786.84966,885.32782 790.52671,880.88941 C 792.72018,877.48488 788.00002,874.28509 789.26323,870.73816 C 790.69261,866.16485 791.48305,861.33297 793.21465,856.88077 C 795.94204,851.01089 799.34384,845.34043 803.20483,840.18282 C 805.32455,837.56608 808.21153,836.11383 810.98889,834.40287 C 814.61793,832.98543 816.41184,829.15994 819.03435,826.50263 C 820.9614,823.81641 822.63839,820.65617 825.83088,819.28497 C 828.19263,817.76975 830.42389,816.06618 832.71455,814.43445 C 831.77586,810.11688 832.49617,805.76612 834.26848,801.77083 C 835.63503,798.52858 837.34325,795.39167 837.12939,791.73576 C 837.31681,785.81333 837.41277,779.69645 840.75885,774.59475 C 843.5817,768.94181 847.86265,764.09654 851.20152,758.85701 C 852.98782,756.24868 855.34018,754.27134 857.18498,751.87152 C 857.71876,749.58468 854.64524,750.33335 853.61245,749.18484 C 849.84617,747.54215 850.432,743.02028 849.69588,739.67764 C 847.27571,738.92517 843.69067,739.561 840.78906,739.32408 C 837.65336,739.50691 833.78456,737.80115 834.07966,734.09598 C 833.13832,724.55589 834.67696,714.66283 832.20628,705.34143 C 831.30352,702.2391 828.49554,700.15093 827.86403,696.96193 C 825.58528,693.17716 825.43889,688.62072 826.43297,684.37364 C 826.43492,681.0515 827.42245,677.86626 829.46151,675.26531 C 830.22699,673.23644 827.79576,672.66381 826.6151,671.79446 C 824.12438,669.7002 824.62684,665.90269 825.17739,663.03737 C 826.03708,660.19672 829.05246,658.3173 829.54864,655.38403 C 827.67991,653.35395 824.10984,653.73395 821.99694,651.76791 C 818.0912,647.87355 816.06735,642.0159 816.55103,636.53383 C 816.77651,634.32134 819.11991,634.33278 820.71896,633.83264 C 823.39993,632.01917 821.02939,628.25814 820.68517,625.86544 C 820.56007,625.67899 819.93651,626.22625 819.76048,626.12117 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3738" />
+ <path
+ d="M 614.97873,661.54157 C 609.00693,661.16404 605.1644,667.42293 599.35252,667.65552 C 594.74277,666.84589 591.53514,661.32241 586.41295,662.60169 C 582.13162,664.50351 576.84636,662.31166 573.0232,665.49169 C 571.15865,667.11171 568.0638,667.78137 566.85116,669.93558 C 568.29147,674.26319 568.9069,679.00083 568.17269,683.55768 C 567.16201,688.31107 561.64653,689.78995 558.02148,692.05332 C 552.17981,694.22924 549.53778,700.42033 548.2698,706.09461 C 547.36633,709.05882 545.21245,711.67004 541.9596,712.06533 C 537.48564,713.61545 531.42802,715.86465 531.14031,721.43236 C 530.75496,725.34475 532.84067,728.87295 535.38088,731.62716 C 537.2103,734.39164 538.12157,737.62618 536.91195,740.84456 C 536.42418,746.34205 534.03036,751.20581 531.5179,755.99591 C 529.50129,761.04496 530.4061,766.8146 528.5989,771.88353 C 525.27856,773.40209 522.14203,775.69354 519.49327,778.20079 C 517.99417,780.93614 516.97262,783.95491 514.9332,786.42053 C 513.18246,789.46649 509.59789,791.84967 510.24752,795.74044 C 509.82077,798.56738 511.01134,802.15692 507.88382,803.71499 C 503.87695,807.72143 499.16474,811.11301 495.51664,815.43648 C 493.51797,818.25078 493.68695,821.88615 492.61214,825.00683 C 490.11474,828.27665 486.17247,830.78177 484.75545,834.795 C 483.7787,836.63799 480.48894,837.36992 482.04385,839.82169 C 484.76079,849.44005 486.24167,859.57605 490.274,868.70501 C 491.91065,871.58149 495.13636,873.51937 496.15396,876.63207 C 495.93944,883.03665 494.08832,889.24912 493.91917,895.61523 C 493.8706,897.97968 496.28589,899.12888 497.09957,901.17732 C 500.14795,905.09584 504.10732,908.49355 506.59729,912.80987 C 507.19385,915.63555 506.76556,918.62951 506.90228,921.52337 C 516.12549,921.62737 525.58765,921.25067 534.4224,918.47364 C 542.01611,915.15499 546.92504,908.04161 553.70828,903.51547 C 556.81823,901.35824 559.99199,898.39658 564.06284,899.30394 C 567.83177,899.50424 572.75366,900.41904 575.15803,896.68989 C 578.09841,892.9844 580.08402,887.71378 585.14951,886.52414 C 589.02755,885.36815 593.4891,885.62417 596.50611,882.48689 C 598.9556,880.24578 603.10462,882.51384 605.24865,879.55334 C 607.08285,877.24685 609.78199,876.2562 612.27754,875.05137 C 614.3929,872.1201 613.86423,868.02499 614.90609,864.65326 C 615.72892,861.45287 615.8498,857.83953 617.4911,854.98127 C 618.9143,853.12388 622.7586,853.29648 622.11757,850.32278 C 622.63922,845.27392 622.50417,839.86221 623.72847,835.07495 C 625.64382,832.8145 629.39982,831.44153 628.72366,827.94535 C 628.52332,824.78623 629.75213,821.52766 632.73972,820.06918 C 635.65649,818.44596 635.71081,814.88765 636.73343,812.18344 C 639.19612,808.2481 643.91489,806.8618 648.2899,806.66675 C 652.49195,805.88672 657.18701,805.90178 660.97146,803.77494 C 664.85921,800.62683 663.5238,794.85213 665.25562,790.63205 C 666.06628,786.94952 669.02306,784.33947 672.31356,782.76086 C 675.16122,780.76303 675.14974,776.6002 677.96279,774.52662 C 679.13676,773.06387 680.65951,772.06194 682.26145,771.30263 C 684.57505,767.20199 683.86185,762.07659 684.62701,757.555 C 685.55045,754.26929 688.58949,751.80344 690.29241,748.79275 C 693.41203,744.08979 690.89278,738.15239 690.79849,732.9945 C 689.8466,727.0888 691.02946,721.14949 693.71972,715.85572 C 697.75154,715.18309 702.56181,716.51251 706.09289,714.04039 C 708.81146,711.06042 709.24708,706.30638 713.30311,704.49973 C 716.40331,702.56524 719.55011,700.3719 720.44112,696.56984 C 722.17778,691.72723 727.76883,690.7239 732.14626,689.71522 C 734.32082,688.80739 731.91799,687.05215 730.69401,686.56382 C 725.59454,684.00693 720.49526,681.06 716.14246,677.55987 C 712.94068,674.84098 709.97883,671.54328 709.28784,667.29248 C 707.92928,663.66832 703.0466,664.34161 700.12412,665.36097 C 695.37519,666.77892 692.20524,670.86 687.98331,673.14503 C 686.69789,674.43625 687.39702,676.57387 686.06634,677.93745 C 683.26942,681.94097 678.69746,685.10088 673.60604,684.48712 C 670.19518,684.69685 666.9058,683.75979 664.09382,681.88757 C 662.3046,680.93058 660.06763,680.88485 658.35741,679.98515 C 655.41648,675.45157 649.14782,676.3752 644.48845,676.15121 C 641.73772,676.32357 639.02794,676.36944 636.86969,674.40605 C 633.48295,672.31676 628.96531,670.97493 627.3519,667.01653 C 625.07621,663.83069 621.62678,661.04167 617.44755,661.54157 C 616.62449,661.51945 615.80179,661.52945 614.97873,661.54157 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3736" />
+ <path
+ d="M 53.074141,753.78849 C 48.489821,754.13118 44.614191,756.96002 41.238281,759.84435 C 32.872301,765.74458 23.549461,770.73744 13.558401,773.33578 C 11.917521,773.88717 8.1517006,773.1405 8.8967006,775.92078 C 9.7057706,780.55804 9.5526006,785.73014 12.774181,789.4993 C 13.282441,790.70148 13.759671,791.79111 15.054241,792.20048 C 18.307931,794.57376 22.087451,796.31595 25.117421,799.09944 C 27.286831,800.69947 29.666151,802.76283 29.257241,805.7645 C 29.402001,810.34208 34.657611,811.60533 36.997711,814.82654 C 38.598211,817.08587 39.603211,819.70986 41.427101,821.82638 C 43.727231,825.20462 43.304661,829.49793 44.375141,833.22657 C 46.850381,835.44129 50.749801,834.63462 53.771221,835.55017 C 58.380451,836.50103 64.816361,836.47087 66.739791,841.75125 C 67.530141,844.17932 67.091541,847.59283 69.876651,848.88182 C 77.376491,854.56354 84.154061,861.12125 89.463951,868.85275 C 92.335691,873.10377 97.205811,876.12232 98.164761,881.47663 C 99.983261,887.45623 101.32862,894.06121 105.96509,898.56327 C 109.29039,900.02119 113.01916,897.94743 116.45033,897.83715 C 123.02784,896.95274 129.68086,896.04598 136.1328,894.39157 C 142.23309,892.29908 148.08958,889.52851 154.45569,888.44111 C 156.56557,890.83726 158.75635,894.05526 162.41272,893.57344 C 165.9847,894.19072 168.46951,891.26313 170.95325,889.34151 C 175.75581,888.141 181.02429,888.90332 185.99703,889.00143 C 195.89826,890.56386 206.05365,889.67151 216.06004,889.98343 C 219.23873,890.93726 220.93575,888.41476 222.82116,886.33747 C 225.72311,883.038 229.31739,880.00017 231.78803,876.53266 C 231.93121,871.48065 230.84553,865.56504 234.82321,861.63258 C 236.15012,860.19395 236.26737,858.17255 234.91034,856.69493 C 233.11095,853.86223 229.83183,851.09561 231.0619,847.35694 C 231.32465,844.34383 232.26924,841.00905 235.41865,839.87787 C 240.50445,836.7814 247.01072,836.38778 251.34981,831.96309 C 253.75646,829.67955 256.9745,827.93494 258.62561,825.05038 C 258.20559,821.83242 255.80332,818.96919 253.06347,817.368 C 250.74056,815.14729 249.62709,812.08213 249.18598,809.01754 C 246.69095,805.33352 241.82616,803.97184 239.23805,800.44926 C 238.49408,796.3614 238.2106,791.34001 234.89584,788.36654 C 229.73331,786.52574 223.91827,787.16743 218.55801,786.02844 C 212.32778,783.89222 205.82988,789.19797 199.73685,786.42053 C 194.63092,783.97094 192.03755,778.33319 186.59856,776.36668 C 183.68509,774.45022 180.21103,776.88559 176.99461,776.87927 C 169.9621,777.88595 163.24624,780.7733 156.3576,782.6918 C 151.01769,784.34225 145.38584,786.45273 139.80251,784.60524 C 131.48523,782.7643 123.21061,780.40403 114.92545,778.30247 C 112.42209,776.23693 110.4619,773.66601 108.492,771.18645 C 104.40158,768.90519 99.302301,770.15519 94.811811,769.82133 C 90.434281,769.43947 86.723631,772.80488 82.307911,771.7528 C 77.344191,770.47422 76.545711,764.51158 73.681551,760.96261 C 69.428571,756.02217 61.996901,756.91295 56.486911,754.26771 C 55.392121,753.92377 54.232691,753.71925 53.074141,753.78849 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3734" />
+ <path
+ d="M 567.75156,616.62346 C 562.27316,618.1311 558.57608,622.98543 554.50704,626.65853 C 551.42209,629.65862 548.2098,634.36656 543.3828,633.83264 C 540.87206,632.86064 538.40384,630.71619 535.52611,631.87208 C 531.28396,634.01528 527.23745,636.77116 522.41231,637.43422 C 518.93969,638.33044 517.78737,642.38749 515.54315,644.79711 C 513.09296,649.2541 508.48739,651.74955 503.75088,652.9733 C 495.05592,656.00797 488.14772,662.64923 479.4983,665.7531 C 475.0566,666.28307 470.50016,665.36469 466.15215,665.23029 C 464.33969,666.32977 464.66992,669.12409 462.73934,670.26957 C 458.72713,673.91437 453.87387,676.59762 448.57992,677.73414 C 442.81697,680.37454 436.05562,680.59969 430.23798,678.01009 C 424.30904,676.82919 418.36197,679.36057 412.50603,680.05774 C 409.6348,681.26378 410.41539,685.47637 408.07665,687.28994 C 405.69161,689.32769 403.23403,693.16642 399.56646,692.02428 C 395.17806,690.64267 391.073,688.03856 386.24935,688.4227 C 382.33492,688.44445 378.42551,688.67123 374.51517,688.82933 C 371.50044,686.2855 372.72131,680.52371 368.25595,679.34616 C 363.22173,677.93941 357.40172,679.3259 352.73142,676.70306 C 351.09905,675.81536 351.00773,673.91368 349.97215,672.66581 C 348.54448,671.33611 346.26224,672.55451 346.70456,674.49564 C 346.27697,679.34239 347.12304,684.43996 346.48019,689.12573 C 345.29479,690.98958 343.56119,692.74617 341.15697,692.28568 C 336.73209,692.52241 332.29778,692.37389 327.86889,692.41641 C 330.25852,694.56388 331.08066,697.45546 331.41814,700.51053 C 333.60643,710.29163 335.495,720.21475 338.3251,729.82637 C 340.64912,735.57393 346.95793,739.50779 346.8483,746.23484 C 347.03005,753.37829 346.83886,760.64144 345.81871,767.6865 C 344.93783,771.07125 342.01544,773.01968 340.0678,775.65938 C 341.43826,780.70884 343.24202,785.64459 344.00338,790.87896 C 345.19678,799.28932 348.72567,807.463 347.53237,816.09002 C 347.13359,821.71341 341.97422,826.38175 342.60922,832.19545 C 343.35477,834.51296 345.49815,836.0957 345.87517,838.63521 C 346.92725,841.25187 347.51977,844.31451 345.8768,846.81963 C 343.79476,851.20807 348.54239,856.05947 345.36849,860.12224 C 343.90546,862.49933 341.0446,863.18934 339.09477,864.91466 C 337.45654,868.94667 341.24717,872.51869 343.70265,875.22499 C 345.84604,877.09144 347.66737,879.7627 350.16092,881.03464 C 352.32567,880.24201 351.32267,876.94194 351.91816,875.19659 C 351.84506,871.7493 354.43178,868.92608 357.6582,868.21952 C 364.04289,865.78666 371.71746,865.29945 377.69088,869.18721 C 381.83279,871.6683 387.12381,872.58008 391.7679,871.13029 C 394.95425,870.22228 396.42026,867.09722 396.89883,864.05925 C 397.74383,860.4027 398.48924,856.05013 402.42742,854.44392 C 406.08973,852.49349 409.95932,850.9113 412.89574,847.86265 C 416.04455,844.59158 420.6542,843.26601 425.05347,844.45244 C 429.13432,844.9746 432.42844,847.47749 435.82917,849.47722 C 439.58271,851.33889 443.88885,850.26465 447.12432,847.89573 C 455.71756,843.10117 464.82658,837.92768 474.93824,837.94636 C 478.208,837.95686 481.95016,837.63156 483.8696,834.57714 C 484.9543,832.67397 485.60481,830.52292 487.52383,829.16566 C 489.47886,827.3566 492.27777,825.78324 492.32169,822.72678 C 493.27795,818.06489 494.94964,813.27451 499.2753,810.75731 C 502.84895,807.59243 506.80381,804.34617 509.6906,800.72521 C 510.09644,797.04259 508.4373,792.68835 511.60441,789.90402 C 514.39626,786.24947 516.95162,782.37733 518.60742,778.1282 C 521.4449,775.05092 525.66437,773.3065 528.39558,770.18437 C 529.55334,764.63789 528.91407,758.61429 532.15689,753.65777 C 534.88804,748.48385 536.29392,742.50858 536.38296,736.65194 C 536.06908,733.88588 534.71085,731.44527 532.76683,729.53592 C 530.5115,726.30263 529.12649,721.94839 531.27104,718.28096 C 533.70766,712.96252 540.34646,712.36907 545.00932,710.01768 C 547.56207,708.14848 547.55673,704.39805 548.79967,701.69626 C 549.96798,696.53671 554.07275,692.6997 558.83474,690.83343 C 561.76587,688.60868 566.9429,687.74834 567.28684,683.29628 C 567.56339,679.83741 567.44479,676.19666 567.11257,672.81103 C 564.94846,668.92458 560.43933,664.71152 562.24751,659.87146 C 565.44524,656.28183 570.81271,653.53254 570.97555,648.09374 C 570.87615,637.86079 570.14398,627.59861 569.31999,617.40767 C 569.11091,616.73011 568.39329,616.54766 567.75156,616.62346 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3732" />
+ <path
+ d="M 221.17206,620.38481 C 219.37926,622.4207 219.36304,625.91744 218.23512,628.49018 C 217.04223,631.91433 216.86656,635.95804 213.47104,638.03975 C 206.70193,644.69273 199.27055,650.65528 194.27434,658.83779 C 192.60051,661.68387 190.63637,664.30573 188.83047,667.01653 C 187.65315,670.12746 188.96199,674.30204 191.85115,676.00598 C 195.26763,676.90294 197.53254,680.07884 197.42779,683.57218 C 198.04908,687.527 199.0676,691.56955 202.06045,694.40597 C 203.44996,697.74322 203.17536,701.7886 205.5023,704.78958 C 207.56417,707.45944 209.58747,710.76862 212.90878,711.9056 C 215.45772,712.19745 219.53192,712.28983 220.31525,715.31837 C 219.97317,724.14944 216.59782,732.68314 216.06014,741.5315 C 216.92986,749.28991 223.59855,754.71933 225.60316,762.12957 C 226.93077,767.9065 228.59331,773.69227 230.75691,779.23191 C 232.54115,781.61955 233.48165,784.75037 235.7091,786.74002 C 239.92318,788.26821 244.6117,787.86892 248.98476,789.03026 C 256.93677,790.1058 264.75289,792.46059 272.78502,792.73784 C 275.58398,792.68049 278.14459,790.59107 279.62514,788.39559 C 282.79291,784.50644 284.76346,779.34154 289.20999,776.64691 C 294.06074,774.29213 300.11716,775.45253 304.47163,771.8786 C 309.43093,769.17365 313.06505,762.89306 319.3732,763.69284 C 326.08032,766.59548 331.66937,771.98967 338.67364,774.16354 C 341.92352,774.48624 343.83659,770.86607 344.70046,768.22386 C 345.94683,760.94281 345.94172,753.44516 346.02203,746.06252 C 345.91644,739.54204 339.91923,735.49595 337.39566,730.01514 C 334.51105,718.65055 332.1866,707.11722 329.53895,695.75658 C 327.45687,692.16811 322.31572,691.36363 321.13045,687.01404 C 319.60217,681.84547 321.65368,675.11739 317.02056,671.22806 C 315.80462,668.95019 312.96773,667.746 311.37133,665.60787 C 307.46164,661.79066 305.46171,656.33532 300.97322,653.11852 C 293.18451,649.34723 284.26263,649.36308 276.18329,646.78671 C 273.06534,645.39004 272.34758,641.40856 269.7972,639.31509 C 267.69759,636.26034 263.34805,637.3331 260.18353,636.23548 C 251.33582,634.71162 242.48537,633.00205 233.79213,630.98623 C 229.43873,627.87289 226.3429,623.13321 221.7675,620.37026 C 221.57469,620.33685 221.35822,620.30948 221.17206,620.38481 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3730" />
+ <path
+ d="M 155.53036,598.77533 C 152.40377,599.14283 150.72204,602.43904 147.71725,603.26276 C 145.91544,604.50026 142.84717,603.48327 141.95184,605.99299 C 140.128,608.12959 138.69457,611.14185 135.91048,612.01985 C 133.61156,611.53831 131.70556,609.8319 129.25207,609.50613 C 125.65388,608.73502 122.61633,606.66502 119.18056,605.62995 C 116.97853,604.9997 115.42483,607.12268 113.21179,606.79175 C 109.10659,607.14838 105.7588,604.23681 102.4361,602.37691 C 98.872951,601.58781 96.999801,605.72215 95.015121,607.88091 C 93.551111,609.81689 92.088591,611.95251 89.438481,612.09244 C 87.633691,612.96695 84.130221,612.84779 83.832801,615.34548 C 84.252671,618.25063 85.472791,623.45842 81.305881,624.04448 C 77.049841,623.57762 72.475091,619.70246 68.235631,622.24369 C 65.364821,624.25667 67.733321,628.10701 68.223221,630.7199 C 69.148571,634.7974 72.110141,638.27551 72.287391,642.5171 C 71.562611,644.37821 69.636581,644.96311 67.858051,644.04194 C 66.086811,643.73197 64.742521,642.69132 63.559391,641.52957 C 60.059211,640.65204 55.825841,643.00543 55.395981,646.79187 C 53.631671,650.62196 57.718181,654.849 54.642571,658.36112 C 51.646711,661.41234 47.295811,659.00383 43.881381,658.18685 C 39.376981,657.24101 36.682171,662.00592 34.215481,664.88621 C 31.291511,668.68548 28.402711,672.56357 25.568531,676.38357 C 20.605361,677.76114 15.594571,679.13169 11.481701,682.39588 C 9.7210606,682.99667 9.9862806,684.87122 11.234801,685.85224 C 12.567151,690.03741 12.243381,694.77486 9.3323706,698.25445 C 5.7603506,703.21655 2.6750206,708.95965 3.1893306,715.28932 C 3.0905806,719.02465 3.5737906,722.67795 5.1063006,726.07956 C 6.6321206,729.71316 5.4256106,733.43696 4.3220906,737.00048 C 2.7835806,742.73267 4.9251506,748.62429 4.9029906,754.42748 C 5.6509106,760.33421 5.1175506,766.60696 7.0232706,772.26111 C 8.3990306,774.29436 11.263331,772.84127 13.224401,772.6532 C 24.122921,769.73843 34.512161,764.59546 43.256931,757.47721 C 47.482351,753.42578 54.140671,751.58386 59.464041,754.45653 C 63.662461,755.98114 68.467571,755.87295 72.171211,758.66805 C 76.513741,761.42882 76.855631,767.71383 80.971841,770.56196 C 85.263951,772.71733 89.519301,769.27445 93.838781,769.29852 C 98.848131,769.17082 104.72349,767.73976 109.05836,770.93954 C 110.83805,773.10937 112.70455,775.23862 115.14331,776.61786 C 115.62211,778.9192 119.00397,778.06951 120.61827,779.04212 C 128.86547,780.97266 137.01266,783.6962 145.37915,784.88114 C 156.70154,782.51 167.5047,777.7048 178.90373,775.71491 C 182.43588,775.38766 186.49163,774.26536 189.35328,777.06804 C 193.40559,779.63538 196.04506,784.26153 200.63724,785.88322 C 206.50647,787.41303 212.24228,784.01221 218.14859,785.25129 C 223.52781,785.76239 228.86661,786.80908 234.31494,786.81266 C 232.32729,782.62985 228.91968,779.18897 228.1502,774.50395 C 225.7522,767.71206 225.35997,760.07788 220.89615,754.18058 C 218.5475,750.07752 215.49866,745.6999 215.17429,740.84892 C 215.86983,734.11262 217.98036,727.48093 218.92978,720.7279 C 219.16172,718.52903 220.81599,714.96021 217.81738,713.93875 C 214.72026,712.5135 210.73747,713.18042 208.66983,709.91098 C 205.16241,706.23068 202.13206,701.7979 201.98786,696.62793 C 201.44785,693.21461 197.55276,691.57211 197.50735,687.92745 C 196.30489,684.3689 197.07934,679.07843 192.94032,677.25492 C 189.89891,676.65919 187.84931,673.20042 187.4944,670.29862 C 187.55416,665.05569 192.4031,661.67472 194.61233,657.2938 C 199.83592,648.47407 208.72727,642.57333 215.52283,635.03799 C 216.74834,630.12037 218.90831,625.35308 219.53104,620.32672 C 216.85123,619.6532 214.23727,621.98242 211.63493,622.61932 C 207.87368,624.8596 203.591,622.39584 199.56304,622.20386 C 194.70035,621.77957 191.28717,617.66043 187.08522,615.52124 C 184.94927,614.40038 182.7946,611.93113 180.23315,613.4721 C 177.40756,614.11523 174.19272,615.66316 171.62129,615.73761 C 170.85111,612.1951 171.77553,608.15333 170.12549,604.84573 C 166.23932,601.26056 160.89327,599.40953 155.70463,598.76078 L 155.53036,598.77533 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3728" />
+ <path
+ d="M 505.10149,478.7033 C 502.6,483.41472 501.37555,488.73614 499.49581,493.73406 C 492.40055,493.77598 485.11142,493.20591 478.13319,493.58884 C 474.42481,496.32269 470.7776,499.81483 467.0235,502.04093 C 464.60142,500.06295 462.49787,496.9984 458.96502,497.29814 C 455.41177,495.77707 455.48217,499.80349 454.44427,502.14573 C 452.69836,506.68902 451.40314,511.56123 449.611,516.01158 C 446.49272,517.23468 442.72273,517.1079 439.41992,517.74024 C 435.09105,518.34006 430.57193,518.29052 426.85882,520.92255 C 416.30554,526.29142 405.46664,531.2622 395.0919,536.88234 C 389.80715,541.75326 384.81016,547.10599 379.34505,551.67786 C 369.23358,555.25263 358.69698,557.79762 348.97007,562.29481 C 346.92981,563.14432 345.27397,565.14085 343.48057,566.0997 C 340.32684,564.29046 338.00849,560.57697 333.91742,561.06279 C 328.59854,560.45322 323.28308,559.81325 317.96454,559.20149 C 314.94609,561.69453 312.38911,565.07388 308.96059,566.84033 C 306.21238,565.85433 303.87423,563.59858 301.22008,562.77403 C 293.8623,564.95733 285.18296,565.18198 279.5263,570.9413 C 277.25093,572.57386 275.44791,574.94584 275.5298,577.90647 C 275.12563,579.03277 275.59774,582.06553 273.64187,581.01429 C 271.49979,580.7533 268.70813,578.14264 267.59981,581.12271 C 265.43138,583.19299 265.00951,586.17463 265.20428,589.04525 C 265.59176,591.51329 262.82077,589.43065 261.57137,589.26744 C 259.04293,588.32461 255.66897,586.49594 253.55723,589.23402 C 252.01036,590.96459 248.69166,592.08322 248.19845,594.17167 C 248.86416,597.08575 249.80573,599.95525 250.17351,602.88517 C 243.43888,601.64748 236.99503,598.90829 230.26314,597.61353 C 224.04537,600.91378 218.2769,605.03646 212.28429,608.73776 C 219.33465,616.0071 226.10501,623.65277 233.83568,630.12938 C 245.28587,633.18464 257.20951,634.5274 268.67518,637.18732 C 271.51759,639.3729 272.99331,642.75792 275.23935,645.39255 C 280.06031,648.34622 286.16333,647.74701 291.49325,649.28458 C 297.29222,650.49063 303.546,652.90889 306.70958,658.27399 C 309.84849,664.11724 315.35681,667.84573 319.43129,672.85458 C 321.53708,676.32989 320.60071,680.86872 321.56612,684.73398 C 321.80039,688.14484 324.11929,691.86943 327.98507,691.42888 C 333.24562,691.29016 338.67531,692.0115 343.84365,690.9932 C 346.70321,689.31064 345.5673,685.24192 346.03653,682.49752 C 346.14178,678.95909 346.23017,675.4202 346.32698,671.88159 C 348.02223,670.43687 350.47665,671.28503 351.19204,673.3193 C 352.85067,677.75584 358.31773,677.44694 362.18178,677.90455 C 365.89127,678.26057 371.20869,678.33023 372.51107,682.67179 C 373.60437,684.32517 372.79482,688.20465 375.19761,687.99121 C 382.37568,688.07244 390.12544,686.66657 396.7491,690.17994 C 398.99569,690.95575 401.96428,692.41172 403.92321,690.23803 C 407.1723,688.1803 409.19011,684.92405 410.25502,681.30667 C 410.77434,678.59647 414.26448,679.40611 416.20023,678.58695 C 420.47231,678.17999 424.73546,676.23853 429.01809,676.89183 C 433.76409,678.61204 439.00901,680.31069 444.03436,678.43122 C 447.20049,677.23614 450.68715,676.79777 453.76443,675.52672 C 456.96807,673.04507 461.76895,672.08779 463.50905,667.98956 C 464.22992,666.20202 465.34056,663.49856 467.77867,664.40248 C 473.96023,665.49629 480.81002,665.48365 486.16415,661.83202 C 493.07505,657.60423 499.85792,652.89606 507.78813,650.82397 C 514.14364,648.44191 516.00415,640.92409 521.14883,637.04209 C 523.73913,636.09179 526.60813,635.85994 529.04907,634.399 C 532.37433,633.24844 535.59767,630.03463 539.30196,630.94264 C 541.71139,632.65081 544.92274,633.74095 547.69596,632.10444 C 551.12676,630.89924 552.1609,627.00163 555.02985,625.01746 C 558.97397,621.21531 563.39927,617.622 568.31791,615.09862 C 569.67545,613.42837 569.27468,610.85103 571.13528,609.43484 C 574.45881,605.30962 580.38581,605.18043 583.94412,601.50556 C 584.72397,600.04666 587.1914,598.17528 585.803,596.49527 C 580.41332,595.8712 574.79982,595.45374 569.48538,596.87272 C 564.86987,597.87303 559.82287,596.70477 557.12443,592.58847 C 554.85321,590.46321 553.0704,587.2907 549.87434,586.59093 C 544.81418,583.77463 539.8671,580.74215 536.1651,576.2945 C 534.53221,573.35849 532.86252,570.22047 531.95803,567.04611 C 532.47387,560.86789 534.27113,553.38171 529.7752,548.25153 C 528.44475,546.2187 529.43539,543.59048 531.72121,542.67489 C 533.63948,541.64228 536.38351,539.61573 534.74189,537.14184 C 533.52284,533.65584 531.21559,530.46786 530.22267,527.02739 C 531.15105,520.01245 533.28351,513.37801 534.87262,506.54291 C 535.74917,501.3795 536.04594,495.74495 534.14649,490.80052 C 532.24653,488.96934 529.8943,491.83564 527.68396,491.57023 C 523.79114,491.72466 522.99437,486.54508 519.46422,485.76123 C 516.5494,484.68903 512.6721,484.08708 511.79634,480.50409 C 510.42486,478.44552 507.52649,478.74703 505.3629,478.42739 L 505.10149,478.7033 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3726" />
+ <path
+ d="M 764.28453,534.4697 C 760.39961,535.12231 757.51197,538.49701 754.88849,541.16455 C 754.36294,542.65481 752.61053,543.97169 753.65406,545.7827 C 754.30522,548.02786 757.62146,550.20117 756.07934,552.63732 C 754.31163,554.91073 751.00757,553.74247 749.19567,552.08547 C 745.29672,550.36995 742.09675,547.22417 738.41998,545.23085 C 734.86793,544.19011 730.80926,545.35163 727.44097,543.7786 C 725.87769,541.59665 723.13822,541.12119 720.5718,541.32432 C 717.42983,540.93879 714.43494,539.62572 711.21931,539.42185 C 708.8807,539.0425 707.05114,537.5941 705.65722,535.82027 C 701.7716,533.39582 697.02137,536.6267 695.0122,540.10443 C 692.49941,543.94915 687.32364,542.65379 683.40875,542.81588 C 680.15124,543.17311 675.83497,541.86432 673.33013,544.57736 C 672.15313,547.01166 671.23415,550.7829 668.04394,551.11248 C 666.12112,551.16332 664.31294,548.84869 662.79511,549.29185 C 661.15856,550.57745 660.87624,552.55521 660.17275,554.27839 C 658.76539,556.91911 655.6362,558.961 652.67914,557.37166 C 648.73417,556.03522 644.27593,554.38695 640.32813,556.60877 C 637.04224,558.58416 633.21992,558.89171 629.45764,558.62059 C 623.54254,558.27851 617.98551,560.68595 612.98912,563.55824 C 609.13143,565.18881 605.71128,567.75415 602.99764,570.87758 C 599.38467,573.65145 594.79482,574.87418 591.16183,577.64507 C 588.81964,578.80891 586.23143,580.61877 585.32378,583.20721 C 584.56689,586.23226 585.08292,589.35615 586.79053,591.94975 C 588.09142,594.80007 588.01762,598.27348 585.5271,600.41635 C 582.68083,604.44858 577.83942,605.69942 573.77837,607.96805 C 570.34302,609.91183 569.74084,614.17503 570.27847,617.75621 C 570.56051,627.93883 571.62779,638.15245 571.85838,648.2919 C 571.2074,652.07899 569.14748,655.48469 565.791,657.44623 C 563.46702,658.4846 561.97123,660.97039 562.90104,663.47304 C 563.60175,665.35623 564.04537,668.28224 566.21217,668.90446 C 569.78485,667.16971 572.98207,664.20828 576.8136,662.87764 C 580.50845,662.59282 584.32872,662.66592 587.92329,661.55607 C 593.1439,661.21371 596.1367,668.18242 601.50185,666.6099 C 607.10669,664.04483 612.4388,659.29377 619.07407,660.56854 C 624.98429,661.31679 627.6146,667.05376 631.63601,670.63266 C 634.32423,672.23738 637.11566,673.93343 639.85575,675.39604 C 645.42523,675.95245 651.55094,674.74083 656.70185,677.26942 C 658.65683,679.1816 661.19434,680.09831 663.75123,680.92337 C 666.81657,682.66068 670.13499,684.03346 673.75126,683.58673 C 677.24451,684.05484 680.57818,682.8165 683.10375,680.44987 C 685.8153,678.57477 685.96582,675.14983 687.12651,672.4189 C 688.17264,671.1169 690.1734,671.5693 691.27994,670.19698 C 695.32598,666.66163 700.64386,662.79125 706.28166,663.99585 C 708.49145,664.54515 710.54272,666.17465 710.55128,668.59951 C 711.60205,673.71175 716.2453,676.98385 720.3104,679.7092 C 724.63764,682.42832 729.2511,685.21502 734.06323,687.21735 C 736.29346,687.35714 736.86888,684.11349 739.23324,684.10954 C 742.33808,683.35892 746.24642,685.0282 748.74545,682.23611 C 750.95919,680.06573 752.34591,676.81292 755.7308,676.26739 C 759.56218,675.26782 761.40266,671.32305 761.57906,667.60245 C 761.86668,664.18565 762.87772,659.93281 766.7824,659.20343 C 768.84812,658.93291 771.21489,658.99654 772.54785,657.06864 C 775.79206,653.70909 778.88454,650.27597 782.17625,646.96098 C 784.64186,647.36594 788.04101,648.00172 789.35036,645.20374 C 791.4837,641.60128 790.56165,636.23088 794.70919,633.91978 C 798.23804,633.06711 802.03982,632.52669 805.26702,630.60865 C 807.29153,631.27673 809.39898,633.34511 811.37363,633.19444 C 813.08356,631.47066 812.98792,628.44547 815.47636,627.34106 C 816.75527,625.93835 819.92094,626.22165 819.76048,623.75403 C 819.51831,622.129 819.53081,620.42013 821.18368,619.57155 C 823.31939,616.73745 820.14108,613.22896 820.25094,610.43125 C 820.75488,608.42919 823.32009,606.141 825.1193,608.18591 C 826.42377,609.26234 826.65543,612.7515 828.83706,611.7294 C 831.45106,607.96177 833.83763,603.984 837.43438,601.17152 C 841.27706,597.7535 842.29637,591.56966 847.57109,589.74233 C 854.00946,588.70527 860.69334,589.87808 867.2148,589.79833 C 871.10911,590.70458 869.50183,588.83237 867.72832,586.86688 C 865.75748,584.62205 869.01605,582.40064 870.444,581.01429 C 871.66714,579.79212 874.1079,579.14347 873.668,576.90444 C 872.86152,574.78039 874.96754,573.63481 876.58704,573.12859 C 878.93653,571.5215 880.68996,568.73625 879.7384,565.80925 C 879.05456,561.50446 877.27878,557.50489 876.04969,553.39249 C 874.02955,551.50001 870.91146,553.00129 868.7013,553.79912 C 865.87571,554.76346 863.22286,553.74303 861.03342,551.99833 C 857.48031,549.68036 852.43029,551.64366 849.34283,548.39675 C 844.69884,545.32588 838.99087,547.29114 834.02157,548.16439 C 823.97149,549.30472 814.02806,544.12547 804.04713,547.10427 C 797.92523,549.59081 790.83556,548.99085 784.61603,546.93 C 778.23946,543.41807 774.37016,535.81042 766.7679,534.60038 C 765.9544,534.43782 765.11191,534.39437 764.28453,534.4697 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3724" />
+ <path
+ d="M 240.03681,462.39451 C 235.39188,463.50138 231.7186,467.09357 227.16987,468.2616 C 221.39814,468.4038 214.93486,468.44907 210.49804,472.69098 C 206.41557,475.49111 202.72495,479.72401 197.66015,480.50409 C 194.39001,480.3525 192.44432,477.24966 189.06283,477.42532 C 186.41648,476.82955 184.04093,477.02566 182.52771,479.5456 C 180.22809,482.83712 175.81129,481.0671 172.63786,480.53313 C 169.33793,479.71151 164.84451,478.39417 162.5157,481.78207 C 160.30429,484.20558 157.76524,487.12542 154.23788,487.25703 C 150.23213,488.66513 151.70627,493.92636 148.74837,496.27552 C 143.85622,500.51911 137.27365,501.59211 131.04542,502.14261 C 125.87969,503.23006 120.34692,502.52322 115.28853,504.08863 C 112.49961,507.26773 113.5884,512.88201 109.74094,515.18382 C 106.64353,515.85497 103.61732,515.09227 100.99839,513.44112 C 95.883541,512.18638 90.093641,514.44794 85.372181,511.61128 C 82.352201,510.28767 78.545541,511.92827 75.743741,510.14449 C 73.439151,507.23464 72.699031,502.79652 68.801991,501.40194 C 63.868431,499.93115 62.076931,494.49541 58.084381,491.81709 C 51.794671,489.72855 45.094851,490.86707 38.711371,491.94782 C 37.037541,493.3147 39.049451,496.01417 39.091691,497.79939 C 40.223841,502.62969 42.550461,507.08143 43.525821,511.90977 C 48.418301,525.57891 48.482341,540.42434 51.621891,554.43811 C 54.153591,561.75313 60.729751,566.46177 64.648551,572.89623 C 65.203981,575.28982 67.379901,577.0927 66.826931,579.67822 C 66.206481,588.2207 63.226321,596.33104 61.787641,604.7586 C 60.619711,607.8297 57.572351,609.95222 55.703711,612.64936 C 52.871901,616.63387 48.752991,619.3944 44.304501,621.44316 C 40.763201,624.27637 36.133521,622.49798 31.991791,622.78727 C 26.876111,622.98752 21.373501,621.65219 16.491941,623.49262 C 12.700751,626.32026 13.467121,631.82324 14.043011,635.92853 C 14.842931,644.68585 17.326211,653.47817 16.288631,662.31124 C 15.736771,665.42096 13.895361,668.13823 11.205751,669.84844 C 9.1799406,670.80944 7.0890306,672.19598 7.0466506,674.7511 C 6.7704206,677.24367 5.0249306,679.85498 5.6872006,682.35229 C 7.9657206,684.76795 11.112161,681.7325 13.128901,680.50452 C 16.645071,677.68418 21.145371,677.06722 25.190941,675.68649 C 29.799661,669.8931 33.894961,663.49605 39.001821,658.2014 C 42.148901,657.24779 45.496051,657.52458 48.485031,658.70966 C 50.512471,659.1011 53.796041,660.01697 54.540891,657.27196 C 55.974511,652.9167 52.700231,648.11284 55.659151,644.05648 C 57.356161,641.58952 60.624591,640.38324 63.501301,640.54204 C 65.481931,642.16205 68.418871,644.60406 71.023951,643.12704 C 72.188861,641.27755 70.391931,638.99015 69.992831,637.08568 C 68.134421,633.11502 66.729061,628.71399 65.970121,624.43656 C 67.977901,618.48136 75.505011,621.21526 79.635771,622.92622 C 82.353501,624.09248 84.705401,620.91417 83.629481,618.45329 C 83.130881,616.62704 82.450071,613.09242 85.154321,612.70238 C 88.525771,611.35855 92.780931,610.84996 94.645991,607.28101 C 96.638061,605.18977 98.308361,601.30712 101.66643,601.37483 C 105.64485,603.3031 109.63145,606.67552 114.42466,605.67582 C 117.45696,605.23759 120.76781,604.5616 123.42113,606.58843 C 127.78569,608.51303 132.49837,609.43289 136.72374,611.7294 C 139.09637,609.43489 140.35446,606.27963 142.66342,604.01793 C 144.81257,602.7386 147.62449,603.36133 149.57613,601.50556 C 152.0306,599.86133 154.36354,597.16363 157.63614,598.22347 C 162.47615,599.21588 167.62878,601.12588 170.83707,605.0345 C 172.62313,607.87957 171.06822,611.61973 172.391,614.53222 C 174.38828,615.26457 176.77498,613.33724 178.88254,613.09451 C 180.76605,612.63676 182.87481,611.20705 184.51727,613.09451 C 188.88958,615.49898 192.72404,619.03373 197.31161,620.95116 C 201.25685,621.81433 205.35689,622.44329 209.33624,622.81004 C 212.54718,621.26155 216.41625,620.57232 219.25509,618.49688 C 219.36206,616.22399 216.69982,614.69836 215.49378,612.93474 C 214.49422,611.53714 212.29628,609.9808 212.13906,608.47636 C 217.87752,604.1817 224.02195,600.284 230.2341,596.74218 C 236.28461,597.94092 242.19924,600.47146 248.30009,601.60719 C 249.6942,600.00052 247.71937,597.48015 247.69098,595.5333 C 246.98711,594.08203 247.6334,592.73374 249.02621,592.05139 C 251.3243,590.14692 253.57717,588.20202 256.01156,586.53284 C 258.6869,587.37245 261.24602,588.63361 263.9263,589.3502 C 265.72035,587.69078 263.24864,584.838 265.29141,583.14912 C 266.57264,581.83057 267.40017,579.24491 269.21249,578.90855 C 271.12908,578.81644 274.65203,582.3847 274.55742,579.14672 C 274.93393,576.45083 274.86799,573.34037 277.5484,571.82157 C 280.99923,569.16672 283.92501,565.38139 288.56487,565.06668 C 292.77184,564.02436 296.98132,562.99194 301.19103,561.96077 C 303.20262,556.32088 305.52259,550.69712 307.33407,545.04208 C 306.96903,541.55747 306.20169,538.10864 306.3175,534.60038 C 308.72117,530.72935 312.02351,527.24386 313.77277,523.06765 C 316.42413,511.63396 320.24483,500.32379 320.07028,488.46242 C 320.01163,486.81173 317.0536,487.46941 315.8878,486.34213 C 311.33638,484.29741 308.21188,480.34711 304.5893,477.13487 C 302.22592,475.47205 299.56753,473.56847 296.66001,473.53329 C 292.03372,471.51919 286.73517,472.98682 281.84706,472.53126 C 276.66692,472.69029 271.5826,470.40531 266.43871,471.79059 C 259.7908,473.21319 254.09501,468.986 248.73576,465.77823 C 245.94642,464.56456 243.12273,462.65303 240.03681,462.39451 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3722" />
+ <path
+ d="M 680.76565,325.6361 C 677.73535,326.88297 677.05649,330.79648 675.66521,333.43824 C 674.18368,337.56827 674.08126,342.58161 676.73657,346.29817 C 678.86759,349.36206 677.73038,353.21282 676.10981,356.21313 C 672.00865,365.95264 669.00112,376.33365 663.26602,385.23644 C 662.53952,387.51074 665.98755,387.17117 667.34686,387.74884 C 671.09106,388.63795 670.55176,393.69766 668.82816,396.15736 C 667.05097,398.22484 663.14161,399.48931 663.71624,402.82319 C 664.88096,406.03012 664.66622,410.20405 661.65404,412.23377 C 657.09848,414.14329 651.69444,413.5191 646.84606,414.4945 C 644.48933,414.66163 642.26137,416.29014 640.00097,414.93496 C 637.46169,414.13946 635.53362,411.50396 632.89949,411.31885 C 629.41507,413.05028 631.28347,418.2536 628.35393,420.46803 C 626.14613,423.62117 623.13159,426.53204 621.92048,430.24167 C 621.81847,433.02034 624.1845,435.30387 623.43082,438.21452 C 622.94124,441.92503 620.54338,445.22403 618.72553,448.48195 C 616.56686,450.55028 616.58071,454.07556 614.36878,456.22242 C 613.33566,457.88477 611.56675,458.22077 609.82322,458.50248 C 606.40213,459.93447 604.51458,463.47057 602.67815,466.38817 C 600.46612,469.01249 596.24591,467.22258 594.19701,470.10598 C 592.07616,475.2548 589.09271,480.10257 584.22583,482.96125 C 581.47069,485.42241 578.37654,487.28454 574.60715,487.52796 C 571.07514,488.05472 567.45009,489.68947 564.16448,487.50774 C 559.08355,485.98472 554.17151,482.68688 548.71254,483.08909 C 544.9444,484.05264 541.81014,486.70954 537.96589,487.53298 C 536.25088,487.77979 534.41896,489.22507 535.33994,491.13475 C 536.93119,496.9668 536.66611,503.06764 535.18923,508.84007 C 533.48129,515.01001 531.65805,521.26858 531.03868,527.61508 C 532.49818,531.31555 535.06287,534.64406 536.13605,538.41982 C 536.52669,540.79138 534.2965,542.28615 532.38925,542.96534 C 530.58376,543.99874 529.33678,546.33112 530.83536,548.19344 C 534.78999,553.49371 533.60495,560.61029 532.85327,566.75784 C 533.13851,569.757 535.32572,572.49407 536.60077,575.26338 C 538.10883,578.19985 541.19197,579.92833 543.65871,581.72591 C 544.39924,583.04182 546.29181,583.04316 547.30388,584.22378 C 550.75851,586.20851 554.57846,587.71811 556.90402,591.15243 C 559.00785,593.61545 561.37476,596.7314 565.06487,596.14673 C 571.03685,596.29303 576.86732,594.09857 582.85496,595.30443 C 584.3448,595.72026 587.25037,595.32353 586.44199,593.1406 C 584.66341,589.72574 582.81564,585.38698 585.07688,581.75496 C 589.21641,576.16061 596.53548,574.69582 601.90848,570.71786 C 605.53529,566.79604 609.9881,563.82392 614.908,561.61446 C 620.39141,558.14491 626.93774,558.09035 633.20444,557.89447 C 637.43971,557.52934 641.29824,554.91464 645.41194,554.42914 C 649.21265,555.20537 652.94714,557.5378 656.89066,556.8198 C 660.21694,555.59485 659.57168,551.03762 662.42371,549.19551 C 664.39993,547.44398 666.07265,550.97293 668.2908,550.13945 C 671.70463,549.73171 671.17927,545.44597 672.9235,543.43006 C 677.14079,541.72481 682.01194,542.68544 686.48677,542.14032 C 689.14892,541.79136 692.50002,542.52274 694.1554,539.85752 C 696.43559,536.63813 700.23486,532.76952 704.55351,534.57133 C 707.24196,535.92451 709.13922,539.03674 712.51184,538.76836 C 716.28006,539.48519 719.9092,540.87256 723.83939,540.67078 C 726.61297,540.56292 727.64953,544.17603 730.56328,543.90932 C 734.41023,544.40355 738.90612,543.49136 741.83274,546.6831 C 744.85723,548.9665 748.29848,550.79847 751.41759,552.79709 C 752.87951,553.09991 756.27666,553.43999 755.89052,551.12698 C 754.6256,548.30149 751.37191,545.28624 753.52338,542.0359 C 755.76249,538.54539 759.42578,536.35 762.52733,533.71453 C 767.09004,533.27811 771.65615,534.71702 774.87057,538.03103 C 779.34986,541.77561 783.52482,547.20953 789.91221,547.44487 C 794.96566,548.37765 800.186,547.70585 804.94753,546.02961 C 811.15446,544.48139 817.76223,545.01684 823.57992,547.59804 C 827.36557,548.10231 831.11582,546.62371 834.96472,546.91718 C 839.84409,546.54656 845.37719,544.38641 849.70587,547.80135 C 852.80499,551.15287 858.27415,548.48593 861.55623,551.60625 C 863.94438,553.5815 867.35157,553.95467 870.02287,552.28878 C 872.87476,551.03037 876.40357,552.53685 878.8816,550.34277 C 884.60365,548.57567 889.1704,544.58549 894.23186,541.57118 C 895.74071,541.39101 897.85686,541.09149 898.0658,539.1169 C 898.57127,535.77463 899.31366,532.46374 900.59271,529.29969 C 898.60529,526.8574 896.00467,524.66941 892.75056,524.44917 C 889.66412,523.0625 887.42998,519.48889 883.57271,520.35764 C 879.62817,520.62318 875.28606,520.21799 872.41906,517.23147 C 869.77257,514.96884 866.11625,515.61926 863.38607,513.45562 C 858.49391,510.94697 855.60902,506.14413 853.38009,501.34385 C 852.08301,498.53727 849.45134,496.93013 846.88851,495.52035 C 840.54299,490.39012 833.82899,484.95383 830.05695,477.57054 C 827.90074,473.86268 824.14116,471.43926 822.24385,467.57902 C 820.69568,461.96153 819.96565,456.11995 820.99491,450.32629 C 820.9042,446.72805 818.14831,443.89006 817.62021,440.32198 C 817.11752,437.10671 816.08988,433.84185 813.21201,431.99512 C 811.36814,430.4036 809.684,428.38583 809.78354,425.82683 C 808.23426,420.53313 803.95275,416.14373 804.29952,410.34741 C 804.11916,408.28378 804.16926,404.74685 801.22977,404.88539 C 797.85283,404.7586 794.09673,404.97155 791.63042,402.1842 C 788.36966,398.79677 783.59308,396.07442 782.19079,391.33589 C 782.5213,387.72639 778.76144,386.06464 776.58511,383.94394 C 772.80698,380.32547 767.40238,379.81915 762.62896,378.62871 C 758.96209,377.92002 757.99905,373.8621 755.20799,372.02097 C 753.78097,371.33861 752.14818,371.22054 751.17073,369.84259 C 749.75561,368.82474 747.37053,366.95139 746.04427,369.10195 C 743.94266,371.49285 741.65605,375.35026 737.9988,374.89642 C 734.89559,372.73553 732.93651,369.30928 729.76457,367.15593 C 720.44191,359.09866 710.00146,352.13519 701.30047,343.44069 C 696.57143,337.23177 692.66662,329.37531 684.81741,326.60911 C 683.4818,326.20014 682.16186,325.60188 680.76565,325.6361 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3720" />
+ <path
+ d="M 400.53949,236.81649 C 395.84089,236.60508 392.3627,240.30571 390.37374,244.13583 C 388.58341,247.50914 386.97464,251.13162 385.50868,254.59203 C 386.24782,257.73709 387.43522,262.18062 384.02739,264.20593 C 381.26383,266.31259 380.01392,270.48427 376.44664,271.351 C 373.23566,272.80973 370.43223,275.36649 369.56925,278.91483 C 368.78875,281.88315 366.70239,283.94868 363.85566,284.9731 C 361.37108,285.7901 360.49485,288.45172 360.89084,290.85455 C 360.83804,293.51059 361.78496,296.53746 359.18308,298.27705 C 356.9291,300.679 353.87431,304.26515 356.17323,307.64273 C 357.69649,309.83524 359.5919,311.87616 359.38273,314.7878 C 360.07353,322.42445 360.92495,330.1197 362.24364,337.60264 C 364.02783,339.02086 366.51395,339.99514 367.44269,342.36602 C 369.75607,347.60981 368.44937,353.77174 369.41775,359.09594 C 371.79047,361.31441 375.28145,363.43225 374.99439,367.17045 C 374.90865,368.91386 376.28896,371.84558 373.78905,372.36951 C 371.24735,372.68383 368.96153,374.41042 367.67505,376.56651 C 366.90877,383.9857 366.92759,391.60371 365.64515,398.89602 C 362.34834,405.85664 359.42269,412.99709 358.40802,420.67534 C 357.33271,425.70151 356.67136,430.93204 355.12761,435.77474 C 350.85507,442.31605 344.88128,447.32777 338.29582,451.49371 C 333.76127,453.67989 332.18711,458.69176 329.47412,462.58964 C 324.2628,471.33493 321.96583,481.7073 320.61995,491.78577 C 320.43653,502.83421 316.95889,513.34097 314.4501,524.028 C 312.02161,527.90762 308.95636,531.62324 306.92744,535.61695 C 307.06044,540.0805 309.19709,544.78783 306.78988,548.94652 C 305.45056,553.17189 303.22441,557.3098 302.38188,561.59773 C 303.92963,564.06195 307.05129,564.96992 309.29459,566.66606 C 312.05563,563.92305 314.82759,561.1911 317.58696,558.44632 C 324.36425,559.49608 331.46935,559.43339 338.02011,561.24919 C 339.95329,562.38673 341.54199,564.03161 343.33534,565.37358 C 347.83518,561.34181 353.47274,559.28296 359.15868,557.55085 C 366.02269,555.20713 373.04545,553.14596 379.83041,550.67681 C 385.2818,545.71509 390.3077,540.14695 396.02729,535.56593 C 407.9113,529.75985 419.68191,523.58638 431.6425,518.02637 C 437.37822,517.11059 443.25734,516.76178 448.89942,515.41618 C 451.56761,509.24089 453.25891,502.59056 455.94281,496.44979 C 458.94006,496.44812 462.60248,496.06942 464.42395,499.02025 C 465.44879,500.35735 467.2191,501.84547 468.60643,500.06587 C 472.04545,497.78875 475.11055,494.60867 478.64136,492.71391 C 485.41381,492.87006 492.18609,493.03605 498.95845,493.19675 C 500.94332,487.97558 502.33167,482.28629 504.782,477.39627 C 507.25282,477.82396 510.33071,477.91713 512.44988,479.34229 C 512.64478,483.09221 517.16855,484.13434 520.04512,485.25292 C 521.75222,485.99211 523.71065,486.97313 524.08238,488.92714 C 525.66135,491.41293 528.86876,490.8252 531.0331,489.5935 C 536.65152,487.06236 542.55444,485.10556 548.0445,482.33392 C 552.66261,480.9255 556.71046,484.67435 561.02836,485.64891 C 564.36277,486.6719 567.60707,488.96887 571.14991,487.41545 C 574.95304,486.34971 579.5106,486.91137 582.27573,483.61297 C 586.86191,480.17665 591.55489,476.05519 593.04975,470.32384 C 594.94297,467.78856 598.18309,467.18219 601.09522,466.76576 C 603.62836,464.86482 604.45217,461.32751 607.06394,459.44642 C 609.07069,457.08062 613.10906,457.96447 614.48496,454.94444 C 616.99194,449.85678 620.0906,444.97945 622.26902,439.78295 C 623.05654,437.25345 622.51318,434.5631 621.41217,432.27482 C 620.215,427.8754 624.62603,424.81946 626.68386,421.49913 C 628.85912,419.24309 629.8315,416.29396 630.14022,413.27939 C 630.58342,410.7152 633.62329,410.16578 635.52804,411.56574 C 638.06871,413.32063 641.61239,415.83605 644.69176,413.75863 C 646.09326,411.04763 644.09278,407.9461 642.99261,405.45176 C 640.7711,401.97943 637.73723,399.06563 635.06332,395.86691 C 631.82208,392.53687 629.64352,388.39837 626.27723,385.12026 C 625.34454,382.78768 623.37245,381.03786 622.3852,378.67227 C 620.52186,375.66281 618.421,372.45562 615.05132,371.09153 C 613.54307,369.61001 611.09288,369.23961 610.79625,366.83644 C 607.70107,360.36819 599.76672,358.60246 593.27035,357.82535 C 587.51349,357.28285 581.58181,357.11078 576.41482,354.17206 C 573.54782,352.3828 570.26639,351.61267 566.83713,351.69717 C 558.76861,351.09589 550.43488,352.35097 542.5405,350.65837 C 533.67099,346.77136 523.67774,346.15916 514.13449,347.17297 C 509.58204,347.79911 505.24704,350.03771 500.52688,348.95924 C 496.37289,348.77496 492.60271,345.26016 488.41512,347.05679 C 486.13399,348.43362 483.25477,347.73976 481.60409,345.67715 C 478.80387,342.32015 476.25637,338.19318 476.91357,333.65255 C 476.54607,324.47684 477.68273,315.03613 475.51914,306.04525 C 474.72906,301.90637 470.47985,299.51617 466.77659,298.39189 C 461.91985,297.08892 457.04484,294.20753 454.01134,290.11407 C 452.38212,287.69683 450.99479,285.06301 450.68566,282.08313 C 448.97675,275.10971 450.33963,266.75004 444.92025,261.17073 C 440.18559,257.87645 434.74837,255.22185 429.30854,253.48832 C 423.9453,250.72969 418.69917,247.68174 414.07446,243.7292 C 410.02038,240.81112 406.01724,236.39721 400.53949,236.81649 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3718" />
+ <path
+ d="M 88.407361,282.72212 C 83.192371,282.83793 79.549891,286.94203 75.990651,290.11407 C 73.878491,290.56972 73.162921,288.29489 71.241771,288.0664 C 67.817661,287.21354 63.861311,289.26083 62.629951,292.53933 C 63.419321,294.39048 66.141051,294.70185 67.335241,296.47492 C 70.493011,299.3495 73.210601,303.21039 72.577841,307.71534 C 73.360941,317.99115 68.452101,327.25798 66.006281,336.97177 C 64.301171,342.8592 63.071661,349.11538 59.609271,354.30352 C 55.086151,359.05062 48.078911,358.52535 42.356541,360.72246 C 38.713691,362.982 36.854301,367.23963 34.427251,370.62681 C 33.930331,374.65808 38.202591,377.04884 39.945801,380.21166 C 41.587521,382.13808 42.320711,384.44417 42.748621,386.86296 C 43.800651,389.50227 45.034491,392.09195 44.781771,395.06818 C 44.905011,402.02167 45.626031,409.50655 41.636691,415.55916 C 39.847751,419.92077 38.214121,425.297 40.395981,429.806 C 44.022091,436.0819 50.626181,439.73276 54.729711,445.73718 C 54.729661,450.72325 54.729711,455.70928 54.729711,460.69535 C 50.376261,464.92523 46.164681,469.31558 43.722261,474.98577 C 41.180001,479.27751 39.374431,484.09428 38.537101,489.01427 C 38.770201,491.68177 42.323731,490.46834 44.023301,490.42568 C 48.993111,489.86397 54.525971,489.33121 59.057411,491.70091 C 62.620421,494.50764 64.605381,499.32794 69.208621,500.70486 C 73.072341,502.50338 74.700681,506.70751 76.484411,510.27521 C 80.406791,510.22363 84.673101,509.53947 88.102411,511.91623 C 92.376491,513.66507 97.277191,511.26609 101.56475,512.70045 C 104.13107,514.76209 108.99209,516.35631 111.06246,512.81663 C 112.70887,509.65151 112.25214,504.71814 116.10179,503.14464 C 124.443,501.56906 133.36228,502.29049 141.47258,499.54306 C 145.12291,497.95079 150.03369,496.00292 150.18608,491.30883 C 150.58601,488.13307 153.60614,486.22893 156.57598,485.97905 C 160.75939,484.39761 162.53457,478.41847 167.46785,478.67425 C 171.96546,478.98413 176.64677,481.83658 181.16259,479.8651 C 183.25908,478.02936 185.5542,475.95973 188.64166,476.49588 C 192.12394,476.24219 194.1412,479.63195 197.58752,479.47301 C 201.73496,479.63813 204.66097,475.93691 207.94208,473.96896 C 211.68735,470.80562 216.00525,467.67117 221.17159,467.96487 C 225.33163,468.32025 229.39509,467.24047 232.83365,464.89238 C 235.82263,462.8556 239.61131,460.93845 243.18817,462.29283 C 246.50859,463.77631 249.76888,465.53467 252.78621,467.53045 C 256.69553,469.57471 260.867,471.82651 265.46568,471.04996 C 270.43935,470.48389 275.34688,470.98476 280.20604,471.93581 C 286.82347,472.36089 293.80877,470.63934 300.02923,473.59138 C 306.38302,475.87074 309.28864,482.80338 315.53378,485.22839 C 317.00806,485.63846 319.69804,488.17494 320.5205,485.76123 C 322.63344,478.46685 323.99298,470.71551 327.76721,464.06457 C 330.99078,459.55107 333.00131,453.83093 338.01611,450.96481 C 344.3066,446.67666 350.76408,441.89775 354.44508,435.07766 C 357.48667,425.01425 357.54392,414.04385 362.51898,404.57318 C 367.38739,395.64424 365.15878,385.03257 367.57342,375.50637 C 369.15016,373.19453 371.8915,371.8206 374.64585,371.41102 C 374.35191,367.86902 374.45057,363.74601 371.24954,361.43929 C 368.56122,359.79808 368.3021,357.07935 368.41488,354.19474 C 367.83877,349.41644 368.67011,343.27541 364.49465,339.8972 C 360.72572,337.41598 355.33543,337.1542 351.36631,339.30178 C 349.01863,341.01986 348.65694,343.96425 347.90995,346.51946 C 347.30391,348.76554 344.89462,349.14241 343.52416,350.77455 C 341.73164,351.44495 340.22762,352.86098 340.30016,354.92799 C 340.09462,356.85711 338.87612,358.49318 337.87488,360.05443 C 332.31841,361.95941 326.11531,361.47562 320.72916,359.26643 C 315.69699,357.48225 310.32292,357.4443 305.12665,356.72878 C 300.14657,355.87359 296.67995,350.6088 291.22869,351.31692 C 288.00367,351.04521 284.23423,352.35768 281.96157,349.36836 C 278.36394,346.11648 273.2028,345.02178 268.54445,346.38876 C 265.45704,346.76868 262.89276,348.90096 259.64218,348.50904 C 253.2738,349.43802 247.31832,345.53089 240.98075,346.7373 C 239.30404,347.49589 238.74238,350.3971 236.40618,349.80154 C 228.90523,348.88308 221.39968,347.82836 213.92535,346.89704 C 208.72625,346.21802 206.49597,340.13325 201.19491,339.88206 C 193.85247,338.88086 186.13863,336.22475 181.13355,330.64637 C 179.92946,328.71163 179.25882,326.3475 177.02366,325.21495 C 173.30966,323.13793 168.71734,324.62231 164.66763,323.80067 C 161.09152,322.97093 158.18879,320.08564 155.02469,318.25664 C 148.36967,313.05353 140.65676,309.06311 132.13463,308.12197 C 126.27507,306.88495 120.18598,307.05939 114.51882,305.18842 C 111.94362,303.2977 109.7631,300.59251 109.50858,297.28818 C 108.13375,291.5707 102.5934,288.40416 97.837971,285.78185 C 94.848891,284.46028 91.798101,282.59746 88.407361,282.72212 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3716" />
+ <path
+ d="M 483.65174,154.96768 C 479.80269,155.28588 479.88648,160.00783 479.41117,162.8534 C 478.62788,166.62918 478.90504,170.62297 478.20582,174.36974 C 476.45866,176.85867 472.62365,175.95026 470.37817,174.57306 C 467.85047,173.691 464.84112,174.63802 463.7995,177.23068 C 461.85683,180.05991 460.46997,183.20137 459.50084,186.43794 C 458.32236,189.13333 456.20184,191.34989 453.19287,191.84204 C 449.2724,192.6481 447.16694,196.29269 445.78463,199.66805 C 445.14378,202.54227 441.84027,201.61965 439.70665,202.10772 C 435.74923,202.91854 431.34267,203.89141 427.63848,201.84631 C 423.2702,201.02195 418.80359,202.06331 414.4375,202.44174 C 411.48736,210.37663 409.30346,218.69612 405.65141,226.28768 C 399.33266,228.66447 392.32947,229.45499 386.26385,232.45974 C 384.54894,234.82051 383.22611,238.1904 385.20373,240.85375 C 386.22481,242.40995 387.58184,243.71622 388.76172,245.15241 C 391.27251,241.51086 393.71819,236.83476 398.60798,236.27916 C 402.92732,235.21287 406.96183,237.20232 410.11793,239.91346 C 414.11289,243.03296 418.17311,245.93092 422.32324,248.75399 C 428.83987,252.97584 436.51096,255.01368 443.14851,258.97783 C 446.7045,261.50167 449.30577,265.74669 449.91599,270.02945 C 449.85692,275.1946 450.9486,280.44843 452.35229,285.41075 C 454.72705,292.75589 462.29976,296.25217 469.06445,298.55611 C 472.9523,300.1326 476.30358,303.50083 476.60212,307.84736 C 478.26837,313.60613 477.23697,319.80771 477.52598,325.75225 C 477.60429,331.51645 476.66156,337.99126 480.45679,342.84527 C 481.6329,345.47337 484.38306,347.73584 487.39854,346.60659 C 489.77512,345.69783 492.12953,345.14806 494.48552,346.50494 C 499.76641,348.49631 505.76311,348.96848 511.02667,346.92609 C 520.22116,344.94139 530.04984,345.64438 539.01151,348.42191 C 545.39118,351.70767 552.90519,350.07786 559.82222,350.41923 C 565.86925,350.12457 572.02391,350.73476 577.36545,353.79523 C 586.64145,358.26452 598.09387,355.25321 606.88967,361.24527 C 610.63132,363.31964 611.16468,368.26854 615.08036,370.13304 C 619.76074,372.617 622.56356,377.1352 624.99637,381.63825 C 629.27138,388.3028 634.72826,394.13123 639.68254,400.26843 C 642.69611,403.29852 645.28298,406.84531 645.85356,411.2172 C 645.75523,413.5557 648.25421,413.73722 649.90532,413.14869 C 653.5753,412.53882 657.56437,412.81727 661.14573,411.89975 C 663.1826,409.90376 664.9832,406.68364 663.14984,403.95595 C 661.72775,401.15133 664.61812,398.22484 666.91119,397.02871 C 669.99953,395.26994 670.56784,389.28357 666.5336,388.34426 C 665.04278,387.79505 661.66092,388.17259 662.24944,385.68664 C 663.41017,382.56522 666.14328,380.29828 667.09996,377.04575 C 670.59432,368.28333 674.58334,359.58606 677.14953,350.52767 C 677.58302,348.73801 676.5604,347.20806 675.55205,345.93856 C 673.34756,341.63021 673.18574,336.15372 675.56999,331.92489 C 676.66566,328.94393 678.13984,325.73561 681.17228,324.30003 C 681.16099,317.72619 681.15425,311.15234 681.15774,304.57848 C 674.92482,300.29929 668.9119,295.57059 663.49838,290.34643 C 661.12017,287.66602 661.05966,282.79545 657.39893,281.44414 C 653.05951,280.89097 648.34121,281.27034 644.59008,278.55416 C 640.50598,276.24479 635.85474,277.08001 631.44747,277.35693 C 626.19521,277.37336 620.38584,277.97587 616.08244,274.37168 C 612.65582,272.17957 610.09814,269.00028 608.15315,265.48391 C 605.53752,262.73182 600.91532,263.24058 598.84421,259.68943 C 596.15552,255.49147 592.65163,251.9683 589.40458,248.26022 C 587.5306,246.00973 585.88214,242.04405 582.41928,242.27695 C 579.32671,243.52456 580.92985,247.58594 579.19529,249.84318 C 578.18847,252.06651 575.71453,254.79382 573.0232,253.31405 C 567.82117,251.61919 565.58582,246.14847 561.60852,242.93047 C 557.39485,241.12612 552.98498,239.76843 548.68349,238.109 C 542.9586,234.75305 542.83192,227.44724 541.18026,221.77402 C 540.87099,219.15858 539.11853,216.93946 536.48459,216.39786 C 534.23902,215.44024 529.85457,215.11322 530.16733,211.69257 C 530.31724,206.87911 532.56542,201.1333 528.88307,197.08062 C 526.88097,194.07415 524.21068,191.63669 521.25051,189.64741 C 517.72073,186.72507 517.18635,181.96487 514.17803,178.68293 C 511.7514,176.53465 507.90143,176.04726 506.68442,172.62704 C 504.01786,166.63868 498.41858,162.72951 492.65569,160.00699 C 489.61321,158.35645 487.51802,154.69933 483.65174,154.96768 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3714" />
+ <path
+ d="M 110.65583,135.76894 C 109.0729,135.85616 105.7456,135.76031 106.60408,138.25229 C 108.13291,142.32066 106.28458,146.4812 104.78874,150.2043 C 104.34359,155.48828 104.45252,160.93327 105.18087,166.17905 C 106.36577,170.69726 110.51604,174.12677 114.78022,175.70581 C 120.2193,177.701 126.3821,176.67922 131.64087,179.10408 C 133.95085,180.5194 133.53613,184.88652 130.50811,184.98569 C 126.92661,185.70758 122.94475,186.82976 119.35483,186.07488 C 118.66993,184.21732 116.23294,185.04271 116.3777,186.83005 C 114.51013,188.67546 111.31174,187.6103 110.42226,185.25163 C 108.92717,183.5084 108.27298,180.24452 105.3406,181.22436 C 100.73327,181.53438 95.847811,180.60678 91.384501,181.77622 C 89.682831,182.87602 91.335651,184.621 91.674951,185.92965 C 92.310501,191.54725 91.370281,197.39873 92.444621,202.90646 C 93.309231,204.88319 94.217521,207.35643 94.146001,209.44664 C 92.434111,213.61469 88.355501,217.9411 89.975791,222.74419 C 92.535931,226.03617 98.421191,225.30343 100.03991,229.64238 C 100.07941,231.49768 100.05473,233.62176 101.75458,234.91524 C 103.85675,236.56448 104.4251,240.20097 101.72452,241.56535 C 99.461141,243.29028 95.839071,242.20769 94.666581,239.59029 C 93.639321,238.3905 91.848051,235.42139 90.062931,237.16503 C 89.022191,239.93907 89.965571,243.20782 88.160501,245.80592 C 86.508751,248.81409 83.149571,251.49028 79.592231,250.54026 C 76.587951,251.19907 74.999031,254.40064 72.839241,256.32021 C 69.857271,259.35737 71.480171,263.95941 70.204881,267.6529 C 69.889341,271.83841 67.347131,275.549 63.521001,277.36511 C 60.551491,279.32072 55.088191,280.48967 55.397741,285.01667 C 55.825001,288.26016 58.049621,291.07701 61.017931,292.43767 C 63.422111,289.00683 67.716541,285.86584 72.011481,287.68881 C 73.849911,288.1075 75.787421,291.14104 77.105701,288.66645 C 80.547041,284.18675 86.477981,280.61752 92.183211,282.56237 C 96.798721,284.12152 101.30966,286.2868 104.87588,289.56221 C 109.08145,292.05727 110.44708,296.94702 111.59982,301.38353 C 113.40098,305.58213 118.94244,305.08091 122.66564,305.9432 C 131.25139,307.19394 140.42668,307.99931 147.90607,312.66751 C 153.47792,315.84534 158.5443,320.15301 164.15672,323.19632 C 168.26438,323.51696 172.59706,322.98128 176.60253,323.86436 C 180.59772,326.25244 181.3232,331.73981 185.70267,333.6489 C 191.24455,337.5483 198.11748,338.34317 204.51477,340.04242 C 208.15413,342.0139 210.62161,346.33056 215.2407,346.24637 C 222.29612,347.2679 229.48553,348.04699 236.44973,349.23517 C 238.94699,348.62895 239.94693,345.04488 242.89772,345.74977 C 249.99841,346.45911 257.52199,349.39237 264.57983,346.80991 C 269.14631,345.23137 274.35498,343.75319 278.84093,346.43232 C 281.59783,347.76122 283.2948,351.13236 286.78229,350.26586 C 291.0369,350.41519 295.6195,350.13982 299.14338,352.96745 C 302.88461,356.39821 308.46176,356.13063 313.19517,356.90464 C 317.4369,357.42085 321.53908,358.59593 325.5017,359.99634 C 329.65383,360.52935 335.07006,361.47952 338.25247,358.06485 C 340.24226,356.10713 338.89262,352.45276 341.67978,351.13761 C 344.2784,349.34968 347.46698,347.50661 347.75018,344.02159 C 348.55089,340.009 352.03606,337.00682 356.23132,337.38481 C 357.87002,337.18648 361.49729,337.97632 361.16897,335.32261 C 359.67615,327.59956 359.6228,319.61307 358.10475,311.91234 C 356.92366,308.94671 353.21148,306.57355 354.77907,302.96648 C 355.78974,299.95964 359.51986,298.36345 360.28312,295.44383 C 360.53709,292.45229 359.78792,288.98239 360.64421,286.27805 C 363.23084,283.75206 367.63443,283.04472 368.67713,279.1641 C 369.92355,276.22185 371.02824,272.75341 374.41349,271.65597 C 376.32804,270.62483 378.63301,270.33029 379.69968,268.18509 C 380.92152,266.08809 382.52425,264.42013 384.44856,263.00056 C 386.45968,260.67605 384.98963,257.6108 384.85519,254.98414 C 385.84435,251.90551 387.41882,249.06743 388.70363,246.08185 C 385.41908,243.38343 382.129,239.07019 384.30334,234.65264 C 385.10916,232.27781 386.35205,230.26785 389.15357,230.24658 C 394.63931,228.66524 400.22831,227.35174 405.60782,225.50347 C 408.16053,217.96133 411.3571,210.55059 413.15952,202.8048 C 413.14767,201.34455 412.08262,200.16139 411.77991,198.76754 C 404.92199,190.37272 396.47603,183.35659 389.47335,175.16848 C 383.86018,169.23131 375.05136,170.03258 367.74769,168.05246 C 360.14408,166.42969 352.67649,164.18637 345.58635,161.06713 C 340.48066,159.48505 336.0805,163.97539 334.43307,168.35743 C 333.04453,171.75757 330.30988,174.589 326.73613,175.60416 C 323.14571,177.63146 320.70198,181.57979 316.35252,182.28451 C 311.91231,182.93419 307.75255,184.68464 304.52056,187.8946 C 301.57164,190.14633 298.87301,193.05671 295.71607,194.83195 C 289.45137,195.71791 282.70837,194.03113 276.92953,197.30481 C 273.4235,196.76865 270.50534,192.61878 266.48286,193.6849 C 257.83103,194.01215 249.10484,193.7149 240.50153,194.64315 C 237.42438,196.59223 235.14428,199.79592 231.75898,201.1928 C 224.74301,199.13338 217.88444,196.56716 210.94822,194.25105 C 207.59136,188.57358 202.46443,184.25859 196.99212,180.70155 C 194.30706,179.85928 191.25213,180.75135 188.83047,178.91529 C 183.54995,175.4178 177.3662,173.18725 172.10055,169.67898 C 166.34885,167.85706 161.58436,163.7693 156.59052,160.55885 C 150.85978,157.7481 143.44438,161.25165 138.4519,156.47802 C 135.15875,153.36147 133.50676,148.43706 129.23013,146.31227 C 124.07983,142.90631 119.56182,138.31072 113.85078,135.8706 C 112.81116,135.62459 111.71484,135.70473 110.65583,135.76894 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path3712" />
+ <path
+ d="M 262.21264,2.9171002 C 259.3383,3.2485122 257.38559,6.5560742 254.48667,6.3589332 C 251.9618,5.0844622 249.54526,3.2967822 246.52834,3.7158382 C 242.51107,3.8475922 237.92809,2.9160072 234.60539,5.7489882 C 232.02006,7.2362572 228.9037,6.1725592 226.44375,4.9066832 C 224.25561,7.4594072 220.58744,9.0797362 219.35677,12.298635 C 219.13654,14.213016 219.71818,16.743722 217.41075,17.49769 C 215.71926,18.975531 211.89555,19.117166 212.73451,22.057755 C 212.50061,25.583581 213.1864,29.483418 212.41013,32.788684 C 208.33649,36.337843 205.08061,41.972131 199.50449,43.11538 C 198.11683,43.254233 196.09655,43.671124 195.83032,41.692175 C 195.21517,39.955776 193.1124,39.409242 191.86565,40.84987 C 190.50253,41.63342 188.94465,44.300867 187.36368,42.47639 C 185.00532,40.522005 182.61726,37.088975 179.08585,38.29391 C 175.38055,39.034111 173.96292,43.052308 170.86612,44.68381 C 167.79125,45.484494 164.49485,43.040722 163.48869,40.225402 C 161.58663,39.108499 159.06014,38.357163 156.85193,38.831242 C 155.73939,39.728658 155.28573,41.736941 153.41007,41.241977 C 149.20324,40.533423 144.25648,40.734944 140.73195,38.11964 C 138.37763,36.507132 137.80519,33.784964 138.28111,31.106411 C 138.45148,29.052916 139.23309,25.980043 136.60756,25.151048 C 133.40936,23.531178 129.38163,21.951548 125.83187,23.263123 C 124.22538,25.273548 127.38914,27.168002 127.45839,29.260915 C 128.96757,34.943734 129.53099,41.454452 126.96462,46.876707 C 123.42429,52.418135 120.19035,58.291197 115.24852,62.731638 C 110.07521,68.212607 104.7484,73.471211 98.361761,77.518081 C 94.749671,80.531572 90.171391,82.680999 88.189551,87.176645 C 85.690101,90.145564 84.484981,93.893847 84.471791,97.778072 C 83.897351,102.19604 83.733901,107.72784 87.318201,110.94998 C 90.564781,112.75743 92.855471,116.13772 92.386531,119.95394 C 92.434021,124.07714 97.864971,125.29342 97.668211,129.5459 C 98.506191,133.03857 98.844001,137.29389 101.63738,139.79167 C 103.75344,140.47123 103.54543,137.6351 104.93397,136.93074 C 107.84339,134.79494 112.1408,134.09612 115.40471,135.65276 C 117.11321,136.83731 119.09863,137.51998 120.57472,139.12364 C 126.21061,143.60931 133.07495,147.11651 136.76729,153.54448 C 138.30644,155.83158 140.57715,157.76909 143.44764,158.04645 C 148.23439,159.19252 153.69453,158.03323 158.11536,160.3991 C 159.39144,162.35957 161.95934,162.97646 163.64846,164.55253 C 171.13045,169.08977 179.43035,172.31684 186.84087,176.86761 C 189.75159,179.30596 193.7598,179.76506 197.41325,180.07709 C 203.00109,183.74377 208.12713,188.16864 211.71793,193.85894 C 218.40395,195.94213 224.9881,198.77278 231.80253,200.21979 C 235.34151,198.83346 237.53461,195.03741 240.9517,193.65562 C 250.5656,193.01986 260.22122,193.42968 269.85148,193.30708 C 272.26793,194.27788 274.66077,196.32551 277.09823,196.66178 C 281.00782,194.31579 285.52151,193.98036 289.96516,194.23652 C 292.73452,193.96806 296.06433,195.22991 297.94189,192.51994 C 303.29129,188.3795 308.06717,182.47896 315.24881,181.8924 C 319.93258,181.29301 322.90702,177.16613 326.6635,174.86351 C 332.29415,173.47308 333.64593,167.00319 336.9164,162.99863 C 339.66219,160.02536 344.49602,158.86192 348.01159,161.19784 C 358.00585,165.57305 368.72527,167.87087 379.52885,169.47807 C 384.78906,169.91191 389.24531,173.14943 392.29592,177.3238 C 398.0234,183.75382 403.98488,190.13426 410.58906,195.63068 C 412.73263,195.36741 411.95943,192.21608 412.47699,190.67851 C 413.576,182.64809 412.71511,174.27612 414.36491,166.41141 C 415.63592,162.73289 419.56201,159.70194 418.32953,155.41788 C 417.79571,151.36664 416.98338,146.99825 413.45053,144.44922 C 410.25065,141.47534 406.32762,139.62405 403.19709,136.49506 C 398.29406,132.55005 398.05821,125.51426 393.94702,120.90097 C 392.4806,118.26057 389.5964,117.09622 387.46924,115.14698 C 384.90343,112.60882 385.31038,108.61102 383.33031,105.80901 C 380.97943,104.41014 377.94048,102.91413 377.41967,99.970972 C 376.26912,97.823162 374.03512,96.669212 371.72685,96.325822 C 368.83522,95.210366 368.25707,91.415556 365.26432,90.589432 C 360.24743,87.307719 354.97769,84.256158 349.92856,81.135285 C 346.80945,78.2732 345.15876,73.887168 342.75444,70.403157 C 339.39177,66.690876 334.51026,64.837787 330.75415,61.516879 C 325.57982,57.735392 319.97367,54.025839 316.86278,48.169089 C 315.07617,46.534618 314.55777,42.152754 311.48119,43.295501 C 309.06734,43.396526 304.42502,44.99138 303.50013,41.634085 C 303.58894,38.644178 307.03121,35.801863 304.89429,32.818928 C 301.58772,28.592913 296.77233,25.811708 292.0709,23.466438 C 288.86429,21.947459 286.00988,19.785497 282.90723,18.093113 C 279.1903,16.934669 277.1019,13.290483 276.82228,9.5974505 C 275.63004,5.8683722 271.16203,5.0963902 267.9926,3.7303602 C 266.11192,3.2068512 264.15735,2.8433252 262.21264,2.9171002 z "
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:black;stroke-width:0.99999964;stroke-opacity:1"
+ id="path1873" />
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien-sad.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien-sad.svg
new file mode 100755
index 0000000..34ea921
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien-sad.svg
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg3927"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ width="218"
+ height="268"
+ sodipodi:docname="bichotriste.png">
+ <metadata
+ id="metadata3933">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs3931">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective3935" />
+ <inkscape:perspective
+ id="perspective4038"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ id="namedview3929"
+ showgrid="false"
+ inkscape:zoom="1"
+ inkscape:cx="190.73982"
+ inkscape:cy="134"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3927" />
+ <g
+ id="g3939"
+ transform="translate(0.5423639,1.4067796)">
+ <path
+ style="fill:#fbfbfb"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -109,0 -109,0 0,-134 z"
+ id="path3971" />
+ <path
+ style="fill:#d0d0d0"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -109,0 -109,0 0,-134 z m 100.99595,-12.86358 c 14.28715,-11.47849 9.77967,-34.299546 -7.743693,-39.205784 -16.710604,-4.67868 -31.835729,15.78224 -23.471359,31.751514 3.198397,6.10639 4.076245,6.08149 4.076245,-0.11562 0,-11.70754 7.711033,-19.059429 14.789988,-14.101136 5.084892,3.561596 7.251564,16.022216 3.940167,22.660066 l -1.555558,3.11819 3.23008,-0.64601 c 1.776544,-0.35531 4.806902,-1.91286 6.73413,-3.46122 z m -46.225375,-0.78086 c 5.274705,-4.01376 6.057065,-6.01269 6.362392,-16.25592 L 61.41317,94.699276 56.456585,93.393771 C 53.730463,92.675743 51.18815,92.068406 50.807,92.044133 50.42585,92.01986 47.422253,89.507917 44.132341,86.462039 37.330646,80.164869 35.842582,80.03252 29.609474,85.170374 c -7.967136,6.567187 -10.510618,18.572816 -5.828576,27.511776 2.586351,4.93787 4.850897,6.84184 3.924608,3.29971 -1.038158,-3.96993 1.29917,-12.14038 4.344059,-15.18527 8.578834,-8.578835 19.249959,3.90266 15.545681,18.18302 l -1.342028,5.17365 2.623391,-0.65449 c 1.442865,-0.35997 4.09515,-1.77441 5.893966,-3.14321 z M 78.337731,76.632247 C 81.222918,75.426739 82.09526,74.35995 83.027804,70.896744 87.131552,55.656588 72.315153,39.852014 57.747743,43.930636 48.219667,46.598333 41.674062,55.129607 41.562368,65.025995 41.50396,70.201132 44.290565,79 45.987941,79 c 0.376305,0 0.756331,-1.841056 0.844502,-4.091236 0.551112,-14.064738 13.080384,-19.041615 18.608623,-7.391716 1.939644,4.087498 2.234687,12.579319 0.587505,16.909389 -1.044377,2.745434 -0.807751,2.640695 3.825742,-1.693395 2.716436,-2.540907 6.533974,-5.286265 8.483418,-6.100795 z"
+ id="path3969" />
+ <path
+ style="fill:#afafaf"
+ d="M 0,134.00646 0,0 l 109,0 109,0 0,133.98012 0,133.98012 -109,0.0263 -109,0.0263 0,-134.00647 z m 98.453492,-10.27864 c 5.274728,-2.98763 10.037828,-9.43893 11.514938,-15.59621 C 113.13456,94.933688 102.01869,80.679194 88.5,80.601446 c -9.62392,-0.05535 -18.983463,7.908453 -21.468428,18.266948 -1.502398,6.262696 0.400657,13.853476 4.786614,19.092536 l 2.897372,3.46093 -0.04125,-6.96093 c -0.04824,-8.14139 1.863504,-12.65344 6.342615,-14.969683 2.68824,-1.390143 3.277906,-1.390143 5.966146,0 1.64069,0.848433 3.743607,2.997493 4.673149,4.775683 2.244716,4.29408 2.240033,14.18096 -0.0088,18.48307 -1.679401,3.21283 -1.672804,3.24981 0.576851,3.23355 1.251624,-0.009 4.054751,-1.02413 6.229172,-2.25573 z m -46.51038,-0.6988 c 2.124889,-1.08404 5.206073,-3.59983 6.847076,-5.59065 2.875137,-3.48804 2.982371,-3.9807 2.948713,-13.54712 C 61.704181,94.022914 61.68848,93.960402 59.101986,93.392091 52.042791,91.841027 49.063567,90.248415 43.762413,85.19197 l -5.76192,-5.495941 -4.085058,1.842105 C 24.831077,85.634608 18.683569,97.641337 20.961757,106.83803 22.167543,111.7056 26.35968,119 27.951318,119 c 0.507617,0 0.682972,-1.47876 0.389676,-3.28612 C 27.046872,107.73914 32.187363,98.666667 38,98.666667 c 8.195041,0 12.331725,13.484773 7.541358,24.583333 -1.029564,2.38535 1.461487,2.29936 6.401754,-0.22098 z m 17.60394,-39.127403 c 2.174122,-2.25411 5.975419,-5.072099 8.447329,-6.262197 4.024993,-1.937829 4.636936,-2.697049 5.859355,-7.269535 1.187339,-4.441266 1.160006,-5.806141 -0.210028,-10.487803 -6.681129,-22.830669 -35.597191,-22.860802 -42.274609,-0.04405 -1.28368,4.386336 -1.353249,6.16919 -0.390213,10 1.168917,4.649769 4.584919,11.163578 5.852673,11.160179 0.367643,-9.85e-4 0.723992,-2.388205 0.791887,-5.304932 0.150454,-6.463377 2.418355,-11.146412 6.393481,-13.202029 2.68824,-1.390143 3.277906,-1.390143 5.966146,0 6.459909,3.340548 8.510885,14.107872 4.525603,23.758753 -1.213702,2.939138 0.879512,1.963493 5.038376,-2.348383 z"
+ id="path3967" />
+ <path
+ style="fill:#79d17a"
+ d="M 0,134 0,0 l 109,0 109,0 0,133.97626 0,133.97625 -79.06231,0.0291 c -63.145239,0.0232 -78.919565,-0.22366 -78.353294,-1.22626 0.567452,-1.00468 0.440132,-1.00575 -0.637692,-0.005 C 58.932995,267.69092 51.355091,268 29.3,268 L 0,268 0,134 z m 99.973564,-10.79527 c 2.630356,-1.62141 5.720526,-4.77451 7.499996,-7.65275 2.63068,-4.25502 3.02644,-5.83102 3.02644,-12.05198 0,-6.220962 -0.39576,-7.796963 -3.02644,-12.051984 C 103.54769,85.09806 96.740321,80.803876 89.705528,80.239686 85.410732,79.895244 83.537749,80.32531 79,82.697844 66.210295,89.384861 62.283614,104.81225 70.342101,116.71354 c 4.615055,6.81581 5.473162,6.56971 4.964404,-1.42376 -0.500208,-7.85913 1.408324,-12.76237 5.943495,-15.26952 2.460736,-1.360348 3.039264,-1.360348 5.5,0 6.033744,3.3356 8.191499,14.74872 4.25,22.47974 -1.1,2.15759 -2,4.10898 -2,4.33644 0,1.12677 7.026503,-1.19866 10.973564,-3.63171 z m -46.288911,-0.777 c 7.213223,-4.19806 8.524757,-7.01982 8.676923,-18.66838 L 62.493638,93.649759 57.403723,92.503411 C 51.089521,91.081329 45.753167,87.854009 42.359902,83.405209 40.801909,81.362575 38.888094,80 37.577092,80 33.747337,80 26.35342,85.541702 23.337628,90.672404 20.942724,94.746803 20.5,96.604369 20.5,102.57842 c 0,6.12234 0.405209,7.73237 3,11.91999 4.246844,6.8538 5.5,6.88798 5.5,0.15002 C 29,105.54341 32.763362,99 38,99 c 7.121193,0 11.47311,13.14525 7.5,22.65424 -0.825,1.97451 -1.5,3.80884 -1.5,4.07629 0,0.98061 5.615099,-0.93434 9.684653,-3.3028 z M 68.812889,85.08321 c 1.750428,-2.178174 5.594218,-5.1138 8.659366,-6.613437 4.849762,-2.372768 5.645763,-3.193467 6.627572,-6.83321 C 86.737408,61.858573 82.332687,50.955127 73.551984,45.526436 63.264319,39.166061 50.230278,42.604806 43.526436,53.448016 40.903933,57.689814 40.5,59.287904 40.5,65.42158 c 0,5.947022 0.446291,7.837649 2.792154,11.82842 1.535684,2.6125 3.223184,4.75 3.75,4.75 0.526815,0 0.958545,-2.3625 0.9594,-5.25 0.0019,-6.276223 2.434391,-11.621238 6.248446,-13.729736 2.460736,-1.360352 3.039264,-1.360352 5.5,0 5.694236,3.147906 8.029661,13.784646 4.75,21.633979 C 62.677182,89.016861 62.677831,89 64.332635,89 c 0.73295,0 2.749064,-1.762556 4.480254,-3.91679 z"
+ id="path3965" />
+ <path
+ style="fill:#76c977"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -17.54966,0 c -22.41276,0 -22.13119,0.12776 -25.39938,-11.52505 l -2.44904,-8.73211 -14.41302,-14.62142 c -19.89135,-20.17896 -28.56332,-29.89863 -31.03472,-34.78413 -1.67243,-3.3061 -2.52552,-4.05294 -4.14556,-3.62929 -1.12188,0.29338 -2.28433,0.9291 -2.58322,1.41271 -0.29889,0.48361 -1.52938,0.88206 -2.73442,0.88545 -1.20504,0.003 -3.38503,0.62916 -4.84443,1.39061 -1.4594,0.76144 -5.3969,1.70286 -8.75,2.09202 C 98.414467,201.14827 98,201.36962 98,203.74476 c 0,2.99316 -4.569349,17.60172 -8.972848,28.68689 -3.053527,7.68681 -5.479899,11.02358 -19.864842,27.31835 -3.034608,3.4375 -6.311001,6.25 -7.280873,6.25 -0.969872,0 -2.041518,0.45 -2.381437,1 -0.389378,0.63003 -11.510384,1 -30.059017,1 L 0,268 0,134 z m 106.39219,57.97158 c 3.90929,-1.11563 7.79758,-2.40841 8.64063,-2.87284 0.84306,-0.46444 2.97609,-1.16142 4.74007,-1.54886 4.53363,-0.99575 16.87352,-9.29153 23.13509,-15.55309 10.04636,-10.04637 17.94615,-25.16825 21.06667,-40.3261 0.66004,-3.20611 1.04785,-5.98153 0.86179,-6.16758 -0.18605,-0.18606 -3.93786,0.0672 -8.33736,0.56288 C 146.92639,127.14444 145,126.69913 145,123.40786 c 0,-2.91037 1.96942,-3.82918 10.43703,-4.86926 11.76346,-1.44491 23.80266,-8.54913 27.4296,-16.18596 1.46095,-3.076143 4.13503,-6.276889 7.30445,-8.743093 2.74988,-2.139749 5.50632,-5.064749 6.12542,-6.5 0.61911,-1.435251 2.17416,-3.903553 3.45567,-5.485115 2.62985,-3.245584 2.39389,-4.308151 -0.60078,-2.705452 C 196.31881,80.434931 188.49695,80.243856 182,78.5 c -8.51768,-2.286242 -15.21143,-1.955942 -19.70559,0.972363 -8.38494,5.46346 -10.21978,7.246346 -12.74442,12.383529 -2.25078,4.579915 -2.95216,5.270086 -4.84106,4.763654 -1.21491,-0.32573 -2.54643,-0.598381 -2.95893,-0.605891 -1.42281,-0.0259 -0.74275,-3.781179 1.67461,-9.247274 1.6222,-3.668074 3.76606,-6.468991 6.47799,-8.463363 l 4.05337,-2.980884 -2.91118,-4.590452 C 146.99771,64.350092 136.40942,54.230352 133.7049,54.159104 132.4922,54.127156 129.475,53.965789 127,53.800509 122.58105,53.505412 122.5,53.436962 122.5,50 c 0,-3.441745 -0.11651,-3.539308 -7,-5.861674 -8.36363,-2.821739 -23.825736,-3.371729 -29.296406,-1.042079 L 82.907188,44.5 85.496837,48 c 3.731621,5.043414 5.853884,13.195568 5.229065,20.086177 l -0.519573,5.729949 3.646835,0.67591 c 5.819356,1.078568 13.127756,5.602957 16.782586,10.389546 11.11115,14.551829 6.91138,35.961548 -8.75649,44.639138 C 97.168269,132.12988 95.506156,132.5 88.5,132.5 c -7.011716,0 -8.666662,-0.36921 -13.396525,-2.98868 -2.968088,-1.64377 -6.302802,-4.21448 -7.410475,-5.71269 l -2.013952,-2.72402 -3.367328,2.95656 c -6.576277,5.77405 -11.041589,7.4326 -20.06172,7.45152 -7.83144,0.0164 -8.25,0.12908 -8.25,2.22026 0,1.21162 -0.536915,3.38134 -1.193144,4.82161 -1.842144,4.04307 0.111889,4.67687 12.693144,4.11714 13.208617,-0.58764 38.303019,2.17635 46.519589,5.12384 C 111.34767,154.69901 123,164.37514 123,173.49178 c 0,4.12626 -3.31857,3.87805 -17.64019,-1.3194 -11.451495,-4.15586 -25.441908,-5.6069 -40.85981,-4.23786 -10.571985,0.93874 -19.603053,2.77507 -22.523022,4.57971 -1.331838,0.82312 6.519189,7.96433 12.523022,11.3908 6.375488,3.63859 12.735621,5.65262 23.924202,7.57595 4.908311,0.84375 9.145811,1.7557 9.416667,2.02656 1.210563,1.21056 12.080955,0.31055 18.551321,-1.53596 z m 41.18105,-82.12522 C 146.70796,108.11186 146,105.94769 146,105.03709 c 0,-1.84829 8.88412,-9.907267 13.50937,-12.254647 4.29608,-2.180317 12.95499,-4.201965 14.86242,-3.470017 2.81355,1.079662 1.90339,5.238777 -1.87179,8.55343 -1.925,1.690173 -3.5,3.452594 -3.5,3.916504 C 169,104.50687 155.62255,113 151.3312,113 c -1.45187,0 -2.71245,-1.05786 -3.75796,-3.15364 z m -47.599676,13.35837 c 2.630356,-1.62141 5.720526,-4.77451 7.499996,-7.65275 2.63068,-4.25502 3.02644,-5.83102 3.02644,-12.05198 0,-6.220962 -0.39576,-7.796963 -3.02644,-12.051984 C 103.54769,85.09806 96.740321,80.803876 89.705528,80.239686 85.410732,79.895244 83.537749,80.32531 79,82.697844 66.210295,89.384861 62.283614,104.81225 70.342101,116.71354 c 4.615055,6.81581 5.473162,6.56971 4.964404,-1.42376 -0.500208,-7.85913 1.408324,-12.76237 5.943495,-15.26952 2.460736,-1.360348 3.039264,-1.360348 5.5,0 6.033744,3.3356 8.191499,14.74872 4.25,22.47974 -1.1,2.15759 -2,4.10898 -2,4.33644 0,1.12677 7.026503,-1.19866 10.973564,-3.63171 z m -46.288911,-0.777 c 7.213223,-4.19806 8.524757,-7.01982 8.676923,-18.66838 L 62.493638,93.649759 57.403723,92.503411 C 51.089521,91.081329 45.753167,87.854009 42.359902,83.405209 40.801909,81.362575 38.888094,80 37.577092,80 33.747337,80 26.35342,85.541702 23.337628,90.672404 20.942724,94.746803 20.5,96.604369 20.5,102.57842 c 0,6.12234 0.405209,7.73237 3,11.91999 4.246844,6.8538 5.5,6.88798 5.5,0.15002 C 29,105.54341 32.763362,99 38,99 c 7.121193,0 11.47311,13.14525 7.5,22.65424 -0.825,1.97451 -1.5,3.80884 -1.5,4.07629 0,0.98061 5.615099,-0.93434 9.684653,-3.3028 z M 68.812889,85.08321 c 1.750428,-2.178174 5.594218,-5.1138 8.659366,-6.613437 4.849762,-2.372768 5.645763,-3.193467 6.627572,-6.83321 C 86.737408,61.858573 82.332687,50.955127 73.551984,45.526436 63.264319,39.166061 50.230278,42.604806 43.526436,53.448016 40.903933,57.689814 40.5,59.287904 40.5,65.42158 c 0,5.947022 0.446291,7.837649 2.792154,11.82842 1.535684,2.6125 3.223184,4.75 3.75,4.75 0.526815,0 0.958545,-2.3625 0.9594,-5.25 0.0019,-6.276223 2.434391,-11.621238 6.248446,-13.729736 2.460736,-1.360352 3.039264,-1.360352 5.5,0 5.694236,3.147906 8.029661,13.784646 4.75,21.633979 C 62.677182,89.016861 62.677831,89 64.332635,89 c 0.73295,0 2.749064,-1.762556 4.480254,-3.91679 z"
+ id="path3963" />
+ <path
+ style="fill:#8e8e8e"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -17.45295,0 c -10.25131,0 -18.4206,-0.44089 -19.79803,-1.06849 -1.84852,-0.84225 -2.85939,-2.90678 -4.77394,-9.75 -2.26879,-8.10937 -2.93069,-9.24169 -10.04357,-17.18151 -4.18809,-4.675 -10.37297,-11.0517 -13.74418,-14.17044 -8.64522,-7.9978 -22.98848,-24.34471 -24.92627,-28.4083 -1.62294,-3.40335 -4.65602,-4.53566 -6.81106,-2.54272 -1.2064,1.11566 -13.67156,4.79772 -18.9913,5.60981 -3.682677,0.56218 -4.062057,0.90066 -4.275138,3.81429 -0.304568,4.16459 -6.615879,23.52279 -10.171207,31.19736 -2.992511,6.45967 -20.836076,27.74036 -25.722166,30.67691 -2.433466,1.46252 -6.529773,1.68626 -32.040189,1.75 L 0,268 0,134 z m 112.58674,56.49472 c 17.9417,-5.8153 29.92101,-14.44553 39.30958,-28.31974 6.50353,-9.61076 11.82376,-23.23439 13.43239,-34.3966 l 0.53634,-3.72162 -4.68253,0.71714 c -2.57538,0.39443 -6.93252,0.71916 -9.68252,0.72162 -4.38198,0.004 -5.03846,-0.26573 -5.31118,-2.18162 -0.25336,-1.77991 0.39698,-2.38275 3.5,-3.24443 2.09615,-0.58207 5.28724,-1.06083 7.09131,-1.06389 3.79523,-0.006 13.66008,-3.94498 19.40739,-7.74838 2.35857,-1.56082 4.92227,-4.51376 6.3291,-7.29 1.32453,-2.61384 5.00819,-6.95659 8.3744,-9.872793 3.30535,-2.863468 6.32151,-6.193628 6.70258,-7.400356 0.38107,-1.206728 2.25761,-4.106551 4.17009,-6.444051 1.91248,-2.3375 3.25523,-4.25 2.98389,-4.25 -0.27134,0 -2.48092,0.879197 -4.91017,1.953772 -4.67491,2.067933 -10.60024,1.812111 -20.61031,-0.889838 -7.50202,-2.02497 -13.29134,-0.83962 -21.03177,4.306214 -5.83238,3.877353 -7.24623,5.393961 -9.03006,9.68634 -1.76374,4.244022 -2.49112,5.035588 -4.37991,4.766358 -1.24571,-0.177565 -2.41502,-1.110334 -2.59846,-2.07282 -0.6175,-3.239869 4.28782,-12.133061 8.13967,-14.756968 2.01287,-1.371182 3.66284,-3.086979 3.6666,-3.812883 C 154.00449,72.99326 147.94692,64.834032 142.1663,59.25 138.15529,55.375388 135.97249,54 133.83435,54 c -1.68875,0 -3.14411,-0.643647 -3.48929,-1.543172 -0.53211,-1.38665 -0.76783,-1.384204 -2.324,0.02411 -2.6386,2.387902 -5.3028,0.892005 -4.77812,-2.68283 0.51154,-3.485348 -1.42949,-4.745512 -11.28728,-7.327963 -7.85474,-2.05771 -16.524753,-2.225205 -24.20566,-0.467626 -6.084483,1.392279 -6.945585,2.605516 -3.84247,5.413797 3.382708,3.061308 6.344159,11.520107 6.322733,18.059636 -0.01085,3.313226 -0.179605,6.630995 -0.375,7.372819 -0.236327,0.897226 1.467208,1.827616 5.088482,2.779088 C 107.45458,78.915018 116.25,90.420898 116.25,103.5 c 0,25.25856 -29.50804,38.06462 -47.00033,20.39746 l -3.912497,-3.95161 -3.765939,3.55174 c -2.071266,1.95345 -5.072411,4.22734 -6.669211,5.05308 -4.3026,2.22496 -11.854208,3.38866 -16.463855,2.53708 l -4.061832,-0.75038 -1.26753,5.45195 c -0.906472,3.89895 -0.960339,5.75915 -0.189106,6.53038 0.683669,0.68367 5.745878,0.99563 13.829362,0.85224 14.077742,-0.24972 34.923721,1.89738 42.722197,4.40031 2.765808,0.88769 7.285873,2.69708 10.044591,4.02086 2.75872,1.32379 5.49111,2.40689 6.07199,2.40689 0.58088,0 4.1626,2.6861 7.95938,5.96911 7.34342,6.34974 10.55101,12.00268 8.32944,14.67951 -1.63924,1.97516 -3.08872,1.73348 -13.73829,-2.29065 -16.241003,-6.13695 -43.09955,-7.35101 -59.63837,-2.69576 -9.003178,2.53416 -9.104914,2.80915 -3.063388,8.28039 7.032319,6.3685 16.16737,10.7083 26.563388,12.61951 4.675,0.85946 9.85,1.93864 11.5,2.39818 1.65,0.45955 6.436204,0.88147 10.636009,0.93762 6.189621,0.0828 9.684501,-0.56187 18.450731,-3.40319 z m 35.57378,-81.04177 c -2.01159,-4.41494 -1.32013,-6.0032 4.90565,-11.268171 4.40519,-3.725344 7.85419,-5.666408 12.59626,-7.089064 11.23849,-3.371629 12.35931,-0.379509 3.58757,9.577325 -8.90259,10.10536 -18.63875,14.15869 -21.08948,8.77991 z m -48.186956,13.75178 c 2.630356,-1.62141 5.720526,-4.77451 7.499996,-7.65275 2.63068,-4.25502 3.02644,-5.83102 3.02644,-12.05198 0,-6.220962 -0.39576,-7.796963 -3.02644,-12.051984 C 103.54769,85.09806 96.740321,80.803876 89.705528,80.239686 85.410732,79.895244 83.537749,80.32531 79,82.697844 66.210295,89.384861 62.283614,104.81225 70.342101,116.71354 c 4.615055,6.81581 5.473162,6.56971 4.964404,-1.42376 -0.500208,-7.85913 1.408324,-12.76237 5.943495,-15.26952 2.460736,-1.360348 3.039264,-1.360348 5.5,0 6.033744,3.3356 8.191499,14.74872 4.25,22.47974 -1.1,2.15759 -2,4.10898 -2,4.33644 0,1.12677 7.026503,-1.19866 10.973564,-3.63171 z m -46.288911,-0.777 c 7.213223,-4.19806 8.524757,-7.01982 8.676923,-18.66838 L 62.493638,93.649759 57.403723,92.503411 C 51.089521,91.081329 45.753167,87.854009 42.359902,83.405209 40.801909,81.362575 38.888094,80 37.577092,80 33.747337,80 26.35342,85.541702 23.337628,90.672404 20.942724,94.746803 20.5,96.604369 20.5,102.57842 c 0,6.12234 0.405209,7.73237 3,11.91999 4.246844,6.8538 5.5,6.88798 5.5,0.15002 C 29,105.54341 32.763362,99 38,99 c 7.121193,0 11.47311,13.14525 7.5,22.65424 -0.825,1.97451 -1.5,3.80884 -1.5,4.07629 0,0.98061 5.615099,-0.93434 9.684653,-3.3028 z M 68.812889,85.08321 c 1.750428,-2.178174 5.594218,-5.1138 8.659366,-6.613437 4.849762,-2.372768 5.645763,-3.193467 6.627572,-6.83321 C 86.737408,61.858573 82.332687,50.955127 73.551984,45.526436 63.264319,39.166061 50.230278,42.604806 43.526436,53.448016 40.903933,57.689814 40.5,59.287904 40.5,65.42158 c 0,5.947022 0.446291,7.837649 2.792154,11.82842 1.535684,2.6125 3.223184,4.75 3.75,4.75 0.526815,0 0.958545,-2.3625 0.9594,-5.25 0.0019,-6.276223 2.434391,-11.621238 6.248446,-13.729736 2.460736,-1.360352 3.039264,-1.360352 5.5,0 5.694236,3.147906 8.029661,13.784646 4.75,21.633979 C 62.677182,89.016861 62.677831,89 64.332635,89 c 0.73295,0 2.749064,-1.762556 4.480254,-3.91679 z M 140.03568,36 l 1.99408,-3.5 -3.08767,3.5 c -1.69822,1.925 -3.75058,4.85 -4.56081,6.5 l -1.47314,3 2.56673,-3 c 1.4117,-1.65 3.46406,-4.575 4.56081,-6.5 z"
+ id="path3961" />
+ <path
+ style="fill:#6cb16d"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -17.45295,0 c -10.25131,0 -18.4206,-0.44089 -19.79803,-1.06849 -1.84852,-0.84225 -2.85939,-2.90678 -4.77394,-9.75 -2.26879,-8.10937 -2.93069,-9.24169 -10.04357,-17.18151 -4.18809,-4.675 -10.37297,-11.0517 -13.74418,-14.17044 -8.64522,-7.9978 -22.98848,-24.34471 -24.92627,-28.4083 -1.62294,-3.40335 -4.65602,-4.53566 -6.81106,-2.54272 -1.2064,1.11566 -13.67156,4.79772 -18.9913,5.60981 -3.682677,0.56218 -4.062057,0.90066 -4.275138,3.81429 -0.304568,4.16459 -6.615879,23.52279 -10.171207,31.19736 -2.992511,6.45967 -20.836076,27.74036 -25.722166,30.67691 -2.433466,1.46252 -6.529773,1.68626 -32.040189,1.75 L 0,268 0,134 z m 112.58674,56.49472 c 17.9417,-5.8153 29.92101,-14.44553 39.30958,-28.31974 6.50353,-9.61076 11.82376,-23.23439 13.43239,-34.3966 l 0.53634,-3.72162 -4.68253,0.71714 c -2.57538,0.39443 -6.93252,0.71916 -9.68252,0.72162 -4.38198,0.004 -5.03846,-0.26573 -5.31118,-2.18162 -0.25336,-1.77991 0.39698,-2.38275 3.5,-3.24443 2.09615,-0.58207 5.28724,-1.06083 7.09131,-1.06389 3.79523,-0.006 13.66008,-3.94498 19.40739,-7.74838 2.35857,-1.56082 4.92227,-4.51376 6.3291,-7.29 1.32453,-2.61384 5.00819,-6.95659 8.3744,-9.872793 3.30535,-2.863468 6.32151,-6.193628 6.70258,-7.400356 0.38107,-1.206728 2.25761,-4.106551 4.17009,-6.444051 1.91248,-2.3375 3.25523,-4.25 2.98389,-4.25 -0.27134,0 -2.48092,0.879197 -4.91017,1.953772 -4.67491,2.067933 -10.60024,1.812111 -20.61031,-0.889838 -7.50202,-2.02497 -13.29134,-0.83962 -21.03177,4.306214 -5.83238,3.877353 -7.24623,5.393961 -9.03006,9.68634 -1.76374,4.244022 -2.49112,5.035588 -4.37991,4.766358 -1.24571,-0.177565 -2.41502,-1.110334 -2.59846,-2.07282 -0.6175,-3.239869 4.28782,-12.133061 8.13967,-14.756968 2.01287,-1.371182 3.66284,-3.086979 3.6666,-3.812883 C 154.00449,72.99326 147.94692,64.834032 142.1663,59.25 138.15529,55.375388 135.97249,54 133.83435,54 c -1.68875,0 -3.14411,-0.643647 -3.48929,-1.543172 -0.53211,-1.38665 -0.76783,-1.384204 -2.324,0.02411 -2.6386,2.387902 -5.3028,0.892005 -4.77812,-2.68283 0.51154,-3.485348 -1.42949,-4.745512 -11.28728,-7.327963 -7.85474,-2.05771 -16.524753,-2.225205 -24.20566,-0.467626 -6.084483,1.392279 -6.945585,2.605516 -3.84247,5.413797 3.382708,3.061308 6.344159,11.520107 6.322733,18.059636 -0.01085,3.313226 -0.179605,6.630995 -0.375,7.372819 -0.236327,0.897226 1.467208,1.827616 5.088482,2.779088 C 107.45458,78.915018 116.25,90.420898 116.25,103.5 c 0,25.25856 -29.50804,38.06462 -47.00033,20.39746 l -3.912497,-3.95161 -3.765939,3.55174 c -2.071266,1.95345 -5.072411,4.22734 -6.669211,5.05308 -4.3026,2.22496 -11.854208,3.38866 -16.463855,2.53708 l -4.061832,-0.75038 -1.26753,5.45195 c -0.906472,3.89895 -0.960339,5.75915 -0.189106,6.53038 0.683669,0.68367 5.745878,0.99563 13.829362,0.85224 14.077742,-0.24972 34.923721,1.89738 42.722197,4.40031 2.765808,0.88769 7.285873,2.69708 10.044591,4.02086 2.75872,1.32379 5.49111,2.40689 6.07199,2.40689 0.58088,0 4.1626,2.6861 7.95938,5.96911 7.34342,6.34974 10.55101,12.00268 8.32944,14.67951 -1.63924,1.97516 -3.08872,1.73348 -13.73829,-2.29065 -16.241003,-6.13695 -43.09955,-7.35101 -59.63837,-2.69576 -9.003178,2.53416 -9.104914,2.80915 -3.063388,8.28039 7.032319,6.3685 16.16737,10.7083 26.563388,12.61951 4.675,0.85946 9.85,1.93864 11.5,2.39818 1.65,0.45955 6.436204,0.88147 10.636009,0.93762 6.189621,0.0828 9.684501,-0.56187 18.450731,-3.40319 z m 35.57378,-81.04177 c -2.01159,-4.41494 -1.32013,-6.0032 4.90565,-11.268171 4.40519,-3.725344 7.85419,-5.666408 12.59626,-7.089064 11.23849,-3.371629 12.35931,-0.379509 3.58757,9.577325 -8.90259,10.10536 -18.63875,14.15869 -21.08948,8.77991 z M 97.932392,125.03449 C 103.23403,122.3298 108.7537,115.56847 110.52253,109.61218 111.33514,106.87583 112,104.12535 112,103.5 c 0,-3.629461 -3.45471,-11.671227 -6.58492,-15.328172 -9.703855,-11.336775 -24.126305,-11.336775 -33.830163,0 C 68.454708,91.828773 65,99.870539 65,103.5 c 0,3.6201 3.450453,11.66626 6.561472,15.30078 4.186425,4.8909 5.696048,4.71575 4.257577,-0.49396 -2.730901,-9.89051 3.83022,-21.246268 10.51568,-18.20017 6.24055,2.84339 8.38325,15.7982 3.827863,23.14335 l -2.325711,3.75 3.121398,0 c 1.716768,0 4.855119,-0.88448 6.974113,-1.96551 z m -45.961475,-1.01965 c 2.140182,-1.09184 5.384755,-3.76385 7.210162,-5.9378 3.275353,-3.90074 3.320309,-4.09017 3.424684,-14.4306 L 62.711526,93.168464 59.180645,92.506066 C 52.471257,91.247378 47.968019,88.758289 43.589503,83.888325 41.17224,81.199746 38.682794,79 38.057401,79 c -2.644421,0 -9.10313,4.235496 -12.486891,8.18866 -5.078821,5.93346 -7.128961,13.31499 -5.538938,19.94295 1.135534,4.73343 6.204661,12.79589 8.524774,13.55866 0.673675,0.22148 1.046444,-2.10476 1.029013,-6.42149 -0.03093,-7.65876 1.768817,-12.05 5.829327,-14.22312 5.710772,-3.056314 11.001483,3.414 11.001483,13.45434 0,3.77653 -0.642497,7.20438 -1.733765,9.25 l -1.733764,3.25 2.565518,0 c 1.411035,0 4.316576,-0.89332 6.456759,-1.98516 z M 69.941993,84.559105 c 2.397124,-2.442492 5.753318,-4.991604 7.458208,-5.664694 4.838708,-1.910321 6.349485,-3.682516 7.606619,-8.922838 C 88.170376,56.784389 76.167097,41.714286 62.5,41.714286 c -13.703706,0 -25.670655,15.068941 -22.491417,28.321493 C 41.116287,74.653205 46.104505,83 47.756272,83 c 0.409051,0 0.752499,-2.8125 0.76322,-6.25 0.0415,-13.307386 9.258963,-19.075159 15.045745,-9.414788 2.477736,4.136299 2.539692,13.873683 0.117167,18.414788 -1.659344,3.110497 -1.655751,3.25 0.08371,3.25 0.99961,0 3.778756,-1.998403 6.175881,-4.440895 z M 140.03568,36 l 1.99408,-3.5 -3.08767,3.5 c -1.69822,1.925 -3.75058,4.85 -4.56081,6.5 l -1.47314,3 2.56673,-3 c 1.4117,-1.65 3.46406,-4.575 4.56081,-6.5 z"
+ id="path3959" />
+ <path
+ style="fill:#6e6e6e"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -17.80887,0 c -12.74525,0 -18.25413,-0.35541 -19.37484,-1.25 -0.86128,-0.6875 -2.83694,-5.47353 -4.39036,-10.63562 l -2.82438,-9.38563 -17.63743,-18.11437 C 133.4782,205.5204 130.72502,202.42032 128.10939,197.25 c -1.18252,-2.3375 -2.4954,-4.25 -2.9175,-4.25 -0.42211,0 -4.57546,1.30931 -9.22968,2.90958 -4.65421,1.60027 -10.82471,3.2175 -13.71221,3.59384 -4.680939,0.61009 -5.25,0.94377 -5.25,3.07846 0,2.81805 -4.991196,18.77225 -9.187726,29.36828 -2.297621,5.80138 -4.871577,9.67427 -11.630647,17.5 C 71.40761,254.97757 65.600579,261.4125 63.277114,263.75 L 59.052632,268 29.526316,268 0,268 0,134 z m 107.39219,58.97158 c 3.90929,-1.11563 7.79758,-2.40841 8.64063,-2.87284 0.84306,-0.46444 2.97609,-1.16142 4.74007,-1.54886 4.75497,-1.04437 17.82759,-9.95428 23.94278,-16.3187 10.55478,-10.98495 19.56515,-29.86292 21.03063,-44.06203 0.52934,-5.12881 0.43811,-5.4497 -1.33913,-4.7104 -2.91799,1.21384 -17.06476,1.9043 -17.70754,0.86425 -1.29891,-2.10168 1.42675,-3.56847 7.96478,-4.28616 12.19936,-1.33915 24.97005,-8.40856 28.78314,-15.93334 1.30313,-2.57161 5.04776,-6.973922 8.44669,-9.930215 C 195.25241,91.252438 198,88.258966 198,87.521125 c 0,-0.737842 1.83896,-3.667983 4.08657,-6.511426 2.24761,-2.843443 3.86001,-5.396453 3.58311,-5.673355 -0.27691,-0.276903 -2.62306,0.434142 -5.21369,1.580098 -5.67204,2.509012 -9.13589,2.602114 -16.99589,0.456821 -7.78049,-2.123591 -17.77847,-1.885161 -21.30158,0.507998 -1.46219,0.993224 -4.49957,3.012947 -6.74975,4.488272 -2.73198,1.791224 -4.86523,4.334947 -6.42093,7.656438 C 147.44067,93.329236 146.04375,95 144.82906,95 140.50442,95 145.4484,83.106484 151.42972,79.121098 153.39337,77.812702 155,76.093781 155,75.301273 155,72.994257 149.16305,65.147491 142.74991,58.833142 138.26095,54.413343 136.11975,53 133.91275,53 c -4.02481,0 -3.7762,-2.179595 0.95899,-8.407629 5.63696,-7.414093 9.49764,-13.556319 8.89782,-14.15614 -0.89089,-0.890895 -8.94532,8.839058 -10.87854,13.141554 -4.03838,8.987659 -9.7229,12.935917 -8.59213,5.967775 0.55316,-3.408681 0.48836,-3.481463 -4.89183,-5.494451 -7.51118,-2.81029 -18.57938,-4.377872 -25.293458,-3.582294 C 87.123549,41.297095 81,42.848774 81,43.791742 c 0,0.393059 1.54593,2.889036 3.4354,5.546616 4.044818,5.689124 5.896772,13.154865 5.014623,20.215346 l -0.63314,5.067483 5.849615,1.626338 C 113.3178,81.433048 121.62557,103.33613 110.88239,119 c -10.38036,15.13487 -28.917834,16.92049 -41.57146,4.00436 l -4.18907,-4.27597 -3.31093,3.49638 c -5.752021,6.0742 -11.112494,8.20176 -20.467886,8.12364 l -8.156955,-0.0681 -0.521699,3.10985 c -0.286934,1.71042 -0.823662,4.30758 -1.192729,5.77148 -1.126778,4.46935 2.172085,5.64983 13.528339,4.84104 11.727731,-0.83524 37.958772,1.88395 46.059604,4.77469 15.120856,5.39578 27.799446,14.23549 30.005666,20.92042 2.1083,6.38819 -0.71481,6.65048 -15.03522,1.3969 -4.7541,-1.74408 -12.424923,-3.58816 -17.484943,-4.2034 -10.941332,-1.33034 -32.8655,-0.39516 -38.659302,1.64901 -2.275492,0.80283 -4.832748,1.4597 -5.682791,1.4597 -0.850043,0 -2.354062,0.73171 -3.342263,1.62602 -1.706184,1.54407 -1.538128,1.85905 3.334721,6.25 9.474539,8.53756 16.892582,11.79811 33.22873,14.60544 4.908311,0.84349 9.145811,1.75522 9.416667,2.02608 1.252736,1.25273 14.159591,0.28811 20.551321,-1.53596 z m 40.98208,-84.5953 -1.71957,-3.62371 4.92265,-4.39203 c 5.78007,-5.15701 8.94604,-7.007536 15.27512,-8.928387 9.71954,-2.949839 10.33999,-0.728847 2.31793,8.297407 C 163.71928,105.86304 154.73004,112 151.197,112 c -0.60674,0 -1.87697,-1.63067 -2.82273,-3.62372 z M 97.932392,125.03449 C 103.23403,122.3298 108.7537,115.56847 110.52253,109.61218 111.33514,106.87583 112,104.12535 112,103.5 c 0,-3.629461 -3.45471,-11.671227 -6.58492,-15.328172 -9.703855,-11.336775 -24.126305,-11.336775 -33.830163,0 C 68.454708,91.828773 65,99.870539 65,103.5 c 0,3.6201 3.450453,11.66626 6.561472,15.30078 4.186425,4.8909 5.696048,4.71575 4.257577,-0.49396 -2.730901,-9.89051 3.83022,-21.246268 10.51568,-18.20017 6.24055,2.84339 8.38325,15.7982 3.827863,23.14335 l -2.325711,3.75 3.121398,0 c 1.716768,0 4.855119,-0.88448 6.974113,-1.96551 z m -45.961475,-1.01965 c 2.140182,-1.09184 5.384755,-3.76385 7.210162,-5.9378 3.275353,-3.90074 3.320309,-4.09017 3.424684,-14.4306 L 62.711526,93.168464 59.180645,92.506066 C 52.471257,91.247378 47.968019,88.758289 43.589503,83.888325 41.17224,81.199746 38.682794,79 38.057401,79 c -2.644421,0 -9.10313,4.235496 -12.486891,8.18866 -5.078821,5.93346 -7.128961,13.31499 -5.538938,19.94295 1.135534,4.73343 6.204661,12.79589 8.524774,13.55866 0.673675,0.22148 1.046444,-2.10476 1.029013,-6.42149 -0.03093,-7.65876 1.768817,-12.05 5.829327,-14.22312 5.710772,-3.056314 11.001483,3.414 11.001483,13.45434 0,3.77653 -0.642497,7.20438 -1.733765,9.25 l -1.733764,3.25 2.565518,0 c 1.411035,0 4.316576,-0.89332 6.456759,-1.98516 z M 69.941993,84.559105 c 2.397124,-2.442492 5.753318,-4.991604 7.458208,-5.664694 4.838708,-1.910321 6.349485,-3.682516 7.606619,-8.922838 C 88.170376,56.784389 76.167097,41.714286 62.5,41.714286 c -13.703706,0 -25.670655,15.068941 -22.491417,28.321493 C 41.116287,74.653205 46.104505,83 47.756272,83 c 0.409051,0 0.752499,-2.8125 0.76322,-6.25 0.0415,-13.307386 9.258963,-19.075159 15.045745,-9.414788 2.477736,4.136299 2.539692,13.873683 0.117167,18.414788 -1.659344,3.110497 -1.655751,3.25 0.08371,3.25 0.99961,0 3.778756,-1.998403 6.175881,-4.440895 z M 56.895845,32.504497 C 53.077353,27.187341 51.125377,25.333558 46.182211,22.329804 38.863637,17.882615 18.795723,7.9014256 17.824083,8.2253058 17.277,8.4076667 23.420536,11.8702 31.476385,15.919824 c 13.278868,6.675203 15.225028,8.002689 20.835306,14.211865 7.068071,7.822589 9.34384,9.000552 4.584154,2.372808 z M 149,25.377555 c 0,-1.120334 -1.87801,-0.137848 -2.4159,1.263889 -0.52667,1.372472 -0.38034,1.434339 0.89301,0.377555 C 148.3147,26.32386 149,25.585211 149,25.377555 z m 7.49292,-6.366101 c 0.35034,-0.56686 -0.0511,-0.734507 -0.94098,-0.393011 C 153.81952,19.283234 153.50255,20 154.94098,20 c 0.51754,0 1.21592,-0.444846 1.55194,-0.988546 z m 17.02385,-5.089349 c 4.12147,-1.272992 6.36912,-2.436218 5.80241,-3.002924 -0.56671,-0.566706 -3.38439,0.03879 -7.27398,1.563106 -10.3178,4.043515 -9.51171,4.832209 1.47157,1.439818 z"
+ id="path3957" />
+ <path
+ style="fill:#558d56"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -17.80887,0 c -12.74525,0 -18.25413,-0.35541 -19.37484,-1.25 -0.86128,-0.6875 -2.83694,-5.47353 -4.39036,-10.63562 l -2.82438,-9.38563 -17.63743,-18.11437 C 133.4782,205.5204 130.72502,202.42032 128.10939,197.25 c -1.18252,-2.3375 -2.4954,-4.25 -2.9175,-4.25 -0.42211,0 -4.57546,1.30931 -9.22968,2.90958 -4.65421,1.60027 -10.82471,3.2175 -13.71221,3.59384 -4.680939,0.61009 -5.25,0.94377 -5.25,3.07846 0,2.81805 -4.991196,18.77225 -9.187726,29.36828 -2.297621,5.80138 -4.871577,9.67427 -11.630647,17.5 C 71.40761,254.97757 65.600579,261.4125 63.277114,263.75 L 59.052632,268 29.526316,268 0,268 0,134 z m 107.39219,58.97158 c 3.90929,-1.11563 7.79758,-2.40841 8.64063,-2.87284 0.84306,-0.46444 2.97609,-1.16142 4.74007,-1.54886 4.75497,-1.04437 17.82759,-9.95428 23.94278,-16.3187 10.55478,-10.98495 19.56515,-29.86292 21.03063,-44.06203 0.52934,-5.12881 0.43811,-5.4497 -1.33913,-4.7104 -2.91799,1.21384 -17.06476,1.9043 -17.70754,0.86425 -1.29891,-2.10168 1.42675,-3.56847 7.96478,-4.28616 12.19936,-1.33915 24.97005,-8.40856 28.78314,-15.93334 1.30313,-2.57161 5.04776,-6.973922 8.44669,-9.930215 C 195.25241,91.252438 198,88.258966 198,87.521125 c 0,-0.737842 1.83896,-3.667983 4.08657,-6.511426 2.24761,-2.843443 3.86001,-5.396453 3.58311,-5.673355 -0.27691,-0.276903 -2.62306,0.434142 -5.21369,1.580098 -5.67204,2.509012 -9.13589,2.602114 -16.99589,0.456821 -7.78049,-2.123591 -17.77847,-1.885161 -21.30158,0.507998 -1.46219,0.993224 -4.49957,3.012947 -6.74975,4.488272 -2.73198,1.791224 -4.86523,4.334947 -6.42093,7.656438 C 147.44067,93.329236 146.04375,95 144.82906,95 140.50442,95 145.4484,83.106484 151.42972,79.121098 153.39337,77.812702 155,76.093781 155,75.301273 155,72.994257 149.16305,65.147491 142.74991,58.833142 138.26095,54.413343 136.11975,53 133.91275,53 c -4.02481,0 -3.7762,-2.179595 0.95899,-8.407629 5.63696,-7.414093 9.49764,-13.556319 8.89782,-14.15614 -0.89089,-0.890895 -8.94532,8.839058 -10.87854,13.141554 -4.03838,8.987659 -9.7229,12.935917 -8.59213,5.967775 0.55303,-3.407925 0.48733,-3.481848 -4.87951,-5.489838 -2.99204,-1.119468 -7.34792,-2.305268 -9.67973,-2.635109 -2.33181,-0.329841 -5.70215,-1.044313 -7.48965,-1.587714 -2.14697,-0.65268 -4.353034,-0.649763 -6.5,0.0086 -1.7875,0.548127 -5.275,1.271157 -7.75,1.606732 -7.559714,1.02499 -7.860381,1.649784 -3.715355,7.720606 4.287917,6.280101 6.058002,13.240554 5.171512,20.33578 l -0.639274,5.116577 5.849615,1.626338 C 113.3178,81.433048 121.62557,103.33613 110.88239,119 c -10.38036,15.13487 -28.917834,16.92049 -41.57146,4.00436 l -4.18907,-4.27597 -3.31093,3.49638 c -5.752021,6.0742 -11.112494,8.20176 -20.467886,8.12364 l -8.156955,-0.0681 -0.521699,3.10985 c -0.286934,1.71042 -0.823662,4.30758 -1.192729,5.77148 -1.126778,4.46935 2.172085,5.64983 13.528339,4.84104 11.727731,-0.83524 37.958772,1.88395 46.059604,4.77469 15.120856,5.39578 27.799446,14.23549 30.005666,20.92042 2.1083,6.38819 -0.71481,6.65048 -15.03522,1.3969 -4.7541,-1.74408 -12.424923,-3.58816 -17.484943,-4.2034 -10.941332,-1.33034 -32.8655,-0.39516 -38.659302,1.64901 -2.275492,0.80283 -4.832748,1.4597 -5.682791,1.4597 -0.850043,0 -2.354062,0.73171 -3.342263,1.62602 -1.706184,1.54407 -1.538128,1.85905 3.334721,6.25 9.474539,8.53756 16.892582,11.79811 33.22873,14.60544 4.908311,0.84349 9.145811,1.75522 9.416667,2.02608 1.252736,1.25273 14.159591,0.28811 20.551321,-1.53596 z m 40.98208,-84.5953 -1.71957,-3.62371 4.92265,-4.39203 c 5.78007,-5.15701 8.94604,-7.007536 15.27512,-8.928387 9.71954,-2.949839 10.33999,-0.728847 2.31793,8.297407 C 163.71928,105.86304 154.73004,112 151.197,112 c -0.60674,0 -1.87697,-1.63067 -2.82273,-3.62372 z M 98,163.10699 C 98,161.88941 95.432727,161 91.918213,161 c -3.698002,0 -3.825408,1.72973 -0.168213,2.28375 5.015527,0.75978 6.25,0.72487 6.25,-0.17676 z M 63,161 c 0,-0.55 -0.675,-1 -1.5,-1 -0.825,0 -1.5,0.45 -1.5,1 0,0.55 0.675,1 1.5,1 0.825,0 1.5,-0.45 1.5,-1 z m 9,-0.13636 C 72,160.38864 70.451558,160 68.559017,160 c -1.892541,0 -3.681173,0.38864 -3.97474,0.86364 -0.293566,0.475 1.254877,0.86363 3.440983,0.86363 2.186107,0 3.97474,-0.38863 3.97474,-0.86363 z M 97.5,157 c -0.339919,-0.55 -0.816476,-1 -1.059017,-1 C 96.198442,156 96,156.45 96,157 c 0,0.55 0.476558,1 1.059017,1 0.582459,0 0.780902,-0.45 0.440983,-1 z m 0.305228,-31.59023 C 106.12906,121.26183 112,112.19998 112,103.5 c 0,-8.699978 -5.87094,-17.761827 -14.194772,-21.909769 -6.681706,-3.329635 -11.92875,-3.329635 -18.610456,0 C 70.870938,85.738173 65,94.800022 65,103.5 c 0,4.71546 2.677943,11.6536 6.100705,15.80601 4.663852,5.65806 5.475919,4.95202 5.434944,-4.72533 -0.02979,-7.03619 0.310643,-8.88435 2.072272,-11.25 2.929724,-3.934261 7.849793,-3.937613 10.784158,-0.007 3.090197,4.13898 3.037888,16.25126 -0.08845,20.47986 -3.700994,5.00586 0.200571,5.74315 8.501596,1.60658 z M 53.6475,123.46643 C 61.260439,119.00495 62.766561,115.99392 63.134534,104.5 63.310615,99 63.10082,93.9375 62.668323,93.25 62.235827,92.5625 60.646879,92 59.137327,92 54.850812,92 46.358888,87.240941 42.937753,82.921407 39.179404,78.176105 36.988055,77.987533 30.84854,81.881099 c -5.200406,3.298 -8.251714,7.175862 -10.369588,13.178557 -2.802982,7.944494 -0.974231,16.720514 4.900364,23.516414 3.867668,4.47423 5.573099,4.00323 4.675522,-1.29129 -1.392414,-8.21341 2.165969,-16.4904 7.354531,-17.10704 3.148125,-0.374137 5.121963,1.01528 7.227996,5.08789 1.962853,3.79574 1.927311,12.74173 -0.06594,16.59624 C 43.707143,123.53322 43,125.42928 43,126.07534 c 0,1.73588 5.557132,0.37424 10.6475,-2.60891 z M 68.870426,86.1636 c 1.671167,-2.11002 5.683623,-5.246243 8.91657,-6.969386 4.971733,-2.649906 6.058097,-3.733815 7.045544,-7.02962 3.366255,-11.235557 -2.043192,-23.100745 -13.027312,-28.574363 -6.681706,-3.329635 -11.92875,-3.329635 -18.610456,0 C 41.838339,49.24938 36.4993,61.660809 40.519618,73.055603 42.100517,77.536349 46.48386,84 47.941591,84 c 0.461895,0 1.009086,-3.35217 1.21598,-7.449266 C 49.623371,67.326552 51.922817,63.5 57,63.5 c 2.414404,0 3.82525,0.724733 5.327298,2.736562 2.775649,3.717681 3.429347,13.016769 1.277137,18.167733 C 61.548157,89.32566 61.585701,90 63.915971,90 c 1.053784,0 3.283289,-1.72638 4.954455,-3.8364 z M 56.895845,32.504497 C 53.077353,27.187341 51.125377,25.333558 46.182211,22.329804 38.863637,17.882615 18.795723,7.9014256 17.824083,8.2253058 17.277,8.4076667 23.420536,11.8702 31.476385,15.919824 c 13.278868,6.675203 15.225028,8.002689 20.835306,14.211865 7.068071,7.822589 9.34384,9.000552 4.584154,2.372808 z M 149,25.377555 c 0,-1.120334 -1.87801,-0.137848 -2.4159,1.263889 -0.52667,1.372472 -0.38034,1.434339 0.89301,0.377555 C 148.3147,26.32386 149,25.585211 149,25.377555 z m 7.49292,-6.366101 c 0.35034,-0.56686 -0.0511,-0.734507 -0.94098,-0.393011 C 153.81952,19.283234 153.50255,20 154.94098,20 c 0.51754,0 1.21592,-0.444846 1.55194,-0.988546 z m 17.02385,-5.089349 c 4.12147,-1.272992 6.36912,-2.436218 5.80241,-3.002924 -0.56671,-0.566706 -3.38439,0.03879 -7.27398,1.563106 -10.3178,4.043515 -9.51171,4.832209 1.47157,1.439818 z"
+ id="path3955" />
+ <path
+ style="fill:#4a724b"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -17.92857,0 c -13.5968,0 -18.24785,-0.32161 -19.25,-1.33108 -0.72679,-0.73209 -2.42345,-5.28979 -3.77037,-10.12822 -2.32494,-8.35173 -2.86782,-9.26761 -10.72231,-18.08959 -4.55036,-5.11085 -10.54678,-11.24065 -13.32538,-13.62178 C 147.10475,219.77448 130.89602,201.63669 129.0275,198 c -3.09092,-6.01583 -3.3592,-6.08089 -12.3444,-2.99389 -4.5007,1.54629 -10.2081,3.11036 -12.6831,3.47571 -7.596153,1.12133 -8,1.36889 -8,4.90407 0,4.12995 -2.11771,11.34675 -7.222809,24.61411 -4.26486,11.08371 -5.667563,13.06804 -22.090251,31.25 L 58.783582,268 29.391791,268 0,268 0,134 z m 107,59.55968 c 18.88115,-5.36552 27.83273,-10.39896 38.38267,-21.58245 8.15543,-8.64518 13.68107,-17.97673 17.59757,-29.71827 3.49719,-10.48446 4.48658,-19.98883 2.01976,-19.40233 -5.98951,1.42404 -16.42985,2.11352 -17.39463,1.14874 -1.64182,-1.64182 0.82257,-2.74869 7.82949,-3.51661 6.46017,-0.70799 14.18045,-3.7542 21.64056,-8.53874 3.22423,-2.06787 5.24554,-4.3652 6.84463,-7.77931 1.4711,-3.14086 4.08723,-6.264758 7.43825,-8.881936 2.84297,-2.220388 5.82421,-5.331203 6.62498,-6.912922 0.80077,-1.581719 3.15712,-5.072135 5.23633,-7.75648 5.50846,-7.111641 5.10753,-8.045375 -1.98347,-4.619372 -5.00947,2.420308 -11.33079,2.550246 -19.5918,0.402718 -8.08834,-2.102645 -15.9942,-1.47005 -20.96655,1.67766 -6.87426,4.351706 -10.80417,8.194999 -12.36275,12.090276 C 147.29499,92.720004 146.15062,94 144.89142,94 c -2.47098,0 -2.38691,-1.088693 0.52833,-6.841627 1.42671,-2.815493 4.09422,-5.935552 6.5,-7.602757 C 154.16389,78.000426 156,76.163702 156,75.474008 156,71.430926 137.83875,52 134.05986,52 c -2.71391,0 -2.60914,-2.180862 0.27256,-5.673275 1.28283,-1.554699 4.27091,-5.751725 6.64017,-9.326725 2.36927,-3.575 5.44938,-7.732806 6.84468,-9.239569 1.39531,-1.506763 2.18603,-3.081763 1.75716,-3.5 C 148.36334,23.079376 135.1689,37.726263 132.31915,43.415175 129.29094,49.460328 127.20426,52 125.26556,52 c -1.05605,0 -1.25746,-0.760411 -0.77873,-2.940042 0.55604,-2.531651 0.24838,-3.145524 -2.21489,-4.419331 C 117.45986,42.152202 106.849,39.775886 100,39.652795 93.448379,39.535048 81.341781,41.63797 80.472338,43.044759 c -0.258015,0.417476 1.096542,3.085608 3.010126,5.929182 4.390553,6.524335 5.784732,11.687971 5.356169,19.837709 L 88.5,75.251264 94,76.664465 c 7.3365,1.885082 12.47575,5.439426 16.07809,11.119723 3.92228,6.184791 5.25557,11.476732 4.63442,18.394352 -2.06719,23.02175 -28.921004,33.034 -44.820216,16.71088 l -4.639269,-4.76296 -2.876513,3.02598 C 60.794431,122.81673 57.475,125.37578 55,126.83921 c -3.957235,2.33986 -5.58463,2.66492 -13.492545,2.69505 l -8.992545,0.0343 -0.667365,4.66546 c -0.367051,2.56601 -0.949319,5.12168 -1.29393,5.67927 -0.34461,0.55759 0.352164,1.99253 1.548388,3.18875 2.059344,2.05935 2.765574,2.14084 13.286474,1.53315 19.188498,-1.10834 44.920785,2.80968 54.126851,8.24139 1.674262,0.98784 4.155732,2.08391 5.514392,2.43571 4.11804,1.0663 14.89124,11.71858 15.59741,15.42235 0.79288,4.15859 -1.04843,4.96414 -6.2604,2.73886 -13.53046,-5.77692 -30.471401,-8.92433 -42.86673,-7.9641 -16.214852,1.25612 -19.482065,1.70152 -24.996151,3.40761 -5.211005,1.61231 -8.860692,4.2338 -7.468479,5.36444 0.255546,0.20753 3.38963,2.77959 6.96463,5.71568 8.689807,7.13681 14.697076,9.71181 30.345679,13.00758 16.526981,3.48077 20.129145,3.54598 30.654321,0.55501 z m 41.97569,-85.61838 c -1.20763,-2.91547 -1.08454,-3.24552 2.62868,-7.04854 4.49455,-4.603263 12.02549,-8.541866 18.14563,-9.489979 5.28807,-0.819212 5.66894,0.873997 1.16072,5.160128 -1.6991,1.6154 -3.69529,4.096541 -4.43599,5.513651 C 165.14305,104.62435 154.60915,111 151.73134,111 c -0.81878,0 -2.05883,-1.37641 -2.75565,-3.0587 z M 98,163.10699 C 98,161.88941 95.432727,161 91.918213,161 c -3.698002,0 -3.825408,1.72973 -0.168213,2.28375 5.015527,0.75978 6.25,0.72487 6.25,-0.17676 z M 63,161 c 0,-0.55 -0.675,-1 -1.5,-1 -0.825,0 -1.5,0.45 -1.5,1 0,0.55 0.675,1 1.5,1 0.825,0 1.5,-0.45 1.5,-1 z m 9,-0.13636 C 72,160.38864 70.451558,160 68.559017,160 c -1.892541,0 -3.681173,0.38864 -3.97474,0.86364 -0.293566,0.475 1.254877,0.86363 3.440983,0.86363 2.186107,0 3.97474,-0.38863 3.97474,-0.86363 z M 97.5,157 c -0.339919,-0.55 -0.816476,-1 -1.059017,-1 C 96.198442,156 96,156.45 96,157 c 0,0.55 0.476558,1 1.059017,1 0.582459,0 0.780902,-0.45 0.440983,-1 z m 0.305228,-31.59023 C 106.12906,121.26183 112,112.19998 112,103.5 c 0,-8.699978 -5.87094,-17.761827 -14.194772,-21.909769 -6.681706,-3.329635 -11.92875,-3.329635 -18.610456,0 C 70.870938,85.738173 65,94.800022 65,103.5 c 0,4.71546 2.677943,11.6536 6.100705,15.80601 4.663852,5.65806 5.475919,4.95202 5.434944,-4.72533 -0.02979,-7.03619 0.310643,-8.88435 2.072272,-11.25 2.929724,-3.934261 7.849793,-3.937613 10.784158,-0.007 3.090197,4.13898 3.037888,16.25126 -0.08845,20.47986 -3.700994,5.00586 0.200571,5.74315 8.501596,1.60658 z M 53.6475,123.46643 C 61.260439,119.00495 62.766561,115.99392 63.134534,104.5 63.310615,99 63.10082,93.9375 62.668323,93.25 62.235827,92.5625 60.646879,92 59.137327,92 54.850812,92 46.358888,87.240941 42.937753,82.921407 39.179404,78.176105 36.988055,77.987533 30.84854,81.881099 c -5.200406,3.298 -8.251714,7.175862 -10.369588,13.178557 -2.802982,7.944494 -0.974231,16.720514 4.900364,23.516414 3.867668,4.47423 5.573099,4.00323 4.675522,-1.29129 -1.392414,-8.21341 2.165969,-16.4904 7.354531,-17.10704 3.148125,-0.374137 5.121963,1.01528 7.227996,5.08789 1.962853,3.79574 1.927311,12.74173 -0.06594,16.59624 C 43.707143,123.53322 43,125.42928 43,126.07534 c 0,1.73588 5.557132,0.37424 10.6475,-2.60891 z M 68.870426,86.1636 c 1.671167,-2.11002 5.683623,-5.246243 8.91657,-6.969386 4.971733,-2.649906 6.058097,-3.733815 7.045544,-7.02962 3.366255,-11.235557 -2.043192,-23.100745 -13.027312,-28.574363 -6.681706,-3.329635 -11.92875,-3.329635 -18.610456,0 C 41.838339,49.24938 36.4993,61.660809 40.519618,73.055603 42.100517,77.536349 46.48386,84 47.941591,84 c 0.461895,0 1.009086,-3.35217 1.21598,-7.449266 C 49.623371,67.326552 51.922817,63.5 57,63.5 c 2.414404,0 3.82525,0.724733 5.327298,2.736562 2.775649,3.717681 3.429347,13.016769 1.277137,18.167733 C 61.548157,89.32566 61.585701,90 63.915971,90 c 1.053784,0 3.283289,-1.72638 4.954455,-3.8364 z M 60,36.842371 C 60,33.909935 51.500141,24.931867 45.187811,21.196835 38.598628,17.297989 18.52784,7 17.518169,7 c -0.284993,0 -0.501917,0.5625 -0.482054,1.25 0.01986,0.6875 5.819322,4.061225 12.887686,7.497166 13.704895,6.661967 20.226089,11.34307 25.173137,18.07001 C 58.13364,37.94645 60,39.097996 60,36.842371 z m 96.59271,-16.989512 c 0.60099,-0.460169 5.77599,-2.222628 11.5,-3.916574 10.36347,-3.066934 12.89135,-4.285562 11.58977,-5.587138 -0.74279,-0.7427885 -2.56555,-0.213069 -16.18248,4.702835 -9.16956,3.31034 -11.5,4.534143 -11.5,6.039078 0,0.901355 2.77577,0.153004 4.59271,-1.238201 z"
+ id="path3953" />
+ <path
+ style="fill:#4b504b"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -17.75,-0.0153 c -9.7625,-0.008 -18.21502,-0.34592 -18.78338,-0.75 -0.56836,-0.40408 -2.29429,-5.00176 -3.8354,-10.21706 -3.20424,-10.84351 -4.00701,-11.87049 -29.79124,-38.11184 C 139.95299,210.87897 132.375,202.41253 131,200.09147 c -1.375,-2.32105 -3.20101,-5.14595 -4.0578,-6.27754 l -1.55781,-2.05745 -7.94219,2.73896 c -4.36821,1.50642 -10.83042,3.24871 -14.36047,3.87176 l -6.418267,1.1328 -1.247053,6 c -1.505113,7.24161 -7.767719,25.39501 -10.756671,31.18032 -1.187856,2.29917 -7.50892,10.28667 -14.046808,17.75 L 58.725862,268 29.362931,268 0,268 0,134 z m 108.5,59.59022 c 16.53288,-4.89334 24.15504,-8.90548 34.24543,-18.02606 C 155.05285,164.43963 167,139.86472 167,125.67327 c 0,-3.58859 -0.18312,-3.85049 -2.25,-3.21789 -4.14403,1.26833 -16.75,1.86496 -16.75,0.79276 0,-1.23621 3.38208,-2.21608 7.71249,-2.23449 4.51893,-0.0192 13.01988,-3.39475 20.14185,-7.9979 4.50213,-2.90987 6.69577,-5.1537 8.52217,-8.71713 1.38334,-2.69901 5.12061,-7.121521 8.54148,-10.10758 C 196.2631,91.271112 199,88.292395 199,87.571669 c 0,-0.720727 1.8,-3.571117 4,-6.334201 2.2,-2.763084 4,-5.746866 4,-6.630628 0,-2.016852 0.32914,-2.067469 -5.80794,0.89316 -6.05999,2.923433 -9.58452,3.097009 -17.73196,0.873263 -3.27806,-0.894705 -8.81853,-1.552565 -12.31217,-1.46191 -5.76322,0.149547 -7.01448,0.601629 -13.49768,4.876737 -5.68584,3.749319 -7.60375,5.682282 -9.38821,9.46191 C 146.05353,93.927776 144,95.474491 144,92.460162 c 0,-3.04574 4.00225,-9.293889 7.96217,-12.4302 C 154.18298,78.271051 156,76.1394 156,75.292961 156,72.796137 147.44726,61.546351 141.77998,56.588747 138.70472,53.898582 135.55205,52 134.16019,52 c -1.62365,0 -2.20442,-0.442367 -1.83718,-1.399372 0.92712,-2.41604 13.4154,-20.05392 15.5965,-22.027783 C 149.06378,27.537294 150,26.127529 150,25.440034 c 0,-2.145995 8.07181,-6.106084 18.87432,-9.25988 11.02617,-3.219095 13.26224,-4.443589 11.44077,-6.2650686 -0.98999,-0.9899819 -8.16752,1.2236576 -23.7026,7.3101706 -4.07659,1.597175 -21.18929,19.2911 -23.92144,24.73392 -4.88734,9.73628 -8.58424,13.256788 -7.32869,6.979004 0.57329,-2.866418 0.3245,-3.189157 -3.89831,-5.057106 C 115.82452,41.386442 104.92373,39.034727 99,39.034727 c -5.45416,0 -17.986041,2.551314 -19.380277,3.94555 -0.675384,0.675384 -0.156595,1.913465 1.576851,3.76313 5.881539,6.275868 8.748861,16.188253 6.963526,24.073039 -0.711796,3.143586 -0.662542,4.415648 0.181268,4.681535 0.637248,0.200799 3.645714,1.054277 6.685481,1.896617 20.626121,5.715641 26.296621,32.901122 9.806811,47.015782 C 100.77507,127.88439 93.052413,131 88.5,131 82.876732,131 75.750256,127.76567 70.746387,122.94258 67.926073,120.22416 65.413538,118 65.162976,118 c -0.250561,0 -2.592262,1.99863 -5.20378,4.4414 -5.922833,5.54011 -13.773908,8.16539 -20.805834,6.95715 C 36.594013,128.9588 34.05,128.57672 33.5,128.5495 32.95,128.5223 32.180536,130.3 31.79008,132.5 c -0.390456,2.2 -0.998852,5.42721 -1.35199,7.17158 -0.974752,4.81491 2.509411,6.1304 14.06191,5.30927 18.513049,-1.31587 46.702027,3.20684 56.27586,9.02904 1.79987,1.09456 3.84358,1.99011 4.54159,1.99011 2.18747,0 13.12091,9.88419 14.45775,13.07027 2.50159,5.96204 0.22322,6.13548 -13.54761,1.03133 -4.73327,-1.75438 -12.213775,-3.54539 -17.484946,-4.1863 -11.13572,-1.35397 -33.00583,-0.43937 -38.856839,1.62499 C 47.610313,168.34313 44.983565,169 44.048588,169 c -0.934978,0 -2.698586,1.06299 -3.919129,2.3622 l -2.219169,2.36219 5.794855,4.97999 c 10.281359,8.83559 17.460663,11.98175 33.719057,14.7766 4.908311,0.84375 9.145811,1.7557 9.416667,2.02656 1.375761,1.37576 14.440451,0.21924 21.659131,-1.91732 z m 40.92823,-85.72902 -1.62314,-3.13879 4.34745,-3.87194 c 5.31353,-4.732331 8.60577,-6.589528 15.09998,-8.518101 6.95809,-2.066331 8.2697,-0.504164 3.4183,4.071298 C 168.65187,98.307783 167,100.26747 167,100.75853 167,102.73511 154.72035,111 151.78364,111 c -0.40276,0 -1.46269,-1.41246 -2.35541,-3.1388 z M 162,99.929632 c 0,-0.64321 -0.71358,-0.618104 -2,0.07037 -1.1,0.5887 -2,1.52037 -2,2.07037 0,0.64321 0.71358,0.6181 2,-0.0704 1.1,-0.5887 2,-1.52037 2,-2.070354 z M 98,163.10699 C 98,161.88941 95.432727,161 91.918213,161 c -3.698002,0 -3.825408,1.72973 -0.168213,2.28375 5.015527,0.75978 6.25,0.72487 6.25,-0.17676 z M 63,161 c 0,-0.55 -0.675,-1 -1.5,-1 -0.825,0 -1.5,0.45 -1.5,1 0,0.55 0.675,1 1.5,1 0.825,0 1.5,-0.45 1.5,-1 z m 9,-0.13636 C 72,160.38864 70.451558,160 68.559017,160 c -1.892541,0 -3.681173,0.38864 -3.97474,0.86364 -0.293566,0.475 1.254877,0.86363 3.440983,0.86363 2.186107,0 3.97474,-0.38863 3.97474,-0.86363 z M 97.5,157 c -0.339919,-0.55 -0.816476,-1 -1.059017,-1 C 96.198442,156 96,156.45 96,157 c 0,0.55 0.476558,1 1.059017,1 0.582459,0 0.780902,-0.45 0.440983,-1 z m 0.305228,-31.59023 C 106.12906,121.26183 112,112.19998 112,103.5 c 0,-8.699978 -5.87094,-17.761827 -14.194772,-21.909769 -6.681706,-3.329635 -11.92875,-3.329635 -18.610456,0 C 70.870938,85.738173 65,94.800022 65,103.5 c 0,4.71546 2.677943,11.6536 6.100705,15.80601 4.663852,5.65806 5.475919,4.95202 5.434944,-4.72533 -0.02979,-7.03619 0.310643,-8.88435 2.072272,-11.25 2.929724,-3.934261 7.849793,-3.937613 10.784158,-0.007 3.090197,4.13898 3.037888,16.25126 -0.08845,20.47986 -3.700994,5.00586 0.200571,5.74315 8.501596,1.60658 z M 53.6475,123.46643 C 61.260439,119.00495 62.766561,115.99392 63.134534,104.5 63.310615,99 63.10082,93.9375 62.668323,93.25 62.235827,92.5625 60.646879,92 59.137327,92 54.850812,92 46.358888,87.240941 42.937753,82.921407 39.179404,78.176105 36.988055,77.987533 30.84854,81.881099 c -5.200406,3.298 -8.251714,7.175862 -10.369588,13.178557 -2.802982,7.944494 -0.974231,16.720514 4.900364,23.516414 3.867668,4.47423 5.573099,4.00323 4.675522,-1.29129 -1.392414,-8.21341 2.165969,-16.4904 7.354531,-17.10704 3.148125,-0.374137 5.121963,1.01528 7.227996,5.08789 1.962853,3.79574 1.927311,12.74173 -0.06594,16.59624 C 43.707143,123.53322 43,125.42928 43,126.07534 c 0,1.73588 5.557132,0.37424 10.6475,-2.60891 z M 68.870426,86.1636 c 1.671167,-2.11002 5.683623,-5.246243 8.91657,-6.969386 4.971733,-2.649906 6.058097,-3.733815 7.045544,-7.02962 3.366255,-11.235557 -2.043192,-23.100745 -13.027312,-28.574363 -6.681706,-3.329635 -11.92875,-3.329635 -18.610456,0 C 41.838339,49.24938 36.4993,61.660809 40.519618,73.055603 42.100517,77.536349 46.48386,84 47.941591,84 c 0.461895,0 1.009086,-3.35217 1.21598,-7.449266 C 49.623371,67.326552 51.922817,63.5 57,63.5 c 2.414404,0 3.82525,0.724733 5.327298,2.736562 2.775649,3.717681 3.429347,13.016769 1.277137,18.167733 C 61.548157,89.32566 61.585701,90 63.915971,90 c 1.053784,0 3.283289,-1.72638 4.954455,-3.8364 z M 61,37.037461 C 61,35.016172 52.188112,25.354639 47.452602,22.183817 41.045509,17.89373 19.507061,7 17.432043,7 13.560015,7 17.598652,9.9226201 30.213853,16.249746 44.188019,23.258458 51.284472,28.488149 55.017885,34.528938 56.991023,37.721543 61,39.402656 61,37.037461 z"
+ id="path3951" />
+ <path
+ style="fill:#335033"
+ d="M 0,134 0,0 l 109,0 109,0 0,134 0,134 -18.01618,0 -18.01618,0 -1.45948,-3.25 c -0.80272,-1.7875 -2.40796,-6.49172 -3.5672,-10.45383 -1.81487,-6.20292 -3.12338,-8.35651 -9.41771,-15.5 C 163.50275,234.23328 157.46056,228.025 154.09615,225 147.1885,218.7892 130,199.69215 130,198.2283 c 0,-0.52722 -0.95183,-2.16864 -2.11518,-3.6476 -1.77879,-2.26136 -2.60852,-2.58066 -5.21718,-2.0077 -1.7061,0.37472 -3.79176,1.01377 -4.63482,1.42011 -3.9353,1.89677 -9.09472,3.33871 -15.28282,4.2712 -6.029278,0.90857 -6.75,1.25714 -6.75,3.26457 0,3.31081 -4.498412,18.25615 -8.428622,28.0029 C 84.083443,238.18172 82.45122,240.44384 66.5,258.73499 l -8,9.17355 -29.25,0.0457 L 0,268 0,134 z m 108.5,59.59022 c 16.53285,-4.89333 24.15504,-8.90549 34.24536,-18.026 C 155.22117,164.2875 167,140.05884 167,125.67327 c 0,-3.58859 -0.18312,-3.85049 -2.25,-3.21789 -4.14403,1.26833 -16.75,1.86496 -16.75,0.79276 0,-1.25403 3.36786,-2.20698 8,-2.26364 4.44467,-0.0544 15.52619,-4.54181 21.3106,-8.62969 2.58361,-1.82586 5.57055,-5.20311 7.12062,-8.05111 1.51082,-2.77587 5.02452,-6.784619 8.09273,-9.232914 2.98243,-2.379845 5.71435,-5.281845 6.07094,-6.448889 0.35659,-1.167043 2.61862,-4.536093 5.02673,-7.486778 6.66257,-8.163722 5.95607,-10.382129 -1.92288,-6.037831 -6.08893,3.357312 -9.59112,3.545937 -19.24879,1.036721 -10.74983,-2.792977 -16.36924,-1.9527 -24.94664,3.730299 -5.524,3.659956 -7.46893,5.635488 -9.24028,9.385692 C 146.05347,93.927929 144,95.474242 144,92.460162 c 0,-3.04574 4.00225,-9.293889 7.96217,-12.4302 C 154.18298,78.271051 156,76.1394 156,75.292961 156,70.45486 138.78123,52 134.26718,52 c -2.8781,0 -2.86135,-1.127741 0.0694,-4.673275 1.28511,-1.554699 4.60677,-6.214857 7.38146,-10.355907 2.77469,-4.14105 5.77323,-8.13365 6.66343,-8.872445 C 149.27166,27.359579 150,26.141689 150,25.39195 c 0,-1.998271 10.21063,-6.723303 20.24422,-9.368143 9.01744,-2.376981 11.97177,-4.20782 9.98916,-6.1904251 -0.75783,-0.7578298 -1.92819,-0.7733993 -3.90762,-0.051983 -1.55417,0.5664291 -7.25713,2.6336911 -12.67325,4.5939151 -9.6763,3.502084 -10.01364,3.734072 -19.40432,13.344365 -5.30647,5.43057 -10.50097,11.781674 -11.67973,14.280321 -4.4228,9.375106 -8.4735,13.275212 -7.2061,6.93818 0.57441,-2.872035 0.32797,-3.187621 -3.9758,-5.091384 -2.52349,-1.11626 -8.5928,-2.832928 -13.48736,-3.814817 -8.580358,-1.721292 -9.227428,-1.719409 -18.06037,0.05255 -5.038643,1.010794 -9.625677,2.302315 -10.193407,2.870045 -0.70965,0.70965 -0.224895,1.893708 1.551151,3.78883 5.881539,6.275868 8.748861,16.188253 6.963526,24.073039 -0.711796,3.143586 -0.662542,4.415648 0.181268,4.681535 0.637248,0.200799 3.645714,1.054277 6.685481,1.896617 20.626121,5.715641 26.296621,32.901125 9.806811,47.015785 C 100.77507,127.88439 93.052413,131 88.5,131 82.876732,131 75.750256,127.76567 70.746387,122.94258 67.926073,120.22416 65.413538,118 65.162976,118 c -0.250561,0 -2.592262,1.99863 -5.20378,4.4414 -5.922833,5.54011 -13.773908,8.16539 -20.805834,6.95715 C 36.594013,128.9588 34.05,128.57672 33.5,128.5495 32.95,128.5223 32.180536,130.3 31.79008,132.5 c -0.390456,2.2 -0.998852,5.42721 -1.35199,7.17158 -0.974752,4.81491 2.509411,6.1304 14.06191,5.30927 18.513049,-1.31587 46.702027,3.20684 56.27586,9.02904 1.79987,1.09456 3.84358,1.99011 4.54159,1.99011 2.18747,0 13.12091,9.88419 14.45775,13.07027 2.50159,5.96204 0.22322,6.13548 -13.54761,1.03133 -4.73327,-1.75438 -12.213775,-3.54539 -17.484946,-4.1863 -11.13572,-1.35397 -33.00583,-0.43937 -38.856839,1.62499 C 47.610313,168.34313 44.983565,169 44.048588,169 c -0.934978,0 -2.698586,1.06299 -3.919129,2.3622 l -2.219169,2.36219 5.794855,4.97999 c 10.281359,8.83559 17.460663,11.98175 33.719057,14.7766 4.908311,0.84375 9.145811,1.7557 9.416667,2.02656 1.375761,1.37576 14.440451,0.21924 21.659131,-1.91732 z m 40.92823,-85.72902 -1.62314,-3.13879 4.34745,-3.87194 c 5.31353,-4.732331 8.60577,-6.589528 15.09998,-8.518101 6.95809,-2.066331 8.2697,-0.504164 3.4183,4.071298 C 168.65187,98.307783 167,100.26747 167,100.75853 167,102.73511 154.72035,111 151.78364,111 c -0.40276,0 -1.46269,-1.41246 -2.35541,-3.1388 z M 162,99.929632 c 0,-0.64321 -0.71358,-0.618104 -2,0.07037 -1.1,0.5887 -2,1.52037 -2,2.07037 0,0.64321 0.71358,0.6181 2,-0.0704 1.1,-0.5887 2,-1.52037 2,-2.070354 z m -49,67.192808 c 0,-1.42135 -2.43896,-3.03109 -4.54609,-3.00046 -1.07465,0.0156 -3.75391,-0.48099 -5.95391,-1.10358 -9.111123,-2.5784 -11.195285,-2.80732 -19.45,-2.13627 -0.922467,0.075 -1.102092,0.46578 -0.493724,1.07415 0.525951,0.52595 4.778451,1.23555 9.45,1.57689 4.671548,0.34134 9.393724,1.00311 10.493724,1.4706 6.28051,2.66917 10.5,3.52057 10.5,2.11867 z m -40.083333,-5.72107 c 1.186475,-1.14292 -1.785755,-1.89384 -7.988964,-2.01839 -6.640651,-0.13334 -8.447563,0.75523 -6.177703,3.03793 0.716629,0.72069 13.300244,-0.18493 14.166667,-1.01954 z m 28.309163,-3.40511 C 99.425037,156.89832 97.250037,156 96.392497,156 c -2.629943,0 -0.909192,2.46066 2.190001,3.13169 5.321232,1.15213 5.951342,0.88147 2.643332,-1.13543 z M 57,148 c 0,-0.55 -0.423442,-1 -0.940983,-1 -0.517541,0 -1.219098,0.45 -1.559017,1 -0.339919,0.55 0.08352,1 0.940983,1 C 56.298442,149 57,148.55 57,148 z m 40.5,-21.96041 c 4.6915,-2.01637 10.77736,-8.4225 13.07901,-13.76731 5.34781,-12.418553 -2.92309,-28.624267 -16.696504,-32.714531 -4.723349,-1.402684 -5.861808,-1.41481 -10.344968,-0.110187 -9.031307,2.62816 -14.672376,8.29233 -17.989748,18.063423 -2.548849,7.507455 -0.447377,15.273755 6.0913,22.511295 4.544538,5.03026 6.864155,5.3269 5.690365,0.72772 -1.466306,-5.74533 -0.845971,-13.58122 1.303039,-16.45958 4.16486,-5.57838 6.588594,-5.553679 10.817321,0.11024 3.053605,4.08997 2.899774,14.28265 -0.280476,18.58417 -4.429992,5.99188 -1.231818,7.16462 8.330661,3.05476 z m -46.717881,-0.59027 c 4.231019,-1.76471 9.787706,-6.75179 11.642795,-10.44932 0.776526,-1.54776 1.220149,-6.29466 1.164681,-12.46245 L 63.5,92.575109 60,91.695901 C 51.123965,89.466223 47.90713,87.716538 43.571386,82.760132 L 39.127164,77.67972 34.699417,79.370692 C 21.883478,84.265144 15.10719,100.32708 20.851809,112.19388 22.909149,116.44378 28.44592,123 29.977643,123 c 0.407181,0 0.691285,-3.56218 0.631343,-7.91597 -0.08987,-6.52747 0.250625,-8.3995 1.941199,-10.67266 2.970418,-3.99407 5.089071,-5.128692 7.14963,-3.82892 5.918169,3.73308 7.885087,13.04619 4.41306,20.89528 C 42.950794,124.10481 42,126.42203 42,126.62712 c 0,0.94705 5.435343,0.2181 8.782119,-1.1778 z M 70.17322,85.455495 c 1.730707,-1.971167 5.314401,-4.682376 7.963766,-6.024911 C 83.95339,76.483189 86.28924,72.492207 86.27661,65.523405 86.257944,55.224197 78.096815,44.591072 67.882506,41.557749 63.159157,40.155065 62.020698,40.142939 57.537538,41.447562 48.178745,44.171022 41.27706,51.508148 38.950192,61.207622 37.979012,65.255954 38.060967,66.89022 39.447789,71.130183 41.207453,76.510045 45.680013,84 47.132886,84 c 0.476913,0 1.204614,0 1.617114,0 0.4125,0 0.75,-3.117001 0.75,-6.92667 0,-5.423592 0.444887,-7.522547 2.050185,-9.672669 4.252748,-5.696094 6.646882,-5.696094 10.89963,0 2.75217,3.686232 2.879833,13.921095 0.224198,17.974106 -4.328183,6.605642 1.713155,6.670676 7.499207,0.08073 z M 61,36.957093 C 61,34.4454 52.627492,25.167735 47.312569,21.789906 38.42248,16.139926 17.140779,5.9631986 16.473477,7.0429153 15.39534,8.7873781 16.964718,9.8695978 29.371294,15.937056 42.693213,22.452164 50.474111,28.095835 54.479817,34.148866 56.855175,37.738275 61,39.523441 61,36.957093 z"
+ id="path3949" />
+ <path
+ style="fill:#282c28"
+ d="M 0,134.02342 0,0 l 109,0 109,0 0,134.02256 0,134.02256 -18.18517,-0.27256 L 181.62966,267.5 178.3251,256.885 175.02053,246.27 153.8916,224.385 c -12.62269,-13.07438 -22.34707,-24.03353 -24.15472,-27.22182 -1.66418,-2.93525 -3.60429,-5.55881 -4.31134,-5.83013 -0.70706,-0.27132 -2.77955,0.16294 -4.60555,0.96502 -6.61011,2.90353 -12.42747,4.63149 -17.81999,5.29318 -3.025,0.37117 -6.005568,1.07284 -6.623484,1.55925 -0.617915,0.48642 -1.411636,3.05659 -1.763823,5.71151 -0.73294,5.52518 -6.15011,22.01249 -9.902314,30.13799 -1.509819,3.26955 -6.671086,10.16366 -12.72703,17 -5.602977,6.325 -10.852402,12.48852 -11.665389,13.69672 -1.464187,2.17596 -1.756194,2.19744 -30.898058,2.27342 L 0,268.04684 0,134.02342 z m 107.59096,60.55959 c 17.15504,-5.03571 27.05455,-10.41898 36.98021,-20.10953 10.84317,-10.58632 19.8715,-28.35471 22.65495,-44.58652 1.39873,-8.15681 0.53683,-10.01124 -3.74605,-8.05983 -1.4158,0.64508 -5.1405,1.12439 -8.27712,1.06513 l -5.70295,-0.10773 7,-1.24367 c 12.65227,-2.24788 23.80331,-8.71463 28.14641,-16.32276 1.48132,-2.59496 5.42938,-7.42115 8.77346,-10.724877 3.34407,-3.303728 7.32831,-8.028728 8.85386,-10.5 1.52555,-2.471273 3.75182,-5.731947 4.94728,-7.245942 1.6603,-2.102709 1.89711,-3.029157 1.00287,-3.923404 -0.89425,-0.894247 -2.33056,-0.539404 -6.08261,1.502719 -5.76134,3.13571 -10.94743,3.418354 -19.68117,1.072627 -8.70767,-2.338724 -15.72808,-1.902664 -21.33225,1.325012 -7.96258,4.585992 -11.18308,7.463692 -13.64849,12.195712 -2.58505,4.961652 -3.34072,4.077334 -1.09949,-1.286679 0.75893,-1.816372 3.45893,-5.006126 6,-7.088343 C 154.92094,78.462708 157,76.244777 157,75.61619 157,71.479685 140.12894,52.572434 135.37274,51.378703 132.50197,50.658185 132.47059,50.209558 135.06646,47 c 1.11209,-1.375 4.36458,-5.792853 7.22776,-9.817451 2.86318,-4.024598 6.24648,-8.749598 7.51844,-10.5 2.98849,-4.112591 6.82192,-6.027527 19.95358,-9.967536 9.41142,-2.823793 10.77505,-3.512096 11.06895,-5.587131 0.30612,-2.1613321 0.0459,-2.3233478 -3,-1.8680536 -6.35023,0.9492086 -23.16069,7.8189686 -26.75617,10.9341776 -6.58269,5.703386 -17.82361,18.731933 -19.88088,23.042493 C 130.079,45.581424 128.41818,48.4 127.50745,49.5 c -1.64164,1.982783 -1.65186,1.981031 -1.18744,-0.203524 0.69404,-3.26473 -1.14225,-4.945311 -7.82484,-7.161302 C 108.17388,38.712561 99.782986,37.656755 92.75,38.895721 c -8.265069,1.456015 -13.549664,2.971111 -14.235882,4.081436 -0.306982,0.496706 0.739357,2.392544 2.325196,4.212973 5.628085,6.460633 6.656524,9.515997 6.658689,19.782131 l 0.002,9.472261 4,0.694526 c 6.167903,1.070944 9.041817,2.452218 13.520137,6.498112 6.49995,5.872314 8.44524,10.447557 8.44524,19.86284 0,9.57347 -2.02029,14.17778 -8.8644,20.2022 -10.289083,9.05681 -23.280045,8.50265 -33.550654,-1.43121 -2.997323,-2.89904 -5.697323,-5.27059 -6,-5.2701 -0.302678,4.9e-4 -2.33228,1.83778 -4.510226,4.08286 -6.247038,6.43962 -8.773451,7.41845 -19.040097,7.37687 -5.123772,-0.0208 -9.316424,0.41056 -9.734687,1.00146 -0.404078,0.57086 -0.741578,2.305 -0.75,3.85366 -0.0084,1.54866 -0.490243,3.70316 -1.070712,4.78777 -3.042721,5.68538 2.429854,8.3973 15.342292,7.60284 10.685382,-0.65743 35.770605,1.63993 43.213107,3.95756 16.931517,5.27255 33.249327,17.33504 31.083937,22.97795 -0.36227,0.94404 -3.27489,0.28236 -11.28611,-2.56397 C 92.333144,164.40576 80.122071,163.31183 58,165.57197 c -10.243183,1.04651 -20,4.81316 -20,7.72106 0,1.76064 9.353994,9.67868 15.5,13.12055 7.402213,4.14538 13.397659,6.08597 24.924202,8.0674 4.908311,0.84375 9.145811,1.7557 9.416667,2.02656 1.294394,1.29439 12.506101,0.20188 19.750091,-1.92453 z m 42.38076,-87.13585 c -1.3004,-2.42983 -1.15194,-2.74356 3.08102,-6.51073 2.44599,-2.176837 5.57226,-4.558012 6.94726,-5.291498 3.60879,-1.925092 11.93876,-4.039508 12.74354,-3.234726 0.3774,0.377402 -0.76668,2.126997 -2.54241,3.88799 -1.77573,1.760992 -4.16681,4.454224 -5.31352,5.984944 -1.8626,2.48638 -10.46075,7.71686 -12.68539,7.71686 -0.47534,0 -1.47907,-1.14878 -2.2305,-2.55284 z m 10.80577,-5.00386 C 162.7588,101.05553 163.89812,98 162.43426,98 c -1.45764,0 -4.49366,2.24247 -5.44653,4.02292 -1.33087,2.48677 0.54284,2.69461 3.78976,0.42038 z m -47.94596,63.71767 c -0.69608,-0.91353 -1.34831,-1.80385 -1.4494,-1.97847 -0.10109,-0.17463 -2.46476,-0.52938 -5.2526,-0.78834 -2.78784,-0.25896 -6.623271,-1.12034 -8.52318,-1.91417 -4.799648,-2.00542 -17.437682,-1.63413 -16.134773,0.47402 0.436733,0.70665 7.250805,1.76514 17.028423,2.64517 1.65,0.14851 5.475,1.14342 8.5,2.21093 6.00597,2.11946 7.78978,1.9209 5.83153,-0.64914 z m -39.601839,-4.3394 c 2.376941,-1.53728 -1.37168,-2.71074 -8.446817,-2.64416 -6.387584,0.0601 -8.252014,1.02012 -6.120578,3.15155 0.919658,0.91966 13.012133,0.49847 14.567395,-0.50739 z M 77.5,161 c -0.339919,-0.55 -1.041476,-1 -1.559017,-1 C 75.423442,160 75,160.45 75,161 c 0,0.55 0.701558,1 1.559017,1 0.857459,0 1.280902,-0.45 0.940983,-1 z M 104,159.52032 C 104,159.01869 96.478685,155 95.539838,155 c -1.588232,0 -0.210776,3.19672 1.710162,3.96884 2.43291,0.97791 6.75,1.33062 6.75,0.55148 z M 58,147.89301 c 0,-1.17433 -3.719257,-1.15628 -4.447214,0.0216 -0.67738,1.09602 1.439688,1.97744 3.197214,1.33111 0.6875,-0.25282 1.25,-0.86153 1.25,-1.35269 z m 15.1875,1.42388 c -0.721875,-0.28887 -1.584375,-0.25335 -1.916667,0.0789 -0.332291,0.33229 0.258334,0.56864 1.3125,0.52522 1.164943,-0.048 1.4019,-0.28494 0.604167,-0.60416 z M 49.2,147.8 c -0.933333,-0.93333 -1.466667,-0.93333 -2.4,0 -0.933333,0.93333 -0.666667,1.2 1.2,1.2 1.866667,0 2.133333,-0.26667 1.2,-1.2 z m 13.9875,0.51689 c -0.721875,-0.28887 -1.584375,-0.25335 -1.916667,0.0789 -0.332291,0.33229 0.258334,0.56864 1.3125,0.52522 1.164943,-0.048 1.4019,-0.28494 0.604167,-0.60416 z M 99.5,125.07119 c 5.95109,-3.26056 10.75333,-9.79024 12.47339,-16.96028 2.35497,-9.816606 -3.24757,-21.222271 -13.050501,-26.568258 -7.25676,-3.957442 -13.575767,-3.94494 -20.899895,0.04135 -5.993581,3.262115 -9.347097,7.188168 -12.051024,14.108463 L 64.093549,100.5 64.046774,96.785184 C 63.997145,92.843641 62.080497,91 58.032498,91 54.360639,91 46.358424,86.231809 42.759945,81.899715 c -4.07307,-4.903441 -5.606652,-4.864922 -13.352101,0.335366 -6.360828,4.270655 -10.836415,12.603722 -10.836415,20.176249 0,6.08066 4.066665,15.37223 8.125266,18.56473 3.996352,3.14353 4.513379,2.58225 3.892849,-4.22606 C 29.908,109.27225 31.37388,104.52226 35.25,101.64841 l 2.75,-2.038912 2.75,2.040762 c 5.546014,4.11567 6.601609,14.80869 2.16978,21.97954 -2.201467,3.56205 -1.986624,3.7985 3.08022,3.39005 4.196015,-0.33825 12.18507,-5.29815 15.172889,-9.41989 1.808223,-2.49447 2.84589,-5.19746 2.879217,-7.5 l 0.05211,-3.59996 2.01957,5.2548 C 68.500523,117.93893 73.836096,124 76.903261,124 c 1.741457,0 1.989635,-0.34372 1.263548,-1.75 -3.12842,-6.05908 -1.929921,-16.32119 2.335774,-20 3.344684,-2.884515 4.067965,-2.833299 7.427195,0.52593 4.933166,4.93317 4.895837,16.58744 -0.07006,21.87339 -1.953494,2.0794 -2.081309,2.60102 -0.833512,3.40158 2.059784,1.32151 6.605008,0.23576 12.473795,-2.97971 z M 63.078947,103.58333 c -0.04342,-1.05416 0.192928,-1.64479 0.52522,-1.3125 0.332291,0.3323 0.367818,1.1948 0.07895,1.91667 -0.319226,0.79773 -0.556183,0.56078 -0.604167,-0.60417 z m 6.66454,-17.596755 c 1.820219,-2.126517 5.762438,-5.026825 8.760486,-6.445129 5.149074,-2.435902 5.540131,-2.885343 7.06024,-8.114335 1.346343,-4.631256 1.41319,-6.35284 0.409179,-10.538026 C 83.236309,49.479643 72.950755,40.5641 62.541554,40.578312 56.451338,40.586628 48.029926,44.783141 44.306127,49.665294 41.406313,53.467145 38,62.005941 38,65.473214 38,71.619859 45.395216,85 48.792473,85 c 0.570498,0 0.952576,-3.072339 0.901614,-7.25 -0.09528,-7.810599 0.991316,-10.842537 4.774039,-13.321072 2.859131,-1.873375 5.582486,-0.807511 8.219374,3.21689 2.554763,3.899061 2.288396,14.039081 -0.486746,18.529354 -1.195835,1.934902 -1.856261,3.835988 -1.467613,4.224636 1.45641,1.456409 5.812378,-0.677127 9.010346,-4.413233 z M 61.67055,37.48975 C 62.374007,35.37645 51.959358,24.120119 45.888561,20.432305 35.837213,14.326433 17.966638,5.7988245 16.4456,6.3825015 c -3.131354,1.2016134 0.411095,3.9387175 13.412248,10.3630905 13.305352,6.574689 19.78567,11.493936 26.437645,20.068971 1.768349,2.279572 4.717682,2.650052 5.375057,0.675187 z M 150.5,32 c 0.99549,-1.1 1.40273,-1.985688 0.90499,-1.968197 C 150.24249,30.072656 147,32.522707 147,33.360243 147,34.630187 148.72719,33.95893 150.5,32 z"
+ id="path3947" />
+ <path
+ style="fill:#1b271b"
+ d="M 0,134.02342 0,0 l 109,0 109,0 0,134 0,134 -17.94098,0 c -12.61931,0 -18.15546,-0.34703 -18.66405,-1.16994 -0.48618,-0.78665 -0.1779,-0.96074 0.94099,-0.53138 2.38102,0.91368 2.0963,-1.48408 -0.43343,-3.65011 -1.66409,-1.42483 -1.96729,-2.48983 -1.46743,-5.15432 0.44132,-2.35243 0.21156,-3.60341 -0.76705,-4.17633 C 177.62049,252.11919 174.5,245.88918 174.5,243 c 0,-1.95005 -0.51662,-2.50538 -2.3485,-2.52446 -2.93525,-0.0306 -5.77596,-3.44319 -3.90143,-4.68688 0.92784,-0.61559 0.62781,-1.35058 -1.1643,-2.85226 -1.52314,-1.27628 -2.65279,-1.63697 -3.06055,-0.97721 -0.38178,0.61773 -1.8494,-0.24644 -3.58576,-2.11138 -1.6167,-1.73642 -2.37696,-2.83598 -1.68946,-2.44345 0.74179,0.42351 1.25,0.1507 1.25,-0.67103 0,-2.12141 -4.69005,-6.06625 -6.42204,-5.40162 -0.86079,0.33032 -2.83974,-0.52255 -4.54819,-1.96012 -2.25026,-1.89346 -2.88064,-3.11758 -2.46279,-4.78242 0.64075,-2.55298 -1.74101,-5.1201 -3.96029,-4.26848 -1.99532,0.76567 -4.63694,-2.48901 -3.99928,-4.92742 0.62619,-2.39457 -1.89063,-4.8823 -4.08679,-4.03956 -0.98384,0.37754 -2.02176,-0.42214 -2.99788,-2.30974 -0.82117,-1.58796 -1.10445,-3.03498 -0.62951,-3.21559 0.47681,-0.18132 0.48664,-1.33047 0.022,-2.56599 -0.74715,-1.98654 -1.39415,-2.19169 -5.76645,-1.82837 -2.70868,0.22507 -5.76275,0.86539 -6.78681,1.42293 -3.37636,1.8382 -8.76204,3.37127 -15.86193,4.51521 -5.971904,0.96219 -7.044971,1.44333 -7.306193,3.2759 -0.168406,1.18144 -1.179385,2.37641 -2.24662,2.6555 -1.261801,0.32997 -1.910253,1.32738 -1.854149,2.85194 0.04745,1.28947 -1.036666,5.71915 -2.409153,9.84372 -1.663589,4.99938 -2.141886,7.71772 -1.434837,8.1547 0.703532,0.43481 0.280921,2.62338 -1.255292,6.50078 -3.516681,8.8761 -4.081426,9.82148 -4.989439,8.35228 -1.176293,-1.90328 -3.257349,-0.0826 -2.633286,2.30384 0.725502,2.77433 -0.944116,4.61358 -3.56573,3.92801 -1.777407,-0.4648 -2.030215,-0.2069 -1.559961,1.59135 0.710957,2.7187 -3.092219,8.03561 -4.323177,6.04388 -1.237524,-2.00236 -5.127211,1.90453 -4.346166,4.36538 0.678553,2.13794 -2.523062,6.46424 -3.551867,4.7996 C 60.219874,260.73773 56,263.61366 56,265.46308 c 0,0.88998 0.734469,1.15761 2.156372,0.78578 1.424519,-0.37252 1.924781,-0.18919 1.474,0.54019 -0.471052,0.76218 -9.810015,1.1279 -30.156372,1.18095 L 0,268.04684 0,134.02342 z m 107.39219,60.90624 c 3.90929,-1.13868 9.58281,-2.97445 12.60781,-4.07948 20.94388,-7.65079 38.893,-28.01775 45.52642,-51.65908 1.24507,-4.43739 2.16494,-6.13978 3.11965,-5.77342 C 169.39073,133.70343 170,133.50135 170,132.96862 170,132.43588 169.55,132 169,132 c -0.55,0 -1,-1.17314 -1,-2.60699 0,-1.935 0.3964,-2.45487 1.53785,-2.01686 2.712,1.04069 2.99771,-2.45781 0.36824,-4.50907 -1.80114,-1.40508 -3.41179,-1.73979 -6.40609,-1.33125 -3.45166,0.47093 -3.00689,0.13291 3.24447,-2.46578 4.05187,-1.68436 7.98446,-2.72756 8.92361,-2.36718 1.29186,0.49573 1.52523,0.24326 1.01182,-1.09465 -0.54537,-1.42121 -0.27533,-1.61459 1.47766,-1.05821 1.69607,0.53831 2.01675,0.34661 1.53224,-0.91599 -0.45755,-1.19237 -0.0641,-1.53818 1.5536,-1.3654 1.56495,0.16715 2.17887,-0.32383 2.21147,-1.76862 0.0513,-2.275 4.26726,-10.649936 5.88172,-11.684017 0.58735,-0.376209 1.43805,-0.455261 1.89044,-0.17567 0.45239,0.27959 0.69887,-0.0876 0.54775,-0.815983 -0.16167,-0.779197 0.64268,-1.336208 1.95408,-1.353186 1.22587,-0.01587 2.77837,-0.578371 3.45,-1.25 C 198.14038,94.259619 198.13233,94 197.14098,94 c -0.69246,0 -0.97636,-0.45734 -0.6309,-1.016312 0.34546,-0.558971 1.05817,-0.750523 1.58379,-0.42567 0.52563,0.324853 0.83754,0.219693 0.69314,-0.233688 C 198.38044,91.04781 201.13363,85 202.12132,85 c 1.19702,0 1.11271,1.737326 -0.12132,2.5 -0.55,0.339919 -0.98999,1.153976 -0.97776,1.809017 0.0122,0.655041 0.90171,0.06598 1.97662,-1.309017 1.07491,-1.375 1.8524,-3.625 1.72776,-5 -0.18864,-2.08097 0.1566,-2.446528 2.05976,-2.180979 2.00197,0.279337 2.20617,-5.39e-4 1.64159,-2.25 C 207.93576,76.607901 208.16378,76 209.39159,76 c 1.20598,0 1.58866,-0.938276 1.52946,-3.75 -0.0434,-2.0625 -0.30592,-3.1875 -0.58333,-2.5 -0.27741,0.6875 -1.27689,1.25 -2.22105,1.25 -0.94417,0 -2.26384,0.547171 -2.93261,1.215937 -0.66876,0.668765 -2.67126,1.231265 -4.45,1.25 -2.04053,0.02149 -3.1418,0.495374 -2.98406,1.284063 0.1375,0.6875 -0.0875,1.28037 -0.5,1.317489 -0.4125,0.03712 -2.2125,0.258331 -4,0.491582 -2.35159,0.306859 -3.25,0.02808 -3.25,-1.008472 0,-2.005639 -1.95541,-2.995184 -3.28713,-1.663467 -1.83692,1.836915 -4.84161,1.266005 -7.30045,-1.387132 -2.92253,-3.153457 -7.36956,-3.379915 -8.14496,-0.414771 -0.45517,1.740578 -1.07313,1.986208 -3.73883,1.48612 -2.47519,-0.464349 -3.62486,-0.122182 -5.11108,1.52118 -1.05465,1.16616 -3.49255,2.931194 -5.41755,3.922298 -4.36316,2.246414 -8.53397,6.588631 -9.96436,10.373861 -0.60038,1.588779 -1.3354,2.644886 -1.63338,2.346906 -1.19844,-1.19844 3.80608,-8.752845 7.55624,-11.406254 2.19934,-1.556137 4.00841,-3.641531 4.02015,-4.634209 C 157.03172,71.208872 139.51576,51 135.57424,51 c -1.80068,0 -2.12962,-2.538725 -0.46244,-3.569098 0.6115,-0.377923 1.5115,-0.06698 2,0.690983 0.74519,1.156229 1.0513,1.136605 1.9012,-0.121885 0.55716,-0.825 0.82831,-2.272116 0.60256,-3.215813 -0.22574,-0.943698 0.10591,-1.618698 0.737,-1.5 0.63109,0.118697 1.08788,-0.55404 1.01509,-1.494971 -0.0728,-0.940932 0.3772,-1.615932 1,-1.5 0.64863,0.120741 1.02426,-0.857165 0.87932,-2.289216 -0.15259,-1.507655 0.06,-2.018916 0.53553,-1.288012 0.56011,0.860886 2.08187,0.09357 5.25302,-2.648724 4.28398,-3.704622 4.95664,-6.788483 0.93257,-4.275409 -2.961,1.849174 -3.06557,1.506058 -0.67205,-2.20508 2.58916,-4.014471 6.61597,-6.343181 7.76204,-4.488797 0.50732,0.820866 0.84961,0.625221 1.09064,-0.623397 0.38852,-2.012639 9.75781,-4.721673 13.35128,-3.860385 2.65491,0.636333 10.44713,-2.172884 12.11283,-4.366868 C 185.27687,12.051536 185.38586,6.7858564 183.8,5.2 c -1.96522,-1.9652181 -3.05945,-1.3698686 -2.38936,1.3 0.7052,2.8097391 -0.5166,3.2511779 -2.76778,1 C 176.76098,5.6181223 175,5.5664033 175,7.3930112 c 0,1.6602962 -2.72546,2.9306148 -3.20447,1.4935828 -0.18352,-0.5505785 -1.11001,-0.7031457 -2.05886,-0.3390381 -0.94885,0.3641075 -1.47739,1.0629465 -1.17454,1.5529751 1.00288,1.622697 -10.11056,5.094812 -13.4808,4.211735 -1.89376,-0.496208 -2.29266,-0.305373 -1.83805,0.879325 0.37616,0.980248 -1.46574,3.520389 -5.23047,7.213309 -3.19611,3.135132 -5.97132,5.219557 -6.16716,4.632057 -0.22389,-0.671674 -1.21426,-0.467075 -2.66803,0.551185 -1.33287,0.933582 -2.07655,2.232852 -1.75607,3.068009 0.74094,1.930878 -2.37653,6.575101 -3.99636,5.953517 -0.70343,-0.269933 -1.87436,0.230645 -2.60208,1.112394 -0.92338,1.118841 -0.98518,1.717048 -0.20454,1.980084 1.39011,0.468397 -0.55292,6.660776 -2.79284,8.900694 -1.32673,1.326734 -1.48552,1.242273 -1.41039,-0.750216 0.10583,-2.806786 -5.647,-6.289397 -13.20763,-7.995544 -3.61549,-0.815877 -5.13431,-1.605965 -4.79368,-2.49365 0.78161,-2.036828 -1.57995,-2.857007 -2.92598,-1.016205 C 104.62834,37.522948 102.75565,38 99,38 c -3.755652,0 -5.628344,-0.477052 -6.488054,-1.652775 -1.362852,-1.863812 -3.703132,-1.009024 -2.908306,1.062259 0.350749,0.914039 -0.653725,1.564931 -3.132748,2.029999 C 81.57112,40.358686 78,42.064683 78,43.486201 c 0,0.640844 1.102283,2.200712 2.449518,3.466373 2.498205,2.346942 6.568231,10.006638 6.52852,12.286528 C 86.965959,59.932596 86.040499,58.475 84.92146,56 81.200838,47.771025 73.027934,41.311867 64.757881,40.064446 c -3.700005,-0.558094 -3.726407,-0.5946 -2.345978,-3.243757 1.531866,-2.939774 1.17751,-3.984098 -1.060465,-3.125307 -1.141171,0.437909 -1.306978,-0.02434 -0.772536,-2.153732 0.610266,-2.431492 0.434901,-2.676756 -1.699203,-2.376481 -1.965011,0.276483 -2.362525,-0.08831 -2.281148,-2.093406 0.105622,-2.602472 -4.657283,-7.594766 -5.674906,-5.948218 -0.79429,1.285188 -4.106832,-0.08537 -3.61755,-1.496752 0.495618,-1.42966 -4.178059,-4.613155 -5.837623,-3.976321 C 40.783375,15.913369 35.211055,13.614961 29.08554,10.5429 20.057366,6.0151007 17.579482,5.1546867 16.001008,5.9994604 14.079091,7.0280395 14.08074,7.093315 16.127856,11.020793 c 2.089349,4.008505 3.39116,4.922159 4.077882,2.861993 0.604139,-1.812417 16.431622,6.622473 17.080156,9.102474 0.422406,1.615283 1.081659,1.960839 2.880928,1.510076 1.369141,-0.343004 3.15955,0.04054 4.333178,0.928269 1.16626,0.882152 1.464245,1.526046 0.714816,1.544592 -0.99271,0.02456 -1.030905,0.506927 -0.167834,2.119589 0.848815,1.586027 1.715016,1.937781 3.604204,1.463625 2.158503,-0.54175 2.444733,-0.32228 2.167835,1.662214 -0.21612,1.548901 0.135247,2.188711 1.089338,1.983589 2.014002,-0.432995 3.192632,1.976172 1.792281,3.663493 -0.975264,1.175121 -0.832419,1.317817 0.807202,0.806367 1.095687,-0.341779 2.65191,-0.207527 3.458274,0.298338 1.161348,0.728563 0.849538,1.143854 -1.5,1.997807 -8.18283,2.974097 -12.679508,7.076917 -16.211307,14.791383 C 38.928644,58.651326 37.428791,60.765007 36.9218,60.45167 36.41481,60.138333 36,60.358524 36,60.940983 36,61.523442 36.45,62 37,62 c 0.55,0 1,1.575 1,3.5 0,1.925 -0.45,3.5 -1,3.5 -0.55,0 -1,0.45 -1,1 0,0.55 0.457358,0.8875 1.016352,0.75 0.558994,-0.1375 1.848097,1.575626 2.864675,3.806946 l 1.848323,4.056945 -2.72284,-0.399628 C 33.167059,77.357214 22.687739,85.690646 19.895805,93.4116 19.084624,95.654882 18.08419,96.862548 17.289617,96.557642 16.580328,96.285462 16,96.750204 16,97.590402 c 0,0.840197 0.45,1.249517 1,0.909598 0.611525,-0.377944 1,1.175955 1,4 0,2.82405 -0.388475,4.37794 -1,4 -0.55,-0.33992 -1,0.0694 -1,0.9096 0,0.8402 0.580328,1.30494 1.289617,1.03276 0.792849,-0.30425 1.790015,0.88895 2.588659,3.09756 1.714131,4.74035 6.796696,10.42633 10.823982,12.10904 4.483315,1.87324 4.652691,1.75015 2.184822,-1.58782 -2.879624,-3.8949 -2.994837,-12.47425 -0.231306,-17.22415 2.603001,-4.47399 7.427862,-5.165172 9.884418,-1.41599 3.946558,6.02321 3.724243,15.02491 -0.512601,20.75555 -2.188496,2.9601 -2.110788,3.09155 2.472409,4.18235 1.1,0.2618 -1.367305,0.40065 -5.482899,0.30855 l -7.4829,-0.16745 -0.703136,4 c -0.386725,2.2 -1.000961,5.19346 -1.364969,6.65213 C 28.324623,143.7263 31.696838,146 39.622445,146 c 5.587522,0 6.439446,0.2205 5.451441,1.41097 -1.740646,2.09735 -0.529163,2.35701 10.343069,2.21686 6.949714,-0.0896 10.041538,-0.50184 10.333333,-1.37783 0.229008,-0.6875 1.46175,-1.25 2.739426,-1.25 1.830717,0 2.212204,0.42387 1.800035,2 -0.425771,1.62815 -0.03068,2 2.125004,2 1.456409,0 2.907038,-0.675 3.223621,-1.5 1.165054,-3.03608 11.334657,-1.05398 22.861626,4.45585 3.3,1.57738 6.94963,3.14298 8.11029,3.4791 1.16067,0.33613 3.53408,2.17577 5.27425,4.0881 1.74018,1.91232 3.59149,3.47695 4.11403,3.47695 1.0462,0 4.00143,5.21696 4.00143,7.06384 0,1.57422 -3.39787,0.81428 -15.5,-3.46661 -5.610814,-1.98472 -8.861687,-3.55046 -7.40655,-3.56727 1.426397,-0.0165 5.20934,0.87004 8.40655,1.97004 6.06245,2.08579 9.5,2.5344 9.5,1.23978 0,-0.41812 -1.18179,-2.03472 -2.6262,-3.59245 -1.89827,-2.0472 -3.30024,-2.70338 -5.05803,-2.36736 -1.6922,0.32348 -2.28262,0.076 -1.94124,-0.81359 0.67926,-1.77014 -2.01088,-3.87029 -7.657185,-5.97785 -2.630461,-0.98185 -5.024055,-2.17578 -5.319099,-2.65317 C 91.763284,151.80797 90,152.70765 90,154.05902 90,154.57656 90.623246,155 91.38499,155 c 0.761745,0 2.122118,1.125 3.023053,2.5 l 1.638063,2.5 -4.054438,0 c -2.681454,0 -4.249359,-0.50796 -4.630042,-1.5 C 86.60168,156.51961 84,156.56681 84,158.56098 c 0,1.34833 -1.328243,1.48045 -9.75,0.96984 -5.3625,-0.32513 -11.396848,-0.83526 -13.409661,-1.13362 -2.548398,-0.37775 -3.914832,-0.11413 -4.5,0.86816 -0.79401,1.33287 -7.463866,3.66813 -11.844154,4.1469 C 42.093016,163.67493 37,166.87005 37,168.11501 37,168.60175 37.685374,169 38.523053,169 c 1.353482,0 1.349269,0.26523 -0.03784,2.38222 -1.524589,2.32682 -1.414657,2.5094 4.726947,7.85072 10.678427,9.28698 17.674997,12.40529 34.212039,15.24804 4.908311,0.84375 9.145811,1.7557 9.416667,2.02656 1.271449,1.27144 14.168694,0.28123 20.551324,-1.57788 z M 41.538785,167.93724 c 0.266607,-0.43137 2.616946,-1.48608 5.222977,-2.34378 5.582813,-1.83742 17.571741,-2.9421 16.704696,-1.53919 C 63.144987,164.57442 60.912819,165 58.506083,165 c -2.406736,0 -5.642679,0.50757 -7.190983,1.12794 -3.904511,1.56445 -10.363793,2.75986 -9.776315,1.8093 z m 23.890621,-4.05146 c -0.302525,-0.4895 3.169865,-0.85046 7.761577,-0.80683 9.510098,0.0904 9.341563,0.54635 -0.45256,1.22446 -3.718867,0.25748 -7.007925,0.0695 -7.309017,-0.41763 z M 86.75,164.33772 c 0.6875,-0.27741 1.8125,-0.27741 2.5,0 0.6875,0.27741 0.125,0.50439 -1.25,0.50439 -1.375,0 -1.9375,-0.22698 -1.25,-0.50439 z M 99,161 c -0.825,-0.53316 -1.05,-0.96937 -0.5,-0.96937 0.55,0 1.675,0.43621 2.5,0.96937 0.825,0.53316 1.05,0.96937 0.5,0.96937 -0.55,0 -1.675,-0.43621 -2.5,-0.96937 z M 50.693853,147.36052 c -1.1799,-1.1799 0.399821,-2.36081 3.115164,-2.32872 2.5821,0.0305 2.61244,0.0912 0.749853,1.5 -2.141385,1.61967 -2.909398,1.78434 -3.865017,0.82872 z M 82.5,129.06493 C 77.478506,127.84245 73.371866,125.25237 69.754441,121.02622 67.858978,118.8118 65.877087,117 65.350239,117 c -0.526848,0 -2.50868,1.61443 -4.404072,3.58763 -3.722766,3.87558 -9.779802,7.4183 -12.656329,7.4026 -0.984411,-0.005 0.460162,-1.07526 3.210162,-2.37754 5.662222,-2.68137 10.840041,-7.68821 12.498875,-12.08615 l 1.121542,-2.97346 1.782811,3.98204 C 69.175579,119.61058 75.245666,125 78.689784,125 c 2.414166,0 2.49936,-0.1376 1.083484,-1.75 -4.471571,-5.09222 -3.580471,-18.67726 1.399958,-21.34271 5.222698,-2.795101 9.993441,2.73911 9.993441,11.59271 0,4.59896 -2.469758,11.5 -4.11564,11.5 -1.483586,0 -1.31259,3.72779 0.198973,4.33772 1.896222,0.76514 -1.222178,0.58605 -4.75,-0.27279 z m 15,-2.21946 c 5.85797,-3.02585 10.42871,-7.67773 13.11269,-13.34547 2.60435,-5.49959 3.27408,-4.8666 0.88944,0.84065 -2.81824,6.745 -12.002234,14.77654 -16.712292,14.61515 C 94.080427,128.9315 95.3,127.98184 97.5,126.84547 z m 55.25,-4.5512 c 1.2375,-0.23836 3.2625,-0.23836 4.5,0 1.2375,0.23835 0.225,0.43337 -2.25,0.43337 -2.475,0 -3.4875,-0.19502 -2.25,-0.43337 z m -2.61802,-14.90395 c -1.12178,-2.46203 -0.92207,-2.88081 2.98731,-6.26437 2.30419,-1.99427 5.13248,-4.172192 6.28508,-4.839822 3.16384,-1.832619 12.72179,-4.495268 13.45312,-3.747763 0.35338,0.3612 -0.72641,1.850332 -2.39954,3.309181 -1.67313,1.45885 -3.78722,3.8384 -4.69799,5.287884 -0.91076,1.44949 -3.70995,3.78345 -6.2204,5.18657 -7.09185,3.96371 -8.03933,4.07131 -9.40758,1.06832 z m 11.55357,-5.56463 C 164.4258,99.251353 164.63151,98 162.31445,98 160.55911,98 156,101.73592 156,103.17431 c 0,1.60432 3.40101,0.79759 5.68555,-1.34862 z m -50.5653,-7.369677 C 109.31856,89.473518 103.61474,83.36334 98.066872,80.47266 c -2.51178,-1.308746 -3.986445,-2.40049 -3.277034,-2.426099 2.499491,-0.09023 8.935982,3.877135 12.056972,7.431752 3.19233,3.635858 6.44992,10.131484 5.90334,11.771227 -0.16349,0.490491 -0.89695,-0.766597 -1.6299,-2.793527 z M 64.282018,93.079975 c -0.993152,-1.590289 -0.84411,-1.961228 0.97964,-2.438149 2.740801,-0.716736 2.820009,-0.597197 1.383206,2.087493 -1.143555,2.136752 -1.238601,2.150858 -2.362846,0.350656 z M 55.5,90.078934 c -1.1,-0.429273 -2,-1.372645 -2,-2.096382 0,-0.723737 -0.625138,-1.524265 -1.389196,-1.778951 -0.843224,-0.281074 -1.114789,-0.01907 -0.690983,0.666667 1.008553,1.631873 -0.714892,1.38768 -2.978691,-0.422047 -1.876854,-1.500395 -1.863271,-1.530212 0.410189,-0.900455 2.203222,0.610301 2.307147,0.450209 1.65,-2.54176 -1.657873,-7.548248 0.09416,-16.183961 3.671907,-18.098714 3.31481,-1.774032 6.793371,-0.231486 8.457034,3.750221 2.678409,6.410335 1.983893,13.097115 -1.982313,19.085654 C 58.316294,91.26371 58.417865,91.217624 55.5,90.078934 z M 83.19735,77.399002 c 0.933542,-1.06707 2.142519,-3.055875 2.686614,-4.419565 L 86.873227,70.5 l 0.06339,2.55 C 86.971476,74.4525 87.54,76.14 88.2,76.8 c 0.933333,0.933333 0.729286,1.2 -0.918213,1.2 -1.165016,0 -2.942516,0.301304 -3.95,0.669565 -1.732627,0.63332 -1.739905,0.564541 -0.134437,-1.270563 z M 181,13.059017 c 0,-0.517541 0.45,-1.219098 1,-1.559017 0.55,-0.339919 1,0.08352 1,0.940983 C 183,13.298442 182.55,14 182,14 c -0.55,0 -1,-0.423442 -1,-0.940983 z M 142.8125,181.0625 c 0.25,-0.75 -0.125,-1.125 -0.875,-0.875 -0.72188,0.24062 -1.50938,1.02812 -1.75,1.75 -0.25,0.75 0.125,1.125 0.875,0.875 0.72187,-0.24063 1.50937,-1.02813 1.75,-1.75 z M 34,174.05902 c 0,-0.51754 -0.45,-1.2191 -1,-1.55902 -0.55,-0.33992 -1,0.0835 -1,0.94098 0,0.85746 0.45,1.55902 1,1.55902 0.55,0 1,-0.42344 1,-0.94098 z M 153,171 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 7.54112,-11.06653 c 1.07627,-1.74144 -0.14952,-2.11024 -1.52106,-0.45764 -0.78875,0.95039 -0.86462,1.52417 -0.20152,1.52417 0.58488,0 1.36004,-0.47994 1.72258,-1.06653 z M 86,151.5 c -1.35737,-1.63553 -5,-2.0605 -5,-0.58333 0,1.08424 1.767649,1.89456 4.372445,2.00438 C 86.92553,152.98653 87.032564,152.74416 86,151.5 z m 79,-1.11803 c 0,-0.825 -0.45,-1.22189 -1,-0.88197 -0.55,0.33992 -1,1.29303 -1,2.11803 0,0.825 0.45,1.22189 1,0.88197 0.55,-0.33992 1,-1.29303 1,-2.11803 z M 25.61691,122.41642 c -2.055444,-1.99622 -4.040889,-3.32577 -4.4121,-2.95456 -0.371211,0.37121 0.27818,1.43165 1.443091,2.35653 1.16491,0.92489 2.662375,2.74242 3.3277,4.03897 0.869221,1.69389 1.51488,2.05216 2.294081,1.27296 0.7792,-0.7792 0.03259,-2.10591 -2.652772,-4.7139 z M 175,117.44098 C 175,117.19844 174.55,117 174,117 c -0.55,0 -1,0.47656 -1,1.05902 0,0.58246 0.45,0.7809 1,0.44098 0.55,-0.33992 1,-0.81648 1,-1.05902 z M 20.361626,115.5 C 19.75303,113.91402 18,113.41916 18,114.83333 18,115.89085 19.093086,117 20.135282,117 c 0.441072,0 0.542927,-0.675 0.226344,-1.5 z m 0.03206,-26.08356 C 20.767417,88.442526 20.54393,87.985357 19.81318,88.22894 18.318343,88.727219 17.495286,91 18.809678,91 c 0.536989,0 1.249795,-0.712602 1.584013,-1.58356 z m 4.058163,-5.983304 1.681874,-2.566864 -2.566864,1.681874 C 21.034688,84.207292 20.161212,86 21.88499,86 c 0.486745,0 1.641833,-1.155089 2.566864,-2.566864 z M 37.916662,75.375772 C 38.145828,75.169098 38.062429,74.7291 37.731329,74.398001 37.40023,74.066902 36.08773,74.558565 34.814663,75.490586 L 32.5,77.185171 35,76.468358 c 1.375,-0.394247 2.6875,-0.885911 2.916667,-1.092586 z M 162,73.622445 C 162,73.414789 161.325,72.684689 160.5,72 159.27149,70.980429 159,71.048765 159,72.377555 159,73.2699 159.675,74 160.5,74 c 0.825,0 1.5,-0.1699 1.5,-0.377555 z M 206.71941,68.25 c 0.36116,-0.9625 1.35953,-2.298188 2.21862,-2.968197 0.85908,-0.670008 1.14097,-1.232508 0.62642,-1.25 C 208.39676,63.992108 204,68.05547 204,69.174314 c 0,1.537015 2.05838,0.837383 2.71941,-0.924314 z M 153,62 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m -10,-9.940983 c 0,-1.17986 -1.95035,-2.441996 -2.66667,-1.725684 C 139.61702,51.049646 140.87916,53 142.05902,53 142.57656,53 143,52.576558 143,52.059017 z M 46.700575,43.367242 c -0.963083,-0.963083 -4.787261,2.683479 -4.055638,3.867271 0.333125,0.539007 1.515583,0.04941 2.670863,-1.105869 1.140199,-1.140199 1.763348,-2.38283 1.384775,-2.761402 z M 129.77083,42.1875 C 130.01137,41.465889 129.10511,41 127.46089,41 c -2.31788,0 -2.52335,0.219816 -1.43325,1.533305 1.39251,1.677875 3.12189,1.518111 3.74319,-0.345805 z M 51,40.940983 C 51,40.358524 50.55,40.160081 50,40.5 49.45,40.839919 49,41.316476 49,41.559017 49,41.801558 49.45,42 50,42 c 0.55,0 1,-0.476558 1,-1.059017 z M 81,39 c 1.333333,-0.861666 1.333333,-0.969374 0,-0.969374 -0.825,0 -2.175,0.436218 -3,0.969374 -1.333333,0.861666 -1.333333,0.969374 0,0.969374 0.825,0 2.175,-0.436218 3,-0.969374 z m 39,0 c -0.825,-0.533156 -2.175,-0.969374 -3,-0.969374 -1.33333,0 -1.33333,0.107708 0,0.969374 0.825,0.533156 2.175,0.969374 3,0.969374 1.33333,0 1.33333,-0.107708 0,-0.969374 z M 67.5,38 C 67.160081,37.45 66.683524,37 66.440983,37 66.198442,37 66,37.45 66,38 c 0,0.55 0.476558,1 1.059017,1 0.582459,0 0.780902,-0.45 0.440983,-1 z M 13.984687,10.25 C 13.976265,9.8375 13.533156,8.825 13,8 12.216126,6.7870411 12.027695,6.9305617 12.015313,8.75 12.006891,9.9875 12.45,11 13,11 c 0.55,0 0.993109,-0.3375 0.984687,-0.75 z M 17,2.8930112 C 17,2.401855 16.325,2 15.5,2 14.675,2 14,2.6608768 14,3.4686152 14,4.3632083 14.586289,4.7122501 15.5,4.3616264 16.325,4.0450442 17,3.3841674 17,2.8930112 z"
+ id="path3945" />
+ <path
+ style="fill:#171817"
+ d="M 0,134.02342 0,0 l 109,0 109,0 0,134 0,134 -17.94098,0 c -12.61931,0 -18.15546,-0.34703 -18.66405,-1.16994 -0.47712,-0.772 -0.19032,-0.96551 0.84322,-0.5689 0.86145,0.33057 1.81944,0.34788 2.12886,0.0385 0.73835,-0.73835 -1.30177,-4.58807 -2.94801,-5.56292 -0.84167,-0.49841 -1.09768,-1.94213 -0.73774,-4.16023 0.43095,-2.65564 0.0894,-3.79235 -1.56503,-5.20894 C 177.95232,250.37092 177,249.03563 177,248.4002 c 0,-0.63542 -0.62854,-1.67696 -1.39677,-2.31452 -0.76822,-0.63757 -1.18693,-1.96161 -0.93047,-2.9423 0.52077,-1.99145 -1.15568,-3.72787 -4.17276,-4.32202 -1.28309,-0.25268 -1.88661,-1.04328 -1.68367,-2.20557 C 169.17545,234.55904 166.35799,231 164.37069,231 c -0.72563,0 -1.96571,-1.2375 -2.75573,-2.75 -2.05184,-3.92824 -7.23845,-8.60073 -8.60773,-7.75447 -1.63119,1.00813 -6.14259,-3.49368 -5.50723,-5.49553 0.59982,-1.88986 -3.02982,-5.62161 -6,-6.1688 -1.25477,-0.23116 -2,-1.15794 -2,-2.48723 C 139.5,203.64642 136.2496,200 133.84501,200 132.47316,200 132,199.25162 132,197.08179 132,192.42019 131.04095,191 127.89301,191 c -1.59115,0 -2.88916,-0.3375 -2.88445,-0.75 0.005,-0.4125 3.25136,-2.75082 7.21478,-5.19626 9.54705,-5.89056 18.12659,-14.64865 24.53888,-25.04957 2.88078,-4.67271 5.23778,-7.7709 5.23778,-6.88486 0,0.88603 -0.9,2.75514 -2,4.15356 -2.11691,2.69121 -2.5926,4.72713 -1.1045,4.72713 1.15152,0 7.44468,-12.99316 6.6689,-13.76894 -0.32179,-0.32178 -1.28368,0.28209 -2.13755,1.34194 -0.9534,1.18339 -1.36192,1.34817 -1.05864,0.427 3.20568,-9.73664 4.12645,-12 4.8818,-12 0.48662,0 0.61067,1.0125 0.27566,2.25 -0.5619,2.07564 -0.49643,2.05724 0.84488,-0.23745 1.48491,-2.54037 1.23593,-4.50541 -0.43965,-3.46984 -0.51199,0.31643 -0.9309,-0.0737 -0.9309,-0.86706 0,-0.79331 1.0125,-1.72727 2.25,-2.07545 2.10072,-0.59107 2.13389,-0.72223 0.5,-1.97688 C 167.40721,129.82432 167.53308,128 170,128 c 2.93614,0 2.52738,-3.44 -0.71149,-5.9877 -2.2308,-1.75474 -2.4524,-2.29673 -1.25,-3.05726 1.91176,-1.20921 3.71113,-1.20008 4.12816,0.0209 0.58549,1.71431 11.79982,-6.28741 11.87901,-8.47599 0.0398,-1.1 1.07878,-4.025 2.30883,-6.5 1.74063,-3.50233 2.72521,-4.447188 4.44097,-4.26179 C 192.37627,99.909023 193,99.440379 193,98.08183 c 0,-1.346065 0.53173,-1.755541 1.83657,-1.414316 2.01467,0.526846 5.69968,-3.990824 4.64597,-5.69576 C 199.15223,90.437289 199.75604,90 200.82435,90 c 1.94447,0 3.40238,-2.625947 3.60767,-6.498004 0.068,-1.282664 0.80933,-1.998718 2.0706,-2 1.1437,-0.0012 2.12103,-0.80817 2.33887,-1.931275 0.20582,-1.061103 1.00068,-2.555746 1.76636,-3.321428 1.57612,-1.576124 1.86913,-5.836469 0.46125,-6.706588 -0.512,-0.316431 -1.21356,-0.117988 -1.55902,0.440983 C 209.16462,70.54266 208.27565,71 207.5346,71 c -2.02343,0 -0.60428,-4.169017 1.61687,-4.749862 C 211.50193,65.635479 211.56668,64 209.24055,64 c -2.0656,0 -4.73213,3.641163 -4.76015,6.5 -0.0156,1.589619 -0.70392,2.006733 -3.35461,2.032811 -1.96719,0.01935 -3.84998,0.737093 -4.59064,1.75 C 194.95897,76.438377 190,76.603183 190,74.5 c 0,-1.681394 -2.54515,-2.044986 -3.5,-0.5 -1.01456,1.641591 -3.0149,1.149658 -6.09446,-1.498779 -3.72655,-3.20485 -8.93064,-3.425229 -9.71874,-0.411561 -0.43677,1.670236 -1.01214,1.939949 -2.86663,1.343772 C 166.54408,73.023194 164.6,72.574075 163.5,72.435391 c -1.1,-0.138684 -2.7875,-0.566526 -3.75,-0.95076 -2.54288,-1.015129 -2.17512,1.217484 0.43022,2.61182 2.10691,1.127582 2.11729,1.212834 0.30887,2.535184 -2.41445,1.765487 -3.56991,1.742565 -2.87931,-0.05712 1.34892,-3.515242 -15.10476,-23.291408 -21.35566,-25.667996 -1.95823,-0.744519 -2.3001,-1.260542 -1.41891,-2.141732 0.88119,-0.881191 2.00465,-0.343099 4.66284,2.233327 2.56803,2.489026 3.50195,2.951258 3.50195,1.733238 0,-0.913541 -0.88324,-2.133681 -1.96276,-2.711422 -1.29275,-0.691859 -1.74732,-1.642613 -1.33165,-2.785183 1.22214,-3.359262 6.66421,-10.766677 9.96045,-13.55755 3.64029,-3.082168 4.12813,-4.356572 1.85804,-4.853872 -1.24462,-0.272657 -1.27497,-0.715091 -0.19363,-2.823324 0.99549,-1.940877 1.99653,-2.467023 4.47591,-2.352552 1.7565,0.0811 3.19364,-0.256403 3.19364,-0.75 C 159,22.403852 159.86786,22 160.92857,22 c 1.06072,0 2.60228,-0.673707 3.4257,-1.497127 0.82342,-0.82342 2.20556,-1.225275 3.07143,-0.893011 0.86586,0.332263 1.5743,0.168373 1.5743,-0.364201 0,-0.532575 1.09131,-0.759701 2.42512,-0.504726 3.16013,0.604096 9.48934,-1.453863 12.27449,-3.991078 1.69956,-1.548268 2.06844,-2.713769 1.62265,-5.1268281 -0.92611,-5.0129624 -2.46282,-6.0617749 -6.78947,-4.6338519 -2.02004,0.6666761 -3.91346,1.8392579 -4.20759,2.6057372 -0.29412,0.7664792 -0.96319,1.1288188 -1.48682,0.805199 C 171.20184,7.3886781 167,8.9621629 167,10.58644 c 0,1.105594 -0.58589,1.36238 -2.04896,0.89802 -1.21072,-0.384267 -3.06326,0.01427 -4.52825,0.974172 -1.3636,0.893469 -2.90727,1.359976 -3.43037,1.036684 C 155.43531,12.532971 152,14.922155 152,16.967433 c 0,1.243133 -2.49913,3.565901 -7.25,6.738376 -5.12611,3.42305 -7.25946,5.459921 -7.28229,6.952968 C 137.42503,33.44909 135.22101,36 132.8528,36 c -1.10899,0 -2.29868,1.042567 -2.8528,2.5 -0.68348,1.797697 -1.69415,2.5 -3.59769,2.5 -2.23968,0 -2.45556,0.230913 -1.40231,1.5 0.68469,0.825 2.08979,1.5 3.12244,1.5 2.05069,0 2.51605,1.487357 0.79764,2.549392 -0.59395,0.367084 -1.70845,-0.22994 -2.47667,-1.32672 -0.76821,-1.09678 -2.64475,-2.326046 -4.17008,-2.731702 -1.52533,-0.405656 -2.21083,-0.944574 -1.52333,-1.197597 1.96043,-0.721501 1.47716,-1.86884 -1.32494,-3.145562 -2.67614,-1.219334 -4.88184,-0.695919 -3.88235,0.921287 0.31643,0.511996 0.079,0.930902 -0.52753,0.930902 -0.60657,0 -0.97063,-0.7875 -0.80902,-1.75 0.17118,-1.019483 -0.33232,-1.75 -1.20616,-1.75 -0.825,0 -1.3875,0.5625 -1.25,1.25 0.1375,0.6875 -0.425,1.25 -1.25,1.25 -0.83333,0 -1.5,-0.888889 -1.5,-2 0,-2.405353 -3.15671,-2.721024 -5,-0.5 -1.6219,1.954269 -8.378101,1.954269 -10,0 -1.843286,-2.221024 -5,-1.905353 -5,0.5 0,1.111111 -0.666667,2 -1.5,2 -0.825,0 -1.3875,-0.5625 -1.25,-1.25 0.1375,-0.6875 -0.425,-1.25 -1.25,-1.25 -0.873843,0 -1.377341,0.730517 -1.206163,1.75 0.16161,0.9625 -0.202448,1.75 -0.809017,1.75 -0.60657,0 -0.843956,-0.418906 -0.527525,-0.930902 1.242481,-2.010376 -1.587014,-2.04273 -5.176238,-0.05919 L 73.5,41.099469 l 4,-0.506359 c 2.997267,-0.379422 3.561304,-0.254092 2.25,0.499956 -0.9625,0.553473 -1.75,1.696454 -1.75,2.539957 0,0.843504 -0.337716,1.383644 -0.75048,1.20031 C 69.533557,41.406208 68,40.407142 68,38.807552 68,37.813398 67.276855,37 66.393011,37 c -1.017592,0 -1.395874,0.550157 -1.031385,1.5 0.391522,1.020289 -0.05397,1.5 -1.393011,1.5 -2.297726,0 -2.327242,-0.118794 -0.840353,-3.382159 C 64.079142,34.530887 63.907138,33.6981 62.03421,31.320788 60.811937,29.769355 59.066719,28.489324 58.155948,28.476275 57.12712,28.461534 56.615737,27.779379 56.805611,26.675001 57.15024,24.670509 53.215912,20.043677 51.144356,20.017277 50.398752,20.007774 48.451725,18.875 46.817631,17.5 45.183536,16.125 42.709788,15 41.320413,15 39.931039,15 34.262608,12.731367 28.723901,9.9585941 18.05648,4.6182973 14.064868,4.1417579 12.019112,7.9642893 c -0.789807,1.4757666 -0.250432,2.2964047 2.981372,4.5360467 2.25576,1.563242 4.620816,2.475226 5.52211,2.129368 2.340521,-0.898143 15.105855,5.841479 15.753252,8.317132 C 36.691743,24.537226 37.622747,25 40.40638,25 43.255214,25 44,25.389128 44,26.877555 c 0,2.38824 2.315011,4.33564 4.675811,3.933318 1.38508,-0.236041 1.748879,0.230735 1.511331,1.939127 -0.233258,1.677533 0.188175,2.25 1.65638,2.25 3.29284,0 1.422323,3.654161 -3.281638,6.410866 -5.476312,3.209332 -7.411269,5.446151 -5.651832,6.533543 0.985932,0.60934 0.708442,1.699679 -1.203282,4.728046 -1.366601,2.164837 -2.653352,4.811649 -2.859445,5.881806 C 38.641232,59.624417 37.953773,60.5 37.319638,60.5 c -2.011471,0 -2.671275,1.427834 -0.962766,2.08345 2.088929,0.801598 2.146758,5.009312 0.07975,5.802498 -0.85986,0.32996 -1.278766,1.060445 -0.930902,1.623301 0.347864,0.562856 1.037768,0.772894 1.533118,0.46675 C 37.744314,70.039988 41,75.913395 41,77.622124 41,77.829956 39.513101,78 37.695781,78 33.805437,78 25.904686,82.68964 23.428675,86.468512 22.493899,87.89516 21.483298,88.816632 21.182894,88.516228 20.882491,88.215824 22.150188,86.408521 24,84.5 c 1.849812,-1.908521 3.010979,-3.81428 2.580371,-4.23502 -1.075086,-1.050447 -8.574313,7.786242 -8.577666,10.107465 -0.0022,1.543731 0.258319,1.655814 1.48416,0.638456 1.29568,-1.075319 1.346506,-0.831355 0.395276,1.897344 -0.696439,1.997807 -1.674045,3.033669 -2.700612,2.861543 C 16.296565,95.621405 15.410694,96.2875 15.212928,97.25 14.991531,98.327501 15.457957,99 16.426676,99 17.558094,99 18,99.983059 18,102.5 c 0,2.51694 -0.441906,3.5 -1.573324,3.5 -0.968719,0 -1.435145,0.6725 -1.213748,1.75 0.197766,0.9625 1.083637,1.6286 1.968601,1.48021 1.026567,-0.17212 2.004173,0.86374 2.700612,2.86155 0.95123,2.72869 0.900404,2.97266 -0.395276,1.89734 -3.160646,-2.6231 -1.474474,2.24014 2.513135,7.24837 2.2,2.76308 4,5.415 4,5.89316 0,0.47815 0.675,0.86937 1.5,0.86937 2.589726,0 1.647324,-2.45025 -2.5,-6.5 -2.2,-2.14824 -3.99501,-4.37707 -3.988911,-4.95295 0.0061,-0.57588 1.172539,0.42673 2.592088,2.22801 2.316094,2.93891 7.950657,6.22494 10.673935,6.22494 0.568075,0 0.212063,-0.90697 -0.791137,-2.0155 -2.304433,-2.54637 -3.134531,-11.48933 -1.520426,-16.38011 1.378878,-4.17804 4.159539,-6.04079 7.693489,-5.15383 5.752026,1.44367 7.178358,15.77094 2.283913,22.94153 -2.183859,3.19946 -2.86496,3.55405 -6.422032,3.34347 -4.412609,-0.26123 -3.781442,-1.47856 -6.153955,11.86914 -0.453388,2.55076 -0.06202,3.49 2.193458,5.26417 2.297544,1.80725 3.535888,2.05458 7.592444,1.51646 C 43.647112,145.78915 44,145.89907 44,147.89511 c 0,2.08073 0.359708,2.14708 10.75,1.98268 7.951408,-0.1258 11.205585,-0.56288 12.5,-1.67892 1.726736,-1.48879 1.878516,-1.41371 2.125,1.05113 0.185964,1.85964 4.28812,2.09937 6.724352,0.39296 C 78.489682,147.96871 81,148.47903 81,150.63921 c 0,1.50825 3.93201,3.46178 5.318174,2.64223 0.449995,-0.26606 0.557392,-1.16333 0.238659,-1.99393 -0.412552,-1.07509 -0.120523,-1.33406 1.013614,-0.89885 C 88.446667,150.7249 89.351771,151 89.581787,151 89.811804,151 90,151.91412 90,153.03138 c 0,1.11727 0.7875,2.32194 1.75,2.67706 1.794068,0.66194 3.207489,2.20945 3.234687,3.54156 0.03013,1.47568 -7.035755,0.78049 -7.623061,-0.75 -0.728742,-1.89907 -2.319123,-1.92044 -3.751383,-0.0504 -0.931446,1.21614 -3.195236,1.30922 -14.057001,0.57795 -10.274286,-0.69171 -13.164169,-0.60202 -14,0.43452 -1.055494,1.30895 -4.013813,2.21175 -10.553242,3.22056 -3.755776,0.57939 -8,3.78946 -8,6.05071 0,0.76159 0.45,1.10659 1,0.76667 1.347785,-0.83298 1.259406,0.11176 -0.234188,2.50339 -1.099344,1.76033 -0.689627,2.468 3.75,6.47714 6.405894,5.78474 14.654216,10.84245 20.984188,12.86711 6.051863,1.9357 21.046022,4.80245 28.25,5.40115 2.8875,0.23997 5.25,0.59037 5.25,0.77866 C 96,199.41228 93.721677,203 92.524751,203 91.59565,203 91,203.90821 91,205.32485 c 0,1.27866 -1.147994,5.66616 -2.551098,9.75 -1.447641,4.21346 -2.331364,8.57552 -2.043091,10.0847 0.345874,1.81073 0.02102,2.84642 -1.017853,3.24507 -0.963682,0.3698 -1.30526,1.28058 -0.927108,2.47203 0.370075,1.166 0.04413,2.09933 -0.853426,2.44375 -0.898148,0.34466 -1.246537,1.34363 -0.91317,2.61843 C 83.109625,237.52721 82.761289,238 81.175648,238 78.817807,238 77.5,239.61336 77.5,242.5 c 0,1.15642 -0.571638,1.87975 -1.35526,1.71491 -2.106448,-0.4431 -4.252991,1.86866 -3.611581,3.88956 0.435905,1.37342 -0.235722,2.16238 -2.727422,3.20392 -3.962248,1.65622 -6.226774,4.15202 -5.495758,6.05702 C 64.963721,259.06903 63.181298,261 60.954988,261 59.156441,261 56,264.01638 56,265.73512 c 0,0.61136 0.933034,0.83365 2.156372,0.51374 1.424519,-0.37252 1.924781,-0.18919 1.474,0.54019 -0.471052,0.76218 -9.810015,1.1279 -30.156372,1.18095 L 0,268.04684 0,134.02342 z m 138,51.03011 c 0,-0.40288 1.125,-1.24508 2.5,-1.87158 1.375,-0.62649 2.5,-1.84913 2.5,-2.71698 0,-1.1478 -1.08539,-0.67664 -3.98197,1.72857 -4.08936,3.39563 -5.17105,5.18615 -2.51803,4.16809 0.825,-0.31659 1.5,-0.90523 1.5,-1.3081 z M 34,173.5 c 0,-0.825 -0.45,-1.5 -1,-1.5 -0.55,0 -1,0.675 -1,1.5 0,0.825 0.45,1.5 1,1.5 0.55,0 1,-0.675 1,-1.5 z m 119.02006,-2.02417 c 0.69572,-0.83829 0.98669,-1.80241 0.64661,-2.1425 -0.72629,-0.72629 -3.66667,1.51036 -3.66667,2.78911 0,1.37745 1.62985,1.02849 3.02006,-0.64661 z M 33.979764,77.39142 C 36.190894,76.506701 38,75.381701 38,74.89142 c 0,-1.270345 -0.482409,-1.146048 -4.719584,1.216042 -6.134253,3.419652 -5.866563,3.911115 0.699348,1.283958 z M 154,63.122445 c 0,-1.278754 -2.94038,-3.515401 -3.66667,-2.789112 C 149.60704,61.059623 151.84369,64 153.12244,64 153.6051,64 154,63.6051 154,63.122445 z M 16.418213,4.3930112 C 18.60639,3.5533288 18.404371,2 16.106989,2 15.065833,2 13.954956,2.675 13.638374,3.5 13.023807,5.1015358 13.866426,5.3722236 16.418213,4.3930112 z M 105.3997,196.26696 c 0.8283,-0.82829 8.6003,-3.25664 8.6003,-2.68714 0,0.20285 -1.32765,1.05538 -2.95034,1.8945 -3.01596,1.55961 -6.97192,2.1146 -5.64996,0.79264 z m 4.857,-26.06435 c -7.0259,-2.86889 -7.87635,-4.03816 -1.23206,-1.69392 4.82106,1.70097 7.25006,0.73215 4.99048,-1.99047 -2.25057,-2.71177 -0.25732,-2.85133 2.42427,-0.16974 2.66423,2.66423 3.48319,6.74306 1.31061,6.52749 -0.6875,-0.0682 -4.05949,-1.27123 -7.4933,-2.67336 z M 43.409864,167.14584 C 43.799358,166.51563 45.126476,166 46.359017,166 c 1.232541,0 2.741608,-0.50062 3.353483,-1.1125 0.611875,-0.61188 1.714375,-0.89051 2.45,-0.6192 1.380469,0.50915 -1.917722,2.13019 -6.855756,3.36956 -1.82833,0.45888 -2.393902,0.31218 -1.89688,-0.49202 z m 56.860966,-0.75001 c 0.3323,-0.33229 1.1948,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.644788,-0.19293 -1.3125,-0.52522 z m -33.999997,-3 c 0.332292,-0.33229 1.194792,-0.36781 1.916667,-0.0789 0.797733,0.31922 0.560776,0.55618 -0.604167,0.60416 -1.054166,0.0434 -1.644791,-0.19293 -1.3125,-0.52522 z m 41.700547,-2.04252 C 106.20829,160.87501 103.50619,157 104.93576,157 c 0.52399,0 2.21531,1.11078 3.75848,2.4684 2.7024,2.37746 2.55072,2.77298 -0.72286,1.88491 z m -10.870276,-6.39304 c -2.419393,-1.0977 -4.175986,-2.21872 -3.90354,-2.49117 0.664391,-0.66439 7.500796,2.23382 8.293076,3.51575 0.81888,1.32499 0.75749,1.31066 -4.389536,-1.02458 z m -45.830271,-8.56444 c 0.332292,-0.33229 1.194792,-0.36781 1.916667,-0.0789 0.797733,0.31922 0.560776,0.55618 -0.604167,0.60416 -1.054166,0.0434 -1.644791,-0.19293 -1.3125,-0.52522 z M 77.75,126.93191 c -4.608373,-2.43284 -4.787085,-3.08973 -0.506602,-1.8621 C 81.239617,126.21591 81,126.22927 81,124.86024 c 0,-0.62686 -0.754412,-1.69139 -1.67647,-2.36562 -1.140013,-0.8336 -1.815356,-3.14594 -2.110499,-7.22625 -0.685816,-9.48131 3.142412,-15.559883 8.690472,-13.799 5.579569,1.77089 6.878623,16.94624 1.907373,22.28165 -1.408746,1.51194 -2.354999,3.31148 -2.102783,3.99898 0.697674,1.90175 -3.653345,1.45447 -7.958093,-0.81809 z M 63.328708,114.94011 C 63.93908,113.32305 64.741673,112 65.112249,112 c 0.653881,0 2.210175,3.17868 1.66129,3.39313 -0.150447,0.0588 -1.236777,0.64242 -2.414068,1.29698 -2.056033,1.14313 -2.096722,1.07405 -1.030763,-1.75 z m 87.122782,-8.09294 c -1.12862,-3.55599 7.84062,-10.525967 17.15098,-13.327973 C 170.02111,92.791293 172,92.406734 172,92.66462 c 0,1.519979 -10.11463,11.79855 -13.64807,13.86928 -5.17013,3.02991 -7.01499,3.10306 -7.90044,0.31327 z M 160.5,103.09445 C 163.0627,101.64591 165.36482,97 163.51989,97 c -1.83998,0 -6.3181,3.21015 -8.3741,6.003 l -2.35422,3.19793 2.35422,-0.70538 C 156.4406,105.1076 158.85,104.0271 160.5,103.09445 z M 64.430902,92.888197 C 64.052979,92.276705 64.363921,91.383595 65.121885,90.903509 67.404139,89.457953 68.132792,89.883359 67,92 c -1.229476,2.297297 -1.615702,2.430824 -2.569098,0.888197 z M 52.984923,86.765738 C 49.80475,82.464323 49.081824,73.737171 51.485998,68.670749 56.084393,58.980352 64.714787,65.441421 63.813634,77.899726 63.373745,83.981135 59.984537,90 57,90 56.106864,90 54.30008,88.544582 52.984923,86.765738 z M 84.207162,76.039889 c 0.883127,-1.414111 1.438333,-1.623028 1.993161,-0.75 C 87.452414,77.260068 87.12238,78 84.991526,78 83.247003,78 83.143923,77.742405 84.207162,76.039889 z M 48.5,43.502303 c 1.1,-0.78875 2.52398,-1.881197 3.164399,-2.427661 C 53.543296,39.4714 58,38.639197 58,39.891592 58,40.501216 57.420149,41 56.711442,41 56.002735,41 53.657586,41.9 51.5,43 c -4.569276,2.329549 -5.846551,2.543409 -3,0.502303 z M 179,7 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z"
+ id="path3943" />
+ <path
+ style="fill:#000000"
+ d="M 0,134.02342 0,0 l 109,0 109,0 0,134 0,134 -17.94098,0 c -12.48267,0 -18.15807,-0.35124 -18.65451,-1.15451 -0.42049,-0.68036 -0.27644,-0.88437 0.35074,-0.49675 0.58535,0.36176 1.70708,0.41108 2.49273,0.10959 1.16794,-0.44818 0.81667,-2.37464 -1.92602,-10.56286 -1.84497,-5.50809 -3.77569,-10.55038 -4.29048,-11.20509 -8.3407,-10.60761 -21.51663,-24.25087 -25.18698,-26.08032 -1.28948,-0.64272 -2.91082,-2.34966 -3.60299,-3.79318 -0.69216,-1.44353 -2.82966,-4.00411 -4.75,-5.69019 C 142.57118,207.44062 141,205.68155 141,205.21764 c 0,-0.4639 -1.40168,-2.16515 -3.11484,-3.78055 -1.71316,-1.6154 -3.94717,-4.84959 -4.96446,-7.18709 -1.53437,-3.52562 -2.31972,-4.25 -4.60767,-4.25 l -2.75804,0 2.18293,-1.52898 c 1.36448,-0.95572 3.13783,-1.28932 4.72979,-0.88977 3.26534,0.81955 5.56622,-0.71005 14.78257,-9.82723 7.41897,-7.33914 12.89157,-14.36746 16.16014,-20.75402 2.55828,-4.99872 7.51455,-19.7417 6.85758,-20.39866 -0.30415,-0.30416 0.0115,-1.23315 0.70137,-2.06444 0.68991,-0.83129 0.97127,-2.2492 0.62525,-3.15091 -0.34602,-0.90172 -0.11534,-2.25857 0.51263,-3.01522 0.62797,-0.75665 0.88004,-2.68434 0.56016,-4.28374 -0.53858,-2.69287 -0.0991,-3.22238 5.94016,-7.15711 5.12295,-3.33774 7.09772,-5.37253 9.2071,-9.48694 1.63789,-3.19478 4.63562,-6.78204 7.68533,-9.196734 2.75,-2.17739 6.125,-5.82702 7.5,-8.110287 1.375,-2.283268 4.23358,-6.504427 6.35239,-9.380355 3.74613,-5.084736 3.83373,-5.393859 3.17599,-11.207521 C 211.73626,62.546617 211.48334,62 209.036,62 c -1.13044,0 -2.86815,1.744249 -4.48313,4.5 -1.45045,2.475 -3.33628,4.5 -4.19073,4.5 -0.85446,0 -2.86972,0.777479 -4.47837,1.72773 -2.39545,1.415026 -3.28063,1.505522 -4.89072,0.5 C 189.9118,72.552479 187.88158,72 186.48145,72 c -1.40013,0 -4.16119,-0.675 -6.13569,-1.5 -5.20572,-2.175089 -9.41114,-1.96599 -10.05601,0.5 -0.56486,2.160024 -1.79933,2.602527 -2.78975,1 -0.33992,-0.55 -2.10277,-1 -3.91744,-1 -2.88785,0 -3.75251,-0.682432 -6.93197,-5.471042 -1.99791,-3.009073 -4.70173,-6.171585 -6.00849,-7.027805 -1.30675,-0.85622 -4.20783,-3.729304 -6.44684,-6.38463 l -4.07091,-4.827866 3.55317,-5.276152 c 1.95424,-2.901883 5.07626,-6.613448 6.93782,-8.24792 3.70128,-3.249767 4.26511,-5.212749 1.77204,-6.169429 -2.44865,-0.939633 0.35222,-3.896515 3.02808,-3.196761 1.13035,0.295592 4.53678,-0.303951 7.56986,-1.332317 3.03307,-1.028366 8.37577,-2.674889 11.87267,-3.65894 C 183.29336,17.033363 186,14.836022 186,10.361678 186,6.1812607 184.47638,3 182.47424,3 c -0.80047,0 -6.29714,1.8115143 -12.21482,4.0255872 -5.91768,2.214073 -12.70484,4.7388638 -15.08257,5.6106458 -2.37774,0.871782 -4.62774,2.369098 -5,3.327368 -0.37227,0.95827 -3.48396,4.070396 -6.91486,6.915835 -3.43091,2.84544 -6.89541,6.444785 -7.69889,7.998545 -0.80348,1.553761 -2.60888,3.577218 -4.01199,4.496572 C 130.148,36.293907 129,37.710732 129,38.523053 c 0,2.021971 -2.65202,1.818643 -8,-0.613353 -2.475,-1.125507 -5.85,-2.1706 -7.5,-2.322428 -1.65,-0.151829 -3.86329,-0.648304 -4.91842,-1.103278 -1.26546,-0.545674 -2.90975,-0.258279 -4.83104,0.84439 -3.70119,2.124195 -5.82779,2.106915 -9.64653,-0.07838 -2.566063,-1.468446 -3.390086,-1.54344 -5.121717,-0.466123 -1.135006,0.706133 -2.467153,1.034497 -2.960327,0.729699 -0.493173,-0.304798 -3.635395,0.393611 -6.982716,1.552021 -5.95522,2.060928 -6.158761,2.066738 -9.469444,0.270301 C 67.708932,36.326154 63.42052,31.989191 60.040002,27.698201 56.659484,23.407212 53.130044,19.61534 52.196802,19.271818 51.263561,18.928296 49.107524,17.601605 47.405609,16.323616 45.703694,15.045627 43.988722,14 43.594559,14 43.200397,14 37.448126,11.275758 30.811734,7.9461297 16.361269,0.69600282 13.398516,0.43834092 11.393932,6.2574207 c -1.172308,3.4030737 -1.108865,3.9302493 0.672726,5.5900543 1.081906,1.007948 2.972005,2.283112 4.200221,2.833697 3.044921,1.364978 19.439928,9.488881 22.64179,11.219251 3.115885,1.683905 8.947392,6.655371 11.281275,9.617493 1.645093,2.087921 1.559138,2.242502 -3.238709,5.824427 -4.749874,3.54611 -8.663479,9.445726 -11.534125,17.387267 -0.913972,2.52847 -0.890563,3.608226 0.107824,4.973603 1.038662,1.420454 1.024323,2.102225 -0.07729,3.674996 -0.914719,1.305943 -1.051028,2.494362 -0.4211,3.671392 1.024724,1.914714 0.411694,2.590749 -4.526546,4.99177 -5.316475,2.584922 -12.846014,11.153661 -14.823216,16.869062 -1.661131,4.801751 -1.683356,5.424824 -0.25,7.008665 1.975819,2.183252 1.971051,2.983822 -0.03094,5.195992 -1.473871,1.62861 -1.460851,2.16292 0.160314,6.57874 0.97046,2.6434 3.410344,6.83117 5.421965,9.30617 2.011621,2.475 3.950356,5.2875 4.308301,6.25 0.884684,2.37888 3.779136,2.21531 4.423829,-0.25 0.287656,-1.1 0.968673,-2 1.513369,-2 0.558922,0 0.667431,0.76236 0.249081,1.75 -0.407703,0.9625 -1.067742,3.55 -1.466754,5.75 -0.399012,2.2 -1.056682,5.21485 -1.461489,6.69968 -0.584081,2.14239 -0.217442,3.21825 1.776129,5.21182 1.656532,1.65653 2.33061,3.20632 1.979146,4.55032 C 31.887384,150.53865 32.24585,151 33.883369,151 35.333333,151 36,150.37007 36,149 c 0,-2.96566 6.532945,-2.89402 7.310712,0.0802 0.522223,1.99699 1.048391,2.06347 13.158165,1.6627 7.366709,-0.24381 12.858214,-0.0226 13.20079,0.53167 0.32263,0.52202 2.66644,0.68793 5.208467,0.36867 3.261651,-0.40963 5.19314,-0.14824 6.562996,0.88817 1.067621,0.80775 3.092621,1.47087 4.5,1.4736 1.407378,0.003 3.90887,1.11155 5.55887,2.46403 l 3,2.45907 -3.25,0.036 C 89.011794,158.9888 88,158.53302 88,157.5 c 0,-2.01469 -3.667373,-1.91679 -4.811948,0.12845 -0.817641,1.46105 -2.236282,1.51912 -13.79969,0.56489 C 59.252309,157.3569 56.28645,157.39641 55.5,158.37836 c -1.14104,1.4247 -10.300762,4.21505 -12.37706,3.77047 -0.757384,-0.16217 -2.894884,1.17627 -4.75,2.97432 C 35.099895,168.29551 33.99344,171 35.968615,171 c 0.532739,0 0.690692,0.72426 0.351008,1.60946 -0.567652,1.47928 -0.69046,1.47928 -1.518305,0 -1.390405,-2.48452 -3.999319,-2.02286 -3.619854,0.64054 0.24811,1.74144 0.918705,2.21062 2.966871,2.0758 1.86624,-0.12286 4.518916,1.36202 8.998985,5.03733 8.313834,6.8204 11.997665,8.9519 19.85268,11.48697 6.066264,1.95777 19.791151,4.82597 28.131859,5.87894 2.910491,0.36743 3.53765,0.81875 3.157546,2.27227 -0.260872,0.99758 -1.332709,2.03826 -2.381859,2.31262 C 90.570908,202.66347 90,203.70175 90,205.78311 c 0,1.63369 -2.050446,8.95658 -4.556546,16.2731 -3.915064,11.42996 -5.282066,14.15738 -9.710014,19.37328 -8.452936,9.95711 -13.68184,15.85788 -17.450282,19.69246 -3.729019,3.79446 -3.785187,6.0836 -0.12579,5.12665 1.42372,-0.37231 1.923741,-0.18885 1.473004,0.54045 -0.471052,0.76218 -9.810015,1.1279 -30.156372,1.18095 L 0,268.04684 0,134.02342 z m 65.447214,19.89117 c -0.321976,-0.52097 -1.011657,-0.68378 -1.532624,-0.3618 -0.520968,0.32197 -0.683779,1.01165 -0.361804,1.53262 0.321976,0.52097 1.011657,0.68378 1.532624,0.3618 0.520968,-0.32197 0.683779,-1.01165 0.361804,-1.53262 z m 49.095496,17.15451 c -0.31644,-0.512 -0.0873,-1.23252 0.50915,-1.60115 0.59647,-0.36864 0.82792,-1.41223 0.51435,-2.3191 -0.34339,-0.99308 0.22607,-0.70993 1.43182,0.71193 1.10109,1.29844 2.00197,2.76094 2.00197,3.25 0,1.18074 -3.72332,1.14592 -4.45729,-0.0417 z M 81,127.60699 c 0,-0.21616 0.675,-0.65203 1.5,-0.96862 0.825,-0.31658 1.5,-0.13972 1.5,0.39301 C 84,127.56412 83.325,128 82.5,128 81.675,128 81,127.82314 81,127.60699 z m -43.614935,-1.42102 c 0.368803,-0.59674 -0.675224,-2.07995 -2.320061,-3.29603 -2.187825,-1.61753 -3.158093,-3.3279 -3.614525,-6.3716 -0.845124,-5.63569 1.034759,-12.13495 4.088785,-14.13602 2.259962,-1.48079 2.660665,-1.48134 4.911121,-0.007 6.131775,4.0177 5.771593,17.86624 -0.586945,22.56731 -1.73191,1.28046 -2.847179,1.83987 -2.478375,1.24313 z m 43.50312,-3.47193 C 77.906728,120.18665 76.72807,115.55275 77.63078,109.90751 78.24435,106.07046 81.869927,101 84,101 c 2.10137,0 5.752009,5.04768 6.348508,8.77799 0.829513,5.18749 -0.223054,10.71023 -2.50885,13.16374 -2.411383,2.58832 -3.678494,2.54681 -6.951473,-0.22769 z m -16.34548,-7.64494 c -0.316431,-0.512 -0.117988,-1.21356 0.440983,-1.55902 C 65.54266,113.16462 66,113.58352 66,114.44098 c 0,1.75653 -0.600055,2.01516 -1.457295,0.62812 z M 154.5,107 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m -4.5,-1.46246 c 0,-0.74312 6.68444,-6.71472 8.88287,-7.93559 0.88942,-0.493928 0.49213,0.337567 -0.88287,1.847767 -2.772,3.044563 -8,7.022953 -8,6.087823 z m 11.92061,-2.89788 c 1.33134,-1.44748 2.6139,-2.43849 2.85014,-2.20225 0.71756,0.71756 -0.75575,2.48611 -3.07644,3.69293 -2.09205,1.08792 -2.08151,1.01845 0.2263,-1.49068 z M 165,98 c 0,-0.55 -0.975,-1 -2.16667,-1 -3.09981,0 -1.76234,-0.916144 3.76675,-2.580157 l 4.79692,-1.44366 -2.88559,3.011908 C 165.35417,99.283539 165,99.486465 165,98 z M 65,92.059017 C 65,91.476558 65.45,91 66,91 c 0.55,0 1,0.198442 1,0.440983 0,0.242541 -0.45,0.719098 -1,1.059017 -0.55,0.339919 -1,0.141476 -1,-0.440983 z M 54.036428,85.88927 c -3.216506,-2.685258 -3.411413,-3.206278 -3.411164,-9.118628 4.76e-4,-11.325294 6.144689,-16.349262 10.976406,-8.97513 2.098123,3.20214 2.439253,12.890988 0.576425,16.371715 -2.394132,4.473476 -4.350292,4.887223 -8.141667,1.722043 z M 158,76 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z M 75,43 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z"
+ id="path3941" />
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien1.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien1.svg
new file mode 100755
index 0000000..2bcf866
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien1.svg
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="218"
+ height="430"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="alien1.svg">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <inkscape:perspective
+ id="perspective2899"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.8"
+ inkscape:cx="130.62808"
+ inkscape:cy="286.18932"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer2"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:snap-bbox="false"
+ inkscape:snap-global="false" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-622.36218)">
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path2909"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path2915"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path2917"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3707"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3711"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3715"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3776"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3778"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3788"
+ transform="translate(0,784.36218)" />
+ <g
+ id="g3794"
+ transform="translate(6,10)">
+ <path
+ id="path2905"
+ d="m 53.60865,1035.3693 c 19.78288,-22.2017 22.20694,-25.4265 25.4678,-33.881 3.44722,-8.9377 6.40012,-18.24962 7.52938,-23.74392 0.82455,-4.01172 -0.36261,-5.08744 -5.63913,-5.10977 -1.99045,-0.008 -7.61545,-0.71148 -12.5,-1.56235 -16.50806,-2.87565 -23.91813,-6.30919 -33.99171,-15.75046 -6.08941,-5.70718 -7.43503,-7.50597 -7.19032,-9.61182 0.34346,-2.95569 -1.50714,-2.82651 22.80104,-1.59153 11.8285,0.60095 15.97106,0.42806 22.48438,-0.93836 4.39141,-0.92127 8.66641,-2.28625 9.5,-3.0333 0.83359,-0.74704 3.31562,-1.68728 5.51562,-2.08942 2.2,-0.40213 5.575,-1.60777 7.5,-2.6792 3.44034,-1.91485 3.44887,-1.93539 0.5,-1.2054 -5.17273,1.28051 -26.63042,1.59889 -36.0133,0.53435 -9.20812,-1.04471 -19.63226,-3.39275 -22.72313,-5.11837 -0.95503,-0.5332 -2.32888,-0.96945 -3.05299,-0.96945 -1.43857,0 -9.42912,-5.54027 -11.50725,-7.97859 -0.95343,-1.11868 -1.14843,-3.94422 -0.73666,-10.67412 l 0.56002,-9.15271 -4.54056,-5.31941 c -9.98832,-11.70162 -9.97623,-27.55255 0.0295,-38.68134 2.60206,-2.89412 6.36378,-5.77306 8.93031,-6.83458 l 4.43446,-1.83411 -0.57302,-6.13624 c -1.06496,-11.40449 5.13162,-23.48816 14.51299,-28.30109 l 3.58712,-1.84031 -5.95375,-5.92765 c -4.93512,-4.9135 -8.52008,-7.18312 -20.95375,-13.26571 -8.25,-4.03593 -15.17459,-7.48627 -15.38799,-7.66742 -0.21339,-0.18115 0.18259,-2.36727 0.87997,-4.85804 1.70691,-6.09651 3.20226,-5.96925 18.29995,1.55747 19.96216,9.95182 24.45018,13.11377 31.13538,21.93586 4.86767,6.42359 6.566,7.95536 9.5,8.56828 1.96498,0.41049 4.02269,0.60686 4.57269,0.43639 17.13317,-5.31045 33.409,-5.14223 47.77024,0.49372 4.94708,1.94144 5.21645,1.90161 6.52227,-0.96436 0.61245,-1.34418 5.43513,-7.16668 10.71706,-12.93889 7.18218,-7.84883 10.66081,-10.87865 13.79697,-12.01685 2.3064,-0.83706 9.11158,-3.33956 15.12261,-5.56111 6.01103,-2.22156 11.68966,-4.03919 12.61916,-4.03919 1.11859,0 1.89014,1.09888 2.28193,3.25 0.32555,1.7875 0.8733,4.21044 1.21722,5.38431 0.70713,2.41364 -0.93804,3.18343 -16.9864,7.94807 -8.24402,2.44759 -9.41386,3.13117 -15.04786,8.79297 -3.35991,3.37649 -7.99751,8.92014 -10.30579,12.31923 l -4.19687,6.18016 4.59822,3.7679 c 3.92224,3.21397 12.53592,13.3479 15.89124,18.69593 0.86818,1.38377 2.03676,1.46094 8.86473,0.5854 6.40489,-0.8213 8.72511,-0.72392 12.5,0.5246 8.01058,2.64945 13.40229,2.97743 17.21675,1.04728 5.01589,-2.53808 7.91852,-5.53295 7.91852,-8.17016 0,-1.91743 0.52663,-2.32569 3,-2.32569 l 3,0 0,7.36937 c 0,6.99889 -0.19005,7.61474 -3.78039,12.25 -2.07921,2.68435 -4.3555,6.00563 -5.05843,7.38063 -1.82398,3.56792 -4.05346,6.02517 -8.95417,9.86899 -2.36114,1.85194 -5.40785,5.56725 -6.77047,8.25624 -1.86654,3.68345 -4.04585,5.93033 -8.8376,9.11161 l -6.36013,4.22255 -1.16111,8.29999 c -3.24143,23.17077 -14.49635,42.93763 -31.7551,55.771 -4.30243,3.19923 -8.0341,5.98766 -8.29259,6.19652 -1.61876,1.30794 6.41126,11.58405 19.25766,24.64423 26.293,26.73057 27.51833,28.27367 30.82393,38.81727 3.56149,11.3598 3.62201,12.8116 0.53407,12.8116 -2.0739,0 -2.62572,-0.9231 -4.63288,-7.75 -1.25321,-4.2625 -3.12892,-9.4395 -4.16826,-11.5044 -1.03933,-2.065 -8.08103,-9.94 -15.6482,-17.5 -17.43517,-17.4188 -29.05724,-30.54815 -30.36702,-34.30539 -0.88138,-2.52833 -1.38534,-2.84102 -3.67537,-2.28044 -1.45967,0.3573 -2.80394,1.03003 -2.98727,1.49494 -0.18334,0.46491 -1.18057,0.84529 -2.21608,0.84529 -1.0355,0 -3.3605,0.6395 -5.16666,1.42112 -1.80616,0.78162 -5.98393,1.79412 -9.28393,2.25 l -6,0.82888 -0.64806,5 c -1.05452,8.13597 -10.19844,32.3753 -13.55944,35.9443 -1.06473,1.1306 -3.96423,4.5663 -6.44331,7.6348 -2.47909,3.0685 -5.37183,6.4995 -6.42831,7.6245 -1.05648,1.1249 -3.66664,3.9018 -5.80036,6.1708 -3.09032,3.2864 -4.58088,4.1256 -7.32754,4.1256 l -3.44807,0 4.67803,-5.25 z m 5.47706,-1.25 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 8,-9 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 6,-7 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 85,-12.8776 c 0,-0.2076 -0.7875,-0.9951 -1.75,-1.75 -1.58606,-1.2438 -1.62143,-1.2085 -0.37756,0.3776 1.30637,1.6657 2.12756,2.1955 2.12756,1.3724 z m -13,-11.9674 c 0,-0.1898 -1.0125,-1.2023 -2.25,-2.25 l -2.25,-1.905 1.90499,2.25 c 1.79022,2.1144 2.59501,2.7052 2.59501,1.905 z m -8,-9.00001 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11444 2.59501,2.70524 2.59501,1.90499 z m -41,-13.2644 c 0,-0.21482 -2.1375,-0.3837 -4.75,-0.37528 -2.69011,0.009 -4.21371,0.35593 -3.51336,0.80076 1.18245,0.75103 8.26336,0.38643 8.26336,-0.42548 z m -15.15913,-0.88305 c -0.27085,-0.27086 -4.50835,-1.18259 -9.41666,-2.02608 -16.13633,-2.77299 -23.51094,-5.97517 -33.27596,-14.44895 -7.06554,-6.13127 -6.84736,-7.42208 1.10175,-6.51825 3.4375,0.39085 6.025,0.48259 5.75,0.20387 -0.99658,-1.01006 -14.48194,-2.63618 -15.27608,-1.84205 -0.44842,0.44842 2.5534,3.97257 6.67071,7.83144 9.85626,9.23759 17.5018,12.85148 33.17531,15.68127 8.58267,1.54956 12.04547,1.89328 11.27093,1.11875 z m 23.7264,-0.47481 c 0.532,-0.532 2.7595,-1.3868 4.95,-1.89955 2.1905,-0.51275 3.08273,-0.97137 1.98273,-1.01914 -1.1,-0.0478 -4.7,0.76597 -8,1.80833 -4.87947,1.54126 -5.4304,1.91223 -2.95,1.98641 1.6775,0.0502 3.48527,-0.34405 4.01727,-0.87605 z m -1.06727,-3.56001 c 3.85,-1.06802 7.225,-2.19571 7.5,-2.50598 0.275,-0.31026 2.3,-1.09477 4.5,-1.74336 5.05158,-1.48926 15.57308,-8.30539 21.71998,-14.07082 10.15582,-9.52554 18.78406,-25.08183 22.17104,-39.97322 2.25857,-9.93017 2.17044,-11.34285 -0.64102,-10.27621 -1.2375,0.4695 -5.625,1.02086 -9.75,1.22525 -7.05688,0.34966 -7.51817,0.24412 -7.80748,-1.7863 -0.33071,-2.32087 0.30249,-2.55846 10.30748,-3.8677 11.1663,-1.4612 23.27502,-8.62225 26.61935,-15.74257 1.23176,-2.6225 3.84631,-5.98973 5.81011,-7.48272 4.73441,-3.59937 9.07054,-8.06924 9.07054,-9.35029 0,-1.14449 5.05979,-8.20389 6.26146,-8.73595 0.4188,-0.18544 1.19818,-1.15318 1.73195,-2.15053 0.8951,-1.67251 0.64174,-1.65381 -3.26146,0.24076 -7.22492,3.5069 -10.3032,3.77646 -18.61575,1.63013 -9.07215,-2.34246 -19.00256,-2.1397 -21.58295,0.44068 -0.92186,0.92186 -2.14171,1.67611 -2.71077,1.67611 -2.54552,0 -8.99433,6.52871 -10.95829,11.09406 -1.16076,2.69827 -2.46826,4.90594 -2.90555,4.90594 -1.95933,0 -3.95864,-1.33678 -3.95864,-2.64683 0,-3.08568 4.35596,-10.05283 8.7413,-13.98128 l 4.60821,-4.12811 -4.56124,-6.37189 c -5.99722,-8.37789 -13.41368,-15.23903 -16.69909,-15.44873 -3.96961,-0.25337 -4.08918,-0.31285 -4.08918,-2.03394 0,-1.26833 -0.37392,-1.14902 -1.75876,0.56119 -3.16363,3.90691 -6.71424,0.67043 -4.27159,-3.89369 0.85843,-1.60399 0.0269,-2.12345 -7.25,-4.52893 -6.21814,-2.0555 -10.28943,-2.73355 -16.71965,-2.78455 -7.5672,-0.06 -19,1.69411 -19,2.91514 0,0.25239 1.31647,2.12001 2.92548,4.15026 4.36394,5.50639 6.47105,13.04213 5.76399,20.6139 l -0.58664,6.28221 5.37473,1.20281 c 21.33616,4.77483 28.69937,31.92058 12.95469,47.75979 -10.80462,10.86949 -26.4913,11.06535 -37.48583,0.46803 l -4.92782,-4.74978 -3.2593,3.39483 c -5.79484,6.0358 -10.13838,7.70973 -20.0093,7.71121 -8.60158,10e-4 -8.75,0.0426 -8.75,2.43384 0,1.33789 -0.52005,3.87072 -1.15568,5.62851 -1.08586,3.00291 -0.94993,3.38302 2.25,6.29169 1.87313,1.70263 3.98611,3.10888 4.69552,3.12501 0.70941,0.0161 2.95941,0.87562 5,1.91 5.35714,2.71554 26.10725,6.12131 37.21074,6.10748 6.7425,-0.008 12.40095,-0.73394 19.49709,-2.5 12.81724,-3.18989 15.50356,-3.23117 15.49859,-0.23817 -0.005,3.2606 -3.59424,8.64665 -6.49672,9.75017 -1.37475,0.52268 -2.49954,1.41147 -2.49954,1.97508 0,0.56361 -0.48214,1.02475 -1.07143,1.02475 -0.58928,0 -1.74575,0.67432 -2.56993,1.4985 -0.82417,0.82417 -2.70453,1.76639 -4.17856,2.09382 -1.47404,0.32743 -4.04917,1.20489 -5.7225,1.94992 -7.22305,3.21595 -18.24045,4.55548 -34.98967,4.25415 l -16.47466,-0.29639 3.75338,3.2447 c 8.53728,7.38027 17.41711,11.11298 32.67758,13.73628 4.90831,0.84375 9.17851,1.7884 9.48934,2.09923 1.09734,1.09735 13.67539,-0.1903 20.58645,-2.10749 z m 40.5,-82.47272 c 0,-1.1 -0.45,-2 -1,-2 -0.55,0 -0.99978,-1.0125 -0.99951,-2.25 4.9e-4,-2.23828 6.86797,-9.01585 11.80351,-11.64897 3.22732,-1.72179 11.25861,-4.07728 13.946,-4.09021 3.59163,-0.0173 2.91267,4.08892 -1.25,7.55971 -1.925,1.60504 -3.5,3.40484 -3.5,3.99955 0,1.65254 -3.95602,4.90826 -9.49204,7.81174 -6.12107,3.21032 -9.50796,3.43052 -9.50796,0.61818 z m 9,-3.36173 c 4.30061,-2.42779 8,-5.65282 8,-6.97419 0,-0.54301 1.6875,-2.48922 3.75,-4.32491 2.0625,-1.83568 3.525,-3.33309 3.25,-3.32756 -1.50707,0.0303 -10.20077,3.05406 -12.64753,4.39899 -3.66433,2.0142 -12.18544,9.58314 -10.7927,9.5867 0.58287,0.001 3.43212,-2.0223 6.33165,-4.4973 5.24143,-4.474 9.10858,-5.78543 9.10858,-3.08889 0,1.84596 -4.51449,5.57987 -9.77988,8.08889 -2.30845,1.1 -4.20234,2.32338 -4.20865,2.71862 -0.0143,0.8945 2.43529,-0.01 6.98853,-2.58035 z m -35,84.31604 c 1.09546,-0.74131 0.69092,-0.83408 -1.5,-0.34401 -3.67693,0.82247 -4.47511,1.39483 -1.91667,1.37439 1.05417,-0.008 2.59167,-0.47209 3.41667,-1.03038 z m 6.427,-2.47578 c 2.91505,-2.20537 1.48811,-2.46248 -1.927,-0.34722 -1.65,1.02199 -2.325,1.84622 -1.5,1.83162 0.825,-0.0146 2.36715,-0.68258 3.427,-1.4844 z m 7.14043,-5.58763 c 0.37335,-0.6041 -0.50159,-0.32492 -1.94431,0.62038 -1.44271,0.94531 -2.62312,1.90782 -2.62312,2.13891 0,0.72338 3.85397,-1.6049 4.56743,-2.75929 z m 3.43257,-2.3909 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 6,-5 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -65.02348,-3.06139 c 4.11208,-0.85786 8.83708,-2.16527 10.5,-2.90536 1.66291,-0.74008 4.22952,-1.6135 5.70356,-1.94093 1.47404,-0.32743 3.28207,-1.19733 4.01785,-1.93311 0.73578,-0.73578 2.00475,-1.59958 2.81993,-1.91955 1.26954,-0.49832 1.25981,-0.59309 -0.0679,-0.66071 -0.8525,-0.0434 -2.0117,0.38275 -2.57599,0.94704 -1.37761,1.37761 -13.6602,5.81918 -19.87401,7.18674 -2.75,0.60523 -10.175,1.4011 -16.5,1.7686 l -11.5,0.66819 10,0.17442 c 5.89347,0.1028 13.07026,-0.46609 17.47652,-1.38533 z m 70.52348,-3.43861 c 0.99549,-1.1 1.58498,-2 1.30998,-2 -0.275,0 -1.31449,0.9 -2.30998,2 -0.99549,1.1 -1.58498,2 -1.30998,2 0.275,0 1.31449,-0.9 2.30998,-2 z m -39.74244,-12.00913 c 1.24166,-1.81999 2.07092,-3.49572 1.84281,-3.72384 -0.22812,-0.22811 -5.13023,0.74348 -10.89357,2.15911 -8.13994,1.99938 -13.01511,2.57386 -21.84222,2.57386 -12.97438,0 -33.27435,-3.17908 -39.07474,-6.11931 -2.04059,-1.03438 -4.29059,-1.85699 -5,-1.82803 -0.70941,0.029 0.84976,1.11449 3.46483,2.41228 11.06002,5.4888 45.285,8.38592 59.24533,5.01506 3.3,-0.79682 6.7875,-1.45579 7.75,-1.46438 2.46056,-0.022 2.17728,2.43675 -0.5,4.33963 l -2.25,1.59919 2.5,-0.82725 c 1.375,-0.45498 3.5159,-2.31633 4.75756,-4.13632 z m 48.7905,-2.0838 c 0.87968,-1.70111 1.42188,-3.27046 1.2049,-3.48744 -0.21698,-0.21698 -1.14288,1.17483 -2.05756,3.09293 -2.05658,4.3127 -1.34401,4.64239 0.85266,0.39451 z m -128.0536,-7.9132 c -0.99854,-1.10337 -2.04794,-1.77372 -2.33199,-1.48967 -0.28406,0.28406 0.35068,1.1725 1.41054,1.97433 2.70408,2.04576 3.04782,1.86496 0.92145,-0.48466 z m -1.82881,-15.83491 c 0.54476,-4.29796 0.58312,-4.33487 3.86431,-3.71932 1.87409,0.35158 3.58779,0.17886 3.944,-0.3975 0.36318,-0.58764 0.011,-0.78172 -0.83176,-0.45833 -1.53986,0.5909 -6.76761,-1.7051 -10.1422,-4.4544 -1.9801,-1.6132 -1.98121,-1.60721 -0.11164,0.60221 1.66468,1.96729 1.82292,3.38868 1.33592,12 -0.43762,7.73827 -0.35047,8.83317 0.41936,5.26838 0.53449,-2.475 1.21939,-6.45347 1.52201,-8.84104 z m 135.93852,5.11187 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m 1,-4 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m -78.41667,-2.95394 c -0.72187,-0.28887 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28494 0.60416,-0.60416 z m 79.46844,-3.58592 c -0.27393,-0.67703 -0.48137,0.11903 -0.46099,1.76903 0.0204,1.65 0.2445,2.20394 0.49804,1.23097 0.25354,-0.97297 0.23687,-2.32297 -0.0371,-3 z m -124.92497,2.57604 c -0.97296,-0.25354 -2.32297,-0.23687 -3,0.0371 -0.67703,0.27393 0.11903,0.48137 1.76903,0.46099 1.65,-0.0204 2.20394,-0.2445 1.23097,-0.49804 z m 41.5128,0.0286 c -0.69092,-0.27855 -1.07389,-0.80553 -0.85104,-1.17105 0.22285,-0.36552 -1.20295,-0.75058 -3.16844,-0.85567 -1.9655,-0.1051 -4.95753,-1.20361 -6.64896,-2.44115 -2.34922,-1.71881 -2.72116,-1.81335 -1.57533,-0.40044 1.81731,2.24089 8.73947,5.51042 11.5,5.43176 1.1,-0.0313 1.4347,-0.28489 0.74377,-0.56345 z m -32.38703,-2.26255 c 2.07738,-1.0598 4.4142,-2.7473 5.19293,-3.75 1.34843,-1.73625 1.32057,-1.74235 -0.58488,-0.12808 -1.10041,0.93226 -4.01766,2.60988 -6.48277,3.72804 -2.46511,1.11817 -3.90159,2.04291 -3.19218,2.05499 0.70941,0.0121 2.98952,-0.84515 5.0669,-1.90495 z m 47.01576,0.49285 c 1.52524,-0.78874 3.40764,-2.25124 4.1831,-3.25 1.33163,-1.71509 1.29982,-1.7257 -0.57283,-0.1911 -1.09052,0.89366 -3.33277,2.33815 -4.98277,3.20996 -1.65,0.87182 -2.64015,1.60314 -2.20034,1.62516 0.43982,0.022 2.04759,-0.60529 3.57284,-1.39402 z m -3.36392,-2.43092 c 7.61004,-3.45714 13.65809,-12.5947 13.65809,-20.63499 0,-11.12314 -11.04986,-22.7 -21.66667,-22.7 -10.70226,0 -21.66666,11.57813 -21.66666,22.87946 0,4.64065 3.02363,11.97613 6.07456,14.73719 1.78745,1.61762 1.83913,1.5186 1.37172,-2.62829 -1.45227,-12.88452 7.92692,-22.30909 15.08152,-15.15449 4.84657,4.84656 5.99347,17.1236 2.14795,22.99261 -1.93035,2.94608 -0.65228,3.07608 4.99949,0.50854 z m -53.08133,-2.28112 c 3.70718,-6.27576 1.47296,-18.7986 -3.64361,-20.42254 -4.73397,-1.50251 -8.98587,3.85239 -9.06867,11.42119 -0.0712,6.50478 0.82438,8.55477 4.54657,10.40756 4.71129,2.34514 6.08999,2.10771 8.16571,-1.40621 z m 8.76107,0.52566 c 1.47857,-0.7519 4.15313,-3.11185 5.94345,-5.24433 3.16416,-3.76887 3.25672,-4.14456 3.31169,-13.44187 l 0.0566,-9.56463 -3.42512,-0.64252 c -6.57739,-1.23384 -11.12219,-3.74493 -15.41056,-8.51464 l -4.3202,-4.8051 -3.93064,1.7598 c -7.58534,3.39606 -13.58015,12.55734 -13.58015,20.75322 0,4.42188 3.08834,12.18072 5.7167,14.36206 1.23314,1.02342 1.44997,0.46906 1.44997,-3.70719 0,-9.99193 6.09864,-17.05981 12.75,-14.7763 5.96164,2.04672 9.18113,14.88436 5.77636,23.03311 -1.44844,3.46661 -1.43562,3.51518 0.75,2.84119 1.223,-0.37713 3.43338,-1.30089 4.91195,-2.0528 z m 37.28108,-0.95627 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 66.2806,0.88741 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z m -84.75,-1.68823 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 37,-1.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -83,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 41.40581,-3.29696 c 1.26469,0.48531 1.32727,0.18279 0.38844,-1.87771 -0.61552,-1.35092 -1.24526,-2.33009 -1.39942,-2.17593 -0.15416,0.15416 -1.48307,2.06857 -2.95312,4.25423 l -2.67282,3.97393 2.56468,-2.37651 c 1.43852,-1.33299 3.22665,-2.12249 4.07224,-1.79801 z m 103.59419,2.7059 c 0,-0.53273 -0.675,-0.70959 -1.5,-0.39301 -0.825,0.31659 -1.5,0.75246 -1.5,0.96862 0,0.21615 0.675,0.39301 1.5,0.39301 0.825,0 1.5,-0.43588 1.5,-0.96862 z m -59.19313,-4.55784 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z m -46.2027,-6.20271 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 48,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 45,-5 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 50,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -96,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 95,-5 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58438 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.0789,-1.91667 z m 49.01374,-4.98626 c -0.12014,-0.12014 -1.54582,0.178 -3.16817,0.66254 -1.62236,0.48454 -2.16224,0.91966 -1.19974,0.96694 0.9625,0.0473 1.76595,0.87345 1.78544,1.83595 0.0268,1.32558 0.37079,1.14405 1.41817,-0.74849 0.76051,-1.37418 1.28444,-2.5968 1.1643,-2.71694 z m 42.50618,0.44876 c -0.98762,-0.98026 -1.10248,-0.8654 -0.5598,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30789,-0.30789 6.4e-4,-1.11479 -0.68278,-1.79313 z M 65.08571,861.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -85,-2.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 38.4694,-2.07674 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 6.58891,-0.87068 c 2.30641,-2.50217 6.01686,-5.17968 8.48316,-6.12157 3.50845,-1.33988 4.61401,-2.37208 5.53737,-5.16987 3.7517,-11.36776 -3.1423,-24.22022 -15.17695,-28.29436 -4.64464,-1.57236 -5.7447,-1.61747 -9.7859,-0.40124 -14.93589,4.49504 -21.66079,20.75015 -13.81981,33.40461 l 2.18716,3.52985 0.74099,-5.89906 c 1.49666,-11.91498 8.85142,-17.25247 15.12639,-10.9775 4.48246,4.48246 5.8535,13.25622 3.22323,20.62656 -0.73605,2.0625 -1.17556,3.75 -0.9767,3.75 0.19886,0 2.20634,-2.00134 4.46106,-4.44742 z m -19.14164,3.16445 c -0.22917,-0.15563 -1.31667,-0.94313 -2.41667,-1.75 -1.85,-1.35701 -1.89707,-1.33579 -0.62755,0.28297 0.75484,0.9625 1.84234,1.75 2.41667,1.75 0.57432,0 0.85672,-0.12734 0.62755,-0.28297 z m 24.08333,-3.21703 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.94528,-0.0659 c -1.51303,-1.82309 -6.92706,-4.78561 -7.57027,-4.1424 -0.24152,0.24152 0.91037,0.99812 2.55977,1.68132 1.6494,0.68321 3.51893,1.86878 4.15451,2.6346 0.63558,0.76583 1.3806,1.39242 1.6556,1.39242 0.275,0 -0.0848,-0.70467 -0.79961,-1.56594 z m -75.94528,-0.9341 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 17,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 35.91667,-3.2579 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m -46,-1 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m 5.95162,-1.75427 c -1.01049,-2.21779 -1.20856,-2.27175 -2.75296,-0.75 -1.54948,1.52676 -1.49021,1.68325 0.86027,2.27141 1.38842,0.34743 2.62726,0.68493 2.75297,0.75 0.1257,0.0651 -0.26142,-0.95706 -0.86028,-2.27141 z m 49.04838,0.74819 c 0.22917,-0.19715 -0.55833,-0.35846 -1.75,-0.35846 -1.38524,0 -2.17763,-0.63115 -2.19707,-1.75 -0.0265,-1.52656 -0.17522,-1.49464 -1.16454,0.25 -0.62377,1.1 -1.62259,2.32475 -2.21959,2.72166 -0.59701,0.39691 0.71453,0.44572 2.91453,0.10846 2.2,-0.33726 4.1875,-0.77451 4.41667,-0.97166 z m 72.08333,-1.88414 c 0,-1.39308 -3.70207,-0.18103 -4.79566,1.57008 -1.24992,2.00144 -1.21295,2.01141 1.75946,0.47432 1.66991,-0.86354 3.0362,-1.78352 3.0362,-2.0444 z m 29.1875,0.84257 c -0.72188,-0.28888 -1.58438,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -19.9375,-2.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -84.64583,-3.06689 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 122.39583,-2.04448 c 0,-0.85783 -0.12734,-1.37218 -0.28297,-1.14302 -0.15563,0.22917 -0.89428,1.21447 -1.64144,2.18956 -1.18269,1.54348 -1.14607,1.69139 0.28297,1.14301 0.90279,-0.34643 1.64144,-1.33173 1.64144,-2.18955 z M 82.68988,837.89013 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 65.39583,1.38416 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11445 2.59501,2.70524 2.59501,1.90499 z m -66.39583,-7.38416 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 60.39583,0.35161 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z M 79.2098,826.35263 c -0.98761,-0.98026 -1.10248,-0.8654 -0.55979,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30788,-0.30789 6.3e-4,-1.11479 -0.68279,-1.79313 z m 56.87591,0.88911 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -97,-4.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 53.22334,-1.87639 c -0.26254,-1.00396 -0.54753,-1.69503 -0.63331,-1.53571 -0.0858,0.15931 -0.6787,0.98073 -1.3176,1.82537 -0.93948,1.24202 -0.81836,1.53572 0.63331,1.53572 1.24538,0 1.6488,-0.55888 1.3176,-1.82538 z M 43.08571,819.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.75848,-0.53051 c -0.94115,-1.51852 -0.96737,-2.21193 -0.10397,-2.75 0.63498,-0.39572 -0.80847,-0.71949 -3.20766,-0.71949 l -4.36218,0 3.39287,1.74065 c 1.86608,0.95735 3.67359,2.19485 4.01668,2.75 0.3431,0.55514 0.82607,1.00935 1.07327,1.00935 0.24721,0 -0.11685,-0.91373 -0.80901,-2.03051 z m 52.17485,-0.31215 c -0.23833,-0.20679 -1.78333,-0.65233 -3.43333,-0.99008 -2.73596,-0.56005 -2.80197,-0.51498 -0.75,0.51213 1.2375,0.61943 2.25,1.59747 2.25,2.17342 0,0.65288 0.44557,0.60162 1.18333,-0.13614 0.65084,-0.65084 0.98834,-1.35253 0.75,-1.55933 z m 9.94836,-7.40734 c 2.30606,-3.4375 3.82136,-6.25 3.36733,-6.25 -1.81925,0 -11.24902,12.98428 -11.24902,15.48929 0,1.26984 3.89338,-3.29416 7.88169,-9.23929 z m -84.96502,4.11454 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35466 2.91667,-1.55517 z m 2.58333,-1.36454 c -0.33991,-0.55 -0.81647,-1 -1.05901,-1 -0.24254,0 -0.44099,0.45 -0.44099,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m 6.82946,-1.58385 c -0.33428,-0.87111 -0.88789,-1.20861 -1.23025,-0.75 -0.34236,0.45862 -1.02974,1.17135 -1.52751,1.58385 -0.49776,0.4125 0.0558,0.75 1.23025,0.75 1.53743,0 1.96511,-0.44346 1.52751,-1.58385 z m 20.85804,0.90074 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28495 0.60416,-0.60417 z m 29,0 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -22.9375,-0.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m 18,0 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -8.5,-1.02705 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z M 53.3824,808.21186 c -0.98818,-1.3241 -1.94149,-2.01468 -2.11847,-1.53464 -0.36611,0.99302 1.91319,3.8465 3.11847,3.90404 0.43818,0.0209 -0.0118,-1.04531 -1,-2.3694 z m -3.29669,-3.66948 c 0,-1.50044 -5.57099,-6.92308 -7.11248,-6.92308 -0.69649,0 0.5064,1.73277 2.67307,3.8506 4.69729,4.5914 4.43941,4.41292 4.43941,3.07248 z m 92,-3.42308 c 1.29175,-1.375 2.12363,-2.5 1.84863,-2.5 -0.275,0 -1.55688,1.125 -2.84863,2.5 -1.29175,1.375 -2.12363,2.5 -1.84863,2.5 0.275,0 1.55688,-1.125 2.84863,-2.5 z m 6.04469,-1.70523 c 2.56704,-3.19434 2.82393,-3.81616 1.06867,-2.58673 -1.89119,1.32465 -5.69179,6.79196 -4.72142,6.79196 0.15033,0 1.79407,-1.89235 3.65275,-4.20523 z m -0.0447,-8.71959 c 0,-0.275 -2.25,1.71617 -5,4.42482 -2.75,2.70865 -5,5.14982 -5,5.42482 0,0.275 2.25,-1.71617 5,-4.42482 2.75,-2.70865 5,-5.14982 5,-5.42482 z m 1,3.42482 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 21.91908,-7.85167 c 2.4305,-0.72671 4.0055,-1.56089 3.5,-1.85373 -0.50549,-0.29284 -2.71908,0.27521 -4.91908,1.26232 -4.84957,2.17594 -4.44469,2.34468 1.41908,0.59141 z m 6.88779,-1.17479 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z M 17.08571,783.6193 c -1.925,-1.05389 -3.95,-1.91617 -4.5,-1.91617 -0.55,0 0.575,0.86228 2.5,1.91617 1.925,1.05389 3.95,1.91617 4.5,1.91617 0.55,0 -0.575,-0.86228 -2.5,-1.91617 z m 160,-2 c 0,-0.55 -0.7875,-0.99311 -1.75,-0.98469 -1.49555,0.0131 -1.5319,0.15626 -0.25,0.98469 1.88721,1.21961 2,1.21961 2,0 z"
+ style="fill:#000000" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path2907"
+ d="m 72.6,181.20757 c -16.765609,-3.86833 -22.376319,-6.32293 -32,-13.9995 l -2,-1.59535 13.2,-0.0317 c 17.959636,-0.043 26.293525,-1.0427 36.676385,-4.39926 12.401975,-4.00929 20.661075,-10.22837 22.672535,-17.07236 1.39926,-4.76097 -0.60247,-5.05117 -14.284918,-2.07088 C 80.913403,145.51284 69.067454,145.46531 50.6,141.85286 39.54215,139.68982 28.750784,134.8087 27.432732,131.37391 c -0.409763,-1.06782 0.94297,-9.55504 1.67366,-10.50077 0.129162,-0.16717 4.118063,-0.56369 8.864224,-0.88115 9.677258,-0.64731 12.721718,-1.79467 18.59718,-7.00868 l 3.565638,-3.16423 4.911016,4.16615 c 6.374081,5.4073 11.045891,7.19552 18.75555,7.17903 10.247136,-0.0219 18.94097,-5.4255 24.01507,-14.92636 2.33003,-4.3628 2.74898,-6.0141 3.03751,-11.972478 0.24409,-5.040832 -0.0244,-7.992693 -0.99183,-10.905433 C 106.83021,74.235948 98.683943,66.74733 89.719703,64.844988 L 85,63.8434 84.966254,55.710271 C 84.929438,46.837023 83.908403,43.511262 79.05568,36.458071 76.206234,32.316543 75.915993,32.561487 85.4,31.103895 c 9.620682,-1.478597 19.97708,-0.291557 29.26619,3.354462 4.00483,1.571915 4.0652,1.646353 4,4.932693 -0.0764,3.849526 1.76499,4.910844 4.39333,2.532225 0.84726,-0.766762 1.54048,-1.021054 1.54048,-0.565095 0,0.45596 1.6637,1.247942 3.6971,1.759959 4.38748,1.10478 11.00212,7.029509 17.23538,15.437707 l 4.03312,5.440379 -4.6828,5.026303 c -4.55714,4.891416 -8.2828,11.01514 -8.2828,13.614092 0,1.528769 2.86706,3.239468 4.42637,2.641103 0.60573,-0.232443 1.86318,-1.915954 2.79432,-3.741133 2.17353,-4.260467 7.69681,-10.272278 10.77931,-11.732734 1.32,-0.625402 3.4424,-1.697018 4.71645,-2.381368 2.96143,-1.590728 11.65807,-1.536216 19.53585,0.122452 7.69091,1.619321 10.4686,1.555228 15.93996,-0.367797 5.65346,-1.987032 5.64225,-1.987649 3.63541,0.2 -0.90817,0.99 -3.01076,3.96 -4.67241,6.6 -1.66166,2.64 -5.30895,6.908849 -8.1051,9.486333 -2.79614,2.577483 -5.99227,6.236344 -7.1025,8.130802 -4.94788,8.442912 -15.3818,14.634562 -28.34766,16.821932 -7.93582,1.33879 -10.1786,2.49921 -9.29263,4.80802 0.46879,1.22165 1.5792,1.32779 10.18353,0.97342 l 9.65736,-0.39773 -0.5479,3.65369 c -1.59381,10.62824 -7.28652,24.58268 -14.24705,34.92353 -11.30309,16.79232 -34.07569,29.48213 -55.75331,31.06798 -4.998646,0.36568 -7.935952,-0.008 -17.6,-2.23755 z m 81.50924,-82.494134 c 3.52664,-1.764307 6.56239,-3.962996 7.90749,-5.727124 1.2008,-1.574879 3.53327,-4.37647 5.18327,-6.225757 1.93865,-2.172795 3,-4.147985 3,-5.583022 0,-2.220043 -0.002,-2.220533 -4.38306,-1.705537 -8.74931,1.028309 -19.06055,6.827181 -22.74752,12.792833 l -1.71519,2.775229 1.70366,3.268542 c 2.14696,4.11903 3.52613,4.16955 11.05135,0.404836 l 0,0 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path2913"
+ d="m 160.6,87.334076 c 0,-0.534851 -1.1468,-0.981516 -2.6,-1.012667 -2.30544,-0.04942 -2.02164,-0.279224 2.50495,-2.028386 2.80772,-1.084959 5.23233,-1.845272 5.38801,-1.689584 0.15569,0.155688 -0.97154,1.499081 -2.50494,2.98532 C 161.85461,87.074997 160.6,87.86039 160.6,87.334076 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3703"
+ d="m 24.692801,119.04257 c -0.05104,-2.05401 -0.313955,-4.31089 -0.584255,-5.01528 -0.431011,-1.12319 -0.185552,-1.10664 1.99579,0.13457 1.631194,0.92818 2.07587,1.50427 1.292,1.67384 -0.657385,0.1422 -1.361474,1.0422 -1.564643,2 -0.203169,0.95779 -0.521653,2.46144 -0.707744,3.34144 -0.186091,0.88 -0.380107,-0.0805 -0.431148,-2.13457 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3709"
+ d="m 104.6,146.52914 c 0,-0.55196 -0.79531,-1.29776 -1.76736,-1.65735 -1.56978,-0.5807 -1.42649,-0.71774 1.28174,-1.2258 3.83551,-0.71955 4.4795,-0.10717 2.24118,2.13115 -1.00812,1.00812 -1.75556,1.32829 -1.75556,0.752 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3719"
+ d="m 76.851058,112.03382 c -3.393188,-2.09142 -4.25448,-3.92327 -4.233488,-9.00408 0.03274,-7.923733 4.577488,-13.887568 8.633406,-11.329161 3.986638,2.514706 5.541626,13.083911 2.747781,18.676561 -1.667169,3.3373 -3.668438,3.80115 -7.147699,1.65668 l 0,0 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3721"
+ d="m 31.011129,112.18685 c -3.337597,-1.68708 -4.784967,-4.28598 -4.794874,-8.60971 -0.01706,-7.444764 3.322321,-12.761965 7.700427,-12.261175 5.345895,0.611491 7.922362,14.073845 3.761169,19.652565 -2.071377,2.777 -3.181718,2.97991 -6.666722,1.21832 z"
+ style="fill:#00d37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3747"
+ d="M 49.694395,74.66073 C 44.47115,71.825511 44.018691,61.3525 48.893397,56.120117 c 1.243238,-1.334459 2.71535,-2.426289 3.27136,-2.426289 3.274952,0 7.59925,10.034368 6.191417,14.366947 -2.961401,9.11366 -3.406311,9.452665 -8.661779,6.599955 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3749"
+ d="m 30.863598,109.87939 c -4.598088,-3.22062 -2.443473,-16.412835 2.680623,-16.412835 3.343974,0 5.248203,11.238065 2.708365,15.983795 -1.423064,2.65902 -2.125412,2.71494 -5.388988,0.42904 l 0,0 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3751"
+ d="M 53.409091,253.22727 C 175,254.36364 176.13636,254.36364 176.13636,254.36364"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3753"
+ d="m 101.91757,251.70568 c -21.718752,-0.17272 -39.488638,-0.58449 -39.488638,-0.91506 0,-0.33057 3.818082,-4.96825 8.484628,-10.30595 4.666545,-5.33771 9.973982,-12.85892 11.794303,-16.71379 3.448266,-7.30236 8.521552,-22.38453 9.820557,-29.19514 0.752563,-3.94565 0.76643,-3.95339 12.3156,-6.87496 6.3592,-1.60867 12.35971,-3.28795 13.33446,-3.73173 1.29391,-0.58909 2.73131,0.66046 5.32536,4.62941 1.9542,2.98995 11.57847,13.87378 21.38726,24.18628 9.8088,10.3125 18.96093,20.28409 20.33807,22.15909 2.01779,2.74727 7.42703,15.23542 7.42703,17.14657 0,0.25689 -7.03125,0.34607 -15.625,0.19819 -8.59375,-0.14789 -33.39488,-0.4102 -55.11363,-0.58291 l 0,0 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3782"
+ d="m 51.774116,254.22272 c 0.816832,-1.01161 5.399709,-6.3219 10.184171,-11.80065 4.784463,-5.47875 10.255577,-12.2121 12.158031,-14.963 5.284789,-7.64167 14.376394,-33.83808 12.993969,-37.44062 -0.338967,-0.88334 -2.48378,-1.73514 -5.328004,-2.116 C 60.981864,185.11713 50.75895,182.31448 43.625018,177.44148 37.971557,173.57975 28.01174,163.28381 28.01174,161.3013 c 0,-1.83865 0.635315,-1.8844 17.079208,-1.22988 19.475363,0.77518 28.155408,-0.12388 38.075567,-3.94376 9.279191,-3.57307 15.45203,-6.36285 15.01445,-6.78568 -0.201984,-0.19518 -4.599918,0.0895 -9.773185,0.63261 -15.856397,1.66468 -37.875872,-0.52821 -50.869606,-5.06603 -3.201056,-1.11791 -7.99066,-3.68786 -10.643565,-5.71099 l -4.823463,-3.67842 0.178374,-9.45002 0.178374,-9.45001 0.5642,7.42574 c 0.582301,7.66397 1.29799,8.16822 2.459224,1.73268 0.423991,-2.34976 0.289983,-3.71287 -0.365011,-3.71287 -0.569229,0 -1.034963,-1.33664 -1.034963,-2.9703 0,-1.63367 -0.407778,-2.9703 -0.906174,-2.9703 -1.708089,0 -9.947718,-12.02652 -11.073528,-16.16286 C 8.4406212,86.620448 14.328838,72.981775 26.509135,66.520142 l 4.472902,-2.372869 0,-7.169297 c 0,-11.907876 4.934342,-21.608335 13.56406,-26.665688 2.388815,-1.399939 4.1792,-3.048653 3.978634,-3.66381 C 47.539733,23.627398 33.787529,13.942425 21.173642,7.3865059 6.6394252,-0.16748247 5.7525435,-1.0667564 8.2445952,-5.7231976 9.9048868,-8.825481 13.26451,-8.0142814 26.786199,-1.2462239 42.52818,6.6331633 49.704459,11.834699 56.658674,20.406047 c 7.066894,8.71023 9.386734,9.398438 22.022822,6.533328 12.009438,-2.723024 25.519864,-2.231151 36.616764,1.3331 4.17096,1.339683 7.95921,2.16177 8.41835,1.826861 0.45913,-0.33491 2.70455,-3.059423 4.98981,-6.054473 2.28526,-2.995049 7.42528,-8.682601 11.42226,-12.639003 7.12067,-7.0483759 7.54019,-7.2929957 20.80065,-12.12871266 7.44339,-2.71438994 14.38913,-4.93525434 15.435,-4.93525434 1.40526,0 2.17641,1.0827118 2.95451,4.1481669 0.5791,2.28149179 0.85167,4.4737776 0.60572,4.871746 -0.24596,0.3979683 -6.12349,2.612099 -13.0612,4.92029 -12.32753,4.1014041 -12.76057,4.3449071 -19.06805,10.7223141 -3.54973,3.589081 -8.19833,9.098685 -10.33023,12.243564 l -3.87618,5.717962 4.38964,4.574292 c 2.4143,2.515859 3.60993,4.300819 2.65696,3.966577 -2.15679,-0.756469 -2.25789,0.631979 -0.17206,2.363061 1.27233,1.05594 1.70648,1.059167 2.35028,0.01747 0.5549,-0.897844 2.45839,0.813688 6.40236,5.756734 3.08697,3.868951 6.15063,7.065929 6.80813,7.104394 0.6575,0.03847 4.65679,0.0099 8.8873,-0.0634 4.23053,-0.07334 11.0745,0.619228 15.20883,1.53903 6.08457,1.353687 8.24222,1.455077 11.32293,0.532074 4.78641,-1.434041 9.61096,-5.430654 10.01889,-8.299556 0.1988,-1.398101 1.12005,-2.308693 2.53968,-2.510314 2.12619,-0.301966 2.22772,-0.004 2.22772,6.538442 0,6.740641 -0.099,7.001552 -5.9449,15.662921 -3.26969,4.844452 -7.74462,10.309246 -9.94428,12.143987 -2.19966,1.834742 -5.77393,5.949037 -7.94282,9.142879 -2.34976,3.460168 -6.29513,7.465423 -9.76248,9.910673 l -5.81903,4.10369 -1.15924,7.92805 c -1.61723,11.06032 -4.40347,19.58965 -9.70377,29.70553 -5.01528,9.57187 -13.95714,20.46445 -14.03497,17.09676 -0.0428,-1.8524 -0.1273,-1.86246 -1.77762,-0.21171 -1.37485,1.3752 -1.46515,1.89852 -0.43722,2.53406 1.41537,0.87508 -1.77232,4.09197 -9.46671,9.55344 -2.27836,1.61719 -4.34463,3.44333 -4.59171,4.0581 -0.8189,2.03758 6.19452,11.05322 18.90021,24.29583 6.90108,7.19272 12.04414,13.24542 11.42903,13.45046 -0.61512,0.20504 -0.83848,1.12371 -0.49637,2.0415 0.34212,0.91778 -1.79925,-0.97306 -4.75858,-4.20188 -2.95935,-3.22881 -5.27705,-6.21281 -5.15046,-6.6311 0.12659,-0.41828 -1.76241,-2.39328 -4.19777,-4.38889 -2.43538,-1.9956 -4.20453,-3.98988 -3.93146,-4.43172 0.27308,-0.44185 -1.40227,-2.36965 -3.72301,-4.28402 -2.32073,-1.91436 -5.99559,-5.73898 -8.16635,-8.49916 -4.50513,-5.7284 -5.73975,-6.34273 -10.18478,-5.06791 -1.75731,0.50399 -3.19511,0.54209 -3.19511,0.0847 0,-1.33295 -11.17951,1.64109 -12.389579,3.29596 -0.60449,0.82669 -2.322383,1.8101 -3.817542,2.18536 -3.551652,0.89142 -4.937215,3.23379 -7.580515,12.81533 -4.406767,15.97381 -11.099683,29.94917 -15.20688,31.75323 -1.152028,0.50601 -2.096442,1.7759 -2.098696,2.82193 -0.0024,1.08338 -1.280677,2.61084 -2.970297,3.54913 -1.631409,0.90597 -2.982805,2.27784 -3.003103,3.04859 -0.05664,2.15103 -3.526894,6.90294 -4.570213,6.25813 -0.985639,-0.60915 -3.808724,1.30636 -3.808724,2.5843 0,1.92758 5.895059,2.34928 41.089109,2.93925 l 37.62376,0.63071 -39.232671,0.18757 c -21.57797,0.10316 -40.736386,0.48547 -42.574257,0.84959 -3.159411,0.62595 -3.260618,0.56176 -1.856436,-1.17724 z m 42.238485,-67.99171 c -1.942887,-0.70765 -3.471758,-0.70422 -4.950495,0.0112 -1.790743,0.86631 -1.332552,1.03319 2.81102,1.02385 4.566697,-0.0103 4.732564,-0.0905 2.139475,-1.03501 l 0,-3e-5 z m -14.020663,-0.82863 c -1.089109,-0.4866 -6.435644,-1.80129 -11.881188,-2.92155 -5.759121,-1.18476 -12.800298,-3.45953 -16.831683,-5.43774 -6.954731,-3.41271 -17.742094,-11.92119 -16.880858,-13.3147 0.253072,-0.40948 3.040932,-0.57204 6.195246,-0.36125 4.48988,0.30005 5.355073,0.14443 3.984772,-0.71671 -0.96269,-0.60499 -4.913826,-1.36519 -8.780302,-1.68935 -6.863409,-0.57539 -7.004171,-0.54119 -5.941584,1.44428 2.200044,4.11082 13.668199,13.46069 20.585236,16.78294 7.129107,3.42411 21.632479,7.0912 28.065212,7.09613 2.851296,0.002 3.114461,-0.15412 1.485149,-0.88205 z m 13.55198,-1.63782 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52001 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 8.981792,-3.22305 c 4.1272,-1.05557 9.34757,-2.85973 11.60083,-4.00925 2.25325,-1.14953 4.87457,-1.8432 5.82513,-1.54151 0.95056,0.30171 2.59602,-0.12295 3.65656,-0.94367 1.60041,-1.23851 1.63367,-1.38963 0.19559,-0.88881 -2.84772,0.99172 -1.97918,-0.17229 2.18456,-2.92772 2.15449,-1.42577 4.50534,-2.36663 5.22413,-2.09081 0.7188,0.27584 3.05637,-1.2901 5.1946,-3.47985 2.13823,-2.18975 3.51995,-3.98136 3.07047,-3.98136 -0.44946,0 -0.26663,-0.66342 0.4063,-1.47425 0.67294,-0.81083 1.5681,-1.26129 1.98925,-1.001 0.42114,0.26029 1.37313,-0.30156 2.11553,-1.24853 1.22149,-1.55808 1.18509,-1.59258 -0.38286,-0.36292 -0.95297,0.74738 -1.73267,0.91332 -1.73267,0.36877 0,-1.1032 2.94273,-3.80059 3.86504,-3.5428 0.32472,0.0908 0.81317,-0.0921 1.08545,-0.40626 0.27228,-0.3142 -0.0619,-0.25079 -0.74257,0.14094 -1.83418,1.05552 -1.52708,0.0245 1.35025,-4.53358 3.80038,-6.02017 8.15245,-16.13427 10.34121,-24.03269 2.90781,-10.4932 3.24131,-10.00199 -6.51584,-9.59724 -8.06376,0.33451 -11.36374,-0.51104 -11.36374,-2.91169 0,-1.41219 3.87705,-3.01077 12.01762,-4.9551 13.6173,-3.2524 18.1279,-6.30458 30.44942,-20.604205 3.20647,-3.721241 5.60795,-5.75908 6.01348,-5.102907 0.45242,0.732027 1.17307,0.513084 2.18435,-0.663636 2.69435,-3.135129 3.29702,-4.863342 0.99046,-2.840244 -1.18271,1.037369 -2.15038,1.440581 -2.15038,0.896027 0,-1.154396 3.94299,-4.919356 4.6419,-4.432319 0.26048,0.181519 0.77064,-0.0013 1.13367,-0.406262 0.36304,-0.404963 0.10314,-0.415797 -0.57755,-0.02408 -1.80598,1.039294 -1.51814,-0.190163 0.80999,-3.459724 2.31999,-3.258114 2.32271,-3.256657 -3.39724,-1.816357 -3.2192,0.810603 -6.66348,0.694459 -14.67251,-0.494768 -15.04707,-2.234274 -20.55437,-0.689621 -28.57683,8.015049 -2.42602,2.632325 -4.72907,4.680174 -5.11788,4.550775 -0.38882,-0.129399 -0.48449,0.344426 -0.2126,1.052946 0.27188,0.70852 -0.4282,2.123094 -1.55573,3.143497 -2.0095,1.818571 -2.09324,1.812104 -4.23219,-0.326854 l -2.18214,-2.182131 2.25594,-4.252496 c 1.24077,-2.338872 4.17354,-6.452573 6.51728,-9.141556 2.34372,-2.688985 4.05061,-5.50801 3.79308,-6.264503 -0.31259,-0.918192 -0.0455,-1.114196 0.80328,-0.589595 0.85837,0.530499 1.02875,0.393018 0.52435,-0.423105 -0.41094,-0.664922 -0.99572,-0.9604 -1.2995,-0.656618 -0.69266,0.69266 -3.20978,-1.330935 -3.20978,-2.580451 0,-0.510014 0.51439,-0.609392 1.14308,-0.220837 0.73045,0.451439 0.87336,0.270048 0.3959,-0.50249 -0.41094,-0.664922 -1.00055,-0.955563 -1.31024,-0.645868 -0.69833,0.698319 -4.18913,-2.365165 -4.18913,-3.67632 0,-0.526833 0.7797,-0.370613 1.73267,0.347155 0.95297,0.717767 -0.70223,-1.23225 -3.67822,-4.333371 -3.76003,-3.918124 -5.93501,-5.472057 -7.12873,-5.093182 -0.94481,0.299873 -3.07003,-0.15402 -4.7227,-1.00865 -2.43778,-1.26062 -3.37289,-1.324035 -4.95495,-0.33602 -2.36555,1.477307 -3.05981,0.886 -3.92467,-3.34268 -0.56625,-2.768728 -1.37248,-3.513567 -5.43639,-5.022464 -7.80616,-2.898363 -17.966683,-4.011606 -26.200113,-2.870631 -3.997279,0.553936 -7.475959,1.215337 -7.730402,1.469779 -0.254442,0.254443 0.998085,3.050852 2.783393,6.214244 2.874608,5.093525 3.291609,6.794112 3.644505,14.862796 l 0.398492,9.111176 3.564442,0.668693 c 7.773644,1.458345 16.010573,8.110583 19.620143,15.845464 3.09701,6.636514 3.26024,18.338664 0.34238,24.546143 -2.99996,6.38214 -7.1277,10.84757 -13.007325,14.07144 -4.530381,2.48406 -6.383854,2.90835 -12.728271,2.91366 -6.074888,0.005 -8.236255,-0.44332 -11.881188,-2.465 -2.450495,-1.35916 -4.455445,-2.98232 -4.455445,-3.60701 0,-0.62469 -0.40559,-1.50708 -0.901312,-1.96089 -0.523658,-0.47936 -0.602889,-0.3065 -0.189092,0.41255 0.391721,0.68069 0.309434,1.23762 -0.182859,1.23762 -1.220735,0 -4.304298,-3.49834 -3.655466,-4.14718 0.286625,-0.28662 -0.191905,-1.11291 -1.063399,-1.83618 -1.321234,-1.09653 -1.725666,-1.0867 -2.433844,0.0592 -0.46712,0.75582 -0.647589,1.7006 -0.401041,2.09952 0.480206,0.77699 -4.431607,4.73002 -8.49972,6.84057 -1.361386,0.7063 -6.473966,1.77939 -11.361289,2.38466 l -8.886042,1.10047 -0.8419,4.2572 c -1.116431,5.64542 -0.634772,6.55826 4.953601,9.38814 6.711939,3.39884 14.108367,5.45589 25.541571,7.10346 13.412147,1.93275 20.966236,1.82034 33.743152,-0.50211 17.901519,-3.25395 20.945769,-2.59407 18.234109,3.95245 -1.77158,4.27697 -8.27108,9.72932 -15.51118,13.01214 -10.066949,4.56456 -20.604188,6.60666 -38.045678,7.37316 -12.034826,0.52888 -15.515628,0.97079 -14.765554,1.87458 0.53979,0.65041 0.751763,1.41223 0.47105,1.69294 -0.280712,0.28071 0.280084,1.1308 1.246214,1.8891 1.597283,1.25367 1.633357,1.22157 0.397743,-0.35396 -1.901096,-2.42408 -0.973659,-2.18092 4.907357,1.28665 4.510039,2.65922 13.386837,5.60901 26.15447,8.69123 6.758464,1.63156 18.458956,1.2966 26.494168,-0.75846 l 0,-4e-5 z m 15.58504,-0.061 c 1.16161,-0.7507 0.90473,-0.96308 -1.17919,-0.97494 -1.46538,-0.008 -2.9397,0.43038 -3.27626,0.97494 -0.78135,1.26425 2.49915,1.26425 4.45545,0 z m 6.00568,-2.01503 c 1.95644,-1.04706 2.62207,-2.93547 1.0347,-2.93547 -0.48422,0 -1.93224,0.87627 -3.21783,1.94726 -2.49465,2.07826 -1.06383,2.72592 2.18313,0.98821 z m -6.00568,-1.45032 c 1.36139,-0.77824 2.0297,-1.41498 1.48515,-1.41498 -0.54456,0 -2.10396,0.63674 -3.46535,1.41498 -1.36138,0.77824 -2.0297,1.41498 -1.48515,1.41498 0.54456,0 2.10396,-0.63674 3.46535,-1.41498 z m -62.458746,0.13411 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553336,0.36093 1.577225,1.26362 4.799862,2.3676 3.441125,1.17883 l 0,0 z m 74.762706,-3.12566 c 1.04936,-0.7939 1.64445,-1.70691 1.32243,-2.02893 -0.78266,-0.78265 -4.7155,1.36919 -4.7155,2.58006 0,1.33049 1.15362,1.1431 3.39307,-0.55113 z m 5.3845,-4.97977 c 0.31295,-1.61495 0.14607,-1.68767 -1.23763,-0.53929 -1.89234,1.57049 -2.12795,3.40609 -0.36172,2.81801 0.68069,-0.22665 1.40039,-1.25207 1.59935,-2.27872 z m -93.926084,0.17176 c 0,-0.2056 -0.779703,-0.9853 -1.732673,-1.73268 -1.570353,-1.23155 -1.605372,-1.19653 -0.373817,0.37382 1.293435,1.64926 2.10649,2.17375 2.10649,1.35886 z m 42.048957,-9.0646 c 10.23476,-3.01561 12.830661,-4.22882 16.665417,-7.78864 1.52559,-1.41621 3.14513,-2.57492 3.599,-2.57492 0.45387,0 1.59099,-1.16873 2.52694,-2.59715 0.93594,-1.42844 1.24801,-2.31675 0.69349,-1.97403 -0.55454,0.34271 -1.20807,0.0635 -1.45231,-0.62067 -0.24423,-0.68409 -0.82632,-0.88541 -1.2935,-0.44739 -0.46721,0.43803 -0.19404,1.21091 0.60702,1.71751 1.25252,0.79212 1.23533,0.92323 -0.12275,0.93627 -0.86857,0.008 -2.42798,0.95441 -3.46535,2.10238 -5.028165,5.56424 -22.795527,11.3182 -38.212356,12.37508 -15.799597,1.08311 -17.048668,2.42489 -1.792578,1.92561 10.641937,-0.34827 15.176438,-0.97076 22.246977,-3.05405 l 0,0 z m 63.891637,-3.12611 c 0,-1.41552 -0.23243,-1.39342 -1.9802,0.18829 -1.08911,0.98563 -1.9802,2.18422 -1.9802,2.66353 0,0.47932 0.89109,0.39459 1.9802,-0.18828 1.08911,-0.58287 1.9802,-1.78147 1.9802,-2.66354 z M 97.166642,146.77097 c 3.547598,-0.77002 4.965228,-1.47727 4.298178,-2.14431 -0.66706,-0.66706 -4.175166,-0.42281 -10.636358,0.74056 -14.897153,2.68229 -37.124591,0.77195 -52.477337,-4.51017 -6.578027,-2.26317 -6.378989,-2.22908 -6.378989,-1.09252 0,1.42916 9.008565,4.85904 15.926311,6.06371 16.965213,2.95437 38.134158,3.35943 49.268195,0.94273 l 0,0 z m 53.617378,0.0462 c 0.58287,-1.08911 0.837,-1.9802 0.56472,-1.9802 -0.27228,0 -0.97195,0.89109 -1.55482,1.9802 -0.58287,1.08911 -0.837,1.9802 -0.56472,1.9802 0.27227,0 0.97195,-0.89109 1.55482,-1.9802 z m 5.94059,-4.62356 c 0,-2.3135 -1.69554,-0.59965 -2.85822,2.88907 l -1.073,3.21964 1.96562,-2.33741 c 1.08108,-1.28558 1.9656,-2.98266 1.9656,-3.7713 z m -77.497329,2.91089 c -2.054226,-0.21433 -5.173038,-0.21074 -6.930694,0.008 -1.757656,0.21872 -0.07693,0.39409 3.734955,0.38969 3.811881,-0.004 5.249963,-0.18335 3.195739,-0.39768 l 0,7e-5 z m 10.356241,-0.94387 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52002 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 19.616338,-1.30386 c 0,-0.54455 -0.47184,-0.99009 -1.04854,-0.99009 -0.57669,0 -0.77316,0.44554 -0.43661,0.99009 0.33655,0.54456 0.8084,0.9901 1.04853,0.9901 0.24014,0 0.43662,-0.44554 0.43662,-0.9901 z m 47.45458,-8.41584 c 0,-0.54455 -0.63674,0.12377 -1.41498,1.48515 -0.77823,1.36139 -1.41498,2.92079 -1.41498,3.46535 0,0.54455 0.63675,-0.12376 1.41498,-1.48515 0.77824,-1.36139 1.41498,-2.92079 1.41498,-3.46535 z M 28.453542,136.6394 c -0.717346,-1.86938 -3.412099,-3.08084 -3.412099,-1.53397 0,1.05715 3.177874,3.9134 3.73462,3.35666 0.149813,-0.14981 0.0047,-0.97003 -0.322521,-1.82269 z m 6.406383,0.90594 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553337,0.36093 1.577226,1.26362 4.799863,2.3676 3.441126,1.17883 z m -8.178941,-9.80642 c -0.27121,-0.67032 -0.476602,0.11785 -0.456423,1.75152 0.02018,1.63366 0.242077,2.18212 0.493111,1.21878 0.251032,-0.96334 0.234523,-2.29997 -0.03668,-2.9703 l -4e-6,0 z M 162.66521,127.0736 c 0,-0.51242 -0.44555,-1.20703 -0.9901,-1.54359 -0.54456,-0.33655 -0.9901,0.0827 -0.9901,0.93167 0,0.84897 0.44554,1.54358 0.9901,1.54358 0.54455,0 0.9901,-0.41925 0.9901,-0.93166 z M 27.619826,122.33281 c -0.329002,-0.329 -0.563011,0.25579 -0.52002,1.29951 0.0475,1.15341 0.28212,1.38802 0.598185,0.59819 0.286011,-0.71474 0.250836,-1.5687 -0.07817,-1.8977 l 3e-6,0 z m 136.035474,0.2269 c 0,-0.81683 -0.44554,-1.48514 -0.99009,-1.48514 -0.54456,0 -0.9901,0.66831 -0.9901,1.48514 0,0.81684 0.44554,1.48515 0.9901,1.48515 0.54455,0 0.99009,-0.66831 0.99009,-1.48515 z M 33.704809,119.40196 c -0.95297,-0.24903 -2.512376,-0.24903 -3.465346,0 -0.952971,0.24904 -0.173268,0.4528 1.732673,0.4528 1.905941,0 2.685644,-0.20376 1.732673,-0.4528 z m 51.237624,-0.30759 c 0.336553,-0.54456 -0.250915,-0.9901 -1.305483,-0.9901 -1.054569,0 -2.472053,-0.66832 -3.149963,-1.48515 -0.677909,-0.81683 -2.197663,-1.48515 -3.37723,-1.48515 -1.179567,0 -3.798279,-0.84306 -5.819362,-1.87346 -3.979476,-2.02885 -4.801958,-1.43381 -1.788124,1.29368 1.984228,1.7957 10.984716,4.90909 10.984716,3.79975 0,-0.35514 0.534654,-0.11106 1.188119,0.54241 1.44777,1.44777 2.457132,1.50894 3.267327,0.19802 z m 79.702967,-3.02873 c 0,-1.05697 -0.44554,-1.92177 -0.9901,-1.92177 -0.54455,0 -0.99009,1.14016 -0.99009,2.53369 0,1.43699 0.42855,2.26881 0.99009,1.92176 0.54456,-0.33656 0.9901,-1.47671 0.9901,-2.53368 z m -126.008939,1.3525 c -0.963334,-0.25103 -2.299968,-0.23452 -2.970297,0.0366 -0.670329,0.27122 0.117853,0.47661 1.751517,0.45643 1.633663,-0.0202 2.182114,-0.24208 1.21878,-0.49311 l 0,5e-5 z m 15.788583,-6.49209 c 2.961802,-2.58663 6.027485,-4.70297 6.812628,-4.70297 1.653245,0 1.836694,-1.82146 0.39887,-3.96039 -0.83888,-1.24794 -1.390264,-1.01072 -3.45205,1.48514 -1.349539,1.63367 -2.677116,3.63862 -2.950173,4.45545 -0.273055,0.81683 -3.168256,2.95063 -6.433779,4.74178 -3.265523,1.79115 -5.937315,3.64601 -5.937315,4.12192 0,1.77959 6.361283,-1.59914 11.561819,-6.14093 z m -20.47271,5.3104 c 0,-1.48733 -5.81027,-1.8801 -6.366582,-0.43038 -0.356538,0.92913 0.492992,1.3081 2.93231,1.3081 1.888849,0 3.434272,-0.39498 3.434272,-0.87772 z m 63.050779,-1.35 c 2.916955,-1.98579 4.205247,-3.71287 2.769577,-3.71287 -0.693665,0 -8.394613,5.11626 -8.394613,5.57711 0,1.01623 2.716191,0.11603 5.625036,-1.86424 z m -5.082551,-1.19364 c 7.593085,-3.17259 13.318898,-12.23833 13.318898,-21.087947 0,-14.183278 -14.801367,-26.126413 -27.276503,-22.009246 -4.871629,1.607782 -12.143736,8.333235 -14.435363,13.350236 -3.260107,7.137268 -1.947056,16.953627 3.009811,22.501317 l 2.75988,3.08884 0.514066,-6.40417 c 0.59176,-7.372086 2.817916,-12.370412 6.194803,-13.909026 9.324945,-4.24873 15.584088,10.950876 9.956609,24.178486 -0.930827,2.18794 1.172672,2.29087 5.957799,0.29151 l 0,0 z m -66.879119,-1.52913 c -2.805149,-2.19422 -4.307733,-2.52716 -3.741707,-0.82908 0.211038,0.6331 1.180081,1.268 2.15343,1.41085 0.973349,0.14286 2.025929,0.51595 2.339067,0.82908 0.313138,0.31314 0.829243,0.55943 1.1469,0.54732 0.317656,-0.0121 -0.536304,-0.89328 -1.89769,-1.95817 z m 12.639913,0.64485 c 0.689575,-0.42992 0.997439,-1.19644 0.684141,-1.70337 -0.313298,-0.50692 -0.139505,-0.92168 0.386206,-0.92168 0.525712,0 0.704595,-0.96077 0.397519,-2.13502 -0.337827,-1.29185 -0.167417,-1.89344 0.431502,-1.52328 0.604271,0.37346 1.005912,-1.20529 1.031127,-4.0531 0.03148,-3.556019 -0.171219,-4.194157 -0.852784,-2.684642 -0.678574,1.502882 -0.773791,1.192692 -0.395022,-1.286842 0.353363,-2.313228 0.165236,-3.060723 -0.644381,-2.560356 -0.737692,0.45592 -0.940577,0.178019 -0.571745,-0.783139 0.314436,-0.819406 0.23569,-2.033505 -0.174991,-2.698 -1.105326,-1.788456 -7.682811,-2.144736 -9.055691,-0.490515 -0.631379,0.760762 -0.759249,1.396753 -0.284156,1.413317 0.475095,0.01654 0.06457,0.495168 -0.912263,1.063584 -1.129264,0.657109 -1.565313,1.697515 -1.197349,2.856861 0.318297,1.002872 0.145073,2.091406 -0.384943,2.418971 -1.212393,0.749301 -1.114708,6.501761 0.11041,6.501761 0.49838,0 0.626441,0.88128 0.284578,1.95839 -1.132056,3.56679 7.260902,7.05039 11.147842,4.62706 l 0,0 z m 8.934184,-0.55418 c 2.020385,-1.03924 5.010061,-3.29502 6.643725,-5.01286 2.868463,-3.01627 2.981671,-3.49028 3.302077,-13.826072 l 0.33178,-10.702722 -3.762914,-0.705927 C 47.602481,80.969761 43.95345,78.863901 38.40778,73.51044 l -4.950496,-4.778915 -3.90401,1.921073 C 17.503668,76.58193 12.423679,90.628824 18.240927,101.93283 c 3.23262,6.2816 4.539882,6.43779 5.329032,0.6367 0.928828,-6.827865 1.319844,-7.895489 4.103161,-11.203281 7.697735,-9.148234 17.690208,3.484377 13.905573,17.579601 -1.6234,6.04608 -1.03574,6.43209 5.036847,3.3085 l 0,0 z m 37.877227,-0.17548 c 0.607833,-1.13574 0.846281,-2.32386 0.529884,-2.64025 -0.316397,-0.3164 -0.575268,-0.0873 -0.575268,0.50911 0,0.59643 -0.700141,1.78455 -1.55587,2.64027 -0.855728,0.85573 -1.094176,1.55587 -0.529884,1.55587 0.564291,0 1.523303,-0.92924 2.131138,-2.065 l 0,0 z m -8.956275,-0.41024 c -0.777242,-0.93653 -0.843612,-1.48515 -0.179665,-1.48515 0.579095,0 1.32826,0.44554 1.664814,0.9901 0.336553,0.54455 1.710509,0.9901 3.053236,0.9901 3.405659,0 4.705098,-3.86234 3.99729,-11.88119 -0.410484,-4.650429 -0.278996,-6.023676 0.474005,-4.950498 0.92628,1.320129 0.997019,1.320129 0.636655,0 -0.222976,-0.816832 -0.888084,-1.485149 -1.478018,-1.485149 -0.589933,0 -1.406765,-0.334158 -1.815181,-0.742574 -0.408416,-0.408416 -1.808473,-0.742574 -3.111239,-0.742574 -1.326986,0 -2.099559,-0.435416 -1.756748,-0.990099 1.082137,-1.750934 -0.356281,-1.056251 -2.436678,1.176792 -1.948858,2.091852 -2.796679,4.371505 -1.276193,3.431475 0.408415,-0.252495 0.742574,2.796683 0.742574,6.775957 0,4.5426 -0.368457,7.02333 -0.990099,6.66611 -0.544555,-0.31292 -0.141343,0.39874 0.896028,1.58146 2.106995,2.4022 3.511949,2.99403 1.579219,0.66524 l 0,0 z m 74.981158,-0.19108 c -0.96334,-0.25103 -2.29997,-0.23453 -2.9703,0.0366 -0.67032,0.27122 0.11786,0.4766 1.75152,0.45643 1.63366,-0.0202 2.18212,-0.24208 1.21878,-0.49311 l 0,5e-5 z m -84.882148,-2.77922 c -0.67791,-0.81683 -1.678108,-1.48515 -2.222662,-1.48515 -0.552304,0 -0.445093,0.65669 0.242464,1.48515 0.67791,0.81683 1.678108,1.48515 2.222663,1.48515 0.552304,0 0.445093,-0.6567 -0.242465,-1.48515 z m 38.428218,-0.43317 c 0.24752,-0.74257 -0.12376,-1.11386 -0.86634,-0.86634 -0.71472,0.23824 -1.49443,1.01795 -1.73267,1.73268 -0.24752,0.74257 0.12376,1.11386 0.86634,0.86633 0.71472,-0.23823 1.49443,-1.01795 1.73267,-1.73267 z m 61.57178,-0.16781 c 0,-1.1313 -2.6849,-1.15685 -3.38,-0.0322 -0.2896,0.4686 -0.27234,1.10622 0.0384,1.41693 0.7726,0.77266 3.34158,-0.29192 3.34158,-1.38475 z m -145.544552,0.16436 c 0,-1.16817 -1.931044,-2.41782 -2.640265,-1.7086 -0.709219,0.70923 0.54042,2.64027 1.708598,2.64027 0.512417,0 0.931667,-0.41925 0.931667,-0.93167 z m 65.94472,-2.76058 c -0.329002,-0.329 -0.563011,0.25578 -0.52002,1.29951 0.04751,1.15341 0.28212,1.38802 0.598185,0.59818 0.286011,-0.71472 0.250836,-1.56868 -0.07817,-1.89769 l 3e-6,0 z m 20.193892,-0.7632 c 0,-0.81683 -0.44554,-1.48515 -0.9901,-1.48515 -0.54455,0 -0.9901,0.66832 -0.9901,1.48515 0,0.81683 0.44555,1.48515 0.9901,1.48515 0.54456,0 0.9901,-0.66832 0.9901,-1.48515 z m 60.18796,-0.40346 c 2.02039,-1.03875 5.45561,-3.52622 7.63382,-5.527735 l 3.9604,-3.639109 -4.45545,3.425762 c -2.45049,1.884172 -6.23762,4.351962 -8.41584,5.483972 -2.17822,1.13201 -3.60848,2.0779 -3.17837,2.10196 0.43011,0.0241 2.43506,-0.80612 4.45544,-1.84485 z m -94.1857,-5.289607 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237627 0,1.36138 0.224726,1.91831 0.499392,1.23762 0.274665,-0.68069 0.274665,-1.794554 0,-2.475247 z m 13.861386,-0.990099 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237624 0,1.361382 0.224726,1.918312 0.499392,1.237622 0.274666,-0.680691 0.274666,-1.794553 0,-2.475246 z m -25.408199,0.742575 c 0,-0.816832 -0.445544,-1.485149 -0.990099,-1.485149 -0.544554,0 -0.990099,0.668317 -0.990099,1.485149 0,0.816831 0.445545,1.485151 0.990099,1.485151 0.544555,0 0.990099,-0.66832 0.990099,-1.485151 z m 47.524753,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921683 -0.55343,0.342039 -0.74992,1.036653 -0.43661,1.543584 0.84874,1.37331 1.44286,1.11724 1.44286,-0.621901 l 0,0 z M 13.75844,96.59024 c -0.329002,-0.329 -0.563011,0.255782 -0.520019,1.299504 0.04751,1.153416 0.282119,1.38802 0.598184,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897693 l 0,0 z m 45.936468,-3.733496 c 0,-0.816831 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668317 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m 49.504952,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921684 -0.55343,0.34204 -0.74992,1.036654 -0.43661,1.543585 0.84874,1.373307 1.44286,1.117237 1.44286,-0.621901 l 0,0 z M 12.768341,90.649645 c -0.329002,-0.328998 -0.563011,0.255783 -0.52002,1.299505 0.04751,1.153416 0.28212,1.38802 0.598185,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897694 l 0,0 z m 70.193894,0.721951 c -0.336554,-0.544555 -1.142551,-0.983277 -1.791106,-0.974941 -0.708531,0.0089 -0.586411,0.398248 0.305957,0.974941 1.902102,1.229238 2.244857,1.229238 1.485149,0 z m 25.247525,-4.513878 c 0,-0.84897 -0.45281,-1.263728 -1.00625,-0.921685 -0.55343,0.342043 -0.74992,1.036654 -0.43661,1.543581 0.84874,1.373311 1.44286,1.117238 1.44286,-0.621896 z M 13.75844,84.709054 c -0.329002,-0.329001 -0.563011,0.255777 -0.520019,1.299505 0.04751,1.153409 0.282119,1.38802 0.598184,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 0,0 z m 48.906765,-3.85473 c 0,-1.356215 -3.082898,-1.911382 -4.232156,-0.762123 -0.330986,0.330986 -0.08945,1.422196 0.536762,2.424911 0.842923,1.349734 1.470503,1.547624 2.416974,0.762123 0.703131,-0.583548 1.27842,-1.674757 1.27842,-2.424911 z m 43.564355,0.09971 c 0,-2.007107 -9.940776,-11.875249 -12.685773,-12.593082 -3.422347,-0.894964 -2.536662,0.72179 2.04221,3.727903 4.685203,3.075921 8.056173,6.371341 8.979963,8.778691 0.77225,2.012434 1.6636,2.058775 1.6636,0.08649 z m -47.693353,-7.404219 2.306645,-4.455446 -0.675699,4.455446 -0.6757,4.455445 3.814599,-3.586129 c 2.098029,-1.972372 6.311347,-5.155371 9.362929,-7.073331 5.874539,-3.692229 6.839458,-5.599101 6.818235,-13.474203 -0.0116,-4.303265 -3.763041,-12.649115 -7.037511,-15.656368 -5.956689,-5.47059 -15.534138,-7.597002 -22.017021,-4.888282 -12.757989,5.330628 -18.072962,19.793085 -11.85765,32.265591 2.52515,5.067315 2.685106,5.196865 3.601855,2.917172 0.958373,-2.383197 0.960066,-2.382511 1.654947,0.671085 0.942906,4.14352 1.700115,5.200511 5.327538,7.436733 4.523217,2.788458 6.716499,2.070908 9.376833,-3.067713 l 0,0 z m 8.682689,1.5849 c 1.905993,-1.851076 4.77995,-3.91008 6.386569,-4.575565 2.564998,-1.062456 4.03369,-2.949929 2.295417,-2.949929 -2.10037,0 -13.235677,8.775011 -13.235677,10.430176 0,1.083649 1.30255,0.252787 4.553691,-2.904682 z M 20.090948,74.8078 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z M 152.76422,69.68259 c 0,-0.272277 -1.78218,1.245201 -3.9604,3.372174 -2.17822,2.126974 -3.9604,4.089996 -3.9604,4.362274 0,0.272277 1.78218,-1.245201 3.9604,-3.372175 2.17822,-2.126973 3.9604,-4.089996 3.9604,-4.362273 z M 41.625601,72.476287 c -2.586633,-2.217071 -4.709793,-4.553304 -4.718131,-5.191628 -0.02877,-2.202305 -1.632163,-3.701423 -3.281819,-3.068391 -2.032483,0.779938 -2.195989,3.392952 -0.212309,3.392952 0.792663,0 3.354544,2.00317 5.693069,4.45149 2.338525,2.44832 4.92018,4.450394 5.737012,4.449053 0.816832,-0.0014 -0.631188,-1.816405 -3.217822,-4.033476 l 0,0 z M 24.051344,70.847404 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z m 6.526162,-3.972749 c -0.745512,-0.745512 -5.536063,1.770447 -5.536063,2.907495 0,0.46652 1.378038,0.135607 3.062307,-0.735362 1.684269,-0.870969 2.797459,-1.848429 2.473756,-2.172133 z m 53.127303,0.748085 c 0.952971,-0.0074 1.732673,-0.459065 1.732673,-1.003619 0,-0.544555 -0.940674,-0.990099 -2.090387,-0.990099 -1.852777,0 -2.016491,-0.393899 -1.440284,-3.465347 0.406143,-2.164925 0.261718,-3.465346 -0.38486,-3.465346 -0.56923,0 -1.034964,1.059307 -1.034964,2.354014 0,1.294709 -0.668316,2.90867 -1.485148,3.58658 -2.367441,1.964801 -1.885292,4.298583 0.742574,3.594342 1.225248,-0.328353 3.007426,-0.60309 3.960396,-0.610525 z m 71.134371,-0.722043 c 1.58154,-0.934242 2.87553,-2.079091 2.87553,-2.544109 0,-1.671282 -4.25968,-0.165537 -5.70037,2.015008 -1.76311,2.668563 -1.02958,2.805958 2.82484,0.529101 z m 47.13694,-2.884855 c -0.37294,-0.372946 -1.68483,-0.148769 -2.91529,0.498172 -1.23047,0.64694 -1.45751,0.953686 -0.50454,0.681656 1.92704,-0.550082 2.24796,0.402733 0.74808,2.221031 -0.54153,0.65649 -0.009,0.312431 1.18262,-0.764577 1.19197,-1.077007 1.86208,-2.263334 1.48913,-2.636282 z m -52.1822,2.108229 c 0.67791,-0.816831 1.00979,-1.485148 0.73751,-1.485148 -0.27227,0 -1.0497,0.668317 -1.72761,1.485148 -0.67791,0.816832 -1.00979,1.485149 -0.73752,1.485149 0.27228,0 1.04971,-0.668317 1.72762,-1.485149 z m 37.15543,-0.451808 c -0.32185,-0.520771 -1.23923,-0.695875 -2.03863,-0.38912 -2.04664,0.785373 -1.80547,1.335978 0.5852,1.335978 1.12125,0 1.7753,-0.426086 1.45343,-0.946858 z m -20.13811,-0.719592 c -0.71473,-0.286011 -1.56869,-0.250835 -1.89769,0.07817 -0.329,0.329001 0.25578,0.56301 1.29951,0.520019 1.15341,-0.04751 1.38802,-0.282119 0.59818,-0.598185 l 0,-3e-6 z M 84.05547,61.936777 c -0.329002,-0.329001 -0.563011,0.255776 -0.52002,1.299505 0.04751,1.153409 0.28212,1.38802 0.598185,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 3e-6,0 z m 82.57013,0.721948 c 0,-0.544555 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445544 -1.48515,0.990099 0,0.544554 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445545 1.48515,-0.990099 z m 37.62376,-5.177658 c 0,-1.661518 -0.24856,-1.789209 -1.48514,-0.762936 -0.81684,0.67791 -1.48515,1.832342 -1.48515,2.565406 0,0.777973 0.61827,1.095588 1.48515,0.762936 0.81683,-0.313447 1.48514,-1.46788 1.48514,-2.565406 z M 83.457284,54.18445 c 0,-0.784694 -0.445544,-1.426715 -0.990099,-1.426715 -0.544554,0 -0.990099,0.917384 -0.990099,2.03863 0,1.121247 0.445545,1.76327 0.990099,1.426716 0.544555,-0.336553 0.990099,-1.253937 0.990099,-2.038631 z m 63.366336,-0.931666 c -1.27896,-1.361386 -2.77092,-2.475247 -3.31547,-2.475247 -0.54456,0 0.0563,1.113861 1.33527,2.475247 1.27896,1.361386 2.77092,2.475248 3.31548,2.475248 0.54455,0 -0.0563,-1.113862 -1.33528,-2.475248 z M 82.467185,48.302289 c 0,-0.816832 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668316 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m -1.985115,-5.19802 c -0.0084,-1.2671 -4.736103,-6.714785 -5.323399,-6.134089 -0.649329,0.642032 3.49033,6.834315 4.585742,6.859554 0.408416,0.0094 0.740362,-0.317049 0.737657,-0.725465 l 0,0 z m 50.49997,-0.247525 c -0.81683,-0.527877 -1.9307,-0.959776 -2.47525,-0.959776 -0.54456,0 -0.32178,0.431899 0.49505,0.959776 0.81683,0.527878 1.93069,0.959777 2.47525,0.959777 0.54455,0 0.32178,-0.431899 -0.49505,-0.959777 z m 4.44995,-0.996169 c -0.98866,-1.092447 -2.01229,-1.771531 -2.27475,-1.509075 -0.66527,0.66528 1.80418,3.495343 3.04998,3.495343 0.56227,0 0.21342,-0.89382 -0.77523,-1.986268 l 0,0 z m -95.539062,-4.19679 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.677909 1.485148,-1.678107 1.485148,-2.222662 z m 92.079212,0.795947 c 0,-2.367417 -1.80911,-2.723191 -2.95546,-0.581213 -0.91594,1.711444 -0.77708,2.007928 0.94043,2.007928 1.10826,0 2.01503,-0.642021 2.01503,-1.426715 z M 43.853324,33.703389 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.67791 1.485148,-1.678108 1.485148,-2.222662 z m 29.450539,-0.0051 c -0.341635,-3.033194 -0.613818,-3.235945 -4.743791,-3.533678 -2.40975,-0.173719 -4.148989,-0.08348 -3.864976,0.200533 0.746043,0.746042 8.309556,6.402673 8.668673,6.483162 0.166387,0.03729 0.139429,-1.380215 -0.05991,-3.150017 z m 45.796987,1.732673 c -0.67791,-0.816832 -1.70871,-1.485149 -2.29066,-1.485149 -0.58196,0 -0.19325,0.654147 0.8638,1.453661 2.48363,1.878524 2.96864,1.889227 1.42686,0.03148 l 0,3e-6 z m 5.94059,-0.933056 c 0,-0.721181 -1.00247,-1.579892 -2.22772,-1.908245 -3.82044,-1.023837 -4.13152,-0.702262 -1.76134,1.820687 2.31705,2.466393 3.98906,2.503093 3.98906,0.08755 l 0,4e-6 z m 8.8851,-5.657864 c 5.0656,-7.213134 5.95021,-9.230659 3.73867,-8.526659 -1.72171,0.548068 -10.64357,12.438161 -10.64357,14.184592 0,2.924919 2.06665,1.231484 6.9049,-5.657933 z m -54.828018,2.397173 c -0.586902,-0.586901 -3.56203,0.943932 -3.56203,1.832819 0,0.490907 0.870827,0.348719 1.935171,-0.315974 1.064342,-0.664694 1.796429,-1.347273 1.626859,-1.516845 z m -29.622424,0.529501 c 3.007757,-1.087619 4.641314,-3.761497 2.298018,-3.761497 -0.544554,0 -0.990099,0.445545 -0.990099,0.990099 0,0.544555 -0.58316,0.990099 -1.295911,0.990099 -1.477794,0 -5.628481,2.890588 -4.219928,2.938809 0.505892,0.01732 2.399456,-0.503561 4.20792,-1.15751 l 0,0 z m 54.958912,-1.46755 c -0.71473,-0.286011 -1.56869,-0.250836 -1.89769,0.07817 -0.329,0.329002 0.25577,0.563011 1.2995,0.52002 1.15341,-0.0475 1.38802,-0.28212 0.59819,-0.598185 l 0,-3e-6 z M 59.694908,28.005259 c 0,-1.089109 -0.39099,-1.980198 -0.868866,-1.980198 -1.298365,0 -3.17241,2.559384 -2.422873,3.30892 1.355486,1.355487 3.291739,0.573912 3.291739,-1.328722 z m 21.287129,0.990099 c 0.336553,-0.544554 -0.331763,-0.990099 -1.485149,-0.990099 -1.153385,0 -1.821702,0.445545 -1.485148,0.990099 0.336553,0.544555 1.00487,0.990099 1.485148,0.990099 0.480279,0 1.148595,-0.445544 1.485149,-0.990099 z m 29.207923,0 c 0,-0.544554 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445545 -1.48515,0.990099 0,0.544555 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445544 1.48515,-0.990099 z M 86.427581,28.005259 c 0,-0.544554 -0.694611,-0.990099 -1.543581,-0.990099 -0.848969,0 -1.268219,0.445545 -0.931666,0.990099 0.336553,0.544555 1.031164,0.990099 1.543581,0.990099 0.512417,0 0.931666,-0.445544 0.931666,-0.990099 z m 18.316829,0 c 0.33656,-0.544554 -0.33176,-0.990099 -1.48515,-0.990099 -1.15338,0 -1.8217,0.445545 -1.48514,0.990099 0.33655,0.544555 1.00487,0.990099 1.48514,0.990099 0.48028,0 1.1486,-0.445544 1.48515,-0.990099 z M 53.397761,23.263982 c -2.293369,-2.293369 -3.273717,-0.599352 -1.065339,1.840877 1.180946,1.304931 2.008695,1.63504 2.254066,0.898928 0.213274,-0.63982 -0.321654,-1.872732 -1.188727,-2.739805 l 0,0 z m 41.674343,3.065049 c -0.963333,-0.251033 -2.299967,-0.234524 -2.970297,0.03668 -0.670328,0.271211 0.117854,0.476602 1.751517,0.456424 1.633663,-0.02018 2.182115,-0.242078 1.21878,-0.493111 l 0,4e-6 z M 50.784017,20.160629 c 0,-1.18906 -5.817795,-7.006855 -7.006854,-7.006855 -1.723094,0 -0.911591,1.747528 2.244318,4.833013 3.196159,3.124838 4.762536,3.839805 4.762536,2.173842 z m 99.083553,-7.807387 c -1.32905,-0.443014 -5.95468,4.804941 -5.94174,6.741126 0.006,0.860676 1.47299,-0.172344 3.48946,-2.456779 1.91375,-2.168059 3.01727,-4.096016 2.45228,-4.284347 z m -7.4939,4.754858 c 2.64699,-2.924889 1.22992,-3.38489 -1.49431,-0.485075 -1.27694,1.359238 -1.86755,2.471343 -1.31247,2.471343 0.55508,0 1.81813,-0.893821 2.80678,-1.986268 z m 1.9747,-5.934524 c 2.68184,-2.7227721 4.44726,-4.9364147 3.92318,-4.9192068 -1.79455,0.058926 -11.48794,9.8697018 -9.75161,9.8697018 0.52381,0 3.1466,-2.227723 5.82843,-4.950495 z m 4.99121,-1.055971 c 1.06562,-1.7242011 -0.14804,-2.0893477 -1.506,-0.4531041 -0.78094,0.9409741 -0.85606,1.5090751 -0.19952,1.5090751 0.57909,0 1.34657,-0.475187 1.70552,-1.055971 z m 22.08877,-7.9517764 c 1.71492,-0.5978257 3.11804,-1.51893899 3.11804,-2.04691859 0,-1.07371396 -3.1521,-0.28577416 -6.93069,1.73248789 -3.09382,1.652504 -0.61271,1.8571218 3.81265,0.3144307 l 0,0 z m 6.85154,-0.707599 c 0.59402,-1.78204068 -1.45248,-1.40757811 -2.14309,0.3921386 -0.37003,0.9642713 -0.14875,1.4169139 0.57476,1.1757426 0.64703,-0.2156762 1.35277,-0.9212228 1.56833,-1.5678812 z M 20.090948,0.80296239 c 0,-0.25829297 -1.366838,-1.17644278 -3.037417,-2.04033289 C 13.07504,-3.294728 10.77735,-2.5105441 14.645403,-0.41549494 17.561715,1.1640635 20.090948,1.729987 20.090948,0.80296239 z M 177.51669,-2.5818805 c 0,-1.2146632 -2.78939,-2.1897491 -3.40672,-1.1908861 -0.27491,0.444817 -0.21492,1.0936751 0.1333,1.4419069 0.94359,0.9435791 3.27342,0.7649164 3.27342,-0.2510208 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3784"
+ d="m 30.061595,110.24748 c -3.028002,-1.91623 -2.918962,-12.207625 0.161986,-15.288574 2.892806,-2.892806 5.380122,-2.029008 6.063557,2.105759 0.787072,4.761775 0.802973,10.540215 0.03451,12.542785 -0.657319,1.71294 -4.021187,2.05687 -6.260057,0.64003 l -1e-6,0 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3786"
+ d="m 50.118347,74.592462 c -5.270942,-3.20545 -6.839578,-11.64359 -3.245566,-17.458823 3.039395,-4.917846 5.720122,-5.336139 9.002245,-1.404685 3.776278,4.523372 4.477791,9.679447 1.982432,14.570755 -2.972944,5.82745 -4.145768,6.477996 -7.739111,4.292753 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3790"
+ d="m 77.269166,109.11407 c -1.309679,-0.76282 -1.732674,-2.30682 -1.732674,-6.32456 0,-2.923449 0.270441,-6.020121 0.600979,-6.881491 0.834308,-2.174169 4.068292,-1.961418 5.30478,0.348981 2.014054,3.7633 0.737507,14.00145 -1.732673,13.89637 -0.389257,-0.0166 -1.487442,-0.48424 -2.440412,-1.0393 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 95.007057,904.9113 c 0.385238,-1.18012 0.683001,-4.84283 0.661695,-8.13936 -0.06173,-9.55135 -4.374737,-15.76658 -10.814412,-15.58404 -5.717482,0.16207 -8.535426,3.73999 -10.755157,13.65574 -0.626384,2.79812 -0.743201,2.86169 -2.028503,1.10394 -0.750113,-1.02584 -1.658284,-3.82865 -2.018159,-6.22846 -1.123135,-7.48961 2.973013,-15.12663 11.054856,-20.61111 11.311099,-7.67592 28.226183,3.70958 28.110343,18.92101 -0.0477,6.25924 -7.5498,17.10293 -12.778543,18.47027 -1.827622,0.47794 -2.032399,0.25087 -1.43212,-1.58799 l 0,0 z"
+ id="path3811" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 94.321764,900.23842 c 0.440779,-7.8007 -1.648977,-15.10122 -4.806385,-16.79102 -2.930485,-1.56835 -7.745336,-1.13314 -9.760732,0.88226 -1.023579,1.02358 -2.637753,4.25377 -3.58705,7.17821 -2.213971,6.82044 -2.943207,7.53411 -4.782516,4.68044 -4.389237,-6.80986 -2.3875,-16.77788 4.760348,-23.70505 7.693856,-7.45631 12.8419,-8.44913 21.381841,-4.12357 6.43095,3.25734 11.22681,9.73104 12.24653,16.53101 0.55267,3.68549 0.22699,5.52969 -1.71763,9.72622 -2.915,6.29064 -8.884085,12.60416 -11.916536,12.60416 -2.117994,0 -2.195585,-0.29804 -1.81787,-6.98266 z"
+ id="path3813" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 68.414978,860.03275 c -0.666772,-7.1403 -2.690223,-11.43547 -6.846791,-14.53367 -5.043154,-3.75904 -10.684684,0.48966 -13.155593,9.90761 l -1.255316,4.78469 -1.58267,-3.68108 c -5.239415,-12.18615 4.528128,-27.50704 17.536589,-27.50704 7.815305,0 13.843009,3.85676 17.516265,11.20759 3.275573,6.55501 3.786297,11.93662 1.449429,15.27296 -0.835454,1.19278 -4.11466,4.166 -7.287125,6.60715 l -5.76812,4.43847 -0.606668,-6.49668 0,0 z"
+ id="path3815" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 49.437482,897.4003 c 0,-7.8807 -0.238746,-8.96321 -2.683838,-12.16889 -3.328287,-4.36361 -6.684995,-5.32335 -11.17181,-3.19422 -3.54658,1.68296 -7.43148,8.02415 -7.43148,12.13015 0,3.17404 -1.621904,2.63477 -2.873441,-0.95539 -3.317414,-9.51634 1.672723,-21.29378 11.117531,-26.23897 2.72797,-1.42833 2.917554,-1.35396 7.517619,2.94886 5.2492,4.91001 8.833683,7.00382 13.835848,8.08195 l 3.359934,0.72418 -0.622318,9.47391 c -0.670618,10.20921 -1.774486,12.37059 -8.280851,16.214 l -2.767194,1.63462 0,-8.6502 z"
+ id="path3817" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3819"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3821"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3823"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3825"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.75;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3827"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#808000;fill-opacity:1;stroke:#ffffff;stroke-width:0.75;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 152.87808,887.09306 c 2.45172,-2.38563 6.15239,-5.46679 7.25,-6.0363 0.54001,-0.28019 0.68775,-0.26331 1.08644,0.12413 0.44739,0.43476 0.43884,0.4601 -0.28084,0.83226 -0.40825,0.21112 -2.36023,1.65931 -4.33774,3.2182 -6.1869,4.87722 -7.48488,5.52718 -3.71786,1.86171 z"
+ id="path3839" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.75;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 150.59772,889.22362 c 0.34146,-0.63802 4.74908,-4.75071 7.28036,-6.79318 2.20817,-1.78177 2.84831,-2.02633 3.52712,-1.34752 0.47552,0.47551 0.41488,0.53183 -4.7711,4.43079 -5.22594,3.92899 -6.60832,4.7786 -6.03638,3.70991 z m 6.51167,-4.63037 c 4.41812,-3.32234 4.19708,-3.12358 3.69007,-3.31814 -0.25508,-0.0979 -0.81904,0.1386 -1.47931,0.62031 -1.56372,1.14083 -6.4108,5.36283 -6.42764,5.59874 -0.0198,0.27784 0.0923,0.20068 4.21688,-2.90091 z"
+ id="path3841" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.75;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 150.25496,889.66995 c -0.21097,-0.34135 1.7128,-2.34389 5.12184,-5.33156 3.7327,-3.27132 3.50343,-3.09344 4.55192,-3.53153 0.84073,-0.35128 0.95004,-0.34455 1.48868,0.0916 l 0.58133,0.47073 -0.49783,0.55012 c -0.52593,0.58118 -7.0647,5.54385 -9.33838,7.08746 -1.42832,0.96971 -1.66686,1.05263 -1.90756,0.66316 z m 9.40501,-7.41898 c 0.31112,-0.37715 0.29066,-0.38798 -0.21939,-0.1162 -0.58174,0.30998 -0.72499,0.53213 -0.34311,0.53213 0.12066,0 0.37378,-0.18716 0.5625,-0.41593 l 0,0 z"
+ id="path3843" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.75;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3845"
+ transform="translate(0,784.36218)" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.75;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 152.76002,892.43504 c 0.27118,-0.26502 1.89931,-1.23544 3.61806,-2.15648 1.71875,-0.92104 3.99303,-2.28424 5.05397,-3.02934 1.95389,-1.37224 4.19603,-3.43057 4.19603,-3.85205 0,-0.12665 0.28125,-0.23027 0.625,-0.23027 2.72931,0 -4.35573,5.77621 -10.78684,8.79417 -1.12026,0.52571 -2.29839,0.95583 -2.61806,0.95583 -0.57779,0 -0.57831,-0.003 -0.0882,-0.48186 z"
+ id="path3847" />
+ <rect
+ inkscape:transform-center-x="198.75"
+ ry="48.941685"
+ rx="36.744724"
+ transform="matrix(0.99994199,0.01077156,-0.00729569,0.99997339,0,0)"
+ y="635.47748"
+ x="20.799452"
+ height="136.85336"
+ width="186.18527"
+ id="rect3011"
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.80059099;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="Layer2">
+ <foreignObject x="15"
+ y="30" height="136.85336"
+ width="186.18527">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <div id='wordBubble' style="font-size:25px">Please help me find my Spaceship</div>
+ </body>
+ </foreignObject>
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien2.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien2.svg
new file mode 100755
index 0000000..bf6f73e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien2.svg
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="102"
+ height="210"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="alien1.svg">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <inkscape:perspective
+ id="perspective2899"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.8"
+ inkscape:cx="130.62808"
+ inkscape:cy="143.81068"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:snap-bbox="false"
+ inkscape:snap-global="false" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-842.36218)">
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18832552;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path2909" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18832552;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path2915" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18832552;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path2917" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18832552;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3707" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18832552;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3711" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18832552;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3715" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.68796229;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3776" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3778" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3788" />
+ <g
+ id="g3794"
+ transform="matrix(0.4951356,0,0,0.4951356,0.8682179,535.87135)">
+ <path
+ id="path2905"
+ d="m 53.60865,1035.3693 c 19.78288,-22.2017 22.20694,-25.4265 25.4678,-33.881 3.44722,-8.9377 6.40012,-18.24962 7.52938,-23.74392 0.82455,-4.01172 -0.36261,-5.08744 -5.63913,-5.10977 -1.99045,-0.008 -7.61545,-0.71148 -12.5,-1.56235 -16.50806,-2.87565 -23.91813,-6.30919 -33.99171,-15.75046 -6.08941,-5.70718 -7.43503,-7.50597 -7.19032,-9.61182 0.34346,-2.95569 -1.50714,-2.82651 22.80104,-1.59153 11.8285,0.60095 15.97106,0.42806 22.48438,-0.93836 4.39141,-0.92127 8.66641,-2.28625 9.5,-3.0333 0.83359,-0.74704 3.31562,-1.68728 5.51562,-2.08942 2.2,-0.40213 5.575,-1.60777 7.5,-2.6792 3.44034,-1.91485 3.44887,-1.93539 0.5,-1.2054 -5.17273,1.28051 -26.63042,1.59889 -36.0133,0.53435 -9.20812,-1.04471 -19.63226,-3.39275 -22.72313,-5.11837 -0.95503,-0.5332 -2.32888,-0.96945 -3.05299,-0.96945 -1.43857,0 -9.42912,-5.54027 -11.50725,-7.97859 -0.95343,-1.11868 -1.14843,-3.94422 -0.73666,-10.67412 l 0.56002,-9.15271 -4.54056,-5.31941 c -9.98832,-11.70162 -9.97623,-27.55255 0.0295,-38.68134 2.60206,-2.89412 6.36378,-5.77306 8.93031,-6.83458 l 4.43446,-1.83411 -0.57302,-6.13624 c -1.06496,-11.40449 5.13162,-23.48816 14.51299,-28.30109 l 3.58712,-1.84031 -5.95375,-5.92765 c -4.93512,-4.9135 -8.52008,-7.18312 -20.95375,-13.26571 -8.25,-4.03593 -15.17459,-7.48627 -15.38799,-7.66742 -0.21339,-0.18115 0.18259,-2.36727 0.87997,-4.85804 1.70691,-6.09651 3.20226,-5.96925 18.29995,1.55747 19.96216,9.95182 24.45018,13.11377 31.13538,21.93586 4.86767,6.42359 6.566,7.95536 9.5,8.56828 1.96498,0.41049 4.02269,0.60686 4.57269,0.43639 17.13317,-5.31045 33.409,-5.14223 47.77024,0.49372 4.94708,1.94144 5.21645,1.90161 6.52227,-0.96436 0.61245,-1.34418 5.43513,-7.16668 10.71706,-12.93889 7.18218,-7.84883 10.66081,-10.87865 13.79697,-12.01685 2.3064,-0.83706 9.11158,-3.33956 15.12261,-5.56111 6.01103,-2.22156 11.68966,-4.03919 12.61916,-4.03919 1.11859,0 1.89014,1.09888 2.28193,3.25 0.32555,1.7875 0.8733,4.21044 1.21722,5.38431 0.70713,2.41364 -0.93804,3.18343 -16.9864,7.94807 -8.24402,2.44759 -9.41386,3.13117 -15.04786,8.79297 -3.35991,3.37649 -7.99751,8.92014 -10.30579,12.31923 l -4.19687,6.18016 4.59822,3.7679 c 3.92224,3.21397 12.53592,13.3479 15.89124,18.69593 0.86818,1.38377 2.03676,1.46094 8.86473,0.5854 6.40489,-0.8213 8.72511,-0.72392 12.5,0.5246 8.01058,2.64945 13.40229,2.97743 17.21675,1.04728 5.01589,-2.53808 7.91852,-5.53295 7.91852,-8.17016 0,-1.91743 0.52663,-2.32569 3,-2.32569 l 3,0 0,7.36937 c 0,6.99889 -0.19005,7.61474 -3.78039,12.25 -2.07921,2.68435 -4.3555,6.00563 -5.05843,7.38063 -1.82398,3.56792 -4.05346,6.02517 -8.95417,9.86899 -2.36114,1.85194 -5.40785,5.56725 -6.77047,8.25624 -1.86654,3.68345 -4.04585,5.93033 -8.8376,9.11161 l -6.36013,4.22255 -1.16111,8.29999 c -3.24143,23.17077 -14.49635,42.93763 -31.7551,55.771 -4.30243,3.19923 -8.0341,5.98766 -8.29259,6.19652 -1.61876,1.30794 6.41126,11.58405 19.25766,24.64423 26.293,26.73057 27.51833,28.27367 30.82393,38.81727 3.56149,11.3598 3.62201,12.8116 0.53407,12.8116 -2.0739,0 -2.62572,-0.9231 -4.63288,-7.75 -1.25321,-4.2625 -3.12892,-9.4395 -4.16826,-11.5044 -1.03933,-2.065 -8.08103,-9.94 -15.6482,-17.5 -17.43517,-17.4188 -29.05724,-30.54815 -30.36702,-34.30539 -0.88138,-2.52833 -1.38534,-2.84102 -3.67537,-2.28044 -1.45967,0.3573 -2.80394,1.03003 -2.98727,1.49494 -0.18334,0.46491 -1.18057,0.84529 -2.21608,0.84529 -1.0355,0 -3.3605,0.6395 -5.16666,1.42112 -1.80616,0.78162 -5.98393,1.79412 -9.28393,2.25 l -6,0.82888 -0.64806,5 c -1.05452,8.13597 -10.19844,32.3753 -13.55944,35.9443 -1.06473,1.1306 -3.96423,4.5663 -6.44331,7.6348 -2.47909,3.0685 -5.37183,6.4995 -6.42831,7.6245 -1.05648,1.1249 -3.66664,3.9018 -5.80036,6.1708 -3.09032,3.2864 -4.58088,4.1256 -7.32754,4.1256 l -3.44807,0 4.67803,-5.25 z m 5.47706,-1.25 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 8,-9 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 6,-7 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 85,-12.8776 c 0,-0.2076 -0.7875,-0.9951 -1.75,-1.75 -1.58606,-1.2438 -1.62143,-1.2085 -0.37756,0.3776 1.30637,1.6657 2.12756,2.1955 2.12756,1.3724 z m -13,-11.9674 c 0,-0.1898 -1.0125,-1.2023 -2.25,-2.25 l -2.25,-1.905 1.90499,2.25 c 1.79022,2.1144 2.59501,2.7052 2.59501,1.905 z m -8,-9.00001 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11444 2.59501,2.70524 2.59501,1.90499 z m -41,-13.2644 c 0,-0.21482 -2.1375,-0.3837 -4.75,-0.37528 -2.69011,0.009 -4.21371,0.35593 -3.51336,0.80076 1.18245,0.75103 8.26336,0.38643 8.26336,-0.42548 z m -15.15913,-0.88305 c -0.27085,-0.27086 -4.50835,-1.18259 -9.41666,-2.02608 -16.13633,-2.77299 -23.51094,-5.97517 -33.27596,-14.44895 -7.06554,-6.13127 -6.84736,-7.42208 1.10175,-6.51825 3.4375,0.39085 6.025,0.48259 5.75,0.20387 -0.99658,-1.01006 -14.48194,-2.63618 -15.27608,-1.84205 -0.44842,0.44842 2.5534,3.97257 6.67071,7.83144 9.85626,9.23759 17.5018,12.85148 33.17531,15.68127 8.58267,1.54956 12.04547,1.89328 11.27093,1.11875 z m 23.7264,-0.47481 c 0.532,-0.532 2.7595,-1.3868 4.95,-1.89955 2.1905,-0.51275 3.08273,-0.97137 1.98273,-1.01914 -1.1,-0.0478 -4.7,0.76597 -8,1.80833 -4.87947,1.54126 -5.4304,1.91223 -2.95,1.98641 1.6775,0.0502 3.48527,-0.34405 4.01727,-0.87605 z m -1.06727,-3.56001 c 3.85,-1.06802 7.225,-2.19571 7.5,-2.50598 0.275,-0.31026 2.3,-1.09477 4.5,-1.74336 5.05158,-1.48926 15.57308,-8.30539 21.71998,-14.07082 10.15582,-9.52554 18.78406,-25.08183 22.17104,-39.97322 2.25857,-9.93017 2.17044,-11.34285 -0.64102,-10.27621 -1.2375,0.4695 -5.625,1.02086 -9.75,1.22525 -7.05688,0.34966 -7.51817,0.24412 -7.80748,-1.7863 -0.33071,-2.32087 0.30249,-2.55846 10.30748,-3.8677 11.1663,-1.4612 23.27502,-8.62225 26.61935,-15.74257 1.23176,-2.6225 3.84631,-5.98973 5.81011,-7.48272 4.73441,-3.59937 9.07054,-8.06924 9.07054,-9.35029 0,-1.14449 5.05979,-8.20389 6.26146,-8.73595 0.4188,-0.18544 1.19818,-1.15318 1.73195,-2.15053 0.8951,-1.67251 0.64174,-1.65381 -3.26146,0.24076 -7.22492,3.5069 -10.3032,3.77646 -18.61575,1.63013 -9.07215,-2.34246 -19.00256,-2.1397 -21.58295,0.44068 -0.92186,0.92186 -2.14171,1.67611 -2.71077,1.67611 -2.54552,0 -8.99433,6.52871 -10.95829,11.09406 -1.16076,2.69827 -2.46826,4.90594 -2.90555,4.90594 -1.95933,0 -3.95864,-1.33678 -3.95864,-2.64683 0,-3.08568 4.35596,-10.05283 8.7413,-13.98128 l 4.60821,-4.12811 -4.56124,-6.37189 c -5.99722,-8.37789 -13.41368,-15.23903 -16.69909,-15.44873 -3.96961,-0.25337 -4.08918,-0.31285 -4.08918,-2.03394 0,-1.26833 -0.37392,-1.14902 -1.75876,0.56119 -3.16363,3.90691 -6.71424,0.67043 -4.27159,-3.89369 0.85843,-1.60399 0.0269,-2.12345 -7.25,-4.52893 -6.21814,-2.0555 -10.28943,-2.73355 -16.71965,-2.78455 -7.5672,-0.06 -19,1.69411 -19,2.91514 0,0.25239 1.31647,2.12001 2.92548,4.15026 4.36394,5.50639 6.47105,13.04213 5.76399,20.6139 l -0.58664,6.28221 5.37473,1.20281 c 21.33616,4.77483 28.69937,31.92058 12.95469,47.75979 -10.80462,10.86949 -26.4913,11.06535 -37.48583,0.46803 l -4.92782,-4.74978 -3.2593,3.39483 c -5.79484,6.0358 -10.13838,7.70973 -20.0093,7.71121 -8.60158,10e-4 -8.75,0.0426 -8.75,2.43384 0,1.33789 -0.52005,3.87072 -1.15568,5.62851 -1.08586,3.00291 -0.94993,3.38302 2.25,6.29169 1.87313,1.70263 3.98611,3.10888 4.69552,3.12501 0.70941,0.0161 2.95941,0.87562 5,1.91 5.35714,2.71554 26.10725,6.12131 37.21074,6.10748 6.7425,-0.008 12.40095,-0.73394 19.49709,-2.5 12.81724,-3.18989 15.50356,-3.23117 15.49859,-0.23817 -0.005,3.2606 -3.59424,8.64665 -6.49672,9.75017 -1.37475,0.52268 -2.49954,1.41147 -2.49954,1.97508 0,0.56361 -0.48214,1.02475 -1.07143,1.02475 -0.58928,0 -1.74575,0.67432 -2.56993,1.4985 -0.82417,0.82417 -2.70453,1.76639 -4.17856,2.09382 -1.47404,0.32743 -4.04917,1.20489 -5.7225,1.94992 -7.22305,3.21595 -18.24045,4.55548 -34.98967,4.25415 l -16.47466,-0.29639 3.75338,3.2447 c 8.53728,7.38027 17.41711,11.11298 32.67758,13.73628 4.90831,0.84375 9.17851,1.7884 9.48934,2.09923 1.09734,1.09735 13.67539,-0.1903 20.58645,-2.10749 z m 40.5,-82.47272 c 0,-1.1 -0.45,-2 -1,-2 -0.55,0 -0.99978,-1.0125 -0.99951,-2.25 4.9e-4,-2.23828 6.86797,-9.01585 11.80351,-11.64897 3.22732,-1.72179 11.25861,-4.07728 13.946,-4.09021 3.59163,-0.0173 2.91267,4.08892 -1.25,7.55971 -1.925,1.60504 -3.5,3.40484 -3.5,3.99955 0,1.65254 -3.95602,4.90826 -9.49204,7.81174 -6.12107,3.21032 -9.50796,3.43052 -9.50796,0.61818 z m 9,-3.36173 c 4.30061,-2.42779 8,-5.65282 8,-6.97419 0,-0.54301 1.6875,-2.48922 3.75,-4.32491 2.0625,-1.83568 3.525,-3.33309 3.25,-3.32756 -1.50707,0.0303 -10.20077,3.05406 -12.64753,4.39899 -3.66433,2.0142 -12.18544,9.58314 -10.7927,9.5867 0.58287,0.001 3.43212,-2.0223 6.33165,-4.4973 5.24143,-4.474 9.10858,-5.78543 9.10858,-3.08889 0,1.84596 -4.51449,5.57987 -9.77988,8.08889 -2.30845,1.1 -4.20234,2.32338 -4.20865,2.71862 -0.0143,0.8945 2.43529,-0.01 6.98853,-2.58035 z m -35,84.31604 c 1.09546,-0.74131 0.69092,-0.83408 -1.5,-0.34401 -3.67693,0.82247 -4.47511,1.39483 -1.91667,1.37439 1.05417,-0.008 2.59167,-0.47209 3.41667,-1.03038 z m 6.427,-2.47578 c 2.91505,-2.20537 1.48811,-2.46248 -1.927,-0.34722 -1.65,1.02199 -2.325,1.84622 -1.5,1.83162 0.825,-0.0146 2.36715,-0.68258 3.427,-1.4844 z m 7.14043,-5.58763 c 0.37335,-0.6041 -0.50159,-0.32492 -1.94431,0.62038 -1.44271,0.94531 -2.62312,1.90782 -2.62312,2.13891 0,0.72338 3.85397,-1.6049 4.56743,-2.75929 z m 3.43257,-2.3909 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 6,-5 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -65.02348,-3.06139 c 4.11208,-0.85786 8.83708,-2.16527 10.5,-2.90536 1.66291,-0.74008 4.22952,-1.6135 5.70356,-1.94093 1.47404,-0.32743 3.28207,-1.19733 4.01785,-1.93311 0.73578,-0.73578 2.00475,-1.59958 2.81993,-1.91955 1.26954,-0.49832 1.25981,-0.59309 -0.0679,-0.66071 -0.8525,-0.0434 -2.0117,0.38275 -2.57599,0.94704 -1.37761,1.37761 -13.6602,5.81918 -19.87401,7.18674 -2.75,0.60523 -10.175,1.4011 -16.5,1.7686 l -11.5,0.66819 10,0.17442 c 5.89347,0.1028 13.07026,-0.46609 17.47652,-1.38533 z m 70.52348,-3.43861 c 0.99549,-1.1 1.58498,-2 1.30998,-2 -0.275,0 -1.31449,0.9 -2.30998,2 -0.99549,1.1 -1.58498,2 -1.30998,2 0.275,0 1.31449,-0.9 2.30998,-2 z m -39.74244,-12.00913 c 1.24166,-1.81999 2.07092,-3.49572 1.84281,-3.72384 -0.22812,-0.22811 -5.13023,0.74348 -10.89357,2.15911 -8.13994,1.99938 -13.01511,2.57386 -21.84222,2.57386 -12.97438,0 -33.27435,-3.17908 -39.07474,-6.11931 -2.04059,-1.03438 -4.29059,-1.85699 -5,-1.82803 -0.70941,0.029 0.84976,1.11449 3.46483,2.41228 11.06002,5.4888 45.285,8.38592 59.24533,5.01506 3.3,-0.79682 6.7875,-1.45579 7.75,-1.46438 2.46056,-0.022 2.17728,2.43675 -0.5,4.33963 l -2.25,1.59919 2.5,-0.82725 c 1.375,-0.45498 3.5159,-2.31633 4.75756,-4.13632 z m 48.7905,-2.0838 c 0.87968,-1.70111 1.42188,-3.27046 1.2049,-3.48744 -0.21698,-0.21698 -1.14288,1.17483 -2.05756,3.09293 -2.05658,4.3127 -1.34401,4.64239 0.85266,0.39451 z m -128.0536,-7.9132 c -0.99854,-1.10337 -2.04794,-1.77372 -2.33199,-1.48967 -0.28406,0.28406 0.35068,1.1725 1.41054,1.97433 2.70408,2.04576 3.04782,1.86496 0.92145,-0.48466 z m -1.82881,-15.83491 c 0.54476,-4.29796 0.58312,-4.33487 3.86431,-3.71932 1.87409,0.35158 3.58779,0.17886 3.944,-0.3975 0.36318,-0.58764 0.011,-0.78172 -0.83176,-0.45833 -1.53986,0.5909 -6.76761,-1.7051 -10.1422,-4.4544 -1.9801,-1.6132 -1.98121,-1.60721 -0.11164,0.60221 1.66468,1.96729 1.82292,3.38868 1.33592,12 -0.43762,7.73827 -0.35047,8.83317 0.41936,5.26838 0.53449,-2.475 1.21939,-6.45347 1.52201,-8.84104 z m 135.93852,5.11187 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m 1,-4 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m -78.41667,-2.95394 c -0.72187,-0.28887 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28494 0.60416,-0.60416 z m 79.46844,-3.58592 c -0.27393,-0.67703 -0.48137,0.11903 -0.46099,1.76903 0.0204,1.65 0.2445,2.20394 0.49804,1.23097 0.25354,-0.97297 0.23687,-2.32297 -0.0371,-3 z m -124.92497,2.57604 c -0.97296,-0.25354 -2.32297,-0.23687 -3,0.0371 -0.67703,0.27393 0.11903,0.48137 1.76903,0.46099 1.65,-0.0204 2.20394,-0.2445 1.23097,-0.49804 z m 41.5128,0.0286 c -0.69092,-0.27855 -1.07389,-0.80553 -0.85104,-1.17105 0.22285,-0.36552 -1.20295,-0.75058 -3.16844,-0.85567 -1.9655,-0.1051 -4.95753,-1.20361 -6.64896,-2.44115 -2.34922,-1.71881 -2.72116,-1.81335 -1.57533,-0.40044 1.81731,2.24089 8.73947,5.51042 11.5,5.43176 1.1,-0.0313 1.4347,-0.28489 0.74377,-0.56345 z m -32.38703,-2.26255 c 2.07738,-1.0598 4.4142,-2.7473 5.19293,-3.75 1.34843,-1.73625 1.32057,-1.74235 -0.58488,-0.12808 -1.10041,0.93226 -4.01766,2.60988 -6.48277,3.72804 -2.46511,1.11817 -3.90159,2.04291 -3.19218,2.05499 0.70941,0.0121 2.98952,-0.84515 5.0669,-1.90495 z m 47.01576,0.49285 c 1.52524,-0.78874 3.40764,-2.25124 4.1831,-3.25 1.33163,-1.71509 1.29982,-1.7257 -0.57283,-0.1911 -1.09052,0.89366 -3.33277,2.33815 -4.98277,3.20996 -1.65,0.87182 -2.64015,1.60314 -2.20034,1.62516 0.43982,0.022 2.04759,-0.60529 3.57284,-1.39402 z m -3.36392,-2.43092 c 7.61004,-3.45714 13.65809,-12.5947 13.65809,-20.63499 0,-11.12314 -11.04986,-22.7 -21.66667,-22.7 -10.70226,0 -21.66666,11.57813 -21.66666,22.87946 0,4.64065 3.02363,11.97613 6.07456,14.73719 1.78745,1.61762 1.83913,1.5186 1.37172,-2.62829 -1.45227,-12.88452 7.92692,-22.30909 15.08152,-15.15449 4.84657,4.84656 5.99347,17.1236 2.14795,22.99261 -1.93035,2.94608 -0.65228,3.07608 4.99949,0.50854 z m -53.08133,-2.28112 c 3.70718,-6.27576 1.47296,-18.7986 -3.64361,-20.42254 -4.73397,-1.50251 -8.98587,3.85239 -9.06867,11.42119 -0.0712,6.50478 0.82438,8.55477 4.54657,10.40756 4.71129,2.34514 6.08999,2.10771 8.16571,-1.40621 z m 8.76107,0.52566 c 1.47857,-0.7519 4.15313,-3.11185 5.94345,-5.24433 3.16416,-3.76887 3.25672,-4.14456 3.31169,-13.44187 l 0.0566,-9.56463 -3.42512,-0.64252 c -6.57739,-1.23384 -11.12219,-3.74493 -15.41056,-8.51464 l -4.3202,-4.8051 -3.93064,1.7598 c -7.58534,3.39606 -13.58015,12.55734 -13.58015,20.75322 0,4.42188 3.08834,12.18072 5.7167,14.36206 1.23314,1.02342 1.44997,0.46906 1.44997,-3.70719 0,-9.99193 6.09864,-17.05981 12.75,-14.7763 5.96164,2.04672 9.18113,14.88436 5.77636,23.03311 -1.44844,3.46661 -1.43562,3.51518 0.75,2.84119 1.223,-0.37713 3.43338,-1.30089 4.91195,-2.0528 z m 37.28108,-0.95627 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 66.2806,0.88741 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z m -84.75,-1.68823 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 37,-1.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -83,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 41.40581,-3.29696 c 1.26469,0.48531 1.32727,0.18279 0.38844,-1.87771 -0.61552,-1.35092 -1.24526,-2.33009 -1.39942,-2.17593 -0.15416,0.15416 -1.48307,2.06857 -2.95312,4.25423 l -2.67282,3.97393 2.56468,-2.37651 c 1.43852,-1.33299 3.22665,-2.12249 4.07224,-1.79801 z m 103.59419,2.7059 c 0,-0.53273 -0.675,-0.70959 -1.5,-0.39301 -0.825,0.31659 -1.5,0.75246 -1.5,0.96862 0,0.21615 0.675,0.39301 1.5,0.39301 0.825,0 1.5,-0.43588 1.5,-0.96862 z m -59.19313,-4.55784 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z m -46.2027,-6.20271 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 48,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 45,-5 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 50,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -96,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 95,-5 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58438 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.0789,-1.91667 z m 49.01374,-4.98626 c -0.12014,-0.12014 -1.54582,0.178 -3.16817,0.66254 -1.62236,0.48454 -2.16224,0.91966 -1.19974,0.96694 0.9625,0.0473 1.76595,0.87345 1.78544,1.83595 0.0268,1.32558 0.37079,1.14405 1.41817,-0.74849 0.76051,-1.37418 1.28444,-2.5968 1.1643,-2.71694 z m 42.50618,0.44876 c -0.98762,-0.98026 -1.10248,-0.8654 -0.5598,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30789,-0.30789 6.4e-4,-1.11479 -0.68278,-1.79313 z M 65.08571,861.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -85,-2.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 38.4694,-2.07674 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 6.58891,-0.87068 c 2.30641,-2.50217 6.01686,-5.17968 8.48316,-6.12157 3.50845,-1.33988 4.61401,-2.37208 5.53737,-5.16987 3.7517,-11.36776 -3.1423,-24.22022 -15.17695,-28.29436 -4.64464,-1.57236 -5.7447,-1.61747 -9.7859,-0.40124 -14.93589,4.49504 -21.66079,20.75015 -13.81981,33.40461 l 2.18716,3.52985 0.74099,-5.89906 c 1.49666,-11.91498 8.85142,-17.25247 15.12639,-10.9775 4.48246,4.48246 5.8535,13.25622 3.22323,20.62656 -0.73605,2.0625 -1.17556,3.75 -0.9767,3.75 0.19886,0 2.20634,-2.00134 4.46106,-4.44742 z m -19.14164,3.16445 c -0.22917,-0.15563 -1.31667,-0.94313 -2.41667,-1.75 -1.85,-1.35701 -1.89707,-1.33579 -0.62755,0.28297 0.75484,0.9625 1.84234,1.75 2.41667,1.75 0.57432,0 0.85672,-0.12734 0.62755,-0.28297 z m 24.08333,-3.21703 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.94528,-0.0659 c -1.51303,-1.82309 -6.92706,-4.78561 -7.57027,-4.1424 -0.24152,0.24152 0.91037,0.99812 2.55977,1.68132 1.6494,0.68321 3.51893,1.86878 4.15451,2.6346 0.63558,0.76583 1.3806,1.39242 1.6556,1.39242 0.275,0 -0.0848,-0.70467 -0.79961,-1.56594 z m -75.94528,-0.9341 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 17,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 35.91667,-3.2579 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m -46,-1 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m 5.95162,-1.75427 c -1.01049,-2.21779 -1.20856,-2.27175 -2.75296,-0.75 -1.54948,1.52676 -1.49021,1.68325 0.86027,2.27141 1.38842,0.34743 2.62726,0.68493 2.75297,0.75 0.1257,0.0651 -0.26142,-0.95706 -0.86028,-2.27141 z m 49.04838,0.74819 c 0.22917,-0.19715 -0.55833,-0.35846 -1.75,-0.35846 -1.38524,0 -2.17763,-0.63115 -2.19707,-1.75 -0.0265,-1.52656 -0.17522,-1.49464 -1.16454,0.25 -0.62377,1.1 -1.62259,2.32475 -2.21959,2.72166 -0.59701,0.39691 0.71453,0.44572 2.91453,0.10846 2.2,-0.33726 4.1875,-0.77451 4.41667,-0.97166 z m 72.08333,-1.88414 c 0,-1.39308 -3.70207,-0.18103 -4.79566,1.57008 -1.24992,2.00144 -1.21295,2.01141 1.75946,0.47432 1.66991,-0.86354 3.0362,-1.78352 3.0362,-2.0444 z m 29.1875,0.84257 c -0.72188,-0.28888 -1.58438,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -19.9375,-2.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -84.64583,-3.06689 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 122.39583,-2.04448 c 0,-0.85783 -0.12734,-1.37218 -0.28297,-1.14302 -0.15563,0.22917 -0.89428,1.21447 -1.64144,2.18956 -1.18269,1.54348 -1.14607,1.69139 0.28297,1.14301 0.90279,-0.34643 1.64144,-1.33173 1.64144,-2.18955 z M 82.68988,837.89013 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 65.39583,1.38416 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11445 2.59501,2.70524 2.59501,1.90499 z m -66.39583,-7.38416 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 60.39583,0.35161 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z M 79.2098,826.35263 c -0.98761,-0.98026 -1.10248,-0.8654 -0.55979,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30788,-0.30789 6.3e-4,-1.11479 -0.68279,-1.79313 z m 56.87591,0.88911 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -97,-4.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 53.22334,-1.87639 c -0.26254,-1.00396 -0.54753,-1.69503 -0.63331,-1.53571 -0.0858,0.15931 -0.6787,0.98073 -1.3176,1.82537 -0.93948,1.24202 -0.81836,1.53572 0.63331,1.53572 1.24538,0 1.6488,-0.55888 1.3176,-1.82538 z M 43.08571,819.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.75848,-0.53051 c -0.94115,-1.51852 -0.96737,-2.21193 -0.10397,-2.75 0.63498,-0.39572 -0.80847,-0.71949 -3.20766,-0.71949 l -4.36218,0 3.39287,1.74065 c 1.86608,0.95735 3.67359,2.19485 4.01668,2.75 0.3431,0.55514 0.82607,1.00935 1.07327,1.00935 0.24721,0 -0.11685,-0.91373 -0.80901,-2.03051 z m 52.17485,-0.31215 c -0.23833,-0.20679 -1.78333,-0.65233 -3.43333,-0.99008 -2.73596,-0.56005 -2.80197,-0.51498 -0.75,0.51213 1.2375,0.61943 2.25,1.59747 2.25,2.17342 0,0.65288 0.44557,0.60162 1.18333,-0.13614 0.65084,-0.65084 0.98834,-1.35253 0.75,-1.55933 z m 9.94836,-7.40734 c 2.30606,-3.4375 3.82136,-6.25 3.36733,-6.25 -1.81925,0 -11.24902,12.98428 -11.24902,15.48929 0,1.26984 3.89338,-3.29416 7.88169,-9.23929 z m -84.96502,4.11454 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35466 2.91667,-1.55517 z m 2.58333,-1.36454 c -0.33991,-0.55 -0.81647,-1 -1.05901,-1 -0.24254,0 -0.44099,0.45 -0.44099,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m 6.82946,-1.58385 c -0.33428,-0.87111 -0.88789,-1.20861 -1.23025,-0.75 -0.34236,0.45862 -1.02974,1.17135 -1.52751,1.58385 -0.49776,0.4125 0.0558,0.75 1.23025,0.75 1.53743,0 1.96511,-0.44346 1.52751,-1.58385 z m 20.85804,0.90074 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28495 0.60416,-0.60417 z m 29,0 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -22.9375,-0.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m 18,0 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -8.5,-1.02705 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z M 53.3824,808.21186 c -0.98818,-1.3241 -1.94149,-2.01468 -2.11847,-1.53464 -0.36611,0.99302 1.91319,3.8465 3.11847,3.90404 0.43818,0.0209 -0.0118,-1.04531 -1,-2.3694 z m -3.29669,-3.66948 c 0,-1.50044 -5.57099,-6.92308 -7.11248,-6.92308 -0.69649,0 0.5064,1.73277 2.67307,3.8506 4.69729,4.5914 4.43941,4.41292 4.43941,3.07248 z m 92,-3.42308 c 1.29175,-1.375 2.12363,-2.5 1.84863,-2.5 -0.275,0 -1.55688,1.125 -2.84863,2.5 -1.29175,1.375 -2.12363,2.5 -1.84863,2.5 0.275,0 1.55688,-1.125 2.84863,-2.5 z m 6.04469,-1.70523 c 2.56704,-3.19434 2.82393,-3.81616 1.06867,-2.58673 -1.89119,1.32465 -5.69179,6.79196 -4.72142,6.79196 0.15033,0 1.79407,-1.89235 3.65275,-4.20523 z m -0.0447,-8.71959 c 0,-0.275 -2.25,1.71617 -5,4.42482 -2.75,2.70865 -5,5.14982 -5,5.42482 0,0.275 2.25,-1.71617 5,-4.42482 2.75,-2.70865 5,-5.14982 5,-5.42482 z m 1,3.42482 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 21.91908,-7.85167 c 2.4305,-0.72671 4.0055,-1.56089 3.5,-1.85373 -0.50549,-0.29284 -2.71908,0.27521 -4.91908,1.26232 -4.84957,2.17594 -4.44469,2.34468 1.41908,0.59141 z m 6.88779,-1.17479 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z M 17.08571,783.6193 c -1.925,-1.05389 -3.95,-1.91617 -4.5,-1.91617 -0.55,0 0.575,0.86228 2.5,1.91617 1.925,1.05389 3.95,1.91617 4.5,1.91617 0.55,0 -0.575,-0.86228 -2.5,-1.91617 z m 160,-2 c 0,-0.55 -0.7875,-0.99311 -1.75,-0.98469 -1.49555,0.0131 -1.5319,0.15626 -0.25,0.98469 1.88721,1.21961 2,1.21961 2,0 z"
+ style="fill:#000000" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path2907"
+ d="m 72.6,181.20757 c -16.765609,-3.86833 -22.376319,-6.32293 -32,-13.9995 l -2,-1.59535 13.2,-0.0317 c 17.959636,-0.043 26.293525,-1.0427 36.676385,-4.39926 12.401975,-4.00929 20.661075,-10.22837 22.672535,-17.07236 1.39926,-4.76097 -0.60247,-5.05117 -14.284918,-2.07088 C 80.913403,145.51284 69.067454,145.46531 50.6,141.85286 39.54215,139.68982 28.750784,134.8087 27.432732,131.37391 c -0.409763,-1.06782 0.94297,-9.55504 1.67366,-10.50077 0.129162,-0.16717 4.118063,-0.56369 8.864224,-0.88115 9.677258,-0.64731 12.721718,-1.79467 18.59718,-7.00868 l 3.565638,-3.16423 4.911016,4.16615 c 6.374081,5.4073 11.045891,7.19552 18.75555,7.17903 10.247136,-0.0219 18.94097,-5.4255 24.01507,-14.92636 2.33003,-4.3628 2.74898,-6.0141 3.03751,-11.972478 0.24409,-5.040832 -0.0244,-7.992693 -0.99183,-10.905433 C 106.83021,74.235948 98.683943,66.74733 89.719703,64.844988 L 85,63.8434 84.966254,55.710271 C 84.929438,46.837023 83.908403,43.511262 79.05568,36.458071 76.206234,32.316543 75.915993,32.561487 85.4,31.103895 c 9.620682,-1.478597 19.97708,-0.291557 29.26619,3.354462 4.00483,1.571915 4.0652,1.646353 4,4.932693 -0.0764,3.849526 1.76499,4.910844 4.39333,2.532225 0.84726,-0.766762 1.54048,-1.021054 1.54048,-0.565095 0,0.45596 1.6637,1.247942 3.6971,1.759959 4.38748,1.10478 11.00212,7.029509 17.23538,15.437707 l 4.03312,5.440379 -4.6828,5.026303 c -4.55714,4.891416 -8.2828,11.01514 -8.2828,13.614092 0,1.528769 2.86706,3.239468 4.42637,2.641103 0.60573,-0.232443 1.86318,-1.915954 2.79432,-3.741133 2.17353,-4.260467 7.69681,-10.272278 10.77931,-11.732734 1.32,-0.625402 3.4424,-1.697018 4.71645,-2.381368 2.96143,-1.590728 11.65807,-1.536216 19.53585,0.122452 7.69091,1.619321 10.4686,1.555228 15.93996,-0.367797 5.65346,-1.987032 5.64225,-1.987649 3.63541,0.2 -0.90817,0.99 -3.01076,3.96 -4.67241,6.6 -1.66166,2.64 -5.30895,6.908849 -8.1051,9.486333 -2.79614,2.577483 -5.99227,6.236344 -7.1025,8.130802 -4.94788,8.442912 -15.3818,14.634562 -28.34766,16.821932 -7.93582,1.33879 -10.1786,2.49921 -9.29263,4.80802 0.46879,1.22165 1.5792,1.32779 10.18353,0.97342 l 9.65736,-0.39773 -0.5479,3.65369 c -1.59381,10.62824 -7.28652,24.58268 -14.24705,34.92353 -11.30309,16.79232 -34.07569,29.48213 -55.75331,31.06798 -4.998646,0.36568 -7.935952,-0.008 -17.6,-2.23755 z m 81.50924,-82.494134 c 3.52664,-1.764307 6.56239,-3.962996 7.90749,-5.727124 1.2008,-1.574879 3.53327,-4.37647 5.18327,-6.225757 1.93865,-2.172795 3,-4.147985 3,-5.583022 0,-2.220043 -0.002,-2.220533 -4.38306,-1.705537 -8.74931,1.028309 -19.06055,6.827181 -22.74752,12.792833 l -1.71519,2.775229 1.70366,3.268542 c 2.14696,4.11903 3.52613,4.16955 11.05135,0.404836 l 0,0 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path2913"
+ d="m 160.6,87.334076 c 0,-0.534851 -1.1468,-0.981516 -2.6,-1.012667 -2.30544,-0.04942 -2.02164,-0.279224 2.50495,-2.028386 2.80772,-1.084959 5.23233,-1.845272 5.38801,-1.689584 0.15569,0.155688 -0.97154,1.499081 -2.50494,2.98532 C 161.85461,87.074997 160.6,87.86039 160.6,87.334076 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3703"
+ d="m 24.692801,119.04257 c -0.05104,-2.05401 -0.313955,-4.31089 -0.584255,-5.01528 -0.431011,-1.12319 -0.185552,-1.10664 1.99579,0.13457 1.631194,0.92818 2.07587,1.50427 1.292,1.67384 -0.657385,0.1422 -1.361474,1.0422 -1.564643,2 -0.203169,0.95779 -0.521653,2.46144 -0.707744,3.34144 -0.186091,0.88 -0.380107,-0.0805 -0.431148,-2.13457 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3709"
+ d="m 104.6,146.52914 c 0,-0.55196 -0.79531,-1.29776 -1.76736,-1.65735 -1.56978,-0.5807 -1.42649,-0.71774 1.28174,-1.2258 3.83551,-0.71955 4.4795,-0.10717 2.24118,2.13115 -1.00812,1.00812 -1.75556,1.32829 -1.75556,0.752 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3719"
+ d="m 76.851058,112.03382 c -3.393188,-2.09142 -4.25448,-3.92327 -4.233488,-9.00408 0.03274,-7.923733 4.577488,-13.887568 8.633406,-11.329161 3.986638,2.514706 5.541626,13.083911 2.747781,18.676561 -1.667169,3.3373 -3.668438,3.80115 -7.147699,1.65668 l 0,0 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3721"
+ d="m 31.011129,112.18685 c -3.337597,-1.68708 -4.784967,-4.28598 -4.794874,-8.60971 -0.01706,-7.444764 3.322321,-12.761965 7.700427,-12.261175 5.345895,0.611491 7.922362,14.073845 3.761169,19.652565 -2.071377,2.777 -3.181718,2.97991 -6.666722,1.21832 z"
+ style="fill:#00d37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3747"
+ d="M 49.694395,74.66073 C 44.47115,71.825511 44.018691,61.3525 48.893397,56.120117 c 1.243238,-1.334459 2.71535,-2.426289 3.27136,-2.426289 3.274952,0 7.59925,10.034368 6.191417,14.366947 -2.961401,9.11366 -3.406311,9.452665 -8.661779,6.599955 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3749"
+ d="m 30.863598,109.87939 c -4.598088,-3.22062 -2.443473,-16.412835 2.680623,-16.412835 3.343974,0 5.248203,11.238065 2.708365,15.983795 -1.423064,2.65902 -2.125412,2.71494 -5.388988,0.42904 l 0,0 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3751"
+ d="M 53.409091,253.22727 C 175,254.36364 176.13636,254.36364 176.13636,254.36364"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3753"
+ d="m 101.91757,251.70568 c -21.718752,-0.17272 -39.488638,-0.58449 -39.488638,-0.91506 0,-0.33057 3.818082,-4.96825 8.484628,-10.30595 4.666545,-5.33771 9.973982,-12.85892 11.794303,-16.71379 3.448266,-7.30236 8.521552,-22.38453 9.820557,-29.19514 0.752563,-3.94565 0.76643,-3.95339 12.3156,-6.87496 6.3592,-1.60867 12.35971,-3.28795 13.33446,-3.73173 1.29391,-0.58909 2.73131,0.66046 5.32536,4.62941 1.9542,2.98995 11.57847,13.87378 21.38726,24.18628 9.8088,10.3125 18.96093,20.28409 20.33807,22.15909 2.01779,2.74727 7.42703,15.23542 7.42703,17.14657 0,0.25689 -7.03125,0.34607 -15.625,0.19819 -8.59375,-0.14789 -33.39488,-0.4102 -55.11363,-0.58291 l 0,0 z"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3782"
+ d="m 51.774116,254.22272 c 0.816832,-1.01161 5.399709,-6.3219 10.184171,-11.80065 4.784463,-5.47875 10.255577,-12.2121 12.158031,-14.963 5.284789,-7.64167 14.376394,-33.83808 12.993969,-37.44062 -0.338967,-0.88334 -2.48378,-1.73514 -5.328004,-2.116 C 60.981864,185.11713 50.75895,182.31448 43.625018,177.44148 37.971557,173.57975 28.01174,163.28381 28.01174,161.3013 c 0,-1.83865 0.635315,-1.8844 17.079208,-1.22988 19.475363,0.77518 28.155408,-0.12388 38.075567,-3.94376 9.279191,-3.57307 15.45203,-6.36285 15.01445,-6.78568 -0.201984,-0.19518 -4.599918,0.0895 -9.773185,0.63261 -15.856397,1.66468 -37.875872,-0.52821 -50.869606,-5.06603 -3.201056,-1.11791 -7.99066,-3.68786 -10.643565,-5.71099 l -4.823463,-3.67842 0.178374,-9.45002 0.178374,-9.45001 0.5642,7.42574 c 0.582301,7.66397 1.29799,8.16822 2.459224,1.73268 0.423991,-2.34976 0.289983,-3.71287 -0.365011,-3.71287 -0.569229,0 -1.034963,-1.33664 -1.034963,-2.9703 0,-1.63367 -0.407778,-2.9703 -0.906174,-2.9703 -1.708089,0 -9.947718,-12.02652 -11.073528,-16.16286 C 8.4406212,86.620448 14.328838,72.981775 26.509135,66.520142 l 4.472902,-2.372869 0,-7.169297 c 0,-11.907876 4.934342,-21.608335 13.56406,-26.665688 2.388815,-1.399939 4.1792,-3.048653 3.978634,-3.66381 C 47.539733,23.627398 33.787529,13.942425 21.173642,7.3865059 6.6394252,-0.16748247 5.7525435,-1.0667564 8.2445952,-5.7231976 9.9048868,-8.825481 13.26451,-8.0142814 26.786199,-1.2462239 42.52818,6.6331633 49.704459,11.834699 56.658674,20.406047 c 7.066894,8.71023 9.386734,9.398438 22.022822,6.533328 12.009438,-2.723024 25.519864,-2.231151 36.616764,1.3331 4.17096,1.339683 7.95921,2.16177 8.41835,1.826861 0.45913,-0.33491 2.70455,-3.059423 4.98981,-6.054473 2.28526,-2.995049 7.42528,-8.682601 11.42226,-12.639003 7.12067,-7.0483759 7.54019,-7.2929957 20.80065,-12.12871266 7.44339,-2.71438994 14.38913,-4.93525434 15.435,-4.93525434 1.40526,0 2.17641,1.0827118 2.95451,4.1481669 0.5791,2.28149179 0.85167,4.4737776 0.60572,4.871746 -0.24596,0.3979683 -6.12349,2.612099 -13.0612,4.92029 -12.32753,4.1014041 -12.76057,4.3449071 -19.06805,10.7223141 -3.54973,3.589081 -8.19833,9.098685 -10.33023,12.243564 l -3.87618,5.717962 4.38964,4.574292 c 2.4143,2.515859 3.60993,4.300819 2.65696,3.966577 -2.15679,-0.756469 -2.25789,0.631979 -0.17206,2.363061 1.27233,1.05594 1.70648,1.059167 2.35028,0.01747 0.5549,-0.897844 2.45839,0.813688 6.40236,5.756734 3.08697,3.868951 6.15063,7.065929 6.80813,7.104394 0.6575,0.03847 4.65679,0.0099 8.8873,-0.0634 4.23053,-0.07334 11.0745,0.619228 15.20883,1.53903 6.08457,1.353687 8.24222,1.455077 11.32293,0.532074 4.78641,-1.434041 9.61096,-5.430654 10.01889,-8.299556 0.1988,-1.398101 1.12005,-2.308693 2.53968,-2.510314 2.12619,-0.301966 2.22772,-0.004 2.22772,6.538442 0,6.740641 -0.099,7.001552 -5.9449,15.662921 -3.26969,4.844452 -7.74462,10.309246 -9.94428,12.143987 -2.19966,1.834742 -5.77393,5.949037 -7.94282,9.142879 -2.34976,3.460168 -6.29513,7.465423 -9.76248,9.910673 l -5.81903,4.10369 -1.15924,7.92805 c -1.61723,11.06032 -4.40347,19.58965 -9.70377,29.70553 -5.01528,9.57187 -13.95714,20.46445 -14.03497,17.09676 -0.0428,-1.8524 -0.1273,-1.86246 -1.77762,-0.21171 -1.37485,1.3752 -1.46515,1.89852 -0.43722,2.53406 1.41537,0.87508 -1.77232,4.09197 -9.46671,9.55344 -2.27836,1.61719 -4.34463,3.44333 -4.59171,4.0581 -0.8189,2.03758 6.19452,11.05322 18.90021,24.29583 6.90108,7.19272 12.04414,13.24542 11.42903,13.45046 -0.61512,0.20504 -0.83848,1.12371 -0.49637,2.0415 0.34212,0.91778 -1.79925,-0.97306 -4.75858,-4.20188 -2.95935,-3.22881 -5.27705,-6.21281 -5.15046,-6.6311 0.12659,-0.41828 -1.76241,-2.39328 -4.19777,-4.38889 -2.43538,-1.9956 -4.20453,-3.98988 -3.93146,-4.43172 0.27308,-0.44185 -1.40227,-2.36965 -3.72301,-4.28402 -2.32073,-1.91436 -5.99559,-5.73898 -8.16635,-8.49916 -4.50513,-5.7284 -5.73975,-6.34273 -10.18478,-5.06791 -1.75731,0.50399 -3.19511,0.54209 -3.19511,0.0847 0,-1.33295 -11.17951,1.64109 -12.389579,3.29596 -0.60449,0.82669 -2.322383,1.8101 -3.817542,2.18536 -3.551652,0.89142 -4.937215,3.23379 -7.580515,12.81533 -4.406767,15.97381 -11.099683,29.94917 -15.20688,31.75323 -1.152028,0.50601 -2.096442,1.7759 -2.098696,2.82193 -0.0024,1.08338 -1.280677,2.61084 -2.970297,3.54913 -1.631409,0.90597 -2.982805,2.27784 -3.003103,3.04859 -0.05664,2.15103 -3.526894,6.90294 -4.570213,6.25813 -0.985639,-0.60915 -3.808724,1.30636 -3.808724,2.5843 0,1.92758 5.895059,2.34928 41.089109,2.93925 l 37.62376,0.63071 -39.232671,0.18757 c -21.57797,0.10316 -40.736386,0.48547 -42.574257,0.84959 -3.159411,0.62595 -3.260618,0.56176 -1.856436,-1.17724 z m 42.238485,-67.99171 c -1.942887,-0.70765 -3.471758,-0.70422 -4.950495,0.0112 -1.790743,0.86631 -1.332552,1.03319 2.81102,1.02385 4.566697,-0.0103 4.732564,-0.0905 2.139475,-1.03501 l 0,-3e-5 z m -14.020663,-0.82863 c -1.089109,-0.4866 -6.435644,-1.80129 -11.881188,-2.92155 -5.759121,-1.18476 -12.800298,-3.45953 -16.831683,-5.43774 -6.954731,-3.41271 -17.742094,-11.92119 -16.880858,-13.3147 0.253072,-0.40948 3.040932,-0.57204 6.195246,-0.36125 4.48988,0.30005 5.355073,0.14443 3.984772,-0.71671 -0.96269,-0.60499 -4.913826,-1.36519 -8.780302,-1.68935 -6.863409,-0.57539 -7.004171,-0.54119 -5.941584,1.44428 2.200044,4.11082 13.668199,13.46069 20.585236,16.78294 7.129107,3.42411 21.632479,7.0912 28.065212,7.09613 2.851296,0.002 3.114461,-0.15412 1.485149,-0.88205 z m 13.55198,-1.63782 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52001 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 8.981792,-3.22305 c 4.1272,-1.05557 9.34757,-2.85973 11.60083,-4.00925 2.25325,-1.14953 4.87457,-1.8432 5.82513,-1.54151 0.95056,0.30171 2.59602,-0.12295 3.65656,-0.94367 1.60041,-1.23851 1.63367,-1.38963 0.19559,-0.88881 -2.84772,0.99172 -1.97918,-0.17229 2.18456,-2.92772 2.15449,-1.42577 4.50534,-2.36663 5.22413,-2.09081 0.7188,0.27584 3.05637,-1.2901 5.1946,-3.47985 2.13823,-2.18975 3.51995,-3.98136 3.07047,-3.98136 -0.44946,0 -0.26663,-0.66342 0.4063,-1.47425 0.67294,-0.81083 1.5681,-1.26129 1.98925,-1.001 0.42114,0.26029 1.37313,-0.30156 2.11553,-1.24853 1.22149,-1.55808 1.18509,-1.59258 -0.38286,-0.36292 -0.95297,0.74738 -1.73267,0.91332 -1.73267,0.36877 0,-1.1032 2.94273,-3.80059 3.86504,-3.5428 0.32472,0.0908 0.81317,-0.0921 1.08545,-0.40626 0.27228,-0.3142 -0.0619,-0.25079 -0.74257,0.14094 -1.83418,1.05552 -1.52708,0.0245 1.35025,-4.53358 3.80038,-6.02017 8.15245,-16.13427 10.34121,-24.03269 2.90781,-10.4932 3.24131,-10.00199 -6.51584,-9.59724 -8.06376,0.33451 -11.36374,-0.51104 -11.36374,-2.91169 0,-1.41219 3.87705,-3.01077 12.01762,-4.9551 13.6173,-3.2524 18.1279,-6.30458 30.44942,-20.604205 3.20647,-3.721241 5.60795,-5.75908 6.01348,-5.102907 0.45242,0.732027 1.17307,0.513084 2.18435,-0.663636 2.69435,-3.135129 3.29702,-4.863342 0.99046,-2.840244 -1.18271,1.037369 -2.15038,1.440581 -2.15038,0.896027 0,-1.154396 3.94299,-4.919356 4.6419,-4.432319 0.26048,0.181519 0.77064,-0.0013 1.13367,-0.406262 0.36304,-0.404963 0.10314,-0.415797 -0.57755,-0.02408 -1.80598,1.039294 -1.51814,-0.190163 0.80999,-3.459724 2.31999,-3.258114 2.32271,-3.256657 -3.39724,-1.816357 -3.2192,0.810603 -6.66348,0.694459 -14.67251,-0.494768 -15.04707,-2.234274 -20.55437,-0.689621 -28.57683,8.015049 -2.42602,2.632325 -4.72907,4.680174 -5.11788,4.550775 -0.38882,-0.129399 -0.48449,0.344426 -0.2126,1.052946 0.27188,0.70852 -0.4282,2.123094 -1.55573,3.143497 -2.0095,1.818571 -2.09324,1.812104 -4.23219,-0.326854 l -2.18214,-2.182131 2.25594,-4.252496 c 1.24077,-2.338872 4.17354,-6.452573 6.51728,-9.141556 2.34372,-2.688985 4.05061,-5.50801 3.79308,-6.264503 -0.31259,-0.918192 -0.0455,-1.114196 0.80328,-0.589595 0.85837,0.530499 1.02875,0.393018 0.52435,-0.423105 -0.41094,-0.664922 -0.99572,-0.9604 -1.2995,-0.656618 -0.69266,0.69266 -3.20978,-1.330935 -3.20978,-2.580451 0,-0.510014 0.51439,-0.609392 1.14308,-0.220837 0.73045,0.451439 0.87336,0.270048 0.3959,-0.50249 -0.41094,-0.664922 -1.00055,-0.955563 -1.31024,-0.645868 -0.69833,0.698319 -4.18913,-2.365165 -4.18913,-3.67632 0,-0.526833 0.7797,-0.370613 1.73267,0.347155 0.95297,0.717767 -0.70223,-1.23225 -3.67822,-4.333371 -3.76003,-3.918124 -5.93501,-5.472057 -7.12873,-5.093182 -0.94481,0.299873 -3.07003,-0.15402 -4.7227,-1.00865 -2.43778,-1.26062 -3.37289,-1.324035 -4.95495,-0.33602 -2.36555,1.477307 -3.05981,0.886 -3.92467,-3.34268 -0.56625,-2.768728 -1.37248,-3.513567 -5.43639,-5.022464 -7.80616,-2.898363 -17.966683,-4.011606 -26.200113,-2.870631 -3.997279,0.553936 -7.475959,1.215337 -7.730402,1.469779 -0.254442,0.254443 0.998085,3.050852 2.783393,6.214244 2.874608,5.093525 3.291609,6.794112 3.644505,14.862796 l 0.398492,9.111176 3.564442,0.668693 c 7.773644,1.458345 16.010573,8.110583 19.620143,15.845464 3.09701,6.636514 3.26024,18.338664 0.34238,24.546143 -2.99996,6.38214 -7.1277,10.84757 -13.007325,14.07144 -4.530381,2.48406 -6.383854,2.90835 -12.728271,2.91366 -6.074888,0.005 -8.236255,-0.44332 -11.881188,-2.465 -2.450495,-1.35916 -4.455445,-2.98232 -4.455445,-3.60701 0,-0.62469 -0.40559,-1.50708 -0.901312,-1.96089 -0.523658,-0.47936 -0.602889,-0.3065 -0.189092,0.41255 0.391721,0.68069 0.309434,1.23762 -0.182859,1.23762 -1.220735,0 -4.304298,-3.49834 -3.655466,-4.14718 0.286625,-0.28662 -0.191905,-1.11291 -1.063399,-1.83618 -1.321234,-1.09653 -1.725666,-1.0867 -2.433844,0.0592 -0.46712,0.75582 -0.647589,1.7006 -0.401041,2.09952 0.480206,0.77699 -4.431607,4.73002 -8.49972,6.84057 -1.361386,0.7063 -6.473966,1.77939 -11.361289,2.38466 l -8.886042,1.10047 -0.8419,4.2572 c -1.116431,5.64542 -0.634772,6.55826 4.953601,9.38814 6.711939,3.39884 14.108367,5.45589 25.541571,7.10346 13.412147,1.93275 20.966236,1.82034 33.743152,-0.50211 17.901519,-3.25395 20.945769,-2.59407 18.234109,3.95245 -1.77158,4.27697 -8.27108,9.72932 -15.51118,13.01214 -10.066949,4.56456 -20.604188,6.60666 -38.045678,7.37316 -12.034826,0.52888 -15.515628,0.97079 -14.765554,1.87458 0.53979,0.65041 0.751763,1.41223 0.47105,1.69294 -0.280712,0.28071 0.280084,1.1308 1.246214,1.8891 1.597283,1.25367 1.633357,1.22157 0.397743,-0.35396 -1.901096,-2.42408 -0.973659,-2.18092 4.907357,1.28665 4.510039,2.65922 13.386837,5.60901 26.15447,8.69123 6.758464,1.63156 18.458956,1.2966 26.494168,-0.75846 l 0,-4e-5 z m 15.58504,-0.061 c 1.16161,-0.7507 0.90473,-0.96308 -1.17919,-0.97494 -1.46538,-0.008 -2.9397,0.43038 -3.27626,0.97494 -0.78135,1.26425 2.49915,1.26425 4.45545,0 z m 6.00568,-2.01503 c 1.95644,-1.04706 2.62207,-2.93547 1.0347,-2.93547 -0.48422,0 -1.93224,0.87627 -3.21783,1.94726 -2.49465,2.07826 -1.06383,2.72592 2.18313,0.98821 z m -6.00568,-1.45032 c 1.36139,-0.77824 2.0297,-1.41498 1.48515,-1.41498 -0.54456,0 -2.10396,0.63674 -3.46535,1.41498 -1.36138,0.77824 -2.0297,1.41498 -1.48515,1.41498 0.54456,0 2.10396,-0.63674 3.46535,-1.41498 z m -62.458746,0.13411 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553336,0.36093 1.577225,1.26362 4.799862,2.3676 3.441125,1.17883 l 0,0 z m 74.762706,-3.12566 c 1.04936,-0.7939 1.64445,-1.70691 1.32243,-2.02893 -0.78266,-0.78265 -4.7155,1.36919 -4.7155,2.58006 0,1.33049 1.15362,1.1431 3.39307,-0.55113 z m 5.3845,-4.97977 c 0.31295,-1.61495 0.14607,-1.68767 -1.23763,-0.53929 -1.89234,1.57049 -2.12795,3.40609 -0.36172,2.81801 0.68069,-0.22665 1.40039,-1.25207 1.59935,-2.27872 z m -93.926084,0.17176 c 0,-0.2056 -0.779703,-0.9853 -1.732673,-1.73268 -1.570353,-1.23155 -1.605372,-1.19653 -0.373817,0.37382 1.293435,1.64926 2.10649,2.17375 2.10649,1.35886 z m 42.048957,-9.0646 c 10.23476,-3.01561 12.830661,-4.22882 16.665417,-7.78864 1.52559,-1.41621 3.14513,-2.57492 3.599,-2.57492 0.45387,0 1.59099,-1.16873 2.52694,-2.59715 0.93594,-1.42844 1.24801,-2.31675 0.69349,-1.97403 -0.55454,0.34271 -1.20807,0.0635 -1.45231,-0.62067 -0.24423,-0.68409 -0.82632,-0.88541 -1.2935,-0.44739 -0.46721,0.43803 -0.19404,1.21091 0.60702,1.71751 1.25252,0.79212 1.23533,0.92323 -0.12275,0.93627 -0.86857,0.008 -2.42798,0.95441 -3.46535,2.10238 -5.028165,5.56424 -22.795527,11.3182 -38.212356,12.37508 -15.799597,1.08311 -17.048668,2.42489 -1.792578,1.92561 10.641937,-0.34827 15.176438,-0.97076 22.246977,-3.05405 l 0,0 z m 63.891637,-3.12611 c 0,-1.41552 -0.23243,-1.39342 -1.9802,0.18829 -1.08911,0.98563 -1.9802,2.18422 -1.9802,2.66353 0,0.47932 0.89109,0.39459 1.9802,-0.18828 1.08911,-0.58287 1.9802,-1.78147 1.9802,-2.66354 z M 97.166642,146.77097 c 3.547598,-0.77002 4.965228,-1.47727 4.298178,-2.14431 -0.66706,-0.66706 -4.175166,-0.42281 -10.636358,0.74056 -14.897153,2.68229 -37.124591,0.77195 -52.477337,-4.51017 -6.578027,-2.26317 -6.378989,-2.22908 -6.378989,-1.09252 0,1.42916 9.008565,4.85904 15.926311,6.06371 16.965213,2.95437 38.134158,3.35943 49.268195,0.94273 l 0,0 z m 53.617378,0.0462 c 0.58287,-1.08911 0.837,-1.9802 0.56472,-1.9802 -0.27228,0 -0.97195,0.89109 -1.55482,1.9802 -0.58287,1.08911 -0.837,1.9802 -0.56472,1.9802 0.27227,0 0.97195,-0.89109 1.55482,-1.9802 z m 5.94059,-4.62356 c 0,-2.3135 -1.69554,-0.59965 -2.85822,2.88907 l -1.073,3.21964 1.96562,-2.33741 c 1.08108,-1.28558 1.9656,-2.98266 1.9656,-3.7713 z m -77.497329,2.91089 c -2.054226,-0.21433 -5.173038,-0.21074 -6.930694,0.008 -1.757656,0.21872 -0.07693,0.39409 3.734955,0.38969 3.811881,-0.004 5.249963,-0.18335 3.195739,-0.39768 l 0,7e-5 z m 10.356241,-0.94387 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52002 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 19.616338,-1.30386 c 0,-0.54455 -0.47184,-0.99009 -1.04854,-0.99009 -0.57669,0 -0.77316,0.44554 -0.43661,0.99009 0.33655,0.54456 0.8084,0.9901 1.04853,0.9901 0.24014,0 0.43662,-0.44554 0.43662,-0.9901 z m 47.45458,-8.41584 c 0,-0.54455 -0.63674,0.12377 -1.41498,1.48515 -0.77823,1.36139 -1.41498,2.92079 -1.41498,3.46535 0,0.54455 0.63675,-0.12376 1.41498,-1.48515 0.77824,-1.36139 1.41498,-2.92079 1.41498,-3.46535 z M 28.453542,136.6394 c -0.717346,-1.86938 -3.412099,-3.08084 -3.412099,-1.53397 0,1.05715 3.177874,3.9134 3.73462,3.35666 0.149813,-0.14981 0.0047,-0.97003 -0.322521,-1.82269 z m 6.406383,0.90594 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553337,0.36093 1.577226,1.26362 4.799863,2.3676 3.441126,1.17883 z m -8.178941,-9.80642 c -0.27121,-0.67032 -0.476602,0.11785 -0.456423,1.75152 0.02018,1.63366 0.242077,2.18212 0.493111,1.21878 0.251032,-0.96334 0.234523,-2.29997 -0.03668,-2.9703 l -4e-6,0 z M 162.66521,127.0736 c 0,-0.51242 -0.44555,-1.20703 -0.9901,-1.54359 -0.54456,-0.33655 -0.9901,0.0827 -0.9901,0.93167 0,0.84897 0.44554,1.54358 0.9901,1.54358 0.54455,0 0.9901,-0.41925 0.9901,-0.93166 z M 27.619826,122.33281 c -0.329002,-0.329 -0.563011,0.25579 -0.52002,1.29951 0.0475,1.15341 0.28212,1.38802 0.598185,0.59819 0.286011,-0.71474 0.250836,-1.5687 -0.07817,-1.8977 l 3e-6,0 z m 136.035474,0.2269 c 0,-0.81683 -0.44554,-1.48514 -0.99009,-1.48514 -0.54456,0 -0.9901,0.66831 -0.9901,1.48514 0,0.81684 0.44554,1.48515 0.9901,1.48515 0.54455,0 0.99009,-0.66831 0.99009,-1.48515 z M 33.704809,119.40196 c -0.95297,-0.24903 -2.512376,-0.24903 -3.465346,0 -0.952971,0.24904 -0.173268,0.4528 1.732673,0.4528 1.905941,0 2.685644,-0.20376 1.732673,-0.4528 z m 51.237624,-0.30759 c 0.336553,-0.54456 -0.250915,-0.9901 -1.305483,-0.9901 -1.054569,0 -2.472053,-0.66832 -3.149963,-1.48515 -0.677909,-0.81683 -2.197663,-1.48515 -3.37723,-1.48515 -1.179567,0 -3.798279,-0.84306 -5.819362,-1.87346 -3.979476,-2.02885 -4.801958,-1.43381 -1.788124,1.29368 1.984228,1.7957 10.984716,4.90909 10.984716,3.79975 0,-0.35514 0.534654,-0.11106 1.188119,0.54241 1.44777,1.44777 2.457132,1.50894 3.267327,0.19802 z m 79.702967,-3.02873 c 0,-1.05697 -0.44554,-1.92177 -0.9901,-1.92177 -0.54455,0 -0.99009,1.14016 -0.99009,2.53369 0,1.43699 0.42855,2.26881 0.99009,1.92176 0.54456,-0.33656 0.9901,-1.47671 0.9901,-2.53368 z m -126.008939,1.3525 c -0.963334,-0.25103 -2.299968,-0.23452 -2.970297,0.0366 -0.670329,0.27122 0.117853,0.47661 1.751517,0.45643 1.633663,-0.0202 2.182114,-0.24208 1.21878,-0.49311 l 0,5e-5 z m 15.788583,-6.49209 c 2.961802,-2.58663 6.027485,-4.70297 6.812628,-4.70297 1.653245,0 1.836694,-1.82146 0.39887,-3.96039 -0.83888,-1.24794 -1.390264,-1.01072 -3.45205,1.48514 -1.349539,1.63367 -2.677116,3.63862 -2.950173,4.45545 -0.273055,0.81683 -3.168256,2.95063 -6.433779,4.74178 -3.265523,1.79115 -5.937315,3.64601 -5.937315,4.12192 0,1.77959 6.361283,-1.59914 11.561819,-6.14093 z m -20.47271,5.3104 c 0,-1.48733 -5.81027,-1.8801 -6.366582,-0.43038 -0.356538,0.92913 0.492992,1.3081 2.93231,1.3081 1.888849,0 3.434272,-0.39498 3.434272,-0.87772 z m 63.050779,-1.35 c 2.916955,-1.98579 4.205247,-3.71287 2.769577,-3.71287 -0.693665,0 -8.394613,5.11626 -8.394613,5.57711 0,1.01623 2.716191,0.11603 5.625036,-1.86424 z m -5.082551,-1.19364 c 7.593085,-3.17259 13.318898,-12.23833 13.318898,-21.087947 0,-14.183278 -14.801367,-26.126413 -27.276503,-22.009246 -4.871629,1.607782 -12.143736,8.333235 -14.435363,13.350236 -3.260107,7.137268 -1.947056,16.953627 3.009811,22.501317 l 2.75988,3.08884 0.514066,-6.40417 c 0.59176,-7.372086 2.817916,-12.370412 6.194803,-13.909026 9.324945,-4.24873 15.584088,10.950876 9.956609,24.178486 -0.930827,2.18794 1.172672,2.29087 5.957799,0.29151 l 0,0 z m -66.879119,-1.52913 c -2.805149,-2.19422 -4.307733,-2.52716 -3.741707,-0.82908 0.211038,0.6331 1.180081,1.268 2.15343,1.41085 0.973349,0.14286 2.025929,0.51595 2.339067,0.82908 0.313138,0.31314 0.829243,0.55943 1.1469,0.54732 0.317656,-0.0121 -0.536304,-0.89328 -1.89769,-1.95817 z m 12.639913,0.64485 c 0.689575,-0.42992 0.997439,-1.19644 0.684141,-1.70337 -0.313298,-0.50692 -0.139505,-0.92168 0.386206,-0.92168 0.525712,0 0.704595,-0.96077 0.397519,-2.13502 -0.337827,-1.29185 -0.167417,-1.89344 0.431502,-1.52328 0.604271,0.37346 1.005912,-1.20529 1.031127,-4.0531 0.03148,-3.556019 -0.171219,-4.194157 -0.852784,-2.684642 -0.678574,1.502882 -0.773791,1.192692 -0.395022,-1.286842 0.353363,-2.313228 0.165236,-3.060723 -0.644381,-2.560356 -0.737692,0.45592 -0.940577,0.178019 -0.571745,-0.783139 0.314436,-0.819406 0.23569,-2.033505 -0.174991,-2.698 -1.105326,-1.788456 -7.682811,-2.144736 -9.055691,-0.490515 -0.631379,0.760762 -0.759249,1.396753 -0.284156,1.413317 0.475095,0.01654 0.06457,0.495168 -0.912263,1.063584 -1.129264,0.657109 -1.565313,1.697515 -1.197349,2.856861 0.318297,1.002872 0.145073,2.091406 -0.384943,2.418971 -1.212393,0.749301 -1.114708,6.501761 0.11041,6.501761 0.49838,0 0.626441,0.88128 0.284578,1.95839 -1.132056,3.56679 7.260902,7.05039 11.147842,4.62706 l 0,0 z m 8.934184,-0.55418 c 2.020385,-1.03924 5.010061,-3.29502 6.643725,-5.01286 2.868463,-3.01627 2.981671,-3.49028 3.302077,-13.826072 l 0.33178,-10.702722 -3.762914,-0.705927 C 47.602481,80.969761 43.95345,78.863901 38.40778,73.51044 l -4.950496,-4.778915 -3.90401,1.921073 C 17.503668,76.58193 12.423679,90.628824 18.240927,101.93283 c 3.23262,6.2816 4.539882,6.43779 5.329032,0.6367 0.928828,-6.827865 1.319844,-7.895489 4.103161,-11.203281 7.697735,-9.148234 17.690208,3.484377 13.905573,17.579601 -1.6234,6.04608 -1.03574,6.43209 5.036847,3.3085 l 0,0 z m 37.877227,-0.17548 c 0.607833,-1.13574 0.846281,-2.32386 0.529884,-2.64025 -0.316397,-0.3164 -0.575268,-0.0873 -0.575268,0.50911 0,0.59643 -0.700141,1.78455 -1.55587,2.64027 -0.855728,0.85573 -1.094176,1.55587 -0.529884,1.55587 0.564291,0 1.523303,-0.92924 2.131138,-2.065 l 0,0 z m -8.956275,-0.41024 c -0.777242,-0.93653 -0.843612,-1.48515 -0.179665,-1.48515 0.579095,0 1.32826,0.44554 1.664814,0.9901 0.336553,0.54455 1.710509,0.9901 3.053236,0.9901 3.405659,0 4.705098,-3.86234 3.99729,-11.88119 -0.410484,-4.650429 -0.278996,-6.023676 0.474005,-4.950498 0.92628,1.320129 0.997019,1.320129 0.636655,0 -0.222976,-0.816832 -0.888084,-1.485149 -1.478018,-1.485149 -0.589933,0 -1.406765,-0.334158 -1.815181,-0.742574 -0.408416,-0.408416 -1.808473,-0.742574 -3.111239,-0.742574 -1.326986,0 -2.099559,-0.435416 -1.756748,-0.990099 1.082137,-1.750934 -0.356281,-1.056251 -2.436678,1.176792 -1.948858,2.091852 -2.796679,4.371505 -1.276193,3.431475 0.408415,-0.252495 0.742574,2.796683 0.742574,6.775957 0,4.5426 -0.368457,7.02333 -0.990099,6.66611 -0.544555,-0.31292 -0.141343,0.39874 0.896028,1.58146 2.106995,2.4022 3.511949,2.99403 1.579219,0.66524 l 0,0 z m 74.981158,-0.19108 c -0.96334,-0.25103 -2.29997,-0.23453 -2.9703,0.0366 -0.67032,0.27122 0.11786,0.4766 1.75152,0.45643 1.63366,-0.0202 2.18212,-0.24208 1.21878,-0.49311 l 0,5e-5 z m -84.882148,-2.77922 c -0.67791,-0.81683 -1.678108,-1.48515 -2.222662,-1.48515 -0.552304,0 -0.445093,0.65669 0.242464,1.48515 0.67791,0.81683 1.678108,1.48515 2.222663,1.48515 0.552304,0 0.445093,-0.6567 -0.242465,-1.48515 z m 38.428218,-0.43317 c 0.24752,-0.74257 -0.12376,-1.11386 -0.86634,-0.86634 -0.71472,0.23824 -1.49443,1.01795 -1.73267,1.73268 -0.24752,0.74257 0.12376,1.11386 0.86634,0.86633 0.71472,-0.23823 1.49443,-1.01795 1.73267,-1.73267 z m 61.57178,-0.16781 c 0,-1.1313 -2.6849,-1.15685 -3.38,-0.0322 -0.2896,0.4686 -0.27234,1.10622 0.0384,1.41693 0.7726,0.77266 3.34158,-0.29192 3.34158,-1.38475 z m -145.544552,0.16436 c 0,-1.16817 -1.931044,-2.41782 -2.640265,-1.7086 -0.709219,0.70923 0.54042,2.64027 1.708598,2.64027 0.512417,0 0.931667,-0.41925 0.931667,-0.93167 z m 65.94472,-2.76058 c -0.329002,-0.329 -0.563011,0.25578 -0.52002,1.29951 0.04751,1.15341 0.28212,1.38802 0.598185,0.59818 0.286011,-0.71472 0.250836,-1.56868 -0.07817,-1.89769 l 3e-6,0 z m 20.193892,-0.7632 c 0,-0.81683 -0.44554,-1.48515 -0.9901,-1.48515 -0.54455,0 -0.9901,0.66832 -0.9901,1.48515 0,0.81683 0.44555,1.48515 0.9901,1.48515 0.54456,0 0.9901,-0.66832 0.9901,-1.48515 z m 60.18796,-0.40346 c 2.02039,-1.03875 5.45561,-3.52622 7.63382,-5.527735 l 3.9604,-3.639109 -4.45545,3.425762 c -2.45049,1.884172 -6.23762,4.351962 -8.41584,5.483972 -2.17822,1.13201 -3.60848,2.0779 -3.17837,2.10196 0.43011,0.0241 2.43506,-0.80612 4.45544,-1.84485 z m -94.1857,-5.289607 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237627 0,1.36138 0.224726,1.91831 0.499392,1.23762 0.274665,-0.68069 0.274665,-1.794554 0,-2.475247 z m 13.861386,-0.990099 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237624 0,1.361382 0.224726,1.918312 0.499392,1.237622 0.274666,-0.680691 0.274666,-1.794553 0,-2.475246 z m -25.408199,0.742575 c 0,-0.816832 -0.445544,-1.485149 -0.990099,-1.485149 -0.544554,0 -0.990099,0.668317 -0.990099,1.485149 0,0.816831 0.445545,1.485151 0.990099,1.485151 0.544555,0 0.990099,-0.66832 0.990099,-1.485151 z m 47.524753,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921683 -0.55343,0.342039 -0.74992,1.036653 -0.43661,1.543584 0.84874,1.37331 1.44286,1.11724 1.44286,-0.621901 l 0,0 z M 13.75844,96.59024 c -0.329002,-0.329 -0.563011,0.255782 -0.520019,1.299504 0.04751,1.153416 0.282119,1.38802 0.598184,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897693 l 0,0 z m 45.936468,-3.733496 c 0,-0.816831 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668317 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m 49.504952,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921684 -0.55343,0.34204 -0.74992,1.036654 -0.43661,1.543585 0.84874,1.373307 1.44286,1.117237 1.44286,-0.621901 l 0,0 z M 12.768341,90.649645 c -0.329002,-0.328998 -0.563011,0.255783 -0.52002,1.299505 0.04751,1.153416 0.28212,1.38802 0.598185,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897694 l 0,0 z m 70.193894,0.721951 c -0.336554,-0.544555 -1.142551,-0.983277 -1.791106,-0.974941 -0.708531,0.0089 -0.586411,0.398248 0.305957,0.974941 1.902102,1.229238 2.244857,1.229238 1.485149,0 z m 25.247525,-4.513878 c 0,-0.84897 -0.45281,-1.263728 -1.00625,-0.921685 -0.55343,0.342043 -0.74992,1.036654 -0.43661,1.543581 0.84874,1.373311 1.44286,1.117238 1.44286,-0.621896 z M 13.75844,84.709054 c -0.329002,-0.329001 -0.563011,0.255777 -0.520019,1.299505 0.04751,1.153409 0.282119,1.38802 0.598184,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 0,0 z m 48.906765,-3.85473 c 0,-1.356215 -3.082898,-1.911382 -4.232156,-0.762123 -0.330986,0.330986 -0.08945,1.422196 0.536762,2.424911 0.842923,1.349734 1.470503,1.547624 2.416974,0.762123 0.703131,-0.583548 1.27842,-1.674757 1.27842,-2.424911 z m 43.564355,0.09971 c 0,-2.007107 -9.940776,-11.875249 -12.685773,-12.593082 -3.422347,-0.894964 -2.536662,0.72179 2.04221,3.727903 4.685203,3.075921 8.056173,6.371341 8.979963,8.778691 0.77225,2.012434 1.6636,2.058775 1.6636,0.08649 z m -47.693353,-7.404219 2.306645,-4.455446 -0.675699,4.455446 -0.6757,4.455445 3.814599,-3.586129 c 2.098029,-1.972372 6.311347,-5.155371 9.362929,-7.073331 5.874539,-3.692229 6.839458,-5.599101 6.818235,-13.474203 -0.0116,-4.303265 -3.763041,-12.649115 -7.037511,-15.656368 -5.956689,-5.47059 -15.534138,-7.597002 -22.017021,-4.888282 -12.757989,5.330628 -18.072962,19.793085 -11.85765,32.265591 2.52515,5.067315 2.685106,5.196865 3.601855,2.917172 0.958373,-2.383197 0.960066,-2.382511 1.654947,0.671085 0.942906,4.14352 1.700115,5.200511 5.327538,7.436733 4.523217,2.788458 6.716499,2.070908 9.376833,-3.067713 l 0,0 z m 8.682689,1.5849 c 1.905993,-1.851076 4.77995,-3.91008 6.386569,-4.575565 2.564998,-1.062456 4.03369,-2.949929 2.295417,-2.949929 -2.10037,0 -13.235677,8.775011 -13.235677,10.430176 0,1.083649 1.30255,0.252787 4.553691,-2.904682 z M 20.090948,74.8078 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z M 152.76422,69.68259 c 0,-0.272277 -1.78218,1.245201 -3.9604,3.372174 -2.17822,2.126974 -3.9604,4.089996 -3.9604,4.362274 0,0.272277 1.78218,-1.245201 3.9604,-3.372175 2.17822,-2.126973 3.9604,-4.089996 3.9604,-4.362273 z M 41.625601,72.476287 c -2.586633,-2.217071 -4.709793,-4.553304 -4.718131,-5.191628 -0.02877,-2.202305 -1.632163,-3.701423 -3.281819,-3.068391 -2.032483,0.779938 -2.195989,3.392952 -0.212309,3.392952 0.792663,0 3.354544,2.00317 5.693069,4.45149 2.338525,2.44832 4.92018,4.450394 5.737012,4.449053 0.816832,-0.0014 -0.631188,-1.816405 -3.217822,-4.033476 l 0,0 z M 24.051344,70.847404 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z m 6.526162,-3.972749 c -0.745512,-0.745512 -5.536063,1.770447 -5.536063,2.907495 0,0.46652 1.378038,0.135607 3.062307,-0.735362 1.684269,-0.870969 2.797459,-1.848429 2.473756,-2.172133 z m 53.127303,0.748085 c 0.952971,-0.0074 1.732673,-0.459065 1.732673,-1.003619 0,-0.544555 -0.940674,-0.990099 -2.090387,-0.990099 -1.852777,0 -2.016491,-0.393899 -1.440284,-3.465347 0.406143,-2.164925 0.261718,-3.465346 -0.38486,-3.465346 -0.56923,0 -1.034964,1.059307 -1.034964,2.354014 0,1.294709 -0.668316,2.90867 -1.485148,3.58658 -2.367441,1.964801 -1.885292,4.298583 0.742574,3.594342 1.225248,-0.328353 3.007426,-0.60309 3.960396,-0.610525 z m 71.134371,-0.722043 c 1.58154,-0.934242 2.87553,-2.079091 2.87553,-2.544109 0,-1.671282 -4.25968,-0.165537 -5.70037,2.015008 -1.76311,2.668563 -1.02958,2.805958 2.82484,0.529101 z m 47.13694,-2.884855 c -0.37294,-0.372946 -1.68483,-0.148769 -2.91529,0.498172 -1.23047,0.64694 -1.45751,0.953686 -0.50454,0.681656 1.92704,-0.550082 2.24796,0.402733 0.74808,2.221031 -0.54153,0.65649 -0.009,0.312431 1.18262,-0.764577 1.19197,-1.077007 1.86208,-2.263334 1.48913,-2.636282 z m -52.1822,2.108229 c 0.67791,-0.816831 1.00979,-1.485148 0.73751,-1.485148 -0.27227,0 -1.0497,0.668317 -1.72761,1.485148 -0.67791,0.816832 -1.00979,1.485149 -0.73752,1.485149 0.27228,0 1.04971,-0.668317 1.72762,-1.485149 z m 37.15543,-0.451808 c -0.32185,-0.520771 -1.23923,-0.695875 -2.03863,-0.38912 -2.04664,0.785373 -1.80547,1.335978 0.5852,1.335978 1.12125,0 1.7753,-0.426086 1.45343,-0.946858 z m -20.13811,-0.719592 c -0.71473,-0.286011 -1.56869,-0.250835 -1.89769,0.07817 -0.329,0.329001 0.25578,0.56301 1.29951,0.520019 1.15341,-0.04751 1.38802,-0.282119 0.59818,-0.598185 l 0,-3e-6 z M 84.05547,61.936777 c -0.329002,-0.329001 -0.563011,0.255776 -0.52002,1.299505 0.04751,1.153409 0.28212,1.38802 0.598185,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 3e-6,0 z m 82.57013,0.721948 c 0,-0.544555 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445544 -1.48515,0.990099 0,0.544554 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445545 1.48515,-0.990099 z m 37.62376,-5.177658 c 0,-1.661518 -0.24856,-1.789209 -1.48514,-0.762936 -0.81684,0.67791 -1.48515,1.832342 -1.48515,2.565406 0,0.777973 0.61827,1.095588 1.48515,0.762936 0.81683,-0.313447 1.48514,-1.46788 1.48514,-2.565406 z M 83.457284,54.18445 c 0,-0.784694 -0.445544,-1.426715 -0.990099,-1.426715 -0.544554,0 -0.990099,0.917384 -0.990099,2.03863 0,1.121247 0.445545,1.76327 0.990099,1.426716 0.544555,-0.336553 0.990099,-1.253937 0.990099,-2.038631 z m 63.366336,-0.931666 c -1.27896,-1.361386 -2.77092,-2.475247 -3.31547,-2.475247 -0.54456,0 0.0563,1.113861 1.33527,2.475247 1.27896,1.361386 2.77092,2.475248 3.31548,2.475248 0.54455,0 -0.0563,-1.113862 -1.33528,-2.475248 z M 82.467185,48.302289 c 0,-0.816832 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668316 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m -1.985115,-5.19802 c -0.0084,-1.2671 -4.736103,-6.714785 -5.323399,-6.134089 -0.649329,0.642032 3.49033,6.834315 4.585742,6.859554 0.408416,0.0094 0.740362,-0.317049 0.737657,-0.725465 l 0,0 z m 50.49997,-0.247525 c -0.81683,-0.527877 -1.9307,-0.959776 -2.47525,-0.959776 -0.54456,0 -0.32178,0.431899 0.49505,0.959776 0.81683,0.527878 1.93069,0.959777 2.47525,0.959777 0.54455,0 0.32178,-0.431899 -0.49505,-0.959777 z m 4.44995,-0.996169 c -0.98866,-1.092447 -2.01229,-1.771531 -2.27475,-1.509075 -0.66527,0.66528 1.80418,3.495343 3.04998,3.495343 0.56227,0 0.21342,-0.89382 -0.77523,-1.986268 l 0,0 z m -95.539062,-4.19679 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.677909 1.485148,-1.678107 1.485148,-2.222662 z m 92.079212,0.795947 c 0,-2.367417 -1.80911,-2.723191 -2.95546,-0.581213 -0.91594,1.711444 -0.77708,2.007928 0.94043,2.007928 1.10826,0 2.01503,-0.642021 2.01503,-1.426715 z M 43.853324,33.703389 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.67791 1.485148,-1.678108 1.485148,-2.222662 z m 29.450539,-0.0051 c -0.341635,-3.033194 -0.613818,-3.235945 -4.743791,-3.533678 -2.40975,-0.173719 -4.148989,-0.08348 -3.864976,0.200533 0.746043,0.746042 8.309556,6.402673 8.668673,6.483162 0.166387,0.03729 0.139429,-1.380215 -0.05991,-3.150017 z m 45.796987,1.732673 c -0.67791,-0.816832 -1.70871,-1.485149 -2.29066,-1.485149 -0.58196,0 -0.19325,0.654147 0.8638,1.453661 2.48363,1.878524 2.96864,1.889227 1.42686,0.03148 l 0,3e-6 z m 5.94059,-0.933056 c 0,-0.721181 -1.00247,-1.579892 -2.22772,-1.908245 -3.82044,-1.023837 -4.13152,-0.702262 -1.76134,1.820687 2.31705,2.466393 3.98906,2.503093 3.98906,0.08755 l 0,4e-6 z m 8.8851,-5.657864 c 5.0656,-7.213134 5.95021,-9.230659 3.73867,-8.526659 -1.72171,0.548068 -10.64357,12.438161 -10.64357,14.184592 0,2.924919 2.06665,1.231484 6.9049,-5.657933 z m -54.828018,2.397173 c -0.586902,-0.586901 -3.56203,0.943932 -3.56203,1.832819 0,0.490907 0.870827,0.348719 1.935171,-0.315974 1.064342,-0.664694 1.796429,-1.347273 1.626859,-1.516845 z m -29.622424,0.529501 c 3.007757,-1.087619 4.641314,-3.761497 2.298018,-3.761497 -0.544554,0 -0.990099,0.445545 -0.990099,0.990099 0,0.544555 -0.58316,0.990099 -1.295911,0.990099 -1.477794,0 -5.628481,2.890588 -4.219928,2.938809 0.505892,0.01732 2.399456,-0.503561 4.20792,-1.15751 l 0,0 z m 54.958912,-1.46755 c -0.71473,-0.286011 -1.56869,-0.250836 -1.89769,0.07817 -0.329,0.329002 0.25577,0.563011 1.2995,0.52002 1.15341,-0.0475 1.38802,-0.28212 0.59819,-0.598185 l 0,-3e-6 z M 59.694908,28.005259 c 0,-1.089109 -0.39099,-1.980198 -0.868866,-1.980198 -1.298365,0 -3.17241,2.559384 -2.422873,3.30892 1.355486,1.355487 3.291739,0.573912 3.291739,-1.328722 z m 21.287129,0.990099 c 0.336553,-0.544554 -0.331763,-0.990099 -1.485149,-0.990099 -1.153385,0 -1.821702,0.445545 -1.485148,0.990099 0.336553,0.544555 1.00487,0.990099 1.485148,0.990099 0.480279,0 1.148595,-0.445544 1.485149,-0.990099 z m 29.207923,0 c 0,-0.544554 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445545 -1.48515,0.990099 0,0.544555 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445544 1.48515,-0.990099 z M 86.427581,28.005259 c 0,-0.544554 -0.694611,-0.990099 -1.543581,-0.990099 -0.848969,0 -1.268219,0.445545 -0.931666,0.990099 0.336553,0.544555 1.031164,0.990099 1.543581,0.990099 0.512417,0 0.931666,-0.445544 0.931666,-0.990099 z m 18.316829,0 c 0.33656,-0.544554 -0.33176,-0.990099 -1.48515,-0.990099 -1.15338,0 -1.8217,0.445545 -1.48514,0.990099 0.33655,0.544555 1.00487,0.990099 1.48514,0.990099 0.48028,0 1.1486,-0.445544 1.48515,-0.990099 z M 53.397761,23.263982 c -2.293369,-2.293369 -3.273717,-0.599352 -1.065339,1.840877 1.180946,1.304931 2.008695,1.63504 2.254066,0.898928 0.213274,-0.63982 -0.321654,-1.872732 -1.188727,-2.739805 l 0,0 z m 41.674343,3.065049 c -0.963333,-0.251033 -2.299967,-0.234524 -2.970297,0.03668 -0.670328,0.271211 0.117854,0.476602 1.751517,0.456424 1.633663,-0.02018 2.182115,-0.242078 1.21878,-0.493111 l 0,4e-6 z M 50.784017,20.160629 c 0,-1.18906 -5.817795,-7.006855 -7.006854,-7.006855 -1.723094,0 -0.911591,1.747528 2.244318,4.833013 3.196159,3.124838 4.762536,3.839805 4.762536,2.173842 z m 99.083553,-7.807387 c -1.32905,-0.443014 -5.95468,4.804941 -5.94174,6.741126 0.006,0.860676 1.47299,-0.172344 3.48946,-2.456779 1.91375,-2.168059 3.01727,-4.096016 2.45228,-4.284347 z m -7.4939,4.754858 c 2.64699,-2.924889 1.22992,-3.38489 -1.49431,-0.485075 -1.27694,1.359238 -1.86755,2.471343 -1.31247,2.471343 0.55508,0 1.81813,-0.893821 2.80678,-1.986268 z m 1.9747,-5.934524 c 2.68184,-2.7227721 4.44726,-4.9364147 3.92318,-4.9192068 -1.79455,0.058926 -11.48794,9.8697018 -9.75161,9.8697018 0.52381,0 3.1466,-2.227723 5.82843,-4.950495 z m 4.99121,-1.055971 c 1.06562,-1.7242011 -0.14804,-2.0893477 -1.506,-0.4531041 -0.78094,0.9409741 -0.85606,1.5090751 -0.19952,1.5090751 0.57909,0 1.34657,-0.475187 1.70552,-1.055971 z m 22.08877,-7.9517764 c 1.71492,-0.5978257 3.11804,-1.51893899 3.11804,-2.04691859 0,-1.07371396 -3.1521,-0.28577416 -6.93069,1.73248789 -3.09382,1.652504 -0.61271,1.8571218 3.81265,0.3144307 l 0,0 z m 6.85154,-0.707599 c 0.59402,-1.78204068 -1.45248,-1.40757811 -2.14309,0.3921386 -0.37003,0.9642713 -0.14875,1.4169139 0.57476,1.1757426 0.64703,-0.2156762 1.35277,-0.9212228 1.56833,-1.5678812 z M 20.090948,0.80296239 c 0,-0.25829297 -1.366838,-1.17644278 -3.037417,-2.04033289 C 13.07504,-3.294728 10.77735,-2.5105441 14.645403,-0.41549494 17.561715,1.1640635 20.090948,1.729987 20.090948,0.80296239 z M 177.51669,-2.5818805 c 0,-1.2146632 -2.78939,-2.1897491 -3.40672,-1.1908861 -0.27491,0.444817 -0.21492,1.0936751 0.1333,1.4419069 0.94359,0.9435791 3.27342,0.7649164 3.27342,-0.2510208 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3784"
+ d="m 30.061595,110.24748 c -3.028002,-1.91623 -2.918962,-12.207625 0.161986,-15.288574 2.892806,-2.892806 5.380122,-2.029008 6.063557,2.105759 0.787072,4.761775 0.802973,10.540215 0.03451,12.542785 -0.657319,1.71294 -4.021187,2.05687 -6.260057,0.64003 l -1e-6,0 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3786"
+ d="m 50.118347,74.592462 c -5.270942,-3.20545 -6.839578,-11.64359 -3.245566,-17.458823 3.039395,-4.917846 5.720122,-5.336139 9.002245,-1.404685 3.776278,4.523372 4.477791,9.679447 1.982432,14.570755 -2.972944,5.82745 -4.145768,6.477996 -7.739111,4.292753 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ transform="translate(0,784.36218)"
+ id="path3790"
+ d="m 77.269166,109.11407 c -1.309679,-0.76282 -1.732674,-2.30682 -1.732674,-6.32456 0,-2.923449 0.270441,-6.020121 0.600979,-6.881491 0.834308,-2.174169 4.068292,-1.961418 5.30478,0.348981 2.014054,3.7633 0.737507,14.00145 -1.732673,13.89637 -0.389257,-0.0166 -1.487442,-0.48424 -2.440412,-1.0393 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 44.93878,978.9738 c 0.190746,-0.58432 0.338179,-2.39786 0.327629,-4.03009 -0.03056,-4.72921 -2.166088,-7.8066 -5.3546,-7.71621 -2.830929,0.0802 -4.226193,1.8518 -5.325261,6.76144 -0.310145,1.38545 -0.367986,1.41692 -1.004384,0.5466 -0.371408,-0.50793 -0.821076,-1.8957 -0.999263,-3.08393 -0.556104,-3.70838 1.472045,-7.48974 5.473653,-10.2053 5.600528,-3.80062 13.975788,1.83675 13.918432,9.36847 -0.02362,3.09917 -3.738175,8.46827 -6.327112,9.14529 -0.904921,0.23664 -1.006313,0.12421 -0.709094,-0.78627 l 0,0 z"
+ id="path3811" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 44.599468,976.66009 c 0.218245,-3.86241 -0.816468,-7.47715 -2.379813,-8.31383 -1.450987,-0.77655 -3.834991,-0.56106 -4.832886,0.43683 -0.50681,0.50681 -1.306045,2.1062 -1.776076,3.55419 -1.096216,3.37704 -1.457286,3.73041 -2.367994,2.31745 -2.173267,-3.3718 -1.182136,-8.30732 2.357018,-11.73721 3.809502,-3.69189 6.358482,-4.18347 10.586911,-2.04173 3.184192,1.61283 5.558793,4.81819 6.063693,8.18509 0.273646,1.82482 0.11239,2.73795 -0.85046,4.8158 -1.44332,3.11472 -4.398827,6.24077 -5.900301,6.24077 -1.048695,0 -1.087113,-0.14757 -0.900092,-3.45736 z"
+ id="path3813" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 31.772095,956.75283 c -0.330142,-3.53542 -1.332025,-5.66211 -3.39009,-7.19614 -2.497045,-1.86123 -5.290367,0.24245 -6.513802,4.90561 l -0.621552,2.36907 -0.783636,-1.82263 c -2.594221,-6.0338 2.242038,-13.61972 8.68299,-13.61972 3.869635,0 6.854166,1.90962 8.672926,5.54928 1.621853,3.24562 1.874731,5.91025 0.717664,7.56219 -0.413663,0.59058 -2.037315,2.06273 -3.608115,3.27143 l -2.856002,2.19765 -0.300383,-3.21674 0,0 z"
+ id="path3815" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 22.375662,975.25483 c 0,-3.90201 -0.118212,-4.438 -1.328864,-6.02525 -1.647954,-2.16058 -3.309979,-2.63578 -5.531561,-1.58157 -1.756038,0.83329 -3.67959,3.97304 -3.67959,6.00607 0,1.57158 -0.803063,1.30457 -1.422743,-0.47305 -1.64257,-4.71188 0.828224,-10.54331 5.504685,-12.99185 1.350715,-0.70721 1.444585,-0.67039 3.722241,1.46009 2.599066,2.43112 4.373871,3.46784 6.850621,4.00166 l 1.663623,0.35857 -0.308132,4.69087 c -0.332047,5.05494 -0.878611,6.12512 -4.100144,8.02813 l -1.370136,0.80935 0,-4.28302 z"
+ id="path3817" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3819" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3821" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3823" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47069979;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3825" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.37135169;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3827" />
+ <path
+ style="fill:#808000;fill-opacity:1;stroke:#ffffff;stroke-width:0.37135169;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 73.592784,970.15135 c 1.213934,-1.18121 3.046268,-2.7068 3.589733,-2.98879 0.267378,-0.13873 0.34053,-0.13037 0.537935,0.0615 0.221519,0.21526 0.217286,0.22781 -0.139053,0.41208 -0.20214,0.10453 -1.168634,0.82158 -2.14777,1.59344 -3.063354,2.41489 -3.706031,2.73671 -1.840845,0.9218 z"
+ id="path3839" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37135169;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 72.463697,971.20627 c 0.169069,-0.31591 2.351438,-2.35225 3.604765,-3.36355 1.093344,-0.88222 1.4103,-1.00331 1.746403,-0.6672 0.235447,0.23544 0.205422,0.26332 -2.362342,2.19384 -2.587549,1.94538 -3.272014,2.36605 -2.988826,1.83691 z m 3.224159,-2.29266 c 2.187569,-1.64501 2.078124,-1.5466 1.827085,-1.64293 -0.126299,-0.0485 -0.405535,0.0686 -0.732459,0.30713 -0.774253,0.56487 -3.174215,2.65533 -3.182553,2.77214 -0.0098,0.13757 0.0457,0.0994 2.087927,-1.43634 z"
+ id="path3841" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37135169;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 72.293984,971.42726 c -0.104459,-0.16901 0.848068,-1.16054 2.536005,-2.63984 1.848193,-1.61975 1.734673,-1.53168 2.253818,-1.74859 0.416275,-0.17393 0.470399,-0.1706 0.737099,0.0453 l 0.287837,0.23308 -0.246494,0.27238 c -0.260406,0.28777 -3.497984,2.74496 -4.623764,3.50926 -0.707212,0.48014 -0.825322,0.52119 -0.944501,0.32835 z m 4.656755,-3.6734 c 0.154047,-0.18674 0.143916,-0.1921 -0.108627,-0.0575 -0.288041,0.15348 -0.358969,0.26347 -0.169886,0.26347 0.05974,0 0.185071,-0.0927 0.278513,-0.20594 l 0,0 z"
+ id="path3843" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37135169;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d=""
+ id="path3845" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37135169;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 73.534328,972.79636 c 0.134271,-0.13123 0.940416,-0.61171 1.791431,-1.06775 0.851014,-0.45604 1.977091,-1.13101 2.5024,-1.49994 0.967441,-0.67944 2.077604,-1.6986 2.077604,-1.90729 0,-0.0627 0.139257,-0.11401 0.30946,-0.11401 1.351378,0 -2.156677,2.86001 -5.340949,4.35431 -0.55468,0.26029 -1.138014,0.47326 -1.296294,0.47326 -0.286085,0 -0.286342,-10e-4 -0.04367,-0.23858 z"
+ id="path3847" />
+ <rect
+ inkscape:transform-center-x="98.4082"
+ ry="24.232771"
+ rx="18.193621"
+ transform="matrix(0.99994199,0.01077156,-0.00729569,0.99997339,0,0)"
+ y="845.56256"
+ x="12.069448"
+ height="67.760971"
+ width="92.186958"
+ id="rect3011"
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.88180792;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:transform-center-y="-1.9302989e-05" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="Layer2"
+ transform="translate(0,-220)">
+ <!--<foreignObject x="15"
+ y="30" height="136.85336"
+ width="186.18527"> -->
+ <foreignObject x="15"
+ y="30" height="69"
+ width="93">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <div id='wordBubble' style="font-size:25px">Please help me find my Spaceship</div>
+ </body>
+ </foreignObject>
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien3.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien3.svg
new file mode 100755
index 0000000..377ee92
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien3.svg
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="150"
+ height="300"
+ id="svg2"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="alien3.svg">
+ <metadata
+ id="metadata47">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ id="namedview45"
+ showgrid="false"
+ inkscape:zoom="1.5"
+ inkscape:cx="106.63021"
+ inkscape:cy="166.28281"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 103.30726 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="100 : 103.30726 : 1"
+ inkscape:persp3d-origin="50 : 68.871506 : 1"
+ id="perspective49" />
+ </defs>
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2909"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2915"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2917"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3707"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3711"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3715"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.68738866;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3776"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3778"
+ d="" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3788"
+ d="" />
+ <g
+ id="g3794"
+ transform="matrix(0.49496731,0,0,0.49496731,23.688009,-216.56245)">
+ <path
+ style="fill:#000000"
+ id="path2905"
+ d="m 53.60865,1035.3693 c 19.78288,-22.2017 22.20694,-25.4265 25.4678,-33.881 3.44722,-8.9377 6.40012,-18.24962 7.52938,-23.74392 0.82455,-4.01172 -0.36261,-5.08744 -5.63913,-5.10977 -1.99045,-0.008 -7.61545,-0.71148 -12.5,-1.56235 -16.50806,-2.87565 -23.91813,-6.30919 -33.99171,-15.75046 -6.08941,-5.70718 -7.43503,-7.50597 -7.19032,-9.61182 0.34346,-2.95569 -1.50714,-2.82651 22.80104,-1.59153 11.8285,0.60095 15.97106,0.42806 22.48438,-0.93836 4.39141,-0.92127 8.66641,-2.28625 9.5,-3.0333 0.83359,-0.74704 3.31562,-1.68728 5.51562,-2.08942 2.2,-0.40213 5.575,-1.60777 7.5,-2.6792 3.44034,-1.91485 3.44887,-1.93539 0.5,-1.2054 -5.17273,1.28051 -26.63042,1.59889 -36.0133,0.53435 -9.20812,-1.04471 -19.63226,-3.39275 -22.72313,-5.11837 -0.95503,-0.5332 -2.32888,-0.96945 -3.05299,-0.96945 -1.43857,0 -9.42912,-5.54027 -11.50725,-7.97859 -0.95343,-1.11868 -1.14843,-3.94422 -0.73666,-10.67412 l 0.56002,-9.15271 -4.54056,-5.31941 c -9.98832,-11.70162 -9.97623,-27.55255 0.0295,-38.68134 2.60206,-2.89412 6.36378,-5.77306 8.93031,-6.83458 l 4.43446,-1.83411 -0.57302,-6.13624 c -1.06496,-11.40449 5.13162,-23.48816 14.51299,-28.30109 l 3.58712,-1.84031 -5.95375,-5.92765 c -4.93512,-4.9135 -8.52008,-7.18312 -20.95375,-13.26571 -8.25,-4.03593 -15.17459,-7.48627 -15.38799,-7.66742 -0.21339,-0.18115 0.18259,-2.36727 0.87997,-4.85804 1.70691,-6.09651 3.20226,-5.96925 18.29995,1.55747 19.96216,9.95182 24.45018,13.11377 31.13538,21.93586 4.86767,6.42359 6.566,7.95536 9.5,8.56828 1.96498,0.41049 4.02269,0.60686 4.57269,0.43639 17.13317,-5.31045 33.409,-5.14223 47.77024,0.49372 4.94708,1.94144 5.21645,1.90161 6.52227,-0.96436 0.61245,-1.34418 5.43513,-7.16668 10.71706,-12.93889 7.18218,-7.84883 10.66081,-10.87865 13.79697,-12.01685 2.3064,-0.83706 9.11158,-3.33956 15.12261,-5.56111 6.01103,-2.22156 11.68966,-4.03919 12.61916,-4.03919 1.11859,0 1.89014,1.09888 2.28193,3.25 0.32555,1.7875 0.8733,4.21044 1.21722,5.38431 0.70713,2.41364 -0.93804,3.18343 -16.9864,7.94807 -8.24402,2.44759 -9.41386,3.13117 -15.04786,8.79297 -3.35991,3.37649 -7.99751,8.92014 -10.30579,12.31923 l -4.19687,6.18016 4.59822,3.7679 c 3.92224,3.21397 12.53592,13.3479 15.89124,18.69593 0.86818,1.38377 2.03676,1.46094 8.86473,0.5854 6.40489,-0.8213 8.72511,-0.72392 12.5,0.5246 8.01058,2.64945 13.40229,2.97743 17.21675,1.04728 5.01589,-2.53808 7.91852,-5.53295 7.91852,-8.17016 0,-1.91743 0.52663,-2.32569 3,-2.32569 l 3,0 0,7.36937 c 0,6.99889 -0.19005,7.61474 -3.78039,12.25 -2.07921,2.68435 -4.3555,6.00563 -5.05843,7.38063 -1.82398,3.56792 -4.05346,6.02517 -8.95417,9.86899 -2.36114,1.85194 -5.40785,5.56725 -6.77047,8.25624 -1.86654,3.68345 -4.04585,5.93033 -8.8376,9.11161 l -6.36013,4.22255 -1.16111,8.29999 c -3.24143,23.17077 -14.49635,42.93763 -31.7551,55.771 -4.30243,3.19923 -8.0341,5.98766 -8.29259,6.19652 -1.61876,1.30794 6.41126,11.58405 19.25766,24.64423 26.293,26.73057 27.51833,28.27367 30.82393,38.81727 3.56149,11.3598 3.62201,12.8116 0.53407,12.8116 -2.0739,0 -2.62572,-0.9231 -4.63288,-7.75 -1.25321,-4.2625 -3.12892,-9.4395 -4.16826,-11.5044 -1.03933,-2.065 -8.08103,-9.94 -15.6482,-17.5 -17.43517,-17.4188 -29.05724,-30.54815 -30.36702,-34.30539 -0.88138,-2.52833 -1.38534,-2.84102 -3.67537,-2.28044 -1.45967,0.3573 -2.80394,1.03003 -2.98727,1.49494 -0.18334,0.46491 -1.18057,0.84529 -2.21608,0.84529 -1.0355,0 -3.3605,0.6395 -5.16666,1.42112 -1.80616,0.78162 -5.98393,1.79412 -9.28393,2.25 l -6,0.82888 -0.64806,5 c -1.05452,8.13597 -10.19844,32.3753 -13.55944,35.9443 -1.06473,1.1306 -3.96423,4.5663 -6.44331,7.6348 -2.47909,3.0685 -5.37183,6.4995 -6.42831,7.6245 -1.05648,1.1249 -3.66664,3.9018 -5.80036,6.1708 -3.09032,3.2864 -4.58088,4.1256 -7.32754,4.1256 l -3.44807,0 4.67803,-5.25 z m 5.47706,-1.25 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 8,-9 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 6,-7 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 85,-12.8776 c 0,-0.2076 -0.7875,-0.9951 -1.75,-1.75 -1.58606,-1.2438 -1.62143,-1.2085 -0.37756,0.3776 1.30637,1.6657 2.12756,2.1955 2.12756,1.3724 z m -13,-11.9674 c 0,-0.1898 -1.0125,-1.2023 -2.25,-2.25 l -2.25,-1.905 1.90499,2.25 c 1.79022,2.1144 2.59501,2.7052 2.59501,1.905 z m -8,-9.00001 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11444 2.59501,2.70524 2.59501,1.90499 z m -41,-13.2644 c 0,-0.21482 -2.1375,-0.3837 -4.75,-0.37528 -2.69011,0.009 -4.21371,0.35593 -3.51336,0.80076 1.18245,0.75103 8.26336,0.38643 8.26336,-0.42548 z m -15.15913,-0.88305 c -0.27085,-0.27086 -4.50835,-1.18259 -9.41666,-2.02608 -16.13633,-2.77299 -23.51094,-5.97517 -33.27596,-14.44895 -7.06554,-6.13127 -6.84736,-7.42208 1.10175,-6.51825 3.4375,0.39085 6.025,0.48259 5.75,0.20387 -0.99658,-1.01006 -14.48194,-2.63618 -15.27608,-1.84205 -0.44842,0.44842 2.5534,3.97257 6.67071,7.83144 9.85626,9.23759 17.5018,12.85148 33.17531,15.68127 8.58267,1.54956 12.04547,1.89328 11.27093,1.11875 z m 23.7264,-0.47481 c 0.532,-0.532 2.7595,-1.3868 4.95,-1.89955 2.1905,-0.51275 3.08273,-0.97137 1.98273,-1.01914 -1.1,-0.0478 -4.7,0.76597 -8,1.80833 -4.87947,1.54126 -5.4304,1.91223 -2.95,1.98641 1.6775,0.0502 3.48527,-0.34405 4.01727,-0.87605 z m -1.06727,-3.56001 c 3.85,-1.06802 7.225,-2.19571 7.5,-2.50598 0.275,-0.31026 2.3,-1.09477 4.5,-1.74336 5.05158,-1.48926 15.57308,-8.30539 21.71998,-14.07082 10.15582,-9.52554 18.78406,-25.08183 22.17104,-39.97322 2.25857,-9.93017 2.17044,-11.34285 -0.64102,-10.27621 -1.2375,0.4695 -5.625,1.02086 -9.75,1.22525 -7.05688,0.34966 -7.51817,0.24412 -7.80748,-1.7863 -0.33071,-2.32087 0.30249,-2.55846 10.30748,-3.8677 11.1663,-1.4612 23.27502,-8.62225 26.61935,-15.74257 1.23176,-2.6225 3.84631,-5.98973 5.81011,-7.48272 4.73441,-3.59937 9.07054,-8.06924 9.07054,-9.35029 0,-1.14449 5.05979,-8.20389 6.26146,-8.73595 0.4188,-0.18544 1.19818,-1.15318 1.73195,-2.15053 0.8951,-1.67251 0.64174,-1.65381 -3.26146,0.24076 -7.22492,3.5069 -10.3032,3.77646 -18.61575,1.63013 -9.07215,-2.34246 -19.00256,-2.1397 -21.58295,0.44068 -0.92186,0.92186 -2.14171,1.67611 -2.71077,1.67611 -2.54552,0 -8.99433,6.52871 -10.95829,11.09406 -1.16076,2.69827 -2.46826,4.90594 -2.90555,4.90594 -1.95933,0 -3.95864,-1.33678 -3.95864,-2.64683 0,-3.08568 4.35596,-10.05283 8.7413,-13.98128 l 4.60821,-4.12811 -4.56124,-6.37189 c -5.99722,-8.37789 -13.41368,-15.23903 -16.69909,-15.44873 -3.96961,-0.25337 -4.08918,-0.31285 -4.08918,-2.03394 0,-1.26833 -0.37392,-1.14902 -1.75876,0.56119 -3.16363,3.90691 -6.71424,0.67043 -4.27159,-3.89369 0.85843,-1.60399 0.0269,-2.12345 -7.25,-4.52893 -6.21814,-2.0555 -10.28943,-2.73355 -16.71965,-2.78455 -7.5672,-0.06 -19,1.69411 -19,2.91514 0,0.25239 1.31647,2.12001 2.92548,4.15026 4.36394,5.50639 6.47105,13.04213 5.76399,20.6139 l -0.58664,6.28221 5.37473,1.20281 c 21.33616,4.77483 28.69937,31.92058 12.95469,47.75979 -10.80462,10.86949 -26.4913,11.06535 -37.48583,0.46803 l -4.92782,-4.74978 -3.2593,3.39483 c -5.79484,6.0358 -10.13838,7.70973 -20.0093,7.71121 -8.60158,10e-4 -8.75,0.0426 -8.75,2.43384 0,1.33789 -0.52005,3.87072 -1.15568,5.62851 -1.08586,3.00291 -0.94993,3.38302 2.25,6.29169 1.87313,1.70263 3.98611,3.10888 4.69552,3.12501 0.70941,0.0161 2.95941,0.87562 5,1.91 5.35714,2.71554 26.10725,6.12131 37.21074,6.10748 6.7425,-0.008 12.40095,-0.73394 19.49709,-2.5 12.81724,-3.18989 15.50356,-3.23117 15.49859,-0.23817 -0.005,3.2606 -3.59424,8.64665 -6.49672,9.75017 -1.37475,0.52268 -2.49954,1.41147 -2.49954,1.97508 0,0.56361 -0.48214,1.02475 -1.07143,1.02475 -0.58928,0 -1.74575,0.67432 -2.56993,1.4985 -0.82417,0.82417 -2.70453,1.76639 -4.17856,2.09382 -1.47404,0.32743 -4.04917,1.20489 -5.7225,1.94992 -7.22305,3.21595 -18.24045,4.55548 -34.98967,4.25415 l -16.47466,-0.29639 3.75338,3.2447 c 8.53728,7.38027 17.41711,11.11298 32.67758,13.73628 4.90831,0.84375 9.17851,1.7884 9.48934,2.09923 1.09734,1.09735 13.67539,-0.1903 20.58645,-2.10749 z m 40.5,-82.47272 c 0,-1.1 -0.45,-2 -1,-2 -0.55,0 -0.99978,-1.0125 -0.99951,-2.25 4.9e-4,-2.23828 6.86797,-9.01585 11.80351,-11.64897 3.22732,-1.72179 11.25861,-4.07728 13.946,-4.09021 3.59163,-0.0173 2.91267,4.08892 -1.25,7.55971 -1.925,1.60504 -3.5,3.40484 -3.5,3.99955 0,1.65254 -3.95602,4.90826 -9.49204,7.81174 -6.12107,3.21032 -9.50796,3.43052 -9.50796,0.61818 z m 9,-3.36173 c 4.30061,-2.42779 8,-5.65282 8,-6.97419 0,-0.54301 1.6875,-2.48922 3.75,-4.32491 2.0625,-1.83568 3.525,-3.33309 3.25,-3.32756 -1.50707,0.0303 -10.20077,3.05406 -12.64753,4.39899 -3.66433,2.0142 -12.18544,9.58314 -10.7927,9.5867 0.58287,0.001 3.43212,-2.0223 6.33165,-4.4973 5.24143,-4.474 9.10858,-5.78543 9.10858,-3.08889 0,1.84596 -4.51449,5.57987 -9.77988,8.08889 -2.30845,1.1 -4.20234,2.32338 -4.20865,2.71862 -0.0143,0.8945 2.43529,-0.01 6.98853,-2.58035 z m -35,84.31604 c 1.09546,-0.74131 0.69092,-0.83408 -1.5,-0.34401 -3.67693,0.82247 -4.47511,1.39483 -1.91667,1.37439 1.05417,-0.008 2.59167,-0.47209 3.41667,-1.03038 z m 6.427,-2.47578 c 2.91505,-2.20537 1.48811,-2.46248 -1.927,-0.34722 -1.65,1.02199 -2.325,1.84622 -1.5,1.83162 0.825,-0.0146 2.36715,-0.68258 3.427,-1.4844 z m 7.14043,-5.58763 c 0.37335,-0.6041 -0.50159,-0.32492 -1.94431,0.62038 -1.44271,0.94531 -2.62312,1.90782 -2.62312,2.13891 0,0.72338 3.85397,-1.6049 4.56743,-2.75929 z m 3.43257,-2.3909 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 6,-5 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -65.02348,-3.06139 c 4.11208,-0.85786 8.83708,-2.16527 10.5,-2.90536 1.66291,-0.74008 4.22952,-1.6135 5.70356,-1.94093 1.47404,-0.32743 3.28207,-1.19733 4.01785,-1.93311 0.73578,-0.73578 2.00475,-1.59958 2.81993,-1.91955 1.26954,-0.49832 1.25981,-0.59309 -0.0679,-0.66071 -0.8525,-0.0434 -2.0117,0.38275 -2.57599,0.94704 -1.37761,1.37761 -13.6602,5.81918 -19.87401,7.18674 -2.75,0.60523 -10.175,1.4011 -16.5,1.7686 l -11.5,0.66819 10,0.17442 c 5.89347,0.1028 13.07026,-0.46609 17.47652,-1.38533 z m 70.52348,-3.43861 c 0.99549,-1.1 1.58498,-2 1.30998,-2 -0.275,0 -1.31449,0.9 -2.30998,2 -0.99549,1.1 -1.58498,2 -1.30998,2 0.275,0 1.31449,-0.9 2.30998,-2 z m -39.74244,-12.00913 c 1.24166,-1.81999 2.07092,-3.49572 1.84281,-3.72384 -0.22812,-0.22811 -5.13023,0.74348 -10.89357,2.15911 -8.13994,1.99938 -13.01511,2.57386 -21.84222,2.57386 -12.97438,0 -33.27435,-3.17908 -39.07474,-6.11931 -2.04059,-1.03438 -4.29059,-1.85699 -5,-1.82803 -0.70941,0.029 0.84976,1.11449 3.46483,2.41228 11.06002,5.4888 45.285,8.38592 59.24533,5.01506 3.3,-0.79682 6.7875,-1.45579 7.75,-1.46438 2.46056,-0.022 2.17728,2.43675 -0.5,4.33963 l -2.25,1.59919 2.5,-0.82725 c 1.375,-0.45498 3.5159,-2.31633 4.75756,-4.13632 z m 48.7905,-2.0838 c 0.87968,-1.70111 1.42188,-3.27046 1.2049,-3.48744 -0.21698,-0.21698 -1.14288,1.17483 -2.05756,3.09293 -2.05658,4.3127 -1.34401,4.64239 0.85266,0.39451 z m -128.0536,-7.9132 c -0.99854,-1.10337 -2.04794,-1.77372 -2.33199,-1.48967 -0.28406,0.28406 0.35068,1.1725 1.41054,1.97433 2.70408,2.04576 3.04782,1.86496 0.92145,-0.48466 z m -1.82881,-15.83491 c 0.54476,-4.29796 0.58312,-4.33487 3.86431,-3.71932 1.87409,0.35158 3.58779,0.17886 3.944,-0.3975 0.36318,-0.58764 0.011,-0.78172 -0.83176,-0.45833 -1.53986,0.5909 -6.76761,-1.7051 -10.1422,-4.4544 -1.9801,-1.6132 -1.98121,-1.60721 -0.11164,0.60221 1.66468,1.96729 1.82292,3.38868 1.33592,12 -0.43762,7.73827 -0.35047,8.83317 0.41936,5.26838 0.53449,-2.475 1.21939,-6.45347 1.52201,-8.84104 z m 135.93852,5.11187 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m 1,-4 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m -78.41667,-2.95394 c -0.72187,-0.28887 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28494 0.60416,-0.60416 z m 79.46844,-3.58592 c -0.27393,-0.67703 -0.48137,0.11903 -0.46099,1.76903 0.0204,1.65 0.2445,2.20394 0.49804,1.23097 0.25354,-0.97297 0.23687,-2.32297 -0.0371,-3 z m -124.92497,2.57604 c -0.97296,-0.25354 -2.32297,-0.23687 -3,0.0371 -0.67703,0.27393 0.11903,0.48137 1.76903,0.46099 1.65,-0.0204 2.20394,-0.2445 1.23097,-0.49804 z m 41.5128,0.0286 c -0.69092,-0.27855 -1.07389,-0.80553 -0.85104,-1.17105 0.22285,-0.36552 -1.20295,-0.75058 -3.16844,-0.85567 -1.9655,-0.1051 -4.95753,-1.20361 -6.64896,-2.44115 -2.34922,-1.71881 -2.72116,-1.81335 -1.57533,-0.40044 1.81731,2.24089 8.73947,5.51042 11.5,5.43176 1.1,-0.0313 1.4347,-0.28489 0.74377,-0.56345 z m -32.38703,-2.26255 c 2.07738,-1.0598 4.4142,-2.7473 5.19293,-3.75 1.34843,-1.73625 1.32057,-1.74235 -0.58488,-0.12808 -1.10041,0.93226 -4.01766,2.60988 -6.48277,3.72804 -2.46511,1.11817 -3.90159,2.04291 -3.19218,2.05499 0.70941,0.0121 2.98952,-0.84515 5.0669,-1.90495 z m 47.01576,0.49285 c 1.52524,-0.78874 3.40764,-2.25124 4.1831,-3.25 1.33163,-1.71509 1.29982,-1.7257 -0.57283,-0.1911 -1.09052,0.89366 -3.33277,2.33815 -4.98277,3.20996 -1.65,0.87182 -2.64015,1.60314 -2.20034,1.62516 0.43982,0.022 2.04759,-0.60529 3.57284,-1.39402 z m -3.36392,-2.43092 c 7.61004,-3.45714 13.65809,-12.5947 13.65809,-20.63499 0,-11.12314 -11.04986,-22.7 -21.66667,-22.7 -10.70226,0 -21.66666,11.57813 -21.66666,22.87946 0,4.64065 3.02363,11.97613 6.07456,14.73719 1.78745,1.61762 1.83913,1.5186 1.37172,-2.62829 -1.45227,-12.88452 7.92692,-22.30909 15.08152,-15.15449 4.84657,4.84656 5.99347,17.1236 2.14795,22.99261 -1.93035,2.94608 -0.65228,3.07608 4.99949,0.50854 z m -53.08133,-2.28112 c 3.70718,-6.27576 1.47296,-18.7986 -3.64361,-20.42254 -4.73397,-1.50251 -8.98587,3.85239 -9.06867,11.42119 -0.0712,6.50478 0.82438,8.55477 4.54657,10.40756 4.71129,2.34514 6.08999,2.10771 8.16571,-1.40621 z m 8.76107,0.52566 c 1.47857,-0.7519 4.15313,-3.11185 5.94345,-5.24433 3.16416,-3.76887 3.25672,-4.14456 3.31169,-13.44187 l 0.0566,-9.56463 -3.42512,-0.64252 c -6.57739,-1.23384 -11.12219,-3.74493 -15.41056,-8.51464 l -4.3202,-4.8051 -3.93064,1.7598 c -7.58534,3.39606 -13.58015,12.55734 -13.58015,20.75322 0,4.42188 3.08834,12.18072 5.7167,14.36206 1.23314,1.02342 1.44997,0.46906 1.44997,-3.70719 0,-9.99193 6.09864,-17.05981 12.75,-14.7763 5.96164,2.04672 9.18113,14.88436 5.77636,23.03311 -1.44844,3.46661 -1.43562,3.51518 0.75,2.84119 1.223,-0.37713 3.43338,-1.30089 4.91195,-2.0528 z m 37.28108,-0.95627 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 66.2806,0.88741 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z m -84.75,-1.68823 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 37,-1.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -83,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 41.40581,-3.29696 c 1.26469,0.48531 1.32727,0.18279 0.38844,-1.87771 -0.61552,-1.35092 -1.24526,-2.33009 -1.39942,-2.17593 -0.15416,0.15416 -1.48307,2.06857 -2.95312,4.25423 l -2.67282,3.97393 2.56468,-2.37651 c 1.43852,-1.33299 3.22665,-2.12249 4.07224,-1.79801 z m 103.59419,2.7059 c 0,-0.53273 -0.675,-0.70959 -1.5,-0.39301 -0.825,0.31659 -1.5,0.75246 -1.5,0.96862 0,0.21615 0.675,0.39301 1.5,0.39301 0.825,0 1.5,-0.43588 1.5,-0.96862 z m -59.19313,-4.55784 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z m -46.2027,-6.20271 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 48,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 45,-5 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 50,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -96,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 95,-5 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58438 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.0789,-1.91667 z m 49.01374,-4.98626 c -0.12014,-0.12014 -1.54582,0.178 -3.16817,0.66254 -1.62236,0.48454 -2.16224,0.91966 -1.19974,0.96694 0.9625,0.0473 1.76595,0.87345 1.78544,1.83595 0.0268,1.32558 0.37079,1.14405 1.41817,-0.74849 0.76051,-1.37418 1.28444,-2.5968 1.1643,-2.71694 z m 42.50618,0.44876 c -0.98762,-0.98026 -1.10248,-0.8654 -0.5598,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30789,-0.30789 6.4e-4,-1.11479 -0.68278,-1.79313 z M 65.08571,861.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -85,-2.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 38.4694,-2.07674 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 6.58891,-0.87068 c 2.30641,-2.50217 6.01686,-5.17968 8.48316,-6.12157 3.50845,-1.33988 4.61401,-2.37208 5.53737,-5.16987 3.7517,-11.36776 -3.1423,-24.22022 -15.17695,-28.29436 -4.64464,-1.57236 -5.7447,-1.61747 -9.7859,-0.40124 -14.93589,4.49504 -21.66079,20.75015 -13.81981,33.40461 l 2.18716,3.52985 0.74099,-5.89906 c 1.49666,-11.91498 8.85142,-17.25247 15.12639,-10.9775 4.48246,4.48246 5.8535,13.25622 3.22323,20.62656 -0.73605,2.0625 -1.17556,3.75 -0.9767,3.75 0.19886,0 2.20634,-2.00134 4.46106,-4.44742 z m -19.14164,3.16445 c -0.22917,-0.15563 -1.31667,-0.94313 -2.41667,-1.75 -1.85,-1.35701 -1.89707,-1.33579 -0.62755,0.28297 0.75484,0.9625 1.84234,1.75 2.41667,1.75 0.57432,0 0.85672,-0.12734 0.62755,-0.28297 z m 24.08333,-3.21703 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.94528,-0.0659 c -1.51303,-1.82309 -6.92706,-4.78561 -7.57027,-4.1424 -0.24152,0.24152 0.91037,0.99812 2.55977,1.68132 1.6494,0.68321 3.51893,1.86878 4.15451,2.6346 0.63558,0.76583 1.3806,1.39242 1.6556,1.39242 0.275,0 -0.0848,-0.70467 -0.79961,-1.56594 z m -75.94528,-0.9341 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 17,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 35.91667,-3.2579 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m -46,-1 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m 5.95162,-1.75427 c -1.01049,-2.21779 -1.20856,-2.27175 -2.75296,-0.75 -1.54948,1.52676 -1.49021,1.68325 0.86027,2.27141 1.38842,0.34743 2.62726,0.68493 2.75297,0.75 0.1257,0.0651 -0.26142,-0.95706 -0.86028,-2.27141 z m 49.04838,0.74819 c 0.22917,-0.19715 -0.55833,-0.35846 -1.75,-0.35846 -1.38524,0 -2.17763,-0.63115 -2.19707,-1.75 -0.0265,-1.52656 -0.17522,-1.49464 -1.16454,0.25 -0.62377,1.1 -1.62259,2.32475 -2.21959,2.72166 -0.59701,0.39691 0.71453,0.44572 2.91453,0.10846 2.2,-0.33726 4.1875,-0.77451 4.41667,-0.97166 z m 72.08333,-1.88414 c 0,-1.39308 -3.70207,-0.18103 -4.79566,1.57008 -1.24992,2.00144 -1.21295,2.01141 1.75946,0.47432 1.66991,-0.86354 3.0362,-1.78352 3.0362,-2.0444 z m 29.1875,0.84257 c -0.72188,-0.28888 -1.58438,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -19.9375,-2.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -84.64583,-3.06689 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 122.39583,-2.04448 c 0,-0.85783 -0.12734,-1.37218 -0.28297,-1.14302 -0.15563,0.22917 -0.89428,1.21447 -1.64144,2.18956 -1.18269,1.54348 -1.14607,1.69139 0.28297,1.14301 0.90279,-0.34643 1.64144,-1.33173 1.64144,-2.18955 z M 82.68988,837.89013 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 65.39583,1.38416 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11445 2.59501,2.70524 2.59501,1.90499 z m -66.39583,-7.38416 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 60.39583,0.35161 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z M 79.2098,826.35263 c -0.98761,-0.98026 -1.10248,-0.8654 -0.55979,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30788,-0.30789 6.3e-4,-1.11479 -0.68279,-1.79313 z m 56.87591,0.88911 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -97,-4.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 53.22334,-1.87639 c -0.26254,-1.00396 -0.54753,-1.69503 -0.63331,-1.53571 -0.0858,0.15931 -0.6787,0.98073 -1.3176,1.82537 -0.93948,1.24202 -0.81836,1.53572 0.63331,1.53572 1.24538,0 1.6488,-0.55888 1.3176,-1.82538 z M 43.08571,819.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.75848,-0.53051 c -0.94115,-1.51852 -0.96737,-2.21193 -0.10397,-2.75 0.63498,-0.39572 -0.80847,-0.71949 -3.20766,-0.71949 l -4.36218,0 3.39287,1.74065 c 1.86608,0.95735 3.67359,2.19485 4.01668,2.75 0.3431,0.55514 0.82607,1.00935 1.07327,1.00935 0.24721,0 -0.11685,-0.91373 -0.80901,-2.03051 z m 52.17485,-0.31215 c -0.23833,-0.20679 -1.78333,-0.65233 -3.43333,-0.99008 -2.73596,-0.56005 -2.80197,-0.51498 -0.75,0.51213 1.2375,0.61943 2.25,1.59747 2.25,2.17342 0,0.65288 0.44557,0.60162 1.18333,-0.13614 0.65084,-0.65084 0.98834,-1.35253 0.75,-1.55933 z m 9.94836,-7.40734 c 2.30606,-3.4375 3.82136,-6.25 3.36733,-6.25 -1.81925,0 -11.24902,12.98428 -11.24902,15.48929 0,1.26984 3.89338,-3.29416 7.88169,-9.23929 z m -84.96502,4.11454 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35466 2.91667,-1.55517 z m 2.58333,-1.36454 c -0.33991,-0.55 -0.81647,-1 -1.05901,-1 -0.24254,0 -0.44099,0.45 -0.44099,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m 6.82946,-1.58385 c -0.33428,-0.87111 -0.88789,-1.20861 -1.23025,-0.75 -0.34236,0.45862 -1.02974,1.17135 -1.52751,1.58385 -0.49776,0.4125 0.0558,0.75 1.23025,0.75 1.53743,0 1.96511,-0.44346 1.52751,-1.58385 z m 20.85804,0.90074 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28495 0.60416,-0.60417 z m 29,0 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -22.9375,-0.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m 18,0 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -8.5,-1.02705 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z M 53.3824,808.21186 c -0.98818,-1.3241 -1.94149,-2.01468 -2.11847,-1.53464 -0.36611,0.99302 1.91319,3.8465 3.11847,3.90404 0.43818,0.0209 -0.0118,-1.04531 -1,-2.3694 z m -3.29669,-3.66948 c 0,-1.50044 -5.57099,-6.92308 -7.11248,-6.92308 -0.69649,0 0.5064,1.73277 2.67307,3.8506 4.69729,4.5914 4.43941,4.41292 4.43941,3.07248 z m 92,-3.42308 c 1.29175,-1.375 2.12363,-2.5 1.84863,-2.5 -0.275,0 -1.55688,1.125 -2.84863,2.5 -1.29175,1.375 -2.12363,2.5 -1.84863,2.5 0.275,0 1.55688,-1.125 2.84863,-2.5 z m 6.04469,-1.70523 c 2.56704,-3.19434 2.82393,-3.81616 1.06867,-2.58673 -1.89119,1.32465 -5.69179,6.79196 -4.72142,6.79196 0.15033,0 1.79407,-1.89235 3.65275,-4.20523 z m -0.0447,-8.71959 c 0,-0.275 -2.25,1.71617 -5,4.42482 -2.75,2.70865 -5,5.14982 -5,5.42482 0,0.275 2.25,-1.71617 5,-4.42482 2.75,-2.70865 5,-5.14982 5,-5.42482 z m 1,3.42482 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 21.91908,-7.85167 c 2.4305,-0.72671 4.0055,-1.56089 3.5,-1.85373 -0.50549,-0.29284 -2.71908,0.27521 -4.91908,1.26232 -4.84957,2.17594 -4.44469,2.34468 1.41908,0.59141 z m 6.88779,-1.17479 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z M 17.08571,783.6193 c -1.925,-1.05389 -3.95,-1.91617 -4.5,-1.91617 -0.55,0 0.575,0.86228 2.5,1.91617 1.925,1.05389 3.95,1.91617 4.5,1.91617 0.55,0 -0.575,-0.86228 -2.5,-1.91617 z m 160,-2 c 0,-0.55 -0.7875,-0.99311 -1.75,-0.98469 -1.49555,0.0131 -1.5319,0.15626 -0.25,0.98469 1.88721,1.21961 2,1.21961 2,0 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2907"
+ transform="translate(0,784.36218)"
+ d="m 72.6,181.20757 c -16.765609,-3.86833 -22.376319,-6.32293 -32,-13.9995 l -2,-1.59535 13.2,-0.0317 c 17.959636,-0.043 26.293525,-1.0427 36.676385,-4.39926 12.401975,-4.00929 20.661075,-10.22837 22.672535,-17.07236 1.39926,-4.76097 -0.60247,-5.05117 -14.284918,-2.07088 C 80.913403,145.51284 69.067454,145.46531 50.6,141.85286 39.54215,139.68982 28.750784,134.8087 27.432732,131.37391 c -0.409763,-1.06782 0.94297,-9.55504 1.67366,-10.50077 0.129162,-0.16717 4.118063,-0.56369 8.864224,-0.88115 9.677258,-0.64731 12.721718,-1.79467 18.59718,-7.00868 l 3.565638,-3.16423 4.911016,4.16615 c 6.374081,5.4073 11.045891,7.19552 18.75555,7.17903 10.247136,-0.0219 18.94097,-5.4255 24.01507,-14.92636 2.33003,-4.3628 2.74898,-6.0141 3.03751,-11.972478 0.24409,-5.040832 -0.0244,-7.992693 -0.99183,-10.905433 C 106.83021,74.235948 98.683943,66.74733 89.719703,64.844988 L 85,63.8434 84.966254,55.710271 C 84.929438,46.837023 83.908403,43.511262 79.05568,36.458071 76.206234,32.316543 75.915993,32.561487 85.4,31.103895 c 9.620682,-1.478597 19.97708,-0.291557 29.26619,3.354462 4.00483,1.571915 4.0652,1.646353 4,4.932693 -0.0764,3.849526 1.76499,4.910844 4.39333,2.532225 0.84726,-0.766762 1.54048,-1.021054 1.54048,-0.565095 0,0.45596 1.6637,1.247942 3.6971,1.759959 4.38748,1.10478 11.00212,7.029509 17.23538,15.437707 l 4.03312,5.440379 -4.6828,5.026303 c -4.55714,4.891416 -8.2828,11.01514 -8.2828,13.614092 0,1.528769 2.86706,3.239468 4.42637,2.641103 0.60573,-0.232443 1.86318,-1.915954 2.79432,-3.741133 2.17353,-4.260467 7.69681,-10.272278 10.77931,-11.732734 1.32,-0.625402 3.4424,-1.697018 4.71645,-2.381368 2.96143,-1.590728 11.65807,-1.536216 19.53585,0.122452 7.69091,1.619321 10.4686,1.555228 15.93996,-0.367797 5.65346,-1.987032 5.64225,-1.987649 3.63541,0.2 -0.90817,0.99 -3.01076,3.96 -4.67241,6.6 -1.66166,2.64 -5.30895,6.908849 -8.1051,9.486333 -2.79614,2.577483 -5.99227,6.236344 -7.1025,8.130802 -4.94788,8.442912 -15.3818,14.634562 -28.34766,16.821932 -7.93582,1.33879 -10.1786,2.49921 -9.29263,4.80802 0.46879,1.22165 1.5792,1.32779 10.18353,0.97342 l 9.65736,-0.39773 -0.5479,3.65369 c -1.59381,10.62824 -7.28652,24.58268 -14.24705,34.92353 -11.30309,16.79232 -34.07569,29.48213 -55.75331,31.06798 -4.998646,0.36568 -7.935952,-0.008 -17.6,-2.23755 z m 81.50924,-82.494134 c 3.52664,-1.764307 6.56239,-3.962996 7.90749,-5.727124 1.2008,-1.574879 3.53327,-4.37647 5.18327,-6.225757 1.93865,-2.172795 3,-4.147985 3,-5.583022 0,-2.220043 -0.002,-2.220533 -4.38306,-1.705537 -8.74931,1.028309 -19.06055,6.827181 -22.74752,12.792833 l -1.71519,2.775229 1.70366,3.268542 c 2.14696,4.11903 3.52613,4.16955 11.05135,0.404836 l 0,0 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2913"
+ transform="translate(0,784.36218)"
+ d="m 160.6,87.334076 c 0,-0.534851 -1.1468,-0.981516 -2.6,-1.012667 -2.30544,-0.04942 -2.02164,-0.279224 2.50495,-2.028386 2.80772,-1.084959 5.23233,-1.845272 5.38801,-1.689584 0.15569,0.155688 -0.97154,1.499081 -2.50494,2.98532 C 161.85461,87.074997 160.6,87.86039 160.6,87.334076 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3703"
+ transform="translate(0,784.36218)"
+ d="m 24.692801,119.04257 c -0.05104,-2.05401 -0.313955,-4.31089 -0.584255,-5.01528 -0.431011,-1.12319 -0.185552,-1.10664 1.99579,0.13457 1.631194,0.92818 2.07587,1.50427 1.292,1.67384 -0.657385,0.1422 -1.361474,1.0422 -1.564643,2 -0.203169,0.95779 -0.521653,2.46144 -0.707744,3.34144 -0.186091,0.88 -0.380107,-0.0805 -0.431148,-2.13457 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3709"
+ transform="translate(0,784.36218)"
+ d="m 104.6,146.52914 c 0,-0.55196 -0.79531,-1.29776 -1.76736,-1.65735 -1.56978,-0.5807 -1.42649,-0.71774 1.28174,-1.2258 3.83551,-0.71955 4.4795,-0.10717 2.24118,2.13115 -1.00812,1.00812 -1.75556,1.32829 -1.75556,0.752 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3719"
+ transform="translate(0,784.36218)"
+ d="m 76.851058,112.03382 c -3.393188,-2.09142 -4.25448,-3.92327 -4.233488,-9.00408 0.03274,-7.923733 4.577488,-13.887568 8.633406,-11.329161 3.986638,2.514706 5.541626,13.083911 2.747781,18.676561 -1.667169,3.3373 -3.668438,3.80115 -7.147699,1.65668 l 0,0 z" />
+ <path
+ style="fill:#00d37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3721"
+ transform="translate(0,784.36218)"
+ d="m 31.011129,112.18685 c -3.337597,-1.68708 -4.784967,-4.28598 -4.794874,-8.60971 -0.01706,-7.444764 3.322321,-12.761965 7.700427,-12.261175 5.345895,0.611491 7.922362,14.073845 3.761169,19.652565 -2.071377,2.777 -3.181718,2.97991 -6.666722,1.21832 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3747"
+ transform="translate(0,784.36218)"
+ d="M 49.694395,74.66073 C 44.47115,71.825511 44.018691,61.3525 48.893397,56.120117 c 1.243238,-1.334459 2.71535,-2.426289 3.27136,-2.426289 3.274952,0 7.59925,10.034368 6.191417,14.366947 -2.961401,9.11366 -3.406311,9.452665 -8.661779,6.599955 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3749"
+ transform="translate(0,784.36218)"
+ d="m 30.863598,109.87939 c -4.598088,-3.22062 -2.443473,-16.412835 2.680623,-16.412835 3.343974,0 5.248203,11.238065 2.708365,15.983795 -1.423064,2.65902 -2.125412,2.71494 -5.388988,0.42904 l 0,0 z" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3751"
+ transform="translate(0,784.36218)"
+ d="M 53.409091,253.22727 C 175,254.36364 176.13636,254.36364 176.13636,254.36364" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3753"
+ transform="translate(0,784.36218)"
+ d="m 101.91757,251.70568 c -21.718752,-0.17272 -39.488638,-0.58449 -39.488638,-0.91506 0,-0.33057 3.818082,-4.96825 8.484628,-10.30595 4.666545,-5.33771 9.973982,-12.85892 11.794303,-16.71379 3.448266,-7.30236 8.521552,-22.38453 9.820557,-29.19514 0.752563,-3.94565 0.76643,-3.95339 12.3156,-6.87496 6.3592,-1.60867 12.35971,-3.28795 13.33446,-3.73173 1.29391,-0.58909 2.73131,0.66046 5.32536,4.62941 1.9542,2.98995 11.57847,13.87378 21.38726,24.18628 9.8088,10.3125 18.96093,20.28409 20.33807,22.15909 2.01779,2.74727 7.42703,15.23542 7.42703,17.14657 0,0.25689 -7.03125,0.34607 -15.625,0.19819 -8.59375,-0.14789 -33.39488,-0.4102 -55.11363,-0.58291 l 0,0 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3782"
+ transform="translate(0,784.36218)"
+ d="m 51.774116,254.22272 c 0.816832,-1.01161 5.399709,-6.3219 10.184171,-11.80065 4.784463,-5.47875 10.255577,-12.2121 12.158031,-14.963 5.284789,-7.64167 14.376394,-33.83808 12.993969,-37.44062 -0.338967,-0.88334 -2.48378,-1.73514 -5.328004,-2.116 C 60.981864,185.11713 50.75895,182.31448 43.625018,177.44148 37.971557,173.57975 28.01174,163.28381 28.01174,161.3013 c 0,-1.83865 0.635315,-1.8844 17.079208,-1.22988 19.475363,0.77518 28.155408,-0.12388 38.075567,-3.94376 9.279191,-3.57307 15.45203,-6.36285 15.01445,-6.78568 -0.201984,-0.19518 -4.599918,0.0895 -9.773185,0.63261 -15.856397,1.66468 -37.875872,-0.52821 -50.869606,-5.06603 -3.201056,-1.11791 -7.99066,-3.68786 -10.643565,-5.71099 l -4.823463,-3.67842 0.178374,-9.45002 0.178374,-9.45001 0.5642,7.42574 c 0.582301,7.66397 1.29799,8.16822 2.459224,1.73268 0.423991,-2.34976 0.289983,-3.71287 -0.365011,-3.71287 -0.569229,0 -1.034963,-1.33664 -1.034963,-2.9703 0,-1.63367 -0.407778,-2.9703 -0.906174,-2.9703 -1.708089,0 -9.947718,-12.02652 -11.073528,-16.16286 C 8.4406212,86.620448 14.328838,72.981775 26.509135,66.520142 l 4.472902,-2.372869 0,-7.169297 c 0,-11.907876 4.934342,-21.608335 13.56406,-26.665688 2.388815,-1.399939 4.1792,-3.048653 3.978634,-3.66381 C 47.539733,23.627398 33.787529,13.942425 21.173642,7.3865059 6.6394252,-0.16748247 5.7525435,-1.0667564 8.2445952,-5.7231976 9.9048868,-8.825481 13.26451,-8.0142814 26.786199,-1.2462239 42.52818,6.6331633 49.704459,11.834699 56.658674,20.406047 c 7.066894,8.71023 9.386734,9.398438 22.022822,6.533328 12.009438,-2.723024 25.519864,-2.231151 36.616764,1.3331 4.17096,1.339683 7.95921,2.16177 8.41835,1.826861 0.45913,-0.33491 2.70455,-3.059423 4.98981,-6.054473 2.28526,-2.995049 7.42528,-8.682601 11.42226,-12.639003 7.12067,-7.0483759 7.54019,-7.2929957 20.80065,-12.12871266 7.44339,-2.71438994 14.38913,-4.93525434 15.435,-4.93525434 1.40526,0 2.17641,1.0827118 2.95451,4.1481669 0.5791,2.28149179 0.85167,4.4737776 0.60572,4.871746 -0.24596,0.3979683 -6.12349,2.612099 -13.0612,4.92029 -12.32753,4.1014041 -12.76057,4.3449071 -19.06805,10.7223141 -3.54973,3.589081 -8.19833,9.098685 -10.33023,12.243564 l -3.87618,5.717962 4.38964,4.574292 c 2.4143,2.515859 3.60993,4.300819 2.65696,3.966577 -2.15679,-0.756469 -2.25789,0.631979 -0.17206,2.363061 1.27233,1.05594 1.70648,1.059167 2.35028,0.01747 0.5549,-0.897844 2.45839,0.813688 6.40236,5.756734 3.08697,3.868951 6.15063,7.065929 6.80813,7.104394 0.6575,0.03847 4.65679,0.0099 8.8873,-0.0634 4.23053,-0.07334 11.0745,0.619228 15.20883,1.53903 6.08457,1.353687 8.24222,1.455077 11.32293,0.532074 4.78641,-1.434041 9.61096,-5.430654 10.01889,-8.299556 0.1988,-1.398101 1.12005,-2.308693 2.53968,-2.510314 2.12619,-0.301966 2.22772,-0.004 2.22772,6.538442 0,6.740641 -0.099,7.001552 -5.9449,15.662921 -3.26969,4.844452 -7.74462,10.309246 -9.94428,12.143987 -2.19966,1.834742 -5.77393,5.949037 -7.94282,9.142879 -2.34976,3.460168 -6.29513,7.465423 -9.76248,9.910673 l -5.81903,4.10369 -1.15924,7.92805 c -1.61723,11.06032 -4.40347,19.58965 -9.70377,29.70553 -5.01528,9.57187 -13.95714,20.46445 -14.03497,17.09676 -0.0428,-1.8524 -0.1273,-1.86246 -1.77762,-0.21171 -1.37485,1.3752 -1.46515,1.89852 -0.43722,2.53406 1.41537,0.87508 -1.77232,4.09197 -9.46671,9.55344 -2.27836,1.61719 -4.34463,3.44333 -4.59171,4.0581 -0.8189,2.03758 6.19452,11.05322 18.90021,24.29583 6.90108,7.19272 12.04414,13.24542 11.42903,13.45046 -0.61512,0.20504 -0.83848,1.12371 -0.49637,2.0415 0.34212,0.91778 -1.79925,-0.97306 -4.75858,-4.20188 -2.95935,-3.22881 -5.27705,-6.21281 -5.15046,-6.6311 0.12659,-0.41828 -1.76241,-2.39328 -4.19777,-4.38889 -2.43538,-1.9956 -4.20453,-3.98988 -3.93146,-4.43172 0.27308,-0.44185 -1.40227,-2.36965 -3.72301,-4.28402 -2.32073,-1.91436 -5.99559,-5.73898 -8.16635,-8.49916 -4.50513,-5.7284 -5.73975,-6.34273 -10.18478,-5.06791 -1.75731,0.50399 -3.19511,0.54209 -3.19511,0.0847 0,-1.33295 -11.17951,1.64109 -12.389579,3.29596 -0.60449,0.82669 -2.322383,1.8101 -3.817542,2.18536 -3.551652,0.89142 -4.937215,3.23379 -7.580515,12.81533 -4.406767,15.97381 -11.099683,29.94917 -15.20688,31.75323 -1.152028,0.50601 -2.096442,1.7759 -2.098696,2.82193 -0.0024,1.08338 -1.280677,2.61084 -2.970297,3.54913 -1.631409,0.90597 -2.982805,2.27784 -3.003103,3.04859 -0.05664,2.15103 -3.526894,6.90294 -4.570213,6.25813 -0.985639,-0.60915 -3.808724,1.30636 -3.808724,2.5843 0,1.92758 5.895059,2.34928 41.089109,2.93925 l 37.62376,0.63071 -39.232671,0.18757 c -21.57797,0.10316 -40.736386,0.48547 -42.574257,0.84959 -3.159411,0.62595 -3.260618,0.56176 -1.856436,-1.17724 z m 42.238485,-67.99171 c -1.942887,-0.70765 -3.471758,-0.70422 -4.950495,0.0112 -1.790743,0.86631 -1.332552,1.03319 2.81102,1.02385 4.566697,-0.0103 4.732564,-0.0905 2.139475,-1.03501 l 0,-3e-5 z m -14.020663,-0.82863 c -1.089109,-0.4866 -6.435644,-1.80129 -11.881188,-2.92155 -5.759121,-1.18476 -12.800298,-3.45953 -16.831683,-5.43774 -6.954731,-3.41271 -17.742094,-11.92119 -16.880858,-13.3147 0.253072,-0.40948 3.040932,-0.57204 6.195246,-0.36125 4.48988,0.30005 5.355073,0.14443 3.984772,-0.71671 -0.96269,-0.60499 -4.913826,-1.36519 -8.780302,-1.68935 -6.863409,-0.57539 -7.004171,-0.54119 -5.941584,1.44428 2.200044,4.11082 13.668199,13.46069 20.585236,16.78294 7.129107,3.42411 21.632479,7.0912 28.065212,7.09613 2.851296,0.002 3.114461,-0.15412 1.485149,-0.88205 z m 13.55198,-1.63782 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52001 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 8.981792,-3.22305 c 4.1272,-1.05557 9.34757,-2.85973 11.60083,-4.00925 2.25325,-1.14953 4.87457,-1.8432 5.82513,-1.54151 0.95056,0.30171 2.59602,-0.12295 3.65656,-0.94367 1.60041,-1.23851 1.63367,-1.38963 0.19559,-0.88881 -2.84772,0.99172 -1.97918,-0.17229 2.18456,-2.92772 2.15449,-1.42577 4.50534,-2.36663 5.22413,-2.09081 0.7188,0.27584 3.05637,-1.2901 5.1946,-3.47985 2.13823,-2.18975 3.51995,-3.98136 3.07047,-3.98136 -0.44946,0 -0.26663,-0.66342 0.4063,-1.47425 0.67294,-0.81083 1.5681,-1.26129 1.98925,-1.001 0.42114,0.26029 1.37313,-0.30156 2.11553,-1.24853 1.22149,-1.55808 1.18509,-1.59258 -0.38286,-0.36292 -0.95297,0.74738 -1.73267,0.91332 -1.73267,0.36877 0,-1.1032 2.94273,-3.80059 3.86504,-3.5428 0.32472,0.0908 0.81317,-0.0921 1.08545,-0.40626 0.27228,-0.3142 -0.0619,-0.25079 -0.74257,0.14094 -1.83418,1.05552 -1.52708,0.0245 1.35025,-4.53358 3.80038,-6.02017 8.15245,-16.13427 10.34121,-24.03269 2.90781,-10.4932 3.24131,-10.00199 -6.51584,-9.59724 -8.06376,0.33451 -11.36374,-0.51104 -11.36374,-2.91169 0,-1.41219 3.87705,-3.01077 12.01762,-4.9551 13.6173,-3.2524 18.1279,-6.30458 30.44942,-20.604205 3.20647,-3.721241 5.60795,-5.75908 6.01348,-5.102907 0.45242,0.732027 1.17307,0.513084 2.18435,-0.663636 2.69435,-3.135129 3.29702,-4.863342 0.99046,-2.840244 -1.18271,1.037369 -2.15038,1.440581 -2.15038,0.896027 0,-1.154396 3.94299,-4.919356 4.6419,-4.432319 0.26048,0.181519 0.77064,-0.0013 1.13367,-0.406262 0.36304,-0.404963 0.10314,-0.415797 -0.57755,-0.02408 -1.80598,1.039294 -1.51814,-0.190163 0.80999,-3.459724 2.31999,-3.258114 2.32271,-3.256657 -3.39724,-1.816357 -3.2192,0.810603 -6.66348,0.694459 -14.67251,-0.494768 -15.04707,-2.234274 -20.55437,-0.689621 -28.57683,8.015049 -2.42602,2.632325 -4.72907,4.680174 -5.11788,4.550775 -0.38882,-0.129399 -0.48449,0.344426 -0.2126,1.052946 0.27188,0.70852 -0.4282,2.123094 -1.55573,3.143497 -2.0095,1.818571 -2.09324,1.812104 -4.23219,-0.326854 l -2.18214,-2.182131 2.25594,-4.252496 c 1.24077,-2.338872 4.17354,-6.452573 6.51728,-9.141556 2.34372,-2.688985 4.05061,-5.50801 3.79308,-6.264503 -0.31259,-0.918192 -0.0455,-1.114196 0.80328,-0.589595 0.85837,0.530499 1.02875,0.393018 0.52435,-0.423105 -0.41094,-0.664922 -0.99572,-0.9604 -1.2995,-0.656618 -0.69266,0.69266 -3.20978,-1.330935 -3.20978,-2.580451 0,-0.510014 0.51439,-0.609392 1.14308,-0.220837 0.73045,0.451439 0.87336,0.270048 0.3959,-0.50249 -0.41094,-0.664922 -1.00055,-0.955563 -1.31024,-0.645868 -0.69833,0.698319 -4.18913,-2.365165 -4.18913,-3.67632 0,-0.526833 0.7797,-0.370613 1.73267,0.347155 0.95297,0.717767 -0.70223,-1.23225 -3.67822,-4.333371 -3.76003,-3.918124 -5.93501,-5.472057 -7.12873,-5.093182 -0.94481,0.299873 -3.07003,-0.15402 -4.7227,-1.00865 -2.43778,-1.26062 -3.37289,-1.324035 -4.95495,-0.33602 -2.36555,1.477307 -3.05981,0.886 -3.92467,-3.34268 -0.56625,-2.768728 -1.37248,-3.513567 -5.43639,-5.022464 -7.80616,-2.898363 -17.966683,-4.011606 -26.200113,-2.870631 -3.997279,0.553936 -7.475959,1.215337 -7.730402,1.469779 -0.254442,0.254443 0.998085,3.050852 2.783393,6.214244 2.874608,5.093525 3.291609,6.794112 3.644505,14.862796 l 0.398492,9.111176 3.564442,0.668693 c 7.773644,1.458345 16.010573,8.110583 19.620143,15.845464 3.09701,6.636514 3.26024,18.338664 0.34238,24.546143 -2.99996,6.38214 -7.1277,10.84757 -13.007325,14.07144 -4.530381,2.48406 -6.383854,2.90835 -12.728271,2.91366 -6.074888,0.005 -8.236255,-0.44332 -11.881188,-2.465 -2.450495,-1.35916 -4.455445,-2.98232 -4.455445,-3.60701 0,-0.62469 -0.40559,-1.50708 -0.901312,-1.96089 -0.523658,-0.47936 -0.602889,-0.3065 -0.189092,0.41255 0.391721,0.68069 0.309434,1.23762 -0.182859,1.23762 -1.220735,0 -4.304298,-3.49834 -3.655466,-4.14718 0.286625,-0.28662 -0.191905,-1.11291 -1.063399,-1.83618 -1.321234,-1.09653 -1.725666,-1.0867 -2.433844,0.0592 -0.46712,0.75582 -0.647589,1.7006 -0.401041,2.09952 0.480206,0.77699 -4.431607,4.73002 -8.49972,6.84057 -1.361386,0.7063 -6.473966,1.77939 -11.361289,2.38466 l -8.886042,1.10047 -0.8419,4.2572 c -1.116431,5.64542 -0.634772,6.55826 4.953601,9.38814 6.711939,3.39884 14.108367,5.45589 25.541571,7.10346 13.412147,1.93275 20.966236,1.82034 33.743152,-0.50211 17.901519,-3.25395 20.945769,-2.59407 18.234109,3.95245 -1.77158,4.27697 -8.27108,9.72932 -15.51118,13.01214 -10.066949,4.56456 -20.604188,6.60666 -38.045678,7.37316 -12.034826,0.52888 -15.515628,0.97079 -14.765554,1.87458 0.53979,0.65041 0.751763,1.41223 0.47105,1.69294 -0.280712,0.28071 0.280084,1.1308 1.246214,1.8891 1.597283,1.25367 1.633357,1.22157 0.397743,-0.35396 -1.901096,-2.42408 -0.973659,-2.18092 4.907357,1.28665 4.510039,2.65922 13.386837,5.60901 26.15447,8.69123 6.758464,1.63156 18.458956,1.2966 26.494168,-0.75846 l 0,-4e-5 z m 15.58504,-0.061 c 1.16161,-0.7507 0.90473,-0.96308 -1.17919,-0.97494 -1.46538,-0.008 -2.9397,0.43038 -3.27626,0.97494 -0.78135,1.26425 2.49915,1.26425 4.45545,0 z m 6.00568,-2.01503 c 1.95644,-1.04706 2.62207,-2.93547 1.0347,-2.93547 -0.48422,0 -1.93224,0.87627 -3.21783,1.94726 -2.49465,2.07826 -1.06383,2.72592 2.18313,0.98821 z m -6.00568,-1.45032 c 1.36139,-0.77824 2.0297,-1.41498 1.48515,-1.41498 -0.54456,0 -2.10396,0.63674 -3.46535,1.41498 -1.36138,0.77824 -2.0297,1.41498 -1.48515,1.41498 0.54456,0 2.10396,-0.63674 3.46535,-1.41498 z m -62.458746,0.13411 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553336,0.36093 1.577225,1.26362 4.799862,2.3676 3.441125,1.17883 l 0,0 z m 74.762706,-3.12566 c 1.04936,-0.7939 1.64445,-1.70691 1.32243,-2.02893 -0.78266,-0.78265 -4.7155,1.36919 -4.7155,2.58006 0,1.33049 1.15362,1.1431 3.39307,-0.55113 z m 5.3845,-4.97977 c 0.31295,-1.61495 0.14607,-1.68767 -1.23763,-0.53929 -1.89234,1.57049 -2.12795,3.40609 -0.36172,2.81801 0.68069,-0.22665 1.40039,-1.25207 1.59935,-2.27872 z m -93.926084,0.17176 c 0,-0.2056 -0.779703,-0.9853 -1.732673,-1.73268 -1.570353,-1.23155 -1.605372,-1.19653 -0.373817,0.37382 1.293435,1.64926 2.10649,2.17375 2.10649,1.35886 z m 42.048957,-9.0646 c 10.23476,-3.01561 12.830661,-4.22882 16.665417,-7.78864 1.52559,-1.41621 3.14513,-2.57492 3.599,-2.57492 0.45387,0 1.59099,-1.16873 2.52694,-2.59715 0.93594,-1.42844 1.24801,-2.31675 0.69349,-1.97403 -0.55454,0.34271 -1.20807,0.0635 -1.45231,-0.62067 -0.24423,-0.68409 -0.82632,-0.88541 -1.2935,-0.44739 -0.46721,0.43803 -0.19404,1.21091 0.60702,1.71751 1.25252,0.79212 1.23533,0.92323 -0.12275,0.93627 -0.86857,0.008 -2.42798,0.95441 -3.46535,2.10238 -5.028165,5.56424 -22.795527,11.3182 -38.212356,12.37508 -15.799597,1.08311 -17.048668,2.42489 -1.792578,1.92561 10.641937,-0.34827 15.176438,-0.97076 22.246977,-3.05405 l 0,0 z m 63.891637,-3.12611 c 0,-1.41552 -0.23243,-1.39342 -1.9802,0.18829 -1.08911,0.98563 -1.9802,2.18422 -1.9802,2.66353 0,0.47932 0.89109,0.39459 1.9802,-0.18828 1.08911,-0.58287 1.9802,-1.78147 1.9802,-2.66354 z M 97.166642,146.77097 c 3.547598,-0.77002 4.965228,-1.47727 4.298178,-2.14431 -0.66706,-0.66706 -4.175166,-0.42281 -10.636358,0.74056 -14.897153,2.68229 -37.124591,0.77195 -52.477337,-4.51017 -6.578027,-2.26317 -6.378989,-2.22908 -6.378989,-1.09252 0,1.42916 9.008565,4.85904 15.926311,6.06371 16.965213,2.95437 38.134158,3.35943 49.268195,0.94273 l 0,0 z m 53.617378,0.0462 c 0.58287,-1.08911 0.837,-1.9802 0.56472,-1.9802 -0.27228,0 -0.97195,0.89109 -1.55482,1.9802 -0.58287,1.08911 -0.837,1.9802 -0.56472,1.9802 0.27227,0 0.97195,-0.89109 1.55482,-1.9802 z m 5.94059,-4.62356 c 0,-2.3135 -1.69554,-0.59965 -2.85822,2.88907 l -1.073,3.21964 1.96562,-2.33741 c 1.08108,-1.28558 1.9656,-2.98266 1.9656,-3.7713 z m -77.497329,2.91089 c -2.054226,-0.21433 -5.173038,-0.21074 -6.930694,0.008 -1.757656,0.21872 -0.07693,0.39409 3.734955,0.38969 3.811881,-0.004 5.249963,-0.18335 3.195739,-0.39768 l 0,7e-5 z m 10.356241,-0.94387 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52002 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 19.616338,-1.30386 c 0,-0.54455 -0.47184,-0.99009 -1.04854,-0.99009 -0.57669,0 -0.77316,0.44554 -0.43661,0.99009 0.33655,0.54456 0.8084,0.9901 1.04853,0.9901 0.24014,0 0.43662,-0.44554 0.43662,-0.9901 z m 47.45458,-8.41584 c 0,-0.54455 -0.63674,0.12377 -1.41498,1.48515 -0.77823,1.36139 -1.41498,2.92079 -1.41498,3.46535 0,0.54455 0.63675,-0.12376 1.41498,-1.48515 0.77824,-1.36139 1.41498,-2.92079 1.41498,-3.46535 z M 28.453542,136.6394 c -0.717346,-1.86938 -3.412099,-3.08084 -3.412099,-1.53397 0,1.05715 3.177874,3.9134 3.73462,3.35666 0.149813,-0.14981 0.0047,-0.97003 -0.322521,-1.82269 z m 6.406383,0.90594 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553337,0.36093 1.577226,1.26362 4.799863,2.3676 3.441126,1.17883 z m -8.178941,-9.80642 c -0.27121,-0.67032 -0.476602,0.11785 -0.456423,1.75152 0.02018,1.63366 0.242077,2.18212 0.493111,1.21878 0.251032,-0.96334 0.234523,-2.29997 -0.03668,-2.9703 l -4e-6,0 z M 162.66521,127.0736 c 0,-0.51242 -0.44555,-1.20703 -0.9901,-1.54359 -0.54456,-0.33655 -0.9901,0.0827 -0.9901,0.93167 0,0.84897 0.44554,1.54358 0.9901,1.54358 0.54455,0 0.9901,-0.41925 0.9901,-0.93166 z M 27.619826,122.33281 c -0.329002,-0.329 -0.563011,0.25579 -0.52002,1.29951 0.0475,1.15341 0.28212,1.38802 0.598185,0.59819 0.286011,-0.71474 0.250836,-1.5687 -0.07817,-1.8977 l 3e-6,0 z m 136.035474,0.2269 c 0,-0.81683 -0.44554,-1.48514 -0.99009,-1.48514 -0.54456,0 -0.9901,0.66831 -0.9901,1.48514 0,0.81684 0.44554,1.48515 0.9901,1.48515 0.54455,0 0.99009,-0.66831 0.99009,-1.48515 z M 33.704809,119.40196 c -0.95297,-0.24903 -2.512376,-0.24903 -3.465346,0 -0.952971,0.24904 -0.173268,0.4528 1.732673,0.4528 1.905941,0 2.685644,-0.20376 1.732673,-0.4528 z m 51.237624,-0.30759 c 0.336553,-0.54456 -0.250915,-0.9901 -1.305483,-0.9901 -1.054569,0 -2.472053,-0.66832 -3.149963,-1.48515 -0.677909,-0.81683 -2.197663,-1.48515 -3.37723,-1.48515 -1.179567,0 -3.798279,-0.84306 -5.819362,-1.87346 -3.979476,-2.02885 -4.801958,-1.43381 -1.788124,1.29368 1.984228,1.7957 10.984716,4.90909 10.984716,3.79975 0,-0.35514 0.534654,-0.11106 1.188119,0.54241 1.44777,1.44777 2.457132,1.50894 3.267327,0.19802 z m 79.702967,-3.02873 c 0,-1.05697 -0.44554,-1.92177 -0.9901,-1.92177 -0.54455,0 -0.99009,1.14016 -0.99009,2.53369 0,1.43699 0.42855,2.26881 0.99009,1.92176 0.54456,-0.33656 0.9901,-1.47671 0.9901,-2.53368 z m -126.008939,1.3525 c -0.963334,-0.25103 -2.299968,-0.23452 -2.970297,0.0366 -0.670329,0.27122 0.117853,0.47661 1.751517,0.45643 1.633663,-0.0202 2.182114,-0.24208 1.21878,-0.49311 l 0,5e-5 z m 15.788583,-6.49209 c 2.961802,-2.58663 6.027485,-4.70297 6.812628,-4.70297 1.653245,0 1.836694,-1.82146 0.39887,-3.96039 -0.83888,-1.24794 -1.390264,-1.01072 -3.45205,1.48514 -1.349539,1.63367 -2.677116,3.63862 -2.950173,4.45545 -0.273055,0.81683 -3.168256,2.95063 -6.433779,4.74178 -3.265523,1.79115 -5.937315,3.64601 -5.937315,4.12192 0,1.77959 6.361283,-1.59914 11.561819,-6.14093 z m -20.47271,5.3104 c 0,-1.48733 -5.81027,-1.8801 -6.366582,-0.43038 -0.356538,0.92913 0.492992,1.3081 2.93231,1.3081 1.888849,0 3.434272,-0.39498 3.434272,-0.87772 z m 63.050779,-1.35 c 2.916955,-1.98579 4.205247,-3.71287 2.769577,-3.71287 -0.693665,0 -8.394613,5.11626 -8.394613,5.57711 0,1.01623 2.716191,0.11603 5.625036,-1.86424 z m -5.082551,-1.19364 c 7.593085,-3.17259 13.318898,-12.23833 13.318898,-21.087947 0,-14.183278 -14.801367,-26.126413 -27.276503,-22.009246 -4.871629,1.607782 -12.143736,8.333235 -14.435363,13.350236 -3.260107,7.137268 -1.947056,16.953627 3.009811,22.501317 l 2.75988,3.08884 0.514066,-6.40417 c 0.59176,-7.372086 2.817916,-12.370412 6.194803,-13.909026 9.324945,-4.24873 15.584088,10.950876 9.956609,24.178486 -0.930827,2.18794 1.172672,2.29087 5.957799,0.29151 l 0,0 z m -66.879119,-1.52913 c -2.805149,-2.19422 -4.307733,-2.52716 -3.741707,-0.82908 0.211038,0.6331 1.180081,1.268 2.15343,1.41085 0.973349,0.14286 2.025929,0.51595 2.339067,0.82908 0.313138,0.31314 0.829243,0.55943 1.1469,0.54732 0.317656,-0.0121 -0.536304,-0.89328 -1.89769,-1.95817 z m 12.639913,0.64485 c 0.689575,-0.42992 0.997439,-1.19644 0.684141,-1.70337 -0.313298,-0.50692 -0.139505,-0.92168 0.386206,-0.92168 0.525712,0 0.704595,-0.96077 0.397519,-2.13502 -0.337827,-1.29185 -0.167417,-1.89344 0.431502,-1.52328 0.604271,0.37346 1.005912,-1.20529 1.031127,-4.0531 0.03148,-3.556019 -0.171219,-4.194157 -0.852784,-2.684642 -0.678574,1.502882 -0.773791,1.192692 -0.395022,-1.286842 0.353363,-2.313228 0.165236,-3.060723 -0.644381,-2.560356 -0.737692,0.45592 -0.940577,0.178019 -0.571745,-0.783139 0.314436,-0.819406 0.23569,-2.033505 -0.174991,-2.698 -1.105326,-1.788456 -7.682811,-2.144736 -9.055691,-0.490515 -0.631379,0.760762 -0.759249,1.396753 -0.284156,1.413317 0.475095,0.01654 0.06457,0.495168 -0.912263,1.063584 -1.129264,0.657109 -1.565313,1.697515 -1.197349,2.856861 0.318297,1.002872 0.145073,2.091406 -0.384943,2.418971 -1.212393,0.749301 -1.114708,6.501761 0.11041,6.501761 0.49838,0 0.626441,0.88128 0.284578,1.95839 -1.132056,3.56679 7.260902,7.05039 11.147842,4.62706 l 0,0 z m 8.934184,-0.55418 c 2.020385,-1.03924 5.010061,-3.29502 6.643725,-5.01286 2.868463,-3.01627 2.981671,-3.49028 3.302077,-13.826072 l 0.33178,-10.702722 -3.762914,-0.705927 C 47.602481,80.969761 43.95345,78.863901 38.40778,73.51044 l -4.950496,-4.778915 -3.90401,1.921073 C 17.503668,76.58193 12.423679,90.628824 18.240927,101.93283 c 3.23262,6.2816 4.539882,6.43779 5.329032,0.6367 0.928828,-6.827865 1.319844,-7.895489 4.103161,-11.203281 7.697735,-9.148234 17.690208,3.484377 13.905573,17.579601 -1.6234,6.04608 -1.03574,6.43209 5.036847,3.3085 l 0,0 z m 37.877227,-0.17548 c 0.607833,-1.13574 0.846281,-2.32386 0.529884,-2.64025 -0.316397,-0.3164 -0.575268,-0.0873 -0.575268,0.50911 0,0.59643 -0.700141,1.78455 -1.55587,2.64027 -0.855728,0.85573 -1.094176,1.55587 -0.529884,1.55587 0.564291,0 1.523303,-0.92924 2.131138,-2.065 l 0,0 z m -8.956275,-0.41024 c -0.777242,-0.93653 -0.843612,-1.48515 -0.179665,-1.48515 0.579095,0 1.32826,0.44554 1.664814,0.9901 0.336553,0.54455 1.710509,0.9901 3.053236,0.9901 3.405659,0 4.705098,-3.86234 3.99729,-11.88119 -0.410484,-4.650429 -0.278996,-6.023676 0.474005,-4.950498 0.92628,1.320129 0.997019,1.320129 0.636655,0 -0.222976,-0.816832 -0.888084,-1.485149 -1.478018,-1.485149 -0.589933,0 -1.406765,-0.334158 -1.815181,-0.742574 -0.408416,-0.408416 -1.808473,-0.742574 -3.111239,-0.742574 -1.326986,0 -2.099559,-0.435416 -1.756748,-0.990099 1.082137,-1.750934 -0.356281,-1.056251 -2.436678,1.176792 -1.948858,2.091852 -2.796679,4.371505 -1.276193,3.431475 0.408415,-0.252495 0.742574,2.796683 0.742574,6.775957 0,4.5426 -0.368457,7.02333 -0.990099,6.66611 -0.544555,-0.31292 -0.141343,0.39874 0.896028,1.58146 2.106995,2.4022 3.511949,2.99403 1.579219,0.66524 l 0,0 z m 74.981158,-0.19108 c -0.96334,-0.25103 -2.29997,-0.23453 -2.9703,0.0366 -0.67032,0.27122 0.11786,0.4766 1.75152,0.45643 1.63366,-0.0202 2.18212,-0.24208 1.21878,-0.49311 l 0,5e-5 z m -84.882148,-2.77922 c -0.67791,-0.81683 -1.678108,-1.48515 -2.222662,-1.48515 -0.552304,0 -0.445093,0.65669 0.242464,1.48515 0.67791,0.81683 1.678108,1.48515 2.222663,1.48515 0.552304,0 0.445093,-0.6567 -0.242465,-1.48515 z m 38.428218,-0.43317 c 0.24752,-0.74257 -0.12376,-1.11386 -0.86634,-0.86634 -0.71472,0.23824 -1.49443,1.01795 -1.73267,1.73268 -0.24752,0.74257 0.12376,1.11386 0.86634,0.86633 0.71472,-0.23823 1.49443,-1.01795 1.73267,-1.73267 z m 61.57178,-0.16781 c 0,-1.1313 -2.6849,-1.15685 -3.38,-0.0322 -0.2896,0.4686 -0.27234,1.10622 0.0384,1.41693 0.7726,0.77266 3.34158,-0.29192 3.34158,-1.38475 z m -145.544552,0.16436 c 0,-1.16817 -1.931044,-2.41782 -2.640265,-1.7086 -0.709219,0.70923 0.54042,2.64027 1.708598,2.64027 0.512417,0 0.931667,-0.41925 0.931667,-0.93167 z m 65.94472,-2.76058 c -0.329002,-0.329 -0.563011,0.25578 -0.52002,1.29951 0.04751,1.15341 0.28212,1.38802 0.598185,0.59818 0.286011,-0.71472 0.250836,-1.56868 -0.07817,-1.89769 l 3e-6,0 z m 20.193892,-0.7632 c 0,-0.81683 -0.44554,-1.48515 -0.9901,-1.48515 -0.54455,0 -0.9901,0.66832 -0.9901,1.48515 0,0.81683 0.44555,1.48515 0.9901,1.48515 0.54456,0 0.9901,-0.66832 0.9901,-1.48515 z m 60.18796,-0.40346 c 2.02039,-1.03875 5.45561,-3.52622 7.63382,-5.527735 l 3.9604,-3.639109 -4.45545,3.425762 c -2.45049,1.884172 -6.23762,4.351962 -8.41584,5.483972 -2.17822,1.13201 -3.60848,2.0779 -3.17837,2.10196 0.43011,0.0241 2.43506,-0.80612 4.45544,-1.84485 z m -94.1857,-5.289607 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237627 0,1.36138 0.224726,1.91831 0.499392,1.23762 0.274665,-0.68069 0.274665,-1.794554 0,-2.475247 z m 13.861386,-0.990099 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237624 0,1.361382 0.224726,1.918312 0.499392,1.237622 0.274666,-0.680691 0.274666,-1.794553 0,-2.475246 z m -25.408199,0.742575 c 0,-0.816832 -0.445544,-1.485149 -0.990099,-1.485149 -0.544554,0 -0.990099,0.668317 -0.990099,1.485149 0,0.816831 0.445545,1.485151 0.990099,1.485151 0.544555,0 0.990099,-0.66832 0.990099,-1.485151 z m 47.524753,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921683 -0.55343,0.342039 -0.74992,1.036653 -0.43661,1.543584 0.84874,1.37331 1.44286,1.11724 1.44286,-0.621901 l 0,0 z M 13.75844,96.59024 c -0.329002,-0.329 -0.563011,0.255782 -0.520019,1.299504 0.04751,1.153416 0.282119,1.38802 0.598184,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897693 l 0,0 z m 45.936468,-3.733496 c 0,-0.816831 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668317 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m 49.504952,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921684 -0.55343,0.34204 -0.74992,1.036654 -0.43661,1.543585 0.84874,1.373307 1.44286,1.117237 1.44286,-0.621901 l 0,0 z M 12.768341,90.649645 c -0.329002,-0.328998 -0.563011,0.255783 -0.52002,1.299505 0.04751,1.153416 0.28212,1.38802 0.598185,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897694 l 0,0 z m 70.193894,0.721951 c -0.336554,-0.544555 -1.142551,-0.983277 -1.791106,-0.974941 -0.708531,0.0089 -0.586411,0.398248 0.305957,0.974941 1.902102,1.229238 2.244857,1.229238 1.485149,0 z m 25.247525,-4.513878 c 0,-0.84897 -0.45281,-1.263728 -1.00625,-0.921685 -0.55343,0.342043 -0.74992,1.036654 -0.43661,1.543581 0.84874,1.373311 1.44286,1.117238 1.44286,-0.621896 z M 13.75844,84.709054 c -0.329002,-0.329001 -0.563011,0.255777 -0.520019,1.299505 0.04751,1.153409 0.282119,1.38802 0.598184,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 0,0 z m 48.906765,-3.85473 c 0,-1.356215 -3.082898,-1.911382 -4.232156,-0.762123 -0.330986,0.330986 -0.08945,1.422196 0.536762,2.424911 0.842923,1.349734 1.470503,1.547624 2.416974,0.762123 0.703131,-0.583548 1.27842,-1.674757 1.27842,-2.424911 z m 43.564355,0.09971 c 0,-2.007107 -9.940776,-11.875249 -12.685773,-12.593082 -3.422347,-0.894964 -2.536662,0.72179 2.04221,3.727903 4.685203,3.075921 8.056173,6.371341 8.979963,8.778691 0.77225,2.012434 1.6636,2.058775 1.6636,0.08649 z m -47.693353,-7.404219 2.306645,-4.455446 -0.675699,4.455446 -0.6757,4.455445 3.814599,-3.586129 c 2.098029,-1.972372 6.311347,-5.155371 9.362929,-7.073331 5.874539,-3.692229 6.839458,-5.599101 6.818235,-13.474203 -0.0116,-4.303265 -3.763041,-12.649115 -7.037511,-15.656368 -5.956689,-5.47059 -15.534138,-7.597002 -22.017021,-4.888282 -12.757989,5.330628 -18.072962,19.793085 -11.85765,32.265591 2.52515,5.067315 2.685106,5.196865 3.601855,2.917172 0.958373,-2.383197 0.960066,-2.382511 1.654947,0.671085 0.942906,4.14352 1.700115,5.200511 5.327538,7.436733 4.523217,2.788458 6.716499,2.070908 9.376833,-3.067713 l 0,0 z m 8.682689,1.5849 c 1.905993,-1.851076 4.77995,-3.91008 6.386569,-4.575565 2.564998,-1.062456 4.03369,-2.949929 2.295417,-2.949929 -2.10037,0 -13.235677,8.775011 -13.235677,10.430176 0,1.083649 1.30255,0.252787 4.553691,-2.904682 z M 20.090948,74.8078 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z M 152.76422,69.68259 c 0,-0.272277 -1.78218,1.245201 -3.9604,3.372174 -2.17822,2.126974 -3.9604,4.089996 -3.9604,4.362274 0,0.272277 1.78218,-1.245201 3.9604,-3.372175 2.17822,-2.126973 3.9604,-4.089996 3.9604,-4.362273 z M 41.625601,72.476287 c -2.586633,-2.217071 -4.709793,-4.553304 -4.718131,-5.191628 -0.02877,-2.202305 -1.632163,-3.701423 -3.281819,-3.068391 -2.032483,0.779938 -2.195989,3.392952 -0.212309,3.392952 0.792663,0 3.354544,2.00317 5.693069,4.45149 2.338525,2.44832 4.92018,4.450394 5.737012,4.449053 0.816832,-0.0014 -0.631188,-1.816405 -3.217822,-4.033476 l 0,0 z M 24.051344,70.847404 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z m 6.526162,-3.972749 c -0.745512,-0.745512 -5.536063,1.770447 -5.536063,2.907495 0,0.46652 1.378038,0.135607 3.062307,-0.735362 1.684269,-0.870969 2.797459,-1.848429 2.473756,-2.172133 z m 53.127303,0.748085 c 0.952971,-0.0074 1.732673,-0.459065 1.732673,-1.003619 0,-0.544555 -0.940674,-0.990099 -2.090387,-0.990099 -1.852777,0 -2.016491,-0.393899 -1.440284,-3.465347 0.406143,-2.164925 0.261718,-3.465346 -0.38486,-3.465346 -0.56923,0 -1.034964,1.059307 -1.034964,2.354014 0,1.294709 -0.668316,2.90867 -1.485148,3.58658 -2.367441,1.964801 -1.885292,4.298583 0.742574,3.594342 1.225248,-0.328353 3.007426,-0.60309 3.960396,-0.610525 z m 71.134371,-0.722043 c 1.58154,-0.934242 2.87553,-2.079091 2.87553,-2.544109 0,-1.671282 -4.25968,-0.165537 -5.70037,2.015008 -1.76311,2.668563 -1.02958,2.805958 2.82484,0.529101 z m 47.13694,-2.884855 c -0.37294,-0.372946 -1.68483,-0.148769 -2.91529,0.498172 -1.23047,0.64694 -1.45751,0.953686 -0.50454,0.681656 1.92704,-0.550082 2.24796,0.402733 0.74808,2.221031 -0.54153,0.65649 -0.009,0.312431 1.18262,-0.764577 1.19197,-1.077007 1.86208,-2.263334 1.48913,-2.636282 z m -52.1822,2.108229 c 0.67791,-0.816831 1.00979,-1.485148 0.73751,-1.485148 -0.27227,0 -1.0497,0.668317 -1.72761,1.485148 -0.67791,0.816832 -1.00979,1.485149 -0.73752,1.485149 0.27228,0 1.04971,-0.668317 1.72762,-1.485149 z m 37.15543,-0.451808 c -0.32185,-0.520771 -1.23923,-0.695875 -2.03863,-0.38912 -2.04664,0.785373 -1.80547,1.335978 0.5852,1.335978 1.12125,0 1.7753,-0.426086 1.45343,-0.946858 z m -20.13811,-0.719592 c -0.71473,-0.286011 -1.56869,-0.250835 -1.89769,0.07817 -0.329,0.329001 0.25578,0.56301 1.29951,0.520019 1.15341,-0.04751 1.38802,-0.282119 0.59818,-0.598185 l 0,-3e-6 z M 84.05547,61.936777 c -0.329002,-0.329001 -0.563011,0.255776 -0.52002,1.299505 0.04751,1.153409 0.28212,1.38802 0.598185,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 3e-6,0 z m 82.57013,0.721948 c 0,-0.544555 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445544 -1.48515,0.990099 0,0.544554 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445545 1.48515,-0.990099 z m 37.62376,-5.177658 c 0,-1.661518 -0.24856,-1.789209 -1.48514,-0.762936 -0.81684,0.67791 -1.48515,1.832342 -1.48515,2.565406 0,0.777973 0.61827,1.095588 1.48515,0.762936 0.81683,-0.313447 1.48514,-1.46788 1.48514,-2.565406 z M 83.457284,54.18445 c 0,-0.784694 -0.445544,-1.426715 -0.990099,-1.426715 -0.544554,0 -0.990099,0.917384 -0.990099,2.03863 0,1.121247 0.445545,1.76327 0.990099,1.426716 0.544555,-0.336553 0.990099,-1.253937 0.990099,-2.038631 z m 63.366336,-0.931666 c -1.27896,-1.361386 -2.77092,-2.475247 -3.31547,-2.475247 -0.54456,0 0.0563,1.113861 1.33527,2.475247 1.27896,1.361386 2.77092,2.475248 3.31548,2.475248 0.54455,0 -0.0563,-1.113862 -1.33528,-2.475248 z M 82.467185,48.302289 c 0,-0.816832 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668316 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m -1.985115,-5.19802 c -0.0084,-1.2671 -4.736103,-6.714785 -5.323399,-6.134089 -0.649329,0.642032 3.49033,6.834315 4.585742,6.859554 0.408416,0.0094 0.740362,-0.317049 0.737657,-0.725465 l 0,0 z m 50.49997,-0.247525 c -0.81683,-0.527877 -1.9307,-0.959776 -2.47525,-0.959776 -0.54456,0 -0.32178,0.431899 0.49505,0.959776 0.81683,0.527878 1.93069,0.959777 2.47525,0.959777 0.54455,0 0.32178,-0.431899 -0.49505,-0.959777 z m 4.44995,-0.996169 c -0.98866,-1.092447 -2.01229,-1.771531 -2.27475,-1.509075 -0.66527,0.66528 1.80418,3.495343 3.04998,3.495343 0.56227,0 0.21342,-0.89382 -0.77523,-1.986268 l 0,0 z m -95.539062,-4.19679 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.677909 1.485148,-1.678107 1.485148,-2.222662 z m 92.079212,0.795947 c 0,-2.367417 -1.80911,-2.723191 -2.95546,-0.581213 -0.91594,1.711444 -0.77708,2.007928 0.94043,2.007928 1.10826,0 2.01503,-0.642021 2.01503,-1.426715 z M 43.853324,33.703389 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.67791 1.485148,-1.678108 1.485148,-2.222662 z m 29.450539,-0.0051 c -0.341635,-3.033194 -0.613818,-3.235945 -4.743791,-3.533678 -2.40975,-0.173719 -4.148989,-0.08348 -3.864976,0.200533 0.746043,0.746042 8.309556,6.402673 8.668673,6.483162 0.166387,0.03729 0.139429,-1.380215 -0.05991,-3.150017 z m 45.796987,1.732673 c -0.67791,-0.816832 -1.70871,-1.485149 -2.29066,-1.485149 -0.58196,0 -0.19325,0.654147 0.8638,1.453661 2.48363,1.878524 2.96864,1.889227 1.42686,0.03148 l 0,3e-6 z m 5.94059,-0.933056 c 0,-0.721181 -1.00247,-1.579892 -2.22772,-1.908245 -3.82044,-1.023837 -4.13152,-0.702262 -1.76134,1.820687 2.31705,2.466393 3.98906,2.503093 3.98906,0.08755 l 0,4e-6 z m 8.8851,-5.657864 c 5.0656,-7.213134 5.95021,-9.230659 3.73867,-8.526659 -1.72171,0.548068 -10.64357,12.438161 -10.64357,14.184592 0,2.924919 2.06665,1.231484 6.9049,-5.657933 z m -54.828018,2.397173 c -0.586902,-0.586901 -3.56203,0.943932 -3.56203,1.832819 0,0.490907 0.870827,0.348719 1.935171,-0.315974 1.064342,-0.664694 1.796429,-1.347273 1.626859,-1.516845 z m -29.622424,0.529501 c 3.007757,-1.087619 4.641314,-3.761497 2.298018,-3.761497 -0.544554,0 -0.990099,0.445545 -0.990099,0.990099 0,0.544555 -0.58316,0.990099 -1.295911,0.990099 -1.477794,0 -5.628481,2.890588 -4.219928,2.938809 0.505892,0.01732 2.399456,-0.503561 4.20792,-1.15751 l 0,0 z m 54.958912,-1.46755 c -0.71473,-0.286011 -1.56869,-0.250836 -1.89769,0.07817 -0.329,0.329002 0.25577,0.563011 1.2995,0.52002 1.15341,-0.0475 1.38802,-0.28212 0.59819,-0.598185 l 0,-3e-6 z M 59.694908,28.005259 c 0,-1.089109 -0.39099,-1.980198 -0.868866,-1.980198 -1.298365,0 -3.17241,2.559384 -2.422873,3.30892 1.355486,1.355487 3.291739,0.573912 3.291739,-1.328722 z m 21.287129,0.990099 c 0.336553,-0.544554 -0.331763,-0.990099 -1.485149,-0.990099 -1.153385,0 -1.821702,0.445545 -1.485148,0.990099 0.336553,0.544555 1.00487,0.990099 1.485148,0.990099 0.480279,0 1.148595,-0.445544 1.485149,-0.990099 z m 29.207923,0 c 0,-0.544554 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445545 -1.48515,0.990099 0,0.544555 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445544 1.48515,-0.990099 z M 86.427581,28.005259 c 0,-0.544554 -0.694611,-0.990099 -1.543581,-0.990099 -0.848969,0 -1.268219,0.445545 -0.931666,0.990099 0.336553,0.544555 1.031164,0.990099 1.543581,0.990099 0.512417,0 0.931666,-0.445544 0.931666,-0.990099 z m 18.316829,0 c 0.33656,-0.544554 -0.33176,-0.990099 -1.48515,-0.990099 -1.15338,0 -1.8217,0.445545 -1.48514,0.990099 0.33655,0.544555 1.00487,0.990099 1.48514,0.990099 0.48028,0 1.1486,-0.445544 1.48515,-0.990099 z M 53.397761,23.263982 c -2.293369,-2.293369 -3.273717,-0.599352 -1.065339,1.840877 1.180946,1.304931 2.008695,1.63504 2.254066,0.898928 0.213274,-0.63982 -0.321654,-1.872732 -1.188727,-2.739805 l 0,0 z m 41.674343,3.065049 c -0.963333,-0.251033 -2.299967,-0.234524 -2.970297,0.03668 -0.670328,0.271211 0.117854,0.476602 1.751517,0.456424 1.633663,-0.02018 2.182115,-0.242078 1.21878,-0.493111 l 0,4e-6 z M 50.784017,20.160629 c 0,-1.18906 -5.817795,-7.006855 -7.006854,-7.006855 -1.723094,0 -0.911591,1.747528 2.244318,4.833013 3.196159,3.124838 4.762536,3.839805 4.762536,2.173842 z m 99.083553,-7.807387 c -1.32905,-0.443014 -5.95468,4.804941 -5.94174,6.741126 0.006,0.860676 1.47299,-0.172344 3.48946,-2.456779 1.91375,-2.168059 3.01727,-4.096016 2.45228,-4.284347 z m -7.4939,4.754858 c 2.64699,-2.924889 1.22992,-3.38489 -1.49431,-0.485075 -1.27694,1.359238 -1.86755,2.471343 -1.31247,2.471343 0.55508,0 1.81813,-0.893821 2.80678,-1.986268 z m 1.9747,-5.934524 c 2.68184,-2.7227721 4.44726,-4.9364147 3.92318,-4.9192068 -1.79455,0.058926 -11.48794,9.8697018 -9.75161,9.8697018 0.52381,0 3.1466,-2.227723 5.82843,-4.950495 z m 4.99121,-1.055971 c 1.06562,-1.7242011 -0.14804,-2.0893477 -1.506,-0.4531041 -0.78094,0.9409741 -0.85606,1.5090751 -0.19952,1.5090751 0.57909,0 1.34657,-0.475187 1.70552,-1.055971 z m 22.08877,-7.9517764 c 1.71492,-0.5978257 3.11804,-1.51893899 3.11804,-2.04691859 0,-1.07371396 -3.1521,-0.28577416 -6.93069,1.73248789 -3.09382,1.652504 -0.61271,1.8571218 3.81265,0.3144307 l 0,0 z m 6.85154,-0.707599 c 0.59402,-1.78204068 -1.45248,-1.40757811 -2.14309,0.3921386 -0.37003,0.9642713 -0.14875,1.4169139 0.57476,1.1757426 0.64703,-0.2156762 1.35277,-0.9212228 1.56833,-1.5678812 z M 20.090948,0.80296239 c 0,-0.25829297 -1.366838,-1.17644278 -3.037417,-2.04033289 C 13.07504,-3.294728 10.77735,-2.5105441 14.645403,-0.41549494 17.561715,1.1640635 20.090948,1.729987 20.090948,0.80296239 z M 177.51669,-2.5818805 c 0,-1.2146632 -2.78939,-2.1897491 -3.40672,-1.1908861 -0.27491,0.444817 -0.21492,1.0936751 0.1333,1.4419069 0.94359,0.9435791 3.27342,0.7649164 3.27342,-0.2510208 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3784"
+ transform="translate(0,784.36218)"
+ d="m 30.061595,110.24748 c -3.028002,-1.91623 -2.918962,-12.207625 0.161986,-15.288574 2.892806,-2.892806 5.380122,-2.029008 6.063557,2.105759 0.787072,4.761775 0.802973,10.540215 0.03451,12.542785 -0.657319,1.71294 -4.021187,2.05687 -6.260057,0.64003 l -1e-6,0 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3786"
+ transform="translate(0,784.36218)"
+ d="m 50.118347,74.592462 c -5.270942,-3.20545 -6.839578,-11.64359 -3.245566,-17.458823 3.039395,-4.917846 5.720122,-5.336139 9.002245,-1.404685 3.776278,4.523372 4.477791,9.679447 1.982432,14.570755 -2.972944,5.82745 -4.145768,6.477996 -7.739111,4.292753 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3790"
+ transform="translate(0,784.36218)"
+ d="m 77.269166,109.11407 c -1.309679,-0.76282 -1.732674,-2.30682 -1.732674,-6.32456 0,-2.923449 0.270441,-6.020121 0.600979,-6.881491 0.834308,-2.174169 4.068292,-1.961418 5.30478,0.348981 2.014054,3.7633 0.737507,14.00145 -1.732673,13.89637 -0.389257,-0.0166 -1.487442,-0.48424 -2.440412,-1.0393 z" />
+ </g>
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3811"
+ d="m 67.743593,226.38939 c 0.19068,-0.58412 0.338063,-2.39704 0.327517,-4.02871 -0.03055,-4.72761 -2.165352,-7.80395 -5.35278,-7.71359 -2.829967,0.0802 -4.224757,1.85117 -5.323452,6.75914 -0.310039,1.38498 -0.36786,1.41644 -1.004042,0.54642 -0.371282,-0.50776 -0.820797,-1.89506 -0.998923,-3.08289 -0.555915,-3.70711 1.471544,-7.48719 5.471792,-10.20182 5.598625,-3.79933 13.971038,1.83612 13.913701,9.36528 -0.02361,3.09812 -3.736904,8.46539 -6.324961,9.14218 -0.904613,0.23656 -1.005971,0.12417 -0.708852,-0.78601 l 0,0 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3813"
+ d="m 67.404395,224.07647 c 0.218171,-3.86109 -0.81619,-7.47461 -2.379003,-8.31101 -1.450495,-0.77628 -3.833689,-0.56086 -4.831244,0.43669 -0.506638,0.50664 -1.305601,2.10548 -1.775472,3.55298 -1.095843,3.3759 -1.456791,3.72914 -2.367189,2.31667 -2.172529,-3.37066 -1.181735,-8.3045 2.356216,-11.73323 3.808208,-3.69063 6.356321,-4.18204 10.583313,-2.04103 3.18311,1.61228 5.556904,4.81655 6.061632,8.18231 0.273553,1.8242 0.112352,2.73702 -0.850171,4.81416 -1.44283,3.11366 -4.397332,6.23865 -5.898296,6.23865 -1.048338,0 -1.086743,-0.14752 -0.899786,-3.45619 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3815"
+ d="m 54.581383,204.17598 c -0.330031,-3.53422 -1.331573,-5.66019 -3.388938,-7.19369 -2.496196,-1.86061 -5.288569,0.24236 -6.511588,4.90394 l -0.621341,2.36827 -0.78337,-1.82202 c -2.593339,-6.03175 2.241276,-13.61508 8.680039,-13.61508 3.86832,0 6.851837,1.90897 8.669978,5.54739 1.621302,3.24451 1.874093,5.90823 0.71742,7.55961 -0.413522,0.59039 -2.036622,2.06204 -3.606889,3.27033 l -2.85503,2.19689 -0.300281,-3.21564 0,0 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3817"
+ d="m 45.188143,222.67169 c 0,-3.90068 -0.118172,-4.43649 -1.328412,-6.0232 -1.647394,-2.15984 -3.308854,-2.63488 -5.529681,-1.58103 -1.755441,0.83301 -3.67834,3.97169 -3.67834,6.00402 0,1.57105 -0.802789,1.30413 -1.422259,-0.47288 -1.642012,-4.71028 0.827943,-10.53973 5.502814,-12.98743 1.350256,-0.70698 1.444094,-0.67017 3.720976,1.45958 2.598182,2.4303 4.372384,3.46667 6.848292,4.00031 l 1.663058,0.35844 -0.308027,4.68928 c -0.331934,5.05322 -0.878313,6.12303 -4.098751,8.0254 l -1.36967,0.80908 0,-4.28157 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3819"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3821"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3823"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3825"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3827"
+ d="" />
+ <path
+ style="fill:#808000;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3839"
+ d="m 96.387857,217.56995 c 1.213522,-1.18081 3.045232,-2.70588 3.588513,-2.98777 0.26729,-0.13869 0.34041,-0.13033 0.53775,0.0614 0.22145,0.21519 0.21721,0.22773 -0.139,0.41194 -0.20207,0.1045 -1.168241,0.8213 -2.147044,1.5929 -3.062313,2.41407 -3.70477,2.73578 -1.840219,0.92149 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3841"
+ d="m 95.259154,218.6245 c 0.169011,-0.31579 2.350639,-2.35144 3.60354,-3.3624 1.092972,-0.88192 1.409816,-1.00296 1.745806,-0.66698 0.23537,0.23537 0.20535,0.26324 -2.361536,2.1931 -2.586669,1.94472 -3.270902,2.36525 -2.98781,1.83628 z m 3.223063,-2.29188 c 2.186823,-1.64445 2.077413,-1.54607 1.826463,-1.64237 -0.12626,-0.0485 -0.405397,0.0686 -0.732209,0.30704 -0.77399,0.56467 -3.173136,2.65442 -3.181471,2.77119 -0.0098,0.13752 0.04568,0.0993 2.087217,-1.43586 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3843"
+ d="m 95.089499,218.84542 c -0.104424,-0.16895 0.84778,-1.16015 2.535143,-2.63894 1.847565,-1.6192 1.734083,-1.53116 2.253052,-1.748 0.416136,-0.17387 0.470236,-0.17054 0.736846,0.0453 l 0.28774,0.233 -0.24641,0.27229 c -0.26032,0.28767 -3.496794,2.74402 -4.622191,3.50806 -0.706972,0.47998 -0.825042,0.52102 -0.94418,0.32824 z m 4.655172,-3.67215 c 0.153994,-0.18668 0.143867,-0.19204 -0.108591,-0.0575 -0.287942,0.15343 -0.358846,0.26338 -0.169828,0.26338 0.05972,0 0.185009,-0.0926 0.278419,-0.20587 l 0,0 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3845"
+ d="" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3847"
+ d="m 96.329421,220.21405 c 0.134226,-0.13117 0.940097,-0.6115 1.790822,-1.06738 0.850725,-0.45589 1.976417,-1.13063 2.501547,-1.49943 0.96712,-0.67921 2.0769,-1.69802 2.0769,-1.90664 0,-0.0627 0.13921,-0.11397 0.30936,-0.11397 1.35091,0 -2.15595,2.85903 -5.339138,4.35282 -0.554492,0.26021 -1.137628,0.47311 -1.295854,0.47311 -0.285987,0 -0.286245,-0.001 -0.04366,-0.23851 z" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.25936007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="rect3011"
+ transform="matrix(0.99992004,0.01264577,-0.00621432,0.99998069,0,0)"
+ y="35.635006"
+ x="1.1525297"
+ ry="15"
+ rx="15.083"
+ height="127.1652"
+ width="147.36519" />
+ <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="10.666666"
+ y="54.666672"
+ id="text2895"><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="54.666672"
+ id="tspan2899">Please help me</tspan><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="74.666672"
+ id="tspan2903">find the pieces </tspan><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="94.666672"
+ id="tspan2905">of my spaceship</tspan></text>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien4.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien4.svg
new file mode 100755
index 0000000..e726de1
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien4.svg
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="150"
+ height="300"
+ id="svg2"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="alien3.svg">
+ <metadata
+ id="metadata47">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ id="namedview45"
+ showgrid="false"
+ inkscape:zoom="1.5"
+ inkscape:cx="106.63021"
+ inkscape:cy="166.28281"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 103.30726 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="100 : 103.30726 : 1"
+ inkscape:persp3d-origin="50 : 68.871506 : 1"
+ id="perspective49" />
+ </defs>
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2909"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2915"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2917"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3707"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3711"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3715"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.68738866;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3776"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3778"
+ d="" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3788"
+ d="" />
+ <g
+ id="g3794"
+ transform="matrix(0.49496731,0,0,0.49496731,23.688009,-216.56245)">
+ <path
+ style="fill:#000000"
+ id="path2905"
+ d="m 53.60865,1035.3693 c 19.78288,-22.2017 22.20694,-25.4265 25.4678,-33.881 3.44722,-8.9377 6.40012,-18.24962 7.52938,-23.74392 0.82455,-4.01172 -0.36261,-5.08744 -5.63913,-5.10977 -1.99045,-0.008 -7.61545,-0.71148 -12.5,-1.56235 -16.50806,-2.87565 -23.91813,-6.30919 -33.99171,-15.75046 -6.08941,-5.70718 -7.43503,-7.50597 -7.19032,-9.61182 0.34346,-2.95569 -1.50714,-2.82651 22.80104,-1.59153 11.8285,0.60095 15.97106,0.42806 22.48438,-0.93836 4.39141,-0.92127 8.66641,-2.28625 9.5,-3.0333 0.83359,-0.74704 3.31562,-1.68728 5.51562,-2.08942 2.2,-0.40213 5.575,-1.60777 7.5,-2.6792 3.44034,-1.91485 3.44887,-1.93539 0.5,-1.2054 -5.17273,1.28051 -26.63042,1.59889 -36.0133,0.53435 -9.20812,-1.04471 -19.63226,-3.39275 -22.72313,-5.11837 -0.95503,-0.5332 -2.32888,-0.96945 -3.05299,-0.96945 -1.43857,0 -9.42912,-5.54027 -11.50725,-7.97859 -0.95343,-1.11868 -1.14843,-3.94422 -0.73666,-10.67412 l 0.56002,-9.15271 -4.54056,-5.31941 c -9.98832,-11.70162 -9.97623,-27.55255 0.0295,-38.68134 2.60206,-2.89412 6.36378,-5.77306 8.93031,-6.83458 l 4.43446,-1.83411 -0.57302,-6.13624 c -1.06496,-11.40449 5.13162,-23.48816 14.51299,-28.30109 l 3.58712,-1.84031 -5.95375,-5.92765 c -4.93512,-4.9135 -8.52008,-7.18312 -20.95375,-13.26571 -8.25,-4.03593 -15.17459,-7.48627 -15.38799,-7.66742 -0.21339,-0.18115 0.18259,-2.36727 0.87997,-4.85804 1.70691,-6.09651 3.20226,-5.96925 18.29995,1.55747 19.96216,9.95182 24.45018,13.11377 31.13538,21.93586 4.86767,6.42359 6.566,7.95536 9.5,8.56828 1.96498,0.41049 4.02269,0.60686 4.57269,0.43639 17.13317,-5.31045 33.409,-5.14223 47.77024,0.49372 4.94708,1.94144 5.21645,1.90161 6.52227,-0.96436 0.61245,-1.34418 5.43513,-7.16668 10.71706,-12.93889 7.18218,-7.84883 10.66081,-10.87865 13.79697,-12.01685 2.3064,-0.83706 9.11158,-3.33956 15.12261,-5.56111 6.01103,-2.22156 11.68966,-4.03919 12.61916,-4.03919 1.11859,0 1.89014,1.09888 2.28193,3.25 0.32555,1.7875 0.8733,4.21044 1.21722,5.38431 0.70713,2.41364 -0.93804,3.18343 -16.9864,7.94807 -8.24402,2.44759 -9.41386,3.13117 -15.04786,8.79297 -3.35991,3.37649 -7.99751,8.92014 -10.30579,12.31923 l -4.19687,6.18016 4.59822,3.7679 c 3.92224,3.21397 12.53592,13.3479 15.89124,18.69593 0.86818,1.38377 2.03676,1.46094 8.86473,0.5854 6.40489,-0.8213 8.72511,-0.72392 12.5,0.5246 8.01058,2.64945 13.40229,2.97743 17.21675,1.04728 5.01589,-2.53808 7.91852,-5.53295 7.91852,-8.17016 0,-1.91743 0.52663,-2.32569 3,-2.32569 l 3,0 0,7.36937 c 0,6.99889 -0.19005,7.61474 -3.78039,12.25 -2.07921,2.68435 -4.3555,6.00563 -5.05843,7.38063 -1.82398,3.56792 -4.05346,6.02517 -8.95417,9.86899 -2.36114,1.85194 -5.40785,5.56725 -6.77047,8.25624 -1.86654,3.68345 -4.04585,5.93033 -8.8376,9.11161 l -6.36013,4.22255 -1.16111,8.29999 c -3.24143,23.17077 -14.49635,42.93763 -31.7551,55.771 -4.30243,3.19923 -8.0341,5.98766 -8.29259,6.19652 -1.61876,1.30794 6.41126,11.58405 19.25766,24.64423 26.293,26.73057 27.51833,28.27367 30.82393,38.81727 3.56149,11.3598 3.62201,12.8116 0.53407,12.8116 -2.0739,0 -2.62572,-0.9231 -4.63288,-7.75 -1.25321,-4.2625 -3.12892,-9.4395 -4.16826,-11.5044 -1.03933,-2.065 -8.08103,-9.94 -15.6482,-17.5 -17.43517,-17.4188 -29.05724,-30.54815 -30.36702,-34.30539 -0.88138,-2.52833 -1.38534,-2.84102 -3.67537,-2.28044 -1.45967,0.3573 -2.80394,1.03003 -2.98727,1.49494 -0.18334,0.46491 -1.18057,0.84529 -2.21608,0.84529 -1.0355,0 -3.3605,0.6395 -5.16666,1.42112 -1.80616,0.78162 -5.98393,1.79412 -9.28393,2.25 l -6,0.82888 -0.64806,5 c -1.05452,8.13597 -10.19844,32.3753 -13.55944,35.9443 -1.06473,1.1306 -3.96423,4.5663 -6.44331,7.6348 -2.47909,3.0685 -5.37183,6.4995 -6.42831,7.6245 -1.05648,1.1249 -3.66664,3.9018 -5.80036,6.1708 -3.09032,3.2864 -4.58088,4.1256 -7.32754,4.1256 l -3.44807,0 4.67803,-5.25 z m 5.47706,-1.25 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 8,-9 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 6,-7 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 85,-12.8776 c 0,-0.2076 -0.7875,-0.9951 -1.75,-1.75 -1.58606,-1.2438 -1.62143,-1.2085 -0.37756,0.3776 1.30637,1.6657 2.12756,2.1955 2.12756,1.3724 z m -13,-11.9674 c 0,-0.1898 -1.0125,-1.2023 -2.25,-2.25 l -2.25,-1.905 1.90499,2.25 c 1.79022,2.1144 2.59501,2.7052 2.59501,1.905 z m -8,-9.00001 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11444 2.59501,2.70524 2.59501,1.90499 z m -41,-13.2644 c 0,-0.21482 -2.1375,-0.3837 -4.75,-0.37528 -2.69011,0.009 -4.21371,0.35593 -3.51336,0.80076 1.18245,0.75103 8.26336,0.38643 8.26336,-0.42548 z m -15.15913,-0.88305 c -0.27085,-0.27086 -4.50835,-1.18259 -9.41666,-2.02608 -16.13633,-2.77299 -23.51094,-5.97517 -33.27596,-14.44895 -7.06554,-6.13127 -6.84736,-7.42208 1.10175,-6.51825 3.4375,0.39085 6.025,0.48259 5.75,0.20387 -0.99658,-1.01006 -14.48194,-2.63618 -15.27608,-1.84205 -0.44842,0.44842 2.5534,3.97257 6.67071,7.83144 9.85626,9.23759 17.5018,12.85148 33.17531,15.68127 8.58267,1.54956 12.04547,1.89328 11.27093,1.11875 z m 23.7264,-0.47481 c 0.532,-0.532 2.7595,-1.3868 4.95,-1.89955 2.1905,-0.51275 3.08273,-0.97137 1.98273,-1.01914 -1.1,-0.0478 -4.7,0.76597 -8,1.80833 -4.87947,1.54126 -5.4304,1.91223 -2.95,1.98641 1.6775,0.0502 3.48527,-0.34405 4.01727,-0.87605 z m -1.06727,-3.56001 c 3.85,-1.06802 7.225,-2.19571 7.5,-2.50598 0.275,-0.31026 2.3,-1.09477 4.5,-1.74336 5.05158,-1.48926 15.57308,-8.30539 21.71998,-14.07082 10.15582,-9.52554 18.78406,-25.08183 22.17104,-39.97322 2.25857,-9.93017 2.17044,-11.34285 -0.64102,-10.27621 -1.2375,0.4695 -5.625,1.02086 -9.75,1.22525 -7.05688,0.34966 -7.51817,0.24412 -7.80748,-1.7863 -0.33071,-2.32087 0.30249,-2.55846 10.30748,-3.8677 11.1663,-1.4612 23.27502,-8.62225 26.61935,-15.74257 1.23176,-2.6225 3.84631,-5.98973 5.81011,-7.48272 4.73441,-3.59937 9.07054,-8.06924 9.07054,-9.35029 0,-1.14449 5.05979,-8.20389 6.26146,-8.73595 0.4188,-0.18544 1.19818,-1.15318 1.73195,-2.15053 0.8951,-1.67251 0.64174,-1.65381 -3.26146,0.24076 -7.22492,3.5069 -10.3032,3.77646 -18.61575,1.63013 -9.07215,-2.34246 -19.00256,-2.1397 -21.58295,0.44068 -0.92186,0.92186 -2.14171,1.67611 -2.71077,1.67611 -2.54552,0 -8.99433,6.52871 -10.95829,11.09406 -1.16076,2.69827 -2.46826,4.90594 -2.90555,4.90594 -1.95933,0 -3.95864,-1.33678 -3.95864,-2.64683 0,-3.08568 4.35596,-10.05283 8.7413,-13.98128 l 4.60821,-4.12811 -4.56124,-6.37189 c -5.99722,-8.37789 -13.41368,-15.23903 -16.69909,-15.44873 -3.96961,-0.25337 -4.08918,-0.31285 -4.08918,-2.03394 0,-1.26833 -0.37392,-1.14902 -1.75876,0.56119 -3.16363,3.90691 -6.71424,0.67043 -4.27159,-3.89369 0.85843,-1.60399 0.0269,-2.12345 -7.25,-4.52893 -6.21814,-2.0555 -10.28943,-2.73355 -16.71965,-2.78455 -7.5672,-0.06 -19,1.69411 -19,2.91514 0,0.25239 1.31647,2.12001 2.92548,4.15026 4.36394,5.50639 6.47105,13.04213 5.76399,20.6139 l -0.58664,6.28221 5.37473,1.20281 c 21.33616,4.77483 28.69937,31.92058 12.95469,47.75979 -10.80462,10.86949 -26.4913,11.06535 -37.48583,0.46803 l -4.92782,-4.74978 -3.2593,3.39483 c -5.79484,6.0358 -10.13838,7.70973 -20.0093,7.71121 -8.60158,10e-4 -8.75,0.0426 -8.75,2.43384 0,1.33789 -0.52005,3.87072 -1.15568,5.62851 -1.08586,3.00291 -0.94993,3.38302 2.25,6.29169 1.87313,1.70263 3.98611,3.10888 4.69552,3.12501 0.70941,0.0161 2.95941,0.87562 5,1.91 5.35714,2.71554 26.10725,6.12131 37.21074,6.10748 6.7425,-0.008 12.40095,-0.73394 19.49709,-2.5 12.81724,-3.18989 15.50356,-3.23117 15.49859,-0.23817 -0.005,3.2606 -3.59424,8.64665 -6.49672,9.75017 -1.37475,0.52268 -2.49954,1.41147 -2.49954,1.97508 0,0.56361 -0.48214,1.02475 -1.07143,1.02475 -0.58928,0 -1.74575,0.67432 -2.56993,1.4985 -0.82417,0.82417 -2.70453,1.76639 -4.17856,2.09382 -1.47404,0.32743 -4.04917,1.20489 -5.7225,1.94992 -7.22305,3.21595 -18.24045,4.55548 -34.98967,4.25415 l -16.47466,-0.29639 3.75338,3.2447 c 8.53728,7.38027 17.41711,11.11298 32.67758,13.73628 4.90831,0.84375 9.17851,1.7884 9.48934,2.09923 1.09734,1.09735 13.67539,-0.1903 20.58645,-2.10749 z m 40.5,-82.47272 c 0,-1.1 -0.45,-2 -1,-2 -0.55,0 -0.99978,-1.0125 -0.99951,-2.25 4.9e-4,-2.23828 6.86797,-9.01585 11.80351,-11.64897 3.22732,-1.72179 11.25861,-4.07728 13.946,-4.09021 3.59163,-0.0173 2.91267,4.08892 -1.25,7.55971 -1.925,1.60504 -3.5,3.40484 -3.5,3.99955 0,1.65254 -3.95602,4.90826 -9.49204,7.81174 -6.12107,3.21032 -9.50796,3.43052 -9.50796,0.61818 z m 9,-3.36173 c 4.30061,-2.42779 8,-5.65282 8,-6.97419 0,-0.54301 1.6875,-2.48922 3.75,-4.32491 2.0625,-1.83568 3.525,-3.33309 3.25,-3.32756 -1.50707,0.0303 -10.20077,3.05406 -12.64753,4.39899 -3.66433,2.0142 -12.18544,9.58314 -10.7927,9.5867 0.58287,0.001 3.43212,-2.0223 6.33165,-4.4973 5.24143,-4.474 9.10858,-5.78543 9.10858,-3.08889 0,1.84596 -4.51449,5.57987 -9.77988,8.08889 -2.30845,1.1 -4.20234,2.32338 -4.20865,2.71862 -0.0143,0.8945 2.43529,-0.01 6.98853,-2.58035 z m -35,84.31604 c 1.09546,-0.74131 0.69092,-0.83408 -1.5,-0.34401 -3.67693,0.82247 -4.47511,1.39483 -1.91667,1.37439 1.05417,-0.008 2.59167,-0.47209 3.41667,-1.03038 z m 6.427,-2.47578 c 2.91505,-2.20537 1.48811,-2.46248 -1.927,-0.34722 -1.65,1.02199 -2.325,1.84622 -1.5,1.83162 0.825,-0.0146 2.36715,-0.68258 3.427,-1.4844 z m 7.14043,-5.58763 c 0.37335,-0.6041 -0.50159,-0.32492 -1.94431,0.62038 -1.44271,0.94531 -2.62312,1.90782 -2.62312,2.13891 0,0.72338 3.85397,-1.6049 4.56743,-2.75929 z m 3.43257,-2.3909 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 6,-5 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -65.02348,-3.06139 c 4.11208,-0.85786 8.83708,-2.16527 10.5,-2.90536 1.66291,-0.74008 4.22952,-1.6135 5.70356,-1.94093 1.47404,-0.32743 3.28207,-1.19733 4.01785,-1.93311 0.73578,-0.73578 2.00475,-1.59958 2.81993,-1.91955 1.26954,-0.49832 1.25981,-0.59309 -0.0679,-0.66071 -0.8525,-0.0434 -2.0117,0.38275 -2.57599,0.94704 -1.37761,1.37761 -13.6602,5.81918 -19.87401,7.18674 -2.75,0.60523 -10.175,1.4011 -16.5,1.7686 l -11.5,0.66819 10,0.17442 c 5.89347,0.1028 13.07026,-0.46609 17.47652,-1.38533 z m 70.52348,-3.43861 c 0.99549,-1.1 1.58498,-2 1.30998,-2 -0.275,0 -1.31449,0.9 -2.30998,2 -0.99549,1.1 -1.58498,2 -1.30998,2 0.275,0 1.31449,-0.9 2.30998,-2 z m -39.74244,-12.00913 c 1.24166,-1.81999 2.07092,-3.49572 1.84281,-3.72384 -0.22812,-0.22811 -5.13023,0.74348 -10.89357,2.15911 -8.13994,1.99938 -13.01511,2.57386 -21.84222,2.57386 -12.97438,0 -33.27435,-3.17908 -39.07474,-6.11931 -2.04059,-1.03438 -4.29059,-1.85699 -5,-1.82803 -0.70941,0.029 0.84976,1.11449 3.46483,2.41228 11.06002,5.4888 45.285,8.38592 59.24533,5.01506 3.3,-0.79682 6.7875,-1.45579 7.75,-1.46438 2.46056,-0.022 2.17728,2.43675 -0.5,4.33963 l -2.25,1.59919 2.5,-0.82725 c 1.375,-0.45498 3.5159,-2.31633 4.75756,-4.13632 z m 48.7905,-2.0838 c 0.87968,-1.70111 1.42188,-3.27046 1.2049,-3.48744 -0.21698,-0.21698 -1.14288,1.17483 -2.05756,3.09293 -2.05658,4.3127 -1.34401,4.64239 0.85266,0.39451 z m -128.0536,-7.9132 c -0.99854,-1.10337 -2.04794,-1.77372 -2.33199,-1.48967 -0.28406,0.28406 0.35068,1.1725 1.41054,1.97433 2.70408,2.04576 3.04782,1.86496 0.92145,-0.48466 z m -1.82881,-15.83491 c 0.54476,-4.29796 0.58312,-4.33487 3.86431,-3.71932 1.87409,0.35158 3.58779,0.17886 3.944,-0.3975 0.36318,-0.58764 0.011,-0.78172 -0.83176,-0.45833 -1.53986,0.5909 -6.76761,-1.7051 -10.1422,-4.4544 -1.9801,-1.6132 -1.98121,-1.60721 -0.11164,0.60221 1.66468,1.96729 1.82292,3.38868 1.33592,12 -0.43762,7.73827 -0.35047,8.83317 0.41936,5.26838 0.53449,-2.475 1.21939,-6.45347 1.52201,-8.84104 z m 135.93852,5.11187 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m 1,-4 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m -78.41667,-2.95394 c -0.72187,-0.28887 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28494 0.60416,-0.60416 z m 79.46844,-3.58592 c -0.27393,-0.67703 -0.48137,0.11903 -0.46099,1.76903 0.0204,1.65 0.2445,2.20394 0.49804,1.23097 0.25354,-0.97297 0.23687,-2.32297 -0.0371,-3 z m -124.92497,2.57604 c -0.97296,-0.25354 -2.32297,-0.23687 -3,0.0371 -0.67703,0.27393 0.11903,0.48137 1.76903,0.46099 1.65,-0.0204 2.20394,-0.2445 1.23097,-0.49804 z m 41.5128,0.0286 c -0.69092,-0.27855 -1.07389,-0.80553 -0.85104,-1.17105 0.22285,-0.36552 -1.20295,-0.75058 -3.16844,-0.85567 -1.9655,-0.1051 -4.95753,-1.20361 -6.64896,-2.44115 -2.34922,-1.71881 -2.72116,-1.81335 -1.57533,-0.40044 1.81731,2.24089 8.73947,5.51042 11.5,5.43176 1.1,-0.0313 1.4347,-0.28489 0.74377,-0.56345 z m -32.38703,-2.26255 c 2.07738,-1.0598 4.4142,-2.7473 5.19293,-3.75 1.34843,-1.73625 1.32057,-1.74235 -0.58488,-0.12808 -1.10041,0.93226 -4.01766,2.60988 -6.48277,3.72804 -2.46511,1.11817 -3.90159,2.04291 -3.19218,2.05499 0.70941,0.0121 2.98952,-0.84515 5.0669,-1.90495 z m 47.01576,0.49285 c 1.52524,-0.78874 3.40764,-2.25124 4.1831,-3.25 1.33163,-1.71509 1.29982,-1.7257 -0.57283,-0.1911 -1.09052,0.89366 -3.33277,2.33815 -4.98277,3.20996 -1.65,0.87182 -2.64015,1.60314 -2.20034,1.62516 0.43982,0.022 2.04759,-0.60529 3.57284,-1.39402 z m -3.36392,-2.43092 c 7.61004,-3.45714 13.65809,-12.5947 13.65809,-20.63499 0,-11.12314 -11.04986,-22.7 -21.66667,-22.7 -10.70226,0 -21.66666,11.57813 -21.66666,22.87946 0,4.64065 3.02363,11.97613 6.07456,14.73719 1.78745,1.61762 1.83913,1.5186 1.37172,-2.62829 -1.45227,-12.88452 7.92692,-22.30909 15.08152,-15.15449 4.84657,4.84656 5.99347,17.1236 2.14795,22.99261 -1.93035,2.94608 -0.65228,3.07608 4.99949,0.50854 z m -53.08133,-2.28112 c 3.70718,-6.27576 1.47296,-18.7986 -3.64361,-20.42254 -4.73397,-1.50251 -8.98587,3.85239 -9.06867,11.42119 -0.0712,6.50478 0.82438,8.55477 4.54657,10.40756 4.71129,2.34514 6.08999,2.10771 8.16571,-1.40621 z m 8.76107,0.52566 c 1.47857,-0.7519 4.15313,-3.11185 5.94345,-5.24433 3.16416,-3.76887 3.25672,-4.14456 3.31169,-13.44187 l 0.0566,-9.56463 -3.42512,-0.64252 c -6.57739,-1.23384 -11.12219,-3.74493 -15.41056,-8.51464 l -4.3202,-4.8051 -3.93064,1.7598 c -7.58534,3.39606 -13.58015,12.55734 -13.58015,20.75322 0,4.42188 3.08834,12.18072 5.7167,14.36206 1.23314,1.02342 1.44997,0.46906 1.44997,-3.70719 0,-9.99193 6.09864,-17.05981 12.75,-14.7763 5.96164,2.04672 9.18113,14.88436 5.77636,23.03311 -1.44844,3.46661 -1.43562,3.51518 0.75,2.84119 1.223,-0.37713 3.43338,-1.30089 4.91195,-2.0528 z m 37.28108,-0.95627 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 66.2806,0.88741 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z m -84.75,-1.68823 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 37,-1.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -83,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 41.40581,-3.29696 c 1.26469,0.48531 1.32727,0.18279 0.38844,-1.87771 -0.61552,-1.35092 -1.24526,-2.33009 -1.39942,-2.17593 -0.15416,0.15416 -1.48307,2.06857 -2.95312,4.25423 l -2.67282,3.97393 2.56468,-2.37651 c 1.43852,-1.33299 3.22665,-2.12249 4.07224,-1.79801 z m 103.59419,2.7059 c 0,-0.53273 -0.675,-0.70959 -1.5,-0.39301 -0.825,0.31659 -1.5,0.75246 -1.5,0.96862 0,0.21615 0.675,0.39301 1.5,0.39301 0.825,0 1.5,-0.43588 1.5,-0.96862 z m -59.19313,-4.55784 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z m -46.2027,-6.20271 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 48,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 45,-5 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 50,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -96,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 95,-5 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58438 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.0789,-1.91667 z m 49.01374,-4.98626 c -0.12014,-0.12014 -1.54582,0.178 -3.16817,0.66254 -1.62236,0.48454 -2.16224,0.91966 -1.19974,0.96694 0.9625,0.0473 1.76595,0.87345 1.78544,1.83595 0.0268,1.32558 0.37079,1.14405 1.41817,-0.74849 0.76051,-1.37418 1.28444,-2.5968 1.1643,-2.71694 z m 42.50618,0.44876 c -0.98762,-0.98026 -1.10248,-0.8654 -0.5598,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30789,-0.30789 6.4e-4,-1.11479 -0.68278,-1.79313 z M 65.08571,861.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -85,-2.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 38.4694,-2.07674 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 6.58891,-0.87068 c 2.30641,-2.50217 6.01686,-5.17968 8.48316,-6.12157 3.50845,-1.33988 4.61401,-2.37208 5.53737,-5.16987 3.7517,-11.36776 -3.1423,-24.22022 -15.17695,-28.29436 -4.64464,-1.57236 -5.7447,-1.61747 -9.7859,-0.40124 -14.93589,4.49504 -21.66079,20.75015 -13.81981,33.40461 l 2.18716,3.52985 0.74099,-5.89906 c 1.49666,-11.91498 8.85142,-17.25247 15.12639,-10.9775 4.48246,4.48246 5.8535,13.25622 3.22323,20.62656 -0.73605,2.0625 -1.17556,3.75 -0.9767,3.75 0.19886,0 2.20634,-2.00134 4.46106,-4.44742 z m -19.14164,3.16445 c -0.22917,-0.15563 -1.31667,-0.94313 -2.41667,-1.75 -1.85,-1.35701 -1.89707,-1.33579 -0.62755,0.28297 0.75484,0.9625 1.84234,1.75 2.41667,1.75 0.57432,0 0.85672,-0.12734 0.62755,-0.28297 z m 24.08333,-3.21703 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.94528,-0.0659 c -1.51303,-1.82309 -6.92706,-4.78561 -7.57027,-4.1424 -0.24152,0.24152 0.91037,0.99812 2.55977,1.68132 1.6494,0.68321 3.51893,1.86878 4.15451,2.6346 0.63558,0.76583 1.3806,1.39242 1.6556,1.39242 0.275,0 -0.0848,-0.70467 -0.79961,-1.56594 z m -75.94528,-0.9341 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 17,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 35.91667,-3.2579 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m -46,-1 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m 5.95162,-1.75427 c -1.01049,-2.21779 -1.20856,-2.27175 -2.75296,-0.75 -1.54948,1.52676 -1.49021,1.68325 0.86027,2.27141 1.38842,0.34743 2.62726,0.68493 2.75297,0.75 0.1257,0.0651 -0.26142,-0.95706 -0.86028,-2.27141 z m 49.04838,0.74819 c 0.22917,-0.19715 -0.55833,-0.35846 -1.75,-0.35846 -1.38524,0 -2.17763,-0.63115 -2.19707,-1.75 -0.0265,-1.52656 -0.17522,-1.49464 -1.16454,0.25 -0.62377,1.1 -1.62259,2.32475 -2.21959,2.72166 -0.59701,0.39691 0.71453,0.44572 2.91453,0.10846 2.2,-0.33726 4.1875,-0.77451 4.41667,-0.97166 z m 72.08333,-1.88414 c 0,-1.39308 -3.70207,-0.18103 -4.79566,1.57008 -1.24992,2.00144 -1.21295,2.01141 1.75946,0.47432 1.66991,-0.86354 3.0362,-1.78352 3.0362,-2.0444 z m 29.1875,0.84257 c -0.72188,-0.28888 -1.58438,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -19.9375,-2.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -84.64583,-3.06689 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 122.39583,-2.04448 c 0,-0.85783 -0.12734,-1.37218 -0.28297,-1.14302 -0.15563,0.22917 -0.89428,1.21447 -1.64144,2.18956 -1.18269,1.54348 -1.14607,1.69139 0.28297,1.14301 0.90279,-0.34643 1.64144,-1.33173 1.64144,-2.18955 z M 82.68988,837.89013 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 65.39583,1.38416 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11445 2.59501,2.70524 2.59501,1.90499 z m -66.39583,-7.38416 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 60.39583,0.35161 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z M 79.2098,826.35263 c -0.98761,-0.98026 -1.10248,-0.8654 -0.55979,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30788,-0.30789 6.3e-4,-1.11479 -0.68279,-1.79313 z m 56.87591,0.88911 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -97,-4.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 53.22334,-1.87639 c -0.26254,-1.00396 -0.54753,-1.69503 -0.63331,-1.53571 -0.0858,0.15931 -0.6787,0.98073 -1.3176,1.82537 -0.93948,1.24202 -0.81836,1.53572 0.63331,1.53572 1.24538,0 1.6488,-0.55888 1.3176,-1.82538 z M 43.08571,819.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.75848,-0.53051 c -0.94115,-1.51852 -0.96737,-2.21193 -0.10397,-2.75 0.63498,-0.39572 -0.80847,-0.71949 -3.20766,-0.71949 l -4.36218,0 3.39287,1.74065 c 1.86608,0.95735 3.67359,2.19485 4.01668,2.75 0.3431,0.55514 0.82607,1.00935 1.07327,1.00935 0.24721,0 -0.11685,-0.91373 -0.80901,-2.03051 z m 52.17485,-0.31215 c -0.23833,-0.20679 -1.78333,-0.65233 -3.43333,-0.99008 -2.73596,-0.56005 -2.80197,-0.51498 -0.75,0.51213 1.2375,0.61943 2.25,1.59747 2.25,2.17342 0,0.65288 0.44557,0.60162 1.18333,-0.13614 0.65084,-0.65084 0.98834,-1.35253 0.75,-1.55933 z m 9.94836,-7.40734 c 2.30606,-3.4375 3.82136,-6.25 3.36733,-6.25 -1.81925,0 -11.24902,12.98428 -11.24902,15.48929 0,1.26984 3.89338,-3.29416 7.88169,-9.23929 z m -84.96502,4.11454 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35466 2.91667,-1.55517 z m 2.58333,-1.36454 c -0.33991,-0.55 -0.81647,-1 -1.05901,-1 -0.24254,0 -0.44099,0.45 -0.44099,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m 6.82946,-1.58385 c -0.33428,-0.87111 -0.88789,-1.20861 -1.23025,-0.75 -0.34236,0.45862 -1.02974,1.17135 -1.52751,1.58385 -0.49776,0.4125 0.0558,0.75 1.23025,0.75 1.53743,0 1.96511,-0.44346 1.52751,-1.58385 z m 20.85804,0.90074 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28495 0.60416,-0.60417 z m 29,0 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -22.9375,-0.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m 18,0 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -8.5,-1.02705 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z M 53.3824,808.21186 c -0.98818,-1.3241 -1.94149,-2.01468 -2.11847,-1.53464 -0.36611,0.99302 1.91319,3.8465 3.11847,3.90404 0.43818,0.0209 -0.0118,-1.04531 -1,-2.3694 z m -3.29669,-3.66948 c 0,-1.50044 -5.57099,-6.92308 -7.11248,-6.92308 -0.69649,0 0.5064,1.73277 2.67307,3.8506 4.69729,4.5914 4.43941,4.41292 4.43941,3.07248 z m 92,-3.42308 c 1.29175,-1.375 2.12363,-2.5 1.84863,-2.5 -0.275,0 -1.55688,1.125 -2.84863,2.5 -1.29175,1.375 -2.12363,2.5 -1.84863,2.5 0.275,0 1.55688,-1.125 2.84863,-2.5 z m 6.04469,-1.70523 c 2.56704,-3.19434 2.82393,-3.81616 1.06867,-2.58673 -1.89119,1.32465 -5.69179,6.79196 -4.72142,6.79196 0.15033,0 1.79407,-1.89235 3.65275,-4.20523 z m -0.0447,-8.71959 c 0,-0.275 -2.25,1.71617 -5,4.42482 -2.75,2.70865 -5,5.14982 -5,5.42482 0,0.275 2.25,-1.71617 5,-4.42482 2.75,-2.70865 5,-5.14982 5,-5.42482 z m 1,3.42482 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 21.91908,-7.85167 c 2.4305,-0.72671 4.0055,-1.56089 3.5,-1.85373 -0.50549,-0.29284 -2.71908,0.27521 -4.91908,1.26232 -4.84957,2.17594 -4.44469,2.34468 1.41908,0.59141 z m 6.88779,-1.17479 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z M 17.08571,783.6193 c -1.925,-1.05389 -3.95,-1.91617 -4.5,-1.91617 -0.55,0 0.575,0.86228 2.5,1.91617 1.925,1.05389 3.95,1.91617 4.5,1.91617 0.55,0 -0.575,-0.86228 -2.5,-1.91617 z m 160,-2 c 0,-0.55 -0.7875,-0.99311 -1.75,-0.98469 -1.49555,0.0131 -1.5319,0.15626 -0.25,0.98469 1.88721,1.21961 2,1.21961 2,0 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2907"
+ transform="translate(0,784.36218)"
+ d="m 72.6,181.20757 c -16.765609,-3.86833 -22.376319,-6.32293 -32,-13.9995 l -2,-1.59535 13.2,-0.0317 c 17.959636,-0.043 26.293525,-1.0427 36.676385,-4.39926 12.401975,-4.00929 20.661075,-10.22837 22.672535,-17.07236 1.39926,-4.76097 -0.60247,-5.05117 -14.284918,-2.07088 C 80.913403,145.51284 69.067454,145.46531 50.6,141.85286 39.54215,139.68982 28.750784,134.8087 27.432732,131.37391 c -0.409763,-1.06782 0.94297,-9.55504 1.67366,-10.50077 0.129162,-0.16717 4.118063,-0.56369 8.864224,-0.88115 9.677258,-0.64731 12.721718,-1.79467 18.59718,-7.00868 l 3.565638,-3.16423 4.911016,4.16615 c 6.374081,5.4073 11.045891,7.19552 18.75555,7.17903 10.247136,-0.0219 18.94097,-5.4255 24.01507,-14.92636 2.33003,-4.3628 2.74898,-6.0141 3.03751,-11.972478 0.24409,-5.040832 -0.0244,-7.992693 -0.99183,-10.905433 C 106.83021,74.235948 98.683943,66.74733 89.719703,64.844988 L 85,63.8434 84.966254,55.710271 C 84.929438,46.837023 83.908403,43.511262 79.05568,36.458071 76.206234,32.316543 75.915993,32.561487 85.4,31.103895 c 9.620682,-1.478597 19.97708,-0.291557 29.26619,3.354462 4.00483,1.571915 4.0652,1.646353 4,4.932693 -0.0764,3.849526 1.76499,4.910844 4.39333,2.532225 0.84726,-0.766762 1.54048,-1.021054 1.54048,-0.565095 0,0.45596 1.6637,1.247942 3.6971,1.759959 4.38748,1.10478 11.00212,7.029509 17.23538,15.437707 l 4.03312,5.440379 -4.6828,5.026303 c -4.55714,4.891416 -8.2828,11.01514 -8.2828,13.614092 0,1.528769 2.86706,3.239468 4.42637,2.641103 0.60573,-0.232443 1.86318,-1.915954 2.79432,-3.741133 2.17353,-4.260467 7.69681,-10.272278 10.77931,-11.732734 1.32,-0.625402 3.4424,-1.697018 4.71645,-2.381368 2.96143,-1.590728 11.65807,-1.536216 19.53585,0.122452 7.69091,1.619321 10.4686,1.555228 15.93996,-0.367797 5.65346,-1.987032 5.64225,-1.987649 3.63541,0.2 -0.90817,0.99 -3.01076,3.96 -4.67241,6.6 -1.66166,2.64 -5.30895,6.908849 -8.1051,9.486333 -2.79614,2.577483 -5.99227,6.236344 -7.1025,8.130802 -4.94788,8.442912 -15.3818,14.634562 -28.34766,16.821932 -7.93582,1.33879 -10.1786,2.49921 -9.29263,4.80802 0.46879,1.22165 1.5792,1.32779 10.18353,0.97342 l 9.65736,-0.39773 -0.5479,3.65369 c -1.59381,10.62824 -7.28652,24.58268 -14.24705,34.92353 -11.30309,16.79232 -34.07569,29.48213 -55.75331,31.06798 -4.998646,0.36568 -7.935952,-0.008 -17.6,-2.23755 z m 81.50924,-82.494134 c 3.52664,-1.764307 6.56239,-3.962996 7.90749,-5.727124 1.2008,-1.574879 3.53327,-4.37647 5.18327,-6.225757 1.93865,-2.172795 3,-4.147985 3,-5.583022 0,-2.220043 -0.002,-2.220533 -4.38306,-1.705537 -8.74931,1.028309 -19.06055,6.827181 -22.74752,12.792833 l -1.71519,2.775229 1.70366,3.268542 c 2.14696,4.11903 3.52613,4.16955 11.05135,0.404836 l 0,0 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2913"
+ transform="translate(0,784.36218)"
+ d="m 160.6,87.334076 c 0,-0.534851 -1.1468,-0.981516 -2.6,-1.012667 -2.30544,-0.04942 -2.02164,-0.279224 2.50495,-2.028386 2.80772,-1.084959 5.23233,-1.845272 5.38801,-1.689584 0.15569,0.155688 -0.97154,1.499081 -2.50494,2.98532 C 161.85461,87.074997 160.6,87.86039 160.6,87.334076 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3703"
+ transform="translate(0,784.36218)"
+ d="m 24.692801,119.04257 c -0.05104,-2.05401 -0.313955,-4.31089 -0.584255,-5.01528 -0.431011,-1.12319 -0.185552,-1.10664 1.99579,0.13457 1.631194,0.92818 2.07587,1.50427 1.292,1.67384 -0.657385,0.1422 -1.361474,1.0422 -1.564643,2 -0.203169,0.95779 -0.521653,2.46144 -0.707744,3.34144 -0.186091,0.88 -0.380107,-0.0805 -0.431148,-2.13457 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3709"
+ transform="translate(0,784.36218)"
+ d="m 104.6,146.52914 c 0,-0.55196 -0.79531,-1.29776 -1.76736,-1.65735 -1.56978,-0.5807 -1.42649,-0.71774 1.28174,-1.2258 3.83551,-0.71955 4.4795,-0.10717 2.24118,2.13115 -1.00812,1.00812 -1.75556,1.32829 -1.75556,0.752 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3719"
+ transform="translate(0,784.36218)"
+ d="m 76.851058,112.03382 c -3.393188,-2.09142 -4.25448,-3.92327 -4.233488,-9.00408 0.03274,-7.923733 4.577488,-13.887568 8.633406,-11.329161 3.986638,2.514706 5.541626,13.083911 2.747781,18.676561 -1.667169,3.3373 -3.668438,3.80115 -7.147699,1.65668 l 0,0 z" />
+ <path
+ style="fill:#00d37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3721"
+ transform="translate(0,784.36218)"
+ d="m 31.011129,112.18685 c -3.337597,-1.68708 -4.784967,-4.28598 -4.794874,-8.60971 -0.01706,-7.444764 3.322321,-12.761965 7.700427,-12.261175 5.345895,0.611491 7.922362,14.073845 3.761169,19.652565 -2.071377,2.777 -3.181718,2.97991 -6.666722,1.21832 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3747"
+ transform="translate(0,784.36218)"
+ d="M 49.694395,74.66073 C 44.47115,71.825511 44.018691,61.3525 48.893397,56.120117 c 1.243238,-1.334459 2.71535,-2.426289 3.27136,-2.426289 3.274952,0 7.59925,10.034368 6.191417,14.366947 -2.961401,9.11366 -3.406311,9.452665 -8.661779,6.599955 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3749"
+ transform="translate(0,784.36218)"
+ d="m 30.863598,109.87939 c -4.598088,-3.22062 -2.443473,-16.412835 2.680623,-16.412835 3.343974,0 5.248203,11.238065 2.708365,15.983795 -1.423064,2.65902 -2.125412,2.71494 -5.388988,0.42904 l 0,0 z" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3751"
+ transform="translate(0,784.36218)"
+ d="M 53.409091,253.22727 C 175,254.36364 176.13636,254.36364 176.13636,254.36364" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3753"
+ transform="translate(0,784.36218)"
+ d="m 101.91757,251.70568 c -21.718752,-0.17272 -39.488638,-0.58449 -39.488638,-0.91506 0,-0.33057 3.818082,-4.96825 8.484628,-10.30595 4.666545,-5.33771 9.973982,-12.85892 11.794303,-16.71379 3.448266,-7.30236 8.521552,-22.38453 9.820557,-29.19514 0.752563,-3.94565 0.76643,-3.95339 12.3156,-6.87496 6.3592,-1.60867 12.35971,-3.28795 13.33446,-3.73173 1.29391,-0.58909 2.73131,0.66046 5.32536,4.62941 1.9542,2.98995 11.57847,13.87378 21.38726,24.18628 9.8088,10.3125 18.96093,20.28409 20.33807,22.15909 2.01779,2.74727 7.42703,15.23542 7.42703,17.14657 0,0.25689 -7.03125,0.34607 -15.625,0.19819 -8.59375,-0.14789 -33.39488,-0.4102 -55.11363,-0.58291 l 0,0 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3782"
+ transform="translate(0,784.36218)"
+ d="m 51.774116,254.22272 c 0.816832,-1.01161 5.399709,-6.3219 10.184171,-11.80065 4.784463,-5.47875 10.255577,-12.2121 12.158031,-14.963 5.284789,-7.64167 14.376394,-33.83808 12.993969,-37.44062 -0.338967,-0.88334 -2.48378,-1.73514 -5.328004,-2.116 C 60.981864,185.11713 50.75895,182.31448 43.625018,177.44148 37.971557,173.57975 28.01174,163.28381 28.01174,161.3013 c 0,-1.83865 0.635315,-1.8844 17.079208,-1.22988 19.475363,0.77518 28.155408,-0.12388 38.075567,-3.94376 9.279191,-3.57307 15.45203,-6.36285 15.01445,-6.78568 -0.201984,-0.19518 -4.599918,0.0895 -9.773185,0.63261 -15.856397,1.66468 -37.875872,-0.52821 -50.869606,-5.06603 -3.201056,-1.11791 -7.99066,-3.68786 -10.643565,-5.71099 l -4.823463,-3.67842 0.178374,-9.45002 0.178374,-9.45001 0.5642,7.42574 c 0.582301,7.66397 1.29799,8.16822 2.459224,1.73268 0.423991,-2.34976 0.289983,-3.71287 -0.365011,-3.71287 -0.569229,0 -1.034963,-1.33664 -1.034963,-2.9703 0,-1.63367 -0.407778,-2.9703 -0.906174,-2.9703 -1.708089,0 -9.947718,-12.02652 -11.073528,-16.16286 C 8.4406212,86.620448 14.328838,72.981775 26.509135,66.520142 l 4.472902,-2.372869 0,-7.169297 c 0,-11.907876 4.934342,-21.608335 13.56406,-26.665688 2.388815,-1.399939 4.1792,-3.048653 3.978634,-3.66381 C 47.539733,23.627398 33.787529,13.942425 21.173642,7.3865059 6.6394252,-0.16748247 5.7525435,-1.0667564 8.2445952,-5.7231976 9.9048868,-8.825481 13.26451,-8.0142814 26.786199,-1.2462239 42.52818,6.6331633 49.704459,11.834699 56.658674,20.406047 c 7.066894,8.71023 9.386734,9.398438 22.022822,6.533328 12.009438,-2.723024 25.519864,-2.231151 36.616764,1.3331 4.17096,1.339683 7.95921,2.16177 8.41835,1.826861 0.45913,-0.33491 2.70455,-3.059423 4.98981,-6.054473 2.28526,-2.995049 7.42528,-8.682601 11.42226,-12.639003 7.12067,-7.0483759 7.54019,-7.2929957 20.80065,-12.12871266 7.44339,-2.71438994 14.38913,-4.93525434 15.435,-4.93525434 1.40526,0 2.17641,1.0827118 2.95451,4.1481669 0.5791,2.28149179 0.85167,4.4737776 0.60572,4.871746 -0.24596,0.3979683 -6.12349,2.612099 -13.0612,4.92029 -12.32753,4.1014041 -12.76057,4.3449071 -19.06805,10.7223141 -3.54973,3.589081 -8.19833,9.098685 -10.33023,12.243564 l -3.87618,5.717962 4.38964,4.574292 c 2.4143,2.515859 3.60993,4.300819 2.65696,3.966577 -2.15679,-0.756469 -2.25789,0.631979 -0.17206,2.363061 1.27233,1.05594 1.70648,1.059167 2.35028,0.01747 0.5549,-0.897844 2.45839,0.813688 6.40236,5.756734 3.08697,3.868951 6.15063,7.065929 6.80813,7.104394 0.6575,0.03847 4.65679,0.0099 8.8873,-0.0634 4.23053,-0.07334 11.0745,0.619228 15.20883,1.53903 6.08457,1.353687 8.24222,1.455077 11.32293,0.532074 4.78641,-1.434041 9.61096,-5.430654 10.01889,-8.299556 0.1988,-1.398101 1.12005,-2.308693 2.53968,-2.510314 2.12619,-0.301966 2.22772,-0.004 2.22772,6.538442 0,6.740641 -0.099,7.001552 -5.9449,15.662921 -3.26969,4.844452 -7.74462,10.309246 -9.94428,12.143987 -2.19966,1.834742 -5.77393,5.949037 -7.94282,9.142879 -2.34976,3.460168 -6.29513,7.465423 -9.76248,9.910673 l -5.81903,4.10369 -1.15924,7.92805 c -1.61723,11.06032 -4.40347,19.58965 -9.70377,29.70553 -5.01528,9.57187 -13.95714,20.46445 -14.03497,17.09676 -0.0428,-1.8524 -0.1273,-1.86246 -1.77762,-0.21171 -1.37485,1.3752 -1.46515,1.89852 -0.43722,2.53406 1.41537,0.87508 -1.77232,4.09197 -9.46671,9.55344 -2.27836,1.61719 -4.34463,3.44333 -4.59171,4.0581 -0.8189,2.03758 6.19452,11.05322 18.90021,24.29583 6.90108,7.19272 12.04414,13.24542 11.42903,13.45046 -0.61512,0.20504 -0.83848,1.12371 -0.49637,2.0415 0.34212,0.91778 -1.79925,-0.97306 -4.75858,-4.20188 -2.95935,-3.22881 -5.27705,-6.21281 -5.15046,-6.6311 0.12659,-0.41828 -1.76241,-2.39328 -4.19777,-4.38889 -2.43538,-1.9956 -4.20453,-3.98988 -3.93146,-4.43172 0.27308,-0.44185 -1.40227,-2.36965 -3.72301,-4.28402 -2.32073,-1.91436 -5.99559,-5.73898 -8.16635,-8.49916 -4.50513,-5.7284 -5.73975,-6.34273 -10.18478,-5.06791 -1.75731,0.50399 -3.19511,0.54209 -3.19511,0.0847 0,-1.33295 -11.17951,1.64109 -12.389579,3.29596 -0.60449,0.82669 -2.322383,1.8101 -3.817542,2.18536 -3.551652,0.89142 -4.937215,3.23379 -7.580515,12.81533 -4.406767,15.97381 -11.099683,29.94917 -15.20688,31.75323 -1.152028,0.50601 -2.096442,1.7759 -2.098696,2.82193 -0.0024,1.08338 -1.280677,2.61084 -2.970297,3.54913 -1.631409,0.90597 -2.982805,2.27784 -3.003103,3.04859 -0.05664,2.15103 -3.526894,6.90294 -4.570213,6.25813 -0.985639,-0.60915 -3.808724,1.30636 -3.808724,2.5843 0,1.92758 5.895059,2.34928 41.089109,2.93925 l 37.62376,0.63071 -39.232671,0.18757 c -21.57797,0.10316 -40.736386,0.48547 -42.574257,0.84959 -3.159411,0.62595 -3.260618,0.56176 -1.856436,-1.17724 z m 42.238485,-67.99171 c -1.942887,-0.70765 -3.471758,-0.70422 -4.950495,0.0112 -1.790743,0.86631 -1.332552,1.03319 2.81102,1.02385 4.566697,-0.0103 4.732564,-0.0905 2.139475,-1.03501 l 0,-3e-5 z m -14.020663,-0.82863 c -1.089109,-0.4866 -6.435644,-1.80129 -11.881188,-2.92155 -5.759121,-1.18476 -12.800298,-3.45953 -16.831683,-5.43774 -6.954731,-3.41271 -17.742094,-11.92119 -16.880858,-13.3147 0.253072,-0.40948 3.040932,-0.57204 6.195246,-0.36125 4.48988,0.30005 5.355073,0.14443 3.984772,-0.71671 -0.96269,-0.60499 -4.913826,-1.36519 -8.780302,-1.68935 -6.863409,-0.57539 -7.004171,-0.54119 -5.941584,1.44428 2.200044,4.11082 13.668199,13.46069 20.585236,16.78294 7.129107,3.42411 21.632479,7.0912 28.065212,7.09613 2.851296,0.002 3.114461,-0.15412 1.485149,-0.88205 z m 13.55198,-1.63782 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52001 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 8.981792,-3.22305 c 4.1272,-1.05557 9.34757,-2.85973 11.60083,-4.00925 2.25325,-1.14953 4.87457,-1.8432 5.82513,-1.54151 0.95056,0.30171 2.59602,-0.12295 3.65656,-0.94367 1.60041,-1.23851 1.63367,-1.38963 0.19559,-0.88881 -2.84772,0.99172 -1.97918,-0.17229 2.18456,-2.92772 2.15449,-1.42577 4.50534,-2.36663 5.22413,-2.09081 0.7188,0.27584 3.05637,-1.2901 5.1946,-3.47985 2.13823,-2.18975 3.51995,-3.98136 3.07047,-3.98136 -0.44946,0 -0.26663,-0.66342 0.4063,-1.47425 0.67294,-0.81083 1.5681,-1.26129 1.98925,-1.001 0.42114,0.26029 1.37313,-0.30156 2.11553,-1.24853 1.22149,-1.55808 1.18509,-1.59258 -0.38286,-0.36292 -0.95297,0.74738 -1.73267,0.91332 -1.73267,0.36877 0,-1.1032 2.94273,-3.80059 3.86504,-3.5428 0.32472,0.0908 0.81317,-0.0921 1.08545,-0.40626 0.27228,-0.3142 -0.0619,-0.25079 -0.74257,0.14094 -1.83418,1.05552 -1.52708,0.0245 1.35025,-4.53358 3.80038,-6.02017 8.15245,-16.13427 10.34121,-24.03269 2.90781,-10.4932 3.24131,-10.00199 -6.51584,-9.59724 -8.06376,0.33451 -11.36374,-0.51104 -11.36374,-2.91169 0,-1.41219 3.87705,-3.01077 12.01762,-4.9551 13.6173,-3.2524 18.1279,-6.30458 30.44942,-20.604205 3.20647,-3.721241 5.60795,-5.75908 6.01348,-5.102907 0.45242,0.732027 1.17307,0.513084 2.18435,-0.663636 2.69435,-3.135129 3.29702,-4.863342 0.99046,-2.840244 -1.18271,1.037369 -2.15038,1.440581 -2.15038,0.896027 0,-1.154396 3.94299,-4.919356 4.6419,-4.432319 0.26048,0.181519 0.77064,-0.0013 1.13367,-0.406262 0.36304,-0.404963 0.10314,-0.415797 -0.57755,-0.02408 -1.80598,1.039294 -1.51814,-0.190163 0.80999,-3.459724 2.31999,-3.258114 2.32271,-3.256657 -3.39724,-1.816357 -3.2192,0.810603 -6.66348,0.694459 -14.67251,-0.494768 -15.04707,-2.234274 -20.55437,-0.689621 -28.57683,8.015049 -2.42602,2.632325 -4.72907,4.680174 -5.11788,4.550775 -0.38882,-0.129399 -0.48449,0.344426 -0.2126,1.052946 0.27188,0.70852 -0.4282,2.123094 -1.55573,3.143497 -2.0095,1.818571 -2.09324,1.812104 -4.23219,-0.326854 l -2.18214,-2.182131 2.25594,-4.252496 c 1.24077,-2.338872 4.17354,-6.452573 6.51728,-9.141556 2.34372,-2.688985 4.05061,-5.50801 3.79308,-6.264503 -0.31259,-0.918192 -0.0455,-1.114196 0.80328,-0.589595 0.85837,0.530499 1.02875,0.393018 0.52435,-0.423105 -0.41094,-0.664922 -0.99572,-0.9604 -1.2995,-0.656618 -0.69266,0.69266 -3.20978,-1.330935 -3.20978,-2.580451 0,-0.510014 0.51439,-0.609392 1.14308,-0.220837 0.73045,0.451439 0.87336,0.270048 0.3959,-0.50249 -0.41094,-0.664922 -1.00055,-0.955563 -1.31024,-0.645868 -0.69833,0.698319 -4.18913,-2.365165 -4.18913,-3.67632 0,-0.526833 0.7797,-0.370613 1.73267,0.347155 0.95297,0.717767 -0.70223,-1.23225 -3.67822,-4.333371 -3.76003,-3.918124 -5.93501,-5.472057 -7.12873,-5.093182 -0.94481,0.299873 -3.07003,-0.15402 -4.7227,-1.00865 -2.43778,-1.26062 -3.37289,-1.324035 -4.95495,-0.33602 -2.36555,1.477307 -3.05981,0.886 -3.92467,-3.34268 -0.56625,-2.768728 -1.37248,-3.513567 -5.43639,-5.022464 -7.80616,-2.898363 -17.966683,-4.011606 -26.200113,-2.870631 -3.997279,0.553936 -7.475959,1.215337 -7.730402,1.469779 -0.254442,0.254443 0.998085,3.050852 2.783393,6.214244 2.874608,5.093525 3.291609,6.794112 3.644505,14.862796 l 0.398492,9.111176 3.564442,0.668693 c 7.773644,1.458345 16.010573,8.110583 19.620143,15.845464 3.09701,6.636514 3.26024,18.338664 0.34238,24.546143 -2.99996,6.38214 -7.1277,10.84757 -13.007325,14.07144 -4.530381,2.48406 -6.383854,2.90835 -12.728271,2.91366 -6.074888,0.005 -8.236255,-0.44332 -11.881188,-2.465 -2.450495,-1.35916 -4.455445,-2.98232 -4.455445,-3.60701 0,-0.62469 -0.40559,-1.50708 -0.901312,-1.96089 -0.523658,-0.47936 -0.602889,-0.3065 -0.189092,0.41255 0.391721,0.68069 0.309434,1.23762 -0.182859,1.23762 -1.220735,0 -4.304298,-3.49834 -3.655466,-4.14718 0.286625,-0.28662 -0.191905,-1.11291 -1.063399,-1.83618 -1.321234,-1.09653 -1.725666,-1.0867 -2.433844,0.0592 -0.46712,0.75582 -0.647589,1.7006 -0.401041,2.09952 0.480206,0.77699 -4.431607,4.73002 -8.49972,6.84057 -1.361386,0.7063 -6.473966,1.77939 -11.361289,2.38466 l -8.886042,1.10047 -0.8419,4.2572 c -1.116431,5.64542 -0.634772,6.55826 4.953601,9.38814 6.711939,3.39884 14.108367,5.45589 25.541571,7.10346 13.412147,1.93275 20.966236,1.82034 33.743152,-0.50211 17.901519,-3.25395 20.945769,-2.59407 18.234109,3.95245 -1.77158,4.27697 -8.27108,9.72932 -15.51118,13.01214 -10.066949,4.56456 -20.604188,6.60666 -38.045678,7.37316 -12.034826,0.52888 -15.515628,0.97079 -14.765554,1.87458 0.53979,0.65041 0.751763,1.41223 0.47105,1.69294 -0.280712,0.28071 0.280084,1.1308 1.246214,1.8891 1.597283,1.25367 1.633357,1.22157 0.397743,-0.35396 -1.901096,-2.42408 -0.973659,-2.18092 4.907357,1.28665 4.510039,2.65922 13.386837,5.60901 26.15447,8.69123 6.758464,1.63156 18.458956,1.2966 26.494168,-0.75846 l 0,-4e-5 z m 15.58504,-0.061 c 1.16161,-0.7507 0.90473,-0.96308 -1.17919,-0.97494 -1.46538,-0.008 -2.9397,0.43038 -3.27626,0.97494 -0.78135,1.26425 2.49915,1.26425 4.45545,0 z m 6.00568,-2.01503 c 1.95644,-1.04706 2.62207,-2.93547 1.0347,-2.93547 -0.48422,0 -1.93224,0.87627 -3.21783,1.94726 -2.49465,2.07826 -1.06383,2.72592 2.18313,0.98821 z m -6.00568,-1.45032 c 1.36139,-0.77824 2.0297,-1.41498 1.48515,-1.41498 -0.54456,0 -2.10396,0.63674 -3.46535,1.41498 -1.36138,0.77824 -2.0297,1.41498 -1.48515,1.41498 0.54456,0 2.10396,-0.63674 3.46535,-1.41498 z m -62.458746,0.13411 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553336,0.36093 1.577225,1.26362 4.799862,2.3676 3.441125,1.17883 l 0,0 z m 74.762706,-3.12566 c 1.04936,-0.7939 1.64445,-1.70691 1.32243,-2.02893 -0.78266,-0.78265 -4.7155,1.36919 -4.7155,2.58006 0,1.33049 1.15362,1.1431 3.39307,-0.55113 z m 5.3845,-4.97977 c 0.31295,-1.61495 0.14607,-1.68767 -1.23763,-0.53929 -1.89234,1.57049 -2.12795,3.40609 -0.36172,2.81801 0.68069,-0.22665 1.40039,-1.25207 1.59935,-2.27872 z m -93.926084,0.17176 c 0,-0.2056 -0.779703,-0.9853 -1.732673,-1.73268 -1.570353,-1.23155 -1.605372,-1.19653 -0.373817,0.37382 1.293435,1.64926 2.10649,2.17375 2.10649,1.35886 z m 42.048957,-9.0646 c 10.23476,-3.01561 12.830661,-4.22882 16.665417,-7.78864 1.52559,-1.41621 3.14513,-2.57492 3.599,-2.57492 0.45387,0 1.59099,-1.16873 2.52694,-2.59715 0.93594,-1.42844 1.24801,-2.31675 0.69349,-1.97403 -0.55454,0.34271 -1.20807,0.0635 -1.45231,-0.62067 -0.24423,-0.68409 -0.82632,-0.88541 -1.2935,-0.44739 -0.46721,0.43803 -0.19404,1.21091 0.60702,1.71751 1.25252,0.79212 1.23533,0.92323 -0.12275,0.93627 -0.86857,0.008 -2.42798,0.95441 -3.46535,2.10238 -5.028165,5.56424 -22.795527,11.3182 -38.212356,12.37508 -15.799597,1.08311 -17.048668,2.42489 -1.792578,1.92561 10.641937,-0.34827 15.176438,-0.97076 22.246977,-3.05405 l 0,0 z m 63.891637,-3.12611 c 0,-1.41552 -0.23243,-1.39342 -1.9802,0.18829 -1.08911,0.98563 -1.9802,2.18422 -1.9802,2.66353 0,0.47932 0.89109,0.39459 1.9802,-0.18828 1.08911,-0.58287 1.9802,-1.78147 1.9802,-2.66354 z M 97.166642,146.77097 c 3.547598,-0.77002 4.965228,-1.47727 4.298178,-2.14431 -0.66706,-0.66706 -4.175166,-0.42281 -10.636358,0.74056 -14.897153,2.68229 -37.124591,0.77195 -52.477337,-4.51017 -6.578027,-2.26317 -6.378989,-2.22908 -6.378989,-1.09252 0,1.42916 9.008565,4.85904 15.926311,6.06371 16.965213,2.95437 38.134158,3.35943 49.268195,0.94273 l 0,0 z m 53.617378,0.0462 c 0.58287,-1.08911 0.837,-1.9802 0.56472,-1.9802 -0.27228,0 -0.97195,0.89109 -1.55482,1.9802 -0.58287,1.08911 -0.837,1.9802 -0.56472,1.9802 0.27227,0 0.97195,-0.89109 1.55482,-1.9802 z m 5.94059,-4.62356 c 0,-2.3135 -1.69554,-0.59965 -2.85822,2.88907 l -1.073,3.21964 1.96562,-2.33741 c 1.08108,-1.28558 1.9656,-2.98266 1.9656,-3.7713 z m -77.497329,2.91089 c -2.054226,-0.21433 -5.173038,-0.21074 -6.930694,0.008 -1.757656,0.21872 -0.07693,0.39409 3.734955,0.38969 3.811881,-0.004 5.249963,-0.18335 3.195739,-0.39768 l 0,7e-5 z m 10.356241,-0.94387 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52002 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 19.616338,-1.30386 c 0,-0.54455 -0.47184,-0.99009 -1.04854,-0.99009 -0.57669,0 -0.77316,0.44554 -0.43661,0.99009 0.33655,0.54456 0.8084,0.9901 1.04853,0.9901 0.24014,0 0.43662,-0.44554 0.43662,-0.9901 z m 47.45458,-8.41584 c 0,-0.54455 -0.63674,0.12377 -1.41498,1.48515 -0.77823,1.36139 -1.41498,2.92079 -1.41498,3.46535 0,0.54455 0.63675,-0.12376 1.41498,-1.48515 0.77824,-1.36139 1.41498,-2.92079 1.41498,-3.46535 z M 28.453542,136.6394 c -0.717346,-1.86938 -3.412099,-3.08084 -3.412099,-1.53397 0,1.05715 3.177874,3.9134 3.73462,3.35666 0.149813,-0.14981 0.0047,-0.97003 -0.322521,-1.82269 z m 6.406383,0.90594 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553337,0.36093 1.577226,1.26362 4.799863,2.3676 3.441126,1.17883 z m -8.178941,-9.80642 c -0.27121,-0.67032 -0.476602,0.11785 -0.456423,1.75152 0.02018,1.63366 0.242077,2.18212 0.493111,1.21878 0.251032,-0.96334 0.234523,-2.29997 -0.03668,-2.9703 l -4e-6,0 z M 162.66521,127.0736 c 0,-0.51242 -0.44555,-1.20703 -0.9901,-1.54359 -0.54456,-0.33655 -0.9901,0.0827 -0.9901,0.93167 0,0.84897 0.44554,1.54358 0.9901,1.54358 0.54455,0 0.9901,-0.41925 0.9901,-0.93166 z M 27.619826,122.33281 c -0.329002,-0.329 -0.563011,0.25579 -0.52002,1.29951 0.0475,1.15341 0.28212,1.38802 0.598185,0.59819 0.286011,-0.71474 0.250836,-1.5687 -0.07817,-1.8977 l 3e-6,0 z m 136.035474,0.2269 c 0,-0.81683 -0.44554,-1.48514 -0.99009,-1.48514 -0.54456,0 -0.9901,0.66831 -0.9901,1.48514 0,0.81684 0.44554,1.48515 0.9901,1.48515 0.54455,0 0.99009,-0.66831 0.99009,-1.48515 z M 33.704809,119.40196 c -0.95297,-0.24903 -2.512376,-0.24903 -3.465346,0 -0.952971,0.24904 -0.173268,0.4528 1.732673,0.4528 1.905941,0 2.685644,-0.20376 1.732673,-0.4528 z m 51.237624,-0.30759 c 0.336553,-0.54456 -0.250915,-0.9901 -1.305483,-0.9901 -1.054569,0 -2.472053,-0.66832 -3.149963,-1.48515 -0.677909,-0.81683 -2.197663,-1.48515 -3.37723,-1.48515 -1.179567,0 -3.798279,-0.84306 -5.819362,-1.87346 -3.979476,-2.02885 -4.801958,-1.43381 -1.788124,1.29368 1.984228,1.7957 10.984716,4.90909 10.984716,3.79975 0,-0.35514 0.534654,-0.11106 1.188119,0.54241 1.44777,1.44777 2.457132,1.50894 3.267327,0.19802 z m 79.702967,-3.02873 c 0,-1.05697 -0.44554,-1.92177 -0.9901,-1.92177 -0.54455,0 -0.99009,1.14016 -0.99009,2.53369 0,1.43699 0.42855,2.26881 0.99009,1.92176 0.54456,-0.33656 0.9901,-1.47671 0.9901,-2.53368 z m -126.008939,1.3525 c -0.963334,-0.25103 -2.299968,-0.23452 -2.970297,0.0366 -0.670329,0.27122 0.117853,0.47661 1.751517,0.45643 1.633663,-0.0202 2.182114,-0.24208 1.21878,-0.49311 l 0,5e-5 z m 15.788583,-6.49209 c 2.961802,-2.58663 6.027485,-4.70297 6.812628,-4.70297 1.653245,0 1.836694,-1.82146 0.39887,-3.96039 -0.83888,-1.24794 -1.390264,-1.01072 -3.45205,1.48514 -1.349539,1.63367 -2.677116,3.63862 -2.950173,4.45545 -0.273055,0.81683 -3.168256,2.95063 -6.433779,4.74178 -3.265523,1.79115 -5.937315,3.64601 -5.937315,4.12192 0,1.77959 6.361283,-1.59914 11.561819,-6.14093 z m -20.47271,5.3104 c 0,-1.48733 -5.81027,-1.8801 -6.366582,-0.43038 -0.356538,0.92913 0.492992,1.3081 2.93231,1.3081 1.888849,0 3.434272,-0.39498 3.434272,-0.87772 z m 63.050779,-1.35 c 2.916955,-1.98579 4.205247,-3.71287 2.769577,-3.71287 -0.693665,0 -8.394613,5.11626 -8.394613,5.57711 0,1.01623 2.716191,0.11603 5.625036,-1.86424 z m -5.082551,-1.19364 c 7.593085,-3.17259 13.318898,-12.23833 13.318898,-21.087947 0,-14.183278 -14.801367,-26.126413 -27.276503,-22.009246 -4.871629,1.607782 -12.143736,8.333235 -14.435363,13.350236 -3.260107,7.137268 -1.947056,16.953627 3.009811,22.501317 l 2.75988,3.08884 0.514066,-6.40417 c 0.59176,-7.372086 2.817916,-12.370412 6.194803,-13.909026 9.324945,-4.24873 15.584088,10.950876 9.956609,24.178486 -0.930827,2.18794 1.172672,2.29087 5.957799,0.29151 l 0,0 z m -66.879119,-1.52913 c -2.805149,-2.19422 -4.307733,-2.52716 -3.741707,-0.82908 0.211038,0.6331 1.180081,1.268 2.15343,1.41085 0.973349,0.14286 2.025929,0.51595 2.339067,0.82908 0.313138,0.31314 0.829243,0.55943 1.1469,0.54732 0.317656,-0.0121 -0.536304,-0.89328 -1.89769,-1.95817 z m 12.639913,0.64485 c 0.689575,-0.42992 0.997439,-1.19644 0.684141,-1.70337 -0.313298,-0.50692 -0.139505,-0.92168 0.386206,-0.92168 0.525712,0 0.704595,-0.96077 0.397519,-2.13502 -0.337827,-1.29185 -0.167417,-1.89344 0.431502,-1.52328 0.604271,0.37346 1.005912,-1.20529 1.031127,-4.0531 0.03148,-3.556019 -0.171219,-4.194157 -0.852784,-2.684642 -0.678574,1.502882 -0.773791,1.192692 -0.395022,-1.286842 0.353363,-2.313228 0.165236,-3.060723 -0.644381,-2.560356 -0.737692,0.45592 -0.940577,0.178019 -0.571745,-0.783139 0.314436,-0.819406 0.23569,-2.033505 -0.174991,-2.698 -1.105326,-1.788456 -7.682811,-2.144736 -9.055691,-0.490515 -0.631379,0.760762 -0.759249,1.396753 -0.284156,1.413317 0.475095,0.01654 0.06457,0.495168 -0.912263,1.063584 -1.129264,0.657109 -1.565313,1.697515 -1.197349,2.856861 0.318297,1.002872 0.145073,2.091406 -0.384943,2.418971 -1.212393,0.749301 -1.114708,6.501761 0.11041,6.501761 0.49838,0 0.626441,0.88128 0.284578,1.95839 -1.132056,3.56679 7.260902,7.05039 11.147842,4.62706 l 0,0 z m 8.934184,-0.55418 c 2.020385,-1.03924 5.010061,-3.29502 6.643725,-5.01286 2.868463,-3.01627 2.981671,-3.49028 3.302077,-13.826072 l 0.33178,-10.702722 -3.762914,-0.705927 C 47.602481,80.969761 43.95345,78.863901 38.40778,73.51044 l -4.950496,-4.778915 -3.90401,1.921073 C 17.503668,76.58193 12.423679,90.628824 18.240927,101.93283 c 3.23262,6.2816 4.539882,6.43779 5.329032,0.6367 0.928828,-6.827865 1.319844,-7.895489 4.103161,-11.203281 7.697735,-9.148234 17.690208,3.484377 13.905573,17.579601 -1.6234,6.04608 -1.03574,6.43209 5.036847,3.3085 l 0,0 z m 37.877227,-0.17548 c 0.607833,-1.13574 0.846281,-2.32386 0.529884,-2.64025 -0.316397,-0.3164 -0.575268,-0.0873 -0.575268,0.50911 0,0.59643 -0.700141,1.78455 -1.55587,2.64027 -0.855728,0.85573 -1.094176,1.55587 -0.529884,1.55587 0.564291,0 1.523303,-0.92924 2.131138,-2.065 l 0,0 z m -8.956275,-0.41024 c -0.777242,-0.93653 -0.843612,-1.48515 -0.179665,-1.48515 0.579095,0 1.32826,0.44554 1.664814,0.9901 0.336553,0.54455 1.710509,0.9901 3.053236,0.9901 3.405659,0 4.705098,-3.86234 3.99729,-11.88119 -0.410484,-4.650429 -0.278996,-6.023676 0.474005,-4.950498 0.92628,1.320129 0.997019,1.320129 0.636655,0 -0.222976,-0.816832 -0.888084,-1.485149 -1.478018,-1.485149 -0.589933,0 -1.406765,-0.334158 -1.815181,-0.742574 -0.408416,-0.408416 -1.808473,-0.742574 -3.111239,-0.742574 -1.326986,0 -2.099559,-0.435416 -1.756748,-0.990099 1.082137,-1.750934 -0.356281,-1.056251 -2.436678,1.176792 -1.948858,2.091852 -2.796679,4.371505 -1.276193,3.431475 0.408415,-0.252495 0.742574,2.796683 0.742574,6.775957 0,4.5426 -0.368457,7.02333 -0.990099,6.66611 -0.544555,-0.31292 -0.141343,0.39874 0.896028,1.58146 2.106995,2.4022 3.511949,2.99403 1.579219,0.66524 l 0,0 z m 74.981158,-0.19108 c -0.96334,-0.25103 -2.29997,-0.23453 -2.9703,0.0366 -0.67032,0.27122 0.11786,0.4766 1.75152,0.45643 1.63366,-0.0202 2.18212,-0.24208 1.21878,-0.49311 l 0,5e-5 z m -84.882148,-2.77922 c -0.67791,-0.81683 -1.678108,-1.48515 -2.222662,-1.48515 -0.552304,0 -0.445093,0.65669 0.242464,1.48515 0.67791,0.81683 1.678108,1.48515 2.222663,1.48515 0.552304,0 0.445093,-0.6567 -0.242465,-1.48515 z m 38.428218,-0.43317 c 0.24752,-0.74257 -0.12376,-1.11386 -0.86634,-0.86634 -0.71472,0.23824 -1.49443,1.01795 -1.73267,1.73268 -0.24752,0.74257 0.12376,1.11386 0.86634,0.86633 0.71472,-0.23823 1.49443,-1.01795 1.73267,-1.73267 z m 61.57178,-0.16781 c 0,-1.1313 -2.6849,-1.15685 -3.38,-0.0322 -0.2896,0.4686 -0.27234,1.10622 0.0384,1.41693 0.7726,0.77266 3.34158,-0.29192 3.34158,-1.38475 z m -145.544552,0.16436 c 0,-1.16817 -1.931044,-2.41782 -2.640265,-1.7086 -0.709219,0.70923 0.54042,2.64027 1.708598,2.64027 0.512417,0 0.931667,-0.41925 0.931667,-0.93167 z m 65.94472,-2.76058 c -0.329002,-0.329 -0.563011,0.25578 -0.52002,1.29951 0.04751,1.15341 0.28212,1.38802 0.598185,0.59818 0.286011,-0.71472 0.250836,-1.56868 -0.07817,-1.89769 l 3e-6,0 z m 20.193892,-0.7632 c 0,-0.81683 -0.44554,-1.48515 -0.9901,-1.48515 -0.54455,0 -0.9901,0.66832 -0.9901,1.48515 0,0.81683 0.44555,1.48515 0.9901,1.48515 0.54456,0 0.9901,-0.66832 0.9901,-1.48515 z m 60.18796,-0.40346 c 2.02039,-1.03875 5.45561,-3.52622 7.63382,-5.527735 l 3.9604,-3.639109 -4.45545,3.425762 c -2.45049,1.884172 -6.23762,4.351962 -8.41584,5.483972 -2.17822,1.13201 -3.60848,2.0779 -3.17837,2.10196 0.43011,0.0241 2.43506,-0.80612 4.45544,-1.84485 z m -94.1857,-5.289607 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237627 0,1.36138 0.224726,1.91831 0.499392,1.23762 0.274665,-0.68069 0.274665,-1.794554 0,-2.475247 z m 13.861386,-0.990099 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237624 0,1.361382 0.224726,1.918312 0.499392,1.237622 0.274666,-0.680691 0.274666,-1.794553 0,-2.475246 z m -25.408199,0.742575 c 0,-0.816832 -0.445544,-1.485149 -0.990099,-1.485149 -0.544554,0 -0.990099,0.668317 -0.990099,1.485149 0,0.816831 0.445545,1.485151 0.990099,1.485151 0.544555,0 0.990099,-0.66832 0.990099,-1.485151 z m 47.524753,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921683 -0.55343,0.342039 -0.74992,1.036653 -0.43661,1.543584 0.84874,1.37331 1.44286,1.11724 1.44286,-0.621901 l 0,0 z M 13.75844,96.59024 c -0.329002,-0.329 -0.563011,0.255782 -0.520019,1.299504 0.04751,1.153416 0.282119,1.38802 0.598184,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897693 l 0,0 z m 45.936468,-3.733496 c 0,-0.816831 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668317 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m 49.504952,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921684 -0.55343,0.34204 -0.74992,1.036654 -0.43661,1.543585 0.84874,1.373307 1.44286,1.117237 1.44286,-0.621901 l 0,0 z M 12.768341,90.649645 c -0.329002,-0.328998 -0.563011,0.255783 -0.52002,1.299505 0.04751,1.153416 0.28212,1.38802 0.598185,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897694 l 0,0 z m 70.193894,0.721951 c -0.336554,-0.544555 -1.142551,-0.983277 -1.791106,-0.974941 -0.708531,0.0089 -0.586411,0.398248 0.305957,0.974941 1.902102,1.229238 2.244857,1.229238 1.485149,0 z m 25.247525,-4.513878 c 0,-0.84897 -0.45281,-1.263728 -1.00625,-0.921685 -0.55343,0.342043 -0.74992,1.036654 -0.43661,1.543581 0.84874,1.373311 1.44286,1.117238 1.44286,-0.621896 z M 13.75844,84.709054 c -0.329002,-0.329001 -0.563011,0.255777 -0.520019,1.299505 0.04751,1.153409 0.282119,1.38802 0.598184,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 0,0 z m 48.906765,-3.85473 c 0,-1.356215 -3.082898,-1.911382 -4.232156,-0.762123 -0.330986,0.330986 -0.08945,1.422196 0.536762,2.424911 0.842923,1.349734 1.470503,1.547624 2.416974,0.762123 0.703131,-0.583548 1.27842,-1.674757 1.27842,-2.424911 z m 43.564355,0.09971 c 0,-2.007107 -9.940776,-11.875249 -12.685773,-12.593082 -3.422347,-0.894964 -2.536662,0.72179 2.04221,3.727903 4.685203,3.075921 8.056173,6.371341 8.979963,8.778691 0.77225,2.012434 1.6636,2.058775 1.6636,0.08649 z m -47.693353,-7.404219 2.306645,-4.455446 -0.675699,4.455446 -0.6757,4.455445 3.814599,-3.586129 c 2.098029,-1.972372 6.311347,-5.155371 9.362929,-7.073331 5.874539,-3.692229 6.839458,-5.599101 6.818235,-13.474203 -0.0116,-4.303265 -3.763041,-12.649115 -7.037511,-15.656368 -5.956689,-5.47059 -15.534138,-7.597002 -22.017021,-4.888282 -12.757989,5.330628 -18.072962,19.793085 -11.85765,32.265591 2.52515,5.067315 2.685106,5.196865 3.601855,2.917172 0.958373,-2.383197 0.960066,-2.382511 1.654947,0.671085 0.942906,4.14352 1.700115,5.200511 5.327538,7.436733 4.523217,2.788458 6.716499,2.070908 9.376833,-3.067713 l 0,0 z m 8.682689,1.5849 c 1.905993,-1.851076 4.77995,-3.91008 6.386569,-4.575565 2.564998,-1.062456 4.03369,-2.949929 2.295417,-2.949929 -2.10037,0 -13.235677,8.775011 -13.235677,10.430176 0,1.083649 1.30255,0.252787 4.553691,-2.904682 z M 20.090948,74.8078 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z M 152.76422,69.68259 c 0,-0.272277 -1.78218,1.245201 -3.9604,3.372174 -2.17822,2.126974 -3.9604,4.089996 -3.9604,4.362274 0,0.272277 1.78218,-1.245201 3.9604,-3.372175 2.17822,-2.126973 3.9604,-4.089996 3.9604,-4.362273 z M 41.625601,72.476287 c -2.586633,-2.217071 -4.709793,-4.553304 -4.718131,-5.191628 -0.02877,-2.202305 -1.632163,-3.701423 -3.281819,-3.068391 -2.032483,0.779938 -2.195989,3.392952 -0.212309,3.392952 0.792663,0 3.354544,2.00317 5.693069,4.45149 2.338525,2.44832 4.92018,4.450394 5.737012,4.449053 0.816832,-0.0014 -0.631188,-1.816405 -3.217822,-4.033476 l 0,0 z M 24.051344,70.847404 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z m 6.526162,-3.972749 c -0.745512,-0.745512 -5.536063,1.770447 -5.536063,2.907495 0,0.46652 1.378038,0.135607 3.062307,-0.735362 1.684269,-0.870969 2.797459,-1.848429 2.473756,-2.172133 z m 53.127303,0.748085 c 0.952971,-0.0074 1.732673,-0.459065 1.732673,-1.003619 0,-0.544555 -0.940674,-0.990099 -2.090387,-0.990099 -1.852777,0 -2.016491,-0.393899 -1.440284,-3.465347 0.406143,-2.164925 0.261718,-3.465346 -0.38486,-3.465346 -0.56923,0 -1.034964,1.059307 -1.034964,2.354014 0,1.294709 -0.668316,2.90867 -1.485148,3.58658 -2.367441,1.964801 -1.885292,4.298583 0.742574,3.594342 1.225248,-0.328353 3.007426,-0.60309 3.960396,-0.610525 z m 71.134371,-0.722043 c 1.58154,-0.934242 2.87553,-2.079091 2.87553,-2.544109 0,-1.671282 -4.25968,-0.165537 -5.70037,2.015008 -1.76311,2.668563 -1.02958,2.805958 2.82484,0.529101 z m 47.13694,-2.884855 c -0.37294,-0.372946 -1.68483,-0.148769 -2.91529,0.498172 -1.23047,0.64694 -1.45751,0.953686 -0.50454,0.681656 1.92704,-0.550082 2.24796,0.402733 0.74808,2.221031 -0.54153,0.65649 -0.009,0.312431 1.18262,-0.764577 1.19197,-1.077007 1.86208,-2.263334 1.48913,-2.636282 z m -52.1822,2.108229 c 0.67791,-0.816831 1.00979,-1.485148 0.73751,-1.485148 -0.27227,0 -1.0497,0.668317 -1.72761,1.485148 -0.67791,0.816832 -1.00979,1.485149 -0.73752,1.485149 0.27228,0 1.04971,-0.668317 1.72762,-1.485149 z m 37.15543,-0.451808 c -0.32185,-0.520771 -1.23923,-0.695875 -2.03863,-0.38912 -2.04664,0.785373 -1.80547,1.335978 0.5852,1.335978 1.12125,0 1.7753,-0.426086 1.45343,-0.946858 z m -20.13811,-0.719592 c -0.71473,-0.286011 -1.56869,-0.250835 -1.89769,0.07817 -0.329,0.329001 0.25578,0.56301 1.29951,0.520019 1.15341,-0.04751 1.38802,-0.282119 0.59818,-0.598185 l 0,-3e-6 z M 84.05547,61.936777 c -0.329002,-0.329001 -0.563011,0.255776 -0.52002,1.299505 0.04751,1.153409 0.28212,1.38802 0.598185,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 3e-6,0 z m 82.57013,0.721948 c 0,-0.544555 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445544 -1.48515,0.990099 0,0.544554 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445545 1.48515,-0.990099 z m 37.62376,-5.177658 c 0,-1.661518 -0.24856,-1.789209 -1.48514,-0.762936 -0.81684,0.67791 -1.48515,1.832342 -1.48515,2.565406 0,0.777973 0.61827,1.095588 1.48515,0.762936 0.81683,-0.313447 1.48514,-1.46788 1.48514,-2.565406 z M 83.457284,54.18445 c 0,-0.784694 -0.445544,-1.426715 -0.990099,-1.426715 -0.544554,0 -0.990099,0.917384 -0.990099,2.03863 0,1.121247 0.445545,1.76327 0.990099,1.426716 0.544555,-0.336553 0.990099,-1.253937 0.990099,-2.038631 z m 63.366336,-0.931666 c -1.27896,-1.361386 -2.77092,-2.475247 -3.31547,-2.475247 -0.54456,0 0.0563,1.113861 1.33527,2.475247 1.27896,1.361386 2.77092,2.475248 3.31548,2.475248 0.54455,0 -0.0563,-1.113862 -1.33528,-2.475248 z M 82.467185,48.302289 c 0,-0.816832 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668316 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m -1.985115,-5.19802 c -0.0084,-1.2671 -4.736103,-6.714785 -5.323399,-6.134089 -0.649329,0.642032 3.49033,6.834315 4.585742,6.859554 0.408416,0.0094 0.740362,-0.317049 0.737657,-0.725465 l 0,0 z m 50.49997,-0.247525 c -0.81683,-0.527877 -1.9307,-0.959776 -2.47525,-0.959776 -0.54456,0 -0.32178,0.431899 0.49505,0.959776 0.81683,0.527878 1.93069,0.959777 2.47525,0.959777 0.54455,0 0.32178,-0.431899 -0.49505,-0.959777 z m 4.44995,-0.996169 c -0.98866,-1.092447 -2.01229,-1.771531 -2.27475,-1.509075 -0.66527,0.66528 1.80418,3.495343 3.04998,3.495343 0.56227,0 0.21342,-0.89382 -0.77523,-1.986268 l 0,0 z m -95.539062,-4.19679 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.677909 1.485148,-1.678107 1.485148,-2.222662 z m 92.079212,0.795947 c 0,-2.367417 -1.80911,-2.723191 -2.95546,-0.581213 -0.91594,1.711444 -0.77708,2.007928 0.94043,2.007928 1.10826,0 2.01503,-0.642021 2.01503,-1.426715 z M 43.853324,33.703389 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.67791 1.485148,-1.678108 1.485148,-2.222662 z m 29.450539,-0.0051 c -0.341635,-3.033194 -0.613818,-3.235945 -4.743791,-3.533678 -2.40975,-0.173719 -4.148989,-0.08348 -3.864976,0.200533 0.746043,0.746042 8.309556,6.402673 8.668673,6.483162 0.166387,0.03729 0.139429,-1.380215 -0.05991,-3.150017 z m 45.796987,1.732673 c -0.67791,-0.816832 -1.70871,-1.485149 -2.29066,-1.485149 -0.58196,0 -0.19325,0.654147 0.8638,1.453661 2.48363,1.878524 2.96864,1.889227 1.42686,0.03148 l 0,3e-6 z m 5.94059,-0.933056 c 0,-0.721181 -1.00247,-1.579892 -2.22772,-1.908245 -3.82044,-1.023837 -4.13152,-0.702262 -1.76134,1.820687 2.31705,2.466393 3.98906,2.503093 3.98906,0.08755 l 0,4e-6 z m 8.8851,-5.657864 c 5.0656,-7.213134 5.95021,-9.230659 3.73867,-8.526659 -1.72171,0.548068 -10.64357,12.438161 -10.64357,14.184592 0,2.924919 2.06665,1.231484 6.9049,-5.657933 z m -54.828018,2.397173 c -0.586902,-0.586901 -3.56203,0.943932 -3.56203,1.832819 0,0.490907 0.870827,0.348719 1.935171,-0.315974 1.064342,-0.664694 1.796429,-1.347273 1.626859,-1.516845 z m -29.622424,0.529501 c 3.007757,-1.087619 4.641314,-3.761497 2.298018,-3.761497 -0.544554,0 -0.990099,0.445545 -0.990099,0.990099 0,0.544555 -0.58316,0.990099 -1.295911,0.990099 -1.477794,0 -5.628481,2.890588 -4.219928,2.938809 0.505892,0.01732 2.399456,-0.503561 4.20792,-1.15751 l 0,0 z m 54.958912,-1.46755 c -0.71473,-0.286011 -1.56869,-0.250836 -1.89769,0.07817 -0.329,0.329002 0.25577,0.563011 1.2995,0.52002 1.15341,-0.0475 1.38802,-0.28212 0.59819,-0.598185 l 0,-3e-6 z M 59.694908,28.005259 c 0,-1.089109 -0.39099,-1.980198 -0.868866,-1.980198 -1.298365,0 -3.17241,2.559384 -2.422873,3.30892 1.355486,1.355487 3.291739,0.573912 3.291739,-1.328722 z m 21.287129,0.990099 c 0.336553,-0.544554 -0.331763,-0.990099 -1.485149,-0.990099 -1.153385,0 -1.821702,0.445545 -1.485148,0.990099 0.336553,0.544555 1.00487,0.990099 1.485148,0.990099 0.480279,0 1.148595,-0.445544 1.485149,-0.990099 z m 29.207923,0 c 0,-0.544554 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445545 -1.48515,0.990099 0,0.544555 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445544 1.48515,-0.990099 z M 86.427581,28.005259 c 0,-0.544554 -0.694611,-0.990099 -1.543581,-0.990099 -0.848969,0 -1.268219,0.445545 -0.931666,0.990099 0.336553,0.544555 1.031164,0.990099 1.543581,0.990099 0.512417,0 0.931666,-0.445544 0.931666,-0.990099 z m 18.316829,0 c 0.33656,-0.544554 -0.33176,-0.990099 -1.48515,-0.990099 -1.15338,0 -1.8217,0.445545 -1.48514,0.990099 0.33655,0.544555 1.00487,0.990099 1.48514,0.990099 0.48028,0 1.1486,-0.445544 1.48515,-0.990099 z M 53.397761,23.263982 c -2.293369,-2.293369 -3.273717,-0.599352 -1.065339,1.840877 1.180946,1.304931 2.008695,1.63504 2.254066,0.898928 0.213274,-0.63982 -0.321654,-1.872732 -1.188727,-2.739805 l 0,0 z m 41.674343,3.065049 c -0.963333,-0.251033 -2.299967,-0.234524 -2.970297,0.03668 -0.670328,0.271211 0.117854,0.476602 1.751517,0.456424 1.633663,-0.02018 2.182115,-0.242078 1.21878,-0.493111 l 0,4e-6 z M 50.784017,20.160629 c 0,-1.18906 -5.817795,-7.006855 -7.006854,-7.006855 -1.723094,0 -0.911591,1.747528 2.244318,4.833013 3.196159,3.124838 4.762536,3.839805 4.762536,2.173842 z m 99.083553,-7.807387 c -1.32905,-0.443014 -5.95468,4.804941 -5.94174,6.741126 0.006,0.860676 1.47299,-0.172344 3.48946,-2.456779 1.91375,-2.168059 3.01727,-4.096016 2.45228,-4.284347 z m -7.4939,4.754858 c 2.64699,-2.924889 1.22992,-3.38489 -1.49431,-0.485075 -1.27694,1.359238 -1.86755,2.471343 -1.31247,2.471343 0.55508,0 1.81813,-0.893821 2.80678,-1.986268 z m 1.9747,-5.934524 c 2.68184,-2.7227721 4.44726,-4.9364147 3.92318,-4.9192068 -1.79455,0.058926 -11.48794,9.8697018 -9.75161,9.8697018 0.52381,0 3.1466,-2.227723 5.82843,-4.950495 z m 4.99121,-1.055971 c 1.06562,-1.7242011 -0.14804,-2.0893477 -1.506,-0.4531041 -0.78094,0.9409741 -0.85606,1.5090751 -0.19952,1.5090751 0.57909,0 1.34657,-0.475187 1.70552,-1.055971 z m 22.08877,-7.9517764 c 1.71492,-0.5978257 3.11804,-1.51893899 3.11804,-2.04691859 0,-1.07371396 -3.1521,-0.28577416 -6.93069,1.73248789 -3.09382,1.652504 -0.61271,1.8571218 3.81265,0.3144307 l 0,0 z m 6.85154,-0.707599 c 0.59402,-1.78204068 -1.45248,-1.40757811 -2.14309,0.3921386 -0.37003,0.9642713 -0.14875,1.4169139 0.57476,1.1757426 0.64703,-0.2156762 1.35277,-0.9212228 1.56833,-1.5678812 z M 20.090948,0.80296239 c 0,-0.25829297 -1.366838,-1.17644278 -3.037417,-2.04033289 C 13.07504,-3.294728 10.77735,-2.5105441 14.645403,-0.41549494 17.561715,1.1640635 20.090948,1.729987 20.090948,0.80296239 z M 177.51669,-2.5818805 c 0,-1.2146632 -2.78939,-2.1897491 -3.40672,-1.1908861 -0.27491,0.444817 -0.21492,1.0936751 0.1333,1.4419069 0.94359,0.9435791 3.27342,0.7649164 3.27342,-0.2510208 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3784"
+ transform="translate(0,784.36218)"
+ d="m 30.061595,110.24748 c -3.028002,-1.91623 -2.918962,-12.207625 0.161986,-15.288574 2.892806,-2.892806 5.380122,-2.029008 6.063557,2.105759 0.787072,4.761775 0.802973,10.540215 0.03451,12.542785 -0.657319,1.71294 -4.021187,2.05687 -6.260057,0.64003 l -1e-6,0 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3786"
+ transform="translate(0,784.36218)"
+ d="m 50.118347,74.592462 c -5.270942,-3.20545 -6.839578,-11.64359 -3.245566,-17.458823 3.039395,-4.917846 5.720122,-5.336139 9.002245,-1.404685 3.776278,4.523372 4.477791,9.679447 1.982432,14.570755 -2.972944,5.82745 -4.145768,6.477996 -7.739111,4.292753 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3790"
+ transform="translate(0,784.36218)"
+ d="m 77.269166,109.11407 c -1.309679,-0.76282 -1.732674,-2.30682 -1.732674,-6.32456 0,-2.923449 0.270441,-6.020121 0.600979,-6.881491 0.834308,-2.174169 4.068292,-1.961418 5.30478,0.348981 2.014054,3.7633 0.737507,14.00145 -1.732673,13.89637 -0.389257,-0.0166 -1.487442,-0.48424 -2.440412,-1.0393 z" />
+ </g>
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3811"
+ d="m 67.743593,226.38939 c 0.19068,-0.58412 0.338063,-2.39704 0.327517,-4.02871 -0.03055,-4.72761 -2.165352,-7.80395 -5.35278,-7.71359 -2.829967,0.0802 -4.224757,1.85117 -5.323452,6.75914 -0.310039,1.38498 -0.36786,1.41644 -1.004042,0.54642 -0.371282,-0.50776 -0.820797,-1.89506 -0.998923,-3.08289 -0.555915,-3.70711 1.471544,-7.48719 5.471792,-10.20182 5.598625,-3.79933 13.971038,1.83612 13.913701,9.36528 -0.02361,3.09812 -3.736904,8.46539 -6.324961,9.14218 -0.904613,0.23656 -1.005971,0.12417 -0.708852,-0.78601 l 0,0 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3813"
+ d="m 67.404395,224.07647 c 0.218171,-3.86109 -0.81619,-7.47461 -2.379003,-8.31101 -1.450495,-0.77628 -3.833689,-0.56086 -4.831244,0.43669 -0.506638,0.50664 -1.305601,2.10548 -1.775472,3.55298 -1.095843,3.3759 -1.456791,3.72914 -2.367189,2.31667 -2.172529,-3.37066 -1.181735,-8.3045 2.356216,-11.73323 3.808208,-3.69063 6.356321,-4.18204 10.583313,-2.04103 3.18311,1.61228 5.556904,4.81655 6.061632,8.18231 0.273553,1.8242 0.112352,2.73702 -0.850171,4.81416 -1.44283,3.11366 -4.397332,6.23865 -5.898296,6.23865 -1.048338,0 -1.086743,-0.14752 -0.899786,-3.45619 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3815"
+ d="m 54.581383,204.17598 c -0.330031,-3.53422 -1.331573,-5.66019 -3.388938,-7.19369 -2.496196,-1.86061 -5.288569,0.24236 -6.511588,4.90394 l -0.621341,2.36827 -0.78337,-1.82202 c -2.593339,-6.03175 2.241276,-13.61508 8.680039,-13.61508 3.86832,0 6.851837,1.90897 8.669978,5.54739 1.621302,3.24451 1.874093,5.90823 0.71742,7.55961 -0.413522,0.59039 -2.036622,2.06204 -3.606889,3.27033 l -2.85503,2.19689 -0.300281,-3.21564 0,0 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3817"
+ d="m 45.188143,222.67169 c 0,-3.90068 -0.118172,-4.43649 -1.328412,-6.0232 -1.647394,-2.15984 -3.308854,-2.63488 -5.529681,-1.58103 -1.755441,0.83301 -3.67834,3.97169 -3.67834,6.00402 0,1.57105 -0.802789,1.30413 -1.422259,-0.47288 -1.642012,-4.71028 0.827943,-10.53973 5.502814,-12.98743 1.350256,-0.70698 1.444094,-0.67017 3.720976,1.45958 2.598182,2.4303 4.372384,3.46667 6.848292,4.00031 l 1.663058,0.35844 -0.308027,4.68928 c -0.331934,5.05322 -0.878313,6.12303 -4.098751,8.0254 l -1.36967,0.80908 0,-4.28157 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3819"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3821"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3823"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3825"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3827"
+ d="" />
+ <path
+ style="fill:#808000;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3839"
+ d="m 96.387857,217.56995 c 1.213522,-1.18081 3.045232,-2.70588 3.588513,-2.98777 0.26729,-0.13869 0.34041,-0.13033 0.53775,0.0614 0.22145,0.21519 0.21721,0.22773 -0.139,0.41194 -0.20207,0.1045 -1.168241,0.8213 -2.147044,1.5929 -3.062313,2.41407 -3.70477,2.73578 -1.840219,0.92149 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3841"
+ d="m 95.259154,218.6245 c 0.169011,-0.31579 2.350639,-2.35144 3.60354,-3.3624 1.092972,-0.88192 1.409816,-1.00296 1.745806,-0.66698 0.23537,0.23537 0.20535,0.26324 -2.361536,2.1931 -2.586669,1.94472 -3.270902,2.36525 -2.98781,1.83628 z m 3.223063,-2.29188 c 2.186823,-1.64445 2.077413,-1.54607 1.826463,-1.64237 -0.12626,-0.0485 -0.405397,0.0686 -0.732209,0.30704 -0.77399,0.56467 -3.173136,2.65442 -3.181471,2.77119 -0.0098,0.13752 0.04568,0.0993 2.087217,-1.43586 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3843"
+ d="m 95.089499,218.84542 c -0.104424,-0.16895 0.84778,-1.16015 2.535143,-2.63894 1.847565,-1.6192 1.734083,-1.53116 2.253052,-1.748 0.416136,-0.17387 0.470236,-0.17054 0.736846,0.0453 l 0.28774,0.233 -0.24641,0.27229 c -0.26032,0.28767 -3.496794,2.74402 -4.622191,3.50806 -0.706972,0.47998 -0.825042,0.52102 -0.94418,0.32824 z m 4.655172,-3.67215 c 0.153994,-0.18668 0.143867,-0.19204 -0.108591,-0.0575 -0.287942,0.15343 -0.358846,0.26338 -0.169828,0.26338 0.05972,0 0.185009,-0.0926 0.278419,-0.20587 l 0,0 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3845"
+ d="" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3847"
+ d="m 96.329421,220.21405 c 0.134226,-0.13117 0.940097,-0.6115 1.790822,-1.06738 0.850725,-0.45589 1.976417,-1.13063 2.501547,-1.49943 0.96712,-0.67921 2.0769,-1.69802 2.0769,-1.90664 0,-0.0627 0.13921,-0.11397 0.30936,-0.11397 1.35091,0 -2.15595,2.85903 -5.339138,4.35282 -0.554492,0.26021 -1.137628,0.47311 -1.295854,0.47311 -0.285987,0 -0.286245,-0.001 -0.04366,-0.23851 z" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.25936007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="rect3011"
+ transform="matrix(0.99992004,0.01264577,-0.00621432,0.99998069,0,0)"
+ y="35.635006"
+ x="1.1525297"
+ ry="15"
+ rx="15.083"
+ height="127.1652"
+ width="147.36519" />
+ <!-- <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="10.666666"
+ y="54.666672"
+ id="text2895"><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="54.666672"
+ id="tspan2899">Please help me</tspan><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="74.666672"
+ id="tspan2903">find the pieces </tspan><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="94.666672"
+ id="tspan2905">of my spaceship</tspan></text>-->
+<foreignObject x="-1"
+ y="40" height="136.85336"
+ width="158">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <div id='alienQuestion' style="font-size:20px">Please help me find the pieces
+ of my spaceship</div>
+ </body>
+ </foreignObject>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien5.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien5.svg
new file mode 100755
index 0000000..b86eaa8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/alien5.svg
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="151.21715"
+ height="264.79129"
+ id="svg2"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="alien4.svg">
+ <metadata
+ id="metadata47">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ id="namedview45"
+ showgrid="false"
+ inkscape:zoom="1.5"
+ inkscape:cx="108.02621"
+ inkscape:cy="191.94948"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 103.30726 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="100 : 103.30726 : 1"
+ inkscape:persp3d-origin="50 : 68.871506 : 1"
+ id="perspective49" />
+ </defs>
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2909"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2915"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2917"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3707"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3711"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3715"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.68738866;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3776"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3778"
+ d="" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3788"
+ d="" />
+ <g
+ id="g3794"
+ transform="matrix(0.49496731,0,0,0.49496731,25.08401,-250.77117)">
+ <path
+ style="fill:#000000"
+ id="path2905"
+ d="m 53.60865,1035.3693 c 19.78288,-22.2017 22.20694,-25.4265 25.4678,-33.881 3.44722,-8.9377 6.40012,-18.24962 7.52938,-23.74392 0.82455,-4.01172 -0.36261,-5.08744 -5.63913,-5.10977 -1.99045,-0.008 -7.61545,-0.71148 -12.5,-1.56235 -16.50806,-2.87565 -23.91813,-6.30919 -33.99171,-15.75046 -6.08941,-5.70718 -7.43503,-7.50597 -7.19032,-9.61182 0.34346,-2.95569 -1.50714,-2.82651 22.80104,-1.59153 11.8285,0.60095 15.97106,0.42806 22.48438,-0.93836 4.39141,-0.92127 8.66641,-2.28625 9.5,-3.0333 0.83359,-0.74704 3.31562,-1.68728 5.51562,-2.08942 2.2,-0.40213 5.575,-1.60777 7.5,-2.6792 3.44034,-1.91485 3.44887,-1.93539 0.5,-1.2054 -5.17273,1.28051 -26.63042,1.59889 -36.0133,0.53435 -9.20812,-1.04471 -19.63226,-3.39275 -22.72313,-5.11837 -0.95503,-0.5332 -2.32888,-0.96945 -3.05299,-0.96945 -1.43857,0 -9.42912,-5.54027 -11.50725,-7.97859 -0.95343,-1.11868 -1.14843,-3.94422 -0.73666,-10.67412 l 0.56002,-9.15271 -4.54056,-5.31941 c -9.98832,-11.70162 -9.97623,-27.55255 0.0295,-38.68134 2.60206,-2.89412 6.36378,-5.77306 8.93031,-6.83458 l 4.43446,-1.83411 -0.57302,-6.13624 c -1.06496,-11.40449 5.13162,-23.48816 14.51299,-28.30109 l 3.58712,-1.84031 -5.95375,-5.92765 c -4.93512,-4.9135 -8.52008,-7.18312 -20.95375,-13.26571 -8.25,-4.03593 -15.17459,-7.48627 -15.38799,-7.66742 -0.21339,-0.18115 0.18259,-2.36727 0.87997,-4.85804 1.70691,-6.09651 3.20226,-5.96925 18.29995,1.55747 19.96216,9.95182 24.45018,13.11377 31.13538,21.93586 4.86767,6.42359 6.566,7.95536 9.5,8.56828 1.96498,0.41049 4.02269,0.60686 4.57269,0.43639 17.13317,-5.31045 33.409,-5.14223 47.77024,0.49372 4.94708,1.94144 5.21645,1.90161 6.52227,-0.96436 0.61245,-1.34418 5.43513,-7.16668 10.71706,-12.93889 7.18218,-7.84883 10.66081,-10.87865 13.79697,-12.01685 2.3064,-0.83706 9.11158,-3.33956 15.12261,-5.56111 6.01103,-2.22156 11.68966,-4.03919 12.61916,-4.03919 1.11859,0 1.89014,1.09888 2.28193,3.25 0.32555,1.7875 0.8733,4.21044 1.21722,5.38431 0.70713,2.41364 -0.93804,3.18343 -16.9864,7.94807 -8.24402,2.44759 -9.41386,3.13117 -15.04786,8.79297 -3.35991,3.37649 -7.99751,8.92014 -10.30579,12.31923 l -4.19687,6.18016 4.59822,3.7679 c 3.92224,3.21397 12.53592,13.3479 15.89124,18.69593 0.86818,1.38377 2.03676,1.46094 8.86473,0.5854 6.40489,-0.8213 8.72511,-0.72392 12.5,0.5246 8.01058,2.64945 13.40229,2.97743 17.21675,1.04728 5.01589,-2.53808 7.91852,-5.53295 7.91852,-8.17016 0,-1.91743 0.52663,-2.32569 3,-2.32569 l 3,0 0,7.36937 c 0,6.99889 -0.19005,7.61474 -3.78039,12.25 -2.07921,2.68435 -4.3555,6.00563 -5.05843,7.38063 -1.82398,3.56792 -4.05346,6.02517 -8.95417,9.86899 -2.36114,1.85194 -5.40785,5.56725 -6.77047,8.25624 -1.86654,3.68345 -4.04585,5.93033 -8.8376,9.11161 l -6.36013,4.22255 -1.16111,8.29999 c -3.24143,23.17077 -14.49635,42.93763 -31.7551,55.771 -4.30243,3.19923 -8.0341,5.98766 -8.29259,6.19652 -1.61876,1.30794 6.41126,11.58405 19.25766,24.64423 26.293,26.73057 27.51833,28.27367 30.82393,38.81727 3.56149,11.3598 3.62201,12.8116 0.53407,12.8116 -2.0739,0 -2.62572,-0.9231 -4.63288,-7.75 -1.25321,-4.2625 -3.12892,-9.4395 -4.16826,-11.5044 -1.03933,-2.065 -8.08103,-9.94 -15.6482,-17.5 -17.43517,-17.4188 -29.05724,-30.54815 -30.36702,-34.30539 -0.88138,-2.52833 -1.38534,-2.84102 -3.67537,-2.28044 -1.45967,0.3573 -2.80394,1.03003 -2.98727,1.49494 -0.18334,0.46491 -1.18057,0.84529 -2.21608,0.84529 -1.0355,0 -3.3605,0.6395 -5.16666,1.42112 -1.80616,0.78162 -5.98393,1.79412 -9.28393,2.25 l -6,0.82888 -0.64806,5 c -1.05452,8.13597 -10.19844,32.3753 -13.55944,35.9443 -1.06473,1.1306 -3.96423,4.5663 -6.44331,7.6348 -2.47909,3.0685 -5.37183,6.4995 -6.42831,7.6245 -1.05648,1.1249 -3.66664,3.9018 -5.80036,6.1708 -3.09032,3.2864 -4.58088,4.1256 -7.32754,4.1256 l -3.44807,0 4.67803,-5.25 z m 5.47706,-1.25 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 8,-9 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 6,-7 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 85,-12.8776 c 0,-0.2076 -0.7875,-0.9951 -1.75,-1.75 -1.58606,-1.2438 -1.62143,-1.2085 -0.37756,0.3776 1.30637,1.6657 2.12756,2.1955 2.12756,1.3724 z m -13,-11.9674 c 0,-0.1898 -1.0125,-1.2023 -2.25,-2.25 l -2.25,-1.905 1.90499,2.25 c 1.79022,2.1144 2.59501,2.7052 2.59501,1.905 z m -8,-9.00001 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11444 2.59501,2.70524 2.59501,1.90499 z m -41,-13.2644 c 0,-0.21482 -2.1375,-0.3837 -4.75,-0.37528 -2.69011,0.009 -4.21371,0.35593 -3.51336,0.80076 1.18245,0.75103 8.26336,0.38643 8.26336,-0.42548 z m -15.15913,-0.88305 c -0.27085,-0.27086 -4.50835,-1.18259 -9.41666,-2.02608 -16.13633,-2.77299 -23.51094,-5.97517 -33.27596,-14.44895 -7.06554,-6.13127 -6.84736,-7.42208 1.10175,-6.51825 3.4375,0.39085 6.025,0.48259 5.75,0.20387 -0.99658,-1.01006 -14.48194,-2.63618 -15.27608,-1.84205 -0.44842,0.44842 2.5534,3.97257 6.67071,7.83144 9.85626,9.23759 17.5018,12.85148 33.17531,15.68127 8.58267,1.54956 12.04547,1.89328 11.27093,1.11875 z m 23.7264,-0.47481 c 0.532,-0.532 2.7595,-1.3868 4.95,-1.89955 2.1905,-0.51275 3.08273,-0.97137 1.98273,-1.01914 -1.1,-0.0478 -4.7,0.76597 -8,1.80833 -4.87947,1.54126 -5.4304,1.91223 -2.95,1.98641 1.6775,0.0502 3.48527,-0.34405 4.01727,-0.87605 z m -1.06727,-3.56001 c 3.85,-1.06802 7.225,-2.19571 7.5,-2.50598 0.275,-0.31026 2.3,-1.09477 4.5,-1.74336 5.05158,-1.48926 15.57308,-8.30539 21.71998,-14.07082 10.15582,-9.52554 18.78406,-25.08183 22.17104,-39.97322 2.25857,-9.93017 2.17044,-11.34285 -0.64102,-10.27621 -1.2375,0.4695 -5.625,1.02086 -9.75,1.22525 -7.05688,0.34966 -7.51817,0.24412 -7.80748,-1.7863 -0.33071,-2.32087 0.30249,-2.55846 10.30748,-3.8677 11.1663,-1.4612 23.27502,-8.62225 26.61935,-15.74257 1.23176,-2.6225 3.84631,-5.98973 5.81011,-7.48272 4.73441,-3.59937 9.07054,-8.06924 9.07054,-9.35029 0,-1.14449 5.05979,-8.20389 6.26146,-8.73595 0.4188,-0.18544 1.19818,-1.15318 1.73195,-2.15053 0.8951,-1.67251 0.64174,-1.65381 -3.26146,0.24076 -7.22492,3.5069 -10.3032,3.77646 -18.61575,1.63013 -9.07215,-2.34246 -19.00256,-2.1397 -21.58295,0.44068 -0.92186,0.92186 -2.14171,1.67611 -2.71077,1.67611 -2.54552,0 -8.99433,6.52871 -10.95829,11.09406 -1.16076,2.69827 -2.46826,4.90594 -2.90555,4.90594 -1.95933,0 -3.95864,-1.33678 -3.95864,-2.64683 0,-3.08568 4.35596,-10.05283 8.7413,-13.98128 l 4.60821,-4.12811 -4.56124,-6.37189 c -5.99722,-8.37789 -13.41368,-15.23903 -16.69909,-15.44873 -3.96961,-0.25337 -4.08918,-0.31285 -4.08918,-2.03394 0,-1.26833 -0.37392,-1.14902 -1.75876,0.56119 -3.16363,3.90691 -6.71424,0.67043 -4.27159,-3.89369 0.85843,-1.60399 0.0269,-2.12345 -7.25,-4.52893 -6.21814,-2.0555 -10.28943,-2.73355 -16.71965,-2.78455 -7.5672,-0.06 -19,1.69411 -19,2.91514 0,0.25239 1.31647,2.12001 2.92548,4.15026 4.36394,5.50639 6.47105,13.04213 5.76399,20.6139 l -0.58664,6.28221 5.37473,1.20281 c 21.33616,4.77483 28.69937,31.92058 12.95469,47.75979 -10.80462,10.86949 -26.4913,11.06535 -37.48583,0.46803 l -4.92782,-4.74978 -3.2593,3.39483 c -5.79484,6.0358 -10.13838,7.70973 -20.0093,7.71121 -8.60158,10e-4 -8.75,0.0426 -8.75,2.43384 0,1.33789 -0.52005,3.87072 -1.15568,5.62851 -1.08586,3.00291 -0.94993,3.38302 2.25,6.29169 1.87313,1.70263 3.98611,3.10888 4.69552,3.12501 0.70941,0.0161 2.95941,0.87562 5,1.91 5.35714,2.71554 26.10725,6.12131 37.21074,6.10748 6.7425,-0.008 12.40095,-0.73394 19.49709,-2.5 12.81724,-3.18989 15.50356,-3.23117 15.49859,-0.23817 -0.005,3.2606 -3.59424,8.64665 -6.49672,9.75017 -1.37475,0.52268 -2.49954,1.41147 -2.49954,1.97508 0,0.56361 -0.48214,1.02475 -1.07143,1.02475 -0.58928,0 -1.74575,0.67432 -2.56993,1.4985 -0.82417,0.82417 -2.70453,1.76639 -4.17856,2.09382 -1.47404,0.32743 -4.04917,1.20489 -5.7225,1.94992 -7.22305,3.21595 -18.24045,4.55548 -34.98967,4.25415 l -16.47466,-0.29639 3.75338,3.2447 c 8.53728,7.38027 17.41711,11.11298 32.67758,13.73628 4.90831,0.84375 9.17851,1.7884 9.48934,2.09923 1.09734,1.09735 13.67539,-0.1903 20.58645,-2.10749 z m 40.5,-82.47272 c 0,-1.1 -0.45,-2 -1,-2 -0.55,0 -0.99978,-1.0125 -0.99951,-2.25 4.9e-4,-2.23828 6.86797,-9.01585 11.80351,-11.64897 3.22732,-1.72179 11.25861,-4.07728 13.946,-4.09021 3.59163,-0.0173 2.91267,4.08892 -1.25,7.55971 -1.925,1.60504 -3.5,3.40484 -3.5,3.99955 0,1.65254 -3.95602,4.90826 -9.49204,7.81174 -6.12107,3.21032 -9.50796,3.43052 -9.50796,0.61818 z m 9,-3.36173 c 4.30061,-2.42779 8,-5.65282 8,-6.97419 0,-0.54301 1.6875,-2.48922 3.75,-4.32491 2.0625,-1.83568 3.525,-3.33309 3.25,-3.32756 -1.50707,0.0303 -10.20077,3.05406 -12.64753,4.39899 -3.66433,2.0142 -12.18544,9.58314 -10.7927,9.5867 0.58287,0.001 3.43212,-2.0223 6.33165,-4.4973 5.24143,-4.474 9.10858,-5.78543 9.10858,-3.08889 0,1.84596 -4.51449,5.57987 -9.77988,8.08889 -2.30845,1.1 -4.20234,2.32338 -4.20865,2.71862 -0.0143,0.8945 2.43529,-0.01 6.98853,-2.58035 z m -35,84.31604 c 1.09546,-0.74131 0.69092,-0.83408 -1.5,-0.34401 -3.67693,0.82247 -4.47511,1.39483 -1.91667,1.37439 1.05417,-0.008 2.59167,-0.47209 3.41667,-1.03038 z m 6.427,-2.47578 c 2.91505,-2.20537 1.48811,-2.46248 -1.927,-0.34722 -1.65,1.02199 -2.325,1.84622 -1.5,1.83162 0.825,-0.0146 2.36715,-0.68258 3.427,-1.4844 z m 7.14043,-5.58763 c 0.37335,-0.6041 -0.50159,-0.32492 -1.94431,0.62038 -1.44271,0.94531 -2.62312,1.90782 -2.62312,2.13891 0,0.72338 3.85397,-1.6049 4.56743,-2.75929 z m 3.43257,-2.3909 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 6,-5 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -65.02348,-3.06139 c 4.11208,-0.85786 8.83708,-2.16527 10.5,-2.90536 1.66291,-0.74008 4.22952,-1.6135 5.70356,-1.94093 1.47404,-0.32743 3.28207,-1.19733 4.01785,-1.93311 0.73578,-0.73578 2.00475,-1.59958 2.81993,-1.91955 1.26954,-0.49832 1.25981,-0.59309 -0.0679,-0.66071 -0.8525,-0.0434 -2.0117,0.38275 -2.57599,0.94704 -1.37761,1.37761 -13.6602,5.81918 -19.87401,7.18674 -2.75,0.60523 -10.175,1.4011 -16.5,1.7686 l -11.5,0.66819 10,0.17442 c 5.89347,0.1028 13.07026,-0.46609 17.47652,-1.38533 z m 70.52348,-3.43861 c 0.99549,-1.1 1.58498,-2 1.30998,-2 -0.275,0 -1.31449,0.9 -2.30998,2 -0.99549,1.1 -1.58498,2 -1.30998,2 0.275,0 1.31449,-0.9 2.30998,-2 z m -39.74244,-12.00913 c 1.24166,-1.81999 2.07092,-3.49572 1.84281,-3.72384 -0.22812,-0.22811 -5.13023,0.74348 -10.89357,2.15911 -8.13994,1.99938 -13.01511,2.57386 -21.84222,2.57386 -12.97438,0 -33.27435,-3.17908 -39.07474,-6.11931 -2.04059,-1.03438 -4.29059,-1.85699 -5,-1.82803 -0.70941,0.029 0.84976,1.11449 3.46483,2.41228 11.06002,5.4888 45.285,8.38592 59.24533,5.01506 3.3,-0.79682 6.7875,-1.45579 7.75,-1.46438 2.46056,-0.022 2.17728,2.43675 -0.5,4.33963 l -2.25,1.59919 2.5,-0.82725 c 1.375,-0.45498 3.5159,-2.31633 4.75756,-4.13632 z m 48.7905,-2.0838 c 0.87968,-1.70111 1.42188,-3.27046 1.2049,-3.48744 -0.21698,-0.21698 -1.14288,1.17483 -2.05756,3.09293 -2.05658,4.3127 -1.34401,4.64239 0.85266,0.39451 z m -128.0536,-7.9132 c -0.99854,-1.10337 -2.04794,-1.77372 -2.33199,-1.48967 -0.28406,0.28406 0.35068,1.1725 1.41054,1.97433 2.70408,2.04576 3.04782,1.86496 0.92145,-0.48466 z m -1.82881,-15.83491 c 0.54476,-4.29796 0.58312,-4.33487 3.86431,-3.71932 1.87409,0.35158 3.58779,0.17886 3.944,-0.3975 0.36318,-0.58764 0.011,-0.78172 -0.83176,-0.45833 -1.53986,0.5909 -6.76761,-1.7051 -10.1422,-4.4544 -1.9801,-1.6132 -1.98121,-1.60721 -0.11164,0.60221 1.66468,1.96729 1.82292,3.38868 1.33592,12 -0.43762,7.73827 -0.35047,8.83317 0.41936,5.26838 0.53449,-2.475 1.21939,-6.45347 1.52201,-8.84104 z m 135.93852,5.11187 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m 1,-4 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m -78.41667,-2.95394 c -0.72187,-0.28887 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28494 0.60416,-0.60416 z m 79.46844,-3.58592 c -0.27393,-0.67703 -0.48137,0.11903 -0.46099,1.76903 0.0204,1.65 0.2445,2.20394 0.49804,1.23097 0.25354,-0.97297 0.23687,-2.32297 -0.0371,-3 z m -124.92497,2.57604 c -0.97296,-0.25354 -2.32297,-0.23687 -3,0.0371 -0.67703,0.27393 0.11903,0.48137 1.76903,0.46099 1.65,-0.0204 2.20394,-0.2445 1.23097,-0.49804 z m 41.5128,0.0286 c -0.69092,-0.27855 -1.07389,-0.80553 -0.85104,-1.17105 0.22285,-0.36552 -1.20295,-0.75058 -3.16844,-0.85567 -1.9655,-0.1051 -4.95753,-1.20361 -6.64896,-2.44115 -2.34922,-1.71881 -2.72116,-1.81335 -1.57533,-0.40044 1.81731,2.24089 8.73947,5.51042 11.5,5.43176 1.1,-0.0313 1.4347,-0.28489 0.74377,-0.56345 z m -32.38703,-2.26255 c 2.07738,-1.0598 4.4142,-2.7473 5.19293,-3.75 1.34843,-1.73625 1.32057,-1.74235 -0.58488,-0.12808 -1.10041,0.93226 -4.01766,2.60988 -6.48277,3.72804 -2.46511,1.11817 -3.90159,2.04291 -3.19218,2.05499 0.70941,0.0121 2.98952,-0.84515 5.0669,-1.90495 z m 47.01576,0.49285 c 1.52524,-0.78874 3.40764,-2.25124 4.1831,-3.25 1.33163,-1.71509 1.29982,-1.7257 -0.57283,-0.1911 -1.09052,0.89366 -3.33277,2.33815 -4.98277,3.20996 -1.65,0.87182 -2.64015,1.60314 -2.20034,1.62516 0.43982,0.022 2.04759,-0.60529 3.57284,-1.39402 z m -3.36392,-2.43092 c 7.61004,-3.45714 13.65809,-12.5947 13.65809,-20.63499 0,-11.12314 -11.04986,-22.7 -21.66667,-22.7 -10.70226,0 -21.66666,11.57813 -21.66666,22.87946 0,4.64065 3.02363,11.97613 6.07456,14.73719 1.78745,1.61762 1.83913,1.5186 1.37172,-2.62829 -1.45227,-12.88452 7.92692,-22.30909 15.08152,-15.15449 4.84657,4.84656 5.99347,17.1236 2.14795,22.99261 -1.93035,2.94608 -0.65228,3.07608 4.99949,0.50854 z m -53.08133,-2.28112 c 3.70718,-6.27576 1.47296,-18.7986 -3.64361,-20.42254 -4.73397,-1.50251 -8.98587,3.85239 -9.06867,11.42119 -0.0712,6.50478 0.82438,8.55477 4.54657,10.40756 4.71129,2.34514 6.08999,2.10771 8.16571,-1.40621 z m 8.76107,0.52566 c 1.47857,-0.7519 4.15313,-3.11185 5.94345,-5.24433 3.16416,-3.76887 3.25672,-4.14456 3.31169,-13.44187 l 0.0566,-9.56463 -3.42512,-0.64252 c -6.57739,-1.23384 -11.12219,-3.74493 -15.41056,-8.51464 l -4.3202,-4.8051 -3.93064,1.7598 c -7.58534,3.39606 -13.58015,12.55734 -13.58015,20.75322 0,4.42188 3.08834,12.18072 5.7167,14.36206 1.23314,1.02342 1.44997,0.46906 1.44997,-3.70719 0,-9.99193 6.09864,-17.05981 12.75,-14.7763 5.96164,2.04672 9.18113,14.88436 5.77636,23.03311 -1.44844,3.46661 -1.43562,3.51518 0.75,2.84119 1.223,-0.37713 3.43338,-1.30089 4.91195,-2.0528 z m 37.28108,-0.95627 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 66.2806,0.88741 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z m -84.75,-1.68823 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 37,-1.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -83,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 41.40581,-3.29696 c 1.26469,0.48531 1.32727,0.18279 0.38844,-1.87771 -0.61552,-1.35092 -1.24526,-2.33009 -1.39942,-2.17593 -0.15416,0.15416 -1.48307,2.06857 -2.95312,4.25423 l -2.67282,3.97393 2.56468,-2.37651 c 1.43852,-1.33299 3.22665,-2.12249 4.07224,-1.79801 z m 103.59419,2.7059 c 0,-0.53273 -0.675,-0.70959 -1.5,-0.39301 -0.825,0.31659 -1.5,0.75246 -1.5,0.96862 0,0.21615 0.675,0.39301 1.5,0.39301 0.825,0 1.5,-0.43588 1.5,-0.96862 z m -59.19313,-4.55784 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z m -46.2027,-6.20271 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 48,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 45,-5 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 50,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -96,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 95,-5 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58438 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.0789,-1.91667 z m 49.01374,-4.98626 c -0.12014,-0.12014 -1.54582,0.178 -3.16817,0.66254 -1.62236,0.48454 -2.16224,0.91966 -1.19974,0.96694 0.9625,0.0473 1.76595,0.87345 1.78544,1.83595 0.0268,1.32558 0.37079,1.14405 1.41817,-0.74849 0.76051,-1.37418 1.28444,-2.5968 1.1643,-2.71694 z m 42.50618,0.44876 c -0.98762,-0.98026 -1.10248,-0.8654 -0.5598,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30789,-0.30789 6.4e-4,-1.11479 -0.68278,-1.79313 z M 65.08571,861.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -85,-2.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 38.4694,-2.07674 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 6.58891,-0.87068 c 2.30641,-2.50217 6.01686,-5.17968 8.48316,-6.12157 3.50845,-1.33988 4.61401,-2.37208 5.53737,-5.16987 3.7517,-11.36776 -3.1423,-24.22022 -15.17695,-28.29436 -4.64464,-1.57236 -5.7447,-1.61747 -9.7859,-0.40124 -14.93589,4.49504 -21.66079,20.75015 -13.81981,33.40461 l 2.18716,3.52985 0.74099,-5.89906 c 1.49666,-11.91498 8.85142,-17.25247 15.12639,-10.9775 4.48246,4.48246 5.8535,13.25622 3.22323,20.62656 -0.73605,2.0625 -1.17556,3.75 -0.9767,3.75 0.19886,0 2.20634,-2.00134 4.46106,-4.44742 z m -19.14164,3.16445 c -0.22917,-0.15563 -1.31667,-0.94313 -2.41667,-1.75 -1.85,-1.35701 -1.89707,-1.33579 -0.62755,0.28297 0.75484,0.9625 1.84234,1.75 2.41667,1.75 0.57432,0 0.85672,-0.12734 0.62755,-0.28297 z m 24.08333,-3.21703 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.94528,-0.0659 c -1.51303,-1.82309 -6.92706,-4.78561 -7.57027,-4.1424 -0.24152,0.24152 0.91037,0.99812 2.55977,1.68132 1.6494,0.68321 3.51893,1.86878 4.15451,2.6346 0.63558,0.76583 1.3806,1.39242 1.6556,1.39242 0.275,0 -0.0848,-0.70467 -0.79961,-1.56594 z m -75.94528,-0.9341 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 17,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 35.91667,-3.2579 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m -46,-1 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m 5.95162,-1.75427 c -1.01049,-2.21779 -1.20856,-2.27175 -2.75296,-0.75 -1.54948,1.52676 -1.49021,1.68325 0.86027,2.27141 1.38842,0.34743 2.62726,0.68493 2.75297,0.75 0.1257,0.0651 -0.26142,-0.95706 -0.86028,-2.27141 z m 49.04838,0.74819 c 0.22917,-0.19715 -0.55833,-0.35846 -1.75,-0.35846 -1.38524,0 -2.17763,-0.63115 -2.19707,-1.75 -0.0265,-1.52656 -0.17522,-1.49464 -1.16454,0.25 -0.62377,1.1 -1.62259,2.32475 -2.21959,2.72166 -0.59701,0.39691 0.71453,0.44572 2.91453,0.10846 2.2,-0.33726 4.1875,-0.77451 4.41667,-0.97166 z m 72.08333,-1.88414 c 0,-1.39308 -3.70207,-0.18103 -4.79566,1.57008 -1.24992,2.00144 -1.21295,2.01141 1.75946,0.47432 1.66991,-0.86354 3.0362,-1.78352 3.0362,-2.0444 z m 29.1875,0.84257 c -0.72188,-0.28888 -1.58438,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -19.9375,-2.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -84.64583,-3.06689 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 122.39583,-2.04448 c 0,-0.85783 -0.12734,-1.37218 -0.28297,-1.14302 -0.15563,0.22917 -0.89428,1.21447 -1.64144,2.18956 -1.18269,1.54348 -1.14607,1.69139 0.28297,1.14301 0.90279,-0.34643 1.64144,-1.33173 1.64144,-2.18955 z M 82.68988,837.89013 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 65.39583,1.38416 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11445 2.59501,2.70524 2.59501,1.90499 z m -66.39583,-7.38416 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 60.39583,0.35161 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z M 79.2098,826.35263 c -0.98761,-0.98026 -1.10248,-0.8654 -0.55979,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30788,-0.30789 6.3e-4,-1.11479 -0.68279,-1.79313 z m 56.87591,0.88911 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -97,-4.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 53.22334,-1.87639 c -0.26254,-1.00396 -0.54753,-1.69503 -0.63331,-1.53571 -0.0858,0.15931 -0.6787,0.98073 -1.3176,1.82537 -0.93948,1.24202 -0.81836,1.53572 0.63331,1.53572 1.24538,0 1.6488,-0.55888 1.3176,-1.82538 z M 43.08571,819.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.75848,-0.53051 c -0.94115,-1.51852 -0.96737,-2.21193 -0.10397,-2.75 0.63498,-0.39572 -0.80847,-0.71949 -3.20766,-0.71949 l -4.36218,0 3.39287,1.74065 c 1.86608,0.95735 3.67359,2.19485 4.01668,2.75 0.3431,0.55514 0.82607,1.00935 1.07327,1.00935 0.24721,0 -0.11685,-0.91373 -0.80901,-2.03051 z m 52.17485,-0.31215 c -0.23833,-0.20679 -1.78333,-0.65233 -3.43333,-0.99008 -2.73596,-0.56005 -2.80197,-0.51498 -0.75,0.51213 1.2375,0.61943 2.25,1.59747 2.25,2.17342 0,0.65288 0.44557,0.60162 1.18333,-0.13614 0.65084,-0.65084 0.98834,-1.35253 0.75,-1.55933 z m 9.94836,-7.40734 c 2.30606,-3.4375 3.82136,-6.25 3.36733,-6.25 -1.81925,0 -11.24902,12.98428 -11.24902,15.48929 0,1.26984 3.89338,-3.29416 7.88169,-9.23929 z m -84.96502,4.11454 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35466 2.91667,-1.55517 z m 2.58333,-1.36454 c -0.33991,-0.55 -0.81647,-1 -1.05901,-1 -0.24254,0 -0.44099,0.45 -0.44099,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m 6.82946,-1.58385 c -0.33428,-0.87111 -0.88789,-1.20861 -1.23025,-0.75 -0.34236,0.45862 -1.02974,1.17135 -1.52751,1.58385 -0.49776,0.4125 0.0558,0.75 1.23025,0.75 1.53743,0 1.96511,-0.44346 1.52751,-1.58385 z m 20.85804,0.90074 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28495 0.60416,-0.60417 z m 29,0 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -22.9375,-0.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m 18,0 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -8.5,-1.02705 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z M 53.3824,808.21186 c -0.98818,-1.3241 -1.94149,-2.01468 -2.11847,-1.53464 -0.36611,0.99302 1.91319,3.8465 3.11847,3.90404 0.43818,0.0209 -0.0118,-1.04531 -1,-2.3694 z m -3.29669,-3.66948 c 0,-1.50044 -5.57099,-6.92308 -7.11248,-6.92308 -0.69649,0 0.5064,1.73277 2.67307,3.8506 4.69729,4.5914 4.43941,4.41292 4.43941,3.07248 z m 92,-3.42308 c 1.29175,-1.375 2.12363,-2.5 1.84863,-2.5 -0.275,0 -1.55688,1.125 -2.84863,2.5 -1.29175,1.375 -2.12363,2.5 -1.84863,2.5 0.275,0 1.55688,-1.125 2.84863,-2.5 z m 6.04469,-1.70523 c 2.56704,-3.19434 2.82393,-3.81616 1.06867,-2.58673 -1.89119,1.32465 -5.69179,6.79196 -4.72142,6.79196 0.15033,0 1.79407,-1.89235 3.65275,-4.20523 z m -0.0447,-8.71959 c 0,-0.275 -2.25,1.71617 -5,4.42482 -2.75,2.70865 -5,5.14982 -5,5.42482 0,0.275 2.25,-1.71617 5,-4.42482 2.75,-2.70865 5,-5.14982 5,-5.42482 z m 1,3.42482 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 21.91908,-7.85167 c 2.4305,-0.72671 4.0055,-1.56089 3.5,-1.85373 -0.50549,-0.29284 -2.71908,0.27521 -4.91908,1.26232 -4.84957,2.17594 -4.44469,2.34468 1.41908,0.59141 z m 6.88779,-1.17479 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z M 17.08571,783.6193 c -1.925,-1.05389 -3.95,-1.91617 -4.5,-1.91617 -0.55,0 0.575,0.86228 2.5,1.91617 1.925,1.05389 3.95,1.91617 4.5,1.91617 0.55,0 -0.575,-0.86228 -2.5,-1.91617 z m 160,-2 c 0,-0.55 -0.7875,-0.99311 -1.75,-0.98469 -1.49555,0.0131 -1.5319,0.15626 -0.25,0.98469 1.88721,1.21961 2,1.21961 2,0 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2907"
+ transform="translate(0,784.36218)"
+ d="m 72.6,181.20757 c -16.765609,-3.86833 -22.376319,-6.32293 -32,-13.9995 l -2,-1.59535 13.2,-0.0317 c 17.959636,-0.043 26.293525,-1.0427 36.676385,-4.39926 12.401975,-4.00929 20.661075,-10.22837 22.672535,-17.07236 1.39926,-4.76097 -0.60247,-5.05117 -14.284918,-2.07088 C 80.913403,145.51284 69.067454,145.46531 50.6,141.85286 39.54215,139.68982 28.750784,134.8087 27.432732,131.37391 c -0.409763,-1.06782 0.94297,-9.55504 1.67366,-10.50077 0.129162,-0.16717 4.118063,-0.56369 8.864224,-0.88115 9.677258,-0.64731 12.721718,-1.79467 18.59718,-7.00868 l 3.565638,-3.16423 4.911016,4.16615 c 6.374081,5.4073 11.045891,7.19552 18.75555,7.17903 10.247136,-0.0219 18.94097,-5.4255 24.01507,-14.92636 2.33003,-4.3628 2.74898,-6.0141 3.03751,-11.972478 0.24409,-5.040832 -0.0244,-7.992693 -0.99183,-10.905433 C 106.83021,74.235948 98.683943,66.74733 89.719703,64.844988 L 85,63.8434 84.966254,55.710271 C 84.929438,46.837023 83.908403,43.511262 79.05568,36.458071 76.206234,32.316543 75.915993,32.561487 85.4,31.103895 c 9.620682,-1.478597 19.97708,-0.291557 29.26619,3.354462 4.00483,1.571915 4.0652,1.646353 4,4.932693 -0.0764,3.849526 1.76499,4.910844 4.39333,2.532225 0.84726,-0.766762 1.54048,-1.021054 1.54048,-0.565095 0,0.45596 1.6637,1.247942 3.6971,1.759959 4.38748,1.10478 11.00212,7.029509 17.23538,15.437707 l 4.03312,5.440379 -4.6828,5.026303 c -4.55714,4.891416 -8.2828,11.01514 -8.2828,13.614092 0,1.528769 2.86706,3.239468 4.42637,2.641103 0.60573,-0.232443 1.86318,-1.915954 2.79432,-3.741133 2.17353,-4.260467 7.69681,-10.272278 10.77931,-11.732734 1.32,-0.625402 3.4424,-1.697018 4.71645,-2.381368 2.96143,-1.590728 11.65807,-1.536216 19.53585,0.122452 7.69091,1.619321 10.4686,1.555228 15.93996,-0.367797 5.65346,-1.987032 5.64225,-1.987649 3.63541,0.2 -0.90817,0.99 -3.01076,3.96 -4.67241,6.6 -1.66166,2.64 -5.30895,6.908849 -8.1051,9.486333 -2.79614,2.577483 -5.99227,6.236344 -7.1025,8.130802 -4.94788,8.442912 -15.3818,14.634562 -28.34766,16.821932 -7.93582,1.33879 -10.1786,2.49921 -9.29263,4.80802 0.46879,1.22165 1.5792,1.32779 10.18353,0.97342 l 9.65736,-0.39773 -0.5479,3.65369 c -1.59381,10.62824 -7.28652,24.58268 -14.24705,34.92353 -11.30309,16.79232 -34.07569,29.48213 -55.75331,31.06798 -4.998646,0.36568 -7.935952,-0.008 -17.6,-2.23755 z m 81.50924,-82.494134 c 3.52664,-1.764307 6.56239,-3.962996 7.90749,-5.727124 1.2008,-1.574879 3.53327,-4.37647 5.18327,-6.225757 1.93865,-2.172795 3,-4.147985 3,-5.583022 0,-2.220043 -0.002,-2.220533 -4.38306,-1.705537 -8.74931,1.028309 -19.06055,6.827181 -22.74752,12.792833 l -1.71519,2.775229 1.70366,3.268542 c 2.14696,4.11903 3.52613,4.16955 11.05135,0.404836 l 0,0 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2913"
+ transform="translate(0,784.36218)"
+ d="m 160.6,87.334076 c 0,-0.534851 -1.1468,-0.981516 -2.6,-1.012667 -2.30544,-0.04942 -2.02164,-0.279224 2.50495,-2.028386 2.80772,-1.084959 5.23233,-1.845272 5.38801,-1.689584 0.15569,0.155688 -0.97154,1.499081 -2.50494,2.98532 C 161.85461,87.074997 160.6,87.86039 160.6,87.334076 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3703"
+ transform="translate(0,784.36218)"
+ d="m 24.692801,119.04257 c -0.05104,-2.05401 -0.313955,-4.31089 -0.584255,-5.01528 -0.431011,-1.12319 -0.185552,-1.10664 1.99579,0.13457 1.631194,0.92818 2.07587,1.50427 1.292,1.67384 -0.657385,0.1422 -1.361474,1.0422 -1.564643,2 -0.203169,0.95779 -0.521653,2.46144 -0.707744,3.34144 -0.186091,0.88 -0.380107,-0.0805 -0.431148,-2.13457 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3709"
+ transform="translate(0,784.36218)"
+ d="m 104.6,146.52914 c 0,-0.55196 -0.79531,-1.29776 -1.76736,-1.65735 -1.56978,-0.5807 -1.42649,-0.71774 1.28174,-1.2258 3.83551,-0.71955 4.4795,-0.10717 2.24118,2.13115 -1.00812,1.00812 -1.75556,1.32829 -1.75556,0.752 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3719"
+ transform="translate(0,784.36218)"
+ d="m 76.851058,112.03382 c -3.393188,-2.09142 -4.25448,-3.92327 -4.233488,-9.00408 0.03274,-7.923733 4.577488,-13.887568 8.633406,-11.329161 3.986638,2.514706 5.541626,13.083911 2.747781,18.676561 -1.667169,3.3373 -3.668438,3.80115 -7.147699,1.65668 l 0,0 z" />
+ <path
+ style="fill:#00d37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3721"
+ transform="translate(0,784.36218)"
+ d="m 31.011129,112.18685 c -3.337597,-1.68708 -4.784967,-4.28598 -4.794874,-8.60971 -0.01706,-7.444764 3.322321,-12.761965 7.700427,-12.261175 5.345895,0.611491 7.922362,14.073845 3.761169,19.652565 -2.071377,2.777 -3.181718,2.97991 -6.666722,1.21832 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3747"
+ transform="translate(0,784.36218)"
+ d="M 49.694395,74.66073 C 44.47115,71.825511 44.018691,61.3525 48.893397,56.120117 c 1.243238,-1.334459 2.71535,-2.426289 3.27136,-2.426289 3.274952,0 7.59925,10.034368 6.191417,14.366947 -2.961401,9.11366 -3.406311,9.452665 -8.661779,6.599955 z" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3749"
+ transform="translate(0,784.36218)"
+ d="m 30.863598,109.87939 c -4.598088,-3.22062 -2.443473,-16.412835 2.680623,-16.412835 3.343974,0 5.248203,11.238065 2.708365,15.983795 -1.423064,2.65902 -2.125412,2.71494 -5.388988,0.42904 l 0,0 z" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3751"
+ transform="translate(0,784.36218)"
+ d="M 53.409091,253.22727 C 175,254.36364 176.13636,254.36364 176.13636,254.36364" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3753"
+ transform="translate(0,784.36218)"
+ d="m 101.91757,251.70568 c -21.718752,-0.17272 -39.488638,-0.58449 -39.488638,-0.91506 0,-0.33057 3.818082,-4.96825 8.484628,-10.30595 4.666545,-5.33771 9.973982,-12.85892 11.794303,-16.71379 3.448266,-7.30236 8.521552,-22.38453 9.820557,-29.19514 0.752563,-3.94565 0.76643,-3.95339 12.3156,-6.87496 6.3592,-1.60867 12.35971,-3.28795 13.33446,-3.73173 1.29391,-0.58909 2.73131,0.66046 5.32536,4.62941 1.9542,2.98995 11.57847,13.87378 21.38726,24.18628 9.8088,10.3125 18.96093,20.28409 20.33807,22.15909 2.01779,2.74727 7.42703,15.23542 7.42703,17.14657 0,0.25689 -7.03125,0.34607 -15.625,0.19819 -8.59375,-0.14789 -33.39488,-0.4102 -55.11363,-0.58291 l 0,0 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3782"
+ transform="translate(0,784.36218)"
+ d="m 51.774116,254.22272 c 0.816832,-1.01161 5.399709,-6.3219 10.184171,-11.80065 4.784463,-5.47875 10.255577,-12.2121 12.158031,-14.963 5.284789,-7.64167 14.376394,-33.83808 12.993969,-37.44062 -0.338967,-0.88334 -2.48378,-1.73514 -5.328004,-2.116 C 60.981864,185.11713 50.75895,182.31448 43.625018,177.44148 37.971557,173.57975 28.01174,163.28381 28.01174,161.3013 c 0,-1.83865 0.635315,-1.8844 17.079208,-1.22988 19.475363,0.77518 28.155408,-0.12388 38.075567,-3.94376 9.279191,-3.57307 15.45203,-6.36285 15.01445,-6.78568 -0.201984,-0.19518 -4.599918,0.0895 -9.773185,0.63261 -15.856397,1.66468 -37.875872,-0.52821 -50.869606,-5.06603 -3.201056,-1.11791 -7.99066,-3.68786 -10.643565,-5.71099 l -4.823463,-3.67842 0.178374,-9.45002 0.178374,-9.45001 0.5642,7.42574 c 0.582301,7.66397 1.29799,8.16822 2.459224,1.73268 0.423991,-2.34976 0.289983,-3.71287 -0.365011,-3.71287 -0.569229,0 -1.034963,-1.33664 -1.034963,-2.9703 0,-1.63367 -0.407778,-2.9703 -0.906174,-2.9703 -1.708089,0 -9.947718,-12.02652 -11.073528,-16.16286 C 8.4406212,86.620448 14.328838,72.981775 26.509135,66.520142 l 4.472902,-2.372869 0,-7.169297 c 0,-11.907876 4.934342,-21.608335 13.56406,-26.665688 2.388815,-1.399939 4.1792,-3.048653 3.978634,-3.66381 C 47.539733,23.627398 33.787529,13.942425 21.173642,7.3865059 6.6394252,-0.16748247 5.7525435,-1.0667564 8.2445952,-5.7231976 9.9048868,-8.825481 13.26451,-8.0142814 26.786199,-1.2462239 42.52818,6.6331633 49.704459,11.834699 56.658674,20.406047 c 7.066894,8.71023 9.386734,9.398438 22.022822,6.533328 12.009438,-2.723024 25.519864,-2.231151 36.616764,1.3331 4.17096,1.339683 7.95921,2.16177 8.41835,1.826861 0.45913,-0.33491 2.70455,-3.059423 4.98981,-6.054473 2.28526,-2.995049 7.42528,-8.682601 11.42226,-12.639003 7.12067,-7.0483759 7.54019,-7.2929957 20.80065,-12.12871266 7.44339,-2.71438994 14.38913,-4.93525434 15.435,-4.93525434 1.40526,0 2.17641,1.0827118 2.95451,4.1481669 0.5791,2.28149179 0.85167,4.4737776 0.60572,4.871746 -0.24596,0.3979683 -6.12349,2.612099 -13.0612,4.92029 -12.32753,4.1014041 -12.76057,4.3449071 -19.06805,10.7223141 -3.54973,3.589081 -8.19833,9.098685 -10.33023,12.243564 l -3.87618,5.717962 4.38964,4.574292 c 2.4143,2.515859 3.60993,4.300819 2.65696,3.966577 -2.15679,-0.756469 -2.25789,0.631979 -0.17206,2.363061 1.27233,1.05594 1.70648,1.059167 2.35028,0.01747 0.5549,-0.897844 2.45839,0.813688 6.40236,5.756734 3.08697,3.868951 6.15063,7.065929 6.80813,7.104394 0.6575,0.03847 4.65679,0.0099 8.8873,-0.0634 4.23053,-0.07334 11.0745,0.619228 15.20883,1.53903 6.08457,1.353687 8.24222,1.455077 11.32293,0.532074 4.78641,-1.434041 9.61096,-5.430654 10.01889,-8.299556 0.1988,-1.398101 1.12005,-2.308693 2.53968,-2.510314 2.12619,-0.301966 2.22772,-0.004 2.22772,6.538442 0,6.740641 -0.099,7.001552 -5.9449,15.662921 -3.26969,4.844452 -7.74462,10.309246 -9.94428,12.143987 -2.19966,1.834742 -5.77393,5.949037 -7.94282,9.142879 -2.34976,3.460168 -6.29513,7.465423 -9.76248,9.910673 l -5.81903,4.10369 -1.15924,7.92805 c -1.61723,11.06032 -4.40347,19.58965 -9.70377,29.70553 -5.01528,9.57187 -13.95714,20.46445 -14.03497,17.09676 -0.0428,-1.8524 -0.1273,-1.86246 -1.77762,-0.21171 -1.37485,1.3752 -1.46515,1.89852 -0.43722,2.53406 1.41537,0.87508 -1.77232,4.09197 -9.46671,9.55344 -2.27836,1.61719 -4.34463,3.44333 -4.59171,4.0581 -0.8189,2.03758 6.19452,11.05322 18.90021,24.29583 6.90108,7.19272 12.04414,13.24542 11.42903,13.45046 -0.61512,0.20504 -0.83848,1.12371 -0.49637,2.0415 0.34212,0.91778 -1.79925,-0.97306 -4.75858,-4.20188 -2.95935,-3.22881 -5.27705,-6.21281 -5.15046,-6.6311 0.12659,-0.41828 -1.76241,-2.39328 -4.19777,-4.38889 -2.43538,-1.9956 -4.20453,-3.98988 -3.93146,-4.43172 0.27308,-0.44185 -1.40227,-2.36965 -3.72301,-4.28402 -2.32073,-1.91436 -5.99559,-5.73898 -8.16635,-8.49916 -4.50513,-5.7284 -5.73975,-6.34273 -10.18478,-5.06791 -1.75731,0.50399 -3.19511,0.54209 -3.19511,0.0847 0,-1.33295 -11.17951,1.64109 -12.389579,3.29596 -0.60449,0.82669 -2.322383,1.8101 -3.817542,2.18536 -3.551652,0.89142 -4.937215,3.23379 -7.580515,12.81533 -4.406767,15.97381 -11.099683,29.94917 -15.20688,31.75323 -1.152028,0.50601 -2.096442,1.7759 -2.098696,2.82193 -0.0024,1.08338 -1.280677,2.61084 -2.970297,3.54913 -1.631409,0.90597 -2.982805,2.27784 -3.003103,3.04859 -0.05664,2.15103 -3.526894,6.90294 -4.570213,6.25813 -0.985639,-0.60915 -3.808724,1.30636 -3.808724,2.5843 0,1.92758 5.895059,2.34928 41.089109,2.93925 l 37.62376,0.63071 -39.232671,0.18757 c -21.57797,0.10316 -40.736386,0.48547 -42.574257,0.84959 -3.159411,0.62595 -3.260618,0.56176 -1.856436,-1.17724 z m 42.238485,-67.99171 c -1.942887,-0.70765 -3.471758,-0.70422 -4.950495,0.0112 -1.790743,0.86631 -1.332552,1.03319 2.81102,1.02385 4.566697,-0.0103 4.732564,-0.0905 2.139475,-1.03501 l 0,-3e-5 z m -14.020663,-0.82863 c -1.089109,-0.4866 -6.435644,-1.80129 -11.881188,-2.92155 -5.759121,-1.18476 -12.800298,-3.45953 -16.831683,-5.43774 -6.954731,-3.41271 -17.742094,-11.92119 -16.880858,-13.3147 0.253072,-0.40948 3.040932,-0.57204 6.195246,-0.36125 4.48988,0.30005 5.355073,0.14443 3.984772,-0.71671 -0.96269,-0.60499 -4.913826,-1.36519 -8.780302,-1.68935 -6.863409,-0.57539 -7.004171,-0.54119 -5.941584,1.44428 2.200044,4.11082 13.668199,13.46069 20.585236,16.78294 7.129107,3.42411 21.632479,7.0912 28.065212,7.09613 2.851296,0.002 3.114461,-0.15412 1.485149,-0.88205 z m 13.55198,-1.63782 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52001 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 8.981792,-3.22305 c 4.1272,-1.05557 9.34757,-2.85973 11.60083,-4.00925 2.25325,-1.14953 4.87457,-1.8432 5.82513,-1.54151 0.95056,0.30171 2.59602,-0.12295 3.65656,-0.94367 1.60041,-1.23851 1.63367,-1.38963 0.19559,-0.88881 -2.84772,0.99172 -1.97918,-0.17229 2.18456,-2.92772 2.15449,-1.42577 4.50534,-2.36663 5.22413,-2.09081 0.7188,0.27584 3.05637,-1.2901 5.1946,-3.47985 2.13823,-2.18975 3.51995,-3.98136 3.07047,-3.98136 -0.44946,0 -0.26663,-0.66342 0.4063,-1.47425 0.67294,-0.81083 1.5681,-1.26129 1.98925,-1.001 0.42114,0.26029 1.37313,-0.30156 2.11553,-1.24853 1.22149,-1.55808 1.18509,-1.59258 -0.38286,-0.36292 -0.95297,0.74738 -1.73267,0.91332 -1.73267,0.36877 0,-1.1032 2.94273,-3.80059 3.86504,-3.5428 0.32472,0.0908 0.81317,-0.0921 1.08545,-0.40626 0.27228,-0.3142 -0.0619,-0.25079 -0.74257,0.14094 -1.83418,1.05552 -1.52708,0.0245 1.35025,-4.53358 3.80038,-6.02017 8.15245,-16.13427 10.34121,-24.03269 2.90781,-10.4932 3.24131,-10.00199 -6.51584,-9.59724 -8.06376,0.33451 -11.36374,-0.51104 -11.36374,-2.91169 0,-1.41219 3.87705,-3.01077 12.01762,-4.9551 13.6173,-3.2524 18.1279,-6.30458 30.44942,-20.604205 3.20647,-3.721241 5.60795,-5.75908 6.01348,-5.102907 0.45242,0.732027 1.17307,0.513084 2.18435,-0.663636 2.69435,-3.135129 3.29702,-4.863342 0.99046,-2.840244 -1.18271,1.037369 -2.15038,1.440581 -2.15038,0.896027 0,-1.154396 3.94299,-4.919356 4.6419,-4.432319 0.26048,0.181519 0.77064,-0.0013 1.13367,-0.406262 0.36304,-0.404963 0.10314,-0.415797 -0.57755,-0.02408 -1.80598,1.039294 -1.51814,-0.190163 0.80999,-3.459724 2.31999,-3.258114 2.32271,-3.256657 -3.39724,-1.816357 -3.2192,0.810603 -6.66348,0.694459 -14.67251,-0.494768 -15.04707,-2.234274 -20.55437,-0.689621 -28.57683,8.015049 -2.42602,2.632325 -4.72907,4.680174 -5.11788,4.550775 -0.38882,-0.129399 -0.48449,0.344426 -0.2126,1.052946 0.27188,0.70852 -0.4282,2.123094 -1.55573,3.143497 -2.0095,1.818571 -2.09324,1.812104 -4.23219,-0.326854 l -2.18214,-2.182131 2.25594,-4.252496 c 1.24077,-2.338872 4.17354,-6.452573 6.51728,-9.141556 2.34372,-2.688985 4.05061,-5.50801 3.79308,-6.264503 -0.31259,-0.918192 -0.0455,-1.114196 0.80328,-0.589595 0.85837,0.530499 1.02875,0.393018 0.52435,-0.423105 -0.41094,-0.664922 -0.99572,-0.9604 -1.2995,-0.656618 -0.69266,0.69266 -3.20978,-1.330935 -3.20978,-2.580451 0,-0.510014 0.51439,-0.609392 1.14308,-0.220837 0.73045,0.451439 0.87336,0.270048 0.3959,-0.50249 -0.41094,-0.664922 -1.00055,-0.955563 -1.31024,-0.645868 -0.69833,0.698319 -4.18913,-2.365165 -4.18913,-3.67632 0,-0.526833 0.7797,-0.370613 1.73267,0.347155 0.95297,0.717767 -0.70223,-1.23225 -3.67822,-4.333371 -3.76003,-3.918124 -5.93501,-5.472057 -7.12873,-5.093182 -0.94481,0.299873 -3.07003,-0.15402 -4.7227,-1.00865 -2.43778,-1.26062 -3.37289,-1.324035 -4.95495,-0.33602 -2.36555,1.477307 -3.05981,0.886 -3.92467,-3.34268 -0.56625,-2.768728 -1.37248,-3.513567 -5.43639,-5.022464 -7.80616,-2.898363 -17.966683,-4.011606 -26.200113,-2.870631 -3.997279,0.553936 -7.475959,1.215337 -7.730402,1.469779 -0.254442,0.254443 0.998085,3.050852 2.783393,6.214244 2.874608,5.093525 3.291609,6.794112 3.644505,14.862796 l 0.398492,9.111176 3.564442,0.668693 c 7.773644,1.458345 16.010573,8.110583 19.620143,15.845464 3.09701,6.636514 3.26024,18.338664 0.34238,24.546143 -2.99996,6.38214 -7.1277,10.84757 -13.007325,14.07144 -4.530381,2.48406 -6.383854,2.90835 -12.728271,2.91366 -6.074888,0.005 -8.236255,-0.44332 -11.881188,-2.465 -2.450495,-1.35916 -4.455445,-2.98232 -4.455445,-3.60701 0,-0.62469 -0.40559,-1.50708 -0.901312,-1.96089 -0.523658,-0.47936 -0.602889,-0.3065 -0.189092,0.41255 0.391721,0.68069 0.309434,1.23762 -0.182859,1.23762 -1.220735,0 -4.304298,-3.49834 -3.655466,-4.14718 0.286625,-0.28662 -0.191905,-1.11291 -1.063399,-1.83618 -1.321234,-1.09653 -1.725666,-1.0867 -2.433844,0.0592 -0.46712,0.75582 -0.647589,1.7006 -0.401041,2.09952 0.480206,0.77699 -4.431607,4.73002 -8.49972,6.84057 -1.361386,0.7063 -6.473966,1.77939 -11.361289,2.38466 l -8.886042,1.10047 -0.8419,4.2572 c -1.116431,5.64542 -0.634772,6.55826 4.953601,9.38814 6.711939,3.39884 14.108367,5.45589 25.541571,7.10346 13.412147,1.93275 20.966236,1.82034 33.743152,-0.50211 17.901519,-3.25395 20.945769,-2.59407 18.234109,3.95245 -1.77158,4.27697 -8.27108,9.72932 -15.51118,13.01214 -10.066949,4.56456 -20.604188,6.60666 -38.045678,7.37316 -12.034826,0.52888 -15.515628,0.97079 -14.765554,1.87458 0.53979,0.65041 0.751763,1.41223 0.47105,1.69294 -0.280712,0.28071 0.280084,1.1308 1.246214,1.8891 1.597283,1.25367 1.633357,1.22157 0.397743,-0.35396 -1.901096,-2.42408 -0.973659,-2.18092 4.907357,1.28665 4.510039,2.65922 13.386837,5.60901 26.15447,8.69123 6.758464,1.63156 18.458956,1.2966 26.494168,-0.75846 l 0,-4e-5 z m 15.58504,-0.061 c 1.16161,-0.7507 0.90473,-0.96308 -1.17919,-0.97494 -1.46538,-0.008 -2.9397,0.43038 -3.27626,0.97494 -0.78135,1.26425 2.49915,1.26425 4.45545,0 z m 6.00568,-2.01503 c 1.95644,-1.04706 2.62207,-2.93547 1.0347,-2.93547 -0.48422,0 -1.93224,0.87627 -3.21783,1.94726 -2.49465,2.07826 -1.06383,2.72592 2.18313,0.98821 z m -6.00568,-1.45032 c 1.36139,-0.77824 2.0297,-1.41498 1.48515,-1.41498 -0.54456,0 -2.10396,0.63674 -3.46535,1.41498 -1.36138,0.77824 -2.0297,1.41498 -1.48515,1.41498 0.54456,0 2.10396,-0.63674 3.46535,-1.41498 z m -62.458746,0.13411 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553336,0.36093 1.577225,1.26362 4.799862,2.3676 3.441125,1.17883 l 0,0 z m 74.762706,-3.12566 c 1.04936,-0.7939 1.64445,-1.70691 1.32243,-2.02893 -0.78266,-0.78265 -4.7155,1.36919 -4.7155,2.58006 0,1.33049 1.15362,1.1431 3.39307,-0.55113 z m 5.3845,-4.97977 c 0.31295,-1.61495 0.14607,-1.68767 -1.23763,-0.53929 -1.89234,1.57049 -2.12795,3.40609 -0.36172,2.81801 0.68069,-0.22665 1.40039,-1.25207 1.59935,-2.27872 z m -93.926084,0.17176 c 0,-0.2056 -0.779703,-0.9853 -1.732673,-1.73268 -1.570353,-1.23155 -1.605372,-1.19653 -0.373817,0.37382 1.293435,1.64926 2.10649,2.17375 2.10649,1.35886 z m 42.048957,-9.0646 c 10.23476,-3.01561 12.830661,-4.22882 16.665417,-7.78864 1.52559,-1.41621 3.14513,-2.57492 3.599,-2.57492 0.45387,0 1.59099,-1.16873 2.52694,-2.59715 0.93594,-1.42844 1.24801,-2.31675 0.69349,-1.97403 -0.55454,0.34271 -1.20807,0.0635 -1.45231,-0.62067 -0.24423,-0.68409 -0.82632,-0.88541 -1.2935,-0.44739 -0.46721,0.43803 -0.19404,1.21091 0.60702,1.71751 1.25252,0.79212 1.23533,0.92323 -0.12275,0.93627 -0.86857,0.008 -2.42798,0.95441 -3.46535,2.10238 -5.028165,5.56424 -22.795527,11.3182 -38.212356,12.37508 -15.799597,1.08311 -17.048668,2.42489 -1.792578,1.92561 10.641937,-0.34827 15.176438,-0.97076 22.246977,-3.05405 l 0,0 z m 63.891637,-3.12611 c 0,-1.41552 -0.23243,-1.39342 -1.9802,0.18829 -1.08911,0.98563 -1.9802,2.18422 -1.9802,2.66353 0,0.47932 0.89109,0.39459 1.9802,-0.18828 1.08911,-0.58287 1.9802,-1.78147 1.9802,-2.66354 z M 97.166642,146.77097 c 3.547598,-0.77002 4.965228,-1.47727 4.298178,-2.14431 -0.66706,-0.66706 -4.175166,-0.42281 -10.636358,0.74056 -14.897153,2.68229 -37.124591,0.77195 -52.477337,-4.51017 -6.578027,-2.26317 -6.378989,-2.22908 -6.378989,-1.09252 0,1.42916 9.008565,4.85904 15.926311,6.06371 16.965213,2.95437 38.134158,3.35943 49.268195,0.94273 l 0,0 z m 53.617378,0.0462 c 0.58287,-1.08911 0.837,-1.9802 0.56472,-1.9802 -0.27228,0 -0.97195,0.89109 -1.55482,1.9802 -0.58287,1.08911 -0.837,1.9802 -0.56472,1.9802 0.27227,0 0.97195,-0.89109 1.55482,-1.9802 z m 5.94059,-4.62356 c 0,-2.3135 -1.69554,-0.59965 -2.85822,2.88907 l -1.073,3.21964 1.96562,-2.33741 c 1.08108,-1.28558 1.9656,-2.98266 1.9656,-3.7713 z m -77.497329,2.91089 c -2.054226,-0.21433 -5.173038,-0.21074 -6.930694,0.008 -1.757656,0.21872 -0.07693,0.39409 3.734955,0.38969 3.811881,-0.004 5.249963,-0.18335 3.195739,-0.39768 l 0,7e-5 z m 10.356241,-0.94387 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52002 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 19.616338,-1.30386 c 0,-0.54455 -0.47184,-0.99009 -1.04854,-0.99009 -0.57669,0 -0.77316,0.44554 -0.43661,0.99009 0.33655,0.54456 0.8084,0.9901 1.04853,0.9901 0.24014,0 0.43662,-0.44554 0.43662,-0.9901 z m 47.45458,-8.41584 c 0,-0.54455 -0.63674,0.12377 -1.41498,1.48515 -0.77823,1.36139 -1.41498,2.92079 -1.41498,3.46535 0,0.54455 0.63675,-0.12376 1.41498,-1.48515 0.77824,-1.36139 1.41498,-2.92079 1.41498,-3.46535 z M 28.453542,136.6394 c -0.717346,-1.86938 -3.412099,-3.08084 -3.412099,-1.53397 0,1.05715 3.177874,3.9134 3.73462,3.35666 0.149813,-0.14981 0.0047,-0.97003 -0.322521,-1.82269 z m 6.406383,0.90594 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553337,0.36093 1.577226,1.26362 4.799863,2.3676 3.441126,1.17883 z m -8.178941,-9.80642 c -0.27121,-0.67032 -0.476602,0.11785 -0.456423,1.75152 0.02018,1.63366 0.242077,2.18212 0.493111,1.21878 0.251032,-0.96334 0.234523,-2.29997 -0.03668,-2.9703 l -4e-6,0 z M 162.66521,127.0736 c 0,-0.51242 -0.44555,-1.20703 -0.9901,-1.54359 -0.54456,-0.33655 -0.9901,0.0827 -0.9901,0.93167 0,0.84897 0.44554,1.54358 0.9901,1.54358 0.54455,0 0.9901,-0.41925 0.9901,-0.93166 z M 27.619826,122.33281 c -0.329002,-0.329 -0.563011,0.25579 -0.52002,1.29951 0.0475,1.15341 0.28212,1.38802 0.598185,0.59819 0.286011,-0.71474 0.250836,-1.5687 -0.07817,-1.8977 l 3e-6,0 z m 136.035474,0.2269 c 0,-0.81683 -0.44554,-1.48514 -0.99009,-1.48514 -0.54456,0 -0.9901,0.66831 -0.9901,1.48514 0,0.81684 0.44554,1.48515 0.9901,1.48515 0.54455,0 0.99009,-0.66831 0.99009,-1.48515 z M 33.704809,119.40196 c -0.95297,-0.24903 -2.512376,-0.24903 -3.465346,0 -0.952971,0.24904 -0.173268,0.4528 1.732673,0.4528 1.905941,0 2.685644,-0.20376 1.732673,-0.4528 z m 51.237624,-0.30759 c 0.336553,-0.54456 -0.250915,-0.9901 -1.305483,-0.9901 -1.054569,0 -2.472053,-0.66832 -3.149963,-1.48515 -0.677909,-0.81683 -2.197663,-1.48515 -3.37723,-1.48515 -1.179567,0 -3.798279,-0.84306 -5.819362,-1.87346 -3.979476,-2.02885 -4.801958,-1.43381 -1.788124,1.29368 1.984228,1.7957 10.984716,4.90909 10.984716,3.79975 0,-0.35514 0.534654,-0.11106 1.188119,0.54241 1.44777,1.44777 2.457132,1.50894 3.267327,0.19802 z m 79.702967,-3.02873 c 0,-1.05697 -0.44554,-1.92177 -0.9901,-1.92177 -0.54455,0 -0.99009,1.14016 -0.99009,2.53369 0,1.43699 0.42855,2.26881 0.99009,1.92176 0.54456,-0.33656 0.9901,-1.47671 0.9901,-2.53368 z m -126.008939,1.3525 c -0.963334,-0.25103 -2.299968,-0.23452 -2.970297,0.0366 -0.670329,0.27122 0.117853,0.47661 1.751517,0.45643 1.633663,-0.0202 2.182114,-0.24208 1.21878,-0.49311 l 0,5e-5 z m 15.788583,-6.49209 c 2.961802,-2.58663 6.027485,-4.70297 6.812628,-4.70297 1.653245,0 1.836694,-1.82146 0.39887,-3.96039 -0.83888,-1.24794 -1.390264,-1.01072 -3.45205,1.48514 -1.349539,1.63367 -2.677116,3.63862 -2.950173,4.45545 -0.273055,0.81683 -3.168256,2.95063 -6.433779,4.74178 -3.265523,1.79115 -5.937315,3.64601 -5.937315,4.12192 0,1.77959 6.361283,-1.59914 11.561819,-6.14093 z m -20.47271,5.3104 c 0,-1.48733 -5.81027,-1.8801 -6.366582,-0.43038 -0.356538,0.92913 0.492992,1.3081 2.93231,1.3081 1.888849,0 3.434272,-0.39498 3.434272,-0.87772 z m 63.050779,-1.35 c 2.916955,-1.98579 4.205247,-3.71287 2.769577,-3.71287 -0.693665,0 -8.394613,5.11626 -8.394613,5.57711 0,1.01623 2.716191,0.11603 5.625036,-1.86424 z m -5.082551,-1.19364 c 7.593085,-3.17259 13.318898,-12.23833 13.318898,-21.087947 0,-14.183278 -14.801367,-26.126413 -27.276503,-22.009246 -4.871629,1.607782 -12.143736,8.333235 -14.435363,13.350236 -3.260107,7.137268 -1.947056,16.953627 3.009811,22.501317 l 2.75988,3.08884 0.514066,-6.40417 c 0.59176,-7.372086 2.817916,-12.370412 6.194803,-13.909026 9.324945,-4.24873 15.584088,10.950876 9.956609,24.178486 -0.930827,2.18794 1.172672,2.29087 5.957799,0.29151 l 0,0 z m -66.879119,-1.52913 c -2.805149,-2.19422 -4.307733,-2.52716 -3.741707,-0.82908 0.211038,0.6331 1.180081,1.268 2.15343,1.41085 0.973349,0.14286 2.025929,0.51595 2.339067,0.82908 0.313138,0.31314 0.829243,0.55943 1.1469,0.54732 0.317656,-0.0121 -0.536304,-0.89328 -1.89769,-1.95817 z m 12.639913,0.64485 c 0.689575,-0.42992 0.997439,-1.19644 0.684141,-1.70337 -0.313298,-0.50692 -0.139505,-0.92168 0.386206,-0.92168 0.525712,0 0.704595,-0.96077 0.397519,-2.13502 -0.337827,-1.29185 -0.167417,-1.89344 0.431502,-1.52328 0.604271,0.37346 1.005912,-1.20529 1.031127,-4.0531 0.03148,-3.556019 -0.171219,-4.194157 -0.852784,-2.684642 -0.678574,1.502882 -0.773791,1.192692 -0.395022,-1.286842 0.353363,-2.313228 0.165236,-3.060723 -0.644381,-2.560356 -0.737692,0.45592 -0.940577,0.178019 -0.571745,-0.783139 0.314436,-0.819406 0.23569,-2.033505 -0.174991,-2.698 -1.105326,-1.788456 -7.682811,-2.144736 -9.055691,-0.490515 -0.631379,0.760762 -0.759249,1.396753 -0.284156,1.413317 0.475095,0.01654 0.06457,0.495168 -0.912263,1.063584 -1.129264,0.657109 -1.565313,1.697515 -1.197349,2.856861 0.318297,1.002872 0.145073,2.091406 -0.384943,2.418971 -1.212393,0.749301 -1.114708,6.501761 0.11041,6.501761 0.49838,0 0.626441,0.88128 0.284578,1.95839 -1.132056,3.56679 7.260902,7.05039 11.147842,4.62706 l 0,0 z m 8.934184,-0.55418 c 2.020385,-1.03924 5.010061,-3.29502 6.643725,-5.01286 2.868463,-3.01627 2.981671,-3.49028 3.302077,-13.826072 l 0.33178,-10.702722 -3.762914,-0.705927 C 47.602481,80.969761 43.95345,78.863901 38.40778,73.51044 l -4.950496,-4.778915 -3.90401,1.921073 C 17.503668,76.58193 12.423679,90.628824 18.240927,101.93283 c 3.23262,6.2816 4.539882,6.43779 5.329032,0.6367 0.928828,-6.827865 1.319844,-7.895489 4.103161,-11.203281 7.697735,-9.148234 17.690208,3.484377 13.905573,17.579601 -1.6234,6.04608 -1.03574,6.43209 5.036847,3.3085 l 0,0 z m 37.877227,-0.17548 c 0.607833,-1.13574 0.846281,-2.32386 0.529884,-2.64025 -0.316397,-0.3164 -0.575268,-0.0873 -0.575268,0.50911 0,0.59643 -0.700141,1.78455 -1.55587,2.64027 -0.855728,0.85573 -1.094176,1.55587 -0.529884,1.55587 0.564291,0 1.523303,-0.92924 2.131138,-2.065 l 0,0 z m -8.956275,-0.41024 c -0.777242,-0.93653 -0.843612,-1.48515 -0.179665,-1.48515 0.579095,0 1.32826,0.44554 1.664814,0.9901 0.336553,0.54455 1.710509,0.9901 3.053236,0.9901 3.405659,0 4.705098,-3.86234 3.99729,-11.88119 -0.410484,-4.650429 -0.278996,-6.023676 0.474005,-4.950498 0.92628,1.320129 0.997019,1.320129 0.636655,0 -0.222976,-0.816832 -0.888084,-1.485149 -1.478018,-1.485149 -0.589933,0 -1.406765,-0.334158 -1.815181,-0.742574 -0.408416,-0.408416 -1.808473,-0.742574 -3.111239,-0.742574 -1.326986,0 -2.099559,-0.435416 -1.756748,-0.990099 1.082137,-1.750934 -0.356281,-1.056251 -2.436678,1.176792 -1.948858,2.091852 -2.796679,4.371505 -1.276193,3.431475 0.408415,-0.252495 0.742574,2.796683 0.742574,6.775957 0,4.5426 -0.368457,7.02333 -0.990099,6.66611 -0.544555,-0.31292 -0.141343,0.39874 0.896028,1.58146 2.106995,2.4022 3.511949,2.99403 1.579219,0.66524 l 0,0 z m 74.981158,-0.19108 c -0.96334,-0.25103 -2.29997,-0.23453 -2.9703,0.0366 -0.67032,0.27122 0.11786,0.4766 1.75152,0.45643 1.63366,-0.0202 2.18212,-0.24208 1.21878,-0.49311 l 0,5e-5 z m -84.882148,-2.77922 c -0.67791,-0.81683 -1.678108,-1.48515 -2.222662,-1.48515 -0.552304,0 -0.445093,0.65669 0.242464,1.48515 0.67791,0.81683 1.678108,1.48515 2.222663,1.48515 0.552304,0 0.445093,-0.6567 -0.242465,-1.48515 z m 38.428218,-0.43317 c 0.24752,-0.74257 -0.12376,-1.11386 -0.86634,-0.86634 -0.71472,0.23824 -1.49443,1.01795 -1.73267,1.73268 -0.24752,0.74257 0.12376,1.11386 0.86634,0.86633 0.71472,-0.23823 1.49443,-1.01795 1.73267,-1.73267 z m 61.57178,-0.16781 c 0,-1.1313 -2.6849,-1.15685 -3.38,-0.0322 -0.2896,0.4686 -0.27234,1.10622 0.0384,1.41693 0.7726,0.77266 3.34158,-0.29192 3.34158,-1.38475 z m -145.544552,0.16436 c 0,-1.16817 -1.931044,-2.41782 -2.640265,-1.7086 -0.709219,0.70923 0.54042,2.64027 1.708598,2.64027 0.512417,0 0.931667,-0.41925 0.931667,-0.93167 z m 65.94472,-2.76058 c -0.329002,-0.329 -0.563011,0.25578 -0.52002,1.29951 0.04751,1.15341 0.28212,1.38802 0.598185,0.59818 0.286011,-0.71472 0.250836,-1.56868 -0.07817,-1.89769 l 3e-6,0 z m 20.193892,-0.7632 c 0,-0.81683 -0.44554,-1.48515 -0.9901,-1.48515 -0.54455,0 -0.9901,0.66832 -0.9901,1.48515 0,0.81683 0.44555,1.48515 0.9901,1.48515 0.54456,0 0.9901,-0.66832 0.9901,-1.48515 z m 60.18796,-0.40346 c 2.02039,-1.03875 5.45561,-3.52622 7.63382,-5.527735 l 3.9604,-3.639109 -4.45545,3.425762 c -2.45049,1.884172 -6.23762,4.351962 -8.41584,5.483972 -2.17822,1.13201 -3.60848,2.0779 -3.17837,2.10196 0.43011,0.0241 2.43506,-0.80612 4.45544,-1.84485 z m -94.1857,-5.289607 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237627 0,1.36138 0.224726,1.91831 0.499392,1.23762 0.274665,-0.68069 0.274665,-1.794554 0,-2.475247 z m 13.861386,-0.990099 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237624 0,1.361382 0.224726,1.918312 0.499392,1.237622 0.274666,-0.680691 0.274666,-1.794553 0,-2.475246 z m -25.408199,0.742575 c 0,-0.816832 -0.445544,-1.485149 -0.990099,-1.485149 -0.544554,0 -0.990099,0.668317 -0.990099,1.485149 0,0.816831 0.445545,1.485151 0.990099,1.485151 0.544555,0 0.990099,-0.66832 0.990099,-1.485151 z m 47.524753,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921683 -0.55343,0.342039 -0.74992,1.036653 -0.43661,1.543584 0.84874,1.37331 1.44286,1.11724 1.44286,-0.621901 l 0,0 z M 13.75844,96.59024 c -0.329002,-0.329 -0.563011,0.255782 -0.520019,1.299504 0.04751,1.153416 0.282119,1.38802 0.598184,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897693 l 0,0 z m 45.936468,-3.733496 c 0,-0.816831 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668317 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m 49.504952,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921684 -0.55343,0.34204 -0.74992,1.036654 -0.43661,1.543585 0.84874,1.373307 1.44286,1.117237 1.44286,-0.621901 l 0,0 z M 12.768341,90.649645 c -0.329002,-0.328998 -0.563011,0.255783 -0.52002,1.299505 0.04751,1.153416 0.28212,1.38802 0.598185,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897694 l 0,0 z m 70.193894,0.721951 c -0.336554,-0.544555 -1.142551,-0.983277 -1.791106,-0.974941 -0.708531,0.0089 -0.586411,0.398248 0.305957,0.974941 1.902102,1.229238 2.244857,1.229238 1.485149,0 z m 25.247525,-4.513878 c 0,-0.84897 -0.45281,-1.263728 -1.00625,-0.921685 -0.55343,0.342043 -0.74992,1.036654 -0.43661,1.543581 0.84874,1.373311 1.44286,1.117238 1.44286,-0.621896 z M 13.75844,84.709054 c -0.329002,-0.329001 -0.563011,0.255777 -0.520019,1.299505 0.04751,1.153409 0.282119,1.38802 0.598184,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 0,0 z m 48.906765,-3.85473 c 0,-1.356215 -3.082898,-1.911382 -4.232156,-0.762123 -0.330986,0.330986 -0.08945,1.422196 0.536762,2.424911 0.842923,1.349734 1.470503,1.547624 2.416974,0.762123 0.703131,-0.583548 1.27842,-1.674757 1.27842,-2.424911 z m 43.564355,0.09971 c 0,-2.007107 -9.940776,-11.875249 -12.685773,-12.593082 -3.422347,-0.894964 -2.536662,0.72179 2.04221,3.727903 4.685203,3.075921 8.056173,6.371341 8.979963,8.778691 0.77225,2.012434 1.6636,2.058775 1.6636,0.08649 z m -47.693353,-7.404219 2.306645,-4.455446 -0.675699,4.455446 -0.6757,4.455445 3.814599,-3.586129 c 2.098029,-1.972372 6.311347,-5.155371 9.362929,-7.073331 5.874539,-3.692229 6.839458,-5.599101 6.818235,-13.474203 -0.0116,-4.303265 -3.763041,-12.649115 -7.037511,-15.656368 -5.956689,-5.47059 -15.534138,-7.597002 -22.017021,-4.888282 -12.757989,5.330628 -18.072962,19.793085 -11.85765,32.265591 2.52515,5.067315 2.685106,5.196865 3.601855,2.917172 0.958373,-2.383197 0.960066,-2.382511 1.654947,0.671085 0.942906,4.14352 1.700115,5.200511 5.327538,7.436733 4.523217,2.788458 6.716499,2.070908 9.376833,-3.067713 l 0,0 z m 8.682689,1.5849 c 1.905993,-1.851076 4.77995,-3.91008 6.386569,-4.575565 2.564998,-1.062456 4.03369,-2.949929 2.295417,-2.949929 -2.10037,0 -13.235677,8.775011 -13.235677,10.430176 0,1.083649 1.30255,0.252787 4.553691,-2.904682 z M 20.090948,74.8078 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z M 152.76422,69.68259 c 0,-0.272277 -1.78218,1.245201 -3.9604,3.372174 -2.17822,2.126974 -3.9604,4.089996 -3.9604,4.362274 0,0.272277 1.78218,-1.245201 3.9604,-3.372175 2.17822,-2.126973 3.9604,-4.089996 3.9604,-4.362273 z M 41.625601,72.476287 c -2.586633,-2.217071 -4.709793,-4.553304 -4.718131,-5.191628 -0.02877,-2.202305 -1.632163,-3.701423 -3.281819,-3.068391 -2.032483,0.779938 -2.195989,3.392952 -0.212309,3.392952 0.792663,0 3.354544,2.00317 5.693069,4.45149 2.338525,2.44832 4.92018,4.450394 5.737012,4.449053 0.816832,-0.0014 -0.631188,-1.816405 -3.217822,-4.033476 l 0,0 z M 24.051344,70.847404 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z m 6.526162,-3.972749 c -0.745512,-0.745512 -5.536063,1.770447 -5.536063,2.907495 0,0.46652 1.378038,0.135607 3.062307,-0.735362 1.684269,-0.870969 2.797459,-1.848429 2.473756,-2.172133 z m 53.127303,0.748085 c 0.952971,-0.0074 1.732673,-0.459065 1.732673,-1.003619 0,-0.544555 -0.940674,-0.990099 -2.090387,-0.990099 -1.852777,0 -2.016491,-0.393899 -1.440284,-3.465347 0.406143,-2.164925 0.261718,-3.465346 -0.38486,-3.465346 -0.56923,0 -1.034964,1.059307 -1.034964,2.354014 0,1.294709 -0.668316,2.90867 -1.485148,3.58658 -2.367441,1.964801 -1.885292,4.298583 0.742574,3.594342 1.225248,-0.328353 3.007426,-0.60309 3.960396,-0.610525 z m 71.134371,-0.722043 c 1.58154,-0.934242 2.87553,-2.079091 2.87553,-2.544109 0,-1.671282 -4.25968,-0.165537 -5.70037,2.015008 -1.76311,2.668563 -1.02958,2.805958 2.82484,0.529101 z m 47.13694,-2.884855 c -0.37294,-0.372946 -1.68483,-0.148769 -2.91529,0.498172 -1.23047,0.64694 -1.45751,0.953686 -0.50454,0.681656 1.92704,-0.550082 2.24796,0.402733 0.74808,2.221031 -0.54153,0.65649 -0.009,0.312431 1.18262,-0.764577 1.19197,-1.077007 1.86208,-2.263334 1.48913,-2.636282 z m -52.1822,2.108229 c 0.67791,-0.816831 1.00979,-1.485148 0.73751,-1.485148 -0.27227,0 -1.0497,0.668317 -1.72761,1.485148 -0.67791,0.816832 -1.00979,1.485149 -0.73752,1.485149 0.27228,0 1.04971,-0.668317 1.72762,-1.485149 z m 37.15543,-0.451808 c -0.32185,-0.520771 -1.23923,-0.695875 -2.03863,-0.38912 -2.04664,0.785373 -1.80547,1.335978 0.5852,1.335978 1.12125,0 1.7753,-0.426086 1.45343,-0.946858 z m -20.13811,-0.719592 c -0.71473,-0.286011 -1.56869,-0.250835 -1.89769,0.07817 -0.329,0.329001 0.25578,0.56301 1.29951,0.520019 1.15341,-0.04751 1.38802,-0.282119 0.59818,-0.598185 l 0,-3e-6 z M 84.05547,61.936777 c -0.329002,-0.329001 -0.563011,0.255776 -0.52002,1.299505 0.04751,1.153409 0.28212,1.38802 0.598185,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 3e-6,0 z m 82.57013,0.721948 c 0,-0.544555 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445544 -1.48515,0.990099 0,0.544554 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445545 1.48515,-0.990099 z m 37.62376,-5.177658 c 0,-1.661518 -0.24856,-1.789209 -1.48514,-0.762936 -0.81684,0.67791 -1.48515,1.832342 -1.48515,2.565406 0,0.777973 0.61827,1.095588 1.48515,0.762936 0.81683,-0.313447 1.48514,-1.46788 1.48514,-2.565406 z M 83.457284,54.18445 c 0,-0.784694 -0.445544,-1.426715 -0.990099,-1.426715 -0.544554,0 -0.990099,0.917384 -0.990099,2.03863 0,1.121247 0.445545,1.76327 0.990099,1.426716 0.544555,-0.336553 0.990099,-1.253937 0.990099,-2.038631 z m 63.366336,-0.931666 c -1.27896,-1.361386 -2.77092,-2.475247 -3.31547,-2.475247 -0.54456,0 0.0563,1.113861 1.33527,2.475247 1.27896,1.361386 2.77092,2.475248 3.31548,2.475248 0.54455,0 -0.0563,-1.113862 -1.33528,-2.475248 z M 82.467185,48.302289 c 0,-0.816832 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668316 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m -1.985115,-5.19802 c -0.0084,-1.2671 -4.736103,-6.714785 -5.323399,-6.134089 -0.649329,0.642032 3.49033,6.834315 4.585742,6.859554 0.408416,0.0094 0.740362,-0.317049 0.737657,-0.725465 l 0,0 z m 50.49997,-0.247525 c -0.81683,-0.527877 -1.9307,-0.959776 -2.47525,-0.959776 -0.54456,0 -0.32178,0.431899 0.49505,0.959776 0.81683,0.527878 1.93069,0.959777 2.47525,0.959777 0.54455,0 0.32178,-0.431899 -0.49505,-0.959777 z m 4.44995,-0.996169 c -0.98866,-1.092447 -2.01229,-1.771531 -2.27475,-1.509075 -0.66527,0.66528 1.80418,3.495343 3.04998,3.495343 0.56227,0 0.21342,-0.89382 -0.77523,-1.986268 l 0,0 z m -95.539062,-4.19679 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.677909 1.485148,-1.678107 1.485148,-2.222662 z m 92.079212,0.795947 c 0,-2.367417 -1.80911,-2.723191 -2.95546,-0.581213 -0.91594,1.711444 -0.77708,2.007928 0.94043,2.007928 1.10826,0 2.01503,-0.642021 2.01503,-1.426715 z M 43.853324,33.703389 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.67791 1.485148,-1.678108 1.485148,-2.222662 z m 29.450539,-0.0051 c -0.341635,-3.033194 -0.613818,-3.235945 -4.743791,-3.533678 -2.40975,-0.173719 -4.148989,-0.08348 -3.864976,0.200533 0.746043,0.746042 8.309556,6.402673 8.668673,6.483162 0.166387,0.03729 0.139429,-1.380215 -0.05991,-3.150017 z m 45.796987,1.732673 c -0.67791,-0.816832 -1.70871,-1.485149 -2.29066,-1.485149 -0.58196,0 -0.19325,0.654147 0.8638,1.453661 2.48363,1.878524 2.96864,1.889227 1.42686,0.03148 l 0,3e-6 z m 5.94059,-0.933056 c 0,-0.721181 -1.00247,-1.579892 -2.22772,-1.908245 -3.82044,-1.023837 -4.13152,-0.702262 -1.76134,1.820687 2.31705,2.466393 3.98906,2.503093 3.98906,0.08755 l 0,4e-6 z m 8.8851,-5.657864 c 5.0656,-7.213134 5.95021,-9.230659 3.73867,-8.526659 -1.72171,0.548068 -10.64357,12.438161 -10.64357,14.184592 0,2.924919 2.06665,1.231484 6.9049,-5.657933 z m -54.828018,2.397173 c -0.586902,-0.586901 -3.56203,0.943932 -3.56203,1.832819 0,0.490907 0.870827,0.348719 1.935171,-0.315974 1.064342,-0.664694 1.796429,-1.347273 1.626859,-1.516845 z m -29.622424,0.529501 c 3.007757,-1.087619 4.641314,-3.761497 2.298018,-3.761497 -0.544554,0 -0.990099,0.445545 -0.990099,0.990099 0,0.544555 -0.58316,0.990099 -1.295911,0.990099 -1.477794,0 -5.628481,2.890588 -4.219928,2.938809 0.505892,0.01732 2.399456,-0.503561 4.20792,-1.15751 l 0,0 z m 54.958912,-1.46755 c -0.71473,-0.286011 -1.56869,-0.250836 -1.89769,0.07817 -0.329,0.329002 0.25577,0.563011 1.2995,0.52002 1.15341,-0.0475 1.38802,-0.28212 0.59819,-0.598185 l 0,-3e-6 z M 59.694908,28.005259 c 0,-1.089109 -0.39099,-1.980198 -0.868866,-1.980198 -1.298365,0 -3.17241,2.559384 -2.422873,3.30892 1.355486,1.355487 3.291739,0.573912 3.291739,-1.328722 z m 21.287129,0.990099 c 0.336553,-0.544554 -0.331763,-0.990099 -1.485149,-0.990099 -1.153385,0 -1.821702,0.445545 -1.485148,0.990099 0.336553,0.544555 1.00487,0.990099 1.485148,0.990099 0.480279,0 1.148595,-0.445544 1.485149,-0.990099 z m 29.207923,0 c 0,-0.544554 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445545 -1.48515,0.990099 0,0.544555 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445544 1.48515,-0.990099 z M 86.427581,28.005259 c 0,-0.544554 -0.694611,-0.990099 -1.543581,-0.990099 -0.848969,0 -1.268219,0.445545 -0.931666,0.990099 0.336553,0.544555 1.031164,0.990099 1.543581,0.990099 0.512417,0 0.931666,-0.445544 0.931666,-0.990099 z m 18.316829,0 c 0.33656,-0.544554 -0.33176,-0.990099 -1.48515,-0.990099 -1.15338,0 -1.8217,0.445545 -1.48514,0.990099 0.33655,0.544555 1.00487,0.990099 1.48514,0.990099 0.48028,0 1.1486,-0.445544 1.48515,-0.990099 z M 53.397761,23.263982 c -2.293369,-2.293369 -3.273717,-0.599352 -1.065339,1.840877 1.180946,1.304931 2.008695,1.63504 2.254066,0.898928 0.213274,-0.63982 -0.321654,-1.872732 -1.188727,-2.739805 l 0,0 z m 41.674343,3.065049 c -0.963333,-0.251033 -2.299967,-0.234524 -2.970297,0.03668 -0.670328,0.271211 0.117854,0.476602 1.751517,0.456424 1.633663,-0.02018 2.182115,-0.242078 1.21878,-0.493111 l 0,4e-6 z M 50.784017,20.160629 c 0,-1.18906 -5.817795,-7.006855 -7.006854,-7.006855 -1.723094,0 -0.911591,1.747528 2.244318,4.833013 3.196159,3.124838 4.762536,3.839805 4.762536,2.173842 z m 99.083553,-7.807387 c -1.32905,-0.443014 -5.95468,4.804941 -5.94174,6.741126 0.006,0.860676 1.47299,-0.172344 3.48946,-2.456779 1.91375,-2.168059 3.01727,-4.096016 2.45228,-4.284347 z m -7.4939,4.754858 c 2.64699,-2.924889 1.22992,-3.38489 -1.49431,-0.485075 -1.27694,1.359238 -1.86755,2.471343 -1.31247,2.471343 0.55508,0 1.81813,-0.893821 2.80678,-1.986268 z m 1.9747,-5.934524 c 2.68184,-2.7227721 4.44726,-4.9364147 3.92318,-4.9192068 -1.79455,0.058926 -11.48794,9.8697018 -9.75161,9.8697018 0.52381,0 3.1466,-2.227723 5.82843,-4.950495 z m 4.99121,-1.055971 c 1.06562,-1.7242011 -0.14804,-2.0893477 -1.506,-0.4531041 -0.78094,0.9409741 -0.85606,1.5090751 -0.19952,1.5090751 0.57909,0 1.34657,-0.475187 1.70552,-1.055971 z m 22.08877,-7.9517764 c 1.71492,-0.5978257 3.11804,-1.51893899 3.11804,-2.04691859 0,-1.07371396 -3.1521,-0.28577416 -6.93069,1.73248789 -3.09382,1.652504 -0.61271,1.8571218 3.81265,0.3144307 l 0,0 z m 6.85154,-0.707599 c 0.59402,-1.78204068 -1.45248,-1.40757811 -2.14309,0.3921386 -0.37003,0.9642713 -0.14875,1.4169139 0.57476,1.1757426 0.64703,-0.2156762 1.35277,-0.9212228 1.56833,-1.5678812 z M 20.090948,0.80296239 c 0,-0.25829297 -1.366838,-1.17644278 -3.037417,-2.04033289 C 13.07504,-3.294728 10.77735,-2.5105441 14.645403,-0.41549494 17.561715,1.1640635 20.090948,1.729987 20.090948,0.80296239 z M 177.51669,-2.5818805 c 0,-1.2146632 -2.78939,-2.1897491 -3.40672,-1.1908861 -0.27491,0.444817 -0.21492,1.0936751 0.1333,1.4419069 0.94359,0.9435791 3.27342,0.7649164 3.27342,-0.2510208 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3784"
+ transform="translate(0,784.36218)"
+ d="m 30.061595,110.24748 c -3.028002,-1.91623 -2.918962,-12.207625 0.161986,-15.288574 2.892806,-2.892806 5.380122,-2.029008 6.063557,2.105759 0.787072,4.761775 0.802973,10.540215 0.03451,12.542785 -0.657319,1.71294 -4.021187,2.05687 -6.260057,0.64003 l -1e-6,0 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3786"
+ transform="translate(0,784.36218)"
+ d="m 50.118347,74.592462 c -5.270942,-3.20545 -6.839578,-11.64359 -3.245566,-17.458823 3.039395,-4.917846 5.720122,-5.336139 9.002245,-1.404685 3.776278,4.523372 4.477791,9.679447 1.982432,14.570755 -2.972944,5.82745 -4.145768,6.477996 -7.739111,4.292753 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3790"
+ transform="translate(0,784.36218)"
+ d="m 77.269166,109.11407 c -1.309679,-0.76282 -1.732674,-2.30682 -1.732674,-6.32456 0,-2.923449 0.270441,-6.020121 0.600979,-6.881491 0.834308,-2.174169 4.068292,-1.961418 5.30478,0.348981 2.014054,3.7633 0.737507,14.00145 -1.732673,13.89637 -0.389257,-0.0166 -1.487442,-0.48424 -2.440412,-1.0393 z" />
+ </g>
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3811"
+ d="m 69.139594,192.18067 c 0.19068,-0.58412 0.338063,-2.39704 0.327517,-4.02871 -0.03055,-4.72761 -2.165352,-7.80395 -5.35278,-7.71359 -2.829967,0.0802 -4.224757,1.85117 -5.323452,6.75914 -0.310039,1.38498 -0.36786,1.41644 -1.004042,0.54642 -0.371282,-0.50776 -0.820797,-1.89506 -0.998923,-3.08289 -0.555915,-3.70711 1.471544,-7.48719 5.471792,-10.20182 5.598625,-3.79933 13.971038,1.83612 13.913701,9.36528 -0.02361,3.09812 -3.736904,8.46539 -6.324961,9.14218 -0.904613,0.23656 -1.005971,0.12417 -0.708852,-0.78601 l 0,0 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3813"
+ d="m 68.800396,189.86775 c 0.218171,-3.86109 -0.81619,-7.47461 -2.379003,-8.31101 -1.450495,-0.77628 -3.833689,-0.56086 -4.831244,0.43669 -0.506638,0.50664 -1.305601,2.10548 -1.775472,3.55298 -1.095843,3.3759 -1.456791,3.72914 -2.367189,2.31667 -2.172529,-3.37066 -1.181735,-8.3045 2.356216,-11.73323 3.808208,-3.69063 6.356321,-4.18204 10.583313,-2.04103 3.18311,1.61228 5.556904,4.81655 6.061632,8.18231 0.273553,1.8242 0.112352,2.73702 -0.850171,4.81416 -1.44283,3.11366 -4.397332,6.23865 -5.898296,6.23865 -1.048338,0 -1.086743,-0.14752 -0.899786,-3.45619 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3815"
+ d="m 55.977384,169.96726 c -0.330031,-3.53422 -1.331573,-5.66019 -3.388938,-7.19369 -2.496196,-1.86061 -5.288569,0.24236 -6.511588,4.90394 l -0.621341,2.36827 -0.78337,-1.82202 c -2.593339,-6.03175 2.241276,-13.61508 8.680039,-13.61508 3.86832,0 6.851837,1.90897 8.669978,5.54739 1.621302,3.24451 1.874093,5.90823 0.71742,7.55961 -0.413522,0.59039 -2.036622,2.06204 -3.606889,3.27033 l -2.85503,2.19689 -0.300281,-3.21564 0,0 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3817"
+ d="m 46.584144,188.46297 c 0,-3.90068 -0.118172,-4.43649 -1.328412,-6.0232 -1.647394,-2.15984 -3.308854,-2.63488 -5.529681,-1.58103 -1.755441,0.83301 -3.67834,3.97169 -3.67834,6.00402 0,1.57105 -0.802789,1.30413 -1.422259,-0.47288 -1.642012,-4.71028 0.827943,-10.53973 5.502814,-12.98743 1.350256,-0.70698 1.444094,-0.67017 3.720976,1.45958 2.598182,2.4303 4.372384,3.46667 6.848292,4.00031 l 1.663058,0.35844 -0.308027,4.68928 c -0.331934,5.05322 -0.878313,6.12303 -4.098751,8.0254 l -1.36967,0.80908 0,-4.28157 z" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3819"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3821"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3823"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3825"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3827"
+ d="" />
+ <path
+ style="fill:#808000;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3839"
+ d="m 97.783858,183.36123 c 1.213522,-1.18081 3.045232,-2.70588 3.588512,-2.98777 0.26729,-0.13869 0.34041,-0.13033 0.53775,0.0614 0.22145,0.21519 0.21721,0.22773 -0.139,0.41194 -0.20207,0.1045 -1.16824,0.8213 -2.147043,1.5929 -3.062313,2.41407 -3.70477,2.73578 -1.840219,0.92149 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3841"
+ d="m 96.655155,184.41578 c 0.169011,-0.31579 2.350639,-2.35144 3.603535,-3.3624 1.09298,-0.88192 1.40982,-1.00296 1.74581,-0.66698 0.23537,0.23537 0.20535,0.26324 -2.361535,2.1931 -2.586669,1.94472 -3.270902,2.36525 -2.98781,1.83628 z m 3.223063,-2.29188 c 2.186822,-1.64445 2.077412,-1.54607 1.826462,-1.64237 -0.12626,-0.0485 -0.4054,0.0686 -0.73221,0.30704 -0.77399,0.56467 -3.173134,2.65442 -3.181469,2.77119 -0.0098,0.13752 0.04568,0.0993 2.087217,-1.43586 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3843"
+ d="m 96.4855,184.6367 c -0.104424,-0.16895 0.84778,-1.16015 2.535143,-2.63894 1.847567,-1.6192 1.734087,-1.53116 2.253047,-1.748 0.41614,-0.17387 0.47024,-0.17054 0.73685,0.0453 l 0.28774,0.233 -0.24641,0.27229 c -0.26032,0.28767 -3.496793,2.74402 -4.62219,3.50806 -0.706972,0.47998 -0.825042,0.52102 -0.94418,0.32824 z m 4.65517,-3.67215 c 0.154,-0.18668 0.14387,-0.19204 -0.10859,-0.0575 -0.28794,0.15343 -0.35885,0.26338 -0.16983,0.26338 0.0597,0 0.18501,-0.0926 0.27842,-0.20587 l 0,0 z" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3845"
+ d="" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3847"
+ d="m 97.725422,186.00533 c 0.134226,-0.13117 0.940097,-0.6115 1.790822,-1.06738 0.850726,-0.45589 1.976416,-1.13063 2.501546,-1.49943 0.96712,-0.67921 2.0769,-1.69802 2.0769,-1.90664 0,-0.0627 0.13921,-0.11397 0.30936,-0.11397 1.35091,0 -2.15595,2.85903 -5.339137,4.35282 -0.554492,0.26021 -1.137628,0.47311 -1.295854,0.47311 -0.285987,0 -0.286245,-0.001 -0.04366,-0.23851 z" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:3.25936007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="rect3011"
+ transform="matrix(0.99992004,0.01264577,-0.00621432,0.99998069,0,0)"
+ y="1.4106648"
+ x="2.3359439"
+ ry="15"
+ rx="15.083"
+ height="127.1652"
+ width="147.36519" />
+ <!-- <text
+ xml:space="preserve"
+ style="font-size:16px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="10.666666"
+ y="54.666672"
+ id="text2895"><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="54.666672"
+ id="tspan2899">Please help me</tspan><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="74.666672"
+ id="tspan2903">find the pieces </tspan><tspan
+ sodipodi:role="line"
+ x="10.666666"
+ y="94.666672"
+ id="tspan2905">of my spaceship</tspan></text>-->
+ <foreignObject
+ x="-1"
+ y="5"
+ height="136.85336"
+ width="158"
+ id="foreignObject47">
+ <xhtml:body>
+ <xhtml:div
+ id="alienQuestion"
+ style="font-size:20px"></xhtml:div>
+ </xhtml:body>
+ </foreignObject>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/capitals1.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/capitals1.svg
new file mode 100755
index 0000000..66d5bc3
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/capitals1.svg
@@ -0,0 +1,788 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="820"
+ height="900"
+ id="svg2925"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="capitals1.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <metadata
+ id="metadata25">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+
+ <sodipodi:namedview
+ inkscape:window-height="818"
+ inkscape:window-width="1440"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:zoom="0.6"
+ inkscape:cx="451.85339"
+ inkscape:cy="495.0624"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:current-layer="svg2925" />
+ <defs
+ id="defs2928">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 502.16385 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="903.70679 : 502.16385 : 1"
+ inkscape:persp3d-origin="451.85339 : 334.7759 : 1"
+ id="perspective27" />
+ </defs>
+<!-- <style type="text/css">
+ .text { display:none;}
+ </style>-->
+
+ <path
+ d="M 237.0797,0.176258 C 234.48671,0.18729 232.0803,1.437348 230.14458,3.072885 C 227.70103,1.934917 225.33348,-0.076312 222.47669,0.890673 C 218.18548,1.080202 213.39642,0.249853 209.73178,2.994949 C 207.3029,4.170487 205.03052,1.091135 202.73122,2.202598 C 200.27131,4.621639 196.63619,6.513341 195.56057,9.970232 C 195.69113,11.914483 194.80139,14.207105 192.69494,14.555475 C 191.43886,15.296598 188.90353,15.883739 189.75078,17.867759 C 189.36697,21.308715 190.31069,25.111112 188.95261,28.3112 C 185.79031,30.571318 183.94408,34.86086 179.97621,35.871004 C 177.41748,35.837098 176.24601,31.884431 173.39437,33.195202 C 171.6652,33.48544 170.13364,36.512671 168.71311,34.408269 C 166.74637,32.324664 163.91014,30.54333 161.01584,31.740395 C 157.79322,32.263494 155.67698,34.916247 153.71435,37.208911 C 151.69667,38.31524 150.0335,36.024243 149.56638,34.377234 C 147.21934,32.068528 143.48484,32.5284 140.57687,31.519578 C 139.30794,32.655502 138.12416,35.188043 135.98402,34.117443 C 132.81654,33.265123 127.8987,33.603684 126.6543,29.753022 C 126.37232,27.949678 128.04347,26.223243 127.46558,24.245533 C 126.8882,20.487184 122.55399,19.324781 119.49676,18.179508 C 116.35168,17.228524 111.26372,17.414464 110.29789,21.232002 C 110.38151,23.499314 112.36987,25.308615 112.69961,27.603846 C 114.56704,33.202905 113.80752,39.721793 109.93038,44.298291 C 105.74607,51.677094 99.225912,57.296046 92.986289,62.94082 C 87.423835,67.911834 79.648796,70.788981 76.446691,78.021467 C 73.110801,81.42447 74.187219,86.68542 73.646478,91.0238 C 73.550249,95.06547 74.506577,99.87615 78.540311,101.75302 C 80.426245,102.85334 80.972806,105.00742 80.843293,107.03969 C 81.1431,109.8258 82.903756,112.07333 84.886577,113.91106 C 86.527134,116.68803 85.975716,120.15789 87.696215,122.96244 C 88.540988,124.82732 89.264086,127.71698 91.520756,128.2513 C 92.444422,127.86241 94.953586,127.7075 93.784462,129.36839 C 92.744643,131.88162 90.758551,134.46595 91.769356,137.3049 C 92.50162,142.63716 90.84787,148.95384 94.7397,153.33375 C 97.56952,156.9545 101.64278,159.61108 106.28748,159.97861 C 109.65771,160.58894 113.07655,160.87818 116.46101,161.40015 C 117.34536,163.7454 114.01977,163.4563 112.65322,163.79018 C 110.92931,164.3583 108.33156,164.62322 107.56312,162.5562 C 105.81909,160.78038 102.30261,162.22608 102.65522,164.8797 C 102.32932,166.78104 101.16783,162.96694 100.31396,162.29642 C 98.916136,159.92376 96.128728,159.47938 93.588209,159.75767 C 89.400718,159.7635 85.067674,159.59748 80.974148,159.88038 C 79.161404,161.49192 78.276473,164.54785 80.12359,166.49197 C 81.849737,172.46614 79.270149,179.11678 82.12564,184.83295 C 82.973927,188.59461 79.096883,191.08496 78.48797,194.58795 C 77.380279,197.70741 78.889692,201.28589 82.034024,202.53744 C 84.030622,203.56447 86.396576,204.07673 87.9485,205.82374 C 85.777537,207.70895 88.084123,210.81291 90.251483,211.38318 C 91.953679,212.57281 89.954182,215.32659 88.34105,213.85117 C 86.225319,211.43279 83.735924,207.64849 79.966569,208.62944 C 77.116945,209.9143 78.693269,213.52145 78.056145,215.87751 C 77.908287,219.02872 75.320536,221.98554 71.946327,221.5815 C 70.031172,221.46838 68.166295,222.16575 67.274002,223.90492 C 64.53651,226.73027 61.037733,229.77117 61.344819,234.07361 C 61.00126,238.21839 60.89729,243.75998 56.361002,245.63612 C 52.840159,247.56511 47.454872,249.47926 47.607073,254.28702 C 47.578934,259.28707 51.939405,262.7288 56.177815,264.56162 C 60.194419,266.79333 63.807635,270.92214 62.942841,275.82338 C 63.188712,281.17019 62.23587,286.42778 60.024837,291.2937 C 57.181998,299.25685 56.360462,308.27355 51.388654,315.34999 C 47.787755,319.05995 42.121411,318.36061 37.610037,319.85729 C 34.001516,322.34742 31.477863,326.24333 29.235556,329.89807 C 27.668441,332.3429 28.750968,335.22975 30.727265,337.01623 C 35.803952,342.16844 37.846574,349.44228 38.355869,356.4743 C 38.752022,361.93725 37.28419,367.30539 34.718209,372.08749 C 32.750749,377.22692 31.99817,383.76271 36.183742,388.05142 C 39.519335,392.20883 44.735302,394.95358 46.756524,400.02762 C 47.566752,403.42897 47.240355,407.23319 46.992052,410.53599 C 40.011924,417.75254 34.186595,426.66619 32.438373,436.65399 C 31.15746,445.42906 35.961523,453.49617 38.107276,461.805 C 41.877126,473.5413 41.361298,486.2219 44.846092,498.04529 C 48.11817,505.40726 56.35966,509.95576 57.865813,518.16583 C 57.869498,524.85932 54.793049,531.06728 53.927173,537.62388 C 53.117648,542.2094 49.211662,545.23286 46.272395,548.50895 C 43.082129,551.41654 39.242603,554.428 34.744374,554.69189 C 28.311727,554.40123 21.830758,554.08915 15.404562,554.30222 C 11.843354,555.76421 9.560221,559.5894 10.170511,563.40774 C 9.8367004,572.65066 13.195791,581.63844 12.51277,590.86722 C 12.098019,594.15439 9.8285822,597.11431 6.650633,598.1153 C 3.7384862,600.55094 3.6851005,604.75657 2.842841,608.18207 C 2.4947483,610.5305 3.7477848,613.45278 6.4936113,613.39078 C 9.6195086,614.58974 8.9495515,618.76729 7.5796521,621.08047 C 5.4766523,624.98609 2.191094,628.39957 1.2464511,632.80988 C -0.1787982,638.50862 0.36922283,644.69417 2.3325369,650.21562 C 3.3580378,653.06591 2.3466108,655.94619 1.4819879,658.6457 C 0.67053438,664.85867 2.1441147,671.09153 2.3051547,677.31066 C 2.6582211,682.92214 2.6724572,688.72566 5.263605,693.82086 C 6.7919496,699.1423 6.8604544,705.33999 11.256598,709.33015 C 15.104917,713.03609 21.002897,714.48861 23.883724,719.12413 C 24.272669,721.97767 24.608868,725.47278 27.756922,726.69694 C 30.361882,728.07648 31.968651,730.4863 33.121819,733.0747 C 35.33277,735.63092 36.866088,738.82082 37.034291,742.29715 C 37.584412,744.29227 36.990952,747.74702 39.834513,748.01246 C 44.549303,748.77752 49.264345,749.37814 53.953339,750.42847 C 56.509401,751.06727 58.554239,753.31489 58.310711,756.02691 C 58.452568,758.51371 60.244588,760.35301 62.35776,761.43842 C 69.796473,766.97945 75.620379,774.15336 81.366698,781.31716 C 84.335618,784.08458 86.407298,787.59304 87.071812,791.60474 C 88.702623,796.85247 90.552037,802.50557 94.818207,806.17879 C 99.527431,807.17574 103.9809,804.51225 108.68451,804.57626 C 117.22464,803.66543 125.49628,801.44942 133.38005,798.15137 C 135.47699,797.37105 138.44573,796.18542 139.88338,798.632 C 143.23711,802.01376 148.96667,802.49006 152.61519,799.33342 C 154.44287,797.73071 156.60407,796.1808 159.21009,796.96935 C 161.9076,797.39558 164.69987,796.68223 167.28364,796.89142 C 173.18651,798.51287 179.46084,797.46795 185.52426,797.75732 C 189.75928,797.87856 194.18686,797.23597 198.10524,799.09662 C 201.57466,800.46688 206.17041,800.23435 208.48867,803.55494 C 212.0019,807.25357 214.46219,811.67967 216.96783,816.06371 C 219.51962,820.37181 224.51948,821.92089 228.40299,824.77078 C 232.04001,827.03874 235.6622,829.81489 237.17128,833.95003 C 238.06993,836.12409 240.11008,837.24982 242.25282,837.75278 C 252.49704,843.51954 263.88856,846.8366 275.48453,848.82286 C 280.93309,849.1561 284.92441,853.16651 288.38646,856.91525 C 293.83577,856.87423 299.46959,855.64524 304.8214,856.6035 C 306.58982,857.99164 309.06097,858.05886 311.01067,859.18838 C 311.2563,862.36704 308.23198,865.44125 309.87224,868.46277 C 313.29213,871.07082 317.56635,872.39083 320.54971,875.59395 C 322.56866,877.10716 324.21957,879.53256 326.60815,880.34805 C 330.51761,880.18947 335.18113,882.15081 338.45016,879.33489 C 339.86343,878.48012 341.46933,878.14057 343.10847,877.945 C 342.11748,879.63087 342.09767,882.46678 344.41698,882.98487 C 349.47433,884.91585 354.54272,881.50022 359.49104,880.67276 C 365.0205,879.06616 371.13765,879.04193 376.24001,876.3603 C 380.50278,873.25769 384.02974,868.90129 388.92357,866.84441 C 393.80925,866.10353 398.28495,863.84592 402.31869,861.07184 C 405.94094,858.74968 410.41416,860.40043 414.36248,859.26547 C 417.51652,858.85784 420.26398,856.81433 423.55583,857.43482 C 427.75843,857.92611 431.97435,858.54871 436.09137,859.3962 C 440.50883,860.8641 444.67492,863.35809 449.4382,863.33199 C 456.31274,864.06036 463.40223,862.41368 470.15198,864.03342 C 474.84265,865.64469 477.71647,869.78706 479.69101,874.08718 C 481.27244,877.16909 483.76942,880.51564 487.58137,880.55588 C 495.34391,881.67226 502.5252,877.18089 510.31012,877.68147 C 512.78876,877.89296 515.99761,877.9467 517.62481,879.94535 C 518.42178,881.53763 517.84196,884.83306 520.51661,884.54359 C 524.35492,884.5874 529.86575,884.41557 531.49505,888.68722 C 531.74397,890.45531 530.42805,893.66997 533.09143,894.12973 C 536.74024,894.71143 538.53949,890.49335 541.02102,888.66123 C 544.2714,885.74788 548.75593,885.273 552.8892,884.76443 C 559.13087,882.98608 564.13529,878.68184 570.18929,876.39198 C 578.56017,872.58126 586.66311,868.19047 594.92997,864.22188 C 606.97621,859.61438 618.20321,853.07681 629.86447,847.56243 C 633.45392,846.89491 636.37109,843.58984 635.71806,839.87318 C 634.88542,836.79618 632.35746,834.07651 629.35868,832.94988 C 627.41354,832.64483 625.01014,832.78365 628.06327,831.28724 C 630.77045,829.28616 634.37844,827.22524 634.99839,823.68844 C 634.08433,822.24968 635.4409,821.01301 636.88266,821.38934 C 638.66997,821.21406 638.84081,823.53054 637.68082,824.45482 C 635.57707,827.71507 637.94039,831.41679 638.87159,834.59949 C 639.35986,836.93833 636.77913,839.46267 638.38743,841.53582 C 641.34227,843.19085 644.55007,840.4943 647.67786,840.62655 C 650.54217,840.16315 654.01563,841.52446 656.45799,839.63937 C 657.73628,836.73217 654.70274,832.54569 658.44694,830.68972 C 665.95173,824.35187 672.94497,817.38954 679.659,810.29543 C 686.86042,804.0913 695.23951,799.29464 703.74765,795.03392 C 708.11079,793.4099 713.97883,791.89378 715.04009,786.68178 C 715.7138,783.29554 711.83418,780.19068 713.95404,776.93977 C 715.80246,772.20753 716.06283,766.91311 719.07646,762.63834 C 721.50534,758.8339 723.49915,754.4923 726.84288,751.44165 C 730.66578,748.51657 735.49241,746.6907 738.05915,742.41614 C 740.69782,738.67973 743.58994,735.05694 747.71162,732.85555 C 749.27224,731.59079 751.49006,730.5102 752.30653,728.63234 C 751.92243,723.03682 753.51966,717.51141 755.9573,712.56453 C 757.09903,706.6647 755.57898,700.00317 759.15007,694.73011 C 762.42189,688.04665 767.22189,682.13668 771.75102,676.32422 C 773.41239,674.34618 776.29715,672.45759 776.40933,669.72562 C 774.48789,667.98622 770.91872,669.22219 769.27795,666.94591 C 767.30066,664.588 769.18609,661.09621 767.64229,658.68468 C 765.33877,657.52528 762.55801,659.19952 760.06603,658.81457 C 757.57399,658.78781 753.6837,658.77259 753.53653,655.55422 C 753.02786,651.86358 754.4656,648.16142 753.60197,644.47432 C 753.66637,641.13039 753.97435,637.78844 753.04176,634.5534 C 752.77491,630.39207 750.7858,626.73091 748.49877,623.30168 C 745.62883,618.3173 746.32221,612.10602 748.14545,606.88313 C 749.11154,605.12609 750.82089,602.99384 749.1792,601.05088 C 748.07255,599.21255 744.86756,598.91739 745.21439,596.24482 C 745.27887,593.01498 747.58646,590.64232 749.24461,588.07455 C 750.65102,586.04949 749.17288,583.50629 746.92856,582.94373 C 744.11314,582.02616 740.75644,580.86643 739.88876,577.70904 C 738.56342,575.03535 738.22894,572.03034 738.03067,569.08409 C 741.02396,570.11532 743.74948,566.88306 742.84599,564.09619 C 743.11349,561.32062 740.73877,558.60313 741.49822,555.99083 C 743.49946,554.55452 743.23143,552.09599 743.06844,549.97674 C 743.90566,550.94992 745.32116,553.51079 746.86311,551.99011 C 748.69034,550.11927 748.86909,547.27138 750.74942,545.39152 C 754.17931,540.50315 759.08128,536.633 761.68859,531.16815 C 764.69527,528.06609 769.44062,529.63915 773.282,529.20678 C 777.42172,529.11093 781.63731,530.06533 785.69977,529.85624 C 787.68875,528.70679 787.35527,525.59483 785.3465,524.58257 C 783.8261,523.93722 783.76748,521.81125 785.39883,521.30925 C 787.35322,520.02174 790.88582,518.72863 789.59914,515.76278 C 789.89459,514.04424 792.23441,514.30638 792.86556,512.71512 C 794.39482,511.39324 795.754,509.47992 795.00331,507.38466 C 795.09007,503.08779 792.73948,499.1433 792.2816,495.00579 C 793.24928,492.94611 796.01411,493.24559 797.68574,492.04421 C 801.79586,490.43906 804.68261,486.05427 809.30533,485.93921 C 811.76835,485.58109 811.85691,482.82139 811.88313,480.88637 C 812.00467,478.22142 813.17786,475.78724 813.80662,473.27461 C 813.2962,470.52806 810.53466,468.74833 808.25853,467.4294 C 805.7293,466.70932 803.26767,465.654 801.37575,463.88329 C 797.15334,461.64135 791.59511,464.46493 787.8719,460.77885 C 784.12629,458.06726 778.97066,458.19204 775.76839,454.60543 C 772.07599,450.73558 771.02503,444.6376 766.11135,441.77542 C 759.90055,438.12347 754.47392,433.019 750.68397,426.90262 C 748.30465,422.0781 742.51722,419.16799 742.15264,413.34904 C 741.19961,409.46941 741.71867,405.47891 742.19174,401.61232 C 741.49709,397.71392 738.58661,394.42947 738.369,390.32525 C 738.01074,387.62228 736.06226,385.60132 733.96118,383.99874 C 731.33963,381.69766 731.76434,377.88822 729.84307,375.19954 C 727.84739,371.9318 726.80208,368.25264 726.75129,364.46274 C 726.58452,362.1633 725.08306,359.6801 722.47243,359.65668 C 719.67246,358.96397 715.74656,359.96712 714.09796,356.99386 C 711.16709,353.96227 706.70417,351.35387 706.6002,346.62836 C 705.79792,344.32004 703.11017,343.26926 701.50855,341.56474 C 697.89037,338.34066 693.12314,337.07236 688.43804,336.40574 C 685.90653,336.09361 684.95464,333.68769 683.70123,331.88544 C 682.09378,329.90436 679.39901,329.82933 677.56931,328.12936 C 675.43298,326.61855 672.09654,326.17277 670.38057,328.59913 C 668.93125,330.0764 667.63223,331.75182 665.72227,332.66481 C 656.39787,322.90153 644.62029,315.8148 634.77593,306.6861 C 629.91513,301.16175 626.84846,293.67479 619.79347,290.42342 C 618.65216,289.62174 616.64316,289.71122 616.05113,288.72182 C 616.02776,282.80298 615.99951,276.88418 615.97262,270.96536 C 610.07121,266.67468 603.88078,262.53458 599.05353,257.06675 C 597.62346,254.30371 596.92104,250.52125 593.57089,249.40304 C 589.67742,248.11914 585.01861,249.33509 581.58491,246.61032 C 574.30923,242.87281 565.73473,247.9668 558.34573,244.37615 C 554.51469,242.71102 551.94849,239.34078 549.77495,235.90708 C 548.54758,233.79483 546.2036,233.33806 544.13528,232.63376 C 540.04702,230.44029 538.58513,225.58193 535.04109,222.76186 C 532.00158,219.58051 529.93384,214.73386 525.13566,213.85117 C 521.56074,213.54799 520.86335,218.10261 520.22136,220.65541 C 519.96401,222.42248 518.60404,225.08088 516.42098,223.95688 C 511.6572,221.67622 510.16256,215.16663 504.69671,213.90313 C 500.67394,211.93337 494.73619,212.02841 492.67146,207.44742 C 490.49284,203.26877 490.82814,198.13002 488.73286,193.99045 C 486.50299,191.26876 482.69933,190.9335 479.76951,189.27531 C 480.43173,184.79584 482.27311,179.7188 479.14143,175.70143 C 476.06934,170.55021 469.62246,167.97851 467.75738,162.03663 C 466.5347,158.45716 463.25145,156.49858 460.10259,154.81455 C 457.8242,153.08327 457.4579,149.92623 455.30034,148.02111 C 452.41135,144.46935 448.13521,142.48694 444.28266,140.24048 C 441.65168,138.03463 438.77811,135.33016 435.07073,136.14884 C 432.08398,136.38416 430.17852,139.26049 430.12456,142.09797 C 429.29984,146.26012 429.22639,150.54335 428.81605,154.77558 C 425.3294,154.21597 421.50839,151.96656 418.25637,154.46383 C 413.73197,157.40944 413.56847,163.43011 410.54921,167.41422 C 407.98498,169.58147 404.06078,169.57325 402.17472,172.66191 C 400.92719,174.28168 400.17792,176.14813 399.37451,177.98756 C 395.50751,177.70209 391.59804,179.72855 387.83342,178.80589 C 383.35316,176.77825 378.24669,178.44359 373.47907,178.37723 C 373.93547,168.95262 374.51872,159.4835 375.3895,150.1124 C 376.12188,146.60749 379.82303,144.30847 379.28886,140.4743 C 379.05068,135.58136 378.181,130.13247 373.91086,127.03032 C 369.65255,123.26393 363.65152,120.88669 361.53232,115.27495 C 359.77988,109.97488 356.60812,105.20759 352.01828,101.94965 C 348.4253,100.38041 349.53634,95.99019 347.59668,93.32293 C 345.82201,91.48918 342.59511,91.04106 342.12711,88.12719 C 340.98101,85.6258 338.28317,84.09241 335.71539,83.64586 C 330.47234,77.598099 322.80047,74.568781 316.32324,70.123933 C 313.29105,66.635696 312.3178,61.612871 308.17119,59.070001 C 301.18184,53.518354 292.32627,49.649278 287.55323,41.77942 C 286.32634,40.026672 285.23209,38.138296 283.92445,36.468513 C 281.24851,36.365126 278.45399,36.899916 275.90325,35.832041 C 278.84398,32.355043 277.60791,26.843849 273.74209,24.583486 C 267.78908,19.726296 260.55312,16.805411 254.03802,12.866856 C 251.13895,10.538254 252.45245,5.856112 248.97405,3.943171 C 245.47889,1.730366 241.28981,0.060261 237.0797,0.176258 z"
+ style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="path3748" />
+ <path
+ d="M 605.20354,701.004 C 601.08337,702.58018 599.56098,707.25102 599.19749,711.27856 C 598.97159,714.58791 598.15419,718.52459 594.60459,719.86454 C 588.95257,722.53132 582.05485,720.81561 576.53405,723.81331 C 574.1191,725.21862 573.79576,728.11186 573.14497,730.52878 C 571.89241,733.12794 568.87713,734.41844 567.34829,736.68573 C 567.05192,739.5567 567.94245,743.24281 564.97986,745.02491 C 563.91777,746.02652 562.13007,746.48985 562.33667,748.31124 C 561.54578,752.94317 562.08937,757.87913 560.68794,762.3527 C 559.39903,763.97307 556.34045,764.0515 556.17359,766.58723 C 554.83965,771.44064 554.36664,776.52536 553.17708,781.38213 C 551.78139,784.01355 548.1709,783.98977 546.38593,786.27909 C 545.0455,787.54777 544.04621,789.52415 541.85846,788.73411 C 537.91672,787.96693 535.63044,792.25815 531.953,792.42308 C 528.27631,792.87673 524.12492,793.71338 522.13916,797.15121 C 519.78681,800.05596 518.11557,804.88284 513.76468,805.20461 C 510.01078,805.02917 505.76466,803.72428 502.45913,806.25673 C 496.1689,809.84341 491.47587,815.37941 485.80179,819.71371 C 480.09111,823.49254 472.89977,823.91797 466.27925,824.61749 C 463.45202,824.99165 460.34629,823.73603 457.68183,824.8315 C 456.29309,826.37821 458.11202,828.49783 458.78099,830.00127 C 459.924,832.21349 462.60061,832.52644 464.06971,834.47282 C 466.23812,835.95841 464.48116,838.9899 464.68239,841.22407 C 464.32827,843.58626 463.6852,846.46071 465.93857,848.13442 C 468.20252,850.39061 470.36402,852.93598 470.58377,856.29177 C 471.26277,858.41487 470.13775,861.58989 472.769,862.64354 C 476.72728,864.4571 479.46452,867.96302 481.06497,871.86598 C 482.65005,875.4106 485.80937,879.04741 490.11988,878.52953 C 496.89089,877.7969 503.38095,875.20764 510.28404,875.52898 C 513.83736,875.68036 518.89962,875.81334 520.21566,879.82848 C 520.53285,881.31403 521.72793,882.86189 523.40844,882.25746 C 527.31496,882.02279 532.18702,883.78954 533.56249,887.68701 C 533.99001,889.29408 533.67425,891.01727 533.77186,892.67492 C 537.37628,889.39784 540.24042,884.79647 545.28677,883.69931 C 548.6917,882.60871 552.49276,883.08466 555.7287,881.30926 C 567.04849,874.5782 579.65103,869.97465 591.01926,863.26703 C 592.98994,861.66403 596.23421,861.84281 597.81047,859.95476 C 597.12053,857.72784 595.31834,855.35288 596.95991,853.04439 C 598.20808,850.98031 600.62178,849.09105 599.79941,846.34187 C 598.57773,842.36709 596.64779,838.59495 596.81636,834.32691 C 596.67208,828.65578 597.67011,822.92288 600.66302,818.01211 C 602.48761,814.73921 602.68986,810.46004 600.28354,807.41279 C 598.44893,804.3104 600.86082,799.79654 597.72714,797.19427 C 595.92859,795.1875 597.37294,792.04513 596.9669,789.55246 C 597.01919,787.64262 596.99303,785.71263 597.30013,783.82413 C 599.34994,783.35501 601.68212,784.11118 603.64643,783.2526 C 604.14103,776.89497 605.9683,770.52452 605.30822,764.13226 C 603.96064,755.34673 604.30136,746.15305 606.49899,737.53006 C 607.45699,734.35336 610.51409,731.84413 609.56894,728.26922 C 609.32475,723.71998 609.68581,719.044 609.09269,714.56805 C 607.7137,711.03013 605.70919,707.50924 606.57749,703.57589 C 606.66476,702.58721 606.61995,700.89368 605.20354,701.004 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptMaldonado"
+ class="dept maldonado" />
+ <path
+ d="M 328.57091,841.10719 C 326.39685,841.6061 323.37627,842.47055 322.77418,844.88707 C 323.45549,848.3429 324.63956,852.7272 321.59652,855.47341 C 319.51098,857.89542 316.75653,859.59909 314.08566,861.2537 C 313.05144,862.94349 311.30729,864.79316 311.56025,866.8651 C 315.08775,868.93164 318.93775,870.74254 321.84507,873.6997 C 324.08052,875.58468 326.20709,878.57094 329.55228,878.00996 C 331.87958,877.87155 334.47618,879.62277 336.51356,877.76314 C 338.74039,876.37691 342.06681,875.03314 344.49549,876.5032 C 345.86095,877.82816 344.21621,881.0698 346.53677,881.37419 C 352.30026,880.97561 357.56734,878.26476 363.29863,877.48229 C 365.4605,876.67329 368.34828,876.97128 370.10311,875.42506 C 370.35994,872.27362 367.62965,869.54561 367.80012,866.33251 C 367.69406,863.17317 367.45442,859.81244 369.30489,857.05812 C 370.25732,855.48297 370.44332,852.3595 367.89169,852.38195 C 365.08862,852.22101 362.03546,851.82796 360.21074,849.40737 C 357.69011,847.36627 356.74178,843.05513 352.98776,842.75682 C 348.91013,843.74879 347.7517,848.82303 343.91975,850.2517 C 341.38936,851.61268 338.94007,849.70847 337.45569,847.77071 C 335.97538,846.45037 335.80928,844.30648 333.92271,843.2894 C 332.40232,842.13499 330.55851,841.05186 328.57091,841.10719 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptMontevideo"
+ class="dept montevideo" />
+ <path
+ d="M 427.75617,749.98684 C 417.17129,749.98404 408.15712,756.17447 399.0343,760.66409 C 394.10574,762.18964 390.0265,758.32451 385.84449,756.50749 C 382.80727,755.28979 379.14842,755.33804 376.04375,755.98791 C 371.76782,758.37883 368.56417,762.72548 363.70445,764.13226 C 361.33251,764.85451 359.38928,766.80813 359.34713,769.34097 C 357.78972,772.34923 358.48418,776.51936 355.06827,778.40755 C 350.37492,781.80038 343.90818,780.11042 339.30118,777.31984 C 337.10203,775.94564 334.78151,775.10729 332.15623,775.54557 C 328.34894,775.41435 324.42781,775.48363 321.06005,777.43337 C 317.23345,778.97181 317.87749,783.71738 317.54013,787.03248 C 317.36452,789.6661 316.29346,792.0736 316.59499,794.81292 C 316.43001,798.68442 316.88394,802.67558 316.44999,806.47267 C 315.00136,810.42488 312.02779,813.62744 308.0796,815.1934 C 306.15892,816.03944 303.76198,817.48689 304.40266,819.97349 C 304.57748,823.67713 306.75149,826.9313 306.49629,830.70269 C 307.09765,833.90951 311.22781,833.69004 313.3529,835.41785 C 316.69619,837.61025 320.1126,840.17811 321.67503,844.00379 C 324.6097,840.46895 330.30314,839.38436 333.97504,842.34115 C 336.75969,844.73053 338.1519,849.53027 342.27102,849.91397 C 345.63698,849.42511 347.63199,846.16252 349.66413,843.783 C 350.91699,842.20647 353.74543,841.92284 355.59168,842.73084 C 358.19743,844.19985 358.57254,847.81286 361.10053,849.49831 C 363.40158,852.18762 367.1714,851.31674 370.14234,852.26502 C 372.24244,855.32349 368.6807,858.50042 368.50672,861.68233 C 367.69309,866.32861 369.52053,870.9739 371.5817,875.02241 C 373.35429,876.47415 375.07113,873.78467 376.51795,873.02634 C 380.64494,870.25189 383.93247,865.75928 388.86717,864.43607 C 394.15285,864.17571 398.21564,860.57498 402.76357,858.43498 C 407.60281,856.29618 413.25366,858.27625 417.99932,855.69267 C 421.04569,854.46378 424.33465,854.60843 427.3505,855.69425 C 432.32813,856.53451 437.39649,856.7623 441.97968,859.13641 C 450.3795,862.64179 459.78336,860.88829 468.63322,861.17356 C 471.55893,861.95163 469.65537,858.35701 469.87716,856.75938 C 469.6333,852.41162 466.24414,849.27149 463.41312,846.3159 C 463.76823,842.51716 464.09249,838.71556 464.38141,834.91124 C 460.0472,833.18718 456.3402,829.53539 456.19013,824.67562 C 455.82013,821.4115 457.22684,817.6943 454.80311,814.93362 C 451.46159,810.18906 446.7616,806.1534 444.14481,801.06223 C 444.43922,795.04622 446.21725,789.20684 446.29777,783.14868 C 442.60499,779.48692 439.68603,775.08738 438.51214,769.99044 C 436.6368,763.39289 435.07442,756.64154 433.3566,749.97387 C 431.48984,749.9831 429.62263,749.9552 427.75617,749.98684 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptCanelones"
+ class="dept canelones" />
+ <path
+ d="M 286.1358,683.20858 C 280.76627,684.44771 277.74905,689.88856 272.59274,691.74257 C 268.11319,694.1992 261.8651,692.68949 258.42153,696.96428 C 254.65673,701.07574 252.59586,707.51747 246.85427,709.36915 C 240.32314,709.53071 233.90258,707.54565 227.43426,706.6957 C 222.60231,705.88766 217.78984,704.95763 212.92456,704.47214 C 214.52086,707.37578 215.65707,710.408 215.98648,713.6816 C 216.94446,718.54242 223.12303,719.48987 225.40776,723.34568 C 225.55599,726.48879 226.97547,729.75599 229.90905,731.34713 C 231.8235,732.89651 233.78455,735.24485 233.63828,737.73789 C 229.60263,742.52584 224.58745,746.72762 218.70819,749.06461 C 215.52282,749.54844 212.47701,751.24354 210.08506,753.32512 C 209.03884,755.75977 208.47762,758.78821 209.19528,761.39149 C 210.13539,763.65227 212.40454,765.07656 213.43485,767.19775 C 213.87535,770.534 209.62614,772.05711 209.75117,775.40075 C 209.15822,778.54642 209.80711,782.04187 209.00387,785.00128 C 205.80521,788.58813 201.68119,791.46068 199.09355,795.46259 C 198.52434,797.83161 201.914,797.85546 203.41722,798.21683 C 206.21417,798.34672 208.71801,799.65876 210.22559,802.01396 C 213.17177,805.53709 216.20563,809.00657 217.90997,813.25801 C 219.16195,815.54031 220.74242,817.64027 223.20771,818.64054 C 227.78151,821.76631 232.81734,824.61744 236.90958,828.35163 C 237.479,829.34864 238.06294,830.23795 238.62375,831.20929 C 238.92129,833.4744 240.79846,835.15279 243.00724,835.44382 C 254.47986,842.14351 267.67498,845.08828 280.65317,847.39403 C 283.94412,849.14966 286.78898,851.63463 289.23701,854.42126 C 294.57557,854.21442 299.91411,854.00484 305.25322,853.81077 C 307.1829,855.91709 310.22062,855.76408 312.43693,857.27895 C 313.69214,857.95939 313.41398,860.67768 315.39417,859.70795 C 318.23575,857.99905 321.14111,855.66392 322.60409,852.60274 C 323.52487,848.4045 321.75179,844.15631 319.11035,840.89936 C 316.1225,837.13822 311.55593,834.9568 307.13747,833.27459 C 304.92594,831.88815 305.9423,828.70803 305.14854,826.5461 C 304.51483,823.38138 302.25332,819.25647 304.96535,816.47937 C 308.15134,814.07278 312.64009,813.07637 314.36046,809.06243 C 316.94466,803.39129 315.4965,796.83456 315.71349,790.8008 C 316.06552,787.85511 312.37772,786.79664 310.81437,784.7074 C 307.93213,781.76471 304.04486,778.28971 304.48117,773.78334 C 305.51639,770.86358 309.89963,771.35588 310.84055,768.27586 C 312.21258,765.26967 310.29851,762.19204 310.31715,759.18331 C 311.01561,756.31757 312.81323,753.1106 310.99447,750.23926 C 309.84092,746.94127 306.55248,743.59737 308.5245,739.97206 C 309.67661,736.60277 312.17301,733.5833 312.68556,730.08715 C 313.14558,724.08545 311.74177,718.2426 310.32648,712.48879 C 308.77376,706.07197 308.29215,699.17838 305.13544,693.30129 C 303.50254,691.9935 301.17552,691.65872 299.55953,690.27272 C 295.28267,687.9198 291.35525,684.59269 286.65922,683.19557 C 286.4847,683.19727 286.30976,683.1883 286.1358,683.20858 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptSanJose"
+ class="dept sanJose " />
+ <path
+ d="M 738.61949,559.74473 C 735.18108,560.20878 733.16134,563.27768 731.94607,566.17448 C 730.48686,568.0916 728.11843,565.49331 726.54193,564.99243 C 724.04755,563.95312 722.03169,566.80063 719.51521,566.75898 C 716.88666,566.64926 714.28684,568.24576 713.82319,570.91558 C 713.25713,574.0009 712.48674,577.75651 709.492,579.41061 C 707.2416,579.85816 704.35805,578.04576 703.0771,580.69114 C 700.03339,583.54357 697.7467,587.41277 694.20857,589.54232 C 692.01383,590.18206 688.78194,589.81192 687.92771,592.5169 C 686.51849,596.62378 687.26812,602.01954 682.98153,604.597 C 681.26752,605.4607 679.03162,605.36501 677.90451,607.22085 C 675.70778,609.85787 672.78992,613.25809 668.90193,612.19575 C 666.2736,611.67311 663.83031,613.07087 662.60801,615.35218 C 659.64751,618.66881 654.54166,617.54077 651.3548,620.52194 C 649.35074,622.44354 649.23467,625.82219 646.82735,627.56218 C 644.82446,630.1857 640.81953,630.56445 639.61741,633.83601 C 638.5496,636.03024 637.46731,638.85353 635.18159,639.98 C 632.10693,640.46284 628.85027,640.14154 625.70796,640.23979 C 622.86666,645.67138 622.17317,651.94754 623.37218,657.93204 C 623.48152,661.12571 624.65474,664.50429 623.81058,667.63433 C 621.7349,671.91166 617.15811,675.10784 617.26803,680.27299 C 616.65945,683.78776 617.41659,688.23233 614.07622,690.57772 C 611.09327,692.83812 608.22015,695.76242 607.84673,699.71803 C 607.48546,703.28002 606.05506,707.10642 608.02587,710.42077 C 609.45019,713.47336 610.42804,716.60794 609.97963,720.0074 C 609.71788,724.35765 610.51987,728.90567 609.41695,733.13967 C 605.67707,738.43961 605.79306,745.33736 605.40168,751.57141 C 605.00359,757.05796 606.00967,762.4915 606.10643,767.95114 C 605.58646,773.39889 605.23558,778.92334 604.22217,784.29174 C 601.96622,784.5813 599.68567,784.4401 597.41791,784.47361 C 597.5535,788.29301 597.15893,792.29311 597.60111,796.00814 C 599.32754,797.76435 600.84487,799.85724 600.34516,802.45082 C 600.16646,804.84 600.40404,807.29462 602.16779,809.06243 C 602.7818,811.19476 603.22194,813.76885 602.58974,815.85817 C 600.32612,820.258 597.63875,824.6275 597.77303,829.73981 C 597.00069,834.63591 598.09343,839.48632 599.8499,844.02653 C 600.48925,846.413 601.70473,849.57417 599.13204,851.31682 C 597.66617,852.79753 596.28933,854.82972 597.45715,856.90225 C 597.98247,858.18522 598.48432,861.13349 600.44993,859.71942 C 610.38961,854.90064 620.13994,849.60247 630.05222,844.79617 C 633.69138,844.53787 634.60036,839.03472 631.61916,837.21046 C 630.37195,835.5862 628.37317,835.11642 626.44072,835.56072 C 624.70996,835.14455 623.99767,832.80219 623.86293,831.32618 C 625.30275,829.14871 628.44541,829.07925 630.07839,826.98774 C 631.36986,825.52113 634.38543,823.98531 631.60932,822.45447 C 630.43283,821.53258 630.97805,819.45412 632.6169,819.62279 C 635.32156,819.22339 638.65658,818.13074 640.72968,820.63596 C 642.77305,821.96816 640.54544,824.19281 639.76138,825.57192 C 638.65808,826.92718 638.68002,828.77898 639.8399,830.05323 C 641.62102,832.80543 641.21464,836.09898 640.65389,839.1688 C 640.18622,841.18899 642.9328,838.85082 644.17105,838.71714 C 647.4878,838.03484 650.97765,838.39862 654.36438,838.30148 C 654.80793,835.55989 653.18814,831.81562 655.88225,829.88439 C 662.96543,823.7547 669.94464,817.58302 676.13803,810.50427 C 682.65283,803.82587 691.0402,799.42303 698.94538,794.64423 C 703.25827,792.19451 708.96603,791.58686 712.27915,787.61702 C 714.25551,784.5719 710.00253,781.70992 711.14072,778.53744 C 712.42863,774.44693 713.14083,770.12516 714.70105,766.14298 C 717.15849,760.89278 720.2236,755.82095 723.70244,751.20784 C 725.61236,748.86734 728.2136,747.5684 730.71607,746.03807 C 733.98592,744.77027 735.60228,741.34865 737.96523,738.97186 C 739.70154,736.56922 741.21255,733.74261 744.08906,732.51617 C 746.21706,731.16092 748.22748,729.63719 750.29142,728.17773 C 749.44564,724.31596 750.09466,720.42452 751.69155,716.85102 C 752.92285,713.95104 754.46199,711.1453 754.2693,707.87535 C 754.43817,702.57815 754.52463,697.10702 757.53954,692.54392 C 760.08299,687.48776 763.94022,683.154 766.94863,678.46761 C 768.55814,676.13464 770.67766,674.36606 772.33987,672.21958 C 772.82082,670.17417 770.05151,670.84379 769.12093,669.81654 C 765.72743,668.34727 766.25527,664.30276 765.59202,661.31301 C 763.41138,660.63998 760.18117,661.2087 757.56675,660.99678 C 754.74141,661.16031 751.25552,659.63462 751.52143,656.32062 C 750.67325,647.78766 752.0596,638.93903 749.83345,630.60169 C 749.02005,627.82687 746.48999,625.95915 745.92098,623.10681 C 743.86777,619.7216 743.73587,615.64619 744.63156,611.84748 C 744.63332,608.87605 745.52311,606.02707 747.36035,603.70071 C 748.05006,601.88603 745.85947,601.37385 744.79566,600.59628 C 742.55146,598.72311 743.0042,595.3265 743.50026,592.76368 C 744.27485,590.22291 746.99178,588.54191 747.43886,585.9183 C 745.75509,584.10254 742.53836,584.44243 740.63459,582.68393 C 737.11543,579.20071 735.29188,573.96145 735.72769,569.05813 C 735.93086,567.07921 738.04232,567.08944 739.4831,566.64209 C 741.89873,565.02008 739.7628,561.6561 739.45266,559.516 C 739.33994,559.34924 738.7781,559.83872 738.61949,559.74473 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptRocha"
+ class="dept rocha" />
+ <path
+ d="M 554.10615,591.4258 C 548.72541,591.08811 545.2632,596.68625 540.02655,596.89429 C 535.87305,596.17013 532.9829,591.22977 528.36768,592.374 C 524.5101,594.07504 519.74796,592.11458 516.30319,594.9589 C 514.62319,596.40789 511.83466,597.00685 510.74203,598.93364 C 512.03979,602.80438 512.59431,607.04187 511.93276,611.11765 C 511.02212,615.36923 506.05254,616.69198 502.78628,618.7164 C 497.52279,620.66262 495.14226,626.2001 493.99978,631.27535 C 493.18573,633.92663 491.24502,636.26218 488.31413,636.61575 C 484.28299,638.00222 478.82493,640.01396 478.5657,644.99389 C 478.21848,648.49325 480.09776,651.64898 482.38655,654.11242 C 484.0349,656.58505 484.85597,659.47813 483.76607,662.35674 C 483.32659,667.27387 481.16969,671.62415 478.90591,675.90856 C 477.08888,680.42459 477.90415,685.58511 476.27582,690.11892 C 473.28411,691.47717 470.45802,693.52671 468.07142,695.76927 C 466.7207,698.21584 465.80026,700.91592 463.96268,703.12125 C 462.38523,705.84564 459.15544,707.97723 459.74078,711.45724 C 459.35627,713.98575 460.429,717.19635 457.61103,718.58992 C 454.00074,722.1734 449.75492,725.20693 446.4679,729.07397 C 444.66705,731.59116 444.8193,734.84275 443.85087,737.63397 C 441.60065,740.5586 438.04857,742.79926 436.77181,746.38881 C 435.89172,748.03723 432.92757,748.6919 434.32859,750.88483 C 436.77662,759.48777 438.11093,768.55371 441.74415,776.71893 C 443.21882,779.29174 446.12526,781.02503 447.04213,783.80913 C 446.84885,789.53758 445.18095,795.09419 445.02854,800.78823 C 444.98478,802.90306 447.161,803.93094 447.89415,805.76313 C 450.64082,809.26797 454.20831,812.30698 456.45183,816.16763 C 456.98934,818.695 456.60345,821.37288 456.72663,823.96124 C 465.03697,824.05427 473.56261,823.71733 481.52293,821.23348 C 488.36504,818.26517 492.78812,811.90275 498.89998,807.85444 C 501.70212,805.92495 504.56175,803.27596 508.22969,804.08752 C 511.62559,804.26667 516.06033,805.0849 518.22673,801.74944 C 520.87608,798.43514 522.66516,793.72094 527.22929,792.65689 C 530.72349,791.62294 534.74346,791.85193 537.46187,789.04585 C 539.66892,787.04133 543.40728,789.06995 545.33911,786.422 C 546.99177,784.35901 549.42376,783.47293 551.67231,782.39529 C 553.5783,779.77349 553.10196,776.1107 554.04069,773.09493 C 554.78208,770.2324 554.891,767.00052 556.36986,764.44401 C 557.65219,762.78271 561.116,762.93707 560.53842,760.27731 C 561.00843,755.76146 560.88675,750.92106 561.98988,746.6392 C 563.71565,744.61739 567.0999,743.38937 566.49066,740.26228 C 566.31015,737.43667 567.41734,734.52211 570.10923,733.2176 C 572.73731,731.76574 572.78625,728.58309 573.70766,726.16436 C 575.9266,722.64448 580.17832,721.40453 584.12032,721.23006 C 587.90648,720.53238 592.13684,720.54586 595.54671,718.64355 C 599.04967,715.82779 597.84644,710.66272 599.40684,706.88815 C 600.13728,703.59439 602.8014,701.25988 605.76623,699.84793 C 608.33203,698.06101 608.32169,694.33765 610.85632,692.48297 C 611.9141,691.17465 613.28613,690.2785 614.72951,689.59934 C 616.81412,685.93161 616.17152,681.3473 616.86094,677.30306 C 617.69298,674.36423 620.43123,672.15869 621.96561,669.46583 C 624.77646,665.25937 622.50655,659.94878 622.4216,655.33541 C 621.56392,650.05319 622.6297,644.74088 625.05369,640.00598 C 628.68647,639.40436 633.02063,640.59343 636.20222,638.38229 C 638.65172,635.71692 639.04422,631.46477 642.69881,629.84885 C 645.49216,628.11858 648.32751,626.15679 649.13032,622.75612 C 650.69509,618.42474 655.73277,617.52734 659.67695,616.62514 C 661.63627,615.81315 659.47126,614.24321 658.36843,613.80643 C 653.77368,611.51948 649.1791,608.88366 645.25712,605.75304 C 642.37224,603.32118 639.70356,600.37162 639.08095,596.56957 C 637.85685,593.32802 633.45744,593.93023 630.82421,594.84198 C 626.54532,596.11023 623.68911,599.76047 619.88505,601.80427 C 618.72686,602.95918 619.35679,604.87112 618.15781,606.09075 C 615.63771,609.67162 611.51828,612.49794 606.93077,611.94897 C 603.85751,612.13656 600.8937,611.29842 598.36004,609.62385 C 596.7479,608.7679 594.73235,608.727 593.1914,607.92228 C 590.54154,603.86731 584.89333,604.69344 580.69513,604.49309 C 578.21664,604.64725 575.77507,604.68828 573.83044,602.93216 C 570.7789,601.06345 566.70839,599.86327 565.25467,596.32277 C 563.20422,593.47325 560.0962,590.97866 556.33062,591.4258 C 555.58901,591.40601 554.84774,591.41495 554.10615,591.4258 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptLavalleja"
+ class="dept lavalleja" />
+ <path
+ d="M 47.816435,673.93418 C 43.68585,674.24069 40.193814,676.77089 37.152037,679.35072 C 29.614085,684.62806 21.213979,689.09382 12.211791,691.41786 C 10.733318,691.91103 7.3402229,691.24319 8.0114861,693.72996 C 8.7404778,697.87766 8.6024679,702.50373 11.505191,705.87499 C 11.963145,706.95025 12.39314,707.92485 13.559579,708.291 C 16.491234,710.41374 19.896673,711.97199 22.626749,714.46164 C 24.581441,715.89275 26.725266,717.73829 26.356829,720.42307 C 26.487262,724.51739 31.222693,725.64728 33.33118,728.52842 C 34.773269,730.54923 35.678799,732.89622 37.322168,734.78928 C 39.394642,737.81089 39.013895,741.65094 39.978424,744.98595 C 42.208676,746.96687 45.722149,746.24536 48.444522,747.06426 C 52.597549,747.91473 58.396461,747.88775 60.129519,752.61068 C 60.841643,754.78242 60.446454,757.83557 62.955906,758.98848 C 69.713443,764.07037 75.8202,769.93579 80.604539,776.85107 C 83.192048,780.65331 87.580144,783.35319 88.444181,788.14224 C 90.082693,793.49058 91.294895,799.39826 95.472468,803.42505 C 98.468644,804.72905 101.82835,802.87421 104.91993,802.77558 C 110.84642,801.98454 116.84095,801.1735 122.65431,799.69375 C 128.15082,797.82217 133.42765,795.34408 139.16367,794.37148 C 141.06473,796.51467 143.03868,799.39295 146.33316,798.962 C 149.5516,799.51411 151.79046,796.89558 154.02838,795.17683 C 158.35561,794.10305 163.10263,794.78489 167.5832,794.87265 C 176.50444,796.27013 185.6547,795.47199 194.6707,795.75097 C 197.53478,796.60411 199.06383,794.34791 200.76263,792.48993 C 203.37736,789.53878 206.61589,786.82165 208.842,783.72021 C 208.971,779.20154 207.99278,773.91045 211.57678,770.39313 C 212.77235,769.10638 212.878,767.29838 211.65528,765.97676 C 210.03399,763.4431 207.07942,760.96856 208.18774,757.62458 C 208.42447,754.92956 209.27558,751.94684 212.11327,750.93508 C 216.6957,748.1655 222.558,747.81344 226.46764,743.85586 C 228.6361,741.81339 231.53562,740.25297 233.02331,737.67293 C 232.64487,734.79469 230.48036,732.23373 228.01169,730.80158 C 225.91869,728.81531 224.91543,726.07374 224.51798,723.33268 C 222.26989,720.03758 217.8866,718.81966 215.55465,715.66896 C 214.88431,712.01266 214.62889,707.52137 211.64221,704.86181 C 206.99064,703.21534 201.75116,703.78929 196.92143,702.77054 C 191.30784,700.85985 185.45307,705.60546 179.9631,703.12125 C 175.36254,700.93026 173.02585,695.88769 168.12518,694.12878 C 165.50008,692.41464 162.36986,694.5929 159.4718,694.58726 C 153.13533,695.48766 147.08417,698.0702 140.87735,699.78616 C 136.06596,701.26237 130.99153,703.15005 125.96081,701.49759 C 118.46674,699.851 111.0111,697.73991 103.54597,695.8602 C 101.29039,694.01273 99.524202,691.71322 97.749275,689.49542 C 94.063707,687.45501 89.469133,688.57304 85.423092,688.27443 C 81.478831,687.93288 78.135444,690.943 74.156774,690.00199 C 69.684341,688.85839 68.96489,683.52522 66.384213,680.35092 C 62.552175,675.93205 55.856059,676.72879 50.891424,674.3628 C 49.904992,674.05518 48.860317,673.87225 47.816435,673.93418 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptColonia"
+ class="dept colonia" />
+ <path
+ d="M 511.55332,551.2497 C 506.61715,552.59818 503.28598,556.94004 499.61968,560.22536 C 496.84006,562.90873 493.94571,567.11965 489.59646,566.64209 C 487.33423,565.77272 485.11031,563.85465 482.5174,564.88852 C 478.69512,566.80546 475.04912,569.2704 470.70155,569.86346 C 467.57264,570.66507 466.53436,574.29381 464.51228,576.44905 C 462.30459,580.43551 458.15486,582.66752 453.88715,583.76207 C 446.05278,586.47637 439.82831,592.41651 432.03499,595.1927 C 428.03291,595.66673 423.92744,594.84531 420.00978,594.7251 C 418.37671,595.7085 418.67424,598.20783 416.93475,599.23238 C 413.31964,602.49239 408.94674,604.89237 404.17677,605.9089 C 398.9842,608.27056 392.89207,608.47194 387.65023,606.15573 C 382.30811,605.0995 376.94966,607.36363 371.67331,607.9872 C 369.08627,609.06592 369.7896,612.83378 367.68234,614.4559 C 365.53336,616.27852 363.31901,619.712 360.01445,618.69044 C 356.06039,617.45469 352.36163,615.12549 348.01541,615.46907 C 344.48841,615.48852 340.96594,615.69136 337.44263,615.83277 C 334.72628,613.55749 335.82632,608.40398 331.80292,607.35075 C 327.26696,606.09251 322.02299,607.33263 317.81493,604.98668 C 316.34414,604.19269 316.26186,602.49177 315.32877,601.37564 C 314.0424,600.18632 311.98605,601.2761 312.38459,603.0123 C 311.99933,607.34737 312.76164,611.90679 312.18243,616.09788 C 311.11435,617.76497 309.55233,619.33612 307.38607,618.92424 C 303.39916,619.13597 299.40374,619.00314 295.41319,619.04117 C 297.56631,620.96192 298.30707,623.54825 298.61115,626.28079 C 300.58286,635.02929 302.28451,643.90482 304.8345,652.50175 C 306.92849,657.64254 312.61288,661.16109 312.5141,667.17796 C 312.67786,673.56728 312.5056,680.06366 311.58641,686.36497 C 310.79272,689.39239 308.15958,691.13512 306.40471,693.49615 C 307.63953,698.01254 309.26476,702.42722 309.95076,707.109 C 311.02604,714.63147 314.20565,721.94226 313.13047,729.65852 C 312.77116,734.68825 308.12244,738.86375 308.69459,744.0637 C 309.36635,746.13654 311.29758,747.55219 311.63728,749.8236 C 312.58524,752.16402 313.11912,754.90334 311.63876,757.144 C 309.76279,761.06914 314.04052,765.40838 311.18075,769.04224 C 309.86253,771.16838 307.28483,771.78554 305.52798,773.32873 C 304.0519,776.93507 307.46735,780.12999 309.67979,782.5506 C 311.61104,784.22001 313.25211,786.60926 315.49886,787.74692 C 317.44935,787.03796 316.54562,784.08629 317.08217,782.52519 C 317.0163,779.44183 319.34701,776.91666 322.25409,776.28469 C 328.00685,774.10867 334.92182,773.67289 340.30402,777.15023 C 344.03598,779.36938 348.80332,780.1849 352.98776,778.88818 C 355.85874,778.07603 357.17965,775.28087 357.61085,772.56362 C 358.37222,769.29309 359.04384,765.40003 362.59224,763.96338 C 365.89208,762.21887 369.37867,760.80371 372.02445,758.0769 C 374.86161,755.15117 379.01502,753.96553 382.97886,755.02671 C 386.65582,755.49374 389.6239,757.7324 392.68803,759.52102 C 396.07006,761.18615 399.95,760.22532 402.86524,758.10649 C 410.60795,753.81809 418.8154,749.19077 427.92626,749.20748 C 430.87239,749.21687 434.24417,748.92591 435.97363,746.19395 C 436.95097,744.4917 437.5371,742.56773 439.26618,741.35376 C 441.02771,739.73568 443.5496,738.32843 443.58917,735.59463 C 444.45078,731.42491 445.95701,727.14024 449.85454,724.88879 C 453.07449,722.05803 456.63791,719.15447 459.23898,715.91578 C 459.60465,712.62193 458.10972,708.72737 460.96336,706.23697 C 463.47889,702.96824 465.78133,699.50489 467.27325,695.70434 C 469.82989,692.95192 473.63174,691.39166 476.09263,688.59915 C 477.1358,683.63821 476.55979,678.25052 479.48166,673.81726 C 481.94249,669.18955 483.20922,663.84509 483.28945,658.60674 C 483.00664,656.13269 481.78284,653.94974 480.03123,652.24197 C 477.99912,649.35 476.75119,645.45545 478.68349,642.17519 C 480.87893,637.41821 486.86065,636.88741 491.06201,634.78426 C 493.36209,633.11239 493.35728,629.7579 494.47721,627.34135 C 495.52988,622.72648 499.22838,619.29455 503.51905,617.62529 C 506.16006,615.63542 510.82469,614.86591 511.13459,610.88385 C 511.38377,607.79014 511.27692,604.53374 510.97756,601.50553 C 509.02765,598.02937 504.96481,594.26109 506.59403,589.932 C 509.47526,586.72132 514.31149,584.26228 514.45821,579.39765 C 514.36865,570.245 513.70894,561.06619 512.96651,551.95111 C 512.77812,551.34509 512.13153,551.1819 511.55332,551.2497 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptFlorida"
+ class="dept florida" />
+ <path
+ d="M 199.27675,554.61396 C 197.6614,556.43492 197.64678,559.56251 196.6305,561.86365 C 195.55567,564.9263 195.39739,568.54312 192.33795,570.40507 C 186.23882,576.35569 179.54295,581.68877 175.04125,589.00745 C 173.53309,591.55308 171.76335,593.89814 170.13619,596.32277 C 169.0754,599.10527 170.25469,602.83913 172.8579,604.3632 C 175.93622,605.16546 177.97697,608.00607 177.88258,611.13062 C 178.44238,614.66793 179.3601,618.28371 182.05672,620.82069 C 183.30871,623.80563 183.06129,627.42393 185.15792,630.1081 C 187.01571,632.4961 188.83876,635.45593 191.83134,636.47288 C 194.12799,636.73392 197.79895,636.81654 198.50474,639.52536 C 198.19652,647.42413 195.15525,655.05693 194.67079,662.97116 C 195.45443,669.91052 201.46308,674.76675 203.26929,681.39469 C 204.46549,686.56174 205.96349,691.73671 207.91294,696.69152 C 209.52058,698.82711 210.36799,701.62741 212.37498,703.40701 C 216.17196,704.77386 220.39644,704.41673 224.33668,705.45546 C 231.50163,706.41746 238.54414,708.52365 245.78128,708.77163 C 248.30322,708.72033 250.61038,706.8515 251.94439,704.8878 C 254.79864,701.40923 256.57415,696.78958 260.58058,694.37943 C 264.95122,692.27325 270.40821,693.31114 274.33169,690.11451 C 278.80014,687.69512 282.07457,682.07758 287.75838,682.79292 C 293.80165,685.38913 298.83751,690.21385 305.14854,692.15822 C 308.07676,692.44686 309.80048,689.20888 310.57885,686.8456 C 311.70186,680.33321 311.69726,673.62709 311.76961,667.02384 C 311.67447,661.19173 306.27084,657.57278 303.99705,652.67059 C 301.39794,642.50575 299.30356,632.19001 296.91796,622.02872 C 295.04196,618.81908 290.40964,618.09953 289.3417,614.20912 C 287.96468,609.5862 289.81314,603.56841 285.63858,600.08967 C 284.54299,598.05228 281.98688,596.97522 280.54849,595.06281 C 277.02577,591.64858 275.22378,586.76916 271.17954,583.89197 C 264.16173,580.51881 256.12289,580.53299 248.8432,578.22861 C 246.03386,576.97938 245.38714,573.41823 243.08919,571.54576 C 241.19739,568.8135 237.27835,569.77301 234.42704,568.79127 C 226.45503,567.42829 218.48057,565.8992 210.64774,564.09619 C 206.72522,561.31153 203.9358,557.07222 199.81325,554.60095 C 199.63953,554.57106 199.44448,554.54658 199.27675,554.61396 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptFlores"
+ class="dept flores" />
+ <path
+ d="M 140.13198,535.2858 C 137.31484,535.61451 135.79957,538.56273 133.09218,539.29949 C 131.46871,540.40634 128.70412,539.49673 127.8974,541.74148 C 126.25408,543.65253 124.96253,546.34679 122.454,547.1321 C 120.38261,546.70139 118.66526,545.17513 116.4546,544.88375 C 113.21254,544.19405 110.47564,542.34257 107.37993,541.41677 C 105.39585,540.85306 103.99593,542.75192 102.00192,542.45593 C 98.303035,542.77491 95.286595,540.17071 92.292762,538.50716 C 89.082277,537.80136 87.394523,541.49925 85.606279,543.43011 C 84.28717,545.1617 82.969404,547.07186 80.58159,547.19701 C 78.955431,547.97921 75.798719,547.87263 75.530737,550.10663 C 75.909049,552.70509 77.008407,557.36308 73.253919,557.88728 C 69.419124,557.46971 65.297163,554.00364 61.477306,556.2766 C 58.890637,558.07707 61.024713,561.52093 61.466125,563.85798 C 62.299888,567.50501 64.968335,570.61594 65.128041,574.40975 C 64.474996,576.07437 62.739596,576.59752 61.137099,575.7736 C 59.541167,575.49636 58.32993,574.56557 57.2639,573.52646 C 54.110153,572.74158 50.295784,574.84652 49.908469,578.23322 C 48.318783,581.65896 52.000828,585.43976 49.229629,588.58111 C 46.530285,591.31021 42.61002,589.15596 39.533535,588.42523 C 35.47496,587.57924 33.046871,591.84112 30.824323,594.41734 C 28.189755,597.81551 25.586876,601.28419 23.033211,604.70092 C 18.561274,605.93306 14.04643,607.15892 10.340634,610.07851 C 8.7542545,610.61587 8.9932241,612.29252 10.118171,613.16997 C 11.318651,616.91332 11.026926,621.15064 8.4040353,624.26288 C 5.1855584,628.70113 2.4056009,633.83792 2.8690067,639.49938 C 2.7800306,642.84037 3.2154146,646.10799 4.5962434,649.15049 C 5.9710444,652.4005 4.8839495,655.73116 3.889651,658.91848 C 2.5034161,664.04552 4.4330229,669.31517 4.413056,674.50571 C 5.0869502,679.78887 4.6063799,685.3994 6.32348,690.45665 C 7.5630733,692.27524 10.143878,690.97555 11.91085,690.80733 C 21.730681,688.20027 31.091639,683.60025 38.97089,677.23348 C 42.778096,673.60977 48.777405,671.96229 53.57389,674.53169 C 57.356769,675.89535 61.68629,675.79858 65.023359,678.2986 C 68.936085,680.76792 69.244137,686.38941 72.952941,688.93687 C 76.820238,690.86469 80.654411,687.78528 84.546367,687.80681 C 89.059914,687.69259 94.353756,686.41261 98.259579,689.27459 C 99.863125,691.21535 101.54488,693.11981 103.74226,694.35344 C 104.17368,696.41183 107.22081,695.65184 108.67534,696.52178 C 116.10626,698.24851 123.44708,700.68452 130.9855,701.74437 C 141.18725,699.62356 150.92115,695.32564 161.19195,693.54581 C 164.37451,693.25311 168.02884,692.24931 170.60726,694.7561 C 174.25849,697.0524 176.63671,701.19017 180.77438,702.64066 C 186.0627,704.00896 191.2308,700.96717 196.55253,702.07544 C 201.39933,702.53258 206.20973,703.46878 211.1188,703.47198 C 209.32788,699.73075 206.25755,696.65312 205.56422,692.46271 C 203.40357,686.38783 203.05016,679.55959 199.02815,674.28488 C 196.91196,670.61498 194.16488,666.69951 193.87262,662.36064 C 194.49931,656.3355 196.40095,650.40392 197.25641,644.36381 C 197.46539,642.39707 198.95592,639.20501 196.25411,638.29139 C 193.46352,637.01661 189.87493,637.61311 188.01194,634.68883 C 184.85167,631.39706 182.12125,627.43224 181.99132,622.80807 C 181.50475,619.7551 177.99519,618.286 177.95427,615.02611 C 176.87083,611.84323 177.56863,607.11128 173.83927,605.48028 C 171.09889,604.94744 169.25214,601.85381 168.93236,599.25835 C 168.98621,594.56893 173.35522,591.54488 175.34579,587.62647 C 180.05237,579.73783 188.06369,574.46004 194.18666,567.7202 C 195.29087,563.32174 197.23706,559.05773 197.79815,554.56201 C 195.38358,553.95958 193.02834,556.0429 190.68357,556.61257 C 187.29459,558.61635 183.4358,556.41269 179.80649,556.24097 C 175.4251,555.86148 172.34974,552.1772 168.56367,550.26384 C 166.63914,549.26131 164.69774,547.05274 162.3898,548.43103 C 159.84387,549.00626 156.94722,550.39078 154.6303,550.45736 C 153.93636,547.28884 154.76928,543.67377 153.28254,540.71535 C 149.78102,537.50866 144.9641,535.85304 140.289,535.27278 L 140.13198,535.2858 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptSoriano"
+ class="dept soriano" />
+ <path
+ d="M 455.10408,427.88981 C 452.85018,432.10384 451.74692,436.86348 450.05322,441.33377 C 443.66023,441.37126 437.09253,440.86137 430.80499,441.20387 C 427.46364,443.64912 424.17742,446.77259 420.79489,448.76368 C 418.61252,446.99452 416.71719,444.25349 413.534,444.52159 C 410.33243,443.1611 410.39586,446.76245 409.4607,448.85741 C 407.88759,452.92107 406.72056,457.27892 405.1058,461.25945 C 402.29615,462.35342 398.89929,462.24002 395.92339,462.8056 C 392.02296,463.3421 387.95112,463.29779 384.60552,465.65196 C 375.09676,470.45404 365.33065,474.90005 355.98276,479.92687 C 351.22106,484.28357 346.71866,489.07121 341.79447,493.16043 C 332.68378,496.3578 323.19006,498.63413 314.42587,502.65654 C 312.58755,503.41637 311.09559,505.20212 309.4797,506.05975 C 306.63811,504.44152 304.54922,501.12006 300.86306,501.55458 C 296.07062,501.00937 291.28126,500.43696 286.48914,499.88978 C 283.76943,502.11963 281.46553,505.14222 278.37635,506.72219 C 275.90014,505.84028 273.79342,503.82267 271.40197,503.08516 C 264.77243,505.03798 256.95213,505.2389 251.85534,510.39022 C 249.80518,511.85043 248.18062,513.972 248.2544,516.62007 C 247.89023,517.62747 248.31562,520.34007 246.55332,519.3998 C 244.62326,519.16636 242.1079,516.83132 241.10928,519.49677 C 239.15548,521.34849 238.77536,524.01536 238.95085,526.58292 C 239.29998,528.79042 236.80326,526.92764 235.67752,526.78167 C 233.39933,525.93837 230.3593,524.30274 228.45659,526.75177 C 227.06281,528.29965 224.07258,529.30018 223.62819,531.16815 C 224.22801,533.77459 225.07639,536.34116 225.40776,538.96177 C 219.33969,537.85473 213.53363,535.40473 207.46804,534.24665 C 201.86567,537.19849 196.66814,540.88594 191.26865,544.19649 C 197.6212,550.69841 203.72146,557.53692 210.68698,563.32979 C 221.00388,566.06251 231.74737,567.26352 242.07821,569.64262 C 244.63929,571.59747 245.96896,574.62514 247.99269,576.98163 C 252.3365,579.62348 257.83546,579.08753 262.63785,580.46277 C 267.86286,581.54151 273.49767,583.70447 276.34813,588.50316 C 279.17637,593.72955 284.13951,597.06442 287.81071,601.54448 C 289.70808,604.6529 288.86438,608.71258 289.73424,612.16977 C 289.94533,615.22054 292.03471,618.55193 295.51788,618.15789 C 300.25775,618.03381 305.15004,618.679 309.80684,617.7682 C 312.38337,616.26327 311.35989,612.62409 311.78268,610.16941 C 311.87752,607.00454 311.95715,603.83925 312.04438,600.67421 C 313.57184,599.38201 315.78333,600.14063 316.42792,601.96015 C 317.92238,605.92831 322.84833,605.65202 326.32995,606.06133 C 329.67228,606.37976 334.46341,606.44207 335.63688,610.3253 C 336.62197,611.80412 335.89256,615.27404 338.05752,615.08313 C 344.52514,615.15579 351.50786,613.89833 357.47594,617.0408 C 359.50017,617.73471 362.17494,619.03697 363.93999,617.09276 C 366.8675,615.25227 368.6856,612.33978 369.64509,609.10429 C 370.11302,606.68019 373.25772,607.40437 375.00188,606.67168 C 378.85113,606.30769 382.69233,604.57119 386.55107,605.15552 C 390.82734,606.69412 395.55315,608.21345 400.08111,606.5324 C 402.93387,605.46348 406.07543,605.07139 408.84813,603.93453 C 411.73469,601.71486 416.0604,600.85865 417.62828,597.19306 C 418.2778,595.59424 419.27851,593.17618 421.47531,593.98467 C 427.04505,594.96301 433.21687,594.9517 438.04108,591.68557 C 444.26796,587.90411 450.3795,583.693 457.52481,581.83965 C 463.25128,579.70907 464.92764,572.9849 469.56312,569.51273 C 471.89704,568.66275 474.48208,568.45537 476.68143,567.14867 C 479.67757,566.11958 482.58188,563.24505 485.91954,564.05719 C 488.09049,565.58504 490.98399,566.56009 493.48273,565.09635 C 496.57396,564.01838 497.50576,560.53225 500.09075,558.75753 C 503.64449,555.35678 507.63179,552.14281 512.06361,549.88583 C 513.28679,548.39191 512.92568,546.08666 514.60213,544.81998 C 517.59671,541.13026 522.93708,541.01471 526.1432,537.7278 C 526.84587,536.42292 529.06908,534.7491 527.8181,533.24645 C 522.96187,532.68827 517.90397,532.31487 513.11553,533.58404 C 508.95685,534.47876 504.40938,533.43383 501.97802,529.75209 C 499.93159,527.85119 498.32524,525.0136 495.4455,524.38771 C 490.88618,521.86873 486.42873,519.15639 483.09315,515.17828 C 481.62188,512.55223 480.11744,509.74548 479.30247,506.90624 C 479.76725,501.38026 481.38664,494.6844 477.33569,490.09582 C 476.13692,488.27758 477.02951,485.92683 479.08909,485.1079 C 480.81751,484.1843 483.28994,482.3717 481.8108,480.15897 C 480.71241,477.041 478.63352,474.18957 477.73887,471.11231 C 478.57538,464.83794 480.49677,458.9039 481.92859,452.79039 C 482.71837,448.17208 482.98579,443.13237 481.27433,438.70992 C 479.56242,437.07206 477.44301,439.63576 475.45143,439.39837 C 471.94391,439.5365 471.226,434.90372 468.04525,434.20263 C 465.41892,433.24363 461.92539,432.70522 461.1363,429.50048 C 459.90057,427.65924 457.28905,427.92893 455.33961,427.64303 L 455.10408,427.88981 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptDurazno"
+ class="dept durazno" />
+ <path
+ d="M 688.63431,477.76894 C 685.13391,478.35265 682.53206,481.37108 680.16824,483.757 C 679.69471,485.08994 678.11576,486.26779 679.05599,487.88762 C 679.64271,489.89576 682.63072,491.83963 681.24123,494.0186 C 679.64848,496.05199 676.67145,495.00707 675.03887,493.525 C 671.52583,491.99059 668.64258,489.17691 665.32972,487.39402 C 662.12923,486.46316 658.47227,487.50206 655.43737,486.09509 C 654.02881,484.14348 651.56049,483.71823 649.24807,483.8999 C 646.41708,483.55508 643.71861,482.38064 640.82125,482.19829 C 638.71411,481.85898 637.06563,480.5635 635.80968,478.97692 C 632.30864,476.80842 628.02856,479.69822 626.21825,482.8088 C 623.95416,486.24763 619.29067,485.08903 615.76326,485.23401 C 612.82816,485.55352 608.9391,484.38291 606.68218,486.80953 C 605.62167,488.98684 604.79365,492.35995 601.91919,492.65473 C 600.18669,492.70021 598.55746,490.62993 597.18986,491.02631 C 595.71529,492.17619 595.46091,493.94515 594.82706,495.48641 C 593.559,497.84835 590.73952,499.67469 588.07513,498.25313 C 584.52062,497.05778 580.50364,495.58351 576.94657,497.57078 C 573.98591,499.33763 570.54191,499.61271 567.152,499.37021 C 561.82235,499.06424 556.81533,501.21752 552.31347,503.78658 C 548.83758,505.24502 545.75595,507.53953 543.31089,510.33322 C 540.05552,512.81426 535.91995,513.90791 532.64654,516.38627 C 530.53616,517.42725 528.20413,519.04603 527.38631,521.36122 C 526.70434,524.06691 527.1693,526.86101 528.70789,529.1808 C 529.88003,531.73021 529.81353,534.83693 527.56951,536.75358 C 525.00495,540.36013 520.64272,541.47892 516.98362,543.50804 C 513.88829,545.24662 513.3457,549.05975 513.83012,552.26287 C 514.08425,561.37051 515.04589,570.50587 515.25366,579.57489 C 514.66711,582.96218 512.81108,586.00833 509.78681,587.7628 C 507.69284,588.69154 506.3451,590.91492 507.18289,593.15335 C 507.81424,594.83774 508.21396,597.45484 510.16629,598.01138 C 513.38536,596.45977 516.26613,593.81097 519.71844,592.62081 C 523.04758,592.36606 526.48974,592.43144 529.72854,591.43876 C 534.43243,591.13255 537.12902,597.36557 541.96315,595.95906 C 547.01325,593.66479 551.8176,589.41529 557.79615,590.55548 C 563.1214,591.22474 565.49137,596.35606 569.11477,599.55712 C 571.53691,600.99244 574.05206,602.50944 576.52094,603.81765 C 581.53918,604.31531 587.0586,603.2316 591.6997,605.49325 C 593.46118,607.20357 595.74753,608.0235 598.05136,608.76145 C 600.8133,610.31535 603.80328,611.54321 607.06162,611.14364 C 610.20913,611.56233 613.21285,610.45472 615.48844,608.33794 C 617.93162,606.66079 618.06724,603.59743 619.11305,601.15479 C 620.05564,599.99024 621.85837,600.39489 622.8554,599.16744 C 626.50097,596.00533 631.29252,592.54354 636.37231,593.62097 C 638.36339,594.11227 640.21163,595.56975 640.21934,597.73862 C 641.16612,602.31116 645.3498,605.23783 649.01254,607.67546 C 652.9115,610.10753 657.06833,612.60003 661.40418,614.39096 C 663.41367,614.51601 663.93214,611.61478 666.06249,611.61125 C 668.86002,610.93988 672.38153,612.43292 674.63321,609.93561 C 676.62785,607.99435 677.87732,605.08495 680.92719,604.597 C 684.37935,603.70296 686.03767,600.17464 686.19661,596.84682 C 686.45577,593.79073 687.36673,589.98688 690.88495,589.33448 C 692.74621,589.09253 694.87873,589.14943 696.07975,587.42507 C 699.00287,584.42019 701.78927,581.3495 704.75519,578.38448 C 706.97675,578.74669 710.03947,579.31535 711.21923,576.81275 C 713.14141,573.59061 712.31063,568.78715 716.04767,566.72004 C 719.22725,565.95739 722.65274,565.47401 725.56053,563.75847 C 727.38466,564.35602 729.28353,566.20604 731.06273,566.07127 C 732.60342,564.52948 732.51725,561.82366 734.7594,560.83584 C 735.91173,559.58121 738.76407,559.83461 738.61949,557.62749 C 738.40128,556.17402 738.41255,554.64556 739.90182,553.88656 C 741.82615,551.35166 738.96242,548.21355 739.0614,545.71121 C 739.51547,543.9205 741.82678,541.87387 743.44791,543.7029 C 744.62328,544.66569 744.83201,547.78651 746.7977,546.8723 C 749.15298,543.50243 751.30334,539.94459 754.54411,537.42903 C 758.00645,534.37184 758.92488,528.84084 763.67752,527.20642 C 769.47865,526.27884 775.501,527.32784 781.37699,527.25651 C 784.88585,528.06708 783.43766,526.39253 781.83968,524.63454 C 780.06391,522.62669 782.99996,520.63979 784.28657,519.3998 C 785.38866,518.30665 787.58784,517.72648 787.19147,515.72383 C 786.46481,513.82402 788.36239,512.79937 789.8216,512.34659 C 791.93854,510.90917 793.51843,508.41795 792.66106,505.79996 C 792.0449,501.94963 790.44487,498.3723 789.33743,494.69404 C 787.51724,493.00135 784.70777,494.34414 782.71636,495.05774 C 780.17044,495.92028 777.78015,495.00757 775.80741,493.44706 C 772.60597,491.3738 768.05577,493.12984 765.2739,490.2257 C 761.08956,487.47902 755.94653,489.23681 751.46908,490.01787 C 742.41371,491.03782 733.45444,486.40534 724.46137,489.06967 C 718.9454,491.2937 712.55743,490.75708 706.95348,488.91379 C 701.20804,485.77262 697.72171,478.96811 690.87188,477.88582 C 690.1389,477.74042 689.3798,477.70156 688.63431,477.76894 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptTreintaYTres"
+ class="dept treintaYTres" />
+ <path
+ d="M 216.27435,413.30274 C 212.08915,414.29275 208.77945,417.50572 204.68093,418.55044 C 199.48046,418.67763 193.65688,418.71812 189.65919,422.51221 C 185.9808,425.01673 182.65545,428.80276 178.09195,429.50048 C 175.14547,429.36491 173.39237,426.58963 170.34556,426.74674 C 167.96113,426.21387 165.82069,426.38928 164.45725,428.64319 C 162.38524,431.58722 158.40559,430.00406 155.54626,429.52647 C 152.57294,428.79159 148.52426,427.61331 146.42595,430.64356 C 144.43341,432.81121 142.14567,435.4228 138.96742,435.54052 C 135.35815,436.79997 136.68639,441.50576 134.02124,443.60692 C 129.6133,447.40252 123.68224,448.36224 118.07046,448.85462 C 113.416,449.82727 108.43085,449.19505 103.87312,450.59519 C 101.36024,453.43868 102.34125,458.46026 98.874604,460.51906 C 96.083758,461.11936 93.35707,460.43719 90.99735,458.96034 C 86.388746,457.83807 81.171906,459.86088 76.917755,457.32368 C 74.19668,456.13981 70.766787,457.60721 68.242297,456.01174 C 66.165805,453.40908 65.498939,449.4395 61.987611,448.19215 C 57.542353,446.87663 55.928168,442.01474 52.330782,439.61917 C 46.663602,437.75112 40.626901,438.76945 34.87523,439.73611 C 33.367068,440.95868 35.179848,443.37317 35.217907,444.96991 C 36.238002,449.29029 38.334343,453.27205 39.213167,457.59066 C 43.62141,469.81674 43.679112,483.09494 46.507922,495.62927 C 48.789045,502.17204 54.714326,506.38359 58.245259,512.13877 C 58.745716,514.27967 60.706274,515.89222 60.208033,518.20477 C 59.648992,525.84542 56.963796,533.09956 55.667511,540.63741 C 54.615178,543.38431 51.869432,545.28275 50.185741,547.69515 C 47.634211,551.25901 43.922973,553.72811 39.914776,555.56058 C 36.723979,558.09469 32.552525,556.50405 28.820725,556.76279 C 24.211373,556.94191 19.253387,555.74755 14.854982,557.39368 C 11.439028,559.9228 12.129546,564.84483 12.648438,568.51672 C 13.369184,576.34954 15.60668,584.21364 14.671795,592.11421 C 14.174556,594.89563 12.515401,597.32604 10.091997,598.8557 C 8.2666922,599.71524 6.3827314,600.95541 6.3445459,603.24078 C 6.095656,605.47021 4.522927,607.80586 5.1196484,610.03952 C 7.1726504,612.20015 10.007669,609.48516 11.824802,608.38682 C 14.992956,605.86422 19.047836,605.31239 22.692994,604.07743 C 26.845562,598.89565 30.535527,593.17394 35.136932,588.43825 C 37.972528,587.5853 40.988392,587.83288 43.681535,588.89284 C 45.508308,589.24297 48.466885,590.06214 49.138013,587.60693 C 50.429739,583.71144 47.479533,579.41473 50.145592,575.78661 C 51.674639,573.58009 54.619575,572.50115 57.21156,572.64319 C 58.996156,574.09217 61.64241,576.27638 63.989651,574.95529 C 65.039263,573.30105 63.420185,571.25512 63.060587,569.55172 C 61.386114,566.00024 60.119851,562.06383 59.436027,558.23797 C 61.245086,552.91146 68.027195,555.35674 71.749111,556.88708 C 74.197851,557.93022 76.31697,555.08744 75.34754,552.88635 C 74.898289,551.25291 74.284863,548.09143 76.721458,547.74257 C 79.759216,546.54061 83.593219,546.08571 85.273683,542.89353 C 87.068587,541.02307 88.573568,537.55031 91.59927,537.61087 C 95.183923,539.33557 98.775944,542.35197 103.09475,541.4578 C 105.82693,541.06584 108.81008,540.46121 111.20079,542.27407 C 115.13335,543.99549 119.37959,544.81824 123.18676,546.8723 C 125.32456,544.82003 126.45812,541.99787 128.53856,539.97494 C 130.47499,538.83067 133.0086,539.38765 134.76708,537.7278 C 136.97862,536.25715 139.08065,533.84425 142.02934,534.7922 C 146.39031,535.67984 151.03296,537.3882 153.9237,540.88419 C 155.53298,543.4289 154.13197,546.77421 155.32383,549.37923 C 157.12342,550.03427 159.27391,548.3104 161.17286,548.0933 C 162.86995,547.68388 164.77,546.4051 166.2499,548.0933 C 170.18944,550.24392 173.64439,553.40551 177.77791,555.12052 C 181.33266,555.89257 185.0269,556.45512 188.61239,556.78316 C 191.50552,555.39815 194.99165,554.78168 197.54952,552.92535 C 197.6459,550.89241 195.24715,549.52783 194.16048,547.9504 C 193.25986,546.70034 191.27946,545.30831 191.13779,543.96269 C 196.30829,540.12142 201.84457,536.6352 207.44188,533.4673 C 212.89353,534.53948 218.22275,536.80287 223.71977,537.8187 C 224.97589,536.38165 223.19653,534.12736 223.17095,532.38603 C 222.53674,531.08797 223.11906,529.88202 224.37402,529.27171 C 226.44465,527.56829 228.47455,525.82872 230.66799,524.33575 C 233.07854,525.08672 235.38437,526.21474 237.79936,526.85569 C 239.41584,525.37146 237.18878,522.81985 239.02936,521.30925 C 240.18378,520.1299 240.9294,517.81722 242.56235,517.51636 C 244.28924,517.43398 247.4635,520.62554 247.37827,517.72938 C 247.7175,515.3181 247.65809,512.53602 250.07321,511.17756 C 253.18248,508.80298 255.81869,505.41727 259.99932,505.13578 C 263.7899,504.2035 267.58274,503.28007 271.37579,502.35776 C 273.18828,497.31328 275.27863,492.28322 276.91082,487.22519 C 276.58192,484.10844 275.89051,481.02371 275.99486,477.88582 C 278.16064,474.42345 281.13612,471.30593 282.71225,467.5706 C 285.10119,457.34397 288.54373,447.22782 288.38646,436.61866 C 288.33361,435.14223 285.66835,435.73047 284.61794,434.72221 C 280.51699,432.89334 277.70174,429.36008 274.43771,426.48695 C 272.30826,424.99968 269.91298,423.29707 267.29323,423.26561 C 263.12483,421.46413 258.35071,422.77682 253.9464,422.36935 C 249.27897,422.51159 244.69787,420.46784 240.06311,421.70688 C 234.07318,422.9793 228.94113,419.19836 224.11232,416.32925 C 221.59905,415.2437 219.05484,413.53397 216.27435,413.30274 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptRioNegro"
+ class="dept rioNegro" />
+ <path
+ d="M 613.38176,290.98195 C 610.65138,292.09719 610.03973,295.59755 608.78614,297.96042 C 607.45125,301.65445 607.35897,306.13852 609.75146,309.46273 C 611.67156,312.20316 610.64691,315.64739 609.18674,318.33096 C 605.49148,327.04226 602.78163,336.32735 597.61417,344.29027 C 596.95957,346.32447 600.06633,346.02074 601.2911,346.53744 C 604.66472,347.33268 604.1788,351.85823 602.6258,354.05827 C 601.0245,355.90748 597.50207,357.03846 598.01983,360.02039 C 599.06928,362.88876 598.87579,366.62205 596.16174,368.43749 C 592.05707,370.14541 587.18789,369.58713 582.81939,370.45954 C 580.69592,370.60904 578.68847,372.06562 576.65179,370.85351 C 574.36384,370.142 572.6266,367.78472 570.25318,367.61915 C 567.11364,369.1678 568.79711,373.8218 566.15752,375.80245 C 564.16824,378.62272 561.45207,381.22628 560.36082,384.54429 C 560.26891,387.02961 562.40077,389.07207 561.72168,391.67544 C 561.28056,394.99424 559.12004,397.94495 557.4821,400.85893 C 555.53709,402.70891 555.54957,405.86203 553.55657,407.78225 C 552.6257,409.2691 551.03187,409.56962 549.46091,409.8216 C 546.37842,411.1024 544.67769,414.2652 543.02302,416.8748 C 541.02993,419.22207 537.22742,417.62111 535.38131,420.20011 C 533.47037,424.80538 530.78221,429.14136 526.39703,431.69824 C 523.91459,433.89958 521.12668,435.56513 517.73036,435.78285 C 514.54795,436.25399 511.28169,437.71617 508.32127,435.76476 C 503.74323,434.40253 499.31736,431.45284 494.3987,431.81259 C 491.00351,432.67442 488.17947,435.05082 484.7157,435.78734 C 483.17044,436.00809 481.51984,437.3008 482.34966,439.00886 C 483.78341,444.22523 483.54457,449.68201 482.21386,454.84503 C 480.67496,460.36361 479.03218,465.96145 478.47412,471.63796 C 479.78916,474.94777 482.10001,477.92489 483.06697,481.30204 C 483.41895,483.42323 481.4095,484.7602 479.69101,485.36769 C 478.06422,486.29199 476.94066,488.37815 478.29091,490.04385 C 481.85414,494.78457 480.78638,501.14986 480.10912,506.64841 C 480.36612,509.33094 482.33685,511.77906 483.4857,514.25601 C 484.84449,516.88247 487.62248,518.42848 489.84508,520.03629 C 490.51231,521.21329 492.21756,521.21448 493.12946,522.27046 C 496.24216,524.04566 499.68403,525.3959 501.77942,528.46765 C 503.67502,530.67065 505.80767,533.45765 509.13255,532.93471 C 514.51345,533.06555 519.76684,531.10276 525.16184,532.18132 C 526.50423,532.55325 529.12222,532.1984 528.39385,530.24593 C 526.7913,527.19157 525.12641,523.31086 527.16386,520.06228 C 530.89367,515.05853 537.48833,513.74837 542.32953,510.19036 C 545.59738,506.68257 549.60947,504.02422 554.04242,502.04801 C 558.9831,498.94474 564.88151,498.89595 570.52796,498.72074 C 574.34403,498.39416 577.82067,496.0555 581.5272,495.62125 C 584.95175,496.31552 588.31661,498.40173 591.86982,497.75953 C 594.86688,496.6639 594.28547,492.58778 596.85523,490.94014 C 598.63585,489.37352 600.14302,492.52992 602.14162,491.78442 C 605.21756,491.41973 604.7442,487.58643 606.3158,485.78334 C 610.11568,484.25812 614.5047,485.11734 618.53664,484.62976 C 620.93529,484.31764 623.95471,484.97181 625.44625,482.58796 C 627.50076,479.70844 630.924,476.24823 634.81521,477.85983 C 637.23757,479.07016 638.94704,481.85383 641.98586,481.61377 C 645.38112,482.25494 648.65105,483.49584 652.19225,483.31536 C 654.69132,483.2189 655.62528,486.45057 658.25064,486.21201 C 661.71684,486.65406 665.76774,485.83817 668.4047,488.69296 C 671.12984,490.73531 674.23049,492.37387 677.04088,494.1615 C 678.35811,494.43235 681.41902,494.73653 681.07111,492.66771 C 679.93138,490.1405 676.99972,487.44357 678.93824,484.53637 C 680.95575,481.41435 684.25646,479.45073 687.05102,477.09348 C 691.16214,476.70314 695.27632,477.99015 698.17259,480.9543 C 702.20853,484.30356 705.97027,489.16381 711.72546,489.37431 C 716.27875,490.20862 720.98241,489.60774 725.27266,488.10846 C 730.86525,486.72369 736.81901,487.20261 742.06089,489.51131 C 745.47186,489.96234 748.85093,488.63985 752.31887,488.90232 C 756.7153,488.57083 761.70077,486.63873 765.60102,489.69316 C 768.3934,492.69086 773.32124,490.30547 776.27847,493.09637 C 778.43026,494.8631 781.50022,495.19687 783.90713,493.70684 C 786.47674,492.58129 789.65629,493.92873 791.88905,491.96628 C 797.04476,490.38573 801.15952,486.8168 805.72002,484.12071 C 807.07952,483.95956 808.98623,483.69166 809.17448,481.92553 C 809.62993,478.93611 810.29884,475.97475 811.4513,473.14473 C 809.66058,470.96026 807.31735,469.00326 804.38532,468.80627 C 801.60437,467.56599 799.59136,464.36965 796.11586,465.14669 C 792.56174,465.3842 788.64939,465.02179 786.06615,462.35055 C 783.68159,460.32679 780.38716,460.90853 777.9272,458.97332 C 773.51925,456.72951 770.91989,452.43371 768.91158,448.14019 C 767.74287,445.62989 765.37167,444.19243 763.06251,442.93148 C 757.34503,438.34285 751.29555,433.48047 747.89686,426.87663 C 745.95406,423.56021 742.56658,421.39263 740.85706,417.93992 C 739.46212,412.91547 738.80435,407.69058 739.73174,402.50857 C 739.65001,399.29019 737.16687,396.75181 736.69105,393.56041 C 736.23811,390.68458 735.31219,387.76439 732.71916,386.11262 C 731.05779,384.68912 729.54033,382.88437 729.63003,380.59552 C 728.23408,375.86068 724.37634,371.93467 724.68879,366.75026 C 724.52628,364.90449 724.57142,361.74097 721.92287,361.86488 C 718.88017,361.75147 715.49582,361.94193 713.27362,359.44884 C 710.33559,356.41903 706.03177,353.98409 704.76829,349.7458 C 705.06609,346.51736 701.67835,345.03103 699.71743,343.13423 C 696.31324,339.89776 691.44356,339.44489 687.1426,338.38013 C 683.83866,337.74625 682.97094,334.11672 680.45612,332.46996 C 679.17034,331.85964 677.69915,331.75404 676.81845,330.52156 C 675.5434,329.61117 673.39437,327.93557 672.19938,329.85911 C 670.30578,331.9976 668.2455,335.44778 664.95022,335.04185 C 662.15415,333.10909 660.38898,330.04455 657.53098,328.11853 C 649.13103,320.91187 639.72394,314.68353 631.88413,306.90691 C 627.62316,301.35347 624.10482,294.32642 617.0325,291.85225 C 615.82908,291.48646 614.63978,290.95135 613.38176,290.98195 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptCerroLargo"
+ class="dept cerroLargo" />
+ <path
+ d="M 360.89117,211.53905 C 356.65761,211.34997 353.52368,214.65993 351.73158,218.08569 C 350.11845,221.10288 348.66891,224.34293 347.34804,227.43803 C 348.01402,230.25106 349.0839,234.22549 346.01337,236.03698 C 343.52333,237.92125 342.39714,241.65253 339.18293,242.42775 C 336.28976,243.73248 333.7638,246.01933 332.98623,249.19306 C 332.28298,251.84802 330.40313,253.69548 327.83815,254.61176 C 325.59948,255.34252 324.80997,257.72313 325.16677,259.87231 C 325.1192,262.24794 325.9724,264.95527 323.62804,266.51121 C 321.59716,268.65958 318.84471,271.86715 320.9161,274.88816 C 322.28859,276.84919 323.9964,278.67466 323.80793,281.27891 C 324.43036,288.10936 325.19751,294.99222 326.38568,301.68519 C 327.99328,302.95368 330.23334,303.82511 331.07014,305.94569 C 333.15456,310.63589 331.9772,316.14731 332.84972,320.90943 C 334.98761,322.89369 338.13306,324.78796 337.87441,328.13151 C 337.79716,329.69087 339.04086,332.31309 336.78837,332.7817 C 334.49825,333.06285 332.43866,334.60716 331.27951,336.53563 C 330.58908,343.17157 330.60604,349.98535 329.45053,356.5078 C 326.48001,362.73358 323.84393,369.12022 322.92969,375.98788 C 321.96081,380.48343 321.36491,385.16177 319.97396,389.49323 C 316.1243,395.34398 310.74177,399.8266 304.80812,403.55274 C 300.72237,405.50812 299.30402,409.9909 296.85954,413.47727 C 292.16402,421.29931 290.09439,430.57668 288.88172,439.59115 C 288.71645,449.4732 285.58301,458.87078 283.32253,468.42956 C 281.13441,471.89961 278.37254,475.22297 276.54444,478.79507 C 276.66428,482.7874 278.58944,486.99777 276.4205,490.71743 C 275.21373,494.49673 273.20791,498.1978 272.44878,502.03304 C 273.84334,504.23712 276.65603,505.04924 278.6773,506.56632 C 281.16506,504.11289 283.66267,501.66935 286.14892,499.21434 C 292.25543,500.15327 298.65729,500.0972 304.55969,501.72131 C 306.30154,502.73876 307.733,504.20999 309.34884,505.41028 C 313.40331,501.80415 318.48288,499.96265 323.60606,498.4134 C 329.79069,496.31711 336.11838,494.47354 342.23179,492.26505 C 347.14363,487.82714 351.67209,482.84684 356.82557,478.74943 C 367.53335,473.5563 378.13895,468.03457 388.91574,463.06154 C 394.08377,462.24243 399.381,461.93044 404.46464,460.7269 C 406.86875,455.20354 408.39266,449.25528 410.81092,443.76279 C 413.51151,443.76131 416.81144,443.42258 418.45263,446.06189 C 419.37604,447.25783 420.97112,448.58885 422.22114,446.99712 C 425.31978,444.9604 428.08151,442.11604 431.26285,440.42132 C 437.36499,440.56099 443.46699,440.70945 449.56905,440.85318 C 451.35746,436.18322 452.6084,431.09455 454.81621,426.72077 C 457.04248,427.1033 459.81573,427.18663 461.72516,428.46135 C 461.90077,431.81538 465.9768,432.74749 468.56865,433.74799 C 470.10679,434.40913 471.87138,435.28659 472.20632,437.03431 C 473.62901,439.25768 476.51897,438.73199 478.46908,437.63033 C 483.53142,435.3664 488.8501,433.61617 493.79677,431.13714 C 497.9578,429.87741 501.60502,433.23049 505.49555,434.10217 C 508.49994,435.01716 511.42313,437.07164 514.61532,435.68221 C 518.04203,434.72899 522.14849,435.23135 524.63995,432.28116 C 528.7722,429.20762 533.0007,425.52126 534.3476,420.39497 C 536.05343,418.12734 538.97286,417.58499 541.59677,417.21252 C 543.87919,415.51226 544.62145,412.34838 546.97473,410.66588 C 548.78285,408.54984 552.42153,409.34038 553.66125,406.63917 C 555.9201,402.08862 558.71206,397.7262 560.67488,393.07829 C 561.38445,390.81583 560.89487,388.4095 559.90283,386.3628 C 558.82415,382.42782 562.79859,379.6945 564.65275,376.7247 C 566.61272,374.70683 567.48884,372.06904 567.76702,369.37271 C 568.16635,367.07923 570.90535,366.58781 572.62157,367.83998 C 574.91079,369.40961 578.10372,371.65947 580.87831,369.80137 C 582.1411,367.37657 580.33861,364.60247 579.34733,362.37146 C 577.34569,359.2657 574.6121,356.6595 572.20285,353.79848 C 569.28241,350.81999 567.31948,347.11839 564.28637,344.18636 C 563.446,342.10003 561.66909,340.53493 560.77956,338.41908 C 559.10064,335.72733 557.20771,332.85873 554.17155,331.63865 C 552.81258,330.31352 550.6049,329.98223 550.33762,327.83277 C 547.54879,322.04737 540.39976,320.46805 534.54637,319.77298 C 529.35929,319.28775 524.01471,319.13384 519.35912,316.50536 C 516.7759,314.90501 513.81923,314.21617 510.72939,314.29175 C 503.45946,313.75395 495.95057,314.87653 488.83754,313.36262 C 480.84589,309.88596 471.84173,309.33839 463.24304,310.24517 C 459.14116,310.80521 455.23522,312.80748 450.98225,311.84286 C 447.23939,311.67804 443.84237,308.53429 440.06925,310.14126 C 438.0139,311.37273 435.41965,310.75212 433.93235,308.90726 C 431.40928,305.90467 429.11393,302.21338 429.70608,298.1521 C 429.37495,289.94507 430.3991,281.50102 428.44966,273.45931 C 427.73778,269.75737 423.90914,267.61952 420.57242,266.61392 C 416.19636,265.44851 411.80387,262.87131 409.07061,259.21 C 407.60263,257.04794 406.35262,254.69217 406.07409,252.02689 C 404.53432,245.78965 405.76231,238.31252 400.87932,233.32221 C 396.61328,230.37571 391.7142,228.00136 386.81279,226.45084 C 381.98037,223.98344 377.25349,221.25726 373.08651,217.72199 C 369.43368,215.11197 365.82676,211.16404 360.89117,211.53905 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptTacuarembo"
+ class="dept tacuarembo" />
+ <path
+ d="M 79.652527,252.59842 C 74.953693,252.702 71.67173,256.37282 68.464768,259.21 C 66.561661,259.61754 65.916915,257.58286 64.185912,257.3785 C 61.100705,256.61567 57.535938,258.44684 56.426452,261.37923 C 57.137694,263.03495 59.590039,263.31344 60.666033,264.89933 C 63.511262,267.47044 65.959876,270.92374 65.389743,274.95309 C 66.095336,284.14408 61.672352,292.43262 59.468608,301.12091 C 57.932262,306.38681 56.824444,311.98252 53.704746,316.62296 C 49.629305,320.8689 43.315612,320.39907 38.159617,322.36424 C 34.87732,324.38524 33.201965,328.19339 31.015134,331.22298 C 30.567397,334.82867 34.416807,336.96704 35.987481,339.79596 C 37.46671,341.51901 38.127333,343.58164 38.51289,345.74509 C 39.460794,348.10576 40.572514,350.42205 40.344808,353.08407 C 40.455849,359.30348 41.105506,365.99817 37.511015,371.41181 C 35.899136,375.31296 34.427195,380.12162 36.393105,384.15461 C 39.660318,389.76796 45.610764,393.0334 49.308144,398.40393 C 49.308099,402.86363 49.308144,407.32327 49.308144,411.78296 C 45.385579,415.56629 41.590843,419.49315 39.390164,424.56474 C 37.099525,428.4034 35.472663,432.71167 34.718209,437.11224 C 34.928237,439.49814 38.130054,438.41281 39.661408,438.37465 C 44.139329,437.87225 49.124569,437.39572 53.207507,439.51526 C 56.417865,442.02568 58.206363,446.3371 62.353994,447.56865 C 65.8353,449.17731 67.302474,452.93761 68.909659,456.12867 C 72.443818,456.08253 76.287867,455.47059 79.37776,457.59644 C 83.228809,459.16066 87.644458,457.01493 91.507654,458.29787 C 93.819971,460.14187 98.199868,461.56779 100.06533,458.40179 C 101.54878,455.57081 101.13726,451.15825 104.60588,449.75087 C 112.12151,448.34163 120.158,448.98688 127.46558,446.52952 C 130.75462,445.10534 135.17935,443.36311 135.31666,439.16457 C 135.677,436.32408 138.39821,434.62096 141.07411,434.39745 C 144.84346,432.98297 146.44295,427.63505 150.88796,427.86382 C 154.94042,428.14099 159.15839,430.69231 163.22725,428.92895 C 165.11623,427.28702 167.18419,425.43588 169.96606,425.91543 C 173.10369,425.68852 174.92129,428.72042 178.02651,428.57827 C 181.76345,428.72594 184.39985,425.41546 187.35622,423.65527 C 190.7308,420.8259 194.62133,418.02234 199.27633,418.28504 C 203.02463,418.6029 206.6859,417.63711 209.78413,415.53691 C 212.47727,413.71515 215.89097,412.00039 219.1138,413.2118 C 222.10558,414.53866 225.04318,416.1114 227.76187,417.89648 C 231.28427,419.72492 235.04286,421.739 239.18638,421.04443 C 243.66778,420.53812 248.08959,420.98612 252.4678,421.83676 C 258.43027,422.21697 264.7242,420.67716 270.32898,423.31756 C 276.0539,425.35628 278.67194,431.55704 284.29896,433.72605 C 285.62732,434.09282 288.05106,436.36153 288.79211,434.20263 C 290.69593,427.67833 291.9209,420.74529 295.32158,414.79649 C 298.22609,410.75948 300.03763,405.64322 304.55608,403.07967 C 310.22396,399.24423 316.04232,394.96983 319.35899,388.86975 C 322.09954,379.86872 322.15111,370.05648 326.63377,361.58563 C 331.02032,353.59932 329.01229,344.10792 331.18793,335.58741 C 332.60862,333.51963 335.07863,332.29075 337.56037,331.9244 C 337.29553,328.75633 337.38442,325.0686 334.50022,323.00539 C 332.07798,321.53745 331.8445,319.10573 331.94611,316.52565 C 331.42702,312.2518 332.17608,306.75907 328.41389,303.73751 C 325.018,301.51823 320.16121,301.28408 316.58494,303.20494 C 314.46962,304.74164 314.14373,307.37519 313.47068,309.66065 C 312.92461,311.66961 310.75379,312.0067 309.51897,313.46653 C 307.90387,314.06616 306.54871,315.3327 306.61407,317.1815 C 306.42888,318.90695 305.33097,320.3703 304.42883,321.76673 C 299.42232,323.4706 293.83318,323.03789 288.98012,321.06192 C 284.44601,319.46609 279.60385,319.43216 274.92187,318.79218 C 270.43471,318.02726 267.31119,313.31828 262.39949,313.95165 C 259.49366,313.70862 256.0973,314.88253 254.04958,312.20879 C 250.80803,309.30022 246.15772,308.32108 241.96042,309.54376 C 239.1786,309.88356 236.86812,311.79074 233.93927,311.4402 C 228.20119,312.2711 222.83518,308.77644 217.12486,309.85549 C 215.61412,310.534 215.10803,313.12893 213.00307,312.59625 C 206.24453,311.77474 199.48184,310.83137 192.74729,309.99837 C 188.06278,309.39103 186.05324,303.94864 181.27685,303.72397 C 174.66114,302.82846 167.71079,300.45276 163.20107,295.46329 C 162.11617,293.73281 161.5119,291.61825 159.49797,290.60526 C 156.15156,288.74752 152.01378,290.07519 148.36488,289.34029 C 145.14273,288.59815 142.5273,286.01746 139.67636,284.38155 C 133.68003,279.72774 126.73051,276.15858 119.05185,275.31679 C 113.77226,274.21037 108.28584,274.3664 103.17958,272.69294 C 100.85927,271.00182 98.894565,268.58222 98.665239,265.62674 C 97.426483,260.51285 92.434492,257.6806 88.149735,255.33513 C 85.456502,254.15308 82.707665,252.48692 79.652527,252.59842 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptPaysandu"
+ class="paysandu dept" />
+ <path
+ d="M 435.77733,138.33105 C 432.30924,138.61566 432.38474,142.83911 431.95648,145.38428 C 431.25071,148.76145 431.50044,152.33361 430.87043,155.68483 C 429.29619,157.911 425.84075,157.09849 423.81752,155.86668 C 421.54,155.07775 418.8285,155.92479 417.88998,158.24373 C 416.13958,160.77429 414.88999,163.5841 414.01678,166.47899 C 412.95494,168.88983 411.04431,170.87238 408.33315,171.31257 C 404.80071,172.03354 402.90364,175.29336 401.65815,178.31239 C 401.08072,180.88318 398.10419,180.05795 396.18173,180.4945 C 392.61601,181.21972 388.64559,182.08989 385.30803,180.26069 C 381.37209,179.52336 377.34757,180.45477 373.41362,180.79326 C 370.75547,187.89046 368.78772,195.33166 365.49714,202.12177 C 359.80379,204.24765 353.49374,204.95471 348.02847,207.64225 C 346.4833,209.75379 345.29139,212.76792 347.07328,215.15011 C 347.99329,216.54201 349.21601,217.71038 350.27912,218.99495 C 352.5414,215.73784 354.74502,211.5554 359.15083,211.05846 C 363.04266,210.10473 366.67785,211.88415 369.52157,214.30908 C 373.12114,217.09926 376.77949,219.69127 380.51886,222.21632 C 386.3905,225.99246 393.30234,227.81517 399.28294,231.36081 C 402.48697,233.61822 404.83077,237.41509 405.3806,241.24572 C 405.32738,245.86558 406.311,250.56475 407.57576,255.00321 C 409.71548,261.57292 416.53868,264.70009 422.63383,266.76081 C 426.13687,268.17087 429.15647,271.18351 429.42545,275.07118 C 430.92679,280.22199 429.99746,285.76887 430.25787,291.08584 C 430.32843,296.24151 429.47901,302.03278 432.8986,306.37435 C 433.95831,308.725 436.43627,310.74862 439.1533,309.73858 C 441.29465,308.92577 443.41603,308.43403 445.53883,309.64767 C 450.29705,311.42881 455.70021,311.85113 460.44281,310.02435 C 468.72728,308.24918 477.58315,308.87795 485.65783,311.36226 C 491.40607,314.30114 498.17638,312.8434 504.40879,313.14873 C 509.85731,312.88518 515.40281,313.43094 520.21566,316.16832 C 528.57356,320.16578 538.89248,317.47239 546.81771,322.83185 C 550.18903,324.68724 550.6696,329.11368 554.19771,330.78134 C 558.41486,333.00307 560.94026,337.04428 563.13228,341.07194 C 566.98417,347.03291 571.90096,352.24604 576.36488,357.73533 C 579.08019,360.44553 581.41101,363.61788 581.92513,367.52824 C 581.83652,369.61986 584.08816,369.78222 585.57585,369.25582 C 588.88259,368.71033 592.47684,368.95938 595.70373,368.13872 C 597.53901,366.35346 599.1614,363.47329 597.50949,361.03356 C 596.22815,358.52502 598.83245,355.90748 600.89856,354.83764 C 603.68122,353.26454 604.19328,347.91015 600.55834,347.06999 C 599.21508,346.57877 596.16794,346.91645 596.6982,344.69295 C 597.74405,341.90105 600.20665,339.87344 601.06864,336.96427 C 604.21715,329.12691 607.81136,321.34781 610.12355,313.24572 C 610.51414,311.64498 609.59273,310.27655 608.68418,309.14109 C 606.69788,305.28756 606.55208,300.38923 608.70035,296.60683 C 609.68757,293.94057 611.01584,291.07097 613.74814,289.78693 C 613.73797,283.9071 613.7319,278.02725 613.73504,272.1474 C 608.11904,268.31997 602.70124,264.09047 597.82353,259.41782 C 595.6807,257.02039 595.62618,252.664 592.32778,251.45536 C 588.41785,250.96058 584.16655,251.2999 580.78669,248.87047 C 577.10681,246.80491 572.91594,247.55194 568.94488,247.79963 C 564.21247,247.81433 558.97808,248.35323 555.10062,245.12953 C 552.01314,243.16884 549.70862,240.32519 547.95614,237.18005 C 545.59939,234.7185 541.43467,235.17355 539.56856,231.9973 C 537.14598,228.24251 533.98889,225.09129 531.06322,221.77467 C 529.37471,219.76176 527.88941,216.21475 524.76929,216.42306 C 521.98281,217.53895 523.42727,221.17158 521.8644,223.19052 C 520.95723,225.17913 518.72814,227.61852 516.30319,226.29497 C 511.61603,224.77903 509.60193,219.88585 506.01829,217.00758 C 502.22167,215.39371 498.24826,214.17936 494.37252,212.69512 C 489.21425,209.69345 489.10012,203.15893 487.61193,198.08462 C 487.33328,195.74531 485.75426,193.76045 483.38102,193.27603 C 481.3577,192.4195 477.40721,192.12701 477.68902,189.06747 C 477.82408,184.76217 479.84974,179.62295 476.53186,175.99811 C 474.72793,173.30903 472.32192,171.1289 469.65473,169.34963 C 466.47432,166.7358 465.99283,162.47814 463.28227,159.54267 C 461.09581,157.62119 457.6269,157.18525 456.53034,154.1261 C 454.12769,148.76994 449.08262,145.27346 443.89011,142.83836 C 441.14876,141.36206 439.26094,138.09103 435.77733,138.33105 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptRivera"
+ class="dept rivera" />
+ <path
+ d="M 99.698943,121.15912 C 98.272679,121.23713 95.274702,121.15141 96.048213,123.3803 C 97.425725,127.01918 95.760336,130.74049 94.412547,134.07054 C 94.011456,138.79669 94.109605,143.66685 94.765866,148.35883 C 95.83349,152.40005 99.572984,155.4675 103.41511,156.87985 C 108.31586,158.66441 113.86869,157.7505 118.60697,159.91936 C 120.68831,161.18527 120.31465,165.09135 117.58632,165.18004 C 114.35931,165.82573 110.77155,166.82944 107.53695,166.15426 C 106.91984,164.49279 104.72405,165.23105 104.85448,166.8297 C 103.17176,168.48028 100.28993,167.52757 99.488487,165.41791 C 98.141373,163.85872 97.551932,160.9394 94.909787,161.81581 C 90.75847,162.0931 86.356553,161.26342 82.335003,162.3094 C 80.801756,163.2931 82.290987,164.85386 82.596705,166.02435 C 83.169351,171.0489 82.322189,176.28265 83.290196,181.20892 C 84.06923,182.97697 84.887622,185.18911 84.82318,187.05865 C 83.280726,190.78668 79.605799,194.65635 81.06572,198.95238 C 83.372468,201.89682 88.675232,201.24143 90.133736,205.12232 C 90.169326,206.78176 90.147089,208.68159 91.678696,209.83852 C 93.572801,211.31365 94.084899,214.56623 91.651611,215.78657 C 89.612251,217.3294 86.348677,216.3611 85.292237,214.02002 C 84.36665,212.9469 82.752672,210.29123 81.144235,211.8508 C 80.206504,214.33199 81.056512,217.25565 79.430099,219.57946 C 77.941833,222.27006 74.915129,224.66372 71.70988,223.814 C 69.00295,224.40326 67.571294,227.26685 65.625271,228.98376 C 62.938443,231.70029 64.400716,235.81649 63.251649,239.12006 C 62.96734,242.8637 60.676746,246.18256 57.22931,247.80695 C 54.553709,249.5561 49.631143,250.60165 49.910054,254.65073 C 50.295026,257.5518 52.299463,260.07128 54.973983,261.2883 C 57.140207,258.21965 61.009594,255.41026 64.879439,257.04078 C 66.535909,257.41526 68.281653,260.12855 69.469456,257.9152 C 72.570187,253.90843 77.914107,250.716 83.054659,252.45554 C 87.213345,253.85008 91.277811,255.78678 94.491064,258.7164 C 98.280383,260.94805 99.510848,265.32159 100.54949,269.28974 C 102.17238,273.0451 107.16537,272.59678 110.52007,273.36804 C 118.25605,274.48674 126.5232,275.20709 133.2623,279.38246 C 138.28269,282.22481 142.84761,286.07771 147.90455,288.79974 C 151.60564,289.08653 155.50949,288.60741 159.11853,289.39727 C 162.71829,291.53323 163.37196,296.4413 167.31797,298.14884 C 172.31134,301.63658 178.50401,302.34754 184.26813,303.8674 C 187.54728,305.63074 189.77053,309.4917 193.93245,309.41639 C 200.28956,310.33008 206.76738,311.02692 213.04231,312.08966 C 215.29239,311.54745 216.19337,308.34175 218.8521,308.97222 C 225.24999,309.60668 232.02892,312.23026 238.38821,309.92044 C 242.50273,308.50855 247.19586,307.18642 251.23781,309.58272 C 253.72183,310.77133 255.25085,313.78657 258.39317,313.01154 C 262.22667,313.14511 266.3557,312.89881 269.53082,315.42793 C 272.90175,318.4965 277.9269,318.25717 282.19182,318.94946 C 286.01371,319.41117 289.70988,320.4622 293.28029,321.71478 C 297.02146,322.19151 301.90162,323.04137 304.76905,319.98719 C 306.5619,318.23615 305.34584,314.96757 307.85715,313.79127 C 310.19856,312.19209 313.07155,310.54359 313.32672,307.42649 C 314.04818,303.8375 317.18839,301.15227 320.96843,301.49034 C 322.44494,301.31296 325.71319,302.01941 325.41737,299.64586 C 324.07231,292.73813 324.02424,285.59478 322.65644,278.70702 C 321.59225,276.05447 318.24748,273.93185 319.65992,270.70558 C 320.57056,268.01617 323.93149,266.58849 324.6192,263.97709 C 324.84804,261.30137 324.17301,258.19779 324.94455,255.77894 C 327.27517,253.51963 331.24291,252.88696 332.18241,249.41602 C 333.30547,246.78438 334.30081,243.6821 337.35102,242.70052 C 339.07607,241.77824 341.15289,241.5148 342.114,239.59606 C 343.2149,237.72045 344.659,236.22858 346.39285,234.95886 C 348.20492,232.87975 346.88036,230.13811 346.75923,227.78874 C 347.65049,225.03512 349.06913,222.49666 350.22677,219.82627 C 347.26732,217.41272 344.30287,213.55484 346.26201,209.60365 C 346.98807,207.47953 348.10794,205.68176 350.63218,205.66273 C 355.57497,204.24834 360.61079,203.0735 365.45786,201.42036 C 367.75791,194.67444 370.6381,188.04605 372.26212,181.11799 C 372.25145,179.8119 371.29181,178.75364 371.01906,177.50694 C 364.83991,169.99837 357.2299,163.72294 350.92031,156.39925 C 345.86271,151.08887 337.92574,151.80554 331.34496,150.03447 C 324.49393,148.58301 317.76544,146.57652 311.37705,143.78658 C 306.7767,142.37152 302.81205,146.38782 301.32768,150.30724 C 300.07657,153.34843 297.61259,155.88093 294.39255,156.78893 C 291.15749,158.60221 288.95563,162.13371 285.03667,162.76404 C 281.03593,163.34513 277.28788,164.91078 274.37578,167.78186 C 271.71872,169.79588 269.28721,172.39901 266.44271,173.98683 C 260.79807,174.77927 254.72246,173.27057 249.51559,176.19863 C 246.35656,175.71908 243.72724,172.00731 240.10288,172.96089 C 232.30737,173.25358 224.44487,172.98771 216.69307,173.81797 C 213.92048,175.56128 211.86607,178.42676 208.81583,179.67617 C 202.49426,177.83416 196.31452,175.53886 190.06482,173.46726 C 187.04021,168.38917 182.42072,164.52971 177.49004,161.34819 C 175.07073,160.59484 172.31817,161.39273 170.13619,159.75051 C 165.37831,156.62225 159.8066,154.62717 155.06213,151.48928 C 149.87971,149.85969 145.58679,146.20349 141.08722,143.33196 C 135.92367,140.81794 129.24222,143.95161 124.74387,139.68194 C 121.77666,136.89441 120.28818,132.48986 116.43483,130.58939 C 111.79429,127.543 107.72345,123.43256 102.57767,121.25006 C 101.64094,121.03002 100.65313,121.1017 99.698943,121.15912 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptSalto"
+ class="salto dept" />
+ <path
+ d="M 236.25531,2.332492 C 233.66546,2.628917 231.90602,5.587298 229.29403,5.410968 C 227.01907,4.271044 224.8417,2.67209 222.12338,3.046907 C 218.50373,3.164751 214.37435,2.331514 211.38052,4.865416 C 209.05107,6.195674 206.24315,5.24427 204.02666,4.112034 C 202.05511,6.395266 198.75,7.844536 197.64113,10.723615 C 197.4427,12.435894 197.96677,14.699433 195.88772,15.373801 C 194.36365,16.695625 190.91839,16.822316 191.67432,19.452462 C 191.46356,22.606069 192.08148,26.0942 191.38204,29.05052 C 187.71159,32.225001 184.77797,37.264475 179.75374,38.287027 C 178.50343,38.411218 176.68311,38.784097 176.44322,37.014073 C 175.88896,35.460984 173.99431,34.972145 172.87096,36.26069 C 171.64276,36.961517 170.23907,39.347366 168.81457,37.715498 C 166.68964,35.967434 164.53793,32.89683 161.35605,33.974564 C 158.01749,34.636622 156.74017,38.230609 153.94988,39.689876 C 151.17934,40.406029 148.2092,38.220252 147.30263,35.702146 C 145.58883,34.703153 143.3124,34.031137 141.32275,34.455171 C 140.32032,35.257847 139.91157,37.054114 138.22155,36.611403 C 134.43109,35.977646 129.97394,36.157891 126.79826,33.81869 C 124.67695,32.376416 124.16118,29.941627 124.58998,27.545852 C 124.74349,25.70914 125.44775,22.960672 123.08208,22.219196 C 120.20042,20.770338 116.57134,19.357463 113.37292,20.530578 C 111.92543,22.328767 114.77605,24.023216 114.83845,25.895177 C 116.19826,30.978065 116.70592,36.801449 114.39355,41.651269 C 111.20363,46.607691 108.28977,51.860732 103.83706,55.83239 C 99.175787,60.734737 94.3762,65.438189 88.621683,69.057822 C 85.367102,71.753185 81.24196,73.675694 79.456274,77.696733 C 77.204208,80.35222 76.118367,83.7048 76.106482,87.17897 C 75.588897,91.13053 75.441625,96.07834 78.671167,98.96032 C 81.596414,100.57695 83.660381,103.60038 83.237855,107.01372 C 83.280645,110.70162 88.174064,111.78951 87.996778,115.59305 C 88.751818,118.717 89.056193,122.52309 91.573095,124.75717 C 93.479717,125.36499 93.292295,122.82828 94.543403,122.19827 C 97.164862,120.28795 101.03693,119.6629 103.9778,121.0552 C 105.5172,122.1147 107.30611,122.7253 108.6361,124.15967 C 113.71417,128.17179 119.89911,131.30873 123.226,137.0581 C 124.61281,139.10375 126.65878,140.83672 129.24515,141.08478 C 133.55813,142.10986 138.47786,141.07297 142.46113,143.18907 C 143.61092,144.94258 145.92464,145.49434 147.44658,146.90402 C 154.18804,150.96226 161.66645,153.84865 168.34351,157.91899 C 170.96614,160.09993 174.57765,160.51056 177.86949,160.78965 C 182.90426,164.06923 187.52295,168.02697 190.75835,173.11655 C 196.78261,174.97981 202.71509,177.51164 208.85506,178.80589 C 212.04377,177.5659 214.0198,174.17061 217.09869,172.93468 C 225.76105,172.36605 234.461,172.73261 243.1381,172.62295 C 245.31538,173.49126 247.47138,175.32272 249.6676,175.62349 C 253.19023,173.52517 257.25717,173.22515 261.26101,173.45427 C 263.75628,173.21414 266.75652,174.34278 268.44824,171.91891 C 273.26818,168.21558 277.57136,162.93796 284.04219,162.41332 C 288.26239,161.87721 290.94243,158.186 294.32711,156.12647 C 299.40046,154.88283 300.61845,149.09597 303.56522,145.51417 C 306.03924,142.85479 310.39464,141.81417 313.56225,143.90349 C 322.56732,147.81681 332.22578,149.87205 341.96007,151.30957 C 346.69965,151.69761 350.71484,154.59335 353.46351,158.32703 C 358.62411,164.07822 363.99554,169.78508 369.94609,174.70124 C 371.87748,174.46576 371.18082,171.64713 371.64715,170.27188 C 372.63739,163.08923 371.8617,155.60109 373.34821,148.56666 C 374.49342,145.27648 378.03092,142.56551 376.92043,138.73372 C 376.43945,135.11017 375.70752,131.20295 372.52433,128.92303 C 369.64116,126.2631 366.10642,124.60725 363.28573,121.80859 C 358.86799,118.28006 358.65548,111.98704 354.9512,107.86077 C 353.62991,105.49911 351.03117,104.45769 349.11456,102.71423 C 346.8027,100.44402 347.16937,96.86827 345.38528,94.36207 C 343.26708,93.11089 340.52892,91.77281 340.05966,89.14036 C 339.02298,87.2193 337.01008,86.18717 334.93028,85.88003 C 332.32485,84.88234 331.80393,81.48814 329.10739,80.74923 C 324.58705,77.813967 319.83888,75.08456 315.28949,72.29316 C 312.4791,69.733229 310.99179,65.810226 308.82543,62.694024 C 305.79558,59.373654 301.39723,57.71619 298.01288,54.745876 C 293.35069,51.363601 288.29941,48.045663 285.49642,42.807215 C 283.88664,41.345293 283.41954,37.426024 280.64748,38.448134 C 278.47253,38.538497 274.28969,39.964974 273.45634,36.962115 C 273.53637,34.287851 276.63794,31.745598 274.71251,29.077577 C 271.73321,25.297699 267.39444,22.810109 263.15833,20.712431 C 260.2691,19.353808 257.69721,17.420089 254.90164,15.906366 C 251.55259,14.870222 249.67091,11.610753 249.41895,8.307595 C 248.34472,4.972197 244.31893,4.281713 241.4632,3.059896 C 239.76866,2.591653 238.00754,2.266504 236.25531,2.332492 z"
+ style="opacity:1;fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.89772069;stroke-opacity:1"
+ id="deptArtigas"
+ inkscape:label="#deptArtigas"
+ class="dept artigas" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="capArtigas"
+ sodipodi:cx="316.13959"
+ sodipodi:cy="54.892403"
+ sodipodi:rx="15.24789"
+ sodipodi:ry="14.231364"
+ d="M 331.38748,54.892403 A 15.24789,14.231364 0 1 1 300.8917,54.892403 A 15.24789,14.231364 0 1 1 331.38748,54.892403 z"
+ transform="matrix(0.6039414,0,0,0.642344,108.56966,30.83595)"
+ class="capital city artigas" />
+ <text
+ xml:space="preserve"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="328.51575"
+ y="70.901649"
+ id="textArtigas"
+ class="text capital artigas"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3196"
+ x="328.51575"
+ y="70.901649"
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">Artigas</tspan></text>
+ <path
+ class="capital city rocha"
+ transform="matrix(0.5497886,0,0,0.6486357,439.84825,779.68051)"
+ d="M 331.38748,54.892403 A 15.24789,14.231364 0 1 1 300.8917,54.892403 A 15.24789,14.231364 0 1 1 331.38748,54.892403 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capRocha"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital rocha"
+ id="textRocha"
+ y="797.08887"
+ x="609.82062"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="797.08887"
+ x="609.82062"
+ id="tspan3290"
+ sodipodi:role="line">Rocha</tspan></text>
+ <path
+ class="capital city rivera"
+ transform="matrix(0.6039414,0,0,0.642344,262.7347,119.88164)"
+ d="M 331.38748,54.892403 A 15.24789,14.231364 0 1 1 300.8917,54.892403 A 15.24789,14.231364 0 1 1 331.38748,54.892403 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capRivera"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital rivera"
+ id="textRivera"
+ y="149.14638"
+ x="465.80826"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="149.14638"
+ x="465.80826"
+ id="tspan3301"
+ sodipodi:role="line">Rivera</tspan></text>
+ <path
+ class="capital city salto"
+ transform="matrix(0.539691,0,0,0.5832904,-101.07632,208.26505)"
+ d="M 331.38748,54.892403 A 15.24789,14.231364 0 1 1 300.8917,54.892403 A 15.24789,14.231364 0 1 1 331.38748,54.892403 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capSalto"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital salto"
+ id="textSalto"
+ y="274.1666"
+ x="77.612114"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="274.1666"
+ x="77.612114"
+ id="tspan3307"
+ sodipodi:role="line">Salto</tspan></text>
+ <path
+ class="capital city tacuarembo"
+ transform="matrix(0.6098569,0,0,0.5847478,181.15794,272.57131)"
+ d="M 331.38748,54.892403 A 15.24789,14.231364 0 1 1 300.8917,54.892403 A 15.24789,14.231364 0 1 1 331.38748,54.892403 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capTacuarembo"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital tacuarembo"
+ id="textTacuarembo"
+ y="333.28595"
+ x="338.82224"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="333.28595"
+ x="338.82224"
+ id="tspan3313"
+ sodipodi:role="line">TacuarembĂł</tspan></text>
+ <path
+ class="capital city paysandu"
+ transform="matrix(0.5341216,0,0,0.6412547,-114.24463,378.89492)"
+ d="M 331.38748,54.892403 A 15.24789,14.231364 0 1 1 300.8917,54.892403 A 15.24789,14.231364 0 1 1 331.38748,54.892403 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capPaysandu"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital paysandu"
+ id="textPaysandu"
+ y="407.20306"
+ x="64.535774"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="407.20306"
+ x="64.535774"
+ id="tspan3359"
+ sodipodi:role="line">PaysandĂş</tspan></text>
+ <path
+ class="capital city rioNegro frayBentos"
+ transform="matrix(0.588227,0,0,0.6349125,-157.57899,529.10736)"
+ d="M 331.38748,54.892403 A 15.24789,14.231364 0 1 1 300.8917,54.892403 A 15.24789,14.231364 0 1 1 331.38748,54.892403 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capFrayBentos"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital frayBentos rioNegro"
+ id="textFrayBentos"
+ y="514.81421"
+ x="0.56596369"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="514.81421"
+ x="0.56596369"
+ id="tspan3365"
+ sodipodi:role="line">Fray </tspan><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="546.23444"
+ x="0.56596369"
+ sodipodi:role="line"
+ id="tspan3367">Bentos</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:3.9274714;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 82.643939,581.6446 C 82.643939,586.22677 78.957279,589.94562 74.414794,589.94562 C 69.872302,589.94562 66.185645,586.22677 66.185645,581.6446 C 66.185645,577.06244 69.872302,573.34358 74.414794,573.34358 C 78.957279,573.34358 82.643939,577.06244 82.643939,581.6446 z"
+ id="capMercedes"
+ class="capital city mercedes soriano" />
+ <text
+ class="text capital mercedes soriano"
+ id="textMercedes"
+ y="579.48608"
+ x="97.159409"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="579.48608"
+ x="97.159409"
+ sodipodi:role="line"
+ id="tspan3375">Mercedes</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 309.38907,589.2048 C 309.38907,594.1925 305.37085,598.24048 300.41985,598.24048 C 295.46883,598.24048 291.45062,594.1925 291.45062,589.2048 C 291.45062,584.2171 295.46883,580.16912 300.41985,580.16912 C 305.37085,580.16912 309.38907,584.2171 309.38907,589.2048 z"
+ id="capDurazno"
+ class="capital city durazno" />
+ <text
+ class="text capital durazno"
+ id="textDurazno"
+ y="571.48175"
+ x="276.13571"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="571.48175"
+ x="276.13571"
+ sodipodi:role="line"
+ id="tspan3384">Durazno</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.45004082;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 244.60627,636.79292 C 244.60627,641.73326 240.21645,645.74281 234.80753,645.74281 C 229.39863,645.74281 225.00881,641.73326 225.00881,636.79292 C 225.00881,631.85256 229.39863,627.84302 234.80753,627.84302 C 240.21645,627.84302 244.60627,631.85256 244.60627,636.79292 z"
+ id="capTrinidad"
+ class="capital trinidad flores city" />
+ <text
+ class="text capital trinidad flores"
+ id="textTrinidad"
+ y="617.46558"
+ x="173.92934"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="617.46558"
+ x="173.92934"
+ sodipodi:role="line"
+ id="tspan3484">Trinidad</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 673.59804,409.83003 C 673.59804,414.81773 669.57983,418.86572 664.62882,418.86572 C 659.67781,418.86572 655.6596,414.81773 655.6596,409.83003 C 655.6596,404.84234 659.67781,400.79436 664.62882,400.79436 C 669.57983,400.79436 673.59804,404.84234 673.59804,409.83003 z"
+ id="capMelo"
+ class="capital city cerroLargo melo" />
+ <text
+ class="text capital melo cerroLargo"
+ id="textMelo"
+ y="389.80011"
+ x="640.30042"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="389.80011"
+ x="640.30042"
+ sodipodi:role="line"
+ id="tspan3493">Melo</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 630.08087,571.40354 C 630.08087,576.39124 626.06265,580.43922 621.11163,580.43922 C 616.16063,580.43922 612.14241,576.39124 612.14241,571.40354 C 612.14241,566.41585 616.16063,562.36786 621.11163,562.36786 C 626.06265,562.36786 630.08087,566.41585 630.08087,571.40354 z"
+ id="capTreintaYTres"
+ class="capital city treintaYTres" />
+ <text
+ class="text capital lavalleja"
+ id="textMinas"
+ y="767.46509"
+ x="463.04156"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="767.46509"
+ x="463.04156"
+ sodipodi:role="line"
+ id="tspan3499">Minas</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.57013035;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 484.75783,779.36916 C 484.75783,784.27647 489.41896,788.25923 495.16211,788.25923 C 500.90528,788.25923 505.5664,784.27647 505.5664,779.36916 C 505.5664,774.46182 500.90528,770.47907 495.16211,770.47907 C 489.41896,770.47907 484.75783,774.46182 484.75783,779.36916 z"
+ id="capMinas"
+ class="capital city lavalleja minas" />
+ <text
+ class="text capital treintaYTres"
+ id="textTreintaYTres"
+ y="607.21118"
+ x="592.32788"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="607.21118"
+ x="592.32788"
+ sodipodi:role="line"
+ id="tspan3505">Treinta Y Tres</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 355.54471,736.40696 C 355.54471,741.39466 351.52649,745.44264 346.57546,745.44264 C 341.62442,745.44264 337.60621,741.39466 337.60621,736.40696 C 337.60621,731.41927 341.62442,727.37128 346.57546,727.37128 C 351.52649,727.37128 355.54471,731.41927 355.54471,736.40696 z"
+ id="capFlorida"
+ class="capital city florida" />
+ <text
+ class="text capital florida"
+ id="textFlorida"
+ y="722.81641"
+ x="318.53119"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="722.81641"
+ x="318.53119"
+ sodipodi:role="line"
+ id="tspan3511">Florida</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 106.32655,799.93349 C 106.32655,804.92117 102.30834,808.96916 97.357311,808.96916 C 92.406363,808.96916 88.388155,804.92117 88.388155,799.93349 C 88.388155,794.94578 92.406363,790.8978 97.357311,790.8978 C 102.30834,790.8978 106.32655,794.94578 106.32655,799.93349 z"
+ id="capColonia"
+ class="capital city colonia" />
+ <text
+ class="text capital Colonia"
+ id="textColonia"
+ y="835.05359"
+ x="48.681427"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="835.05359"
+ x="48.681427"
+ sodipodi:role="line"
+ id="tspan3517">Colonia</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 533.96209,879.87046 C 533.96209,884.85815 529.94387,888.90614 524.99286,888.90614 C 520.04185,888.90614 516.02364,884.85815 516.02364,879.87046 C 516.02364,874.88277 520.04185,870.83479 524.99286,870.83479 C 529.94387,870.83479 533.96209,874.88277 533.96209,879.87046 z"
+ id="capMaldonado"
+ class="capital city maldonado" />
+ <text
+ class="text capital maldonado"
+ id="textMaldonado"
+ y="890.14856"
+ x="535.79425"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="890.14856"
+ x="535.79425"
+ sodipodi:role="line"
+ id="tspan3523">Maldonado</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 267.45341,766.41815 C 267.45341,771.40585 263.43519,775.45383 258.48419,775.45383 C 253.53317,775.45383 249.51497,771.40585 249.51497,766.41815 C 249.51497,761.43046 253.53317,757.38247 258.48419,757.38247 C 263.43519,757.38247 267.45341,761.43046 267.45341,766.41815 z"
+ id="capSanJose"
+ class="capital city sanJose" />
+ <text
+ class="text capital sanJose"
+ id="textSanJose"
+ y="801.41498"
+ x="194.85408"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="801.41498"
+ x="194.85408"
+ sodipodi:role="line"
+ id="tspan3529">San José</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 348.75343,806.03914 C 348.75343,811.02681 344.73521,815.0748 339.78419,815.0748 C 334.83319,815.0748 330.81498,811.02681 330.81498,806.03914 C 330.81498,801.05143 334.83319,797.00345 339.78419,797.00345 C 344.73521,797.00345 348.75343,801.05143 348.75343,806.03914 z"
+ id="capCanelones"
+ class="capital city canelones" />
+ <text
+ class="text capital canelones"
+ id="textCanelones"
+ y="790.90936"
+ x="324.33298"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="790.90936"
+ x="324.33298"
+ sodipodi:role="line"
+ id="tspan3535">Canelones</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:4.27786922;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:0;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 361.39756,881.05298 C 361.39756,886.04069 357.37935,890.08861 352.42833,890.08861 C 347.47732,890.08861 343.4591,886.04069 343.4591,881.05298 C 343.4591,876.06528 347.47732,872.01729 352.42833,872.01729 C 357.37935,872.01729 361.39756,876.06528 361.39756,881.05298 z"
+ id="capMontevideo"
+ class="capital city montevideo" />
+ <text
+ class="text capital montevideo"
+ id="textMontevideo"
+ y="898.42822"
+ x="162.60995"
+ style="font-size:25.1361866px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:25.1361866px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="898.42822"
+ x="162.60995"
+ sodipodi:role="line"
+ id="tspan3541">Montevideo</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:35.90884018px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="87.556"
+ y="873.71393"
+ id="textDeptMontevideo"
+ class="text dept montevideo"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3545"
+ x="87.556"
+ y="873.71393"
+ style="font-size:32.31795502px">MONTEVIDEO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:35.90884018px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="287.81403"
+ y="839.00708"
+ id="textDeptCanelones"
+ class="text dept canelones"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3549"
+ x="287.81403"
+ y="839.00708"
+ style="font-size:32.31795502px">CANELONES</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:35.90884018px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="496.66357"
+ y="842.30121"
+ id="textDeptMaldonado"
+ class="text dept maldonado"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3553"
+ x="496.66357"
+ y="842.30121"
+ style="font-size:32.31795502px">MALDONADO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:35.90884018px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="621.24603"
+ y="711.51624"
+ id="textDeptRocha"
+ class="text dept rocha"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3557"
+ x="621.24603"
+ y="711.51624"
+ style="font-size:32.31795502px">Rocha</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:35.90884018px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="208.62206"
+ y="745.89661"
+ id="textDeptSanJose"
+ class="text dept sanJose"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3561"
+ x="208.62206"
+ y="745.89661"
+ style="font-size:32.31795502px">S. JOSÉ</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:35.90884018px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="36.734997"
+ y="754.93323"
+ id="textDeptColonia"
+ class="text dept colonia"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3565"
+ x="36.734997"
+ y="754.93323"
+ style="font-size:32.31795502px">COLONIA</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="325.66666"
+ y="678.36743"
+ id="textDeptFlorida"
+ class="text dept florida"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3569"
+ x="325.66666"
+ y="678.36743">FLORIDA</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="437.44366"
+ y="731.17706"
+ id="textDeptLavalleja"
+ class="text dept lavalleja"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3573"
+ x="437.44366"
+ y="731.17706">LAVALLEJA</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="512.06561"
+ y="549.08112"
+ id="textDeptTreintaYTres"
+ class="text dept treintaYTres"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3577"
+ x="512.06561"
+ y="549.08112">TREINTA Y TRES</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="281.77496"
+ y="537.92273"
+ id="textDeptDurazno"
+ class="text dept durazno"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3581"
+ x="281.77496"
+ y="537.92273">DURAZNO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="172.50551"
+ y="678.45642"
+ id="textDeptFlores"
+ class="text dept flores"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3585"
+ x="172.50551"
+ y="678.45642">FLORES</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="17.103823"
+ y="645.72308"
+ id="textDeptSoriano"
+ class="text dept soriano"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3589"
+ x="17.103823"
+ y="645.72308">SORIANO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="67.034668"
+ y="497.88922"
+ id="textDeptRioNegro"
+ class="text dept rioNegro"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2492"
+ x="67.034668"
+ y="497.88922">RĂŤO NEGRO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="315.0127"
+ y="395.77188"
+ id="textDeptTacuarembo"
+ class="text dept tacuarembo"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2496"
+ x="315.0127"
+ y="395.77188">TACUAREMBĂ“</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:35.90884018px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="512.15466"
+ y="466.83258"
+ id="textDeptCerroLargo"
+ class="text dept cerroLargo"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2500"
+ x="512.15466"
+ y="466.83258"
+ style="font-size:32.31795502px">CERRO LARGO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="85.256134"
+ y="364.41855"
+ id="textDeptPaysandu"
+ class="text dept paysandu"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2504"
+ x="85.256134"
+ y="364.41855">PAYSANDĂš</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="391.75647"
+ y="210.4411"
+ id="textDeptRivera"
+ class="text dept rivera"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2508"
+ x="391.75647"
+ y="210.4411">RIVERA</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="152.04353"
+ y="233.09941"
+ id="textDeptSalto"
+ class="text dept salto"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2512"
+ x="152.04353"
+ y="233.09941">SALTO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:32.31795502px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+ x="139.83151"
+ y="118.35461"
+ id="textDeptArtigas"
+ class="text dept artigas"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2516"
+ x="139.83151"
+ y="118.35461">ARTIGAS</tspan></text>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/capitals2.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/capitals2.svg
new file mode 100755
index 0000000..a549de0
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/capitals2.svg
@@ -0,0 +1,789 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml-stylesheet href="../../css/lesson.css" type="text/css"?><!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="399.99994"
+ height="440.04074"
+ id="svg2925"
+ sodipodi:version="0.32"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="capitals2.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <metadata
+ id="metadata25">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ inkscape:window-height="551"
+ inkscape:window-width="1024"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ showgrid="false"
+ inkscape:zoom="1.5"
+ inkscape:cx="451.8564"
+ inkscape:cy="79.294499"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:current-layer="svg2925"
+ inkscape:window-maximized="1" />
+ <defs
+ id="defs2928">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 220.02037 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="399.99994 : 220.02037 : 1"
+ inkscape:persp3d-origin="199.99997 : 146.68025 : 1"
+ id="perspective122" />
+ </defs>
+ <!-- <style type="text/css">
+ .text { display:none;}
+ </style>-->
+ <path
+ d="m 116.46558,0.2233067 c -1.27379,0.005 -2.45593,0.61951 -3.40684,1.42296 -1.20038,-0.55902 -2.36343,-1.54703 -3.76681,-1.072 -2.10803,0.0931 -4.46063,-0.3148 -6.26087,1.03371 -1.19317,0.57748 -2.30946,-0.93524 -3.438987,-0.38924 -1.208418,1.18834 -2.99415,2.11763 -3.522543,3.81581 0.06414,0.9551 -0.372943,2.08134 -1.407725,2.25248 -0.617042,0.36407 -1.862509,0.6525 -1.446302,1.62714 -0.188545,1.6903503 0.275053,3.5582503 -0.392097,5.1302803 -1.553462,1.11027 -2.460412,3.21748 -4.409607,3.71371 -1.256962,-0.0167 -1.83244,-1.95838 -3.233292,-1.31447 -0.849446,0.14258 -1.601816,1.62969 -2.299644,0.59591 -0.96615,-1.02356 -2.359432,-1.89863 -3.781241,-1.31058 -1.583095,0.25697 -2.622686,1.56012 -3.586817,2.68638 -0.991174,0.54348 -1.808197,-0.58196 -2.037667,-1.39104 -1.152971,-1.13414 -2.987523,-0.90823 -4.416048,-1.40381 -0.623355,0.55801 -1.20488,1.80211 -2.256212,1.27618 -1.556007,-0.41869 -3.971869,-0.25238 -4.583174,-2.14399 -0.138521,-0.88589 0.682423,-1.73399 0.398537,-2.70553 -0.283634,-1.84627 -2.412791,-2.4172903 -3.914639,-2.9799003 -1.545003,-0.46716 -4.044435,-0.37582 -4.518894,1.4995203 0.04108,1.11381 1.017849,2.00262 1.179832,3.13014 0.917364,2.7505 0.544254,5.95287 -1.360369,8.20105 -2.055519,3.6248 -5.258511,6.38508 -8.323692,9.15804 -2.732525,2.44198 -6.55197,3.85537 -8.124986,7.40828 -1.638738,1.67171 -1.109953,4.25612 -1.375589,6.38733 -0.04727,1.98545 0.422519,4.34867 2.404068,5.27067 0.926455,0.54053 1.19495,1.59871 1.131327,2.59705 0.147279,1.36866 1.012191,2.47274 1.986241,3.37552 0.805915,1.36417 0.535034,3.06872 1.38022,4.44644 0.41499,0.91611 0.770208,2.33564 1.878784,2.59812 0.453746,-0.19104 1.686359,-0.26714 1.112033,0.54877 -0.510805,1.23461 -1.486462,2.50415 -0.989909,3.89876 0.35972,2.61945 -0.452675,5.72248 1.459165,7.87409 1.390133,1.77867 3.3911,3.0837 5.672783,3.26425 1.655607,0.29982 3.335093,0.44191 4.997691,0.69832 0.434432,1.15209 -1.199246,1.01008 -1.870556,1.17409 -0.846861,0.27909 -2.122992,0.40923 -2.500484,-0.60618 -0.856745,-0.87237 -2.584196,-0.16217 -2.410979,1.1414 -0.160096,0.93403 -0.730672,-0.93963 -1.150131,-1.26902 -0.686673,-1.16555 -2.055972,-1.38385 -3.303988,-1.24715 -2.057082,0.003 -4.185666,-0.0787 -6.196588,0.0603 -0.8905,0.79166 -1.325218,2.29287 -0.417832,3.24791 0.84796,2.93478 -0.419248,6.20187 0.983496,9.00991 0.416717,1.84789 -1.48786,3.07126 -1.786985,4.79209 -0.544147,1.53242 0.197344,3.29032 1.741979,3.90514 0.980818,0.504523 2.14308,0.756173 2.905454,1.614383 -1.066473,0.9261 0.06662,2.4509 1.131328,2.73104 0.836194,0.5844 -0.146048,1.93718 -0.93849,1.21239 -1.039341,-1.18802 -2.262243,-3.04703 -4.113917,-2.56515 -1.399863,0.63118 -0.625502,2.40318 -0.938486,3.56058 -0.07263,1.54801 -1.343853,3.00053 -3.001414,2.80205 -0.94081,-0.0556 -1.85692,0.28701 -2.295254,1.14137 -1.344778,1.38794 -3.063533,2.88176 -2.912679,4.99531 -0.168771,2.0361 -0.219846,4.75838 -2.448272,5.68002 -1.729595,0.94761 -4.375088,1.88792 -4.30032,4.24971 -0.01382,2.45624 2.128234,4.14698 4.21033,5.04734 1.973135,1.09631 3.748107,3.12457 3.323282,5.53228 0.120783,2.62659 -0.347296,5.20935 -1.433454,7.59971 -1.396529,3.91185 -1.800104,8.34125 -4.242477,11.81752 -1.768922,1.82249 -4.552482,1.47895 -6.76867,2.21418 -1.772666,1.22326 -3.012396,3.13711 -4.113917,4.93248 -0.769837,1.20101 -0.238052,2.61916 0.732793,3.49676 2.493895,2.53099 3.497322,6.10422 3.74751,9.55867 0.194608,2.68364 -0.526456,5.32071 -1.78698,7.66989 -0.966504,2.52472 -1.336204,5.73539 0.719935,7.84219 1.638591,2.04231 4.200907,3.39065 5.193821,5.88324 0.39802,1.6709 0.237679,3.5397 0.115702,5.16218 -3.42895,3.54509 -6.290611,7.92388 -7.149415,12.83033 -0.629242,4.3107 1.730728,8.27363 2.784817,12.35529 1.851918,5.7654 1.598521,11.99467 3.310407,17.80285 1.60739,3.61652 5.655976,5.85095 6.395866,9.8841 0.0018,3.28814 -1.509479,6.33777 -1.934835,9.55866 -0.397675,2.25261 -2.316469,3.73787 -3.760368,5.34723 -1.567201,1.42834 -3.453347,2.9077 -5.663077,3.03734 -3.160002,-0.14279 -6.343743,-0.2961 -9.500576,-0.19143 -1.7494238,0.7182 -2.8710003,2.5973 -2.5711987,4.47304 -0.1639826,4.54053 1.4861521,8.95573 1.1506218,13.48932 -0.2037441,1.6148 -1.3185925,3.06885 -2.8797425,3.56058 -1.4305761,1.19649 -1.4568015,3.26248 -1.8705569,4.94524 -0.1709986,1.15366 0.4445487,2.58921 1.7934208,2.55875 1.5355799,0.58899 1.2064671,2.64118 0.5335116,3.77752 -1.0330871,1.91862 -2.6470995,3.59547 -3.11115012,5.76201 -0.70014588,2.79947 -0.43093356,5.83809 0.53353362,8.55047 0.5037717,1.40019 0.00691,2.81511 -0.41782746,4.14123 -0.39862208,3.05209 0.32526616,6.11395 0.40437616,9.16906 0.1734419,2.75661 0.1804353,5.60756 1.4533224,8.11055 0.7507909,2.61413 0.7844435,5.65871 2.9440248,7.61885 1.8904656,1.82052 4.7878155,2.53407 6.2030065,4.81124 0.191067,1.40178 0.356223,3.11874 1.902687,3.7201 1.279672,0.67769 2.068988,1.8615 2.635476,3.13304 1.086117,1.25573 1.839351,2.82275 1.92198,4.53048 0.270244,0.98009 -0.02129,2.67722 1.375594,2.80761 2.316115,0.37583 4.632353,0.67088 6.935795,1.18685 1.255652,0.31381 2.260167,1.41794 2.140535,2.75021 0.06969,1.22162 0.950007,2.12517 1.988091,2.65837 3.654227,2.722 6.515189,6.24615 9.338036,9.76532 1.458466,1.35948 2.476167,3.08299 2.802606,5.05372 0.801127,2.57792 1.709641,5.35497 3.805374,7.15942 2.31338,0.48975 4.501122,-0.81868 6.811745,-0.78723 4.195292,-0.44744 8.258689,-1.53605 12.131548,-3.15619 1.03011,-0.38333 2.488488,-0.96577 3.194725,0.2361 1.647502,1.66127 4.462116,1.89525 6.254432,0.34457 0.897837,-0.78732 1.959515,-1.54871 3.239708,-1.16134 1.325137,0.20939 2.696824,-0.14104 3.966087,-0.0383 2.899752,0.79653 5.981983,0.28322 8.960604,0.42537 2.080431,0.0596 4.255455,-0.25611 6.180337,0.65792 1.704334,0.67314 3.961975,0.55891 5.100805,2.19013 1.72586,1.81693 2.93446,3.99123 4.16534,6.14486 1.25356,2.11633 3.70971,2.87731 5.61746,4.2773 1.78667,1.11413 3.56605,2.4779 4.30738,4.50926 0.44145,1.068 1.44367,1.621 2.49628,1.86808 5.03241,2.83289 10.62843,4.46238 16.32489,5.43812 2.67657,0.1637 4.63729,2.13379 6.338,3.97534 2.67695,-0.0202 5.44453,-0.62389 8.07358,-0.15315 0.86872,0.68192 2.08266,0.71494 3.04044,1.26981 0.12066,1.5615 -1.36502,3.07169 -0.55925,4.55599 1.68001,1.28119 3.77969,1.92964 5.24525,3.50316 0.9918,0.74335 1.8028,1.93482 2.97618,2.33542 1.9205,-0.0779 4.21143,0.8856 5.81732,-0.49771 0.69426,-0.4199 1.48315,-0.5867 2.28837,-0.68277 -0.48682,0.82817 -0.49655,2.2213 0.6428,2.47581 2.48439,0.94858 4.97421,-0.72933 7.40505,-1.13582 2.71631,-0.78923 5.72133,-0.80113 8.22783,-2.11847 2.09407,-1.52414 3.82667,-3.6642 6.23073,-4.67463 2.40007,-0.36395 4.59873,-1.47299 6.58028,-2.83574 1.77941,-1.14075 3.97686,-0.32983 5.91645,-0.88737 1.5494,-0.20024 2.89908,-1.20411 4.51618,-0.8993 2.06451,0.24135 4.13555,0.5472 6.15802,0.96352 2.17005,0.7211 4.21662,1.94626 6.55655,1.93344 3.37708,0.3578 6.85976,-0.45112 10.17553,0.34457 2.30427,0.79153 3.71602,2.82644 4.686,4.93885 0.77687,1.51398 2.0035,3.15795 3.8761,3.17772 3.8133,0.54841 7.34107,-1.65795 11.16537,-1.41204 1.21762,0.10389 2.79395,0.13029 3.5933,1.11212 0.39151,0.7822 0.10667,2.40106 1.42058,2.25886 1.88555,0.0215 4.59271,-0.0629 5.3931,2.03553 0.12228,0.86857 -0.52416,2.44775 0.78421,2.67361 1.79246,0.28575 2.67633,-1.78635 3.89537,-2.68637 1.59673,-1.43117 3.79973,-1.66445 5.83018,-1.91429 3.06618,-0.8736 5.52458,-2.98803 8.49857,-4.11292 4.11215,-1.87199 8.09267,-4.02894 12.15372,-5.97849 5.91765,-2.26341 11.43286,-5.47495 17.16138,-8.18386 1.7633,-0.32792 3.19635,-1.95152 2.87555,-3.7773 -0.40903,-1.51156 -1.65088,-2.84759 -3.12401,-3.40104 -0.95554,-0.14985 -2.1362,-0.0817 -0.63636,-0.81676 1.32988,-0.98302 3.10229,-1.99544 3.40683,-3.73287 -0.44902,-0.70678 0.21739,-1.31429 0.92564,-1.12942 0.87801,-0.0861 0.96193,1.05185 0.39209,1.5059 -1.03345,1.60158 0.12752,3.42003 0.58496,4.98351 0.23986,1.14895 -1.02791,2.38901 -0.23784,3.40744 1.45155,0.81302 3.02737,-0.51164 4.56387,-0.44668 1.40708,-0.22764 3.1134,0.4411 4.3132,-0.48494 0.62795,-1.42815 -0.86226,-3.48473 0.97706,-4.39647 3.68668,-3.11343 7.12207,-6.53364 10.4203,-10.01858 3.53766,-3.04775 7.65384,-5.40408 11.83342,-7.49713 2.14337,-0.7978 5.02601,-1.54258 5.54735,-4.10295 0.33096,-1.66347 -1.57489,-3.18871 -0.53352,-4.78571 0.90803,-2.32468 1.03593,-4.92554 2.51636,-7.02549 1.19318,-1.86891 2.17263,-4.0017 3.81522,-5.50032 1.87797,-1.43693 4.24903,-2.33388 5.50993,-4.43373 1.29623,-1.83549 2.71697,-3.61517 4.74172,-4.69659 0.76664,-0.6213 1.85614,-1.15214 2.25722,-2.07463 -0.18868,-2.74876 0.59595,-5.46309 1.79342,-7.89322 0.56087,-2.89826 -0.18584,-6.1707 1.56843,-8.76106 1.60727,-3.28321 3.96524,-6.18645 6.19015,-9.04179 0.81614,-0.9717 2.23326,-1.89946 2.28837,-3.24153 -0.9439,-0.85447 -2.69723,-0.2473 -3.50325,-1.36551 -0.97133,-1.15831 -0.0451,-2.87364 -0.80351,-4.05829 -1.13159,-0.56955 -2.49762,0.25291 -3.7218,0.0638 -1.2242,-0.0131 -3.13528,-0.0206 -3.20758,-1.60163 -0.24988,-1.81301 0.4564,-3.63167 0.0321,-5.44294 0.0316,-1.64269 0.18293,-3.2844 -0.2752,-4.8736 -0.13109,-2.04423 -1.10823,-3.84275 -2.23172,-5.52734 -1.40984,-2.44855 -1.06922,-5.49981 -0.17356,-8.06552 0.47458,-0.86314 1.31429,-1.9106 0.50782,-2.86507 -0.54364,-0.90306 -2.11807,-1.04806 -1.94769,-2.36095 0.0317,-1.58664 1.16526,-2.75219 1.97982,-4.0136 0.69089,-0.9948 -0.0352,-2.24413 -1.13775,-2.52048 -1.38305,-0.45075 -3.03202,-1.02047 -3.45826,-2.57152 -0.65106,-1.31343 -0.81538,-2.78963 -0.91277,-4.23695 1.47043,0.50658 2.80933,-1.08125 2.36549,-2.45028 0.13141,-1.36349 -1.03516,-2.69844 -0.66208,-3.98172 0.9831,-0.70558 0.85143,-1.91332 0.77136,-2.95439 0.41128,0.47807 1.10664,1.73609 1.86411,0.98906 0.89762,-0.91904 0.98543,-2.31805 1.90913,-3.24152 1.68492,-2.40138 4.09298,-4.30257 5.37381,-6.98715 1.47701,-1.52387 3.80814,-0.75111 5.6952,-0.96351 2.03361,-0.0471 4.1045,0.42175 6.10016,0.31904 0.97707,-0.56466 0.81325,-2.09339 -0.17354,-2.59066 -0.74689,-0.31703 -0.77569,-1.3614 0.0257,-1.608 0.96009,-0.63248 2.69546,-1.26772 2.06338,-2.72467 0.14514,-0.84423 1.29456,-0.71545 1.60461,-1.49715 0.75124,-0.64937 1.41893,-1.58928 1.05016,-2.61856 0.0426,-2.11081 -1.11209,-4.04852 -1.33702,-6.08105 0.47536,-1.01181 1.83357,-0.86469 2.65475,-1.45486 2.01907,-0.78852 3.43717,-2.94253 5.70806,-2.99905 1.20994,-0.17592 1.25345,-1.53161 1.26633,-2.48218 0.0597,-1.30914 0.63603,-2.50492 0.9449,-3.73923 -0.25074,-1.34923 -1.60733,-2.22351 -2.72546,-2.87143 -1.24248,-0.35374 -2.45174,-0.87216 -3.38113,-1.74201 -2.07424,-1.10134 -4.80469,0.28573 -6.63369,-1.52504 -1.84002,-1.33205 -4.37269,-1.27075 -5.94579,-3.03266 -1.81387,-1.90104 -2.33015,-4.89664 -4.74397,-6.30267 -3.05102,-1.794 -5.71682,-4.30154 -7.57861,-7.30618 -1.16883,-2.37002 -4.01187,-3.79959 -4.19097,-6.65812 -0.46817,-1.90585 -0.21318,-3.86616 0.0192,-5.7656 -0.34124,-1.91507 -1.771,-3.52854 -1.8779,-5.54471 -0.176,-1.32782 -1.13318,-2.32061 -2.16532,-3.10786 -1.28782,-1.1304 -1.07918,-3.00176 -2.023,-4.32256 -0.98036,-1.60526 -1.49387,-3.41263 -1.51882,-5.2744 -0.0819,-1.12958 -0.81951,-2.34944 -2.10196,-2.36095 -1.37547,-0.34029 -3.30405,0.1525 -4.11392,-1.30809 -1.43977,-1.48925 -3.63216,-2.77062 -3.68323,-5.092 -0.39412,-1.13395 -1.71446,-1.65014 -2.50125,-2.48747 -1.77741,-1.58381 -4.11928,-2.20686 -6.42081,-2.53433 -1.24359,-0.15334 -1.7112,-1.33523 -2.32693,-2.22058 -0.78965,-0.97319 -2.11344,-1.01005 -3.01228,-1.84515 -1.04946,-0.74218 -2.68846,-0.96116 -3.53142,0.23077 -0.71197,0.7257 -1.35011,1.54874 -2.28837,1.99725 -4.58056,-4.79616 -10.36623,-8.27748 -15.20222,-12.7619 -2.38784,-2.71381 -3.89432,-6.39174 -7.36005,-7.98896 -0.56066,-0.39382 -1.54757,-0.34986 -1.8384,-0.8359 -0.0115,-2.90759 -0.0254,-5.81517 -0.0386,-8.72276 -2.89904,-2.10777 -5.94005,-4.14157 -8.31141,-6.82762 -0.70251,-1.35732 -1.04757,-3.21544 -2.69332,-3.76475 -1.91264,-0.63071 -4.20126,-0.0334 -5.88804,-1.37191 -3.57414,-1.83603 -7.78632,0.66636 -11.41612,-1.09752 -1.88198,-0.81799 -3.14261,-2.4736 -4.21035,-4.16039 -0.60294,-1.03763 -1.75441,-1.26201 -2.77046,-1.608 -2.00833,-1.07753 -2.72648,-3.46417 -4.46747,-4.84951 -1.49314,-1.56282 -2.50891,-3.94372 -4.86599,-4.37733 -1.75616,-0.14894 -2.09875,2.08849 -2.41412,3.34254 -0.12642,0.86807 -0.7945,2.17399 -1.86692,1.62183 -2.34018,-1.12036 -3.07441,-4.31816 -5.75948,-4.93885 -1.97616,-0.96763 -4.89305,-0.92094 -5.90734,-3.17133 -1.07023,-2.052743 -0.90552,-4.577123 -1.93481,-6.610663 -1.09541,-1.33702 -2.96394,-1.50171 -4.4032,-2.31629 0.32531,-2.20051 1.22988,-4.69458 -0.30854,-6.66809 -1.50915,-2.53051 -4.67614,-3.79384 -5.59235,-6.71276 -0.60064,-1.75839 -2.21351,-2.72054 -3.76037,-3.54781 -1.11925,-0.85048 -1.29919,-2.40136 -2.35908,-3.33724 -1.4192,-1.74478 -3.51983,-2.71863 -5.41238,-3.82219 -1.29245,-1.08361 -2.70408,-2.41217 -4.52531,-2.00999 -1.46722,0.1156 -2.40327,1.52858 -2.42978,2.92247 -0.40514,2.04464 -0.44122,4.14875 -0.64279,6.22781 -1.7128,-0.27491 -3.58985,-1.37992 -5.18739,-0.15315 -2.22259,1.44702 -2.3029,4.40464 -3.7861,6.36181 -1.25966,1.06465 -3.18741,1.06061 -4.11392,2.5779 -0.61284,0.7957 -0.98092,1.71259 -1.37559,2.6162 -1.89964,-0.14024 -3.82015,0.85525 -5.6695,0.402 -2.2009,-0.99607 -4.70942,-0.17798 -7.05149,-0.21058 0.2242,-4.62979 0.51072,-9.28144 0.93849,-13.88494 0.35977,-1.72177 2.17794,-2.85115 1.91554,-4.73467 -0.11701,-2.40362 -0.54423,-5.08036 -2.64192,-6.60428 -2.09187,-1.85021 -5.03984,-3.01802 -6.08089,-5.77476 -0.86087,-2.60363 -2.41898,-4.94553 -4.67372,-6.54598 -1.76503,-0.77088 -1.21924,-2.92755 -2.17208,-4.23783 -0.8718,-0.90082 -2.457,-1.12095 -2.6869,-2.55237 -0.56301,-1.2288 -1.88831,-1.98207 -3.14972,-2.20143 -2.57562,-2.97093 -6.34439,-4.45907 -9.52629,-6.64258 -1.48955,-1.71357 -1.96765,-4.18101 -4.00465,-5.43018 -3.43348,-2.72722 -7.78373,-4.62788 -10.12846,-8.4939 -0.6027,-0.86103 -1.14025,-1.78868 -1.78262,-2.60896 -1.31454,-0.0508 -2.68733,0.21193 -3.94037,-0.31266 1.44462,-1.70806 0.83741,-4.4154 -1.06165,-5.52579 -2.92439,-2.3860703 -6.47901,-3.8209403 -9.67952,-5.7557303 -1.42415,-1.14391 -0.7789,-3.44399 -2.48765,-4.38371 -1.71698,-1.08703 -3.77484,-1.90746 -5.84303,-1.85048 z"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="path3748" />
+ <path
+ d="m 297.30439,344.50108 c -2.02401,0.77429 -2.77188,3.06882 -2.95044,5.04733 -0.11097,1.6257 -0.51252,3.55957 -2.25624,4.21781 -2.77652,1.31004 -6.16499,0.46721 -8.87705,1.93981 -1.18633,0.69035 -1.34517,2.11164 -1.66487,3.29894 -0.61531,1.27682 -2.09655,1.91077 -2.84758,3.02457 -0.14559,1.41035 0.29187,3.22113 -1.16348,4.09657 -0.52175,0.49204 -1.39995,0.71965 -1.29846,1.6144 -0.38852,2.27541 -0.12148,4.70017 -0.80992,6.89779 -0.63317,0.79599 -2.13569,0.83452 -2.21765,2.08019 -0.6553,2.38421 -0.88766,4.88205 -1.47202,7.26791 -0.68563,1.29267 -2.45926,1.28099 -3.33612,2.4056 -0.65848,0.62324 -1.14937,1.59412 -2.22409,1.20602 -1.93636,-0.37687 -3.05948,1.73116 -4.86601,1.81218 -1.80615,0.22286 -3.8455,0.63386 -4.82099,2.32267 -1.15558,1.42695 -1.97657,3.79812 -4.11392,3.95619 -1.84408,-0.0862 -3.92996,-0.7272 -5.55379,0.51685 -3.09004,1.76194 -5.39546,4.48147 -8.18282,6.61067 -2.80534,1.85633 -6.33805,2.06532 -9.59034,2.40895 -1.38887,0.18381 -2.91454,-0.43301 -4.22344,0.10513 -0.68221,0.75982 0.21133,1.80107 0.53996,2.53962 0.56149,1.08674 1.87636,1.24048 2.59805,2.19663 1.06522,0.72979 0.20212,2.21899 0.30098,3.31651 -0.17396,1.16042 -0.48987,2.57247 0.61709,3.39467 1.11215,1.10834 2.17398,2.35874 2.28193,4.00726 0.33355,1.04296 -0.21911,2.60267 1.07348,3.12027 1.94448,0.8909 3.28914,2.61316 4.07535,4.53047 0.77866,1.74128 2.33066,3.52784 4.44817,3.27343 3.32623,-0.3599 6.51443,-1.63186 9.90554,-1.474 1.74555,0.0744 4.23235,0.13969 4.87885,2.11211 0.15582,0.72976 0.74289,1.49014 1.56844,1.19322 1.91905,-0.11528 4.31243,0.75263 4.98812,2.66724 0.21001,0.78946 0.0549,1.63597 0.10285,2.45028 1.77065,-1.60985 3.17764,-3.87025 5.65664,-4.40922 1.67265,-0.53575 3.5399,-0.30194 5.12954,-1.1741 5.56078,-3.30659 11.75171,-5.56806 17.33629,-8.86314 0.96808,-0.78747 2.56181,-0.69964 3.33614,-1.62714 -0.33893,-1.09396 -1.22424,-2.26065 -0.41783,-3.39468 0.61316,-1.01397 1.79887,-1.94206 1.39489,-3.29258 -0.60014,-1.95259 -1.54822,-3.80563 -1.46541,-5.90228 -0.0709,-2.78591 0.4194,-5.60217 1.88965,-8.01455 0.89632,-1.6078 0.99568,-3.70992 -0.18641,-5.20686 -0.90125,-1.52403 0.28358,-3.74144 -1.25582,-5.01979 -0.88353,-0.98582 -0.174,-2.52949 -0.37347,-3.754 0.0257,-0.9382 0.0128,-1.8863 0.1637,-2.81401 1.00696,-0.23045 2.15263,0.14101 3.11759,-0.28076 0.24297,-3.12315 1.1406,-6.2526 0.81634,-9.39276 -0.66199,-4.31585 -0.49461,-8.83219 0.58496,-13.06819 0.47061,-1.56054 1.9724,-2.79318 1.5081,-4.54934 -0.11996,-2.23478 0.0574,-4.53183 -0.23396,-6.73062 -0.67742,-1.73798 -1.66212,-3.4676 -1.23558,-5.39984 0.0429,-0.48568 0.0209,-1.31762 -0.67494,-1.26343 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptMaldonado"
+ class="dept maldonado" />
+ <path
+ d="m 161.41013,413.32601 c -1.06799,0.24508 -2.55184,0.66974 -2.84761,1.85684 0.33469,1.69766 0.91636,3.85142 -0.57852,5.20048 -1.02451,1.1898 -2.37762,2.02672 -3.68967,2.83954 -0.50805,0.8301 -1.36486,1.73874 -1.24059,2.75657 1.73286,1.01517 3.62415,1.90477 5.05236,3.35746 1.09815,0.92598 2.14282,2.39297 3.78612,2.11739 1.14328,-0.068 2.41884,0.79228 3.41969,-0.12125 1.09392,-0.68098 2.72801,-1.3411 3.92108,-0.61894 0.67078,0.65088 -0.13719,2.24332 1.00277,2.39285 2.83128,-0.1958 5.41871,-1.52749 8.23417,-1.91188 1.06201,-0.39741 2.48062,-0.25103 3.34267,-1.0106 0.12616,-1.54813 -1.21508,-2.88825 -1.13133,-4.46666 -0.0521,-1.55201 -0.16983,-3.20295 0.73921,-4.556 0.46787,-0.77378 0.55924,-2.30817 -0.69423,-2.29714 -1.37699,-0.0791 -2.87684,-0.27214 -3.77323,-1.46125 -1.23824,-1.00268 -1.7041,-3.1205 -3.54825,-3.26704 -2.00311,0.4873 -2.57218,2.97999 -4.45461,3.68182 -1.24304,0.66857 -2.44624,-0.26686 -3.17543,-1.21878 -0.72719,-0.64861 -0.80879,-1.70178 -1.73556,-2.20142 -0.74688,-0.56709 -1.65264,-1.09917 -2.62904,-1.07199 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptMontevideo"
+ class="dept montevideo" />
+ <path
+ d="m 210.13434,368.56364 c -5.19976,-0.001 -9.62792,3.03963 -14.10946,5.24514 -2.42112,0.74941 -4.42503,-1.14931 -6.47942,-2.04191 -1.49201,-0.59819 -3.2894,-0.57449 -4.81456,-0.25524 -2.10052,1.17452 -3.6743,3.30979 -6.06161,4.00087 -1.1652,0.3548 -2.1198,1.3145 -2.14051,2.55875 -0.76507,1.47779 -0.42392,3.52634 -2.10197,4.4539 -2.30558,1.66671 -5.48233,0.83653 -7.74549,-0.53433 -1.08032,-0.67507 -2.22027,-1.0869 -3.50992,-0.8716 -1.87031,-0.0645 -3.79654,-0.0304 -5.45094,0.92737 -1.87979,0.75575 -1.56341,3.08699 -1.72914,4.71551 -0.0863,1.29375 -0.61242,2.47642 -0.46429,3.8221 -0.0811,1.90185 0.14194,3.86249 -0.0712,5.72779 -0.71163,1.9415 -2.17238,3.51474 -4.11191,4.28401 -0.94352,0.41561 -2.12101,1.12666 -1.80628,2.34819 0.0859,1.81939 1.15385,3.41799 1.02849,5.27066 0.29541,1.57534 2.32433,1.46752 3.36827,2.3163 1.64237,1.077 3.32066,2.33845 4.0882,4.21779 1.44164,-1.73647 4.23851,-2.26926 6.04231,-0.81676 1.36794,1.17377 2.05186,3.53162 4.07536,3.72011 1.6535,-0.24015 2.63354,-1.84288 3.63182,-3.01181 0.61546,-0.77446 2.00492,-0.91379 2.91188,-0.51686 1.28006,0.72164 1.46433,2.49651 2.70619,3.32448 1.13038,1.32111 2.98228,0.89329 4.44174,1.35913 1.03166,1.50246 -0.71802,3.0631 -0.80349,4.6262 -0.39969,2.28246 0.49803,4.56443 1.51057,6.55324 0.87077,0.71316 1.71416,-0.60803 2.4249,-0.98056 2.02736,-1.36293 3.64234,-3.5699 6.06649,-4.21992 2.59656,-0.1279 4.59238,-1.89674 6.82653,-2.948 2.37725,-1.05068 5.1532,-0.078 7.48448,-1.34715 1.49651,-0.60368 3.11219,-0.53262 4.59371,7.8e-4 2.44524,0.41277 4.93504,0.52467 7.18651,1.69094 4.12636,1.722 8.74596,0.8606 13.0934,1.00074 1.43724,0.38222 0.50213,-1.38361 0.61108,-2.16844 -0.1198,-2.13582 -1.7847,-3.67839 -3.17542,-5.1303 0.17444,-1.86611 0.33373,-3.73363 0.47566,-5.60248 -2.12915,-0.84694 -3.9502,-2.64086 -4.02392,-5.02819 -0.18176,-1.60348 0.50928,-3.42954 -0.68136,-4.78571 -1.64151,-2.33074 -3.95035,-4.31323 -5.23584,-6.81424 0.14463,-2.95533 1.01808,-5.8239 1.05763,-8.79993 -1.81405,-1.79882 -3.24798,-3.96007 -3.82464,-6.46392 -0.92125,-3.24101 -1.68877,-6.55757 -2.53263,-9.83303 -0.91704,0.005 -1.8343,-0.009 -2.75119,0.006 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptCanelones"
+ class="dept canelones" />
+ <path
+ d="m 140.56412,335.75918 c -2.63775,0.60872 -4.11995,3.28151 -6.65296,4.19228 -2.20055,1.2068 -5.26989,0.46517 -6.96153,2.56513 -1.84943,2.01974 -2.86182,5.1842 -5.68235,6.09383 -3.20838,0.0794 -6.36244,-0.89579 -9.53997,-1.31332 -2.37367,-0.39694 -4.73777,-0.85382 -7.12781,-1.09231 0.78417,1.4264 1.34233,2.91596 1.50415,4.5241 0.4706,2.38785 3.50579,2.85328 4.62815,4.74742 0.0728,1.54404 0.77013,3.14903 2.21124,3.93067 0.94046,0.76112 1.90381,1.91473 1.83196,3.13943 -1.98249,2.35205 -4.44617,4.41615 -7.33432,5.56419 -1.5648,0.23767 -3.06104,1.07038 -4.23607,2.09295 -0.51395,1.19601 -0.78965,2.68371 -0.4371,3.96256 0.46182,1.11059 1.57653,1.81027 2.08267,2.85229 0.21639,1.63891 -1.87101,2.38713 -1.80959,4.02968 -0.29128,1.54529 0.0275,3.26241 -0.36711,4.71621 -1.57132,1.76202 -3.597229,3.17314 -4.868393,5.13906 -0.279621,1.16377 1.385531,1.17548 2.123979,1.353 1.373994,0.0638 2.603984,0.70834 3.344574,1.86532 1.4473,1.73072 2.93767,3.43508 3.77491,5.52358 0.61503,1.12117 1.39143,2.15276 2.60249,2.64414 2.24685,1.53552 4.72068,2.93612 6.73097,4.77052 0.27972,0.48977 0.56658,0.92664 0.84207,1.40381 0.14617,1.11272 1.06832,1.93722 2.15337,2.08019 5.63586,3.29118 12.11789,4.73778 18.49336,5.87047 1.61666,0.86245 3.01418,2.08317 4.21676,3.45209 2.62254,-0.10161 5.24507,-0.20456 7.86787,-0.2999 0.94795,1.03472 2.44021,0.95955 3.52896,1.70372 0.61662,0.33427 0.47997,1.66961 1.45273,1.19324 1.39591,-0.83949 2.82315,-1.98661 3.54183,-3.4904 0.45233,-2.06236 -0.41868,-4.14926 -1.71628,-5.74922 -1.46776,-1.84764 -3.71106,-2.91925 -5.88161,-3.74563 -1.0864,-0.68108 -0.58712,-2.24329 -0.97705,-3.30533 -0.31131,-1.55465 -1.42226,-3.58099 -0.09,-4.94523 1.5651,-1.18222 3.77017,-1.6717 4.6153,-3.64353 1.26947,-2.78591 0.55807,-6.00687 0.66466,-8.97092 0.17294,-1.44706 -1.63867,-1.96702 -2.40666,-2.99335 -1.41589,-1.44558 -3.32549,-3.15266 -3.11115,-5.36638 0.50855,-1.43432 2.66179,-1.19248 3.12401,-2.70552 0.674,-1.47678 -0.26627,-2.98865 -0.25712,-4.46667 0.34312,-1.40778 1.22619,-2.98318 0.33273,-4.39371 -0.56667,-1.62012 -2.1821,-3.2628 -1.21336,-5.04371 0.56597,-1.65515 1.79231,-3.13844 2.0441,-4.85591 0.22598,-2.9483 -0.46363,-5.81857 -1.15888,-8.6451 -0.76277,-3.15222 -0.99936,-6.53866 -2.55007,-9.42575 -0.80216,-0.64244 -1.94529,-0.8069 -2.73914,-1.48777 -2.10098,-1.15586 -4.03031,-2.79028 -6.33721,-3.47661 -0.0857,8.4e-4 -0.17167,-0.004 -0.25712,0.006 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptSanJose"
+ class="dept sanJose " />
+ <path
+ d="m 362.84424,275.10825 c -1.6891,0.22796 -2.68129,1.73554 -3.27828,3.15858 -0.71683,0.94177 -1.88031,-0.33463 -2.65475,-0.58068 -1.22536,-0.51056 -2.21564,0.88827 -3.45184,0.86781 -1.29126,-0.0539 -2.56841,0.73037 -2.79618,2.0419 -0.27807,1.51565 -0.65652,3.36057 -2.12767,4.17314 -1.1055,0.21986 -2.52202,-0.67047 -3.15128,0.62905 -1.49521,1.40125 -2.61853,3.30197 -4.35662,4.3481 -1.07815,0.31427 -2.6658,0.13244 -3.08544,1.46124 -0.69227,2.01749 -0.32402,4.66812 -2.42978,5.93429 -0.842,0.42428 -1.94037,0.37728 -2.49406,1.28895 -1.07913,1.29542 -2.51251,2.96576 -4.42247,2.44389 -1.29115,-0.25674 -2.4914,0.4299 -3.09185,1.55058 -1.45433,1.62928 -3.96255,1.07513 -5.52808,2.53962 -0.98448,0.94397 -1.0415,2.60371 -2.22408,3.45848 -0.98391,1.28878 -2.95131,1.47484 -3.54185,3.08198 -0.52455,1.0779 -1.05622,2.46483 -2.17907,3.0182 -1.51041,0.23719 -3.11023,0.0794 -4.65387,0.12762 -1.39577,2.66824 -1.73644,5.75137 -1.14744,8.69122 0.0537,1.56887 0.63005,3.22858 0.21536,4.7662 -1.01966,2.10121 -3.26798,3.67132 -3.21399,6.20867 -0.29896,1.72661 0.073,3.90998 -1.56796,5.06214 -1.46535,1.11041 -2.87676,2.54696 -3.0602,4.49013 -0.17747,1.74981 -0.88015,3.62951 0.088,5.25766 0.69969,1.49957 1.18006,3.03941 0.95978,4.70938 -0.12859,2.13704 0.26539,4.37123 -0.27642,6.45116 -1.83719,2.60356 -1.78021,5.99204 -1.97248,9.05449 -0.19556,2.69523 0.29868,5.36443 0.34621,8.04645 -0.25543,2.67618 -0.4278,5.39003 -0.92563,8.02723 -1.10823,0.14224 -2.22853,0.0729 -3.34256,0.0893 0.0666,1.87626 -0.12722,3.84129 0.09,5.66628 0.8481,0.86272 1.59348,1.89085 1.348,3.16493 -0.0878,1.17367 0.0289,2.37949 0.89535,3.24791 0.30163,1.0475 0.51785,2.31201 0.20728,3.33837 -1.11199,2.1614 -2.43214,4.30789 -2.36618,6.81928 -0.37941,2.40519 0.1574,4.78792 1.02025,7.01828 0.31408,1.17234 0.91118,2.72524 -0.35264,3.58131 -0.7201,0.72739 -1.39647,1.72569 -0.82278,2.74381 0.25806,0.63025 0.50459,2.07858 1.47018,1.38392 4.88282,-2.3672 9.67261,-4.96989 14.54197,-7.33096 1.78771,-0.12689 2.23424,-2.83028 0.76975,-3.72644 -0.61269,-0.79791 -1.59458,-1.02869 -2.54388,-0.81043 -0.85023,-0.20444 -1.20014,-1.35511 -1.26633,-2.08019 0.70731,-1.06967 2.25112,-1.10379 3.05331,-2.13124 0.63443,-0.72046 2.11581,-1.47492 0.75206,-2.22694 -0.57794,-0.45287 -0.31011,-1.47391 0.49497,-1.39105 1.32865,-0.1962 2.96696,-0.73296 3.98536,0.49772 1.00379,0.65443 -0.0905,1.74728 -0.47567,2.42476 -0.54199,0.66576 -0.53121,1.57545 0.0386,2.20142 0.87497,1.352 0.67533,2.96994 0.39987,4.47797 -0.22974,0.99241 1.1195,-0.1562 1.72778,-0.22187 1.62934,-0.33518 3.34371,-0.15647 5.00742,-0.20419 0.21789,-1.34679 -0.57782,-3.18615 0.74565,-4.13485 3.47957,-3.01118 6.90807,-6.04298 9.95054,-9.52038 3.20036,-3.28073 7.32061,-5.4436 11.20398,-7.79116 2.11869,-1.20341 4.92259,-1.50191 6.55014,-3.45208 0.97088,-1.49589 -1.11837,-2.90183 -0.55924,-4.46029 0.63267,-2.00944 0.98254,-4.13249 1.74899,-6.08871 1.2072,-2.57913 2.71292,-5.07064 4.42188,-7.3368 0.93824,-1.14976 2.21608,-1.78786 3.44541,-2.53963 1.60629,-0.6228 2.40032,-2.30365 3.56111,-3.47123 0.85295,-1.18029 1.59523,-2.56884 3.0083,-3.17132 1.04536,-0.66576 2.03297,-1.41429 3.04687,-2.13124 -0.41548,-1.89707 -0.0967,-3.80872 0.68781,-5.56418 0.60487,-1.4246 1.36096,-2.80291 1.2663,-4.40925 0.083,-2.60222 0.12543,-5.28989 1.60649,-7.53148 1.24946,-2.48381 3.1443,-4.61275 4.62216,-6.91491 0.79067,-1.14606 1.83187,-2.01487 2.64842,-3.06931 0.23627,-1.0048 -1.12414,-0.67585 -1.58129,-1.18048 -1.66703,-0.72177 -1.40774,-2.70862 -1.73355,-4.17732 -1.07123,-0.33062 -2.65805,-0.0512 -3.94237,-0.15534 -1.38794,0.0803 -3.10036,-0.66916 -2.96973,-2.29714 -0.41667,-4.19177 0.26437,-8.53861 -0.82921,-12.63428 -0.39958,-1.36312 -1.64246,-2.28062 -1.92198,-3.68182 -1.00863,-1.66297 -1.07343,-3.66499 -0.63342,-5.53108 8.6e-4,-1.4597 0.43797,-2.85925 1.3405,-4.00206 0.33882,-0.89145 -0.7373,-1.14306 -1.25989,-1.52503 -1.10245,-0.92019 -0.88005,-2.58876 -0.63636,-3.84773 0.38051,-1.24814 1.71519,-2.07392 1.93482,-3.36275 -0.82715,-0.89198 -2.40735,-0.72501 -3.34256,-1.58887 -1.72877,-1.71111 -2.62458,-4.28487 -2.41049,-6.6936 0.0998,-0.97213 1.13705,-0.96711 1.84482,-1.18686 1.18667,-0.79681 0.1374,-2.44934 -0.0149,-3.50066 -0.0554,-0.0819 -0.33137,0.15854 -0.40929,0.11237 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptRocha"
+ class="dept rocha" />
+ <path
+ d="m 272.20308,290.6714 c -2.64326,-0.16589 -4.34405,2.58416 -6.91653,2.68636 -2.04038,-0.35574 -3.46015,-2.78266 -5.72735,-2.22056 -1.89502,0.83562 -4.23439,-0.12744 -5.92662,1.26981 -0.82529,0.71181 -2.19514,1.00605 -2.73189,1.95257 0.63752,1.90148 0.90992,3.98313 0.58494,5.98533 -0.44735,2.08857 -2.88862,2.73836 -4.49316,3.73284 -2.58566,0.95607 -3.75508,3.67633 -4.31632,6.16952 -0.39989,1.30243 -1.35326,2.44975 -2.79304,2.62344 -1.98028,0.6811 -4.66152,1.66935 -4.78886,4.11572 -0.17057,1.71904 0.75261,3.26927 1.87697,4.47942 0.80974,1.21467 1.21309,2.63588 0.67768,4.04998 -0.21589,2.41551 -1.27546,4.55257 -2.38753,6.65726 -0.8926,2.21847 -0.49211,4.75355 -1.29201,6.98076 -1.46967,0.66723 -2.85797,1.67406 -4.03037,2.7757 -0.66353,1.20187 -1.1157,2.52827 -2.0184,3.61162 -0.77491,1.33834 -2.36153,2.38548 -2.07398,4.09501 -0.18889,1.24212 0.33808,2.81931 -1.04623,3.50389 -1.77353,1.76037 -3.85927,3.25057 -5.474,5.15023 -0.88466,1.23656 -0.80987,2.83388 -1.2856,4.20506 -1.10541,1.4367 -2.85035,2.53742 -3.47755,4.30076 -0.43234,0.80978 -1.88846,1.13138 -1.20022,2.20865 1.20258,4.22615 1.85805,8.67974 3.64285,12.69086 0.72443,1.26388 2.1522,2.11535 2.60261,3.48302 -0.0949,2.81407 -0.9143,5.54372 -0.98917,8.34089 -0.0215,1.0389 1.04756,1.54384 1.40772,2.44389 1.34928,1.72173 3.10179,3.21463 4.20391,5.11115 0.26405,1.24156 0.0745,2.55705 0.13499,3.82857 4.08241,0.0457 8.27059,-0.11982 12.18105,-1.33999 3.36115,-1.45817 5.53396,-4.58367 8.53638,-6.57238 1.37654,-0.94786 2.78131,-2.24916 4.58317,-1.85048 1.66822,0.088 3.84676,0.48995 4.91099,-1.14857 1.30148,-1.62813 2.18035,-3.94396 4.42246,-4.46667 1.7165,-0.50792 3.69129,-0.39543 5.0267,-1.7739 1.0842,-0.98471 2.92065,0.0118 3.86965,-1.28895 0.81186,-1.01344 2.00656,-1.44872 3.11115,-1.9781 0.9363,-1.28795 0.7023,-3.08727 1.16345,-4.56875 0.3642,-1.4062 0.41771,-2.99385 1.14419,-4.24972 0.62994,-0.8161 2.33152,-0.74028 2.04778,-2.04687 0.23089,-2.21838 0.17112,-4.5962 0.71303,-6.69964 0.84777,-0.99321 2.51027,-1.59647 2.21098,-3.13263 -0.0887,-1.38807 0.45523,-2.81983 1.7776,-3.46066 1.29103,-0.71322 1.31507,-2.27668 1.76771,-3.46487 1.09004,-1.72912 3.17868,-2.33824 5.11516,-2.42394 1.85993,-0.34274 3.93807,-0.33611 5.61315,-1.27061 1.72081,-1.38323 1.12973,-3.92054 1.89627,-5.77478 0.35883,-1.61804 1.66756,-2.76486 3.12402,-3.45847 1.26043,-0.87781 1.25535,-2.70689 2.50048,-3.61799 0.51962,-0.64271 1.19363,-1.08294 1.90268,-1.41657 1.02405,-1.80175 0.70838,-4.05377 1.04705,-6.04048 0.40874,-1.44369 1.75389,-2.52714 2.50764,-3.85 1.38082,-2.0664 0.26574,-4.6752 0.22401,-6.94149 -0.42133,-2.59486 0.10222,-5.2045 1.293,-7.5305 1.78458,-0.29554 3.91371,0.28858 5.47665,-0.79763 1.2033,-1.30934 1.39612,-3.39819 3.19141,-4.192 1.37222,-0.84999 2.76507,-1.81371 3.15945,-3.48427 0.76868,-2.12776 3.24341,-2.5686 5.18097,-3.01181 0.96251,-0.39888 -0.10104,-1.17011 -0.6428,-1.38467 -2.25715,-1.12345 -4.51421,-2.41829 -6.44086,-3.95618 -1.41718,-1.19464 -2.72816,-2.6436 -3.03401,-4.51133 -0.60133,-1.5924 -2.76252,-1.29657 -4.05608,-0.84867 -2.10198,0.62302 -3.50508,2.41618 -5.3738,3.42018 -0.56895,0.56735 -0.25951,1.50658 -0.8485,2.10571 -1.23798,1.75909 -3.26163,3.1475 -5.51522,2.87782 -1.50972,0.0921 -2.96568,-0.31958 -4.21032,-1.1422 -0.79196,-0.42048 -1.78209,-0.44057 -2.53907,-0.83589 -1.30173,-1.99198 -4.07638,-1.58615 -6.13872,-1.68457 -1.21755,0.0757 -2.41696,0.0959 -3.37224,-0.7668 -1.49906,-0.91799 -3.49867,-1.50757 -4.2128,-3.24682 -1.00728,-1.39981 -2.53407,-2.62527 -4.38389,-2.40561 -0.36432,-0.01 -0.72846,-0.005 -1.09276,0 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptLavalleja"
+ class="dept lavalleja" />
+ <path
+ d="m 23.491037,331.20318 c -2.029127,0.15058 -3.74457,1.39352 -5.238827,2.66085 -3.702977,2.59246 -7.829483,4.78624 -12.2517582,5.92792 -0.7262917,0.24226 -2.393131,-0.0858 -2.0633766,1.1358 0.3581131,2.03754 0.2903165,4.31007 1.7162633,5.96618 0.2249674,0.52822 0.4362,1.00698 1.0092068,1.18685 1.4401594,1.04279 3.1130625,1.80827 4.4541977,3.0313 0.960231,0.70302 2.013373,1.60963 1.832381,2.92852 0.06407,2.01131 2.390329,2.56636 3.426111,3.9817 0.708419,0.99272 1.153255,2.14566 1.960551,3.07562 1.018092,1.48435 0.831052,3.37075 1.304871,5.00906 1.095599,0.97311 2.821574,0.61867 4.158924,1.02095 2.040152,0.41779 4.888836,0.40454 5.740191,2.72465 0.349827,1.06686 0.155692,2.5667 1.388447,3.13306 3.319603,2.49645 6.319514,5.37781 8.669794,8.7749 1.271099,1.86783 3.426727,3.19413 3.851181,5.54673 0.80491,2.62734 1.400397,5.52945 3.452607,7.50759 1.471855,0.64058 3.122292,-0.2706 4.641014,-0.31905 2.911355,-0.38859 5.856135,-0.78701 8.711916,-1.51393 2.700131,-0.9194 5.292344,-2.13675 8.110133,-2.61453 0.933885,1.05283 1.903577,2.46677 3.521972,2.25506 1.581041,0.27122 2.680869,-1.01511 3.780235,-1.85944 2.125727,-0.52749 4.457675,-0.19254 6.65873,-0.14943 4.38251,0.68651 8.877525,0.29443 13.306586,0.43147 1.406963,0.4191 2.158101,-0.68924 2.992627,-1.60197 1.284471,-1.44973 2.875386,-2.78451 3.968946,-4.30807 0.0634,-2.21977 -0.41717,-4.81899 1.34345,-6.54686 0.58732,-0.63211 0.63922,-1.52028 0.0386,-2.16951 -0.79645,-1.24465 -2.24786,-2.46025 -1.70341,-4.10297 0.11629,-1.32391 0.5344,-2.78916 1.9284,-3.28618 2.25109,-1.36054 5.13091,-1.53349 7.0515,-3.47762 1.06525,-1.00336 2.48962,-1.7699 3.22044,-3.03733 -0.18591,-1.41392 -1.24921,-2.67198 -2.46193,-3.37552 -1.02818,-0.97574 -1.52102,-2.32252 -1.71627,-3.66905 -1.10436,-1.6187 -3.25763,-2.217 -4.40318,-3.76476 -0.3293,-1.79614 -0.45478,-4.00246 -1.92197,-5.30896 -2.28506,-0.80882 -4.858926,-0.52687 -7.231505,-1.02732 -2.757645,-0.93862 -5.633768,1.39264 -8.330686,0.17228 -2.26,-1.07631 -3.407886,-3.55344 -5.815313,-4.4175 -1.289566,-0.84206 -2.827269,0.228 -4.250925,0.22523 -3.112756,0.44231 -6.085355,1.71097 -9.134422,2.55393 -2.363568,0.72518 -4.856354,1.65249 -7.327668,0.84073 -3.68142,-0.80888 -7.343962,-1.84594 -11.011167,-2.76934 -1.108041,-0.90756 -1.975671,-2.03718 -2.847594,-3.12666 -1.810515,-1.00234 -4.067574,-0.45312 -6.05517,-0.59981 -1.937596,-0.16778 -3.580017,1.31092 -5.534516,0.84866 -2.197058,-0.56179 -2.550485,-3.18168 -3.818228,-4.74104 -1.882468,-2.17074 -5.171898,-1.77935 -7.610747,-2.94163 -0.48458,-0.15111 -0.997771,-0.24098 -1.510572,-0.21056 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptColonia"
+ class="dept colonia" />
+ <path
+ d="m 251.29923,270.93511 c -2.42486,0.66243 -4.06128,2.79535 -5.86233,4.40924 -1.36547,1.31819 -2.78731,3.38678 -4.92385,3.15219 -1.11131,-0.42708 -2.2038,-1.36932 -3.47755,-0.86144 -1.87768,0.94169 -3.66875,2.15258 -5.80447,2.44392 -1.53706,0.39378 -2.04711,2.17638 -3.04045,3.23513 -1.08451,1.95833 -3.12305,3.05479 -5.21954,3.59248 -3.84859,1.33339 -6.90632,4.25145 -10.73475,5.61524 -1.966,0.23286 -3.98279,-0.17066 -5.90732,-0.22971 -0.80223,0.48309 -0.65607,1.71087 -1.51059,2.21418 -1.7759,1.60146 -3.92406,2.78044 -6.26729,3.2798 -2.55082,1.16015 -5.54354,1.25908 -8.11857,0.12125 -2.62428,-0.51886 -5.25659,0.59338 -7.84857,0.8997 -1.27087,0.52992 -0.92536,2.38086 -1.96054,3.17772 -1.05568,0.89535 -2.14347,2.58203 -3.76681,2.08019 -1.94241,-0.60705 -3.75941,-1.75126 -5.89446,-1.58248 -1.73262,0.01 -3.46302,0.1092 -5.19382,0.17867 -1.3344,-1.11772 -0.79401,-3.64936 -2.77048,-4.16675 -2.22827,-0.6181 -4.80434,-0.009 -6.87152,-1.16134 -0.72252,-0.39004 -0.76294,-1.22561 -1.22132,-1.7739 -0.63192,-0.58425 -1.64209,-0.0489 -1.44631,0.804 -0.18926,2.12958 0.18522,4.36937 -0.0993,6.42822 -0.52469,0.81895 -1.29202,1.59077 -2.35618,1.38843 -1.95855,0.10402 -3.92128,0.0388 -5.88162,0.0575 1.05771,0.94355 1.42161,2.21407 1.57098,3.55642 0.9686,4.29765 1.80452,8.65771 3.05719,12.8809 1.02866,2.52539 3.82109,4.25385 3.77256,7.20961 0.0805,3.13872 -0.004,6.33003 -0.45572,9.42551 -0.3899,1.48721 -1.68341,2.34331 -2.54548,3.50315 0.6066,2.21866 1.40498,4.38734 1.74198,6.68724 0.52822,3.69537 2.09019,7.28676 1.56201,11.07733 -0.17651,2.47083 -2.46017,4.52202 -2.1791,7.07647 0.33,1.01827 1.2787,1.7137 1.44558,2.82951 0.46568,1.14972 0.72794,2.4954 7.3e-4,3.59611 -0.92156,1.9282 1.17985,4.05983 -0.225,5.84495 -0.64757,1.04445 -1.91385,1.34763 -2.77689,2.10571 -0.72512,1.7716 0.9527,3.34108 2.03955,4.53019 0.94872,0.82009 1.75489,1.9938 2.85859,2.55267 0.95817,-0.34828 0.51421,-1.79827 0.77779,-2.56515 -0.0324,-1.51468 1.11259,-2.75516 2.54068,-3.06561 2.82601,-1.06896 6.22295,-1.28303 8.86693,0.42519 1.8333,1.09015 4.17523,1.49077 6.23081,0.85376 1.41036,-0.39896 2.05925,-1.77207 2.27107,-3.10691 0.37402,-1.60663 0.70395,-3.51907 2.44708,-4.22482 1.62103,-0.85698 3.3338,-1.55217 4.63352,-2.8917 1.39374,-1.43725 3.43408,-2.01968 5.3813,-1.49839 1.80628,0.22943 3.26434,1.32916 4.76957,2.20781 1.66141,0.81798 3.56741,0.34598 4.9995,-0.69488 3.80357,-2.10665 7.83543,-4.3798 12.31109,-4.37159 1.44727,0.005 3.10364,-0.13832 3.95323,-1.48038 0.48011,-0.83622 0.76804,-1.78136 1.61744,-2.37772 0.86535,-0.79487 2.10421,-1.48617 2.12365,-2.82914 0.42326,-2.04835 1.16319,-4.15317 3.07783,-5.25918 1.58178,-1.3906 3.33229,-2.81696 4.61005,-4.40795 0.17964,-1.61808 -0.55474,-3.53126 0.84709,-4.75466 1.23574,-1.60574 2.36681,-3.30709 3.0997,-5.17409 1.25594,-1.35212 3.12358,-2.11858 4.33247,-3.49039 0.51246,-2.43703 0.22949,-5.08371 1.66485,-7.26152 1.20887,-2.27334 1.83114,-4.89878 1.87055,-7.47209 -0.13893,-1.21536 -0.74011,-2.28772 -1.60058,-3.12665 -0.99826,-1.42067 -1.6113,-3.33384 -0.66207,-4.94525 1.0785,-2.33684 4.01699,-2.5976 6.08088,-3.63076 1.1299,-0.82129 1.12754,-2.46917 1.6777,-3.65629 0.51712,-2.26703 2.33398,-3.95294 4.44175,-4.77296 1.29738,-0.97751 3.58886,-1.35553 3.74109,-3.31169 0.12241,-1.51977 0.0699,-3.11946 -0.0771,-4.60705 -0.95788,-1.70765 -2.95373,-3.55879 -2.15338,-5.68543 1.41539,-1.57723 3.79116,-2.78522 3.86323,-5.17495 -0.044,-4.49618 -0.36807,-9.00522 -0.73278,-13.48296 -0.0926,-0.2977 -0.41018,-0.37787 -0.69423,-0.34456 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptFlorida"
+ class="dept florida" />
+ <path
+ d="m 97.895083,272.58778 c -0.793532,0.89454 -0.800713,2.43095 -1.299955,3.56137 -0.528005,1.50451 -0.605759,3.28126 -2.108692,4.19593 -2.996164,2.92321 -6.285473,5.54305 -8.496909,9.13832 -0.740875,1.25052 -1.61025,2.40252 -2.409583,3.59361 -0.521108,1.36688 0.05821,3.20112 1.337025,3.94981 1.512207,0.39411 2.514715,1.78954 2.468346,3.32446 0.274999,1.73769 0.725824,3.51392 2.050523,4.7602 0.615034,1.46633 0.49349,3.2438 1.523448,4.56238 0.912629,1.1731 1.808192,2.6271 3.278281,3.12667 1.128216,0.12823 2.931555,0.16882 3.278271,1.49951 -0.151412,3.88023 -1.645419,7.6298 -1.883407,11.51762 0.384959,3.40892 3.336675,5.79452 4.223966,9.05046 0.587633,2.53828 1.323513,5.08046 2.281173,7.51448 0.78974,1.0491 1.20603,2.42473 2.19195,3.29895 1.86525,0.67146 3.9405,0.49602 5.87612,1.00629 3.51974,0.47258 6.97934,1.50723 10.53454,1.62905 1.23889,-0.0252 2.37227,-0.94325 3.0276,-1.90791 1.40213,-1.70883 2.27434,-3.97821 4.24248,-5.16218 2.14705,-1.03465 4.82777,-0.52479 6.75515,-2.09512 2.1951,-1.18851 3.80365,-3.94809 6.59579,-3.59669 2.96872,1.27538 5.44256,3.64549 8.54282,4.60065 1.43847,0.1418 2.28524,-1.44884 2.66761,-2.60979 0.55167,-3.19918 0.54941,-6.49352 0.58496,-9.73733 -0.0467,-2.86499 -2.70124,-4.64278 -3.81823,-7.05096 -1.2768,-4.99342 -2.30565,-10.06097 -3.47757,-15.05265 -0.92157,-1.57671 -3.19717,-1.93019 -3.72179,-3.84133 -0.67646,-2.27099 0.23159,-5.22719 -1.81914,-6.9361 -0.5382,-1.00086 -1.79388,-1.52996 -2.50048,-2.46942 -1.73051,-1.67722 -2.61573,-4.07421 -4.60244,-5.48762 -3.44746,-1.65704 -7.3965,-1.65008 -10.97261,-2.78209 -1.38007,-0.61368 -1.69777,-2.36307 -2.82662,-3.28291 -0.92934,-1.34221 -2.85455,-0.87086 -4.25524,-1.35313 -3.9162,-0.66956 -7.83361,-1.42071 -11.68145,-2.30643 -1.92691,-1.36795 -3.2972,-3.45049 -5.322384,-4.66449 -0.08534,-0.0147 -0.181156,-0.0267 -0.263553,0.006 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptFlores"
+ class="dept flores" />
+ <path
+ d="m 68.840541,263.09293 c -1.383905,0.16148 -2.128273,1.60978 -3.458263,1.9717 -0.797521,0.54374 -2.155611,0.0969 -2.551908,1.19962 -0.807271,0.93879 -1.441738,2.26233 -2.67404,2.64811 -1.017559,-0.21158 -1.861198,-0.96135 -2.947172,-1.10449 -1.592644,-0.33881 -2.937131,-1.24834 -4.457882,-1.70313 -0.974668,-0.27692 -1.662371,0.65588 -2.641918,0.51048 -1.817056,0.1567 -3.298866,-1.1226 -4.76957,-1.93981 -1.577133,-0.34672 -2.406233,1.46984 -3.284698,2.41837 -0.648005,0.85063 -1.29535,1.78899 -2.468351,1.85047 -0.798841,0.38425 -2.349559,0.33189 -2.481204,1.42933 0.185844,1.27648 0.725898,3.56469 -1.118474,3.8222 -1.883822,-0.20513 -3.908712,-1.90781 -5.785196,-0.79123 -1.270687,0.88447 -0.222334,2.57624 -0.0055,3.72431 0.409582,1.79158 1.720442,3.31981 1.798896,5.1835 -0.320804,0.81773 -1.17331,1.07473 -1.960528,0.66998 -0.783993,-0.13619 -1.379006,-0.59344 -1.902688,-1.10389 -1.549261,-0.38557 -3.423048,0.64847 -3.613315,2.31216 -0.780924,1.68288 1.02786,3.54018 -0.333476,5.08335 -1.326038,1.34065 -3.251847,0.28239 -4.763153,-0.0766 -1.993753,-0.41558 -3.186538,1.67804 -4.278352,2.94359 -1.294217,1.66934 -2.572867,3.37331 -3.827341,5.05176 -2.1968146,0.60528 -4.4147068,1.20748 -6.2351587,2.64171 -0.7793002,0.26397 -0.6619077,1.08762 -0.1092838,1.51866 0.5897292,1.8389 0.4464209,3.92046 -0.8420597,5.44933 -1.581059,2.18027 -2.9466979,4.70369 -2.7190523,7.48485 -0.043709,1.64124 0.170171,3.24644 0.8484955,4.74105 0.6753634,1.59655 0.141334,3.23272 -0.3471096,4.79847 -0.6809803,2.51864 0.2669284,5.10732 0.2571198,7.65715 0.3310468,2.59532 0.094969,5.35146 0.9384853,7.83581 0.6089434,0.89337 1.8767495,0.2549 2.7447647,0.17227 4.8239378,-1.28071 9.4224568,-3.54044 13.2930958,-6.66808 1.870269,-1.78013 4.817396,-2.58945 7.173643,-1.32724 1.858319,0.66989 3.985172,0.62235 5.624489,1.85047 1.922105,1.21304 2.073434,3.97457 3.895363,5.22599 1.899789,0.94703 3.783305,-0.56571 5.695207,-0.55513 2.217255,-0.0561 4.817826,-0.6849 6.73654,0.72104 0.787733,0.95338 1.613886,1.88894 2.693337,2.49495 0.211933,1.01118 1.708818,0.63784 2.423348,1.06519 3.650399,0.84825 7.256536,2.04492 10.959744,2.56557 5.011553,-1.04184 9.793278,-3.15317 14.838752,-4.0275 1.563415,-0.14379 3.358584,-0.6369 4.625219,0.59455 1.793647,1.12804 2.961934,3.1607 4.994542,3.87325 2.597858,0.67217 5.136659,-0.8221 7.750929,-0.27767 2.380964,0.22457 4.744052,0.68447 7.155602,0.68605 -0.87978,-1.83786 -2.38806,-3.34973 -2.72866,-5.40825 -1.061406,-2.98425 -1.235017,-6.33858 -3.210807,-8.92976 -1.039567,-1.80281 -2.389055,-3.72627 -2.532626,-5.85771 0.307858,-2.95982 1.242028,-5.87368 1.662268,-8.84085 0.102661,-0.96615 0.834875,-2.53423 -0.492374,-2.98304 -1.370862,-0.62623 -3.133737,-0.3332 -4.048921,-1.76974 -1.552465,-1.61706 -2.893769,-3.56476 -2.957596,-5.83636 -0.239025,-1.49975 -1.963077,-2.22144 -1.983179,-3.82284 -0.532234,-1.56357 -0.189443,-3.88812 -2.021471,-4.68934 -1.346196,-0.26175 -2.253402,-1.78148 -2.410492,-3.05649 0.02645,-2.30365 2.172705,-3.7892 3.150562,-5.71409 2.312081,-3.87525 6.247598,-6.46794 9.255474,-9.77885 0.542437,-2.16072 1.498492,-4.25539 1.774124,-6.46389 -1.186144,-0.29594 -2.343143,0.72748 -3.494998,1.00733 -1.664818,0.98435 -3.560427,-0.0982 -5.343306,-0.18255 -2.152333,-0.18642 -3.663087,-1.9963 -5.522973,-2.93623 -0.945415,-0.49249 -1.899117,-1.57743 -3.03288,-0.90036 -1.250674,0.28258 -2.673637,0.96272 -3.811812,0.99543 -0.340894,-1.55652 0.06827,-3.3324 -0.662079,-4.78571 -1.720103,-1.57527 -4.086388,-2.38859 -6.383005,-2.67363 l -0.07713,0.006 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptSoriano"
+ class="dept soriano" />
+ <path
+ d="m 223.56886,210.33524 c -1.10722,2.07012 -1.64919,4.40827 -2.48121,6.60427 -3.14052,0.0184 -6.36687,-0.23206 -9.45559,-0.0638 -1.64142,1.20122 -3.25576,2.7356 -4.91741,3.71372 -1.07207,-0.86909 -2.00314,-2.21561 -3.56687,-2.08391 -1.57275,-0.66833 -1.54159,1.10081 -2.00098,2.12995 -0.77279,1.99625 -1.34608,4.13702 -2.13932,6.09243 -1.38023,0.53741 -3.04892,0.4817 -4.51081,0.75954 -1.91607,0.26355 -3.91634,0.24179 -5.55984,1.39826 -4.67113,2.359 -9.46868,4.54307 -14.06078,7.01247 -2.33916,2.14021 -4.55094,4.49211 -6.96992,6.50092 -4.47557,1.57069 -9.13931,2.68892 -13.44467,4.66491 -0.90307,0.37326 -1.63598,1.2505 -2.42978,1.67181 -1.39592,-0.79495 -2.42207,-2.4266 -4.23288,-2.21314 -2.35426,-0.26784 -4.707,-0.54903 -7.06111,-0.81783 -1.33604,1.0954 -2.46782,2.58023 -3.98536,3.35639 -1.21642,-0.43324 -2.25134,-1.42438 -3.42613,-1.78668 -3.25672,0.95932 -7.0984,1.05802 -9.60217,3.58857 -1.00713,0.71732 -1.80519,1.75953 -1.76894,3.06038 -0.1789,0.49488 0.0301,1.82743 -0.83565,1.36553 -0.94813,-0.11467 -2.18379,-1.26175 -2.67435,0.0476 -0.9598,0.90964 -1.14653,2.21973 -1.06032,3.48103 0.17151,1.08442 -1.05499,0.16934 -1.608,0.0976 -1.11915,-0.41426 -2.61255,-1.21776 -3.54725,-0.0147 -0.68468,0.76038 -2.15362,1.25189 -2.37192,2.16952 0.29466,1.2804 0.71142,2.54121 0.8742,3.82857 -2.9809,-0.54383 -5.8331,-1.74738 -8.81279,-2.31628 -2.752134,1.45008 -5.305392,3.26152 -7.957862,4.88781 3.120655,3.19403 6.117382,6.55341 9.539152,9.39913 5.06812,1.34243 10.3458,1.93242 15.42077,3.10114 1.25812,0.96031 1.91131,2.44764 2.90545,3.60525 2.13388,1.29779 4.83521,1.03451 7.19436,1.71009 2.56676,0.52992 5.33483,1.59247 6.7351,3.9498 1.38936,2.56743 3.82747,4.20567 5.63093,6.40647 0.93207,1.527 0.51761,3.52129 0.94492,5.21962 0.1037,1.49867 1.13009,3.1352 2.84118,2.94163 2.32844,-0.0609 4.73175,0.25599 7.01938,-0.19143 1.2657,-0.73929 0.76292,-2.52702 0.97062,-3.73287 0.0466,-1.55472 0.0857,-3.10965 0.12855,-4.66446 0.75036,-0.63479 1.83674,-0.26212 2.15339,0.63171 0.73415,1.94934 3.154,1.81361 4.86432,2.01468 1.6419,0.15643 3.99552,0.18704 4.57198,2.09465 0.48392,0.72646 0.1256,2.43104 1.18913,2.33726 3.17718,0.0357 6.6074,-0.58203 9.53919,0.9617 0.99439,0.34087 2.30836,0.9806 3.17543,0.0255 1.43812,-0.90413 2.33125,-2.33488 2.8026,-3.92429 0.22986,-1.19083 1.77468,-0.83508 2.63149,-1.19501 1.89092,-0.17881 3.77789,-1.03185 5.67348,-0.7448 2.10069,0.75583 4.42222,1.50219 6.64655,0.67638 1.40141,-0.5251 2.94468,-0.71771 4.30675,-1.27619 1.41801,-1.0904 3.54299,-1.51101 4.3132,-3.31171 0.31908,-0.78541 0.81067,-1.97327 1.88984,-1.5761 2.7361,0.4806 5.76797,0.47505 8.13784,-1.12942 3.05892,-1.85762 6.06118,-3.92631 9.57128,-4.83676 2.81309,-1.04663 3.63659,-4.34984 5.91375,-6.05553 1.14652,-0.41755 2.41641,-0.51942 3.49683,-1.16133 1.47184,-0.50553 2.89856,-1.91763 4.53817,-1.51867 1.06647,0.75055 2.48788,1.22953 3.71538,0.51048 1.51855,-0.52955 1.97629,-2.24209 3.24615,-3.11391 1.74575,-1.6706 3.70449,-3.24945 5.8816,-4.35817 0.60088,-0.73388 0.42349,-1.86633 1.24703,-2.48858 1.47108,-1.81255 4.0945,-1.86931 5.66949,-3.48399 0.34518,-0.64101 1.43732,-1.46327 0.82279,-2.20144 -2.3856,-0.2742 -4.87026,-0.45763 -7.22256,0.16584 -2.04293,0.43953 -4.27685,-0.0738 -5.47124,-1.88242 -1.0053,-0.93381 -1.79441,-2.32776 -3.20906,-2.63523 -2.23975,-1.23743 -4.42944,-2.56985 -6.06803,-4.52408 -0.72275,-1.29003 -1.4618,-2.66883 -1.86215,-4.06359 0.22832,-2.71461 1.02384,-6.00391 -0.96617,-8.25803 -0.58889,-0.8932 -0.15041,-2.04799 0.86135,-2.45029 0.84908,-0.45371 2.06364,-1.34414 1.33702,-2.43113 -0.53957,-1.53169 -1.56082,-2.93244 -2.00031,-4.44412 0.41093,-3.08225 1.3548,-5.99732 2.05818,-9.00054 0.38797,-2.26872 0.51934,-4.74445 -0.3214,-6.91696 -0.84097,-0.80459 -1.88212,0.45482 -2.86047,0.3382 -1.72305,0.0679 -2.07572,-2.20797 -3.63825,-2.55238 -1.29017,-0.4711 -3.00634,-0.73559 -3.39398,-2.3099 -0.60705,-0.9045 -1.88994,-0.77202 -2.84759,-0.91247 l -0.1157,0.12123 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptDurazno"
+ class="dept durazno" />
+ <path
+ d="m 338.2893,234.83809 c -1.71956,0.28674 -2.9977,1.76953 -4.15891,2.9416 -0.23262,0.6548 -1.00827,1.23341 -0.54639,2.02915 0.28822,0.98648 1.75606,1.9414 1.07349,3.01181 -0.78243,0.99889 -2.24488,0.48558 -3.04688,-0.24248 -1.72576,-0.75377 -3.14214,-2.13598 -4.76957,-3.01181 -1.57222,-0.45728 -3.36868,0.0531 -4.85956,-0.63809 -0.69195,-0.95872 -1.90449,-1.16762 -3.04046,-1.07838 -1.39071,-0.16939 -2.71632,-0.74633 -4.13963,-0.83591 -1.03512,-0.16668 -1.84492,-0.80308 -2.4619,-1.58248 -1.71987,-1.06526 -3.82244,0.35434 -4.71174,1.88239 -1.11222,1.68931 -3.40314,1.12015 -5.13596,1.19137 -1.44185,0.15696 -3.35233,-0.41809 -4.46103,0.77397 -0.52097,1.06959 -0.92773,2.72661 -2.33979,2.87142 -0.85108,0.0223 -1.65143,-0.99467 -2.32326,-0.79995 -0.72437,0.56487 -0.84933,1.43386 -1.16071,2.191 -0.62293,1.16029 -2.00798,2.05747 -3.31685,1.35914 -1.74613,-0.58721 -3.71945,-1.31144 -5.46684,-0.3352 -1.45441,0.86795 -3.14626,1.00308 -4.81153,0.88396 -2.61816,-0.15031 -5.07783,0.90748 -7.28935,2.16951 -1.70751,0.71645 -3.22134,1.84362 -4.42246,3.216 -1.59919,1.2188 -3.63076,1.75605 -5.23881,2.97353 -1.03671,0.51138 -2.18231,1.30659 -2.58406,2.44392 -0.33501,1.32915 -0.1066,2.70174 0.64922,3.84132 0.57581,1.25239 0.54314,2.77855 -0.55922,3.72009 -1.25983,1.7717 -3.40275,2.3213 -5.20026,3.31809 -1.52057,0.85407 -1.78711,2.72725 -1.54914,4.30076 0.12484,4.47408 0.59724,8.96178 0.69931,13.41688 -0.28814,1.66399 -1.19991,3.16039 -2.68556,4.02227 -1.02866,0.45624 -1.69073,1.54846 -1.27917,2.64808 0.31015,0.82744 0.50651,2.11308 1.46558,2.38648 1.58135,-0.76222 2.99652,-2.06343 4.69244,-2.64809 1.63543,-0.12515 3.32637,-0.093 4.91741,-0.58068 2.31076,-0.15042 3.63545,2.91152 6.01019,2.22058 2.48083,-1.12705 4.84094,-3.21459 7.77787,-2.65448 2.616,0.32877 3.78023,2.8495 5.56021,4.422 1.18986,0.7051 2.42542,1.45031 3.63824,2.09297 2.46518,0.24447 5.17657,-0.2879 7.45648,0.82312 0.86532,0.84019 1.98848,1.24298 3.12022,1.60549 1.35679,0.76334 2.8256,1.36652 4.42624,1.17024 1.5462,0.20568 3.02176,-0.33843 4.13963,-1.37829 1.2002,-0.82389 1.26682,-2.32875 1.78057,-3.52868 0.46304,-0.57208 1.34862,-0.3733 1.83841,-0.97627 1.79086,-1.55337 4.14469,-3.25396 6.64011,-2.72468 0.9781,0.24135 1.88604,0.95733 1.88983,2.02278 0.4651,2.24623 2.52031,3.68394 4.31961,4.88141 1.91534,1.19474 3.95736,2.41917 6.08732,3.29896 0.98715,0.0614 1.24185,-1.36379 2.28837,-1.36552 1.37427,-0.32981 3.1042,0.40364 4.21032,-0.82315 0.97986,-0.95363 1.59365,-2.38286 3.09189,-2.62256 1.69585,-0.4392 2.51049,-2.17246 2.58857,-3.80724 0.12731,-1.50128 0.57481,-3.3699 2.30312,-3.69039 0.91433,-0.11886 1.96192,-0.0909 2.55192,-0.93799 1.43596,-1.47613 2.80477,-2.98459 4.26176,-4.44114 1.09133,0.17793 2.59587,0.45729 3.17542,-0.7721 0.94426,-1.58286 0.53615,-3.94253 2.37195,-4.95799 1.56195,-0.37465 3.2447,-0.61211 4.67314,-1.45486 0.89609,0.29355 1.8289,1.20236 2.70292,1.13615 0.75686,-0.75739 0.71453,-2.08661 1.81597,-2.57187 0.56608,-0.61633 1.96727,-0.49185 1.89625,-1.57609 -0.10719,-0.71401 -0.10166,-1.46485 0.62994,-1.83771 0.94531,-1.24525 -0.46148,-2.78683 -0.41285,-4.01609 0.22306,-0.87968 1.35847,-1.88508 2.15484,-0.98657 0.5774,0.47296 0.67994,2.00605 1.64557,1.55695 1.15702,-1.65543 2.21337,-3.4032 3.80538,-4.63896 1.70086,-1.50183 2.15203,-4.2189 4.48674,-5.0218 2.84977,-0.45567 5.80822,0.0597 8.69477,0.0246 1.7237,0.39818 1.01229,-0.42443 0.22729,-1.28803 -0.87234,-0.98635 0.56998,-1.9624 1.20202,-2.57154 0.5414,-0.537 1.62173,-0.82201 1.42702,-1.8058 -0.35697,-0.93327 0.57521,-1.43662 1.29203,-1.65905 1.03994,-0.70612 1.81605,-1.92992 1.39487,-3.216 -0.30268,-1.89145 -1.08869,-3.64879 -1.63271,-5.45572 -0.89416,-0.83152 -2.2743,-0.17188 -3.25257,0.17867 -1.25066,0.42372 -2.42488,-0.0246 -3.39398,-0.79124 -1.57269,-1.01848 -3.80795,-0.15583 -5.17453,-1.58247 -2.05553,-1.3493 -4.58202,-0.48579 -6.78154,-0.1021 -4.4484,0.50104 -8.84959,-1.77464 -13.26739,-0.4658 -2.70969,1.09254 -5.84774,0.82893 -8.60065,-0.0766 -2.82242,-1.54309 -4.53506,-4.88576 -7.9,-5.41743 -0.36007,-0.0714 -0.73298,-0.0905 -1.09919,-0.0574 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptTreintaYTres"
+ class="dept treintaYTres" />
+ <path
+ d="m 106.24506,203.16942 c -2.05595,0.48634 -3.68182,2.0647 -5.6952,2.57791 -2.554705,0.0625 -5.415507,0.0824 -7.37935,1.9462 -1.806989,1.23033 -3.440549,3.09019 -5.682343,3.43295 -1.447442,-0.0666 -2.308643,-1.42994 -3.805372,-1.35276 -1.171338,-0.26177 -2.222817,-0.1756 -2.892599,0.93162 -1.017864,1.44623 -2.972845,0.66852 -4.377475,0.4339 -1.460627,-0.361 -3.449519,-0.93983 -4.480302,0.54877 -0.978825,1.06484 -2.102664,2.34777 -3.663962,2.4056 -1.773034,0.6187 -1.120544,2.93039 -2.429784,3.96258 -2.165376,1.86456 -5.078977,2.33602 -7.835733,2.5779 -2.286478,0.47781 -4.735405,0.16723 -6.974365,0.85505 -1.234438,1.39684 -0.752523,3.86367 -2.455493,4.87504 -1.370988,0.2949 -2.710459,-0.0402 -3.869658,-0.76571 -2.263951,-0.55131 -4.826695,0.44238 -6.916524,-0.804 -1.336713,-0.58157 -3.021629,0.13928 -4.261771,-0.64448 -1.020065,-1.27855 -1.347659,-3.22858 -3.07258,-3.84133 -2.183708,-0.64625 -2.976668,-3.03462 -4.743864,-4.21143 -2.783971,-0.91767 -5.749467,-0.41742 -8.574944,0.0574 -0.740876,0.60058 0.149642,1.78669 0.168339,2.57108 0.501116,2.12236 1.530932,4.07838 1.962649,6.19987 2.165525,6.006 2.193871,12.52884 3.583508,18.68626 1.120589,3.2141 4.031351,5.283 5.765903,8.1102 0.245846,1.05171 1.20896,1.84386 0.964201,2.97989 -0.274625,3.75343 -1.593713,7.31698 -2.230506,11.01991 -0.516953,1.3494 -1.865785,2.282 -2.692889,3.46708 -1.253425,1.75072 -3.076551,2.96365 -5.045555,3.86385 -1.567462,1.24486 -3.616666,0.46347 -5.449892,0.59057 -2.264319,0.088 -4.6999019,-0.49873 -6.8605941,0.30993 -1.6780686,1.24241 -1.3388555,3.66033 -1.0839526,5.46413 0.3540625,3.84783 1.4532201,7.71102 0.993963,11.59213 -0.244266,1.36636 -1.0593167,2.56029 -2.2498006,3.31172 -0.8966709,0.42225 -1.8221563,1.03148 -1.8409147,2.15415 -0.1222658,1.0952 -0.8948603,2.24257 -0.6017242,3.33984 1.008526,1.0614 2.4012132,-0.27232 3.2938698,-0.81187 1.5563382,-1.23922 3.5482757,-1.5103 5.3389394,-2.11697 2.039926,-2.54552 3.852601,-5.35628 6.113016,-7.68266 1.392971,-0.41901 2.874498,-0.29738 4.197489,0.22331 0.897392,0.172 2.350777,0.57442 2.680465,-0.63169 0.634553,-1.91364 -0.814719,-4.02437 0.494968,-5.80667 0.751136,-1.08394 2.197819,-1.61396 3.471118,-1.54419 0.876673,0.71181 2.17663,1.78479 3.329699,1.13581 0.515617,-0.81264 -0.279747,-1.81769 -0.456397,-2.65447 -0.822576,-1.74465 -1.44462,-3.67839 -1.780545,-5.55782 0.88869,-2.61662 4.220364,-1.41539 6.048735,-0.66362 1.20293,0.51244 2.243935,-0.88406 1.767708,-1.96534 -0.220692,-0.80241 -0.522034,-2.35547 0.67493,-2.52685 1.492282,-0.59046 3.375714,-0.81392 4.201233,-2.38206 0.881737,-0.91886 1.62105,-2.62483 3.10741,-2.59508 1.760941,0.84725 3.525501,2.32904 5.647091,1.88978 1.342169,-0.19255 2.807625,-0.48957 3.982048,0.40099 1.931848,0.84564 4.01779,1.24981 5.888041,2.25886 1.050183,-1.00817 1.607038,-2.39454 2.629043,-3.38829 0.95126,-0.56212 2.195882,-0.28851 3.059726,-1.1039 1.086407,-0.72245 2.119017,-1.90777 3.567545,-1.4421 2.142303,0.43605 4.422979,1.27527 5.843039,2.99266 0.79055,1.25007 0.102312,2.89344 0.687806,4.17314 0.884039,0.32179 1.940455,-0.52506 2.873304,-0.6317 0.833686,-0.20113 1.767075,-0.82932 2.494068,0 1.935277,1.05648 3.632503,2.60959 5.663071,3.45208 1.746252,0.37926 3.561027,0.65561 5.322379,0.81676 1.421234,-0.68038 3.133777,-0.98321 4.390316,-1.89513 0.04735,-0.99867 -1.131027,-1.66901 -1.664847,-2.44391 -0.442425,-0.61409 -1.415285,-1.29792 -1.48488,-1.95894 2.53998,-1.88701 5.259647,-3.59959 8.009296,-5.15581 2.6781,0.52671 5.29605,1.63858 7.99643,2.1376 0.61706,-0.70594 -0.25704,-1.81335 -0.26961,-2.66876 -0.31155,-0.63767 -0.0255,-1.23009 0.591,-1.5299 1.01719,-0.83679 2.01437,-1.69135 3.09188,-2.42476 1.18417,0.36891 2.3169,0.92304 3.50325,1.23791 0.79408,-0.72912 -0.29995,-1.98259 0.60423,-2.72466 0.5671,-0.57935 0.93338,-1.71544 1.73556,-1.86324 0.84833,-0.0405 2.40766,1.52737 2.36579,0.10465 0.16665,-1.18453 0.13746,-2.55121 1.32388,-3.21855 1.52741,-1.1665 2.82243,-2.82971 4.87615,-2.96799 1.8621,-0.45798 3.72531,-0.91161 5.58862,-1.36469 0.89038,-2.47807 1.91725,-4.94906 2.71906,-7.43379 -0.16157,-1.53109 -0.50122,-3.04644 -0.44996,-4.58791 1.06392,-1.70087 2.52561,-3.23234 3.29988,-5.0673 1.17355,-5.02377 2.86468,-9.99328 2.78742,-15.20497 -0.026,-0.72529 -1.33525,-0.43632 -1.85126,-0.93162 -2.01457,-0.89842 -3.39755,-2.63412 -5.00098,-4.04552 -1.04609,-0.73062 -2.22275,-1.56702 -3.50969,-1.58247 -2.0477,-0.88497 -4.39296,-0.24012 -6.55656,-0.44028 -2.29285,0.0699 -4.54329,-0.93411 -6.82009,-0.32544 -2.94252,0.62507 -5.46361,-1.23229 -7.83574,-2.64173 -1.23463,-0.53327 -2.48445,-1.37317 -3.85036,-1.48676 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptRioNegro"
+ class="dept rioNegro" />
+ <path
+ d="m 301.32189,143.08001 c -1.34128,0.54786 -1.64175,2.26739 -2.25757,3.42813 -0.65576,1.81468 -0.70109,4.01745 0.47421,5.65045 0.94324,1.34622 0.43988,3.03818 -0.27742,4.35647 -1.81527,4.27938 -3.14647,8.84063 -5.68496,12.75237 -0.32157,0.99929 1.20461,0.85008 1.80627,1.10391 1.65728,0.39066 1.41857,2.61381 0.65567,3.69456 -0.78663,0.90842 -2.51701,1.46401 -2.26266,2.92886 0.51554,1.40907 0.42049,3.24303 -0.91278,4.13486 -2.01639,0.839 -4.40835,0.56475 -6.55435,0.99332 -1.04314,0.0734 -2.02929,0.78898 -3.0298,0.19353 -1.12394,-0.34952 -1.97735,-1.50752 -3.14328,-1.58886 -1.54228,0.76077 -0.71529,3.04702 -2.01197,4.02 -0.97723,1.38545 -2.31153,2.66443 -2.8476,4.29438 -0.0452,1.2209 1.00211,2.22425 0.66851,3.50314 -0.21669,1.63034 -1.27804,3.07986 -2.08267,4.51134 -0.95547,0.90879 -0.94934,2.45775 -1.92839,3.40104 -0.45729,0.73041 -1.24025,0.87804 -2.01197,1.00182 -1.51426,0.62919 -2.34973,2.1829 -3.16258,3.46485 -0.97909,1.15308 -2.84706,0.36662 -3.75395,1.63354 -0.93874,2.26231 -2.25928,4.39234 -4.41348,5.64839 -1.21948,1.0814 -2.58903,1.89959 -4.25745,2.00654 -1.56334,0.23145 -3.16787,0.94974 -4.62216,-0.009 -2.24894,-0.66919 -4.42312,-2.11821 -6.83939,-1.94148 -1.66787,0.42337 -3.05516,1.59076 -4.75672,1.95257 -0.7591,0.10844 -1.56995,0.74348 -1.1623,1.58255 0.70432,2.56252 0.58699,5.24313 -0.0667,7.77944 -0.75598,2.71097 -1.56299,5.46088 -1.83713,8.24943 0.646,1.62593 1.7812,3.08842 2.25621,4.74743 0.17291,1.04202 -0.81422,1.6988 -1.65842,1.99722 -0.79915,0.45406 -1.3511,1.47888 -0.68779,2.29714 1.75041,2.32885 1.22588,5.45577 0.89318,8.1569 0.12625,1.31778 1.09436,2.5204 1.65873,3.73719 0.6675,1.29024 2.03217,2.04971 3.12401,2.83953 0.32777,0.5782 1.16547,0.57878 1.61343,1.09753 1.5291,0.87205 3.2199,1.53535 4.24925,3.04433 0.9312,1.08221 1.97885,2.45131 3.61218,2.19442 2.64334,0.0643 5.22404,-0.89993 7.8743,-0.3701 0.65945,0.18271 1.94552,0.008 1.58771,-0.95075 -0.78724,-1.50043 -1.60511,-3.40681 -0.60422,-5.00266 1.83224,-2.45806 5.07183,-3.10167 7.45005,-4.84953 1.60531,-1.72318 3.57623,-3.02908 5.75389,-3.99988 2.42708,-1.52446 5.32464,-1.54843 8.09843,-1.6345 1.87462,-0.16043 3.5825,-1.30929 5.40332,-1.52261 1.68229,0.34106 3.33526,1.36589 5.08075,1.05042 1.47229,-0.53822 1.18668,-2.5406 2.44906,-3.34999 0.87472,-0.76959 1.61511,0.78097 2.59691,0.41475 1.51104,-0.17915 1.2785,-2.06224 2.05054,-2.948 1.86667,-0.74926 4.02275,-0.32717 6.00342,-0.56669 1.17832,-0.15333 2.6616,0.16803 3.39431,-1.00302 1.00927,-1.41455 2.69091,-3.11436 4.60245,-2.32267 1.18997,0.59457 2.02974,1.96203 3.52254,1.8441 1.6679,0.31497 3.27424,0.92456 5.01383,0.8359 1.22766,-0.0474 1.68646,1.54015 2.97615,1.42296 1.70276,0.21716 3.69274,-0.18364 4.98813,1.21876 1.33871,1.00329 2.86189,1.80822 4.24248,2.68639 0.64708,0.13305 2.15073,0.28248 1.97982,-0.73382 -0.55988,-1.24148 -2.00004,-2.56633 -1.04776,-3.99448 0.9911,-1.53367 2.61255,-2.49829 3.98536,-3.65628 2.01957,-0.19175 4.04064,0.44049 5.46341,1.89661 1.98264,1.64531 3.83057,4.03288 6.65778,4.13628 2.23677,0.40985 4.54742,0.11468 6.65498,-0.62184 2.74733,-0.68026 5.67208,-0.44499 8.24713,0.68915 1.67562,0.22156 3.33557,-0.4281 5.03917,-0.29917 2.15973,-0.16284 4.60881,-1.11197 6.52479,0.3885 1.37174,1.4726 3.79251,0.30079 5.24524,1.67181 1.05705,0.86789 2.56515,1.03186 3.74753,0.29989 1.26231,-0.55292 2.82425,0.109 3.92108,-0.85504 2.53271,-0.77644 4.55407,-2.52966 6.79439,-3.8541 0.66784,-0.0792 1.6045,-0.21077 1.69698,-1.07837 0.22374,-1.46853 0.55234,-2.92329 1.11848,-4.31352 -0.87969,-1.07311 -2.03078,-2.03447 -3.47113,-2.13124 -1.36612,-0.60928 -2.355,-2.17947 -4.06232,-1.79775 -1.74595,0.11668 -3.66787,-0.0614 -4.93687,-1.37359 -1.1714,-0.99416 -2.78977,-0.70838 -3.99821,-1.65904 -2.16539,-1.10226 -3.44231,-3.21255 -4.42888,-5.32172 -0.57412,-1.23317 -1.73896,-1.93932 -2.87332,-2.55875 -2.80868,-2.25414 -5.78046,-4.64276 -7.45004,-7.88686 -0.95439,-1.62917 -2.61847,-2.69398 -3.45827,-4.39011 -0.68525,-2.46823 -1.00838,-5.03493 -0.5528,-7.58056 -0.0402,-1.58101 -1.25998,-2.82798 -1.49373,-4.39574 -0.2225,-1.41273 -0.67735,-2.84726 -1.95116,-3.65868 -0.81614,-0.69929 -1.56159,-1.58586 -1.51752,-2.71025 -0.68576,-2.32596 -2.58085,-4.25459 -2.42736,-6.80141 -0.0798,-0.90672 -0.0577,-2.46078 -1.35874,-2.39991 -1.49471,-0.0557 -3.15726,0.0378 -4.2489,-1.18687 -1.44329,-1.48838 -3.55752,-2.68453 -4.1782,-4.76656 0.1463,-1.58596 -1.51791,-2.31611 -2.4812,-3.2479 -1.67229,-1.5899 -4.0645,-1.81237 -6.17732,-2.33543 -1.62304,-0.31139 -2.0493,-2.09437 -3.2847,-2.90333 -0.63163,-0.29982 -1.35434,-0.3517 -1.78698,-0.95714 -0.62636,-0.44723 -1.68206,-1.27036 -2.26909,-0.32543 -0.93022,1.05052 -1.94233,2.7454 -3.56111,2.54599 -1.37356,-0.94945 -2.24069,-2.45489 -3.64466,-3.40104 -4.12643,-3.54023 -8.74761,-6.59987 -12.59888,-10.42009 -2.09318,-2.7281 -3.82154,-6.1801 -7.29578,-7.39552 -0.59117,-0.17969 -1.17541,-0.44256 -1.79341,-0.42753 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptCerroLargo"
+ class="dept cerroLargo" />
+ <path
+ d="m 177.28728,104.05412 c -2.07971,-0.0929 -3.61924,1.53312 -4.4996,3.216 -0.79244,1.48218 -1.50452,3.07384 -2.15339,4.59429 0.32716,1.38188 0.85274,3.3343 -0.65565,4.22419 -1.22321,0.92563 -1.77645,2.7586 -3.35541,3.13943 -1.42126,0.64094 -2.66212,1.76434 -3.0441,3.32342 -0.34546,1.30423 -1.26893,2.21179 -2.52896,2.6619 -1.09974,0.35899 -1.48758,1.52845 -1.3123,2.58422 -0.0234,1.16702 0.39576,2.49698 -0.7559,3.26132 -0.99765,1.05538 -2.34978,2.63108 -1.33222,4.11513 0.67423,0.96335 1.51318,1.8601 1.42059,3.13942 0.30577,3.35543 0.68263,6.73659 1.26631,10.02448 0.78972,0.62314 1.89014,1.05122 2.30121,2.09294 1.02396,2.30404 0.44559,5.01149 0.87421,7.35086 1.05023,0.97476 2.59542,1.90531 2.46835,3.54781 -0.0379,0.76602 0.57302,2.05417 -0.53351,2.28438 -1.12501,0.13811 -2.13677,0.89674 -2.70619,1.84409 -0.33917,3.25987 -0.33084,6.60711 -0.89848,9.81122 -1.45925,3.05838 -2.75421,6.19578 -3.20333,9.56948 -0.47595,2.20842 -0.76869,4.50663 -1.45198,6.63443 -1.89113,2.87415 -4.53527,5.07621 -7.45014,6.90666 -2.0071,0.96057 -2.70386,3.16271 -3.90469,4.87537 -2.30665,3.84254 -3.32335,8.39999 -3.91906,12.8283 -0.0812,4.8545 -1.62048,9.47101 -2.73093,14.16671 -1.0749,1.70464 -2.43165,3.33723 -3.3297,5.092 0.0589,1.96121 1.0046,4.02953 -0.0609,5.85679 -0.59282,1.85657 -1.57817,3.6747 -1.95109,5.55874 0.68507,1.08274 2.06679,1.48169 3.05973,2.22694 1.2221,-1.20523 2.44904,-2.4056 3.67039,-3.61161 2.99979,0.46124 6.14467,0.4337 9.04419,1.23153 0.85568,0.49982 1.55887,1.22255 2.35265,1.81219 1.99173,-1.7715 4.48704,-2.67612 7.00378,-3.43718 3.03816,-1.02979 6.1466,-1.93544 9.14978,-3.02035 2.41292,-2.18009 4.6375,-4.62664 7.16912,-6.63947 5.26014,-2.5511 10.47008,-5.26362 15.76412,-7.70659 2.53876,-0.40238 5.141,-0.55565 7.63831,-1.14688 1.181,-2.71332 1.92962,-5.63537 3.11757,-8.33352 1.32665,-7.3e-4 2.94773,-0.16713 3.75395,1.12942 0.45362,0.5875 1.2372,1.24135 1.85126,0.45942 1.52219,-1.00052 2.87888,-2.3978 4.44169,-3.23032 2.99764,0.0686 5.99522,0.14154 8.99282,0.21215 0.87855,-2.2941 1.49307,-4.79388 2.57764,-6.94247 1.09364,0.18791 2.45599,0.22885 3.39398,0.85505 0.0863,1.64765 2.0886,2.10554 3.36183,2.59703 0.7556,0.32478 1.62245,0.75583 1.78699,1.61439 0.69889,1.09222 2.11856,0.83397 3.07654,0.29279 2.48685,-1.11214 5.09962,-1.97193 7.52965,-3.18974 2.04408,-0.61884 3.83576,1.02834 5.74696,1.45655 1.47589,0.44948 2.91189,1.45874 4.48003,0.77619 1.68336,-0.46827 3.70063,-0.22149 4.92455,-1.67075 2.02994,-1.50986 4.10717,-3.32076 4.76883,-5.83903 0.83798,-1.11396 2.27213,-1.38038 3.56111,-1.56336 1.12123,-0.83524 1.48586,-2.38948 2.6419,-3.216 0.88823,-1.03949 2.67571,-0.65114 3.28471,-1.9781 1.10965,-2.23543 2.48119,-4.37845 3.44541,-6.66171 0.34857,-1.11142 0.10807,-2.29351 -0.37927,-3.29894 -0.52989,-1.93304 1.42253,-3.27577 2.33338,-4.73467 0.96282,-0.99126 1.39321,-2.28706 1.52986,-3.61162 0.19617,-1.12666 1.54169,-1.36807 2.38478,-0.75295 1.12456,0.77108 2.69307,1.87631 4.05607,0.96353 0.62034,-1.19117 -0.26512,-2.55394 -0.75208,-3.64991 -0.9833,-1.52568 -2.32616,-2.80597 -3.50969,-4.21143 -1.43465,-1.46316 -2.39893,-3.28155 -3.88893,-4.7219 -0.41282,-1.02489 -1.28572,-1.79374 -1.7227,-2.83314 -0.82476,-1.32231 -1.75465,-2.73149 -3.24615,-3.33085 -0.66758,-0.65096 -1.75209,-0.81371 -1.88339,-1.86962 -1.37,-2.84204 -4.88192,-3.61788 -7.75737,-3.95933 -2.54812,-0.23836 -5.17362,-0.31397 -7.46065,-1.6052 -1.26899,-0.78616 -2.72144,-1.12455 -4.23931,-1.08742 -3.57131,-0.26419 -7.26001,0.28727 -10.75425,-0.45643 -3.92585,-1.70789 -8.3491,-1.97688 -12.57316,-1.53143 -2.01502,0.27512 -3.93379,1.25872 -6.02304,0.78486 -1.83866,-0.081 -3.50743,-1.62532 -5.36095,-0.8359 -1.00968,0.60495 -2.28409,0.30008 -3.01472,-0.6062 -1.23944,-1.47501 -2.36702,-3.28833 -2.07613,-5.28341 -0.16267,-4.03166 0.34044,-8.17976 -0.61721,-12.1302 -0.34971,-1.81856 -2.23051,-2.86877 -3.86965,-3.36276 -2.14972,-0.5725 -4.3075,-1.83854 -5.6502,-3.63714 -0.72114,-1.0621 -1.3352,-2.21936 -1.47203,-3.52866 -0.7564,-3.06401 -0.15316,-6.73711 -2.5519,-9.18857 -2.09567,-1.44745 -4.50231,-2.61384 -6.91011,-3.37552 -2.37389,-1.2121 -4.69595,-2.55132 -6.74295,-4.288 -1.79444,-1.28216 -3.56632,-3.22156 -5.9909,-3.03734 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptTacuarembo"
+ class="dept tacuarembo" />
+ <path
+ d="m 39.130342,124.22431 c -2.308276,0.0509 -3.920522,1.85415 -5.495925,3.2479 -0.934891,0.20021 -1.251619,-0.79932 -2.101964,-0.89971 -1.515591,-0.37474 -3.266763,0.52482 -3.811792,1.96534 0.349393,0.81336 1.554094,0.95017 2.08267,1.72923 1.397704,1.26304 2.600572,2.95945 2.320497,4.93885 0.346619,4.51502 -1.826148,8.58672 -2.908725,12.8548 -0.754722,2.58684 -1.298931,5.3357 -2.831465,7.61529 -2.002038,2.0858 -5.103605,1.855 -7.63646,2.82038 -1.61241,0.9928 -2.435419,2.86353 -3.509687,4.3518 -0.219949,1.77128 1.671053,2.82174 2.442638,4.21143 0.726663,0.84644 1.05119,1.8597 1.240593,2.92248 0.465652,1.15967 1.011779,2.29753 0.89992,3.60523 0.05455,3.05526 0.373688,6.34398 -1.392086,9.00341 -0.791826,1.91641 -1.514909,4.27864 -0.549167,6.25983 1.605001,2.75752 4.528124,4.36165 6.344442,6.9999 -2.2e-5,2.1908 0,4.38157 0,6.57237 -1.926938,1.85854 -3.791082,3.78759 -4.872153,6.27898 -1.125264,1.88572 -1.924451,4.00213 -2.295072,6.16389 0.103175,1.17206 1.67605,0.6389 2.428319,0.62015 2.199754,-0.2468 4.648726,-0.48089 6.654447,0.56032 1.57707,1.23323 2.45566,3.35119 4.493161,3.95618 1.710172,0.79025 2.430914,2.63748 3.220434,4.20507 1.736137,-0.0227 3.624504,-0.32328 5.142397,0.72103 1.891807,0.76842 4.06097,-0.28566 5.958744,0.34457 1.135913,0.90586 3.287513,1.60633 4.203911,0.0511 0.728737,-1.3907 0.52658,-3.55834 2.23052,-4.24971 3.692012,-0.69228 7.639894,-0.37531 11.229702,-1.58247 1.615723,-0.69962 3.789347,-1.55548 3.8568,-3.61799 0.177015,-1.39538 1.513795,-2.23203 2.828316,-2.34183 1.851672,-0.69485 2.637413,-3.32199 4.821,-3.20961 1.990748,0.13616 4.062803,1.38948 6.061608,0.52324 0.927951,-0.80658 1.943825,-1.71595 3.310403,-1.48037 1.541344,-0.11147 2.43423,1.37793 3.959652,1.3081 1.835751,0.0726 3.130868,-1.55371 4.583169,-2.41839 1.657743,-1.38991 3.568945,-2.76715 5.855688,-2.6381 1.841332,0.15615 3.639913,-0.31829 5.161903,-1.35 1.32299,-0.89493 2.99995,-1.7373 4.58315,-1.1422 1.46969,0.65181 2.91277,1.42441 4.24832,2.30132 1.73036,0.89822 3.57674,1.88762 5.61222,1.54642 2.20147,-0.24872 4.37366,-0.0287 6.52443,0.38922 2.92903,0.18678 6.02089,-0.56964 8.7742,0.72744 2.81234,1.00151 4.09844,4.0476 6.86268,5.11311 0.65255,0.18018 1.8432,1.29467 2.20724,0.23412 0.93524,-3.20503 1.537,-6.61084 3.20756,-9.53316 1.42683,-1.98316 2.31674,-4.49649 4.5364,-5.75582 2.78431,-1.88414 5.64255,-3.98392 7.27185,-6.98055 1.34628,-4.4217 1.37161,-9.24191 3.57369,-13.40317 2.15487,-3.92323 1.16844,-8.58583 2.23721,-12.77148 0.6979,-1.01579 1.91128,-1.61947 3.13042,-1.79944 -0.1301,-1.55629 -0.0864,-3.36787 -1.50328,-4.38141 -1.18991,-0.72112 -1.30461,-1.91569 -1.25469,-3.18314 -0.255,-2.0995 0.11297,-4.79778 -1.73518,-6.2821 -1.66822,-1.09021 -4.05409,-1.20524 -5.81091,-0.26162 -1.03914,0.75489 -1.19923,2.04861 -1.52986,3.17133 -0.26826,0.98689 -1.33466,1.15248 -1.94126,1.86962 -0.79341,0.29456 -1.45912,0.91674 -1.42702,1.82495 -0.091,0.84762 -0.63031,1.56648 -1.07348,2.25247 -2.45942,0.83702 -5.20506,0.62445 -7.5891,-0.34623 -2.22735,-0.78394 -4.60604,-0.80061 -6.90603,-1.115 -2.2043,-0.37576 -3.73871,-2.68902 -6.15155,-2.37788 -1.42748,-0.11939 -3.09592,0.45729 -4.10185,-0.85617 -1.5924,-1.42882 -3.87683,-1.90982 -5.93873,-1.30918 -1.36656,0.16692 -2.50157,1.10381 -3.94035,0.93161 -2.8188,0.40818 -5.45482,-1.30856 -8.25999,-0.77848 -0.74214,0.33332 -0.99075,1.60806 -2.0248,1.34639 -3.3201,-0.40357 -6.642237,-0.86699 -9.950548,-1.2762 -2.30124,-0.29835 -3.288415,-2.9719 -5.634791,-3.08226 -3.249931,-0.43992 -6.664252,-1.60697 -8.879627,-4.05802 -0.532951,-0.85009 -0.829795,-1.88885 -1.819127,-2.38648 -1.643906,-0.9126 -3.676568,-0.26039 -5.46907,-0.62141 -1.582863,-0.36457 -2.867679,-1.63232 -4.268187,-2.43595 -2.945664,-2.28616 -6.359578,-4.03949 -10.131677,-4.45301 -2.59357,-0.54353 -5.288743,-0.46688 -7.797166,-1.28896 -1.139839,-0.83075 -2.10499,-2.01936 -2.217645,-3.47123 -0.608532,-2.51217 -3.06082,-3.9035 -5.165683,-5.05569 -1.323036,-0.58068 -2.673387,-1.39917 -4.174207,-1.3444 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptPaysandu"
+ class="paysandu dept" />
+ <path
+ d="m 214.0747,68.091097 c -1.70368,0.13981 -1.6666,2.21455 -1.87698,3.46486 -0.3467,1.65901 -0.22402,3.41382 -0.53351,5.06008 -0.77334,1.0936 -2.4708,0.69446 -3.46471,0.0893 -1.11881,-0.38756 -2.45082,0.0285 -2.91187,1.16771 -0.85987,1.24312 -1.47373,2.62343 -1.90268,4.04553 -0.52163,1.18431 -1.46021,2.15822 -2.79206,2.37447 -1.73529,0.35417 -2.66721,1.95554 -3.27905,3.43862 -0.28366,1.26288 -1.74587,0.8575 -2.69026,1.07195 -1.75165,0.35626 -3.70209,0.78372 -5.34165,-0.11486 -1.93351,-0.36221 -3.91053,0.0953 -5.84306,0.26162 -1.30581,3.48646 -2.27245,7.14191 -3.88893,10.47752 -2.79683,1.044323 -5.89661,1.391663 -8.58139,2.711903 -0.75906,1.03728 -1.34457,2.51796 -0.46923,3.6882 0.45195,0.68376 1.0526,1.25771 1.57485,1.88875 1.11133,-1.60004 2.19385,-3.65464 4.35818,-3.89876 1.91184,-0.46851 3.69761,0.40562 5.09457,1.59685 1.76827,1.37066 3.56541,2.64398 5.40236,3.88439 2.88441,1.85501 6.27981,2.75041 9.21775,4.49218 1.57396,1.10894 2.72534,2.97413 2.99544,4.85591 -0.0261,2.26948 0.45705,4.57792 1.07836,6.75829 1.05113,3.22734 4.40298,4.76354 7.39719,5.77586 1.72085,0.69268 3.20421,2.17262 3.33635,4.08242 0.73752,2.53031 0.281,5.25518 0.40892,7.86711 0.0347,2.5327 -0.38261,5.37763 1.29725,7.5104 0.52057,1.15475 1.73786,2.14884 3.07258,1.65266 1.05193,-0.39929 2.09404,-0.64085 3.13686,-0.0447 2.33745,0.87498 4.99172,1.08244 7.3215,0.18504 4.0697,-0.87204 8.42009,-0.56316 12.38674,0.65724 2.82379,1.44371 6.14967,0.72761 9.2113,0.8776 2.67656,-0.12947 5.40075,0.13863 7.76504,1.48336 4.10577,1.96373 9.17489,0.64061 13.06811,3.27342 1.65614,0.91145 1.89222,3.08591 3.62539,3.90514 2.07165,1.09141 3.31224,3.07664 4.38905,5.0552 1.89222,2.9283 4.30757,5.48922 6.50045,8.1858 1.33388,1.33137 2.47888,2.88977 2.73144,4.81071 -0.0435,1.0275 1.06257,1.10726 1.79339,0.84867 1.62442,-0.26797 3.39008,-0.14563 4.97527,-0.54877 0.90157,-0.877 1.69856,-2.29187 0.88707,-3.49037 -0.62945,-1.23231 0.6499,-2.51816 1.66486,-3.04371 1.36697,-0.77278 1.61851,-3.4031 -0.16713,-3.81582 -0.65987,-0.24131 -2.15676,-0.0754 -1.89627,-1.16771 0.51377,-1.3715 1.7235,-2.36756 2.14695,-3.79667 1.54669,-3.85006 3.31233,-7.6715 4.44818,-11.65161 0.19187,-0.78635 -0.26077,-1.45858 -0.70709,-2.01637 -0.97575,-1.89303 -1.04738,-4.29931 0.008,-6.15739 0.48496,-1.30978 1.13747,-2.71946 2.4797,-3.35024 -0.005,-2.88843 -0.008,-5.77688 -0.006,-8.66532 -2.75883,-1.8802 -5.42029,-3.95792 -7.81644,-6.25334 -1.05265,-1.17772 -1.07944,-3.31777 -2.69976,-3.91151 -1.92073,-0.24306 -4.00916,-0.0764 -5.66949,-1.26981 -1.80773,-1.0147 -3.86647,-0.64772 -5.81723,-0.52605 -2.32477,0.007 -4.89613,0.27196 -6.80091,-1.31167 -1.51671,-0.96318 -2.6488,-2.3601 -3.50969,-3.90514 -1.15774,-1.20922 -3.20364,-0.98568 -4.12035,-2.546 -1.19008,-1.84452 -2.74099,-3.39253 -4.17821,-5.02181 -0.82947,-0.98883 -1.55911,-2.73128 -3.09185,-2.62894 -1.36885,0.54817 -0.65926,2.33268 -1.42702,3.32447 -0.44564,0.9769 -1.54067,2.17523 -2.73191,1.52505 -2.30254,-0.7447 -3.29196,-3.14845 -5.0524,-4.56238 -1.86507,-0.79281 -3.81698,-1.38935 -5.72092,-2.11847 -2.53397,-1.47456 -2.59004,-4.684613 -3.3211,-7.177333 -0.13689,-1.14918 -0.91257,-2.12423 -2.07841,-2.3622 -0.99395,-0.42076 -2.9346,-0.56445 -2.79617,-2.06743 0.0663,-2.11495 1.06144,-4.63957 -0.56845,-6.42025 -0.88617,-1.32099 -2.06811,-2.39197 -3.37835,-3.26603 -1.56236,-1.28403 -1.79889,-3.37558 -3.13043,-4.81761 -1.07409,-0.94392 -2.77817,-1.15807 -3.31685,-2.66086 -1.18029,-2.63119 -3.65865,-4.34881 -6.20945,-5.54504 -1.34667,-0.72523 -2.27405,-2.3321 -3.98535,-2.21419 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptRivera"
+ class="dept rivera" />
+ <path
+ d="m 48.978034,59.655477 c -0.700645,0.0383 -2.173384,-0.004 -1.793401,1.09114 0.676695,1.78758 -0.141418,3.61565 -0.803512,5.25152 -0.197034,2.3217 -0.148819,4.71414 0.173566,7.01905 0.524464,1.98522 2.36147,3.49209 4.248893,4.1859 2.407467,0.87666 5.135264,0.4277 7.462918,1.49314 1.022447,0.62187 0.838888,2.54072 -0.501389,2.58428 -1.585251,0.3172 -3.347718,0.81026 -4.936698,0.47858 -0.303151,-0.81618 -1.381821,-0.45352 -1.317748,0.33181 -0.826627,0.81084 -2.24231,0.34282 -2.636015,-0.69353 -0.661762,-0.76595 -0.951322,-2.20005 -2.249261,-1.76952 -2.039311,0.13622 -4.201729,-0.27135 -6.177293,0.24248 -0.753199,0.48323 -0.02162,1.24995 0.128559,1.82495 0.28131,2.46828 -0.134854,5.03933 0.340674,7.45933 0.382696,0.86855 0.784727,1.95525 0.75307,2.87365 -0.757722,1.83137 -2.56301,3.73233 -1.845832,5.84273 1.133178,1.44644 3.738131,1.12448 4.454613,3.030953 0.01748,0.81519 0.0066,1.74847 0.758953,2.31681 0.930469,0.72465 1.182034,2.32246 -0.01331,2.92194 -1.001824,0.75791 -2.605037,0.28224 -3.124007,-0.8678 -0.45469,-0.52717 -1.247548,-1.83175 -2.037684,-1.06562 -0.460655,1.21887 -0.04309,2.6551 -0.842059,3.79666 -0.731103,1.32174 -2.217955,2.49761 -3.792515,2.08019 -1.329765,0.28947 -2.033058,1.6962 -2.989031,2.53962 -1.31989,1.33448 -0.601556,3.35654 -1.166029,4.9794 -0.139665,1.83904 -1.264907,3.46942 -2.958441,4.26739 -1.314374,0.85926 -3.732558,1.37288 -3.595544,3.36197 0.189115,1.42513 1.173784,2.66281 2.487627,3.26067 1.064146,-1.50746 2.964961,-2.88756 4.866001,-2.08657 0.813732,0.18396 1.671319,1.51685 2.254821,0.42955 1.523217,-1.9683 4.148388,-3.53657 6.673656,-2.68203 2.042931,0.68506 4.039578,1.63646 5.618071,3.07562 1.861482,1.09628 2.465941,3.24476 2.976168,5.19409 0.797236,1.8448 3.250015,1.62457 4.897993,2.00344 3.800257,0.54956 7.861449,0.90343 11.171995,2.95455 2.466239,1.39629 4.708731,3.28901 7.192925,4.62619 1.81814,0.14088 3.735885,-0.0945 5.508806,0.29353 1.768362,1.04928 2.089474,3.46035 4.02793,4.29916 2.452965,1.71334 5.49508,2.06259 8.326672,2.80922 1.610865,0.86623 2.703024,2.7629 4.747544,2.72591 3.122896,0.44884 6.3051,0.79116 9.38762,1.31323 1.10534,-0.26636 1.54794,-1.84114 2.85403,-1.53143 3.14293,0.31168 6.47304,1.60049 9.59701,0.46581 2.02123,-0.69358 4.32671,-1.34307 6.31229,-0.1659 1.22026,0.58389 1.97139,2.06511 3.51503,1.68438 1.88319,0.0656 3.91155,-0.0554 5.4713,1.18704 1.65595,1.50742 4.12453,1.38985 6.21965,1.72993 1.87748,0.22682 3.6932,0.74313 5.44715,1.35845 1.83783,0.23419 4.23518,0.65168 5.64379,-0.84867 0.88073,-0.86018 0.28334,-2.46586 1.51701,-3.04371 1.15021,-0.78559 2.56155,-1.5954 2.6869,-3.12666 0.35441,-1.76307 1.89702,-3.08218 3.75395,-2.9161 0.72533,-0.0871 2.33083,0.2599 2.18551,-0.90609 -0.66075,-3.39339 -0.68436,-6.90252 -1.35629,-10.28609 -0.52278,-1.30305 -2.16587,-2.34578 -1.47201,-3.93067 0.44734,-1.32115 2.09837,-2.02249 2.43621,-3.30533 0.11242,-1.31443 -0.21919,-2.83905 0.15982,-4.0273 1.14492,-1.10987 3.09404,-1.42066 3.55556,-3.12574 0.5517,-1.29278 1.04065,-2.81676 2.53905,-3.29896 0.84742,-0.45306 1.86765,-0.58248 2.33979,-1.52505 0.54081,-0.92138 1.25022,-1.65425 2.10196,-2.278 0.89017,-1.02135 0.23949,-2.36816 0.17998,-3.52228 0.43783,-1.3527 1.13473,-2.5997 1.70341,-3.91152 -1.45381,-1.18564 -2.91008,-3.0808 -1.94766,-5.0218 0.35667,-1.04346 0.9068,-1.92661 2.14682,-1.93596 2.42812,-0.69481 4.90194,-1.271943 7.28303,-2.084043 1.12989,-3.31389 2.54477,-6.57005 3.34256,-9.97343 -0.005,-0.64161 -0.47666,-1.16147 -0.61065,-1.7739 -3.03547,-3.68855 -6.77385,-6.77132 -9.8734,-10.36904 -2.48452,-2.6087 -6.38351,-2.25664 -9.61628,-3.12666 -3.36553,-0.71303 -6.67087,-1.6987 -9.80913,-3.06925 -2.25989,-0.69514 -4.20751,1.27785 -4.9367,3.20324 -0.6146,1.49397 -1.82501,2.73805 -3.40684,3.1841 -1.5892,0.89076 -2.67086,2.62559 -4.59602,2.93524 -1.96535,0.28545 -3.80655,1.05457 -5.23711,2.46497 -1.30526,0.98938 -2.49973,2.26815 -3.89707,3.04816 -2.7729,0.38928 -5.75751,-0.35186 -8.31536,1.08654 -1.55186,-0.23558 -2.84349,-2.05897 -4.62394,-1.59053 -3.8295,0.14379 -7.69191,0.0132 -11.49994,0.42104 -1.36202,0.85639 -2.37124,2.26404 -3.86965,2.87781 -3.105438,-0.90488 -6.141201,-2.03243 -9.211332,-3.0501 -1.485823,-2.49458 -3.755122,-4.39052 -6.177291,-5.95342 -1.188473,-0.37008 -2.540653,0.0219 -3.612538,-0.78485 -2.337283,-1.53674 -5.074355,-2.51682 -7.405049,-4.05829 -2.545836,-0.80052 -4.654709,-2.59661 -6.865098,-4.00724 -2.536566,-1.23499 -5.818791,0.3044 -8.028581,-1.79305 -1.457625,-1.36936 -2.188833,-3.53307 -4.08177,-4.46666 -2.27964,-1.49653 -4.279417,-3.51576 -6.807254,-4.5879 -0.460163,-0.10809 -0.945419,-0.0729 -1.414158,-0.0447 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptSalto"
+ class="salto dept" />
+ <path
+ d="m 116.0606,1.2825467 c -1.27225,0.14562 -2.13656,1.59891 -3.41969,1.51229 -1.11756,-0.55999 -2.18718,-1.34546 -3.52254,-1.16134 -1.77813,0.0579 -3.80667,-0.35143 -5.27737,0.89334 -1.14433,0.65348 -2.52371,0.18611 -3.61255,-0.3701 -0.968513,1.12163 -2.59213,1.83357 -3.136856,3.2479 -0.09748,0.84115 0.159969,1.9531 -0.861353,2.28438 -0.748691,0.64934 -2.441156,0.71158 -2.06981,2.00362 -0.103534,1.5492003 0.200016,3.2627203 -0.143581,4.7150003 -1.803088,1.55944 -3.244213,4.03506 -5.712338,4.53738 -0.614208,0.061 -1.50843,0.24418 -1.626275,-0.62533 -0.272277,-0.76295 -1.203013,-1.00309 -1.754853,-0.3701 -0.603346,0.34428 -1.292901,1.51632 -1.992679,0.71467 -1.04386,-0.85873 -2.100876,-2.36715 -3.663957,-1.83771 -1.640049,0.32523 -2.267526,2.09075 -3.63824,2.80761 -1.361013,0.35181 -2.820078,-0.72194 -3.265425,-1.95895 -0.841895,-0.49075 -1.960179,-0.82087 -2.937583,-0.61257 -0.492438,0.39431 -0.693235,1.27672 -1.523448,1.05924 -1.862042,-0.31133 -4.051593,-0.22279 -5.611628,-1.37191 -1.042082,-0.70851 -1.295451,-1.90458 -1.084805,-3.08149 0.07541,-0.90228 0.421374,-2.25245 -0.740748,-2.61669 -1.4156,-0.71175 -3.198365,-1.4058103 -4.769571,-0.82953 -0.711072,0.88335 0.689279,1.71574 0.719933,2.63533 0.667999,2.49694 0.917385,5.35765 -0.218555,7.74009 -1.56703,2.43482 -2.998448,5.01535 -5.185817,6.9664 -2.289825,2.40825 -4.647596,4.7188 -7.47447,6.49692 -1.598795,1.32409 -3.625249,2.26851 -4.502457,4.24382 -1.106315,1.30449 -1.639729,2.95143 -1.645567,4.6581 -0.254261,1.94118 -0.326607,4.37176 1.259887,5.78752 1.437012,0.79416 2.450924,2.2794 2.243361,3.95619 0.02102,1.81166 2.424885,2.34608 2.337795,4.21455 0.370909,1.53462 0.520431,3.40434 1.756846,4.50182 0.936617,0.29859 0.844547,-0.94756 1.459147,-1.25704 1.287777,-0.93844 3.189909,-1.24549 4.634596,-0.56153 0.756221,0.52047 1.635014,0.82043 2.288364,1.52505 2.494574,1.97093 5.532892,3.51194 7.167208,6.33629 0.681263,1.00491 1.686334,1.85622 2.956874,1.97808 2.118728,0.50356 4.535518,-0.006 6.492278,1.03372 0.564828,0.8614 1.70143,1.13245 2.449075,1.82495 3.311705,1.99359 6.985432,3.41151 10.265501,5.41104 1.288353,1.07138 3.062487,1.2731 4.679586,1.4102 2.473303,1.61107 4.742209,3.55529 6.331581,6.05552 2.959385,0.91532 5.873683,2.15906 8.889914,2.79486 1.56644,-0.60914 2.53715,-2.27706 4.04964,-2.8842 4.25533,-0.27934 8.52914,-0.0993 12.79171,-0.15314 1.06958,0.42655 2.1287,1.32625 3.20759,1.474 1.73047,-1.03079 3.72833,-1.17817 5.69519,-1.06562 1.22579,-0.11796 2.69964,0.43648 3.53069,-0.75423 2.36777,-1.81924 4.48168,-4.41185 7.66044,-4.66957 2.07315,-0.26336 3.38971,-2.07665 5.05241,-3.08838 2.49226,-0.61093 3.09059,-3.4537 4.53817,-5.21324 1.21535,-1.3064 3.35492,-1.8176 4.91099,-0.79123 4.42369,1.92239 9.16836,2.93202 13.95027,3.63819 2.3283,0.19062 4.30074,1.61314 5.651,3.44729 2.53512,2.82524 5.17381,5.6287 8.09698,8.04374 0.94879,-0.11568 0.60656,-1.50031 0.83564,-2.1759 0.48645,-3.52844 0.10539,-7.20694 0.83563,-10.66257 0.56258,-1.61628 2.30036,-2.94803 1.75484,-4.83038 -0.23628,-1.78004 -0.59584,-3.69944 -2.15956,-4.81944 -1.41634,-1.30668 -3.15277,-2.12011 -4.53841,-3.49493 -2.17019,-1.73337 -2.27459,-4.82478 -4.0943,-6.85179 -0.64907,-1.16015 -1.92569,-1.67175 -2.86721,-2.52821 -1.13569,-1.11523 -0.95557,-2.8718 -1.83199,-4.10295 -1.04056,-0.61464 -2.38566,-1.27196 -2.61618,-2.56514 -0.50927,-0.94371 -1.49809,-1.45074 -2.51978,-1.60162 -1.27991,-0.49011 -1.5358,-2.15749 -2.86047,-2.52048 -2.22059,-1.44193 -4.5531,-2.78274 -6.78796,-4.15399 -1.38059,-1.25756 -2.11122,-3.18471 -3.17544,-4.71553 -1.48839,-1.63111 -3.64906,-2.44533 -5.3116,-3.90448 -2.29028,-1.66153 -4.77169,-3.29144 -6.14864,-5.8648 -0.7908,-0.71816 -1.02026,-2.64348 -2.38202,-2.14138 -1.06843,0.0444 -3.12323,0.74514 -3.53261,-0.73 0.0393,-1.31371 1.56295,-2.56258 0.61709,-3.87323 -1.46357,-1.85685 -3.59496,-3.07886 -5.67593,-4.10933 -1.41932,-0.6674203 -2.68274,-1.6173503 -4.05605,-2.3609603 -1.6452,-0.509 -2.56957,-2.11019 -2.69334,-3.73285 -0.52771,-1.6385 -2.50536,-1.97769 -3.90822,-2.5779 -0.83243,-0.23003 -1.69758,-0.38975 -2.55835,-0.35734 z"
+ style="fill:#fff3e3;fill-opacity:1;stroke:#000000;stroke-width:0.44100034;stroke-opacity:1"
+ id="deptArtigas"
+ inkscape:label="#deptArtigas"
+ class="dept artigas" />
+ <path
+ sodipodi:type="arc"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="capArtigas"
+ sodipodi:cx="316.13959"
+ sodipodi:cy="54.892403"
+ sodipodi:rx="15.24789"
+ sodipodi:ry="14.231364"
+ d="m 331.38748,54.892403 a 15.24789,14.231364 0 1 1 -30.49578,0 15.24789,14.231364 0 1 1 30.49578,0 z"
+ transform="matrix(0.29668289,0,0,0.31554795,53.335725,15.284717)"
+ class="capital city artigas" />
+ <text
+ xml:space="preserve"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="161.38303"
+ y="34.967274"
+ id="textArtigas"
+ class="text capital artigas"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3196"
+ x="161.38303"
+ y="34.967274"
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">Artigas</tspan></text>
+ <path
+ class="capital city rocha"
+ transform="matrix(0.27008062,0,0,0.31863872,216.07451,383.15049)"
+ d="m 331.38748,54.892403 a 15.24789,14.231364 0 1 1 -30.49578,0 15.24789,14.231364 0 1 1 30.49578,0 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capRocha"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital rocha"
+ id="textRocha"
+ y="391.70276"
+ x="299.57248"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="391.70276"
+ x="299.57248"
+ id="tspan3290"
+ sodipodi:role="line">Rocha</tspan></text>
+ <path
+ class="capital city rivera"
+ transform="matrix(0.29668289,0,0,0.31554795,129.06846,59.027917)"
+ d="m 331.38748,54.892403 a 15.24789,14.231364 0 1 1 -30.49578,0 15.24789,14.231364 0 1 1 30.49578,0 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capRivera"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital rivera"
+ id="textRivera"
+ y="73.404587"
+ x="228.82721"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="73.404587"
+ x="228.82721"
+ id="tspan3301"
+ sodipodi:role="line">Rivera</tspan></text>
+ <path
+ class="capital city salto"
+ transform="matrix(0.26512023,0,0,0.2865382,-49.651709,102.44579)"
+ d="m 331.38748,54.892403 a 15.24789,14.231364 0 1 1 -30.49578,0 15.24789,14.231364 0 1 1 30.49578,0 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capSalto"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital salto"
+ id="textSalto"
+ y="134.82005"
+ x="38.127995"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="134.82005"
+ x="38.127995"
+ id="tspan3307"
+ sodipodi:role="line">Salto</tspan></text>
+ <path
+ class="capital city tacuarembo"
+ transform="matrix(0.29958885,0,0,0.28725414,88.994318,134.03588)"
+ d="m 331.38748,54.892403 a 15.24789,14.231364 0 1 1 -30.49578,0 15.24789,14.231364 0 1 1 30.49578,0 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capTacuarembo"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital tacuarembo"
+ id="textTacuarembo"
+ y="163.86211"
+ x="166.44603"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="163.86211"
+ x="166.44603"
+ id="tspan3313"
+ sodipodi:role="line">TacuarembĂł</tspan></text>
+ <path
+ class="capital city paysandu"
+ transform="matrix(0.2623843,0,0,0.31501284,-56.120569,186.26677)"
+ d="m 331.38748,54.892403 a 15.24789,14.231364 0 1 1 -30.49578,0 15.24789,14.231364 0 1 1 30.49578,0 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capPaysandu"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital paysandu"
+ id="textPaysandu"
+ y="200.17351"
+ x="31.704315"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="200.17351"
+ x="31.704315"
+ id="tspan3359"
+ sodipodi:role="line">PaysandĂş</tspan></text>
+ <path
+ class="capital city rioNegro frayBentos"
+ transform="matrix(0.28896328,0,0,0.31189727,-77.408335,260.05781)"
+ d="m 331.38748,54.892403 a 15.24789,14.231364 0 1 1 -30.49578,0 15.24789,14.231364 0 1 1 30.49578,0 z"
+ sodipodi:ry="14.231364"
+ sodipodi:rx="15.24789"
+ sodipodi:cy="54.892403"
+ sodipodi:cx="316.13959"
+ id="capFrayBentos"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:7;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ sodipodi:type="arc" />
+ <text
+ class="text capital frayBentos rioNegro"
+ id="textFrayBentos"
+ y="253.03685"
+ x="0.27949786"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="253.03685"
+ x="0.27949786"
+ id="tspan3365"
+ sodipodi:role="line">Fray </tspan><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="268.47186"
+ x="0.27949786"
+ sodipodi:role="line"
+ id="tspan3367">Bentos</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.92934871;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 40.599857,285.86644 c 0,2.25096 -1.811052,4.07783 -4.042522,4.07783 -2.231475,0 -4.042525,-1.82687 -4.042525,-4.07783 0,-2.25096 1.81105,-4.07783 4.042525,-4.07783 2.23147,0 4.042522,1.82687 4.042522,4.07783 z"
+ id="capMercedes"
+ class="capital city mercedes soriano" />
+ <text
+ class="text capital mercedes soriano"
+ id="textMercedes"
+ y="284.80658"
+ x="47.730495"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="284.80658"
+ x="47.730495"
+ sodipodi:role="line"
+ id="tspan3375">Mercedes</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 151.98716,289.58034 c 0,2.45018 -1.97393,4.43873 -4.40608,4.43873 -2.43216,0 -4.40609,-1.98855 -4.40609,-4.43873 0,-2.45018 1.97393,-4.43872 4.40609,-4.43872 2.43215,0 4.40608,1.98854 4.40608,4.43872 z"
+ id="capDurazno"
+ class="capital city durazno" />
+ <text
+ class="text capital durazno"
+ id="textDurazno"
+ y="280.87451"
+ x="135.65161"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="280.87451"
+ x="135.65161"
+ sodipodi:role="line"
+ id="tspan3384">Durazno</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.18605804;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 120.16296,312.95775 c 0,2.42691 -2.15647,4.39658 -4.81357,4.39658 -2.65709,0 -4.81357,-1.96967 -4.81357,-4.39658 0,-2.42693 2.15648,-4.39659 4.81357,-4.39659 2.6571,0 4.81357,1.96966 4.81357,4.39659 z"
+ id="capTrinidad"
+ class="capital trinidad flores city" />
+ <text
+ class="text capital trinidad flores"
+ id="textTrinidad"
+ y="303.46381"
+ x="85.443306"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="303.46381"
+ x="85.443306"
+ sodipodi:role="line"
+ id="tspan3484">Trinidad</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 330.90281,201.46347 c 0,2.45018 -1.97392,4.43874 -4.40608,4.43874 -2.43216,0 -4.40608,-1.98856 -4.40608,-4.43874 0,-2.45017 1.97392,-4.43872 4.40608,-4.43872 2.43216,0 4.40608,1.98855 4.40608,4.43872 z"
+ id="capMelo"
+ class="capital city cerroLargo melo" />
+ <text
+ class="text capital melo cerroLargo"
+ id="textMelo"
+ y="191.62437"
+ x="314.54553"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="191.62437"
+ x="314.54553"
+ sodipodi:role="line"
+ id="tspan3493">Melo</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 309.52524,280.83557 c 0,2.45018 -1.97393,4.43873 -4.40609,4.43873 -2.43215,0 -4.40608,-1.98855 -4.40608,-4.43873 0,-2.45017 1.97393,-4.43873 4.40608,-4.43873 2.43216,0 4.40609,1.98856 4.40609,4.43873 z"
+ id="capTreintaYTres"
+ class="capital city treintaYTres" />
+ <text
+ class="text capital lavalleja"
+ id="textMinas"
+ y="377.15027"
+ x="227.46809"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="377.15027"
+ x="227.46809"
+ sodipodi:role="line"
+ id="tspan3499">Minas</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.24505138;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 238.1361,382.99754 c 0,2.41069 2.28975,4.3672 5.11104,4.3672 2.8213,0 5.11105,-1.95651 5.11105,-4.3672 0,-2.41071 -2.28975,-4.36721 -5.11105,-4.36721 -2.82129,0 -5.11104,1.9565 -5.11104,4.36721 z"
+ id="capMinas"
+ class="capital city lavalleja minas" />
+ <text
+ class="text capital treintaYTres"
+ id="textTreintaYTres"
+ y="298.42639"
+ x="290.97928"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="298.42639"
+ x="290.97928"
+ sodipodi:role="line"
+ id="tspan3505">Treinta Y Tres</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 174.66086,361.89259 c 0,2.45018 -1.97393,4.43873 -4.40609,4.43873 -2.43217,0 -4.4061,-1.98855 -4.4061,-4.43873 0,-2.45017 1.97393,-4.43872 4.4061,-4.43872 2.43216,0 4.40609,1.98855 4.40609,4.43872 z"
+ id="capFlorida"
+ class="capital city florida" />
+ <text
+ class="text capital florida"
+ id="textFlorida"
+ y="355.2168"
+ x="156.47816"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="355.2168"
+ x="156.47816"
+ sodipodi:role="line"
+ id="tspan3511">Florida</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 52.233809,393.09965 c 0,2.45017 -1.973923,4.43873 -4.406089,4.43873 -2.432126,0 -4.406049,-1.98856 -4.406049,-4.43873 0,-2.45018 1.973923,-4.43873 4.406049,-4.43873 2.432166,0 4.406089,1.98855 4.406089,4.43873 z"
+ id="capColonia"
+ class="capital city colonia" />
+ <text
+ class="text capital colonia"
+ id="textColonia"
+ y="410.35272"
+ x="23.915955"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="410.35272"
+ x="23.915955"
+ sodipodi:role="line"
+ id="tspan3517">Colonia</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 262.30742,432.36825 c 0,2.45017 -1.97393,4.43873 -4.40609,4.43873 -2.43215,0 -4.40608,-1.98856 -4.40608,-4.43873 0,-2.45018 1.97393,-4.43872 4.40608,-4.43872 2.43216,0 4.40609,1.98854 4.40609,4.43872 z"
+ id="capMaldonado"
+ class="capital city maldonado" />
+ <text
+ class="text capital maldonado"
+ id="textMaldonado"
+ y="437.41785"
+ x="263.20746"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="437.41785"
+ x="263.20746"
+ sodipodi:role="line"
+ id="tspan3523">Maldonado</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 131.3865,376.63543 c 0,2.45018 -1.97393,4.43872 -4.40608,4.43872 -2.43216,0 -4.40608,-1.98854 -4.40608,-4.43872 0,-2.45018 1.97392,-4.43873 4.40608,-4.43873 2.43215,0 4.40608,1.98855 4.40608,4.43873 z"
+ id="capSanJose"
+ class="capital city sanJose" />
+ <text
+ class="text capital sanJose"
+ id="textSanJose"
+ y="393.82794"
+ x="95.722473"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="393.82794"
+ x="95.722473"
+ sodipodi:role="line"
+ id="tspan3529">San José</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 171.32468,396.09902 c 0,2.45016 -1.97392,4.43872 -4.40609,4.43872 -2.43215,0 -4.40607,-1.98856 -4.40607,-4.43872 0,-2.45019 1.97392,-4.43873 4.40607,-4.43873 2.43217,0 4.40609,1.98854 4.40609,4.43873 z"
+ id="capCanelones"
+ class="capital city canelones" />
+ <text
+ class="text capital canelones"
+ id="textCanelones"
+ y="388.66711"
+ x="159.32826"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="388.66711"
+ x="159.32826"
+ sodipodi:role="line"
+ id="tspan3535">Canelones</tspan></text>
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.10147977;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:0;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 177.53604,432.94916 c 0,2.45018 -1.97392,4.4387 -4.40608,4.4387 -2.43216,0 -4.40609,-1.98852 -4.40609,-4.4387 0,-2.45018 1.97393,-4.43874 4.40609,-4.43874 2.43216,0 4.40608,1.98856 4.40608,4.43874 z"
+ id="capMontevideo"
+ class="capital city montevideo" />
+ <text
+ class="text capital montevideo"
+ id="textMontevideo"
+ y="441.48517"
+ x="79.882721"
+ style="font-size:12.34801292px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ xml:space="preserve"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ style="font-size:12.34801292px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ y="441.48517"
+ x="79.882721"
+ sodipodi:role="line"
+ id="tspan3541">Montevideo</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.64002037px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="43.012875"
+ y="429.34442"
+ id="textDeptMontevideo"
+ class="text dept montevideo"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3545"
+ x="43.012875"
+ y="429.34442"
+ style="font-size:15.87601757px">MONTEVIDEO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.64002037px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="141.38852"
+ y="412.29486"
+ id="textDeptCanelones"
+ class="text dept canelones"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3549"
+ x="141.38852"
+ y="412.29486"
+ style="font-size:15.87601757px">CANELONES</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.64002037px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="245.97739"
+ y="421.9425"
+ id="textDeptMaldonado"
+ class="text dept maldonado"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3553"
+ x="245.97739"
+ y="421.9425"
+ style="font-size:15.87601757px">MALDONADO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.64002037px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="305.18515"
+ y="349.66565"
+ id="textDeptRocha"
+ class="text dept rocha"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3557"
+ x="305.18515"
+ y="349.66565"
+ style="font-size:15.87601757px">Rocha</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.64002037px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="102.48591"
+ y="366.55487"
+ id="textDeptSanJose"
+ class="text dept sanJose"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3561"
+ x="102.48591"
+ y="366.55487"
+ style="font-size:15.87601757px">S. JOSÉ</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.64002037px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="18.047337"
+ y="370.99402"
+ id="textDeptColonia"
+ class="text dept colonia"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3565"
+ x="18.047337"
+ y="370.99402"
+ style="font-size:15.87601757px">COLONIA</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="159.98341"
+ y="333.38153"
+ id="textDeptFlorida"
+ class="text dept florida"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3569"
+ x="159.98341"
+ y="333.38153">FLORIDA</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="214.89326"
+ y="359.32397"
+ id="textDeptLavalleja"
+ class="text dept lavalleja"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3573"
+ x="214.89326"
+ y="359.32397">LAVALLEJA</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="251.55089"
+ y="269.8703"
+ id="textDeptTreintaYTres"
+ class="text dept treintaYTres"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3577"
+ x="251.55089"
+ y="269.8703">TREINTA Y TRES</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="138.42188"
+ y="264.38879"
+ id="textDeptDurazno"
+ class="text dept durazno"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3581"
+ x="138.42188"
+ y="264.38879">DURAZNO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="84.743858"
+ y="333.42523"
+ id="textDeptFlores"
+ class="text dept flores"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3585"
+ x="84.743858"
+ y="333.42523">FLORES</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="8.4036303"
+ y="317.34515"
+ id="textDeptSoriano"
+ class="text dept soriano"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan3589"
+ x="8.4036303"
+ y="317.34515">SORIANO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="32.931881"
+ y="244.72258"
+ id="textDeptRioNegro"
+ class="text dept rioNegro"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2492"
+ x="32.931881"
+ y="244.72258">RĂŤO NEGRO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="154.74973"
+ y="194.55797"
+ id="textDeptTacuarembo"
+ class="text dept tacuarembo"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2496"
+ x="154.74973"
+ y="194.55797">TACUAREMBĂ“</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:17.64002037px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="251.59464"
+ y="229.46617"
+ id="textDeptCerroLargo"
+ class="text dept cerroLargo"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2500"
+ x="251.59464"
+ y="229.46617"
+ style="font-size:15.87601757px">CERRO LARGO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="41.883076"
+ y="179.15581"
+ id="textDeptPaysandu"
+ class="text dept paysandu"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2504"
+ x="41.883076"
+ y="179.15581">PAYSANDĂš</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="192.44968"
+ y="103.51524"
+ id="textDeptRivera"
+ class="text dept rivera"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2508"
+ x="192.44968"
+ y="103.51524">RIVERA</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="74.692024"
+ y="114.64604"
+ id="textDeptSalto"
+ class="text dept salto"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2512"
+ x="74.692024"
+ y="114.64604">SALTO</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:15.87601757px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="68.692932"
+ y="58.278309"
+ id="textDeptArtigas"
+ class="text dept artigas"
+ transform="scale(1.0036798,0.9963337)"><tspan
+ sodipodi:role="line"
+ id="tspan2516"
+ x="68.692932"
+ y="58.278309">ARTIGAS</tspan></text>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/deptosLineas.png b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/deptosLineas.png
new file mode 100755
index 0000000..bcca5a4
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/deptosLineas.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/fondo.png b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/fondo.png
new file mode 100755
index 0000000..81f9e9e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/fondo.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/helpIcon.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/helpIcon.svg
new file mode 100755
index 0000000..d83c915
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/helpIcon.svg
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml-stylesheet href="../../css/lesson.css" type="text/css"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="49.999996"
+ height="49.994019"
+ viewBox="0 0 4.9999996 4.9994018"
+ id="helpIcon"
+ class="iconSVG"
+ sodipodi:version="0.32"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="helpIcon.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <metadata
+ id="metadata19">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ inkscape:window-height="551"
+ inkscape:window-width="1024"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ guidetolerance="10.0"
+ gridtolerance="10.0"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ inkscape:zoom="1"
+ inkscape:cx="393.54668"
+ inkscape:cy="108.50799"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:current-layer="svg0"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ showgrid="false"
+ inkscape:window-maximized="1" />
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 49.994019 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="100 : 49.994019 : 1"
+ inkscape:persp3d-origin="50 : 33.329346 : 1"
+ id="perspective22" />
+ <radialGradient
+ id="shadowGradient">
+ <stop
+ id="stop17"
+ style="stop-color:#c0c0c0;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop19"
+ style="stop-color:#c0c0c0;stop-opacity:1"
+ offset="0.88" />
+ <stop
+ id="stop21"
+ style="stop-color:#c0c0c0;stop-opacity:0"
+ offset="1" />
+ </radialGradient>
+ <linearGradient
+ x1="52.778114"
+ y1="-13.238551"
+ x2="22.0144"
+ y2="51.987099"
+ id="fieldGradient"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ id="stop7"
+ style="stop-color:#d8ebff;stop-opacity:1;"
+ offset="0" />
+ <stop
+ id="stop9"
+ style="stop-color:#4fa9ff;stop-opacity:1;"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="54.509937"
+ y1="41.179295"
+ x2="9.5471001"
+ y2="16.248501"
+ id="edgeGradient"
+ gradientUnits="userSpaceOnUse"
+ xlink:href="#fieldGradient"
+ spreadMethod="pad">
+ <stop
+ id="stop12"
+ style="stop-color:#2b79e0;stop-opacity:1;"
+ offset="0" />
+ <stop
+ id="stop14"
+ style="stop-color:#008df7;stop-opacity:1;"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#shadowGradient"
+ id="radialGradient4073"
+ cx="32.5"
+ cy="29.5"
+ fx="32.5"
+ fy="29.5"
+ r="26.5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#fieldGradient"
+ id="linearGradient4075"
+ gradientUnits="userSpaceOnUse"
+ x1="52.778114"
+ y1="-13.238551"
+ x2="22.0144"
+ y2="51.987099" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#edgeGradient"
+ id="linearGradient4077"
+ gradientUnits="userSpaceOnUse"
+ spreadMethod="pad"
+ x1="54.509937"
+ y1="41.179295"
+ x2="9.5471001"
+ y2="16.248501" />
+ </defs>
+ <circle
+ sodipodi:ry="26.5"
+ sodipodi:rx="26.5"
+ sodipodi:cy="29.5"
+ sodipodi:cx="32.5"
+ cx="32.5"
+ cy="29.5"
+ r="26.5"
+ transform="matrix(0.09423773,0,0,0.09423968,-0.56002628,-0.27802028)"
+ id="circle3820"
+ style="fill:url(#radialGradient4073);stroke:none" />
+ <circle
+ sodipodi:ry="25.799999"
+ sodipodi:rx="25.799999"
+ sodipodi:cy="31"
+ sodipodi:cx="31"
+ cx="31"
+ cy="31"
+ r="25.799999"
+ id="circle3822"
+ style="fill:url(#linearGradient4075);fill-opacity:1;stroke:url(#linearGradient4077);stroke-width:1.94443798"
+ transform="matrix(0.08850274,0,0,0.08850274,-0.37417027,-0.37417028)" />
+ <path
+ sodipodi:nodetypes="cccccccscsccccccccccccccccc"
+ style="font-size:51.7265625px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:100%;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
+ id="text2466"
+ d="m 2.6933187,2.8209993 -0.6841433,0 0,-0.0942 c -5e-7,-0.1051 0.02085,-0.198 0.06254,-0.27875 0.0417,-0.082 0.1294999,-0.18585 0.2634249,-0.31145 l 0.12129,-0.1115 c 0.072015,-0.06665 0.124445,-0.12945 0.157295,-0.1884 0.0341,-0.05895 0.051165,-0.1179 0.05117,-0.17685 -1e-6,-0.0897 -0.0303,-0.1595496 -0.090965,-0.2095496 -0.060645,-0.05125 -0.145295,-0.0769 -0.25395,-0.0769 -0.10234,0 -0.212885,0.022 -0.3316499,0.06535 -0.118765,0.0425 -0.24258,0.1057501 -0.371445,0.1903501 l 0,-0.6036601 c 0.152875,-0.0538 0.29248,-0.09355 0.418825,-0.11919998 0.1263399,-0.0255 0.2482599,-0.0385 0.3657599,-0.0385 0.3082699,5e-6 0.5432699,0.0641 0.7049894,0.19224998 0.161715,0.1269 0.242575,0.31275 0.242575,0.5575201 -1.5e-6,0.1255995 -0.02465,0.2383995 -0.07391,0.3383495 -0.04925,0.0987 -0.13329,0.20505 -0.25205,0.31915 l -0.12129,0.1096 c -0.085915,0.07945 -0.142135,0.14355 -0.168665,0.19225 -0.02655,0.0475 -0.0398,0.09995 -0.0398,0.15765 l 0,0.0865 m -0.6412628,0.40005 0.6114828,-0.0075 0.01115,0.57645 c 0,0 -0.6668573,0 -0.6283053,0" />
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/helpScreen.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/helpScreen.svg
new file mode 100755
index 0000000..6271a3d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/helpScreen.svg
@@ -0,0 +1,426 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml-stylesheet href="../../css/lesson.css" type="text/css"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="417.33334"
+ height="341.33334"
+ id="helpScreenSvg"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="help.svg">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <inkscape:perspective
+ id="perspective49"
+ inkscape:persp3d-origin="50 : 68.871506 : 1"
+ inkscape:vp_z="100 : 103.30726 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 103.30726 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective3109" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2898" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective3053" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2913" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective4204" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective4133" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective4003" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective3930" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2923" />
+ <inkscape:perspective
+ id="perspective10-7"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:path-effect
+ fuse_tolerance="0"
+ vertical_pattern="false"
+ prop_units="false"
+ tang_offset="0"
+ normal_offset="0"
+ spacing="0"
+ scale_y_rel="false"
+ prop_scale="1"
+ copytype="single_stretched"
+ pattern="m -38,719.36218 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 z"
+ is_visible="true"
+ id="path-effect3780"
+ effect="skeletal" />
+ <inkscape:path-effect
+ fuse_tolerance="0"
+ vertical_pattern="false"
+ prop_units="false"
+ tang_offset="0"
+ normal_offset="0"
+ spacing="0"
+ scale_y_rel="false"
+ prop_scale="1"
+ copytype="single_stretched"
+ pattern="M 0,5 C 0,2.24 2.24,0 5,0 7.76,0 10,2.24 10,5 10,7.76 7.76,10 5,10 2.24,10 0,7.76 0,5 z"
+ is_visible="true"
+ id="path-effect3784"
+ effect="skeletal" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.75"
+ inkscape:cx="270.00001"
+ inkscape:cy="178.31425"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer2"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-366.33331,-308.64746)">
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2909"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2915"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2917"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3707"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3711"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3715"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.68738866;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3776"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3778"
+ d="" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3788"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3819"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3821"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3823"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3825"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3827"
+ d="" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3845"
+ d="" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="rect3874"
+ width="413.33334"
+ height="337.33334"
+ x="368.33331"
+ y="310.64746"
+ rx="15.083"
+ ry="15" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="Layer2"
+ transform="translate(3.333344,-1.5466619)">
+ <g
+ id="g3080"
+ transform="matrix(1.2133333,0,0,1.0708387,-844.70703,-450.83406)">
+ <g
+ transform="matrix(0.49496731,0,0,0.49496731,930.18973,120.62394)"
+ id="g3794">
+ <path
+ d="m 53.60865,1035.3693 c 19.78288,-22.2017 22.20694,-25.4265 25.4678,-33.881 3.44722,-8.9377 6.40012,-18.24962 7.52938,-23.74392 0.82455,-4.01172 -0.36261,-5.08744 -5.63913,-5.10977 -1.99045,-0.008 -7.61545,-0.71148 -12.5,-1.56235 -16.50806,-2.87565 -23.91813,-6.30919 -33.99171,-15.75046 -6.08941,-5.70718 -7.43503,-7.50597 -7.19032,-9.61182 0.34346,-2.95569 -1.50714,-2.82651 22.80104,-1.59153 11.8285,0.60095 15.97106,0.42806 22.48438,-0.93836 4.39141,-0.92127 8.66641,-2.28625 9.5,-3.0333 0.83359,-0.74704 3.31562,-1.68728 5.51562,-2.08942 2.2,-0.40213 5.575,-1.60777 7.5,-2.6792 3.44034,-1.91485 3.44887,-1.93539 0.5,-1.2054 -5.17273,1.28051 -26.63042,1.59889 -36.0133,0.53435 -9.20812,-1.04471 -19.63226,-3.39275 -22.72313,-5.11837 -0.95503,-0.5332 -2.32888,-0.96945 -3.05299,-0.96945 -1.43857,0 -9.42912,-5.54027 -11.50725,-7.97859 -0.95343,-1.11868 -1.14843,-3.94422 -0.73666,-10.67412 l 0.56002,-9.15271 -4.54056,-5.31941 c -9.98832,-11.70162 -9.97623,-27.55255 0.0295,-38.68134 2.60206,-2.89412 6.36378,-5.77306 8.93031,-6.83458 l 4.43446,-1.83411 -0.57302,-6.13624 c -1.06496,-11.40449 5.13162,-23.48816 14.51299,-28.30109 l 3.58712,-1.84031 -5.95375,-5.92765 c -4.93512,-4.9135 -8.52008,-7.18312 -20.95375,-13.26571 -8.25,-4.03593 -15.17459,-7.48627 -15.38799,-7.66742 -0.21339,-0.18115 0.18259,-2.36727 0.87997,-4.85804 1.70691,-6.09651 3.20226,-5.96925 18.29995,1.55747 19.96216,9.95182 24.45018,13.11377 31.13538,21.93586 4.86767,6.42359 6.566,7.95536 9.5,8.56828 1.96498,0.41049 4.02269,0.60686 4.57269,0.43639 17.13317,-5.31045 33.409,-5.14223 47.77024,0.49372 4.94708,1.94144 5.21645,1.90161 6.52227,-0.96436 0.61245,-1.34418 5.43513,-7.16668 10.71706,-12.93889 7.18218,-7.84883 10.66081,-10.87865 13.79697,-12.01685 2.3064,-0.83706 9.11158,-3.33956 15.12261,-5.56111 6.01103,-2.22156 11.68966,-4.03919 12.61916,-4.03919 1.11859,0 1.89014,1.09888 2.28193,3.25 0.32555,1.7875 0.8733,4.21044 1.21722,5.38431 0.70713,2.41364 -0.93804,3.18343 -16.9864,7.94807 -8.24402,2.44759 -9.41386,3.13117 -15.04786,8.79297 -3.35991,3.37649 -7.99751,8.92014 -10.30579,12.31923 l -4.19687,6.18016 4.59822,3.7679 c 3.92224,3.21397 12.53592,13.3479 15.89124,18.69593 0.86818,1.38377 2.03676,1.46094 8.86473,0.5854 6.40489,-0.8213 8.72511,-0.72392 12.5,0.5246 8.01058,2.64945 13.40229,2.97743 17.21675,1.04728 5.01589,-2.53808 7.91852,-5.53295 7.91852,-8.17016 0,-1.91743 0.52663,-2.32569 3,-2.32569 l 3,0 0,7.36937 c 0,6.99889 -0.19005,7.61474 -3.78039,12.25 -2.07921,2.68435 -4.3555,6.00563 -5.05843,7.38063 -1.82398,3.56792 -4.05346,6.02517 -8.95417,9.86899 -2.36114,1.85194 -5.40785,5.56725 -6.77047,8.25624 -1.86654,3.68345 -4.04585,5.93033 -8.8376,9.11161 l -6.36013,4.22255 -1.16111,8.29999 c -3.24143,23.17077 -14.49635,42.93763 -31.7551,55.771 -4.30243,3.19923 -8.0341,5.98766 -8.29259,6.19652 -1.61876,1.30794 6.41126,11.58405 19.25766,24.64423 26.293,26.73057 27.51833,28.27367 30.82393,38.81727 3.56149,11.3598 3.62201,12.8116 0.53407,12.8116 -2.0739,0 -2.62572,-0.9231 -4.63288,-7.75 -1.25321,-4.2625 -3.12892,-9.4395 -4.16826,-11.5044 -1.03933,-2.065 -8.08103,-9.94 -15.6482,-17.5 -17.43517,-17.4188 -29.05724,-30.54815 -30.36702,-34.30539 -0.88138,-2.52833 -1.38534,-2.84102 -3.67537,-2.28044 -1.45967,0.3573 -2.80394,1.03003 -2.98727,1.49494 -0.18334,0.46491 -1.18057,0.84529 -2.21608,0.84529 -1.0355,0 -3.3605,0.6395 -5.16666,1.42112 -1.80616,0.78162 -5.98393,1.79412 -9.28393,2.25 l -6,0.82888 -0.64806,5 c -1.05452,8.13597 -10.19844,32.3753 -13.55944,35.9443 -1.06473,1.1306 -3.96423,4.5663 -6.44331,7.6348 -2.47909,3.0685 -5.37183,6.4995 -6.42831,7.6245 -1.05648,1.1249 -3.66664,3.9018 -5.80036,6.1708 -3.09032,3.2864 -4.58088,4.1256 -7.32754,4.1256 l -3.44807,0 4.67803,-5.25 z m 5.47706,-1.25 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 8,-9 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 6,-7 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 85,-12.8776 c 0,-0.2076 -0.7875,-0.9951 -1.75,-1.75 -1.58606,-1.2438 -1.62143,-1.2085 -0.37756,0.3776 1.30637,1.6657 2.12756,2.1955 2.12756,1.3724 z m -13,-11.9674 c 0,-0.1898 -1.0125,-1.2023 -2.25,-2.25 l -2.25,-1.905 1.90499,2.25 c 1.79022,2.1144 2.59501,2.7052 2.59501,1.905 z m -8,-9.00001 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11444 2.59501,2.70524 2.59501,1.90499 z m -41,-13.2644 c 0,-0.21482 -2.1375,-0.3837 -4.75,-0.37528 -2.69011,0.009 -4.21371,0.35593 -3.51336,0.80076 1.18245,0.75103 8.26336,0.38643 8.26336,-0.42548 z m -15.15913,-0.88305 c -0.27085,-0.27086 -4.50835,-1.18259 -9.41666,-2.02608 -16.13633,-2.77299 -23.51094,-5.97517 -33.27596,-14.44895 -7.06554,-6.13127 -6.84736,-7.42208 1.10175,-6.51825 3.4375,0.39085 6.025,0.48259 5.75,0.20387 -0.99658,-1.01006 -14.48194,-2.63618 -15.27608,-1.84205 -0.44842,0.44842 2.5534,3.97257 6.67071,7.83144 9.85626,9.23759 17.5018,12.85148 33.17531,15.68127 8.58267,1.54956 12.04547,1.89328 11.27093,1.11875 z m 23.7264,-0.47481 c 0.532,-0.532 2.7595,-1.3868 4.95,-1.89955 2.1905,-0.51275 3.08273,-0.97137 1.98273,-1.01914 -1.1,-0.0478 -4.7,0.76597 -8,1.80833 -4.87947,1.54126 -5.4304,1.91223 -2.95,1.98641 1.6775,0.0502 3.48527,-0.34405 4.01727,-0.87605 z m -1.06727,-3.56001 c 3.85,-1.06802 7.225,-2.19571 7.5,-2.50598 0.275,-0.31026 2.3,-1.09477 4.5,-1.74336 5.05158,-1.48926 15.57308,-8.30539 21.71998,-14.07082 10.15582,-9.52554 18.78406,-25.08183 22.17104,-39.97322 2.25857,-9.93017 2.17044,-11.34285 -0.64102,-10.27621 -1.2375,0.4695 -5.625,1.02086 -9.75,1.22525 -7.05688,0.34966 -7.51817,0.24412 -7.80748,-1.7863 -0.33071,-2.32087 0.30249,-2.55846 10.30748,-3.8677 11.1663,-1.4612 23.27502,-8.62225 26.61935,-15.74257 1.23176,-2.6225 3.84631,-5.98973 5.81011,-7.48272 4.73441,-3.59937 9.07054,-8.06924 9.07054,-9.35029 0,-1.14449 5.05979,-8.20389 6.26146,-8.73595 0.4188,-0.18544 1.19818,-1.15318 1.73195,-2.15053 0.8951,-1.67251 0.64174,-1.65381 -3.26146,0.24076 -7.22492,3.5069 -10.3032,3.77646 -18.61575,1.63013 -9.07215,-2.34246 -19.00256,-2.1397 -21.58295,0.44068 -0.92186,0.92186 -2.14171,1.67611 -2.71077,1.67611 -2.54552,0 -8.99433,6.52871 -10.95829,11.09406 -1.16076,2.69827 -2.46826,4.90594 -2.90555,4.90594 -1.95933,0 -3.95864,-1.33678 -3.95864,-2.64683 0,-3.08568 4.35596,-10.05283 8.7413,-13.98128 l 4.60821,-4.12811 -4.56124,-6.37189 c -5.99722,-8.37789 -13.41368,-15.23903 -16.69909,-15.44873 -3.96961,-0.25337 -4.08918,-0.31285 -4.08918,-2.03394 0,-1.26833 -0.37392,-1.14902 -1.75876,0.56119 -3.16363,3.90691 -6.71424,0.67043 -4.27159,-3.89369 0.85843,-1.60399 0.0269,-2.12345 -7.25,-4.52893 -6.21814,-2.0555 -10.28943,-2.73355 -16.71965,-2.78455 -7.5672,-0.06 -19,1.69411 -19,2.91514 0,0.25239 1.31647,2.12001 2.92548,4.15026 4.36394,5.50639 6.47105,13.04213 5.76399,20.6139 l -0.58664,6.28221 5.37473,1.20281 c 21.33616,4.77483 28.69937,31.92058 12.95469,47.75979 -10.80462,10.86949 -26.4913,11.06535 -37.48583,0.46803 l -4.92782,-4.74978 -3.2593,3.39483 c -5.79484,6.0358 -10.13838,7.70973 -20.0093,7.71121 -8.60158,10e-4 -8.75,0.0426 -8.75,2.43384 0,1.33789 -0.52005,3.87072 -1.15568,5.62851 -1.08586,3.00291 -0.94993,3.38302 2.25,6.29169 1.87313,1.70263 3.98611,3.10888 4.69552,3.12501 0.70941,0.0161 2.95941,0.87562 5,1.91 5.35714,2.71554 26.10725,6.12131 37.21074,6.10748 6.7425,-0.008 12.40095,-0.73394 19.49709,-2.5 12.81724,-3.18989 15.50356,-3.23117 15.49859,-0.23817 -0.005,3.2606 -3.59424,8.64665 -6.49672,9.75017 -1.37475,0.52268 -2.49954,1.41147 -2.49954,1.97508 0,0.56361 -0.48214,1.02475 -1.07143,1.02475 -0.58928,0 -1.74575,0.67432 -2.56993,1.4985 -0.82417,0.82417 -2.70453,1.76639 -4.17856,2.09382 -1.47404,0.32743 -4.04917,1.20489 -5.7225,1.94992 -7.22305,3.21595 -18.24045,4.55548 -34.98967,4.25415 l -16.47466,-0.29639 3.75338,3.2447 c 8.53728,7.38027 17.41711,11.11298 32.67758,13.73628 4.90831,0.84375 9.17851,1.7884 9.48934,2.09923 1.09734,1.09735 13.67539,-0.1903 20.58645,-2.10749 z m 40.5,-82.47272 c 0,-1.1 -0.45,-2 -1,-2 -0.55,0 -0.99978,-1.0125 -0.99951,-2.25 4.9e-4,-2.23828 6.86797,-9.01585 11.80351,-11.64897 3.22732,-1.72179 11.25861,-4.07728 13.946,-4.09021 3.59163,-0.0173 2.91267,4.08892 -1.25,7.55971 -1.925,1.60504 -3.5,3.40484 -3.5,3.99955 0,1.65254 -3.95602,4.90826 -9.49204,7.81174 -6.12107,3.21032 -9.50796,3.43052 -9.50796,0.61818 z m 9,-3.36173 c 4.30061,-2.42779 8,-5.65282 8,-6.97419 0,-0.54301 1.6875,-2.48922 3.75,-4.32491 2.0625,-1.83568 3.525,-3.33309 3.25,-3.32756 -1.50707,0.0303 -10.20077,3.05406 -12.64753,4.39899 -3.66433,2.0142 -12.18544,9.58314 -10.7927,9.5867 0.58287,0.001 3.43212,-2.0223 6.33165,-4.4973 5.24143,-4.474 9.10858,-5.78543 9.10858,-3.08889 0,1.84596 -4.51449,5.57987 -9.77988,8.08889 -2.30845,1.1 -4.20234,2.32338 -4.20865,2.71862 -0.0143,0.8945 2.43529,-0.01 6.98853,-2.58035 z m -35,84.31604 c 1.09546,-0.74131 0.69092,-0.83408 -1.5,-0.34401 -3.67693,0.82247 -4.47511,1.39483 -1.91667,1.37439 1.05417,-0.008 2.59167,-0.47209 3.41667,-1.03038 z m 6.427,-2.47578 c 2.91505,-2.20537 1.48811,-2.46248 -1.927,-0.34722 -1.65,1.02199 -2.325,1.84622 -1.5,1.83162 0.825,-0.0146 2.36715,-0.68258 3.427,-1.4844 z m 7.14043,-5.58763 c 0.37335,-0.6041 -0.50159,-0.32492 -1.94431,0.62038 -1.44271,0.94531 -2.62312,1.90782 -2.62312,2.13891 0,0.72338 3.85397,-1.6049 4.56743,-2.75929 z m 3.43257,-2.3909 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 6,-5 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -65.02348,-3.06139 c 4.11208,-0.85786 8.83708,-2.16527 10.5,-2.90536 1.66291,-0.74008 4.22952,-1.6135 5.70356,-1.94093 1.47404,-0.32743 3.28207,-1.19733 4.01785,-1.93311 0.73578,-0.73578 2.00475,-1.59958 2.81993,-1.91955 1.26954,-0.49832 1.25981,-0.59309 -0.0679,-0.66071 -0.8525,-0.0434 -2.0117,0.38275 -2.57599,0.94704 -1.37761,1.37761 -13.6602,5.81918 -19.87401,7.18674 -2.75,0.60523 -10.175,1.4011 -16.5,1.7686 l -11.5,0.66819 10,0.17442 c 5.89347,0.1028 13.07026,-0.46609 17.47652,-1.38533 z m 70.52348,-3.43861 c 0.99549,-1.1 1.58498,-2 1.30998,-2 -0.275,0 -1.31449,0.9 -2.30998,2 -0.99549,1.1 -1.58498,2 -1.30998,2 0.275,0 1.31449,-0.9 2.30998,-2 z m -39.74244,-12.00913 c 1.24166,-1.81999 2.07092,-3.49572 1.84281,-3.72384 -0.22812,-0.22811 -5.13023,0.74348 -10.89357,2.15911 -8.13994,1.99938 -13.01511,2.57386 -21.84222,2.57386 -12.97438,0 -33.27435,-3.17908 -39.07474,-6.11931 -2.04059,-1.03438 -4.29059,-1.85699 -5,-1.82803 -0.70941,0.029 0.84976,1.11449 3.46483,2.41228 11.06002,5.4888 45.285,8.38592 59.24533,5.01506 3.3,-0.79682 6.7875,-1.45579 7.75,-1.46438 2.46056,-0.022 2.17728,2.43675 -0.5,4.33963 l -2.25,1.59919 2.5,-0.82725 c 1.375,-0.45498 3.5159,-2.31633 4.75756,-4.13632 z m 48.7905,-2.0838 c 0.87968,-1.70111 1.42188,-3.27046 1.2049,-3.48744 -0.21698,-0.21698 -1.14288,1.17483 -2.05756,3.09293 -2.05658,4.3127 -1.34401,4.64239 0.85266,0.39451 z m -128.0536,-7.9132 c -0.99854,-1.10337 -2.04794,-1.77372 -2.33199,-1.48967 -0.28406,0.28406 0.35068,1.1725 1.41054,1.97433 2.70408,2.04576 3.04782,1.86496 0.92145,-0.48466 z m -1.82881,-15.83491 c 0.54476,-4.29796 0.58312,-4.33487 3.86431,-3.71932 1.87409,0.35158 3.58779,0.17886 3.944,-0.3975 0.36318,-0.58764 0.011,-0.78172 -0.83176,-0.45833 -1.53986,0.5909 -6.76761,-1.7051 -10.1422,-4.4544 -1.9801,-1.6132 -1.98121,-1.60721 -0.11164,0.60221 1.66468,1.96729 1.82292,3.38868 1.33592,12 -0.43762,7.73827 -0.35047,8.83317 0.41936,5.26838 0.53449,-2.475 1.21939,-6.45347 1.52201,-8.84104 z m 135.93852,5.11187 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m 1,-4 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m -78.41667,-2.95394 c -0.72187,-0.28887 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28494 0.60416,-0.60416 z m 79.46844,-3.58592 c -0.27393,-0.67703 -0.48137,0.11903 -0.46099,1.76903 0.0204,1.65 0.2445,2.20394 0.49804,1.23097 0.25354,-0.97297 0.23687,-2.32297 -0.0371,-3 z m -124.92497,2.57604 c -0.97296,-0.25354 -2.32297,-0.23687 -3,0.0371 -0.67703,0.27393 0.11903,0.48137 1.76903,0.46099 1.65,-0.0204 2.20394,-0.2445 1.23097,-0.49804 z m 41.5128,0.0286 c -0.69092,-0.27855 -1.07389,-0.80553 -0.85104,-1.17105 0.22285,-0.36552 -1.20295,-0.75058 -3.16844,-0.85567 -1.9655,-0.1051 -4.95753,-1.20361 -6.64896,-2.44115 -2.34922,-1.71881 -2.72116,-1.81335 -1.57533,-0.40044 1.81731,2.24089 8.73947,5.51042 11.5,5.43176 1.1,-0.0313 1.4347,-0.28489 0.74377,-0.56345 z m -32.38703,-2.26255 c 2.07738,-1.0598 4.4142,-2.7473 5.19293,-3.75 1.34843,-1.73625 1.32057,-1.74235 -0.58488,-0.12808 -1.10041,0.93226 -4.01766,2.60988 -6.48277,3.72804 -2.46511,1.11817 -3.90159,2.04291 -3.19218,2.05499 0.70941,0.0121 2.98952,-0.84515 5.0669,-1.90495 z m 47.01576,0.49285 c 1.52524,-0.78874 3.40764,-2.25124 4.1831,-3.25 1.33163,-1.71509 1.29982,-1.7257 -0.57283,-0.1911 -1.09052,0.89366 -3.33277,2.33815 -4.98277,3.20996 -1.65,0.87182 -2.64015,1.60314 -2.20034,1.62516 0.43982,0.022 2.04759,-0.60529 3.57284,-1.39402 z m -3.36392,-2.43092 c 7.61004,-3.45714 13.65809,-12.5947 13.65809,-20.63499 0,-11.12314 -11.04986,-22.7 -21.66667,-22.7 -10.70226,0 -21.66666,11.57813 -21.66666,22.87946 0,4.64065 3.02363,11.97613 6.07456,14.73719 1.78745,1.61762 1.83913,1.5186 1.37172,-2.62829 -1.45227,-12.88452 7.92692,-22.30909 15.08152,-15.15449 4.84657,4.84656 5.99347,17.1236 2.14795,22.99261 -1.93035,2.94608 -0.65228,3.07608 4.99949,0.50854 z m -53.08133,-2.28112 c 3.70718,-6.27576 1.47296,-18.7986 -3.64361,-20.42254 -4.73397,-1.50251 -8.98587,3.85239 -9.06867,11.42119 -0.0712,6.50478 0.82438,8.55477 4.54657,10.40756 4.71129,2.34514 6.08999,2.10771 8.16571,-1.40621 z m 8.76107,0.52566 c 1.47857,-0.7519 4.15313,-3.11185 5.94345,-5.24433 3.16416,-3.76887 3.25672,-4.14456 3.31169,-13.44187 l 0.0566,-9.56463 -3.42512,-0.64252 c -6.57739,-1.23384 -11.12219,-3.74493 -15.41056,-8.51464 l -4.3202,-4.8051 -3.93064,1.7598 c -7.58534,3.39606 -13.58015,12.55734 -13.58015,20.75322 0,4.42188 3.08834,12.18072 5.7167,14.36206 1.23314,1.02342 1.44997,0.46906 1.44997,-3.70719 0,-9.99193 6.09864,-17.05981 12.75,-14.7763 5.96164,2.04672 9.18113,14.88436 5.77636,23.03311 -1.44844,3.46661 -1.43562,3.51518 0.75,2.84119 1.223,-0.37713 3.43338,-1.30089 4.91195,-2.0528 z m 37.28108,-0.95627 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 66.2806,0.88741 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z m -84.75,-1.68823 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 37,-1.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -83,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 41.40581,-3.29696 c 1.26469,0.48531 1.32727,0.18279 0.38844,-1.87771 -0.61552,-1.35092 -1.24526,-2.33009 -1.39942,-2.17593 -0.15416,0.15416 -1.48307,2.06857 -2.95312,4.25423 l -2.67282,3.97393 2.56468,-2.37651 c 1.43852,-1.33299 3.22665,-2.12249 4.07224,-1.79801 z m 103.59419,2.7059 c 0,-0.53273 -0.675,-0.70959 -1.5,-0.39301 -0.825,0.31659 -1.5,0.75246 -1.5,0.96862 0,0.21615 0.675,0.39301 1.5,0.39301 0.825,0 1.5,-0.43588 1.5,-0.96862 z m -59.19313,-4.55784 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z m -46.2027,-6.20271 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 48,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 45,-5 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 50,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -96,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 95,-5 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58438 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.0789,-1.91667 z m 49.01374,-4.98626 c -0.12014,-0.12014 -1.54582,0.178 -3.16817,0.66254 -1.62236,0.48454 -2.16224,0.91966 -1.19974,0.96694 0.9625,0.0473 1.76595,0.87345 1.78544,1.83595 0.0268,1.32558 0.37079,1.14405 1.41817,-0.74849 0.76051,-1.37418 1.28444,-2.5968 1.1643,-2.71694 z m 42.50618,0.44876 c -0.98762,-0.98026 -1.10248,-0.8654 -0.5598,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30789,-0.30789 6.4e-4,-1.11479 -0.68278,-1.79313 z M 65.08571,861.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -85,-2.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 38.4694,-2.07674 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 6.58891,-0.87068 c 2.30641,-2.50217 6.01686,-5.17968 8.48316,-6.12157 3.50845,-1.33988 4.61401,-2.37208 5.53737,-5.16987 3.7517,-11.36776 -3.1423,-24.22022 -15.17695,-28.29436 -4.64464,-1.57236 -5.7447,-1.61747 -9.7859,-0.40124 -14.93589,4.49504 -21.66079,20.75015 -13.81981,33.40461 l 2.18716,3.52985 0.74099,-5.89906 c 1.49666,-11.91498 8.85142,-17.25247 15.12639,-10.9775 4.48246,4.48246 5.8535,13.25622 3.22323,20.62656 -0.73605,2.0625 -1.17556,3.75 -0.9767,3.75 0.19886,0 2.20634,-2.00134 4.46106,-4.44742 z m -19.14164,3.16445 c -0.22917,-0.15563 -1.31667,-0.94313 -2.41667,-1.75 -1.85,-1.35701 -1.89707,-1.33579 -0.62755,0.28297 0.75484,0.9625 1.84234,1.75 2.41667,1.75 0.57432,0 0.85672,-0.12734 0.62755,-0.28297 z m 24.08333,-3.21703 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.94528,-0.0659 c -1.51303,-1.82309 -6.92706,-4.78561 -7.57027,-4.1424 -0.24152,0.24152 0.91037,0.99812 2.55977,1.68132 1.6494,0.68321 3.51893,1.86878 4.15451,2.6346 0.63558,0.76583 1.3806,1.39242 1.6556,1.39242 0.275,0 -0.0848,-0.70467 -0.79961,-1.56594 z m -75.94528,-0.9341 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 17,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 35.91667,-3.2579 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m -46,-1 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m 5.95162,-1.75427 c -1.01049,-2.21779 -1.20856,-2.27175 -2.75296,-0.75 -1.54948,1.52676 -1.49021,1.68325 0.86027,2.27141 1.38842,0.34743 2.62726,0.68493 2.75297,0.75 0.1257,0.0651 -0.26142,-0.95706 -0.86028,-2.27141 z m 49.04838,0.74819 c 0.22917,-0.19715 -0.55833,-0.35846 -1.75,-0.35846 -1.38524,0 -2.17763,-0.63115 -2.19707,-1.75 -0.0265,-1.52656 -0.17522,-1.49464 -1.16454,0.25 -0.62377,1.1 -1.62259,2.32475 -2.21959,2.72166 -0.59701,0.39691 0.71453,0.44572 2.91453,0.10846 2.2,-0.33726 4.1875,-0.77451 4.41667,-0.97166 z m 72.08333,-1.88414 c 0,-1.39308 -3.70207,-0.18103 -4.79566,1.57008 -1.24992,2.00144 -1.21295,2.01141 1.75946,0.47432 1.66991,-0.86354 3.0362,-1.78352 3.0362,-2.0444 z m 29.1875,0.84257 c -0.72188,-0.28888 -1.58438,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -19.9375,-2.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -84.64583,-3.06689 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 122.39583,-2.04448 c 0,-0.85783 -0.12734,-1.37218 -0.28297,-1.14302 -0.15563,0.22917 -0.89428,1.21447 -1.64144,2.18956 -1.18269,1.54348 -1.14607,1.69139 0.28297,1.14301 0.90279,-0.34643 1.64144,-1.33173 1.64144,-2.18955 z M 82.68988,837.89013 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 65.39583,1.38416 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11445 2.59501,2.70524 2.59501,1.90499 z m -66.39583,-7.38416 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 60.39583,0.35161 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z M 79.2098,826.35263 c -0.98761,-0.98026 -1.10248,-0.8654 -0.55979,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30788,-0.30789 6.3e-4,-1.11479 -0.68279,-1.79313 z m 56.87591,0.88911 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -97,-4.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 53.22334,-1.87639 c -0.26254,-1.00396 -0.54753,-1.69503 -0.63331,-1.53571 -0.0858,0.15931 -0.6787,0.98073 -1.3176,1.82537 -0.93948,1.24202 -0.81836,1.53572 0.63331,1.53572 1.24538,0 1.6488,-0.55888 1.3176,-1.82538 z M 43.08571,819.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.75848,-0.53051 c -0.94115,-1.51852 -0.96737,-2.21193 -0.10397,-2.75 0.63498,-0.39572 -0.80847,-0.71949 -3.20766,-0.71949 l -4.36218,0 3.39287,1.74065 c 1.86608,0.95735 3.67359,2.19485 4.01668,2.75 0.3431,0.55514 0.82607,1.00935 1.07327,1.00935 0.24721,0 -0.11685,-0.91373 -0.80901,-2.03051 z m 52.17485,-0.31215 c -0.23833,-0.20679 -1.78333,-0.65233 -3.43333,-0.99008 -2.73596,-0.56005 -2.80197,-0.51498 -0.75,0.51213 1.2375,0.61943 2.25,1.59747 2.25,2.17342 0,0.65288 0.44557,0.60162 1.18333,-0.13614 0.65084,-0.65084 0.98834,-1.35253 0.75,-1.55933 z m 9.94836,-7.40734 c 2.30606,-3.4375 3.82136,-6.25 3.36733,-6.25 -1.81925,0 -11.24902,12.98428 -11.24902,15.48929 0,1.26984 3.89338,-3.29416 7.88169,-9.23929 z m -84.96502,4.11454 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35466 2.91667,-1.55517 z m 2.58333,-1.36454 c -0.33991,-0.55 -0.81647,-1 -1.05901,-1 -0.24254,0 -0.44099,0.45 -0.44099,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m 6.82946,-1.58385 c -0.33428,-0.87111 -0.88789,-1.20861 -1.23025,-0.75 -0.34236,0.45862 -1.02974,1.17135 -1.52751,1.58385 -0.49776,0.4125 0.0558,0.75 1.23025,0.75 1.53743,0 1.96511,-0.44346 1.52751,-1.58385 z m 20.85804,0.90074 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28495 0.60416,-0.60417 z m 29,0 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -22.9375,-0.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m 18,0 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -8.5,-1.02705 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z M 53.3824,808.21186 c -0.98818,-1.3241 -1.94149,-2.01468 -2.11847,-1.53464 -0.36611,0.99302 1.91319,3.8465 3.11847,3.90404 0.43818,0.0209 -0.0118,-1.04531 -1,-2.3694 z m -3.29669,-3.66948 c 0,-1.50044 -5.57099,-6.92308 -7.11248,-6.92308 -0.69649,0 0.5064,1.73277 2.67307,3.8506 4.69729,4.5914 4.43941,4.41292 4.43941,3.07248 z m 92,-3.42308 c 1.29175,-1.375 2.12363,-2.5 1.84863,-2.5 -0.275,0 -1.55688,1.125 -2.84863,2.5 -1.29175,1.375 -2.12363,2.5 -1.84863,2.5 0.275,0 1.55688,-1.125 2.84863,-2.5 z m 6.04469,-1.70523 c 2.56704,-3.19434 2.82393,-3.81616 1.06867,-2.58673 -1.89119,1.32465 -5.69179,6.79196 -4.72142,6.79196 0.15033,0 1.79407,-1.89235 3.65275,-4.20523 z m -0.0447,-8.71959 c 0,-0.275 -2.25,1.71617 -5,4.42482 -2.75,2.70865 -5,5.14982 -5,5.42482 0,0.275 2.25,-1.71617 5,-4.42482 2.75,-2.70865 5,-5.14982 5,-5.42482 z m 1,3.42482 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 21.91908,-7.85167 c 2.4305,-0.72671 4.0055,-1.56089 3.5,-1.85373 -0.50549,-0.29284 -2.71908,0.27521 -4.91908,1.26232 -4.84957,2.17594 -4.44469,2.34468 1.41908,0.59141 z m 6.88779,-1.17479 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z M 17.08571,783.6193 c -1.925,-1.05389 -3.95,-1.91617 -4.5,-1.91617 -0.55,0 0.575,0.86228 2.5,1.91617 1.925,1.05389 3.95,1.91617 4.5,1.91617 0.55,0 -0.575,-0.86228 -2.5,-1.91617 z m 160,-2 c 0,-0.55 -0.7875,-0.99311 -1.75,-0.98469 -1.49555,0.0131 -1.5319,0.15626 -0.25,0.98469 1.88721,1.21961 2,1.21961 2,0 z"
+ id="path2905"
+ style="fill:#000000" />
+ <path
+ d="m 72.6,181.20757 c -16.765609,-3.86833 -22.376319,-6.32293 -32,-13.9995 l -2,-1.59535 13.2,-0.0317 c 17.959636,-0.043 26.293525,-1.0427 36.676385,-4.39926 12.401975,-4.00929 20.661075,-10.22837 22.672535,-17.07236 1.39926,-4.76097 -0.60247,-5.05117 -14.284918,-2.07088 C 80.913403,145.51284 69.067454,145.46531 50.6,141.85286 39.54215,139.68982 28.750784,134.8087 27.432732,131.37391 c -0.409763,-1.06782 0.94297,-9.55504 1.67366,-10.50077 0.129162,-0.16717 4.118063,-0.56369 8.864224,-0.88115 9.677258,-0.64731 12.721718,-1.79467 18.59718,-7.00868 l 3.565638,-3.16423 4.911016,4.16615 c 6.374081,5.4073 11.045891,7.19552 18.75555,7.17903 10.247136,-0.0219 18.94097,-5.4255 24.01507,-14.92636 2.33003,-4.3628 2.74898,-6.0141 3.03751,-11.972478 0.24409,-5.040832 -0.0244,-7.992693 -0.99183,-10.905433 C 106.83021,74.235948 98.683943,66.74733 89.719703,64.844988 L 85,63.8434 84.966254,55.710271 C 84.929438,46.837023 83.908403,43.511262 79.05568,36.458071 76.206234,32.316543 75.915993,32.561487 85.4,31.103895 c 9.620682,-1.478597 19.97708,-0.291557 29.26619,3.354462 4.00483,1.571915 4.0652,1.646353 4,4.932693 -0.0764,3.849526 1.76499,4.910844 4.39333,2.532225 0.84726,-0.766762 1.54048,-1.021054 1.54048,-0.565095 0,0.45596 1.6637,1.247942 3.6971,1.759959 4.38748,1.10478 11.00212,7.029509 17.23538,15.437707 l 4.03312,5.440379 -4.6828,5.026303 c -4.55714,4.891416 -8.2828,11.01514 -8.2828,13.614092 0,1.528769 2.86706,3.239468 4.42637,2.641103 0.60573,-0.232443 1.86318,-1.915954 2.79432,-3.741133 2.17353,-4.260467 7.69681,-10.272278 10.77931,-11.732734 1.32,-0.625402 3.4424,-1.697018 4.71645,-2.381368 2.96143,-1.590728 11.65807,-1.536216 19.53585,0.122452 7.69091,1.619321 10.4686,1.555228 15.93996,-0.367797 5.65346,-1.987032 5.64225,-1.987649 3.63541,0.2 -0.90817,0.99 -3.01076,3.96 -4.67241,6.6 -1.66166,2.64 -5.30895,6.908849 -8.1051,9.486333 -2.79614,2.577483 -5.99227,6.236344 -7.1025,8.130802 -4.94788,8.442912 -15.3818,14.634562 -28.34766,16.821932 -7.93582,1.33879 -10.1786,2.49921 -9.29263,4.80802 0.46879,1.22165 1.5792,1.32779 10.18353,0.97342 l 9.65736,-0.39773 -0.5479,3.65369 c -1.59381,10.62824 -7.28652,24.58268 -14.24705,34.92353 -11.30309,16.79232 -34.07569,29.48213 -55.75331,31.06798 -4.998646,0.36568 -7.935952,-0.008 -17.6,-2.23755 z m 81.50924,-82.494134 c 3.52664,-1.764307 6.56239,-3.962996 7.90749,-5.727124 1.2008,-1.574879 3.53327,-4.37647 5.18327,-6.225757 1.93865,-2.172795 3,-4.147985 3,-5.583022 0,-2.220043 -0.002,-2.220533 -4.38306,-1.705537 -8.74931,1.028309 -19.06055,6.827181 -22.74752,12.792833 l -1.71519,2.775229 1.70366,3.268542 c 2.14696,4.11903 3.52613,4.16955 11.05135,0.404836 l 0,0 z"
+ transform="translate(0,784.36218)"
+ id="path2907"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 160.6,87.334076 c 0,-0.534851 -1.1468,-0.981516 -2.6,-1.012667 -2.30544,-0.04942 -2.02164,-0.279224 2.50495,-2.028386 2.80772,-1.084959 5.23233,-1.845272 5.38801,-1.689584 0.15569,0.155688 -0.97154,1.499081 -2.50494,2.98532 C 161.85461,87.074997 160.6,87.86039 160.6,87.334076 z"
+ transform="translate(0,784.36218)"
+ id="path2913"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 24.692801,119.04257 c -0.05104,-2.05401 -0.313955,-4.31089 -0.584255,-5.01528 -0.431011,-1.12319 -0.185552,-1.10664 1.99579,0.13457 1.631194,0.92818 2.07587,1.50427 1.292,1.67384 -0.657385,0.1422 -1.361474,1.0422 -1.564643,2 -0.203169,0.95779 -0.521653,2.46144 -0.707744,3.34144 -0.186091,0.88 -0.380107,-0.0805 -0.431148,-2.13457 z"
+ transform="translate(0,784.36218)"
+ id="path3703"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 104.6,146.52914 c 0,-0.55196 -0.79531,-1.29776 -1.76736,-1.65735 -1.56978,-0.5807 -1.42649,-0.71774 1.28174,-1.2258 3.83551,-0.71955 4.4795,-0.10717 2.24118,2.13115 -1.00812,1.00812 -1.75556,1.32829 -1.75556,0.752 z"
+ transform="translate(0,784.36218)"
+ id="path3709"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 76.851058,112.03382 c -3.393188,-2.09142 -4.25448,-3.92327 -4.233488,-9.00408 0.03274,-7.923733 4.577488,-13.887568 8.633406,-11.329161 3.986638,2.514706 5.541626,13.083911 2.747781,18.676561 -1.667169,3.3373 -3.668438,3.80115 -7.147699,1.65668 l 0,0 z"
+ transform="translate(0,784.36218)"
+ id="path3719"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 31.011129,112.18685 c -3.337597,-1.68708 -4.784967,-4.28598 -4.794874,-8.60971 -0.01706,-7.444764 3.322321,-12.761965 7.700427,-12.261175 5.345895,0.611491 7.922362,14.073845 3.761169,19.652565 -2.071377,2.777 -3.181718,2.97991 -6.666722,1.21832 z"
+ transform="translate(0,784.36218)"
+ id="path3721"
+ style="fill:#00d37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="M 49.694395,74.66073 C 44.47115,71.825511 44.018691,61.3525 48.893397,56.120117 c 1.243238,-1.334459 2.71535,-2.426289 3.27136,-2.426289 3.274952,0 7.59925,10.034368 6.191417,14.366947 -2.961401,9.11366 -3.406311,9.452665 -8.661779,6.599955 z"
+ transform="translate(0,784.36218)"
+ id="path3747"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 30.863598,109.87939 c -4.598088,-3.22062 -2.443473,-16.412835 2.680623,-16.412835 3.343974,0 5.248203,11.238065 2.708365,15.983795 -1.423064,2.65902 -2.125412,2.71494 -5.388988,0.42904 l 0,0 z"
+ transform="translate(0,784.36218)"
+ id="path3749"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="M 53.409091,253.22727 C 175,254.36364 176.13636,254.36364 176.13636,254.36364"
+ transform="translate(0,784.36218)"
+ id="path3751"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 101.91757,251.70568 c -21.718752,-0.17272 -39.488638,-0.58449 -39.488638,-0.91506 0,-0.33057 3.818082,-4.96825 8.484628,-10.30595 4.666545,-5.33771 9.973982,-12.85892 11.794303,-16.71379 3.448266,-7.30236 8.521552,-22.38453 9.820557,-29.19514 0.752563,-3.94565 0.76643,-3.95339 12.3156,-6.87496 6.3592,-1.60867 12.35971,-3.28795 13.33446,-3.73173 1.29391,-0.58909 2.73131,0.66046 5.32536,4.62941 1.9542,2.98995 11.57847,13.87378 21.38726,24.18628 9.8088,10.3125 18.96093,20.28409 20.33807,22.15909 2.01779,2.74727 7.42703,15.23542 7.42703,17.14657 0,0.25689 -7.03125,0.34607 -15.625,0.19819 -8.59375,-0.14789 -33.39488,-0.4102 -55.11363,-0.58291 l 0,0 z"
+ transform="translate(0,784.36218)"
+ id="path3753"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 51.774116,254.22272 c 0.816832,-1.01161 5.399709,-6.3219 10.184171,-11.80065 4.784463,-5.47875 10.255577,-12.2121 12.158031,-14.963 5.284789,-7.64167 14.376394,-33.83808 12.993969,-37.44062 -0.338967,-0.88334 -2.48378,-1.73514 -5.328004,-2.116 C 60.981864,185.11713 50.75895,182.31448 43.625018,177.44148 37.971557,173.57975 28.01174,163.28381 28.01174,161.3013 c 0,-1.83865 0.635315,-1.8844 17.079208,-1.22988 19.475363,0.77518 28.155408,-0.12388 38.075567,-3.94376 9.279191,-3.57307 15.45203,-6.36285 15.01445,-6.78568 -0.201984,-0.19518 -4.599918,0.0895 -9.773185,0.63261 -15.856397,1.66468 -37.875872,-0.52821 -50.869606,-5.06603 -3.201056,-1.11791 -7.99066,-3.68786 -10.643565,-5.71099 l -4.823463,-3.67842 0.178374,-9.45002 0.178374,-9.45001 0.5642,7.42574 c 0.582301,7.66397 1.29799,8.16822 2.459224,1.73268 0.423991,-2.34976 0.289983,-3.71287 -0.365011,-3.71287 -0.569229,0 -1.034963,-1.33664 -1.034963,-2.9703 0,-1.63367 -0.407778,-2.9703 -0.906174,-2.9703 -1.708089,0 -9.947718,-12.02652 -11.073528,-16.16286 C 8.4406212,86.620448 14.328838,72.981775 26.509135,66.520142 l 4.472902,-2.372869 0,-7.169297 c 0,-11.907876 4.934342,-21.608335 13.56406,-26.665688 2.388815,-1.399939 4.1792,-3.048653 3.978634,-3.66381 C 47.539733,23.627398 33.787529,13.942425 21.173642,7.3865059 6.6394252,-0.16748247 5.7525435,-1.0667564 8.2445952,-5.7231976 9.9048868,-8.825481 13.26451,-8.0142814 26.786199,-1.2462239 42.52818,6.6331633 49.704459,11.834699 56.658674,20.406047 c 7.066894,8.71023 9.386734,9.398438 22.022822,6.533328 12.009438,-2.723024 25.519864,-2.231151 36.616764,1.3331 4.17096,1.339683 7.95921,2.16177 8.41835,1.826861 0.45913,-0.33491 2.70455,-3.059423 4.98981,-6.054473 2.28526,-2.995049 7.42528,-8.682601 11.42226,-12.639003 7.12067,-7.0483759 7.54019,-7.2929957 20.80065,-12.12871266 7.44339,-2.71438994 14.38913,-4.93525434 15.435,-4.93525434 1.40526,0 2.17641,1.0827118 2.95451,4.1481669 0.5791,2.28149179 0.85167,4.4737776 0.60572,4.871746 -0.24596,0.3979683 -6.12349,2.612099 -13.0612,4.92029 -12.32753,4.1014041 -12.76057,4.3449071 -19.06805,10.7223141 -3.54973,3.589081 -8.19833,9.098685 -10.33023,12.243564 l -3.87618,5.717962 4.38964,4.574292 c 2.4143,2.515859 3.60993,4.300819 2.65696,3.966577 -2.15679,-0.756469 -2.25789,0.631979 -0.17206,2.363061 1.27233,1.05594 1.70648,1.059167 2.35028,0.01747 0.5549,-0.897844 2.45839,0.813688 6.40236,5.756734 3.08697,3.868951 6.15063,7.065929 6.80813,7.104394 0.6575,0.03847 4.65679,0.0099 8.8873,-0.0634 4.23053,-0.07334 11.0745,0.619228 15.20883,1.53903 6.08457,1.353687 8.24222,1.455077 11.32293,0.532074 4.78641,-1.434041 9.61096,-5.430654 10.01889,-8.299556 0.1988,-1.398101 1.12005,-2.308693 2.53968,-2.510314 2.12619,-0.301966 2.22772,-0.004 2.22772,6.538442 0,6.740641 -0.099,7.001552 -5.9449,15.662921 -3.26969,4.844452 -7.74462,10.309246 -9.94428,12.143987 -2.19966,1.834742 -5.77393,5.949037 -7.94282,9.142879 -2.34976,3.460168 -6.29513,7.465423 -9.76248,9.910673 l -5.81903,4.10369 -1.15924,7.92805 c -1.61723,11.06032 -4.40347,19.58965 -9.70377,29.70553 -5.01528,9.57187 -13.95714,20.46445 -14.03497,17.09676 -0.0428,-1.8524 -0.1273,-1.86246 -1.77762,-0.21171 -1.37485,1.3752 -1.46515,1.89852 -0.43722,2.53406 1.41537,0.87508 -1.77232,4.09197 -9.46671,9.55344 -2.27836,1.61719 -4.34463,3.44333 -4.59171,4.0581 -0.8189,2.03758 6.19452,11.05322 18.90021,24.29583 6.90108,7.19272 12.04414,13.24542 11.42903,13.45046 -0.61512,0.20504 -0.83848,1.12371 -0.49637,2.0415 0.34212,0.91778 -1.79925,-0.97306 -4.75858,-4.20188 -2.95935,-3.22881 -5.27705,-6.21281 -5.15046,-6.6311 0.12659,-0.41828 -1.76241,-2.39328 -4.19777,-4.38889 -2.43538,-1.9956 -4.20453,-3.98988 -3.93146,-4.43172 0.27308,-0.44185 -1.40227,-2.36965 -3.72301,-4.28402 -2.32073,-1.91436 -5.99559,-5.73898 -8.16635,-8.49916 -4.50513,-5.7284 -5.73975,-6.34273 -10.18478,-5.06791 -1.75731,0.50399 -3.19511,0.54209 -3.19511,0.0847 0,-1.33295 -11.17951,1.64109 -12.389579,3.29596 -0.60449,0.82669 -2.322383,1.8101 -3.817542,2.18536 -3.551652,0.89142 -4.937215,3.23379 -7.580515,12.81533 -4.406767,15.97381 -11.099683,29.94917 -15.20688,31.75323 -1.152028,0.50601 -2.096442,1.7759 -2.098696,2.82193 -0.0024,1.08338 -1.280677,2.61084 -2.970297,3.54913 -1.631409,0.90597 -2.982805,2.27784 -3.003103,3.04859 -0.05664,2.15103 -3.526894,6.90294 -4.570213,6.25813 -0.985639,-0.60915 -3.808724,1.30636 -3.808724,2.5843 0,1.92758 5.895059,2.34928 41.089109,2.93925 l 37.62376,0.63071 -39.232671,0.18757 c -21.57797,0.10316 -40.736386,0.48547 -42.574257,0.84959 -3.159411,0.62595 -3.260618,0.56176 -1.856436,-1.17724 z m 42.238485,-67.99171 c -1.942887,-0.70765 -3.471758,-0.70422 -4.950495,0.0112 -1.790743,0.86631 -1.332552,1.03319 2.81102,1.02385 4.566697,-0.0103 4.732564,-0.0905 2.139475,-1.03501 l 0,-3e-5 z m -14.020663,-0.82863 c -1.089109,-0.4866 -6.435644,-1.80129 -11.881188,-2.92155 -5.759121,-1.18476 -12.800298,-3.45953 -16.831683,-5.43774 -6.954731,-3.41271 -17.742094,-11.92119 -16.880858,-13.3147 0.253072,-0.40948 3.040932,-0.57204 6.195246,-0.36125 4.48988,0.30005 5.355073,0.14443 3.984772,-0.71671 -0.96269,-0.60499 -4.913826,-1.36519 -8.780302,-1.68935 -6.863409,-0.57539 -7.004171,-0.54119 -5.941584,1.44428 2.200044,4.11082 13.668199,13.46069 20.585236,16.78294 7.129107,3.42411 21.632479,7.0912 28.065212,7.09613 2.851296,0.002 3.114461,-0.15412 1.485149,-0.88205 z m 13.55198,-1.63782 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52001 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 8.981792,-3.22305 c 4.1272,-1.05557 9.34757,-2.85973 11.60083,-4.00925 2.25325,-1.14953 4.87457,-1.8432 5.82513,-1.54151 0.95056,0.30171 2.59602,-0.12295 3.65656,-0.94367 1.60041,-1.23851 1.63367,-1.38963 0.19559,-0.88881 -2.84772,0.99172 -1.97918,-0.17229 2.18456,-2.92772 2.15449,-1.42577 4.50534,-2.36663 5.22413,-2.09081 0.7188,0.27584 3.05637,-1.2901 5.1946,-3.47985 2.13823,-2.18975 3.51995,-3.98136 3.07047,-3.98136 -0.44946,0 -0.26663,-0.66342 0.4063,-1.47425 0.67294,-0.81083 1.5681,-1.26129 1.98925,-1.001 0.42114,0.26029 1.37313,-0.30156 2.11553,-1.24853 1.22149,-1.55808 1.18509,-1.59258 -0.38286,-0.36292 -0.95297,0.74738 -1.73267,0.91332 -1.73267,0.36877 0,-1.1032 2.94273,-3.80059 3.86504,-3.5428 0.32472,0.0908 0.81317,-0.0921 1.08545,-0.40626 0.27228,-0.3142 -0.0619,-0.25079 -0.74257,0.14094 -1.83418,1.05552 -1.52708,0.0245 1.35025,-4.53358 3.80038,-6.02017 8.15245,-16.13427 10.34121,-24.03269 2.90781,-10.4932 3.24131,-10.00199 -6.51584,-9.59724 -8.06376,0.33451 -11.36374,-0.51104 -11.36374,-2.91169 0,-1.41219 3.87705,-3.01077 12.01762,-4.9551 13.6173,-3.2524 18.1279,-6.30458 30.44942,-20.604205 3.20647,-3.721241 5.60795,-5.75908 6.01348,-5.102907 0.45242,0.732027 1.17307,0.513084 2.18435,-0.663636 2.69435,-3.135129 3.29702,-4.863342 0.99046,-2.840244 -1.18271,1.037369 -2.15038,1.440581 -2.15038,0.896027 0,-1.154396 3.94299,-4.919356 4.6419,-4.432319 0.26048,0.181519 0.77064,-0.0013 1.13367,-0.406262 0.36304,-0.404963 0.10314,-0.415797 -0.57755,-0.02408 -1.80598,1.039294 -1.51814,-0.190163 0.80999,-3.459724 2.31999,-3.258114 2.32271,-3.256657 -3.39724,-1.816357 -3.2192,0.810603 -6.66348,0.694459 -14.67251,-0.494768 -15.04707,-2.234274 -20.55437,-0.689621 -28.57683,8.015049 -2.42602,2.632325 -4.72907,4.680174 -5.11788,4.550775 -0.38882,-0.129399 -0.48449,0.344426 -0.2126,1.052946 0.27188,0.70852 -0.4282,2.123094 -1.55573,3.143497 -2.0095,1.818571 -2.09324,1.812104 -4.23219,-0.326854 l -2.18214,-2.182131 2.25594,-4.252496 c 1.24077,-2.338872 4.17354,-6.452573 6.51728,-9.141556 2.34372,-2.688985 4.05061,-5.50801 3.79308,-6.264503 -0.31259,-0.918192 -0.0455,-1.114196 0.80328,-0.589595 0.85837,0.530499 1.02875,0.393018 0.52435,-0.423105 -0.41094,-0.664922 -0.99572,-0.9604 -1.2995,-0.656618 -0.69266,0.69266 -3.20978,-1.330935 -3.20978,-2.580451 0,-0.510014 0.51439,-0.609392 1.14308,-0.220837 0.73045,0.451439 0.87336,0.270048 0.3959,-0.50249 -0.41094,-0.664922 -1.00055,-0.955563 -1.31024,-0.645868 -0.69833,0.698319 -4.18913,-2.365165 -4.18913,-3.67632 0,-0.526833 0.7797,-0.370613 1.73267,0.347155 0.95297,0.717767 -0.70223,-1.23225 -3.67822,-4.333371 -3.76003,-3.918124 -5.93501,-5.472057 -7.12873,-5.093182 -0.94481,0.299873 -3.07003,-0.15402 -4.7227,-1.00865 -2.43778,-1.26062 -3.37289,-1.324035 -4.95495,-0.33602 -2.36555,1.477307 -3.05981,0.886 -3.92467,-3.34268 -0.56625,-2.768728 -1.37248,-3.513567 -5.43639,-5.022464 -7.80616,-2.898363 -17.966683,-4.011606 -26.200113,-2.870631 -3.997279,0.553936 -7.475959,1.215337 -7.730402,1.469779 -0.254442,0.254443 0.998085,3.050852 2.783393,6.214244 2.874608,5.093525 3.291609,6.794112 3.644505,14.862796 l 0.398492,9.111176 3.564442,0.668693 c 7.773644,1.458345 16.010573,8.110583 19.620143,15.845464 3.09701,6.636514 3.26024,18.338664 0.34238,24.546143 -2.99996,6.38214 -7.1277,10.84757 -13.007325,14.07144 -4.530381,2.48406 -6.383854,2.90835 -12.728271,2.91366 -6.074888,0.005 -8.236255,-0.44332 -11.881188,-2.465 -2.450495,-1.35916 -4.455445,-2.98232 -4.455445,-3.60701 0,-0.62469 -0.40559,-1.50708 -0.901312,-1.96089 -0.523658,-0.47936 -0.602889,-0.3065 -0.189092,0.41255 0.391721,0.68069 0.309434,1.23762 -0.182859,1.23762 -1.220735,0 -4.304298,-3.49834 -3.655466,-4.14718 0.286625,-0.28662 -0.191905,-1.11291 -1.063399,-1.83618 -1.321234,-1.09653 -1.725666,-1.0867 -2.433844,0.0592 -0.46712,0.75582 -0.647589,1.7006 -0.401041,2.09952 0.480206,0.77699 -4.431607,4.73002 -8.49972,6.84057 -1.361386,0.7063 -6.473966,1.77939 -11.361289,2.38466 l -8.886042,1.10047 -0.8419,4.2572 c -1.116431,5.64542 -0.634772,6.55826 4.953601,9.38814 6.711939,3.39884 14.108367,5.45589 25.541571,7.10346 13.412147,1.93275 20.966236,1.82034 33.743152,-0.50211 17.901519,-3.25395 20.945769,-2.59407 18.234109,3.95245 -1.77158,4.27697 -8.27108,9.72932 -15.51118,13.01214 -10.066949,4.56456 -20.604188,6.60666 -38.045678,7.37316 -12.034826,0.52888 -15.515628,0.97079 -14.765554,1.87458 0.53979,0.65041 0.751763,1.41223 0.47105,1.69294 -0.280712,0.28071 0.280084,1.1308 1.246214,1.8891 1.597283,1.25367 1.633357,1.22157 0.397743,-0.35396 -1.901096,-2.42408 -0.973659,-2.18092 4.907357,1.28665 4.510039,2.65922 13.386837,5.60901 26.15447,8.69123 6.758464,1.63156 18.458956,1.2966 26.494168,-0.75846 l 0,-4e-5 z m 15.58504,-0.061 c 1.16161,-0.7507 0.90473,-0.96308 -1.17919,-0.97494 -1.46538,-0.008 -2.9397,0.43038 -3.27626,0.97494 -0.78135,1.26425 2.49915,1.26425 4.45545,0 z m 6.00568,-2.01503 c 1.95644,-1.04706 2.62207,-2.93547 1.0347,-2.93547 -0.48422,0 -1.93224,0.87627 -3.21783,1.94726 -2.49465,2.07826 -1.06383,2.72592 2.18313,0.98821 z m -6.00568,-1.45032 c 1.36139,-0.77824 2.0297,-1.41498 1.48515,-1.41498 -0.54456,0 -2.10396,0.63674 -3.46535,1.41498 -1.36138,0.77824 -2.0297,1.41498 -1.48515,1.41498 0.54456,0 2.10396,-0.63674 3.46535,-1.41498 z m -62.458746,0.13411 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553336,0.36093 1.577225,1.26362 4.799862,2.3676 3.441125,1.17883 l 0,0 z m 74.762706,-3.12566 c 1.04936,-0.7939 1.64445,-1.70691 1.32243,-2.02893 -0.78266,-0.78265 -4.7155,1.36919 -4.7155,2.58006 0,1.33049 1.15362,1.1431 3.39307,-0.55113 z m 5.3845,-4.97977 c 0.31295,-1.61495 0.14607,-1.68767 -1.23763,-0.53929 -1.89234,1.57049 -2.12795,3.40609 -0.36172,2.81801 0.68069,-0.22665 1.40039,-1.25207 1.59935,-2.27872 z m -93.926084,0.17176 c 0,-0.2056 -0.779703,-0.9853 -1.732673,-1.73268 -1.570353,-1.23155 -1.605372,-1.19653 -0.373817,0.37382 1.293435,1.64926 2.10649,2.17375 2.10649,1.35886 z m 42.048957,-9.0646 c 10.23476,-3.01561 12.830661,-4.22882 16.665417,-7.78864 1.52559,-1.41621 3.14513,-2.57492 3.599,-2.57492 0.45387,0 1.59099,-1.16873 2.52694,-2.59715 0.93594,-1.42844 1.24801,-2.31675 0.69349,-1.97403 -0.55454,0.34271 -1.20807,0.0635 -1.45231,-0.62067 -0.24423,-0.68409 -0.82632,-0.88541 -1.2935,-0.44739 -0.46721,0.43803 -0.19404,1.21091 0.60702,1.71751 1.25252,0.79212 1.23533,0.92323 -0.12275,0.93627 -0.86857,0.008 -2.42798,0.95441 -3.46535,2.10238 -5.028165,5.56424 -22.795527,11.3182 -38.212356,12.37508 -15.799597,1.08311 -17.048668,2.42489 -1.792578,1.92561 10.641937,-0.34827 15.176438,-0.97076 22.246977,-3.05405 l 0,0 z m 63.891637,-3.12611 c 0,-1.41552 -0.23243,-1.39342 -1.9802,0.18829 -1.08911,0.98563 -1.9802,2.18422 -1.9802,2.66353 0,0.47932 0.89109,0.39459 1.9802,-0.18828 1.08911,-0.58287 1.9802,-1.78147 1.9802,-2.66354 z M 97.166642,146.77097 c 3.547598,-0.77002 4.965228,-1.47727 4.298178,-2.14431 -0.66706,-0.66706 -4.175166,-0.42281 -10.636358,0.74056 -14.897153,2.68229 -37.124591,0.77195 -52.477337,-4.51017 -6.578027,-2.26317 -6.378989,-2.22908 -6.378989,-1.09252 0,1.42916 9.008565,4.85904 15.926311,6.06371 16.965213,2.95437 38.134158,3.35943 49.268195,0.94273 l 0,0 z m 53.617378,0.0462 c 0.58287,-1.08911 0.837,-1.9802 0.56472,-1.9802 -0.27228,0 -0.97195,0.89109 -1.55482,1.9802 -0.58287,1.08911 -0.837,1.9802 -0.56472,1.9802 0.27227,0 0.97195,-0.89109 1.55482,-1.9802 z m 5.94059,-4.62356 c 0,-2.3135 -1.69554,-0.59965 -2.85822,2.88907 l -1.073,3.21964 1.96562,-2.33741 c 1.08108,-1.28558 1.9656,-2.98266 1.9656,-3.7713 z m -77.497329,2.91089 c -2.054226,-0.21433 -5.173038,-0.21074 -6.930694,0.008 -1.757656,0.21872 -0.07693,0.39409 3.734955,0.38969 3.811881,-0.004 5.249963,-0.18335 3.195739,-0.39768 l 0,7e-5 z m 10.356241,-0.94387 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52002 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 19.616338,-1.30386 c 0,-0.54455 -0.47184,-0.99009 -1.04854,-0.99009 -0.57669,0 -0.77316,0.44554 -0.43661,0.99009 0.33655,0.54456 0.8084,0.9901 1.04853,0.9901 0.24014,0 0.43662,-0.44554 0.43662,-0.9901 z m 47.45458,-8.41584 c 0,-0.54455 -0.63674,0.12377 -1.41498,1.48515 -0.77823,1.36139 -1.41498,2.92079 -1.41498,3.46535 0,0.54455 0.63675,-0.12376 1.41498,-1.48515 0.77824,-1.36139 1.41498,-2.92079 1.41498,-3.46535 z M 28.453542,136.6394 c -0.717346,-1.86938 -3.412099,-3.08084 -3.412099,-1.53397 0,1.05715 3.177874,3.9134 3.73462,3.35666 0.149813,-0.14981 0.0047,-0.97003 -0.322521,-1.82269 z m 6.406383,0.90594 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553337,0.36093 1.577226,1.26362 4.799863,2.3676 3.441126,1.17883 z m -8.178941,-9.80642 c -0.27121,-0.67032 -0.476602,0.11785 -0.456423,1.75152 0.02018,1.63366 0.242077,2.18212 0.493111,1.21878 0.251032,-0.96334 0.234523,-2.29997 -0.03668,-2.9703 l -4e-6,0 z M 162.66521,127.0736 c 0,-0.51242 -0.44555,-1.20703 -0.9901,-1.54359 -0.54456,-0.33655 -0.9901,0.0827 -0.9901,0.93167 0,0.84897 0.44554,1.54358 0.9901,1.54358 0.54455,0 0.9901,-0.41925 0.9901,-0.93166 z M 27.619826,122.33281 c -0.329002,-0.329 -0.563011,0.25579 -0.52002,1.29951 0.0475,1.15341 0.28212,1.38802 0.598185,0.59819 0.286011,-0.71474 0.250836,-1.5687 -0.07817,-1.8977 l 3e-6,0 z m 136.035474,0.2269 c 0,-0.81683 -0.44554,-1.48514 -0.99009,-1.48514 -0.54456,0 -0.9901,0.66831 -0.9901,1.48514 0,0.81684 0.44554,1.48515 0.9901,1.48515 0.54455,0 0.99009,-0.66831 0.99009,-1.48515 z M 33.704809,119.40196 c -0.95297,-0.24903 -2.512376,-0.24903 -3.465346,0 -0.952971,0.24904 -0.173268,0.4528 1.732673,0.4528 1.905941,0 2.685644,-0.20376 1.732673,-0.4528 z m 51.237624,-0.30759 c 0.336553,-0.54456 -0.250915,-0.9901 -1.305483,-0.9901 -1.054569,0 -2.472053,-0.66832 -3.149963,-1.48515 -0.677909,-0.81683 -2.197663,-1.48515 -3.37723,-1.48515 -1.179567,0 -3.798279,-0.84306 -5.819362,-1.87346 -3.979476,-2.02885 -4.801958,-1.43381 -1.788124,1.29368 1.984228,1.7957 10.984716,4.90909 10.984716,3.79975 0,-0.35514 0.534654,-0.11106 1.188119,0.54241 1.44777,1.44777 2.457132,1.50894 3.267327,0.19802 z m 79.702967,-3.02873 c 0,-1.05697 -0.44554,-1.92177 -0.9901,-1.92177 -0.54455,0 -0.99009,1.14016 -0.99009,2.53369 0,1.43699 0.42855,2.26881 0.99009,1.92176 0.54456,-0.33656 0.9901,-1.47671 0.9901,-2.53368 z m -126.008939,1.3525 c -0.963334,-0.25103 -2.299968,-0.23452 -2.970297,0.0366 -0.670329,0.27122 0.117853,0.47661 1.751517,0.45643 1.633663,-0.0202 2.182114,-0.24208 1.21878,-0.49311 l 0,5e-5 z m 15.788583,-6.49209 c 2.961802,-2.58663 6.027485,-4.70297 6.812628,-4.70297 1.653245,0 1.836694,-1.82146 0.39887,-3.96039 -0.83888,-1.24794 -1.390264,-1.01072 -3.45205,1.48514 -1.349539,1.63367 -2.677116,3.63862 -2.950173,4.45545 -0.273055,0.81683 -3.168256,2.95063 -6.433779,4.74178 -3.265523,1.79115 -5.937315,3.64601 -5.937315,4.12192 0,1.77959 6.361283,-1.59914 11.561819,-6.14093 z m -20.47271,5.3104 c 0,-1.48733 -5.81027,-1.8801 -6.366582,-0.43038 -0.356538,0.92913 0.492992,1.3081 2.93231,1.3081 1.888849,0 3.434272,-0.39498 3.434272,-0.87772 z m 63.050779,-1.35 c 2.916955,-1.98579 4.205247,-3.71287 2.769577,-3.71287 -0.693665,0 -8.394613,5.11626 -8.394613,5.57711 0,1.01623 2.716191,0.11603 5.625036,-1.86424 z m -5.082551,-1.19364 c 7.593085,-3.17259 13.318898,-12.23833 13.318898,-21.087947 0,-14.183278 -14.801367,-26.126413 -27.276503,-22.009246 -4.871629,1.607782 -12.143736,8.333235 -14.435363,13.350236 -3.260107,7.137268 -1.947056,16.953627 3.009811,22.501317 l 2.75988,3.08884 0.514066,-6.40417 c 0.59176,-7.372086 2.817916,-12.370412 6.194803,-13.909026 9.324945,-4.24873 15.584088,10.950876 9.956609,24.178486 -0.930827,2.18794 1.172672,2.29087 5.957799,0.29151 l 0,0 z m -66.879119,-1.52913 c -2.805149,-2.19422 -4.307733,-2.52716 -3.741707,-0.82908 0.211038,0.6331 1.180081,1.268 2.15343,1.41085 0.973349,0.14286 2.025929,0.51595 2.339067,0.82908 0.313138,0.31314 0.829243,0.55943 1.1469,0.54732 0.317656,-0.0121 -0.536304,-0.89328 -1.89769,-1.95817 z m 12.639913,0.64485 c 0.689575,-0.42992 0.997439,-1.19644 0.684141,-1.70337 -0.313298,-0.50692 -0.139505,-0.92168 0.386206,-0.92168 0.525712,0 0.704595,-0.96077 0.397519,-2.13502 -0.337827,-1.29185 -0.167417,-1.89344 0.431502,-1.52328 0.604271,0.37346 1.005912,-1.20529 1.031127,-4.0531 0.03148,-3.556019 -0.171219,-4.194157 -0.852784,-2.684642 -0.678574,1.502882 -0.773791,1.192692 -0.395022,-1.286842 0.353363,-2.313228 0.165236,-3.060723 -0.644381,-2.560356 -0.737692,0.45592 -0.940577,0.178019 -0.571745,-0.783139 0.314436,-0.819406 0.23569,-2.033505 -0.174991,-2.698 -1.105326,-1.788456 -7.682811,-2.144736 -9.055691,-0.490515 -0.631379,0.760762 -0.759249,1.396753 -0.284156,1.413317 0.475095,0.01654 0.06457,0.495168 -0.912263,1.063584 -1.129264,0.657109 -1.565313,1.697515 -1.197349,2.856861 0.318297,1.002872 0.145073,2.091406 -0.384943,2.418971 -1.212393,0.749301 -1.114708,6.501761 0.11041,6.501761 0.49838,0 0.626441,0.88128 0.284578,1.95839 -1.132056,3.56679 7.260902,7.05039 11.147842,4.62706 l 0,0 z m 8.934184,-0.55418 c 2.020385,-1.03924 5.010061,-3.29502 6.643725,-5.01286 2.868463,-3.01627 2.981671,-3.49028 3.302077,-13.826072 l 0.33178,-10.702722 -3.762914,-0.705927 C 47.602481,80.969761 43.95345,78.863901 38.40778,73.51044 l -4.950496,-4.778915 -3.90401,1.921073 C 17.503668,76.58193 12.423679,90.628824 18.240927,101.93283 c 3.23262,6.2816 4.539882,6.43779 5.329032,0.6367 0.928828,-6.827865 1.319844,-7.895489 4.103161,-11.203281 7.697735,-9.148234 17.690208,3.484377 13.905573,17.579601 -1.6234,6.04608 -1.03574,6.43209 5.036847,3.3085 l 0,0 z m 37.877227,-0.17548 c 0.607833,-1.13574 0.846281,-2.32386 0.529884,-2.64025 -0.316397,-0.3164 -0.575268,-0.0873 -0.575268,0.50911 0,0.59643 -0.700141,1.78455 -1.55587,2.64027 -0.855728,0.85573 -1.094176,1.55587 -0.529884,1.55587 0.564291,0 1.523303,-0.92924 2.131138,-2.065 l 0,0 z m -8.956275,-0.41024 c -0.777242,-0.93653 -0.843612,-1.48515 -0.179665,-1.48515 0.579095,0 1.32826,0.44554 1.664814,0.9901 0.336553,0.54455 1.710509,0.9901 3.053236,0.9901 3.405659,0 4.705098,-3.86234 3.99729,-11.88119 -0.410484,-4.650429 -0.278996,-6.023676 0.474005,-4.950498 0.92628,1.320129 0.997019,1.320129 0.636655,0 -0.222976,-0.816832 -0.888084,-1.485149 -1.478018,-1.485149 -0.589933,0 -1.406765,-0.334158 -1.815181,-0.742574 -0.408416,-0.408416 -1.808473,-0.742574 -3.111239,-0.742574 -1.326986,0 -2.099559,-0.435416 -1.756748,-0.990099 1.082137,-1.750934 -0.356281,-1.056251 -2.436678,1.176792 -1.948858,2.091852 -2.796679,4.371505 -1.276193,3.431475 0.408415,-0.252495 0.742574,2.796683 0.742574,6.775957 0,4.5426 -0.368457,7.02333 -0.990099,6.66611 -0.544555,-0.31292 -0.141343,0.39874 0.896028,1.58146 2.106995,2.4022 3.511949,2.99403 1.579219,0.66524 l 0,0 z m 74.981158,-0.19108 c -0.96334,-0.25103 -2.29997,-0.23453 -2.9703,0.0366 -0.67032,0.27122 0.11786,0.4766 1.75152,0.45643 1.63366,-0.0202 2.18212,-0.24208 1.21878,-0.49311 l 0,5e-5 z m -84.882148,-2.77922 c -0.67791,-0.81683 -1.678108,-1.48515 -2.222662,-1.48515 -0.552304,0 -0.445093,0.65669 0.242464,1.48515 0.67791,0.81683 1.678108,1.48515 2.222663,1.48515 0.552304,0 0.445093,-0.6567 -0.242465,-1.48515 z m 38.428218,-0.43317 c 0.24752,-0.74257 -0.12376,-1.11386 -0.86634,-0.86634 -0.71472,0.23824 -1.49443,1.01795 -1.73267,1.73268 -0.24752,0.74257 0.12376,1.11386 0.86634,0.86633 0.71472,-0.23823 1.49443,-1.01795 1.73267,-1.73267 z m 61.57178,-0.16781 c 0,-1.1313 -2.6849,-1.15685 -3.38,-0.0322 -0.2896,0.4686 -0.27234,1.10622 0.0384,1.41693 0.7726,0.77266 3.34158,-0.29192 3.34158,-1.38475 z m -145.544552,0.16436 c 0,-1.16817 -1.931044,-2.41782 -2.640265,-1.7086 -0.709219,0.70923 0.54042,2.64027 1.708598,2.64027 0.512417,0 0.931667,-0.41925 0.931667,-0.93167 z m 65.94472,-2.76058 c -0.329002,-0.329 -0.563011,0.25578 -0.52002,1.29951 0.04751,1.15341 0.28212,1.38802 0.598185,0.59818 0.286011,-0.71472 0.250836,-1.56868 -0.07817,-1.89769 l 3e-6,0 z m 20.193892,-0.7632 c 0,-0.81683 -0.44554,-1.48515 -0.9901,-1.48515 -0.54455,0 -0.9901,0.66832 -0.9901,1.48515 0,0.81683 0.44555,1.48515 0.9901,1.48515 0.54456,0 0.9901,-0.66832 0.9901,-1.48515 z m 60.18796,-0.40346 c 2.02039,-1.03875 5.45561,-3.52622 7.63382,-5.527735 l 3.9604,-3.639109 -4.45545,3.425762 c -2.45049,1.884172 -6.23762,4.351962 -8.41584,5.483972 -2.17822,1.13201 -3.60848,2.0779 -3.17837,2.10196 0.43011,0.0241 2.43506,-0.80612 4.45544,-1.84485 z m -94.1857,-5.289607 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237627 0,1.36138 0.224726,1.91831 0.499392,1.23762 0.274665,-0.68069 0.274665,-1.794554 0,-2.475247 z m 13.861386,-0.990099 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237624 0,1.361382 0.224726,1.918312 0.499392,1.237622 0.274666,-0.680691 0.274666,-1.794553 0,-2.475246 z m -25.408199,0.742575 c 0,-0.816832 -0.445544,-1.485149 -0.990099,-1.485149 -0.544554,0 -0.990099,0.668317 -0.990099,1.485149 0,0.816831 0.445545,1.485151 0.990099,1.485151 0.544555,0 0.990099,-0.66832 0.990099,-1.485151 z m 47.524753,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921683 -0.55343,0.342039 -0.74992,1.036653 -0.43661,1.543584 0.84874,1.37331 1.44286,1.11724 1.44286,-0.621901 l 0,0 z M 13.75844,96.59024 c -0.329002,-0.329 -0.563011,0.255782 -0.520019,1.299504 0.04751,1.153416 0.282119,1.38802 0.598184,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897693 l 0,0 z m 45.936468,-3.733496 c 0,-0.816831 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668317 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m 49.504952,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921684 -0.55343,0.34204 -0.74992,1.036654 -0.43661,1.543585 0.84874,1.373307 1.44286,1.117237 1.44286,-0.621901 l 0,0 z M 12.768341,90.649645 c -0.329002,-0.328998 -0.563011,0.255783 -0.52002,1.299505 0.04751,1.153416 0.28212,1.38802 0.598185,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897694 l 0,0 z m 70.193894,0.721951 c -0.336554,-0.544555 -1.142551,-0.983277 -1.791106,-0.974941 -0.708531,0.0089 -0.586411,0.398248 0.305957,0.974941 1.902102,1.229238 2.244857,1.229238 1.485149,0 z m 25.247525,-4.513878 c 0,-0.84897 -0.45281,-1.263728 -1.00625,-0.921685 -0.55343,0.342043 -0.74992,1.036654 -0.43661,1.543581 0.84874,1.373311 1.44286,1.117238 1.44286,-0.621896 z M 13.75844,84.709054 c -0.329002,-0.329001 -0.563011,0.255777 -0.520019,1.299505 0.04751,1.153409 0.282119,1.38802 0.598184,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 0,0 z m 48.906765,-3.85473 c 0,-1.356215 -3.082898,-1.911382 -4.232156,-0.762123 -0.330986,0.330986 -0.08945,1.422196 0.536762,2.424911 0.842923,1.349734 1.470503,1.547624 2.416974,0.762123 0.703131,-0.583548 1.27842,-1.674757 1.27842,-2.424911 z m 43.564355,0.09971 c 0,-2.007107 -9.940776,-11.875249 -12.685773,-12.593082 -3.422347,-0.894964 -2.536662,0.72179 2.04221,3.727903 4.685203,3.075921 8.056173,6.371341 8.979963,8.778691 0.77225,2.012434 1.6636,2.058775 1.6636,0.08649 z m -47.693353,-7.404219 2.306645,-4.455446 -0.675699,4.455446 -0.6757,4.455445 3.814599,-3.586129 c 2.098029,-1.972372 6.311347,-5.155371 9.362929,-7.073331 5.874539,-3.692229 6.839458,-5.599101 6.818235,-13.474203 -0.0116,-4.303265 -3.763041,-12.649115 -7.037511,-15.656368 -5.956689,-5.47059 -15.534138,-7.597002 -22.017021,-4.888282 -12.757989,5.330628 -18.072962,19.793085 -11.85765,32.265591 2.52515,5.067315 2.685106,5.196865 3.601855,2.917172 0.958373,-2.383197 0.960066,-2.382511 1.654947,0.671085 0.942906,4.14352 1.700115,5.200511 5.327538,7.436733 4.523217,2.788458 6.716499,2.070908 9.376833,-3.067713 l 0,0 z m 8.682689,1.5849 c 1.905993,-1.851076 4.77995,-3.91008 6.386569,-4.575565 2.564998,-1.062456 4.03369,-2.949929 2.295417,-2.949929 -2.10037,0 -13.235677,8.775011 -13.235677,10.430176 0,1.083649 1.30255,0.252787 4.553691,-2.904682 z M 20.090948,74.8078 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z M 152.76422,69.68259 c 0,-0.272277 -1.78218,1.245201 -3.9604,3.372174 -2.17822,2.126974 -3.9604,4.089996 -3.9604,4.362274 0,0.272277 1.78218,-1.245201 3.9604,-3.372175 2.17822,-2.126973 3.9604,-4.089996 3.9604,-4.362273 z M 41.625601,72.476287 c -2.586633,-2.217071 -4.709793,-4.553304 -4.718131,-5.191628 -0.02877,-2.202305 -1.632163,-3.701423 -3.281819,-3.068391 -2.032483,0.779938 -2.195989,3.392952 -0.212309,3.392952 0.792663,0 3.354544,2.00317 5.693069,4.45149 2.338525,2.44832 4.92018,4.450394 5.737012,4.449053 0.816832,-0.0014 -0.631188,-1.816405 -3.217822,-4.033476 l 0,0 z M 24.051344,70.847404 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z m 6.526162,-3.972749 c -0.745512,-0.745512 -5.536063,1.770447 -5.536063,2.907495 0,0.46652 1.378038,0.135607 3.062307,-0.735362 1.684269,-0.870969 2.797459,-1.848429 2.473756,-2.172133 z m 53.127303,0.748085 c 0.952971,-0.0074 1.732673,-0.459065 1.732673,-1.003619 0,-0.544555 -0.940674,-0.990099 -2.090387,-0.990099 -1.852777,0 -2.016491,-0.393899 -1.440284,-3.465347 0.406143,-2.164925 0.261718,-3.465346 -0.38486,-3.465346 -0.56923,0 -1.034964,1.059307 -1.034964,2.354014 0,1.294709 -0.668316,2.90867 -1.485148,3.58658 -2.367441,1.964801 -1.885292,4.298583 0.742574,3.594342 1.225248,-0.328353 3.007426,-0.60309 3.960396,-0.610525 z m 71.134371,-0.722043 c 1.58154,-0.934242 2.87553,-2.079091 2.87553,-2.544109 0,-1.671282 -4.25968,-0.165537 -5.70037,2.015008 -1.76311,2.668563 -1.02958,2.805958 2.82484,0.529101 z m 47.13694,-2.884855 c -0.37294,-0.372946 -1.68483,-0.148769 -2.91529,0.498172 -1.23047,0.64694 -1.45751,0.953686 -0.50454,0.681656 1.92704,-0.550082 2.24796,0.402733 0.74808,2.221031 -0.54153,0.65649 -0.009,0.312431 1.18262,-0.764577 1.19197,-1.077007 1.86208,-2.263334 1.48913,-2.636282 z m -52.1822,2.108229 c 0.67791,-0.816831 1.00979,-1.485148 0.73751,-1.485148 -0.27227,0 -1.0497,0.668317 -1.72761,1.485148 -0.67791,0.816832 -1.00979,1.485149 -0.73752,1.485149 0.27228,0 1.04971,-0.668317 1.72762,-1.485149 z m 37.15543,-0.451808 c -0.32185,-0.520771 -1.23923,-0.695875 -2.03863,-0.38912 -2.04664,0.785373 -1.80547,1.335978 0.5852,1.335978 1.12125,0 1.7753,-0.426086 1.45343,-0.946858 z m -20.13811,-0.719592 c -0.71473,-0.286011 -1.56869,-0.250835 -1.89769,0.07817 -0.329,0.329001 0.25578,0.56301 1.29951,0.520019 1.15341,-0.04751 1.38802,-0.282119 0.59818,-0.598185 l 0,-3e-6 z M 84.05547,61.936777 c -0.329002,-0.329001 -0.563011,0.255776 -0.52002,1.299505 0.04751,1.153409 0.28212,1.38802 0.598185,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 3e-6,0 z m 82.57013,0.721948 c 0,-0.544555 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445544 -1.48515,0.990099 0,0.544554 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445545 1.48515,-0.990099 z m 37.62376,-5.177658 c 0,-1.661518 -0.24856,-1.789209 -1.48514,-0.762936 -0.81684,0.67791 -1.48515,1.832342 -1.48515,2.565406 0,0.777973 0.61827,1.095588 1.48515,0.762936 0.81683,-0.313447 1.48514,-1.46788 1.48514,-2.565406 z M 83.457284,54.18445 c 0,-0.784694 -0.445544,-1.426715 -0.990099,-1.426715 -0.544554,0 -0.990099,0.917384 -0.990099,2.03863 0,1.121247 0.445545,1.76327 0.990099,1.426716 0.544555,-0.336553 0.990099,-1.253937 0.990099,-2.038631 z m 63.366336,-0.931666 c -1.27896,-1.361386 -2.77092,-2.475247 -3.31547,-2.475247 -0.54456,0 0.0563,1.113861 1.33527,2.475247 1.27896,1.361386 2.77092,2.475248 3.31548,2.475248 0.54455,0 -0.0563,-1.113862 -1.33528,-2.475248 z M 82.467185,48.302289 c 0,-0.816832 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668316 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m -1.985115,-5.19802 c -0.0084,-1.2671 -4.736103,-6.714785 -5.323399,-6.134089 -0.649329,0.642032 3.49033,6.834315 4.585742,6.859554 0.408416,0.0094 0.740362,-0.317049 0.737657,-0.725465 l 0,0 z m 50.49997,-0.247525 c -0.81683,-0.527877 -1.9307,-0.959776 -2.47525,-0.959776 -0.54456,0 -0.32178,0.431899 0.49505,0.959776 0.81683,0.527878 1.93069,0.959777 2.47525,0.959777 0.54455,0 0.32178,-0.431899 -0.49505,-0.959777 z m 4.44995,-0.996169 c -0.98866,-1.092447 -2.01229,-1.771531 -2.27475,-1.509075 -0.66527,0.66528 1.80418,3.495343 3.04998,3.495343 0.56227,0 0.21342,-0.89382 -0.77523,-1.986268 l 0,0 z m -95.539062,-4.19679 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.677909 1.485148,-1.678107 1.485148,-2.222662 z m 92.079212,0.795947 c 0,-2.367417 -1.80911,-2.723191 -2.95546,-0.581213 -0.91594,1.711444 -0.77708,2.007928 0.94043,2.007928 1.10826,0 2.01503,-0.642021 2.01503,-1.426715 z M 43.853324,33.703389 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.67791 1.485148,-1.678108 1.485148,-2.222662 z m 29.450539,-0.0051 c -0.341635,-3.033194 -0.613818,-3.235945 -4.743791,-3.533678 -2.40975,-0.173719 -4.148989,-0.08348 -3.864976,0.200533 0.746043,0.746042 8.309556,6.402673 8.668673,6.483162 0.166387,0.03729 0.139429,-1.380215 -0.05991,-3.150017 z m 45.796987,1.732673 c -0.67791,-0.816832 -1.70871,-1.485149 -2.29066,-1.485149 -0.58196,0 -0.19325,0.654147 0.8638,1.453661 2.48363,1.878524 2.96864,1.889227 1.42686,0.03148 l 0,3e-6 z m 5.94059,-0.933056 c 0,-0.721181 -1.00247,-1.579892 -2.22772,-1.908245 -3.82044,-1.023837 -4.13152,-0.702262 -1.76134,1.820687 2.31705,2.466393 3.98906,2.503093 3.98906,0.08755 l 0,4e-6 z m 8.8851,-5.657864 c 5.0656,-7.213134 5.95021,-9.230659 3.73867,-8.526659 -1.72171,0.548068 -10.64357,12.438161 -10.64357,14.184592 0,2.924919 2.06665,1.231484 6.9049,-5.657933 z m -54.828018,2.397173 c -0.586902,-0.586901 -3.56203,0.943932 -3.56203,1.832819 0,0.490907 0.870827,0.348719 1.935171,-0.315974 1.064342,-0.664694 1.796429,-1.347273 1.626859,-1.516845 z m -29.622424,0.529501 c 3.007757,-1.087619 4.641314,-3.761497 2.298018,-3.761497 -0.544554,0 -0.990099,0.445545 -0.990099,0.990099 0,0.544555 -0.58316,0.990099 -1.295911,0.990099 -1.477794,0 -5.628481,2.890588 -4.219928,2.938809 0.505892,0.01732 2.399456,-0.503561 4.20792,-1.15751 l 0,0 z m 54.958912,-1.46755 c -0.71473,-0.286011 -1.56869,-0.250836 -1.89769,0.07817 -0.329,0.329002 0.25577,0.563011 1.2995,0.52002 1.15341,-0.0475 1.38802,-0.28212 0.59819,-0.598185 l 0,-3e-6 z M 59.694908,28.005259 c 0,-1.089109 -0.39099,-1.980198 -0.868866,-1.980198 -1.298365,0 -3.17241,2.559384 -2.422873,3.30892 1.355486,1.355487 3.291739,0.573912 3.291739,-1.328722 z m 21.287129,0.990099 c 0.336553,-0.544554 -0.331763,-0.990099 -1.485149,-0.990099 -1.153385,0 -1.821702,0.445545 -1.485148,0.990099 0.336553,0.544555 1.00487,0.990099 1.485148,0.990099 0.480279,0 1.148595,-0.445544 1.485149,-0.990099 z m 29.207923,0 c 0,-0.544554 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445545 -1.48515,0.990099 0,0.544555 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445544 1.48515,-0.990099 z M 86.427581,28.005259 c 0,-0.544554 -0.694611,-0.990099 -1.543581,-0.990099 -0.848969,0 -1.268219,0.445545 -0.931666,0.990099 0.336553,0.544555 1.031164,0.990099 1.543581,0.990099 0.512417,0 0.931666,-0.445544 0.931666,-0.990099 z m 18.316829,0 c 0.33656,-0.544554 -0.33176,-0.990099 -1.48515,-0.990099 -1.15338,0 -1.8217,0.445545 -1.48514,0.990099 0.33655,0.544555 1.00487,0.990099 1.48514,0.990099 0.48028,0 1.1486,-0.445544 1.48515,-0.990099 z M 53.397761,23.263982 c -2.293369,-2.293369 -3.273717,-0.599352 -1.065339,1.840877 1.180946,1.304931 2.008695,1.63504 2.254066,0.898928 0.213274,-0.63982 -0.321654,-1.872732 -1.188727,-2.739805 l 0,0 z m 41.674343,3.065049 c -0.963333,-0.251033 -2.299967,-0.234524 -2.970297,0.03668 -0.670328,0.271211 0.117854,0.476602 1.751517,0.456424 1.633663,-0.02018 2.182115,-0.242078 1.21878,-0.493111 l 0,4e-6 z M 50.784017,20.160629 c 0,-1.18906 -5.817795,-7.006855 -7.006854,-7.006855 -1.723094,0 -0.911591,1.747528 2.244318,4.833013 3.196159,3.124838 4.762536,3.839805 4.762536,2.173842 z m 99.083553,-7.807387 c -1.32905,-0.443014 -5.95468,4.804941 -5.94174,6.741126 0.006,0.860676 1.47299,-0.172344 3.48946,-2.456779 1.91375,-2.168059 3.01727,-4.096016 2.45228,-4.284347 z m -7.4939,4.754858 c 2.64699,-2.924889 1.22992,-3.38489 -1.49431,-0.485075 -1.27694,1.359238 -1.86755,2.471343 -1.31247,2.471343 0.55508,0 1.81813,-0.893821 2.80678,-1.986268 z m 1.9747,-5.934524 c 2.68184,-2.7227721 4.44726,-4.9364147 3.92318,-4.9192068 -1.79455,0.058926 -11.48794,9.8697018 -9.75161,9.8697018 0.52381,0 3.1466,-2.227723 5.82843,-4.950495 z m 4.99121,-1.055971 c 1.06562,-1.7242011 -0.14804,-2.0893477 -1.506,-0.4531041 -0.78094,0.9409741 -0.85606,1.5090751 -0.19952,1.5090751 0.57909,0 1.34657,-0.475187 1.70552,-1.055971 z m 22.08877,-7.9517764 c 1.71492,-0.5978257 3.11804,-1.51893899 3.11804,-2.04691859 0,-1.07371396 -3.1521,-0.28577416 -6.93069,1.73248789 -3.09382,1.652504 -0.61271,1.8571218 3.81265,0.3144307 l 0,0 z m 6.85154,-0.707599 c 0.59402,-1.78204068 -1.45248,-1.40757811 -2.14309,0.3921386 -0.37003,0.9642713 -0.14875,1.4169139 0.57476,1.1757426 0.64703,-0.2156762 1.35277,-0.9212228 1.56833,-1.5678812 z M 20.090948,0.80296239 c 0,-0.25829297 -1.366838,-1.17644278 -3.037417,-2.04033289 C 13.07504,-3.294728 10.77735,-2.5105441 14.645403,-0.41549494 17.561715,1.1640635 20.090948,1.729987 20.090948,0.80296239 z M 177.51669,-2.5818805 c 0,-1.2146632 -2.78939,-2.1897491 -3.40672,-1.1908861 -0.27491,0.444817 -0.21492,1.0936751 0.1333,1.4419069 0.94359,0.9435791 3.27342,0.7649164 3.27342,-0.2510208 z"
+ transform="translate(0,784.36218)"
+ id="path3782"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 30.061595,110.24748 c -3.028002,-1.91623 -2.918962,-12.207625 0.161986,-15.288574 2.892806,-2.892806 5.380122,-2.029008 6.063557,2.105759 0.787072,4.761775 0.802973,10.540215 0.03451,12.542785 -0.657319,1.71294 -4.021187,2.05687 -6.260057,0.64003 l -1e-6,0 z"
+ transform="translate(0,784.36218)"
+ id="path3784"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 50.118347,74.592462 c -5.270942,-3.20545 -6.839578,-11.64359 -3.245566,-17.458823 3.039395,-4.917846 5.720122,-5.336139 9.002245,-1.404685 3.776278,4.523372 4.477791,9.679447 1.982432,14.570755 -2.972944,5.82745 -4.145768,6.477996 -7.739111,4.292753 z"
+ transform="translate(0,784.36218)"
+ id="path3786"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 77.269166,109.11407 c -1.309679,-0.76282 -1.732674,-2.30682 -1.732674,-6.32456 0,-2.923449 0.270441,-6.020121 0.600979,-6.881491 0.834308,-2.174169 4.068292,-1.961418 5.30478,0.348981 2.014054,3.7633 0.737507,14.00145 -1.732673,13.89637 -0.389257,-0.0166 -1.487442,-0.48424 -2.440412,-1.0393 z"
+ transform="translate(0,784.36218)"
+ id="path3790"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <path
+ d="m 974.24531,563.57578 c 0.19068,-0.58412 0.33807,-2.39704 0.32752,-4.02871 -0.0305,-4.72761 -2.16535,-7.80395 -5.35278,-7.71359 -2.82997,0.0802 -4.22476,1.85117 -5.32345,6.75914 -0.31004,1.38498 -0.36786,1.41644 -1.00404,0.54642 -0.37128,-0.50776 -0.8208,-1.89506 -0.99893,-3.08289 -0.55591,-3.70711 1.47155,-7.48719 5.4718,-10.20182 5.59862,-3.79933 13.97103,1.83612 13.9137,9.36528 -0.0236,3.09812 -3.73691,8.46539 -6.32496,9.14218 -0.90462,0.23656 -1.00597,0.12417 -0.70886,-0.78601 l 0,0 z"
+ id="path3811"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 973.90612,561.26286 c 0.21817,-3.86109 -0.81619,-7.47461 -2.37901,-8.31101 -1.45049,-0.77628 -3.83369,-0.56086 -4.83124,0.43669 -0.50664,0.50664 -1.3056,2.10548 -1.77547,3.55298 -1.09585,3.3759 -1.45679,3.72914 -2.36719,2.31667 -2.17253,-3.37066 -1.18174,-8.3045 2.35621,-11.73323 3.80821,-3.69063 6.35633,-4.18204 10.58332,-2.04103 3.18311,1.61228 5.5569,4.81655 6.06163,8.18231 0.27355,1.8242 0.11235,2.73702 -0.85017,4.81416 -1.44283,3.11366 -4.39733,6.23865 -5.8983,6.23865 -1.04834,0 -1.08674,-0.14752 -0.89978,-3.45619 z"
+ id="path3813"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 961.0831,541.36237 c -0.33003,-3.53422 -1.33157,-5.66019 -3.38893,-7.19369 -2.4962,-1.86061 -5.28857,0.24236 -6.51159,4.90394 l -0.62134,2.36827 -0.78337,-1.82202 c -2.59334,-6.03175 2.24127,-13.61508 8.68004,-13.61508 3.86832,0 6.85183,1.90897 8.66997,5.54739 1.62131,3.24451 1.8741,5.90823 0.71742,7.55961 -0.41352,0.59039 -2.03662,2.06204 -3.60688,3.27033 l -2.85504,2.19689 -0.30028,-3.21564 0,0 z"
+ id="path3815"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 951.68986,559.85808 c 0,-3.90068 -0.11817,-4.43649 -1.32841,-6.0232 -1.64739,-2.15984 -3.30885,-2.63488 -5.52968,-1.58103 -1.75544,0.83301 -3.67834,3.97169 -3.67834,6.00402 0,1.57105 -0.80279,1.30413 -1.42226,-0.47288 -1.64201,-4.71028 0.82795,-10.53973 5.50282,-12.98743 1.35025,-0.70698 1.44409,-0.67017 3.72097,1.45958 2.59818,2.4303 4.37239,3.46667 6.84829,4.00031 l 1.66306,0.35844 -0.30803,4.68928 c -0.33193,5.05322 -0.87831,6.12303 -4.09875,8.0254 l -1.36967,0.80908 0,-4.28157 z"
+ id="path3817"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 1002.8896,554.75634 c 1.2135,-1.18081 3.0452,-2.70588 3.5885,-2.98777 0.2673,-0.13869 0.3404,-0.13033 0.5377,0.0614 0.2215,0.21519 0.2173,0.22773 -0.139,0.41194 -0.202,0.1045 -1.1682,0.8213 -2.147,1.5929 -3.0623,2.41407 -3.7048,2.73578 -1.8402,0.92149 z"
+ id="path3839"
+ style="fill:#808000;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 1001.7609,555.81089 c 0.169,-0.31579 2.3506,-2.35144 3.6035,-3.3624 1.093,-0.88192 1.4098,-1.00296 1.7458,-0.66698 0.2354,0.23537 0.2054,0.26324 -2.3615,2.1931 -2.5867,1.94472 -3.2709,2.36525 -2.9878,1.83628 z m 3.223,-2.29188 c 2.1869,-1.64445 2.0774,-1.54607 1.8265,-1.64237 -0.1263,-0.0485 -0.4054,0.0686 -0.7322,0.30704 -0.774,0.56467 -3.1731,2.65442 -3.1815,2.77119 -0.01,0.13752 0.046,0.0993 2.0872,-1.43586 z"
+ id="path3841"
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 1001.5912,556.03181 c -0.1044,-0.16895 0.8478,-1.16015 2.5352,-2.63894 1.8475,-1.6192 1.7341,-1.53116 2.253,-1.748 0.4162,-0.17387 0.4702,-0.17054 0.7369,0.0453 l 0.2877,0.233 -0.2464,0.27229 c -0.2603,0.28767 -3.4968,2.74402 -4.6222,3.50806 -0.707,0.47998 -0.825,0.52102 -0.9442,0.32824 z m 4.6552,-3.67215 c 0.154,-0.18668 0.1439,-0.19204 -0.1086,-0.0575 -0.2879,0.15343 -0.3589,0.26338 -0.1698,0.26338 0.06,0 0.185,-0.0926 0.2784,-0.20587 l 0,0 z"
+ id="path3843"
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 1002.8311,557.40044 c 0.1343,-0.13117 0.9401,-0.6115 1.7909,-1.06738 0.8507,-0.45589 1.9764,-1.13063 2.5015,-1.49943 0.9671,-0.67921 2.0769,-1.69802 2.0769,-1.90664 0,-0.0627 0.1392,-0.11397 0.3094,-0.11397 1.3509,0 -2.156,2.85903 -5.3392,4.35282 -0.5545,0.26021 -1.1376,0.47311 -1.2958,0.47311 -0.286,0 -0.2863,-10e-4 -0.044,-0.23851 z"
+ id="path3847"
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <path
+ transform="translate(-369.66666,-307.1008)"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ d="m 545.47795,569.43686 c 0.16709,-0.66839 0.34267,-1.29362 0.48523,-1.72439 0.14256,-0.43078 0.25181,-0.66597 0.31085,-0.65272 0.059,0.0132 0.0679,0.27495 0.0363,0.73114 -0.0315,0.45619 -0.1032,1.10576 -0.18053,1.7962 -0.002,0.004 -0.003,0.008 -0.005,0.0117 -0.25593,0.64374 -0.49797,1.24996 -0.68464,1.6675 -0.18667,0.41755 -0.31769,0.6453 -0.37624,0.63065 -0.0585,-0.0147 -0.0446,-0.27169 0.0318,-0.7168 0.0765,-0.4451 0.21524,-1.07716 0.38176,-1.74325 0.16652,-0.66609 0.34152,-1.28909 0.48351,-1.71781 0.142,-0.42873 0.25071,-0.66208 0.30928,-0.64744 0.0586,0.0146 0.067,0.27725 0.0351,0.73349 -0.0319,0.45625 -0.10372,1.10502 -0.18105,1.79339 -4.7e-4,0.004 -9.3e-4,0.008 -0.001,0.0125 -0.25647,0.64565 -0.49876,1.25256 -0.68551,1.66995 -0.18676,0.41739 -0.3177,0.64415 -0.37604,0.62805 -0.0584,-0.0161 -0.0441,-0.27503 0.0328,-0.72222 0.0769,-0.44718 0.21618,-1.08149 0.38327,-1.74988 z"
+ id="path3778-7"
+ inkscape:path-effect="#path-effect3780"
+ inkscape:original-d="m 545.47795,569.43686 c 0.56247,0.14061 1.12494,0.28123 0,0 z" />
+ <path
+ id="path3344"
+ d="m 209.18914,316.00624 c -3.8948,1.47104 -7.87507,2.59585 -9.06207,2.56094 -1.72389,-0.0507 -4.38339,-1.83009 -9.60628,-6.42729 -7.63643,-6.7216 -17.45944,-17.5199 -17.10611,-18.80449 0.12706,-0.46193 1.42619,-0.77671 4.78545,-1.15929 l 4.61105,-0.52524 6.69586,-4.1503 c 3.68273,-2.28268 7.67976,-4.91631 8.8823,-5.85252 1.20254,-0.93621 4.40706,-3.17362 7.12115,-4.972 2.71408,-1.79837 5.5043,-3.73276 6.20046,-4.29862 l 1.26577,-1.02886 0.56932,1.54395 c 3.58457,9.72121 6.64551,22.33702 7.70526,31.75765 l 0.22743,2.02177 -3.90019,3.2806 c -4.32655,3.63923 -6.88538,5.48566 -8.3894,6.0537 z"
+ style="fill:#008000;fill-opacity:0.93984112;stroke:#000000;stroke-width:1.95739317;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ id="path3347"
+ d="m 91.64537,296.70125 1.26556,-9.28074 3.37482,-6.32778 4.21851,-6.74963 5.06223,-5.90593 4.21852,-2.53111 1.68741,-1.26556 3.79666,11.81185 0.42186,1.68741"
+ style="fill:#ff0000;stroke:#000000;stroke-width:1.95739317;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ id="path3350"
+ d="m 250.11676,320.29166 -11.97061,-3.88433 5.72801,-8.44369 6.69808,-4.561 4.78873,-1.74642 8.25083,-2.74891 10.28901,-1.74562 -10.28983,7.24588 -5.50111,5.49947 -3.72142,4.36731 -4.27169,6.01731 z"
+ style="fill:#ff0000;stroke:#000000;stroke-width:1.95739317;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <g
+ id="g4687"
+ transform="matrix(0.99383644,0.11085634,-0.11085634,0.99383644,-333.04542,-11.579789)"
+ inkscape:transform-center-x="-202.66667"
+ inkscape:transform-center-y="-64">
+ <path
+ id="path3814"
+ d="m 589.40196,162.27017 c 2.78402,-5.30853 3.97939,-7.2694 4.41074,-7.23528 0.32543,0.0257 1.22175,0.83297 1.99183,1.79385 0.77007,0.96089 2.5696,2.63931 3.99895,3.72983 3.19366,2.43661 14.13967,12.49605 14.14017,12.9949 1.8e-4,0.19922 0.22005,0.45451 0.48855,0.56729 1.77022,0.74358 11.88728,12.63389 11.51131,13.52894 -0.21552,0.51308 -6.58682,1.33181 -10.64063,1.36737 -5.11249,0.0448 -19.09344,-0.3777 -22.59109,-0.68275 -13.33759,-1.16325 -13.63312,-1.23489 -12.86829,-3.11939 0.43885,-1.08114 3.45699,-9.26144 4.60427,-12.47904 0.62433,-1.75099 2.85372,-6.46057 4.95419,-10.46572 l 0,0 z"
+ style="fill:#ffff00;fill-opacity:0.93984112;stroke:#000000;stroke-width:1.95739317;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ id="path3820"
+ d="m 625.24632,187.71693 c 9.10883,3.36862 9.10883,3.36862 9.10883,3.36862 l -0.38893,-0.16337"
+ style="fill:none;stroke:#000000;stroke-width:2.93608975;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:26;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="12.550781"
+ y="25.687605"
+ id="text3655"><tspan
+ sodipodi:role="line"
+ id="tspan3657"
+ x="12.550781"
+ y="25.687605">Pieces of my spaceship have </tspan><tspan
+ sodipodi:role="line"
+ id="tspan3659"
+ x="12.550781"
+ y="55.687607">fallen in different department </tspan><tspan
+ sodipodi:role="line"
+ id="tspan3661"
+ x="12.550781"
+ y="85.687607">capitals </tspan><tspan
+ sodipodi:role="line"
+ id="tspan3663"
+ x="12.550781"
+ y="115.68761" /><tspan
+ sodipodi:role="line"
+ id="tspan3665"
+ x="12.550781"
+ y="145.68761">Please help me put </tspan><tspan
+ sodipodi:role="line"
+ id="tspan3667"
+ x="12.550781"
+ y="175.68761">my spaceship back </tspan><tspan
+ sodipodi:role="line"
+ id="tspan3669"
+ x="12.550781"
+ y="205.68761">together </tspan></text>
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/playAgain.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/playAgain.svg
new file mode 100755
index 0000000..251eaf5
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/playAgain.svg
@@ -0,0 +1,884 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml-stylesheet href="../../css/lesson.css" type="text/css"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="417.33334"
+ height="341.33334"
+ id="playAgainSVG"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="playAgain.svg">
+ <defs
+ id="defs4">
+ <inkscape:path-effect
+ fuse_tolerance="0"
+ vertical_pattern="false"
+ prop_units="false"
+ tang_offset="0"
+ normal_offset="0"
+ spacing="0"
+ scale_y_rel="false"
+ prop_scale="1"
+ copytype="single_stretched"
+ pattern="m -38,719.36218 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 z"
+ is_visible="true"
+ id="path-effect3780"
+ effect="skeletal" />
+ <inkscape:path-effect
+ fuse_tolerance="0"
+ vertical_pattern="false"
+ prop_units="false"
+ tang_offset="0"
+ normal_offset="0"
+ spacing="0"
+ scale_y_rel="false"
+ prop_scale="1"
+ copytype="single_stretched"
+ pattern="m -38,719.36218 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 z"
+ is_visible="true"
+ id="path-effect3780-0"
+ effect="skeletal" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.75"
+ inkscape:cx="270.00001"
+ inkscape:cy="178.31425"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer2"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-366.33331,-308.64746)">
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2909"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2915"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path2917"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3707"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3711"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:1.18792164;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3715"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.68738866;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3776"
+ d="" />
+ <path
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3778"
+ d="" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3788"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3819"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3821"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3823"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3825"
+ d="" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3827"
+ d="" />
+ <path
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="path3845"
+ d="" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:4;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ id="rect3874"
+ width="413.33334"
+ height="337.33334"
+ x="368.33331"
+ y="310.64746"
+ rx="15.083"
+ ry="15" />
+ </g>
+ <g
+ inkscape:groupmode="layer"
+ id="layer2"
+ inkscape:label="Layer2"
+ transform="translate(3.333344,-1.5466619)">
+ <g
+ id="g3080"
+ transform="matrix(1.2133333,0,0,1.0708387,-844.70703,-450.83406)">
+ <g
+ transform="matrix(0.49496731,0,0,0.49496731,930.18973,120.62394)"
+ id="g3794">
+ <path
+ d="m 53.60865,1035.3693 c 19.78288,-22.2017 22.20694,-25.4265 25.4678,-33.881 3.44722,-8.9377 6.40012,-18.24962 7.52938,-23.74392 0.82455,-4.01172 -0.36261,-5.08744 -5.63913,-5.10977 -1.99045,-0.008 -7.61545,-0.71148 -12.5,-1.56235 -16.50806,-2.87565 -23.91813,-6.30919 -33.99171,-15.75046 -6.08941,-5.70718 -7.43503,-7.50597 -7.19032,-9.61182 0.34346,-2.95569 -1.50714,-2.82651 22.80104,-1.59153 11.8285,0.60095 15.97106,0.42806 22.48438,-0.93836 4.39141,-0.92127 8.66641,-2.28625 9.5,-3.0333 0.83359,-0.74704 3.31562,-1.68728 5.51562,-2.08942 2.2,-0.40213 5.575,-1.60777 7.5,-2.6792 3.44034,-1.91485 3.44887,-1.93539 0.5,-1.2054 -5.17273,1.28051 -26.63042,1.59889 -36.0133,0.53435 -9.20812,-1.04471 -19.63226,-3.39275 -22.72313,-5.11837 -0.95503,-0.5332 -2.32888,-0.96945 -3.05299,-0.96945 -1.43857,0 -9.42912,-5.54027 -11.50725,-7.97859 -0.95343,-1.11868 -1.14843,-3.94422 -0.73666,-10.67412 l 0.56002,-9.15271 -4.54056,-5.31941 c -9.98832,-11.70162 -9.97623,-27.55255 0.0295,-38.68134 2.60206,-2.89412 6.36378,-5.77306 8.93031,-6.83458 l 4.43446,-1.83411 -0.57302,-6.13624 c -1.06496,-11.40449 5.13162,-23.48816 14.51299,-28.30109 l 3.58712,-1.84031 -5.95375,-5.92765 c -4.93512,-4.9135 -8.52008,-7.18312 -20.95375,-13.26571 -8.25,-4.03593 -15.17459,-7.48627 -15.38799,-7.66742 -0.21339,-0.18115 0.18259,-2.36727 0.87997,-4.85804 1.70691,-6.09651 3.20226,-5.96925 18.29995,1.55747 19.96216,9.95182 24.45018,13.11377 31.13538,21.93586 4.86767,6.42359 6.566,7.95536 9.5,8.56828 1.96498,0.41049 4.02269,0.60686 4.57269,0.43639 17.13317,-5.31045 33.409,-5.14223 47.77024,0.49372 4.94708,1.94144 5.21645,1.90161 6.52227,-0.96436 0.61245,-1.34418 5.43513,-7.16668 10.71706,-12.93889 7.18218,-7.84883 10.66081,-10.87865 13.79697,-12.01685 2.3064,-0.83706 9.11158,-3.33956 15.12261,-5.56111 6.01103,-2.22156 11.68966,-4.03919 12.61916,-4.03919 1.11859,0 1.89014,1.09888 2.28193,3.25 0.32555,1.7875 0.8733,4.21044 1.21722,5.38431 0.70713,2.41364 -0.93804,3.18343 -16.9864,7.94807 -8.24402,2.44759 -9.41386,3.13117 -15.04786,8.79297 -3.35991,3.37649 -7.99751,8.92014 -10.30579,12.31923 l -4.19687,6.18016 4.59822,3.7679 c 3.92224,3.21397 12.53592,13.3479 15.89124,18.69593 0.86818,1.38377 2.03676,1.46094 8.86473,0.5854 6.40489,-0.8213 8.72511,-0.72392 12.5,0.5246 8.01058,2.64945 13.40229,2.97743 17.21675,1.04728 5.01589,-2.53808 7.91852,-5.53295 7.91852,-8.17016 0,-1.91743 0.52663,-2.32569 3,-2.32569 l 3,0 0,7.36937 c 0,6.99889 -0.19005,7.61474 -3.78039,12.25 -2.07921,2.68435 -4.3555,6.00563 -5.05843,7.38063 -1.82398,3.56792 -4.05346,6.02517 -8.95417,9.86899 -2.36114,1.85194 -5.40785,5.56725 -6.77047,8.25624 -1.86654,3.68345 -4.04585,5.93033 -8.8376,9.11161 l -6.36013,4.22255 -1.16111,8.29999 c -3.24143,23.17077 -14.49635,42.93763 -31.7551,55.771 -4.30243,3.19923 -8.0341,5.98766 -8.29259,6.19652 -1.61876,1.30794 6.41126,11.58405 19.25766,24.64423 26.293,26.73057 27.51833,28.27367 30.82393,38.81727 3.56149,11.3598 3.62201,12.8116 0.53407,12.8116 -2.0739,0 -2.62572,-0.9231 -4.63288,-7.75 -1.25321,-4.2625 -3.12892,-9.4395 -4.16826,-11.5044 -1.03933,-2.065 -8.08103,-9.94 -15.6482,-17.5 -17.43517,-17.4188 -29.05724,-30.54815 -30.36702,-34.30539 -0.88138,-2.52833 -1.38534,-2.84102 -3.67537,-2.28044 -1.45967,0.3573 -2.80394,1.03003 -2.98727,1.49494 -0.18334,0.46491 -1.18057,0.84529 -2.21608,0.84529 -1.0355,0 -3.3605,0.6395 -5.16666,1.42112 -1.80616,0.78162 -5.98393,1.79412 -9.28393,2.25 l -6,0.82888 -0.64806,5 c -1.05452,8.13597 -10.19844,32.3753 -13.55944,35.9443 -1.06473,1.1306 -3.96423,4.5663 -6.44331,7.6348 -2.47909,3.0685 -5.37183,6.4995 -6.42831,7.6245 -1.05648,1.1249 -3.66664,3.9018 -5.80036,6.1708 -3.09032,3.2864 -4.58088,4.1256 -7.32754,4.1256 l -3.44807,0 4.67803,-5.25 z m 5.47706,-1.25 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 8,-9 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 6,-7 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 85,-12.8776 c 0,-0.2076 -0.7875,-0.9951 -1.75,-1.75 -1.58606,-1.2438 -1.62143,-1.2085 -0.37756,0.3776 1.30637,1.6657 2.12756,2.1955 2.12756,1.3724 z m -13,-11.9674 c 0,-0.1898 -1.0125,-1.2023 -2.25,-2.25 l -2.25,-1.905 1.90499,2.25 c 1.79022,2.1144 2.59501,2.7052 2.59501,1.905 z m -8,-9.00001 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11444 2.59501,2.70524 2.59501,1.90499 z m -41,-13.2644 c 0,-0.21482 -2.1375,-0.3837 -4.75,-0.37528 -2.69011,0.009 -4.21371,0.35593 -3.51336,0.80076 1.18245,0.75103 8.26336,0.38643 8.26336,-0.42548 z m -15.15913,-0.88305 c -0.27085,-0.27086 -4.50835,-1.18259 -9.41666,-2.02608 -16.13633,-2.77299 -23.51094,-5.97517 -33.27596,-14.44895 -7.06554,-6.13127 -6.84736,-7.42208 1.10175,-6.51825 3.4375,0.39085 6.025,0.48259 5.75,0.20387 -0.99658,-1.01006 -14.48194,-2.63618 -15.27608,-1.84205 -0.44842,0.44842 2.5534,3.97257 6.67071,7.83144 9.85626,9.23759 17.5018,12.85148 33.17531,15.68127 8.58267,1.54956 12.04547,1.89328 11.27093,1.11875 z m 23.7264,-0.47481 c 0.532,-0.532 2.7595,-1.3868 4.95,-1.89955 2.1905,-0.51275 3.08273,-0.97137 1.98273,-1.01914 -1.1,-0.0478 -4.7,0.76597 -8,1.80833 -4.87947,1.54126 -5.4304,1.91223 -2.95,1.98641 1.6775,0.0502 3.48527,-0.34405 4.01727,-0.87605 z m -1.06727,-3.56001 c 3.85,-1.06802 7.225,-2.19571 7.5,-2.50598 0.275,-0.31026 2.3,-1.09477 4.5,-1.74336 5.05158,-1.48926 15.57308,-8.30539 21.71998,-14.07082 10.15582,-9.52554 18.78406,-25.08183 22.17104,-39.97322 2.25857,-9.93017 2.17044,-11.34285 -0.64102,-10.27621 -1.2375,0.4695 -5.625,1.02086 -9.75,1.22525 -7.05688,0.34966 -7.51817,0.24412 -7.80748,-1.7863 -0.33071,-2.32087 0.30249,-2.55846 10.30748,-3.8677 11.1663,-1.4612 23.27502,-8.62225 26.61935,-15.74257 1.23176,-2.6225 3.84631,-5.98973 5.81011,-7.48272 4.73441,-3.59937 9.07054,-8.06924 9.07054,-9.35029 0,-1.14449 5.05979,-8.20389 6.26146,-8.73595 0.4188,-0.18544 1.19818,-1.15318 1.73195,-2.15053 0.8951,-1.67251 0.64174,-1.65381 -3.26146,0.24076 -7.22492,3.5069 -10.3032,3.77646 -18.61575,1.63013 -9.07215,-2.34246 -19.00256,-2.1397 -21.58295,0.44068 -0.92186,0.92186 -2.14171,1.67611 -2.71077,1.67611 -2.54552,0 -8.99433,6.52871 -10.95829,11.09406 -1.16076,2.69827 -2.46826,4.90594 -2.90555,4.90594 -1.95933,0 -3.95864,-1.33678 -3.95864,-2.64683 0,-3.08568 4.35596,-10.05283 8.7413,-13.98128 l 4.60821,-4.12811 -4.56124,-6.37189 c -5.99722,-8.37789 -13.41368,-15.23903 -16.69909,-15.44873 -3.96961,-0.25337 -4.08918,-0.31285 -4.08918,-2.03394 0,-1.26833 -0.37392,-1.14902 -1.75876,0.56119 -3.16363,3.90691 -6.71424,0.67043 -4.27159,-3.89369 0.85843,-1.60399 0.0269,-2.12345 -7.25,-4.52893 -6.21814,-2.0555 -10.28943,-2.73355 -16.71965,-2.78455 -7.5672,-0.06 -19,1.69411 -19,2.91514 0,0.25239 1.31647,2.12001 2.92548,4.15026 4.36394,5.50639 6.47105,13.04213 5.76399,20.6139 l -0.58664,6.28221 5.37473,1.20281 c 21.33616,4.77483 28.69937,31.92058 12.95469,47.75979 -10.80462,10.86949 -26.4913,11.06535 -37.48583,0.46803 l -4.92782,-4.74978 -3.2593,3.39483 c -5.79484,6.0358 -10.13838,7.70973 -20.0093,7.71121 -8.60158,10e-4 -8.75,0.0426 -8.75,2.43384 0,1.33789 -0.52005,3.87072 -1.15568,5.62851 -1.08586,3.00291 -0.94993,3.38302 2.25,6.29169 1.87313,1.70263 3.98611,3.10888 4.69552,3.12501 0.70941,0.0161 2.95941,0.87562 5,1.91 5.35714,2.71554 26.10725,6.12131 37.21074,6.10748 6.7425,-0.008 12.40095,-0.73394 19.49709,-2.5 12.81724,-3.18989 15.50356,-3.23117 15.49859,-0.23817 -0.005,3.2606 -3.59424,8.64665 -6.49672,9.75017 -1.37475,0.52268 -2.49954,1.41147 -2.49954,1.97508 0,0.56361 -0.48214,1.02475 -1.07143,1.02475 -0.58928,0 -1.74575,0.67432 -2.56993,1.4985 -0.82417,0.82417 -2.70453,1.76639 -4.17856,2.09382 -1.47404,0.32743 -4.04917,1.20489 -5.7225,1.94992 -7.22305,3.21595 -18.24045,4.55548 -34.98967,4.25415 l -16.47466,-0.29639 3.75338,3.2447 c 8.53728,7.38027 17.41711,11.11298 32.67758,13.73628 4.90831,0.84375 9.17851,1.7884 9.48934,2.09923 1.09734,1.09735 13.67539,-0.1903 20.58645,-2.10749 z m 40.5,-82.47272 c 0,-1.1 -0.45,-2 -1,-2 -0.55,0 -0.99978,-1.0125 -0.99951,-2.25 4.9e-4,-2.23828 6.86797,-9.01585 11.80351,-11.64897 3.22732,-1.72179 11.25861,-4.07728 13.946,-4.09021 3.59163,-0.0173 2.91267,4.08892 -1.25,7.55971 -1.925,1.60504 -3.5,3.40484 -3.5,3.99955 0,1.65254 -3.95602,4.90826 -9.49204,7.81174 -6.12107,3.21032 -9.50796,3.43052 -9.50796,0.61818 z m 9,-3.36173 c 4.30061,-2.42779 8,-5.65282 8,-6.97419 0,-0.54301 1.6875,-2.48922 3.75,-4.32491 2.0625,-1.83568 3.525,-3.33309 3.25,-3.32756 -1.50707,0.0303 -10.20077,3.05406 -12.64753,4.39899 -3.66433,2.0142 -12.18544,9.58314 -10.7927,9.5867 0.58287,0.001 3.43212,-2.0223 6.33165,-4.4973 5.24143,-4.474 9.10858,-5.78543 9.10858,-3.08889 0,1.84596 -4.51449,5.57987 -9.77988,8.08889 -2.30845,1.1 -4.20234,2.32338 -4.20865,2.71862 -0.0143,0.8945 2.43529,-0.01 6.98853,-2.58035 z m -35,84.31604 c 1.09546,-0.74131 0.69092,-0.83408 -1.5,-0.34401 -3.67693,0.82247 -4.47511,1.39483 -1.91667,1.37439 1.05417,-0.008 2.59167,-0.47209 3.41667,-1.03038 z m 6.427,-2.47578 c 2.91505,-2.20537 1.48811,-2.46248 -1.927,-0.34722 -1.65,1.02199 -2.325,1.84622 -1.5,1.83162 0.825,-0.0146 2.36715,-0.68258 3.427,-1.4844 z m 7.14043,-5.58763 c 0.37335,-0.6041 -0.50159,-0.32492 -1.94431,0.62038 -1.44271,0.94531 -2.62312,1.90782 -2.62312,2.13891 0,0.72338 3.85397,-1.6049 4.56743,-2.75929 z m 3.43257,-2.3909 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 6,-5 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -65.02348,-3.06139 c 4.11208,-0.85786 8.83708,-2.16527 10.5,-2.90536 1.66291,-0.74008 4.22952,-1.6135 5.70356,-1.94093 1.47404,-0.32743 3.28207,-1.19733 4.01785,-1.93311 0.73578,-0.73578 2.00475,-1.59958 2.81993,-1.91955 1.26954,-0.49832 1.25981,-0.59309 -0.0679,-0.66071 -0.8525,-0.0434 -2.0117,0.38275 -2.57599,0.94704 -1.37761,1.37761 -13.6602,5.81918 -19.87401,7.18674 -2.75,0.60523 -10.175,1.4011 -16.5,1.7686 l -11.5,0.66819 10,0.17442 c 5.89347,0.1028 13.07026,-0.46609 17.47652,-1.38533 z m 70.52348,-3.43861 c 0.99549,-1.1 1.58498,-2 1.30998,-2 -0.275,0 -1.31449,0.9 -2.30998,2 -0.99549,1.1 -1.58498,2 -1.30998,2 0.275,0 1.31449,-0.9 2.30998,-2 z m -39.74244,-12.00913 c 1.24166,-1.81999 2.07092,-3.49572 1.84281,-3.72384 -0.22812,-0.22811 -5.13023,0.74348 -10.89357,2.15911 -8.13994,1.99938 -13.01511,2.57386 -21.84222,2.57386 -12.97438,0 -33.27435,-3.17908 -39.07474,-6.11931 -2.04059,-1.03438 -4.29059,-1.85699 -5,-1.82803 -0.70941,0.029 0.84976,1.11449 3.46483,2.41228 11.06002,5.4888 45.285,8.38592 59.24533,5.01506 3.3,-0.79682 6.7875,-1.45579 7.75,-1.46438 2.46056,-0.022 2.17728,2.43675 -0.5,4.33963 l -2.25,1.59919 2.5,-0.82725 c 1.375,-0.45498 3.5159,-2.31633 4.75756,-4.13632 z m 48.7905,-2.0838 c 0.87968,-1.70111 1.42188,-3.27046 1.2049,-3.48744 -0.21698,-0.21698 -1.14288,1.17483 -2.05756,3.09293 -2.05658,4.3127 -1.34401,4.64239 0.85266,0.39451 z m -128.0536,-7.9132 c -0.99854,-1.10337 -2.04794,-1.77372 -2.33199,-1.48967 -0.28406,0.28406 0.35068,1.1725 1.41054,1.97433 2.70408,2.04576 3.04782,1.86496 0.92145,-0.48466 z m -1.82881,-15.83491 c 0.54476,-4.29796 0.58312,-4.33487 3.86431,-3.71932 1.87409,0.35158 3.58779,0.17886 3.944,-0.3975 0.36318,-0.58764 0.011,-0.78172 -0.83176,-0.45833 -1.53986,0.5909 -6.76761,-1.7051 -10.1422,-4.4544 -1.9801,-1.6132 -1.98121,-1.60721 -0.11164,0.60221 1.66468,1.96729 1.82292,3.38868 1.33592,12 -0.43762,7.73827 -0.35047,8.83317 0.41936,5.26838 0.53449,-2.475 1.21939,-6.45347 1.52201,-8.84104 z m 135.93852,5.11187 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m 1,-4 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72188 0.25335,-1.58438 -0.0789,-1.91667 z m -78.41667,-2.95394 c -0.72187,-0.28887 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28494 0.60416,-0.60416 z m 79.46844,-3.58592 c -0.27393,-0.67703 -0.48137,0.11903 -0.46099,1.76903 0.0204,1.65 0.2445,2.20394 0.49804,1.23097 0.25354,-0.97297 0.23687,-2.32297 -0.0371,-3 z m -124.92497,2.57604 c -0.97296,-0.25354 -2.32297,-0.23687 -3,0.0371 -0.67703,0.27393 0.11903,0.48137 1.76903,0.46099 1.65,-0.0204 2.20394,-0.2445 1.23097,-0.49804 z m 41.5128,0.0286 c -0.69092,-0.27855 -1.07389,-0.80553 -0.85104,-1.17105 0.22285,-0.36552 -1.20295,-0.75058 -3.16844,-0.85567 -1.9655,-0.1051 -4.95753,-1.20361 -6.64896,-2.44115 -2.34922,-1.71881 -2.72116,-1.81335 -1.57533,-0.40044 1.81731,2.24089 8.73947,5.51042 11.5,5.43176 1.1,-0.0313 1.4347,-0.28489 0.74377,-0.56345 z m -32.38703,-2.26255 c 2.07738,-1.0598 4.4142,-2.7473 5.19293,-3.75 1.34843,-1.73625 1.32057,-1.74235 -0.58488,-0.12808 -1.10041,0.93226 -4.01766,2.60988 -6.48277,3.72804 -2.46511,1.11817 -3.90159,2.04291 -3.19218,2.05499 0.70941,0.0121 2.98952,-0.84515 5.0669,-1.90495 z m 47.01576,0.49285 c 1.52524,-0.78874 3.40764,-2.25124 4.1831,-3.25 1.33163,-1.71509 1.29982,-1.7257 -0.57283,-0.1911 -1.09052,0.89366 -3.33277,2.33815 -4.98277,3.20996 -1.65,0.87182 -2.64015,1.60314 -2.20034,1.62516 0.43982,0.022 2.04759,-0.60529 3.57284,-1.39402 z m -3.36392,-2.43092 c 7.61004,-3.45714 13.65809,-12.5947 13.65809,-20.63499 0,-11.12314 -11.04986,-22.7 -21.66667,-22.7 -10.70226,0 -21.66666,11.57813 -21.66666,22.87946 0,4.64065 3.02363,11.97613 6.07456,14.73719 1.78745,1.61762 1.83913,1.5186 1.37172,-2.62829 -1.45227,-12.88452 7.92692,-22.30909 15.08152,-15.15449 4.84657,4.84656 5.99347,17.1236 2.14795,22.99261 -1.93035,2.94608 -0.65228,3.07608 4.99949,0.50854 z m -53.08133,-2.28112 c 3.70718,-6.27576 1.47296,-18.7986 -3.64361,-20.42254 -4.73397,-1.50251 -8.98587,3.85239 -9.06867,11.42119 -0.0712,6.50478 0.82438,8.55477 4.54657,10.40756 4.71129,2.34514 6.08999,2.10771 8.16571,-1.40621 z m 8.76107,0.52566 c 1.47857,-0.7519 4.15313,-3.11185 5.94345,-5.24433 3.16416,-3.76887 3.25672,-4.14456 3.31169,-13.44187 l 0.0566,-9.56463 -3.42512,-0.64252 c -6.57739,-1.23384 -11.12219,-3.74493 -15.41056,-8.51464 l -4.3202,-4.8051 -3.93064,1.7598 c -7.58534,3.39606 -13.58015,12.55734 -13.58015,20.75322 0,4.42188 3.08834,12.18072 5.7167,14.36206 1.23314,1.02342 1.44997,0.46906 1.44997,-3.70719 0,-9.99193 6.09864,-17.05981 12.75,-14.7763 5.96164,2.04672 9.18113,14.88436 5.77636,23.03311 -1.44844,3.46661 -1.43562,3.51518 0.75,2.84119 1.223,-0.37713 3.43338,-1.30089 4.91195,-2.0528 z m 37.28108,-0.95627 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 66.2806,0.88741 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z m -84.75,-1.68823 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 37,-1.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m -83,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 41.40581,-3.29696 c 1.26469,0.48531 1.32727,0.18279 0.38844,-1.87771 -0.61552,-1.35092 -1.24526,-2.33009 -1.39942,-2.17593 -0.15416,0.15416 -1.48307,2.06857 -2.95312,4.25423 l -2.67282,3.97393 2.56468,-2.37651 c 1.43852,-1.33299 3.22665,-2.12249 4.07224,-1.79801 z m 103.59419,2.7059 c 0,-0.53273 -0.675,-0.70959 -1.5,-0.39301 -0.825,0.31659 -1.5,0.75246 -1.5,0.96862 0,0.21615 0.675,0.39301 1.5,0.39301 0.825,0 1.5,-0.43588 1.5,-0.96862 z m -59.19313,-4.55784 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z m -46.2027,-6.20271 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 48,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 45,-5 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.079,-1.91667 z m 50,0 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58437 -0.0789,-1.91667 z m -96,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58437 -0.0789,-1.91667 z m 95,-5 c -0.3323,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60416,0.60417 0.28887,-0.72187 0.25335,-1.58438 -0.0789,-1.91667 z m -94,-1 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.0789,-1.91667 z m 49.01374,-4.98626 c -0.12014,-0.12014 -1.54582,0.178 -3.16817,0.66254 -1.62236,0.48454 -2.16224,0.91966 -1.19974,0.96694 0.9625,0.0473 1.76595,0.87345 1.78544,1.83595 0.0268,1.32558 0.37079,1.14405 1.41817,-0.74849 0.76051,-1.37418 1.28444,-2.5968 1.1643,-2.71694 z m 42.50618,0.44876 c -0.98762,-0.98026 -1.10248,-0.8654 -0.5598,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30789,-0.30789 6.4e-4,-1.11479 -0.68278,-1.79313 z M 65.08571,861.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -85,-2.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 38.4694,-2.07674 c 2.16291,-4.55801 2.17032,-11.2729 0.0174,-15.80976 -5.23294,-11.0276 -15.07762,-0.45826 -12.08634,12.97601 0.47039,2.1126 1.70159,3.59433 3.89371,4.68604 4.85109,2.41592 6.30623,2.08622 8.17518,-1.85229 z m 6.58891,-0.87068 c 2.30641,-2.50217 6.01686,-5.17968 8.48316,-6.12157 3.50845,-1.33988 4.61401,-2.37208 5.53737,-5.16987 3.7517,-11.36776 -3.1423,-24.22022 -15.17695,-28.29436 -4.64464,-1.57236 -5.7447,-1.61747 -9.7859,-0.40124 -14.93589,4.49504 -21.66079,20.75015 -13.81981,33.40461 l 2.18716,3.52985 0.74099,-5.89906 c 1.49666,-11.91498 8.85142,-17.25247 15.12639,-10.9775 4.48246,4.48246 5.8535,13.25622 3.22323,20.62656 -0.73605,2.0625 -1.17556,3.75 -0.9767,3.75 0.19886,0 2.20634,-2.00134 4.46106,-4.44742 z m -19.14164,3.16445 c -0.22917,-0.15563 -1.31667,-0.94313 -2.41667,-1.75 -1.85,-1.35701 -1.89707,-1.33579 -0.62755,0.28297 0.75484,0.9625 1.84234,1.75 2.41667,1.75 0.57432,0 0.85672,-0.12734 0.62755,-0.28297 z m 24.08333,-3.21703 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.94528,-0.0659 c -1.51303,-1.82309 -6.92706,-4.78561 -7.57027,-4.1424 -0.24152,0.24152 0.91037,0.99812 2.55977,1.68132 1.6494,0.68321 3.51893,1.86878 4.15451,2.6346 0.63558,0.76583 1.3806,1.39242 1.6556,1.39242 0.275,0 -0.0848,-0.70467 -0.79961,-1.56594 z m -75.94528,-0.9341 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01988,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 17,0.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 35.91667,-3.2579 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m -46,-1 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35467 2.91667,-1.55517 z m 5.95162,-1.75427 c -1.01049,-2.21779 -1.20856,-2.27175 -2.75296,-0.75 -1.54948,1.52676 -1.49021,1.68325 0.86027,2.27141 1.38842,0.34743 2.62726,0.68493 2.75297,0.75 0.1257,0.0651 -0.26142,-0.95706 -0.86028,-2.27141 z m 49.04838,0.74819 c 0.22917,-0.19715 -0.55833,-0.35846 -1.75,-0.35846 -1.38524,0 -2.17763,-0.63115 -2.19707,-1.75 -0.0265,-1.52656 -0.17522,-1.49464 -1.16454,0.25 -0.62377,1.1 -1.62259,2.32475 -2.21959,2.72166 -0.59701,0.39691 0.71453,0.44572 2.91453,0.10846 2.2,-0.33726 4.1875,-0.77451 4.41667,-0.97166 z m 72.08333,-1.88414 c 0,-1.39308 -3.70207,-0.18103 -4.79566,1.57008 -1.24992,2.00144 -1.21295,2.01141 1.75946,0.47432 1.66991,-0.86354 3.0362,-1.78352 3.0362,-2.0444 z m 29.1875,0.84257 c -0.72188,-0.28888 -1.58438,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -19.9375,-2.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -84.64583,-3.06689 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 122.39583,-2.04448 c 0,-0.85783 -0.12734,-1.37218 -0.28297,-1.14302 -0.15563,0.22917 -0.89428,1.21447 -1.64144,2.18956 -1.18269,1.54348 -1.14607,1.69139 0.28297,1.14301 0.90279,-0.34643 1.64144,-1.33173 1.64144,-2.18955 z M 82.68988,837.89013 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 65.39583,1.38416 c 0,-0.18976 -1.0125,-1.20226 -2.25,-2.25 l -2.25,-1.90499 1.90499,2.25 c 1.79022,2.11445 2.59501,2.70524 2.59501,1.90499 z m -66.39583,-7.38416 c -0.33229,-0.33229 -0.56864,0.25834 -0.52522,1.3125 0.048,1.16495 0.28494,1.4019 0.60417,0.60417 0.28887,-0.72187 0.25334,-1.58438 -0.079,-1.91667 z m 60.39583,0.35161 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z M 79.2098,826.35263 c -0.98761,-0.98026 -1.10248,-0.8654 -0.55979,0.5598 0.37553,0.98622 0.93469,1.54122 1.24258,1.23333 0.30788,-0.30789 6.3e-4,-1.11479 -0.68279,-1.79313 z m 56.87591,0.88911 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58606,-1.24387 -1.62143,-1.2085 -0.37756,0.37756 1.30637,1.66575 2.12756,2.19548 2.12756,1.37244 z m -97,-4.12244 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 39,1.12244 c 0,-0.20765 -0.7875,-0.99515 -1.75,-1.75 -1.58605,-1.24387 -1.62142,-1.2085 -0.37755,0.37756 1.30637,1.66575 2.12755,2.19548 2.12755,1.37244 z m 53.22334,-1.87639 c -0.26254,-1.00396 -0.54753,-1.69503 -0.63331,-1.53571 -0.0858,0.15931 -0.6787,0.98073 -1.3176,1.82537 -0.93948,1.24202 -0.81836,1.53572 0.63331,1.53572 1.24538,0 1.6488,-0.55888 1.3176,-1.82538 z M 43.08571,819.1193 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68468,0.825 -1.01989,1.5 -0.74488,1.5 0.275,0 1.0602,-0.675 1.74488,-1.5 z m 29.75848,-0.53051 c -0.94115,-1.51852 -0.96737,-2.21193 -0.10397,-2.75 0.63498,-0.39572 -0.80847,-0.71949 -3.20766,-0.71949 l -4.36218,0 3.39287,1.74065 c 1.86608,0.95735 3.67359,2.19485 4.01668,2.75 0.3431,0.55514 0.82607,1.00935 1.07327,1.00935 0.24721,0 -0.11685,-0.91373 -0.80901,-2.03051 z m 52.17485,-0.31215 c -0.23833,-0.20679 -1.78333,-0.65233 -3.43333,-0.99008 -2.73596,-0.56005 -2.80197,-0.51498 -0.75,0.51213 1.2375,0.61943 2.25,1.59747 2.25,2.17342 0,0.65288 0.44557,0.60162 1.18333,-0.13614 0.65084,-0.65084 0.98834,-1.35253 0.75,-1.55933 z m 9.94836,-7.40734 c 2.30606,-3.4375 3.82136,-6.25 3.36733,-6.25 -1.81925,0 -11.24902,12.98428 -11.24902,15.48929 0,1.26984 3.89338,-3.29416 7.88169,-9.23929 z m -84.96502,4.11454 c 1.37233,-1.20065 -1.88254,-0.0856 -3.47554,1.19063 -1.8303,1.46637 -1.79839,1.48719 0.55887,0.36454 1.375,-0.65484 2.6875,-1.35466 2.91667,-1.55517 z m 2.58333,-1.36454 c -0.33991,-0.55 -0.81647,-1 -1.05901,-1 -0.24254,0 -0.44099,0.45 -0.44099,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m 6.82946,-1.58385 c -0.33428,-0.87111 -0.88789,-1.20861 -1.23025,-0.75 -0.34236,0.45862 -1.02974,1.17135 -1.52751,1.58385 -0.49776,0.4125 0.0558,0.75 1.23025,0.75 1.53743,0 1.96511,-0.44346 1.52751,-1.58385 z m 20.85804,0.90074 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91666,0.0789 -0.33229,0.33229 0.25833,0.56864 1.3125,0.52522 1.16494,-0.048 1.4019,-0.28495 0.60416,-0.60417 z m 29,0 c -0.72187,-0.28888 -1.58437,-0.25335 -1.91667,0.0789 -0.33229,0.33229 0.25834,0.56864 1.3125,0.52522 1.16495,-0.048 1.4019,-0.28495 0.60417,-0.60417 z m -22.9375,-0.97917 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m 18,0 c -0.6875,-0.27741 -1.8125,-0.27741 -2.5,0 -0.6875,0.27741 -0.125,0.50438 1.25,0.50438 1.375,0 1.9375,-0.22697 1.25,-0.50438 z m -8.5,-1.02705 c -0.9625,-0.25152 -2.5375,-0.25152 -3.5,0 -0.9625,0.25153 -0.175,0.45733 1.75,0.45733 1.925,0 2.7125,-0.2058 1.75,-0.45733 z M 53.3824,808.21186 c -0.98818,-1.3241 -1.94149,-2.01468 -2.11847,-1.53464 -0.36611,0.99302 1.91319,3.8465 3.11847,3.90404 0.43818,0.0209 -0.0118,-1.04531 -1,-2.3694 z m -3.29669,-3.66948 c 0,-1.50044 -5.57099,-6.92308 -7.11248,-6.92308 -0.69649,0 0.5064,1.73277 2.67307,3.8506 4.69729,4.5914 4.43941,4.41292 4.43941,3.07248 z m 92,-3.42308 c 1.29175,-1.375 2.12363,-2.5 1.84863,-2.5 -0.275,0 -1.55688,1.125 -2.84863,2.5 -1.29175,1.375 -2.12363,2.5 -1.84863,2.5 0.275,0 1.55688,-1.125 2.84863,-2.5 z m 6.04469,-1.70523 c 2.56704,-3.19434 2.82393,-3.81616 1.06867,-2.58673 -1.89119,1.32465 -5.69179,6.79196 -4.72142,6.79196 0.15033,0 1.79407,-1.89235 3.65275,-4.20523 z m -0.0447,-8.71959 c 0,-0.275 -2.25,1.71617 -5,4.42482 -2.75,2.70865 -5,5.14982 -5,5.42482 0,0.275 2.25,-1.71617 5,-4.42482 2.75,-2.70865 5,-5.14982 5,-5.42482 z m 1,3.42482 c 0.68469,-0.825 1.01989,-1.5 0.74489,-1.5 -0.275,0 -1.0602,0.675 -1.74489,1.5 -0.68469,0.825 -1.01989,1.5 -0.74489,1.5 0.275,0 1.0602,-0.675 1.74489,-1.5 z m 21.91908,-7.85167 c 2.4305,-0.72671 4.0055,-1.56089 3.5,-1.85373 -0.50549,-0.29284 -2.71908,0.27521 -4.91908,1.26232 -4.84957,2.17594 -4.44469,2.34468 1.41908,0.59141 z m 6.88779,-1.17479 c -0.30789,-0.30789 -0.86705,0.24711 -1.24258,1.23333 -0.54268,1.4252 -0.42782,1.54006 0.5598,0.5598 0.68342,-0.67834 0.99067,-1.48524 0.68278,-1.79313 z M 17.08571,783.6193 c -1.925,-1.05389 -3.95,-1.91617 -4.5,-1.91617 -0.55,0 0.575,0.86228 2.5,1.91617 1.925,1.05389 3.95,1.91617 4.5,1.91617 0.55,0 -0.575,-0.86228 -2.5,-1.91617 z m 160,-2 c 0,-0.55 -0.7875,-0.99311 -1.75,-0.98469 -1.49555,0.0131 -1.5319,0.15626 -0.25,0.98469 1.88721,1.21961 2,1.21961 2,0 z"
+ id="path2905"
+ style="fill:#000000" />
+ <path
+ d="m 72.6,181.20757 c -16.765609,-3.86833 -22.376319,-6.32293 -32,-13.9995 l -2,-1.59535 13.2,-0.0317 c 17.959636,-0.043 26.293525,-1.0427 36.676385,-4.39926 12.401975,-4.00929 20.661075,-10.22837 22.672535,-17.07236 1.39926,-4.76097 -0.60247,-5.05117 -14.284918,-2.07088 C 80.913403,145.51284 69.067454,145.46531 50.6,141.85286 39.54215,139.68982 28.750784,134.8087 27.432732,131.37391 c -0.409763,-1.06782 0.94297,-9.55504 1.67366,-10.50077 0.129162,-0.16717 4.118063,-0.56369 8.864224,-0.88115 9.677258,-0.64731 12.721718,-1.79467 18.59718,-7.00868 l 3.565638,-3.16423 4.911016,4.16615 c 6.374081,5.4073 11.045891,7.19552 18.75555,7.17903 10.247136,-0.0219 18.94097,-5.4255 24.01507,-14.92636 2.33003,-4.3628 2.74898,-6.0141 3.03751,-11.972478 0.24409,-5.040832 -0.0244,-7.992693 -0.99183,-10.905433 C 106.83021,74.235948 98.683943,66.74733 89.719703,64.844988 L 85,63.8434 84.966254,55.710271 C 84.929438,46.837023 83.908403,43.511262 79.05568,36.458071 76.206234,32.316543 75.915993,32.561487 85.4,31.103895 c 9.620682,-1.478597 19.97708,-0.291557 29.26619,3.354462 4.00483,1.571915 4.0652,1.646353 4,4.932693 -0.0764,3.849526 1.76499,4.910844 4.39333,2.532225 0.84726,-0.766762 1.54048,-1.021054 1.54048,-0.565095 0,0.45596 1.6637,1.247942 3.6971,1.759959 4.38748,1.10478 11.00212,7.029509 17.23538,15.437707 l 4.03312,5.440379 -4.6828,5.026303 c -4.55714,4.891416 -8.2828,11.01514 -8.2828,13.614092 0,1.528769 2.86706,3.239468 4.42637,2.641103 0.60573,-0.232443 1.86318,-1.915954 2.79432,-3.741133 2.17353,-4.260467 7.69681,-10.272278 10.77931,-11.732734 1.32,-0.625402 3.4424,-1.697018 4.71645,-2.381368 2.96143,-1.590728 11.65807,-1.536216 19.53585,0.122452 7.69091,1.619321 10.4686,1.555228 15.93996,-0.367797 5.65346,-1.987032 5.64225,-1.987649 3.63541,0.2 -0.90817,0.99 -3.01076,3.96 -4.67241,6.6 -1.66166,2.64 -5.30895,6.908849 -8.1051,9.486333 -2.79614,2.577483 -5.99227,6.236344 -7.1025,8.130802 -4.94788,8.442912 -15.3818,14.634562 -28.34766,16.821932 -7.93582,1.33879 -10.1786,2.49921 -9.29263,4.80802 0.46879,1.22165 1.5792,1.32779 10.18353,0.97342 l 9.65736,-0.39773 -0.5479,3.65369 c -1.59381,10.62824 -7.28652,24.58268 -14.24705,34.92353 -11.30309,16.79232 -34.07569,29.48213 -55.75331,31.06798 -4.998646,0.36568 -7.935952,-0.008 -17.6,-2.23755 z m 81.50924,-82.494134 c 3.52664,-1.764307 6.56239,-3.962996 7.90749,-5.727124 1.2008,-1.574879 3.53327,-4.37647 5.18327,-6.225757 1.93865,-2.172795 3,-4.147985 3,-5.583022 0,-2.220043 -0.002,-2.220533 -4.38306,-1.705537 -8.74931,1.028309 -19.06055,6.827181 -22.74752,12.792833 l -1.71519,2.775229 1.70366,3.268542 c 2.14696,4.11903 3.52613,4.16955 11.05135,0.404836 l 0,0 z"
+ transform="translate(0,784.36218)"
+ id="path2907"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 160.6,87.334076 c 0,-0.534851 -1.1468,-0.981516 -2.6,-1.012667 -2.30544,-0.04942 -2.02164,-0.279224 2.50495,-2.028386 2.80772,-1.084959 5.23233,-1.845272 5.38801,-1.689584 0.15569,0.155688 -0.97154,1.499081 -2.50494,2.98532 C 161.85461,87.074997 160.6,87.86039 160.6,87.334076 z"
+ transform="translate(0,784.36218)"
+ id="path2913"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 24.692801,119.04257 c -0.05104,-2.05401 -0.313955,-4.31089 -0.584255,-5.01528 -0.431011,-1.12319 -0.185552,-1.10664 1.99579,0.13457 1.631194,0.92818 2.07587,1.50427 1.292,1.67384 -0.657385,0.1422 -1.361474,1.0422 -1.564643,2 -0.203169,0.95779 -0.521653,2.46144 -0.707744,3.34144 -0.186091,0.88 -0.380107,-0.0805 -0.431148,-2.13457 z"
+ transform="translate(0,784.36218)"
+ id="path3703"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 104.6,146.52914 c 0,-0.55196 -0.79531,-1.29776 -1.76736,-1.65735 -1.56978,-0.5807 -1.42649,-0.71774 1.28174,-1.2258 3.83551,-0.71955 4.4795,-0.10717 2.24118,2.13115 -1.00812,1.00812 -1.75556,1.32829 -1.75556,0.752 z"
+ transform="translate(0,784.36218)"
+ id="path3709"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 76.851058,112.03382 c -3.393188,-2.09142 -4.25448,-3.92327 -4.233488,-9.00408 0.03274,-7.923733 4.577488,-13.887568 8.633406,-11.329161 3.986638,2.514706 5.541626,13.083911 2.747781,18.676561 -1.667169,3.3373 -3.668438,3.80115 -7.147699,1.65668 l 0,0 z"
+ transform="translate(0,784.36218)"
+ id="path3719"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 31.011129,112.18685 c -3.337597,-1.68708 -4.784967,-4.28598 -4.794874,-8.60971 -0.01706,-7.444764 3.322321,-12.761965 7.700427,-12.261175 5.345895,0.611491 7.922362,14.073845 3.761169,19.652565 -2.071377,2.777 -3.181718,2.97991 -6.666722,1.21832 z"
+ transform="translate(0,784.36218)"
+ id="path3721"
+ style="fill:#00d37c;fill-opacity:1;stroke:#000000;stroke-width:2.4000001;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="M 49.694395,74.66073 C 44.47115,71.825511 44.018691,61.3525 48.893397,56.120117 c 1.243238,-1.334459 2.71535,-2.426289 3.27136,-2.426289 3.274952,0 7.59925,10.034368 6.191417,14.366947 -2.961401,9.11366 -3.406311,9.452665 -8.661779,6.599955 z"
+ transform="translate(0,784.36218)"
+ id="path3747"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 30.863598,109.87939 c -4.598088,-3.22062 -2.443473,-16.412835 2.680623,-16.412835 3.343974,0 5.248203,11.238065 2.708365,15.983795 -1.423064,2.65902 -2.125412,2.71494 -5.388988,0.42904 l 0,0 z"
+ transform="translate(0,784.36218)"
+ id="path3749"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="M 53.409091,253.22727 C 175,254.36364 176.13636,254.36364 176.13636,254.36364"
+ transform="translate(0,784.36218)"
+ id="path3751"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 101.91757,251.70568 c -21.718752,-0.17272 -39.488638,-0.58449 -39.488638,-0.91506 0,-0.33057 3.818082,-4.96825 8.484628,-10.30595 4.666545,-5.33771 9.973982,-12.85892 11.794303,-16.71379 3.448266,-7.30236 8.521552,-22.38453 9.820557,-29.19514 0.752563,-3.94565 0.76643,-3.95339 12.3156,-6.87496 6.3592,-1.60867 12.35971,-3.28795 13.33446,-3.73173 1.29391,-0.58909 2.73131,0.66046 5.32536,4.62941 1.9542,2.98995 11.57847,13.87378 21.38726,24.18628 9.8088,10.3125 18.96093,20.28409 20.33807,22.15909 2.01779,2.74727 7.42703,15.23542 7.42703,17.14657 0,0.25689 -7.03125,0.34607 -15.625,0.19819 -8.59375,-0.14789 -33.39488,-0.4102 -55.11363,-0.58291 l 0,0 z"
+ transform="translate(0,784.36218)"
+ id="path3753"
+ style="fill:#7bd37c;fill-opacity:1;stroke:#7bd37c;stroke-width:3.409091;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 51.774116,254.22272 c 0.816832,-1.01161 5.399709,-6.3219 10.184171,-11.80065 4.784463,-5.47875 10.255577,-12.2121 12.158031,-14.963 5.284789,-7.64167 14.376394,-33.83808 12.993969,-37.44062 -0.338967,-0.88334 -2.48378,-1.73514 -5.328004,-2.116 C 60.981864,185.11713 50.75895,182.31448 43.625018,177.44148 37.971557,173.57975 28.01174,163.28381 28.01174,161.3013 c 0,-1.83865 0.635315,-1.8844 17.079208,-1.22988 19.475363,0.77518 28.155408,-0.12388 38.075567,-3.94376 9.279191,-3.57307 15.45203,-6.36285 15.01445,-6.78568 -0.201984,-0.19518 -4.599918,0.0895 -9.773185,0.63261 -15.856397,1.66468 -37.875872,-0.52821 -50.869606,-5.06603 -3.201056,-1.11791 -7.99066,-3.68786 -10.643565,-5.71099 l -4.823463,-3.67842 0.178374,-9.45002 0.178374,-9.45001 0.5642,7.42574 c 0.582301,7.66397 1.29799,8.16822 2.459224,1.73268 0.423991,-2.34976 0.289983,-3.71287 -0.365011,-3.71287 -0.569229,0 -1.034963,-1.33664 -1.034963,-2.9703 0,-1.63367 -0.407778,-2.9703 -0.906174,-2.9703 -1.708089,0 -9.947718,-12.02652 -11.073528,-16.16286 C 8.4406212,86.620448 14.328838,72.981775 26.509135,66.520142 l 4.472902,-2.372869 0,-7.169297 c 0,-11.907876 4.934342,-21.608335 13.56406,-26.665688 2.388815,-1.399939 4.1792,-3.048653 3.978634,-3.66381 C 47.539733,23.627398 33.787529,13.942425 21.173642,7.3865059 6.6394252,-0.16748247 5.7525435,-1.0667564 8.2445952,-5.7231976 9.9048868,-8.825481 13.26451,-8.0142814 26.786199,-1.2462239 42.52818,6.6331633 49.704459,11.834699 56.658674,20.406047 c 7.066894,8.71023 9.386734,9.398438 22.022822,6.533328 12.009438,-2.723024 25.519864,-2.231151 36.616764,1.3331 4.17096,1.339683 7.95921,2.16177 8.41835,1.826861 0.45913,-0.33491 2.70455,-3.059423 4.98981,-6.054473 2.28526,-2.995049 7.42528,-8.682601 11.42226,-12.639003 7.12067,-7.0483759 7.54019,-7.2929957 20.80065,-12.12871266 7.44339,-2.71438994 14.38913,-4.93525434 15.435,-4.93525434 1.40526,0 2.17641,1.0827118 2.95451,4.1481669 0.5791,2.28149179 0.85167,4.4737776 0.60572,4.871746 -0.24596,0.3979683 -6.12349,2.612099 -13.0612,4.92029 -12.32753,4.1014041 -12.76057,4.3449071 -19.06805,10.7223141 -3.54973,3.589081 -8.19833,9.098685 -10.33023,12.243564 l -3.87618,5.717962 4.38964,4.574292 c 2.4143,2.515859 3.60993,4.300819 2.65696,3.966577 -2.15679,-0.756469 -2.25789,0.631979 -0.17206,2.363061 1.27233,1.05594 1.70648,1.059167 2.35028,0.01747 0.5549,-0.897844 2.45839,0.813688 6.40236,5.756734 3.08697,3.868951 6.15063,7.065929 6.80813,7.104394 0.6575,0.03847 4.65679,0.0099 8.8873,-0.0634 4.23053,-0.07334 11.0745,0.619228 15.20883,1.53903 6.08457,1.353687 8.24222,1.455077 11.32293,0.532074 4.78641,-1.434041 9.61096,-5.430654 10.01889,-8.299556 0.1988,-1.398101 1.12005,-2.308693 2.53968,-2.510314 2.12619,-0.301966 2.22772,-0.004 2.22772,6.538442 0,6.740641 -0.099,7.001552 -5.9449,15.662921 -3.26969,4.844452 -7.74462,10.309246 -9.94428,12.143987 -2.19966,1.834742 -5.77393,5.949037 -7.94282,9.142879 -2.34976,3.460168 -6.29513,7.465423 -9.76248,9.910673 l -5.81903,4.10369 -1.15924,7.92805 c -1.61723,11.06032 -4.40347,19.58965 -9.70377,29.70553 -5.01528,9.57187 -13.95714,20.46445 -14.03497,17.09676 -0.0428,-1.8524 -0.1273,-1.86246 -1.77762,-0.21171 -1.37485,1.3752 -1.46515,1.89852 -0.43722,2.53406 1.41537,0.87508 -1.77232,4.09197 -9.46671,9.55344 -2.27836,1.61719 -4.34463,3.44333 -4.59171,4.0581 -0.8189,2.03758 6.19452,11.05322 18.90021,24.29583 6.90108,7.19272 12.04414,13.24542 11.42903,13.45046 -0.61512,0.20504 -0.83848,1.12371 -0.49637,2.0415 0.34212,0.91778 -1.79925,-0.97306 -4.75858,-4.20188 -2.95935,-3.22881 -5.27705,-6.21281 -5.15046,-6.6311 0.12659,-0.41828 -1.76241,-2.39328 -4.19777,-4.38889 -2.43538,-1.9956 -4.20453,-3.98988 -3.93146,-4.43172 0.27308,-0.44185 -1.40227,-2.36965 -3.72301,-4.28402 -2.32073,-1.91436 -5.99559,-5.73898 -8.16635,-8.49916 -4.50513,-5.7284 -5.73975,-6.34273 -10.18478,-5.06791 -1.75731,0.50399 -3.19511,0.54209 -3.19511,0.0847 0,-1.33295 -11.17951,1.64109 -12.389579,3.29596 -0.60449,0.82669 -2.322383,1.8101 -3.817542,2.18536 -3.551652,0.89142 -4.937215,3.23379 -7.580515,12.81533 -4.406767,15.97381 -11.099683,29.94917 -15.20688,31.75323 -1.152028,0.50601 -2.096442,1.7759 -2.098696,2.82193 -0.0024,1.08338 -1.280677,2.61084 -2.970297,3.54913 -1.631409,0.90597 -2.982805,2.27784 -3.003103,3.04859 -0.05664,2.15103 -3.526894,6.90294 -4.570213,6.25813 -0.985639,-0.60915 -3.808724,1.30636 -3.808724,2.5843 0,1.92758 5.895059,2.34928 41.089109,2.93925 l 37.62376,0.63071 -39.232671,0.18757 c -21.57797,0.10316 -40.736386,0.48547 -42.574257,0.84959 -3.159411,0.62595 -3.260618,0.56176 -1.856436,-1.17724 z m 42.238485,-67.99171 c -1.942887,-0.70765 -3.471758,-0.70422 -4.950495,0.0112 -1.790743,0.86631 -1.332552,1.03319 2.81102,1.02385 4.566697,-0.0103 4.732564,-0.0905 2.139475,-1.03501 l 0,-3e-5 z m -14.020663,-0.82863 c -1.089109,-0.4866 -6.435644,-1.80129 -11.881188,-2.92155 -5.759121,-1.18476 -12.800298,-3.45953 -16.831683,-5.43774 -6.954731,-3.41271 -17.742094,-11.92119 -16.880858,-13.3147 0.253072,-0.40948 3.040932,-0.57204 6.195246,-0.36125 4.48988,0.30005 5.355073,0.14443 3.984772,-0.71671 -0.96269,-0.60499 -4.913826,-1.36519 -8.780302,-1.68935 -6.863409,-0.57539 -7.004171,-0.54119 -5.941584,1.44428 2.200044,4.11082 13.668199,13.46069 20.585236,16.78294 7.129107,3.42411 21.632479,7.0912 28.065212,7.09613 2.851296,0.002 3.114461,-0.15412 1.485149,-0.88205 z m 13.55198,-1.63782 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52001 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 8.981792,-3.22305 c 4.1272,-1.05557 9.34757,-2.85973 11.60083,-4.00925 2.25325,-1.14953 4.87457,-1.8432 5.82513,-1.54151 0.95056,0.30171 2.59602,-0.12295 3.65656,-0.94367 1.60041,-1.23851 1.63367,-1.38963 0.19559,-0.88881 -2.84772,0.99172 -1.97918,-0.17229 2.18456,-2.92772 2.15449,-1.42577 4.50534,-2.36663 5.22413,-2.09081 0.7188,0.27584 3.05637,-1.2901 5.1946,-3.47985 2.13823,-2.18975 3.51995,-3.98136 3.07047,-3.98136 -0.44946,0 -0.26663,-0.66342 0.4063,-1.47425 0.67294,-0.81083 1.5681,-1.26129 1.98925,-1.001 0.42114,0.26029 1.37313,-0.30156 2.11553,-1.24853 1.22149,-1.55808 1.18509,-1.59258 -0.38286,-0.36292 -0.95297,0.74738 -1.73267,0.91332 -1.73267,0.36877 0,-1.1032 2.94273,-3.80059 3.86504,-3.5428 0.32472,0.0908 0.81317,-0.0921 1.08545,-0.40626 0.27228,-0.3142 -0.0619,-0.25079 -0.74257,0.14094 -1.83418,1.05552 -1.52708,0.0245 1.35025,-4.53358 3.80038,-6.02017 8.15245,-16.13427 10.34121,-24.03269 2.90781,-10.4932 3.24131,-10.00199 -6.51584,-9.59724 -8.06376,0.33451 -11.36374,-0.51104 -11.36374,-2.91169 0,-1.41219 3.87705,-3.01077 12.01762,-4.9551 13.6173,-3.2524 18.1279,-6.30458 30.44942,-20.604205 3.20647,-3.721241 5.60795,-5.75908 6.01348,-5.102907 0.45242,0.732027 1.17307,0.513084 2.18435,-0.663636 2.69435,-3.135129 3.29702,-4.863342 0.99046,-2.840244 -1.18271,1.037369 -2.15038,1.440581 -2.15038,0.896027 0,-1.154396 3.94299,-4.919356 4.6419,-4.432319 0.26048,0.181519 0.77064,-0.0013 1.13367,-0.406262 0.36304,-0.404963 0.10314,-0.415797 -0.57755,-0.02408 -1.80598,1.039294 -1.51814,-0.190163 0.80999,-3.459724 2.31999,-3.258114 2.32271,-3.256657 -3.39724,-1.816357 -3.2192,0.810603 -6.66348,0.694459 -14.67251,-0.494768 -15.04707,-2.234274 -20.55437,-0.689621 -28.57683,8.015049 -2.42602,2.632325 -4.72907,4.680174 -5.11788,4.550775 -0.38882,-0.129399 -0.48449,0.344426 -0.2126,1.052946 0.27188,0.70852 -0.4282,2.123094 -1.55573,3.143497 -2.0095,1.818571 -2.09324,1.812104 -4.23219,-0.326854 l -2.18214,-2.182131 2.25594,-4.252496 c 1.24077,-2.338872 4.17354,-6.452573 6.51728,-9.141556 2.34372,-2.688985 4.05061,-5.50801 3.79308,-6.264503 -0.31259,-0.918192 -0.0455,-1.114196 0.80328,-0.589595 0.85837,0.530499 1.02875,0.393018 0.52435,-0.423105 -0.41094,-0.664922 -0.99572,-0.9604 -1.2995,-0.656618 -0.69266,0.69266 -3.20978,-1.330935 -3.20978,-2.580451 0,-0.510014 0.51439,-0.609392 1.14308,-0.220837 0.73045,0.451439 0.87336,0.270048 0.3959,-0.50249 -0.41094,-0.664922 -1.00055,-0.955563 -1.31024,-0.645868 -0.69833,0.698319 -4.18913,-2.365165 -4.18913,-3.67632 0,-0.526833 0.7797,-0.370613 1.73267,0.347155 0.95297,0.717767 -0.70223,-1.23225 -3.67822,-4.333371 -3.76003,-3.918124 -5.93501,-5.472057 -7.12873,-5.093182 -0.94481,0.299873 -3.07003,-0.15402 -4.7227,-1.00865 -2.43778,-1.26062 -3.37289,-1.324035 -4.95495,-0.33602 -2.36555,1.477307 -3.05981,0.886 -3.92467,-3.34268 -0.56625,-2.768728 -1.37248,-3.513567 -5.43639,-5.022464 -7.80616,-2.898363 -17.966683,-4.011606 -26.200113,-2.870631 -3.997279,0.553936 -7.475959,1.215337 -7.730402,1.469779 -0.254442,0.254443 0.998085,3.050852 2.783393,6.214244 2.874608,5.093525 3.291609,6.794112 3.644505,14.862796 l 0.398492,9.111176 3.564442,0.668693 c 7.773644,1.458345 16.010573,8.110583 19.620143,15.845464 3.09701,6.636514 3.26024,18.338664 0.34238,24.546143 -2.99996,6.38214 -7.1277,10.84757 -13.007325,14.07144 -4.530381,2.48406 -6.383854,2.90835 -12.728271,2.91366 -6.074888,0.005 -8.236255,-0.44332 -11.881188,-2.465 -2.450495,-1.35916 -4.455445,-2.98232 -4.455445,-3.60701 0,-0.62469 -0.40559,-1.50708 -0.901312,-1.96089 -0.523658,-0.47936 -0.602889,-0.3065 -0.189092,0.41255 0.391721,0.68069 0.309434,1.23762 -0.182859,1.23762 -1.220735,0 -4.304298,-3.49834 -3.655466,-4.14718 0.286625,-0.28662 -0.191905,-1.11291 -1.063399,-1.83618 -1.321234,-1.09653 -1.725666,-1.0867 -2.433844,0.0592 -0.46712,0.75582 -0.647589,1.7006 -0.401041,2.09952 0.480206,0.77699 -4.431607,4.73002 -8.49972,6.84057 -1.361386,0.7063 -6.473966,1.77939 -11.361289,2.38466 l -8.886042,1.10047 -0.8419,4.2572 c -1.116431,5.64542 -0.634772,6.55826 4.953601,9.38814 6.711939,3.39884 14.108367,5.45589 25.541571,7.10346 13.412147,1.93275 20.966236,1.82034 33.743152,-0.50211 17.901519,-3.25395 20.945769,-2.59407 18.234109,3.95245 -1.77158,4.27697 -8.27108,9.72932 -15.51118,13.01214 -10.066949,4.56456 -20.604188,6.60666 -38.045678,7.37316 -12.034826,0.52888 -15.515628,0.97079 -14.765554,1.87458 0.53979,0.65041 0.751763,1.41223 0.47105,1.69294 -0.280712,0.28071 0.280084,1.1308 1.246214,1.8891 1.597283,1.25367 1.633357,1.22157 0.397743,-0.35396 -1.901096,-2.42408 -0.973659,-2.18092 4.907357,1.28665 4.510039,2.65922 13.386837,5.60901 26.15447,8.69123 6.758464,1.63156 18.458956,1.2966 26.494168,-0.75846 l 0,-4e-5 z m 15.58504,-0.061 c 1.16161,-0.7507 0.90473,-0.96308 -1.17919,-0.97494 -1.46538,-0.008 -2.9397,0.43038 -3.27626,0.97494 -0.78135,1.26425 2.49915,1.26425 4.45545,0 z m 6.00568,-2.01503 c 1.95644,-1.04706 2.62207,-2.93547 1.0347,-2.93547 -0.48422,0 -1.93224,0.87627 -3.21783,1.94726 -2.49465,2.07826 -1.06383,2.72592 2.18313,0.98821 z m -6.00568,-1.45032 c 1.36139,-0.77824 2.0297,-1.41498 1.48515,-1.41498 -0.54456,0 -2.10396,0.63674 -3.46535,1.41498 -1.36138,0.77824 -2.0297,1.41498 -1.48515,1.41498 0.54456,0 2.10396,-0.63674 3.46535,-1.41498 z m -62.458746,0.13411 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553336,0.36093 1.577225,1.26362 4.799862,2.3676 3.441125,1.17883 l 0,0 z m 74.762706,-3.12566 c 1.04936,-0.7939 1.64445,-1.70691 1.32243,-2.02893 -0.78266,-0.78265 -4.7155,1.36919 -4.7155,2.58006 0,1.33049 1.15362,1.1431 3.39307,-0.55113 z m 5.3845,-4.97977 c 0.31295,-1.61495 0.14607,-1.68767 -1.23763,-0.53929 -1.89234,1.57049 -2.12795,3.40609 -0.36172,2.81801 0.68069,-0.22665 1.40039,-1.25207 1.59935,-2.27872 z m -93.926084,0.17176 c 0,-0.2056 -0.779703,-0.9853 -1.732673,-1.73268 -1.570353,-1.23155 -1.605372,-1.19653 -0.373817,0.37382 1.293435,1.64926 2.10649,2.17375 2.10649,1.35886 z m 42.048957,-9.0646 c 10.23476,-3.01561 12.830661,-4.22882 16.665417,-7.78864 1.52559,-1.41621 3.14513,-2.57492 3.599,-2.57492 0.45387,0 1.59099,-1.16873 2.52694,-2.59715 0.93594,-1.42844 1.24801,-2.31675 0.69349,-1.97403 -0.55454,0.34271 -1.20807,0.0635 -1.45231,-0.62067 -0.24423,-0.68409 -0.82632,-0.88541 -1.2935,-0.44739 -0.46721,0.43803 -0.19404,1.21091 0.60702,1.71751 1.25252,0.79212 1.23533,0.92323 -0.12275,0.93627 -0.86857,0.008 -2.42798,0.95441 -3.46535,2.10238 -5.028165,5.56424 -22.795527,11.3182 -38.212356,12.37508 -15.799597,1.08311 -17.048668,2.42489 -1.792578,1.92561 10.641937,-0.34827 15.176438,-0.97076 22.246977,-3.05405 l 0,0 z m 63.891637,-3.12611 c 0,-1.41552 -0.23243,-1.39342 -1.9802,0.18829 -1.08911,0.98563 -1.9802,2.18422 -1.9802,2.66353 0,0.47932 0.89109,0.39459 1.9802,-0.18828 1.08911,-0.58287 1.9802,-1.78147 1.9802,-2.66354 z M 97.166642,146.77097 c 3.547598,-0.77002 4.965228,-1.47727 4.298178,-2.14431 -0.66706,-0.66706 -4.175166,-0.42281 -10.636358,0.74056 -14.897153,2.68229 -37.124591,0.77195 -52.477337,-4.51017 -6.578027,-2.26317 -6.378989,-2.22908 -6.378989,-1.09252 0,1.42916 9.008565,4.85904 15.926311,6.06371 16.965213,2.95437 38.134158,3.35943 49.268195,0.94273 l 0,0 z m 53.617378,0.0462 c 0.58287,-1.08911 0.837,-1.9802 0.56472,-1.9802 -0.27228,0 -0.97195,0.89109 -1.55482,1.9802 -0.58287,1.08911 -0.837,1.9802 -0.56472,1.9802 0.27227,0 0.97195,-0.89109 1.55482,-1.9802 z m 5.94059,-4.62356 c 0,-2.3135 -1.69554,-0.59965 -2.85822,2.88907 l -1.073,3.21964 1.96562,-2.33741 c 1.08108,-1.28558 1.9656,-2.98266 1.9656,-3.7713 z m -77.497329,2.91089 c -2.054226,-0.21433 -5.173038,-0.21074 -6.930694,0.008 -1.757656,0.21872 -0.07693,0.39409 3.734955,0.38969 3.811881,-0.004 5.249963,-0.18335 3.195739,-0.39768 l 0,7e-5 z m 10.356241,-0.94387 c -0.714728,-0.28601 -1.568688,-0.25085 -1.89769,0.0781 -0.329001,0.329 0.255776,0.56301 1.299505,0.52002 1.153409,-0.0475 1.38802,-0.28211 0.598185,-0.59817 l 0,4e-5 z m 19.616338,-1.30386 c 0,-0.54455 -0.47184,-0.99009 -1.04854,-0.99009 -0.57669,0 -0.77316,0.44554 -0.43661,0.99009 0.33655,0.54456 0.8084,0.9901 1.04853,0.9901 0.24014,0 0.43662,-0.44554 0.43662,-0.9901 z m 47.45458,-8.41584 c 0,-0.54455 -0.63674,0.12377 -1.41498,1.48515 -0.77823,1.36139 -1.41498,2.92079 -1.41498,3.46535 0,0.54455 0.63675,-0.12376 1.41498,-1.48515 0.77824,-1.36139 1.41498,-2.92079 1.41498,-3.46535 z M 28.453542,136.6394 c -0.717346,-1.86938 -3.412099,-3.08084 -3.412099,-1.53397 0,1.05715 3.177874,3.9134 3.73462,3.35666 0.149813,-0.14981 0.0047,-0.97003 -0.322521,-1.82269 z m 6.406383,0.90594 c -0.226898,-0.19852 -1.526403,-0.89141 -2.887789,-1.53976 -2.333929,-1.11154 -2.365521,-1.09092 -0.553337,0.36093 1.577226,1.26362 4.799863,2.3676 3.441126,1.17883 z m -8.178941,-9.80642 c -0.27121,-0.67032 -0.476602,0.11785 -0.456423,1.75152 0.02018,1.63366 0.242077,2.18212 0.493111,1.21878 0.251032,-0.96334 0.234523,-2.29997 -0.03668,-2.9703 l -4e-6,0 z M 162.66521,127.0736 c 0,-0.51242 -0.44555,-1.20703 -0.9901,-1.54359 -0.54456,-0.33655 -0.9901,0.0827 -0.9901,0.93167 0,0.84897 0.44554,1.54358 0.9901,1.54358 0.54455,0 0.9901,-0.41925 0.9901,-0.93166 z M 27.619826,122.33281 c -0.329002,-0.329 -0.563011,0.25579 -0.52002,1.29951 0.0475,1.15341 0.28212,1.38802 0.598185,0.59819 0.286011,-0.71474 0.250836,-1.5687 -0.07817,-1.8977 l 3e-6,0 z m 136.035474,0.2269 c 0,-0.81683 -0.44554,-1.48514 -0.99009,-1.48514 -0.54456,0 -0.9901,0.66831 -0.9901,1.48514 0,0.81684 0.44554,1.48515 0.9901,1.48515 0.54455,0 0.99009,-0.66831 0.99009,-1.48515 z M 33.704809,119.40196 c -0.95297,-0.24903 -2.512376,-0.24903 -3.465346,0 -0.952971,0.24904 -0.173268,0.4528 1.732673,0.4528 1.905941,0 2.685644,-0.20376 1.732673,-0.4528 z m 51.237624,-0.30759 c 0.336553,-0.54456 -0.250915,-0.9901 -1.305483,-0.9901 -1.054569,0 -2.472053,-0.66832 -3.149963,-1.48515 -0.677909,-0.81683 -2.197663,-1.48515 -3.37723,-1.48515 -1.179567,0 -3.798279,-0.84306 -5.819362,-1.87346 -3.979476,-2.02885 -4.801958,-1.43381 -1.788124,1.29368 1.984228,1.7957 10.984716,4.90909 10.984716,3.79975 0,-0.35514 0.534654,-0.11106 1.188119,0.54241 1.44777,1.44777 2.457132,1.50894 3.267327,0.19802 z m 79.702967,-3.02873 c 0,-1.05697 -0.44554,-1.92177 -0.9901,-1.92177 -0.54455,0 -0.99009,1.14016 -0.99009,2.53369 0,1.43699 0.42855,2.26881 0.99009,1.92176 0.54456,-0.33656 0.9901,-1.47671 0.9901,-2.53368 z m -126.008939,1.3525 c -0.963334,-0.25103 -2.299968,-0.23452 -2.970297,0.0366 -0.670329,0.27122 0.117853,0.47661 1.751517,0.45643 1.633663,-0.0202 2.182114,-0.24208 1.21878,-0.49311 l 0,5e-5 z m 15.788583,-6.49209 c 2.961802,-2.58663 6.027485,-4.70297 6.812628,-4.70297 1.653245,0 1.836694,-1.82146 0.39887,-3.96039 -0.83888,-1.24794 -1.390264,-1.01072 -3.45205,1.48514 -1.349539,1.63367 -2.677116,3.63862 -2.950173,4.45545 -0.273055,0.81683 -3.168256,2.95063 -6.433779,4.74178 -3.265523,1.79115 -5.937315,3.64601 -5.937315,4.12192 0,1.77959 6.361283,-1.59914 11.561819,-6.14093 z m -20.47271,5.3104 c 0,-1.48733 -5.81027,-1.8801 -6.366582,-0.43038 -0.356538,0.92913 0.492992,1.3081 2.93231,1.3081 1.888849,0 3.434272,-0.39498 3.434272,-0.87772 z m 63.050779,-1.35 c 2.916955,-1.98579 4.205247,-3.71287 2.769577,-3.71287 -0.693665,0 -8.394613,5.11626 -8.394613,5.57711 0,1.01623 2.716191,0.11603 5.625036,-1.86424 z m -5.082551,-1.19364 c 7.593085,-3.17259 13.318898,-12.23833 13.318898,-21.087947 0,-14.183278 -14.801367,-26.126413 -27.276503,-22.009246 -4.871629,1.607782 -12.143736,8.333235 -14.435363,13.350236 -3.260107,7.137268 -1.947056,16.953627 3.009811,22.501317 l 2.75988,3.08884 0.514066,-6.40417 c 0.59176,-7.372086 2.817916,-12.370412 6.194803,-13.909026 9.324945,-4.24873 15.584088,10.950876 9.956609,24.178486 -0.930827,2.18794 1.172672,2.29087 5.957799,0.29151 l 0,0 z m -66.879119,-1.52913 c -2.805149,-2.19422 -4.307733,-2.52716 -3.741707,-0.82908 0.211038,0.6331 1.180081,1.268 2.15343,1.41085 0.973349,0.14286 2.025929,0.51595 2.339067,0.82908 0.313138,0.31314 0.829243,0.55943 1.1469,0.54732 0.317656,-0.0121 -0.536304,-0.89328 -1.89769,-1.95817 z m 12.639913,0.64485 c 0.689575,-0.42992 0.997439,-1.19644 0.684141,-1.70337 -0.313298,-0.50692 -0.139505,-0.92168 0.386206,-0.92168 0.525712,0 0.704595,-0.96077 0.397519,-2.13502 -0.337827,-1.29185 -0.167417,-1.89344 0.431502,-1.52328 0.604271,0.37346 1.005912,-1.20529 1.031127,-4.0531 0.03148,-3.556019 -0.171219,-4.194157 -0.852784,-2.684642 -0.678574,1.502882 -0.773791,1.192692 -0.395022,-1.286842 0.353363,-2.313228 0.165236,-3.060723 -0.644381,-2.560356 -0.737692,0.45592 -0.940577,0.178019 -0.571745,-0.783139 0.314436,-0.819406 0.23569,-2.033505 -0.174991,-2.698 -1.105326,-1.788456 -7.682811,-2.144736 -9.055691,-0.490515 -0.631379,0.760762 -0.759249,1.396753 -0.284156,1.413317 0.475095,0.01654 0.06457,0.495168 -0.912263,1.063584 -1.129264,0.657109 -1.565313,1.697515 -1.197349,2.856861 0.318297,1.002872 0.145073,2.091406 -0.384943,2.418971 -1.212393,0.749301 -1.114708,6.501761 0.11041,6.501761 0.49838,0 0.626441,0.88128 0.284578,1.95839 -1.132056,3.56679 7.260902,7.05039 11.147842,4.62706 l 0,0 z m 8.934184,-0.55418 c 2.020385,-1.03924 5.010061,-3.29502 6.643725,-5.01286 2.868463,-3.01627 2.981671,-3.49028 3.302077,-13.826072 l 0.33178,-10.702722 -3.762914,-0.705927 C 47.602481,80.969761 43.95345,78.863901 38.40778,73.51044 l -4.950496,-4.778915 -3.90401,1.921073 C 17.503668,76.58193 12.423679,90.628824 18.240927,101.93283 c 3.23262,6.2816 4.539882,6.43779 5.329032,0.6367 0.928828,-6.827865 1.319844,-7.895489 4.103161,-11.203281 7.697735,-9.148234 17.690208,3.484377 13.905573,17.579601 -1.6234,6.04608 -1.03574,6.43209 5.036847,3.3085 l 0,0 z m 37.877227,-0.17548 c 0.607833,-1.13574 0.846281,-2.32386 0.529884,-2.64025 -0.316397,-0.3164 -0.575268,-0.0873 -0.575268,0.50911 0,0.59643 -0.700141,1.78455 -1.55587,2.64027 -0.855728,0.85573 -1.094176,1.55587 -0.529884,1.55587 0.564291,0 1.523303,-0.92924 2.131138,-2.065 l 0,0 z m -8.956275,-0.41024 c -0.777242,-0.93653 -0.843612,-1.48515 -0.179665,-1.48515 0.579095,0 1.32826,0.44554 1.664814,0.9901 0.336553,0.54455 1.710509,0.9901 3.053236,0.9901 3.405659,0 4.705098,-3.86234 3.99729,-11.88119 -0.410484,-4.650429 -0.278996,-6.023676 0.474005,-4.950498 0.92628,1.320129 0.997019,1.320129 0.636655,0 -0.222976,-0.816832 -0.888084,-1.485149 -1.478018,-1.485149 -0.589933,0 -1.406765,-0.334158 -1.815181,-0.742574 -0.408416,-0.408416 -1.808473,-0.742574 -3.111239,-0.742574 -1.326986,0 -2.099559,-0.435416 -1.756748,-0.990099 1.082137,-1.750934 -0.356281,-1.056251 -2.436678,1.176792 -1.948858,2.091852 -2.796679,4.371505 -1.276193,3.431475 0.408415,-0.252495 0.742574,2.796683 0.742574,6.775957 0,4.5426 -0.368457,7.02333 -0.990099,6.66611 -0.544555,-0.31292 -0.141343,0.39874 0.896028,1.58146 2.106995,2.4022 3.511949,2.99403 1.579219,0.66524 l 0,0 z m 74.981158,-0.19108 c -0.96334,-0.25103 -2.29997,-0.23453 -2.9703,0.0366 -0.67032,0.27122 0.11786,0.4766 1.75152,0.45643 1.63366,-0.0202 2.18212,-0.24208 1.21878,-0.49311 l 0,5e-5 z m -84.882148,-2.77922 c -0.67791,-0.81683 -1.678108,-1.48515 -2.222662,-1.48515 -0.552304,0 -0.445093,0.65669 0.242464,1.48515 0.67791,0.81683 1.678108,1.48515 2.222663,1.48515 0.552304,0 0.445093,-0.6567 -0.242465,-1.48515 z m 38.428218,-0.43317 c 0.24752,-0.74257 -0.12376,-1.11386 -0.86634,-0.86634 -0.71472,0.23824 -1.49443,1.01795 -1.73267,1.73268 -0.24752,0.74257 0.12376,1.11386 0.86634,0.86633 0.71472,-0.23823 1.49443,-1.01795 1.73267,-1.73267 z m 61.57178,-0.16781 c 0,-1.1313 -2.6849,-1.15685 -3.38,-0.0322 -0.2896,0.4686 -0.27234,1.10622 0.0384,1.41693 0.7726,0.77266 3.34158,-0.29192 3.34158,-1.38475 z m -145.544552,0.16436 c 0,-1.16817 -1.931044,-2.41782 -2.640265,-1.7086 -0.709219,0.70923 0.54042,2.64027 1.708598,2.64027 0.512417,0 0.931667,-0.41925 0.931667,-0.93167 z m 65.94472,-2.76058 c -0.329002,-0.329 -0.563011,0.25578 -0.52002,1.29951 0.04751,1.15341 0.28212,1.38802 0.598185,0.59818 0.286011,-0.71472 0.250836,-1.56868 -0.07817,-1.89769 l 3e-6,0 z m 20.193892,-0.7632 c 0,-0.81683 -0.44554,-1.48515 -0.9901,-1.48515 -0.54455,0 -0.9901,0.66832 -0.9901,1.48515 0,0.81683 0.44555,1.48515 0.9901,1.48515 0.54456,0 0.9901,-0.66832 0.9901,-1.48515 z m 60.18796,-0.40346 c 2.02039,-1.03875 5.45561,-3.52622 7.63382,-5.527735 l 3.9604,-3.639109 -4.45545,3.425762 c -2.45049,1.884172 -6.23762,4.351962 -8.41584,5.483972 -2.17822,1.13201 -3.60848,2.0779 -3.17837,2.10196 0.43011,0.0241 2.43506,-0.80612 4.45544,-1.84485 z m -94.1857,-5.289607 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237627 0,1.36138 0.224726,1.91831 0.499392,1.23762 0.274665,-0.68069 0.274665,-1.794554 0,-2.475247 z m 13.861386,-0.990099 c -0.274666,-0.680693 -0.499392,-0.123762 -0.499392,1.237624 0,1.361382 0.224726,1.918312 0.499392,1.237622 0.274666,-0.680691 0.274666,-1.794553 0,-2.475246 z m -25.408199,0.742575 c 0,-0.816832 -0.445544,-1.485149 -0.990099,-1.485149 -0.544554,0 -0.990099,0.668317 -0.990099,1.485149 0,0.816831 0.445545,1.485151 0.990099,1.485151 0.544555,0 0.990099,-0.66832 0.990099,-1.485151 z m 47.524753,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921683 -0.55343,0.342039 -0.74992,1.036653 -0.43661,1.543584 0.84874,1.37331 1.44286,1.11724 1.44286,-0.621901 l 0,0 z M 13.75844,96.59024 c -0.329002,-0.329 -0.563011,0.255782 -0.520019,1.299504 0.04751,1.153416 0.282119,1.38802 0.598184,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897693 l 0,0 z m 45.936468,-3.733496 c 0,-0.816831 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668317 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m 49.504952,-0.05842 c 0,-0.848971 -0.45281,-1.263723 -1.00625,-0.921684 -0.55343,0.34204 -0.74992,1.036654 -0.43661,1.543585 0.84874,1.373307 1.44286,1.117237 1.44286,-0.621901 l 0,0 z M 12.768341,90.649645 c -0.329002,-0.328998 -0.563011,0.255783 -0.52002,1.299505 0.04751,1.153416 0.28212,1.38802 0.598185,0.598189 0.286011,-0.714723 0.250836,-1.568684 -0.07817,-1.897694 l 0,0 z m 70.193894,0.721951 c -0.336554,-0.544555 -1.142551,-0.983277 -1.791106,-0.974941 -0.708531,0.0089 -0.586411,0.398248 0.305957,0.974941 1.902102,1.229238 2.244857,1.229238 1.485149,0 z m 25.247525,-4.513878 c 0,-0.84897 -0.45281,-1.263728 -1.00625,-0.921685 -0.55343,0.342043 -0.74992,1.036654 -0.43661,1.543581 0.84874,1.373311 1.44286,1.117238 1.44286,-0.621896 z M 13.75844,84.709054 c -0.329002,-0.329001 -0.563011,0.255777 -0.520019,1.299505 0.04751,1.153409 0.282119,1.38802 0.598184,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 0,0 z m 48.906765,-3.85473 c 0,-1.356215 -3.082898,-1.911382 -4.232156,-0.762123 -0.330986,0.330986 -0.08945,1.422196 0.536762,2.424911 0.842923,1.349734 1.470503,1.547624 2.416974,0.762123 0.703131,-0.583548 1.27842,-1.674757 1.27842,-2.424911 z m 43.564355,0.09971 c 0,-2.007107 -9.940776,-11.875249 -12.685773,-12.593082 -3.422347,-0.894964 -2.536662,0.72179 2.04221,3.727903 4.685203,3.075921 8.056173,6.371341 8.979963,8.778691 0.77225,2.012434 1.6636,2.058775 1.6636,0.08649 z m -47.693353,-7.404219 2.306645,-4.455446 -0.675699,4.455446 -0.6757,4.455445 3.814599,-3.586129 c 2.098029,-1.972372 6.311347,-5.155371 9.362929,-7.073331 5.874539,-3.692229 6.839458,-5.599101 6.818235,-13.474203 -0.0116,-4.303265 -3.763041,-12.649115 -7.037511,-15.656368 -5.956689,-5.47059 -15.534138,-7.597002 -22.017021,-4.888282 -12.757989,5.330628 -18.072962,19.793085 -11.85765,32.265591 2.52515,5.067315 2.685106,5.196865 3.601855,2.917172 0.958373,-2.383197 0.960066,-2.382511 1.654947,0.671085 0.942906,4.14352 1.700115,5.200511 5.327538,7.436733 4.523217,2.788458 6.716499,2.070908 9.376833,-3.067713 l 0,0 z m 8.682689,1.5849 c 1.905993,-1.851076 4.77995,-3.91008 6.386569,-4.575565 2.564998,-1.062456 4.03369,-2.949929 2.295417,-2.949929 -2.10037,0 -13.235677,8.775011 -13.235677,10.430176 0,1.083649 1.30255,0.252787 4.553691,-2.904682 z M 20.090948,74.8078 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z M 152.76422,69.68259 c 0,-0.272277 -1.78218,1.245201 -3.9604,3.372174 -2.17822,2.126974 -3.9604,4.089996 -3.9604,4.362274 0,0.272277 1.78218,-1.245201 3.9604,-3.372175 2.17822,-2.126973 3.9604,-4.089996 3.9604,-4.362273 z M 41.625601,72.476287 c -2.586633,-2.217071 -4.709793,-4.553304 -4.718131,-5.191628 -0.02877,-2.202305 -1.632163,-3.701423 -3.281819,-3.068391 -2.032483,0.779938 -2.195989,3.392952 -0.212309,3.392952 0.792663,0 3.354544,2.00317 5.693069,4.45149 2.338525,2.44832 4.92018,4.450394 5.737012,4.449053 0.816832,-0.0014 -0.631188,-1.816405 -3.217822,-4.033476 l 0,0 z M 24.051344,70.847404 c 0,-1.221474 -0.276132,-1.271282 -1.485149,-0.267887 -0.816831,0.67791 -1.485148,1.60957 -1.485148,2.070356 0,0.460786 0.668317,0.581336 1.485148,0.267887 0.816832,-0.313447 1.485149,-1.245108 1.485149,-2.070356 z m 6.526162,-3.972749 c -0.745512,-0.745512 -5.536063,1.770447 -5.536063,2.907495 0,0.46652 1.378038,0.135607 3.062307,-0.735362 1.684269,-0.870969 2.797459,-1.848429 2.473756,-2.172133 z m 53.127303,0.748085 c 0.952971,-0.0074 1.732673,-0.459065 1.732673,-1.003619 0,-0.544555 -0.940674,-0.990099 -2.090387,-0.990099 -1.852777,0 -2.016491,-0.393899 -1.440284,-3.465347 0.406143,-2.164925 0.261718,-3.465346 -0.38486,-3.465346 -0.56923,0 -1.034964,1.059307 -1.034964,2.354014 0,1.294709 -0.668316,2.90867 -1.485148,3.58658 -2.367441,1.964801 -1.885292,4.298583 0.742574,3.594342 1.225248,-0.328353 3.007426,-0.60309 3.960396,-0.610525 z m 71.134371,-0.722043 c 1.58154,-0.934242 2.87553,-2.079091 2.87553,-2.544109 0,-1.671282 -4.25968,-0.165537 -5.70037,2.015008 -1.76311,2.668563 -1.02958,2.805958 2.82484,0.529101 z m 47.13694,-2.884855 c -0.37294,-0.372946 -1.68483,-0.148769 -2.91529,0.498172 -1.23047,0.64694 -1.45751,0.953686 -0.50454,0.681656 1.92704,-0.550082 2.24796,0.402733 0.74808,2.221031 -0.54153,0.65649 -0.009,0.312431 1.18262,-0.764577 1.19197,-1.077007 1.86208,-2.263334 1.48913,-2.636282 z m -52.1822,2.108229 c 0.67791,-0.816831 1.00979,-1.485148 0.73751,-1.485148 -0.27227,0 -1.0497,0.668317 -1.72761,1.485148 -0.67791,0.816832 -1.00979,1.485149 -0.73752,1.485149 0.27228,0 1.04971,-0.668317 1.72762,-1.485149 z m 37.15543,-0.451808 c -0.32185,-0.520771 -1.23923,-0.695875 -2.03863,-0.38912 -2.04664,0.785373 -1.80547,1.335978 0.5852,1.335978 1.12125,0 1.7753,-0.426086 1.45343,-0.946858 z m -20.13811,-0.719592 c -0.71473,-0.286011 -1.56869,-0.250835 -1.89769,0.07817 -0.329,0.329001 0.25578,0.56301 1.29951,0.520019 1.15341,-0.04751 1.38802,-0.282119 0.59818,-0.598185 l 0,-3e-6 z M 84.05547,61.936777 c -0.329002,-0.329001 -0.563011,0.255776 -0.52002,1.299505 0.04751,1.153409 0.28212,1.38802 0.598185,0.598185 0.286011,-0.714727 0.250836,-1.568688 -0.07817,-1.89769 l 3e-6,0 z m 82.57013,0.721948 c 0,-0.544555 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445544 -1.48515,0.990099 0,0.544554 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445545 1.48515,-0.990099 z m 37.62376,-5.177658 c 0,-1.661518 -0.24856,-1.789209 -1.48514,-0.762936 -0.81684,0.67791 -1.48515,1.832342 -1.48515,2.565406 0,0.777973 0.61827,1.095588 1.48515,0.762936 0.81683,-0.313447 1.48514,-1.46788 1.48514,-2.565406 z M 83.457284,54.18445 c 0,-0.784694 -0.445544,-1.426715 -0.990099,-1.426715 -0.544554,0 -0.990099,0.917384 -0.990099,2.03863 0,1.121247 0.445545,1.76327 0.990099,1.426716 0.544555,-0.336553 0.990099,-1.253937 0.990099,-2.038631 z m 63.366336,-0.931666 c -1.27896,-1.361386 -2.77092,-2.475247 -3.31547,-2.475247 -0.54456,0 0.0563,1.113861 1.33527,2.475247 1.27896,1.361386 2.77092,2.475248 3.31548,2.475248 0.54455,0 -0.0563,-1.113862 -1.33528,-2.475248 z M 82.467185,48.302289 c 0,-0.816832 -0.445544,-1.485148 -0.990099,-1.485148 -0.544554,0 -0.990099,0.668316 -0.990099,1.485148 0,0.816832 0.445545,1.485149 0.990099,1.485149 0.544555,0 0.990099,-0.668317 0.990099,-1.485149 z m -1.985115,-5.19802 c -0.0084,-1.2671 -4.736103,-6.714785 -5.323399,-6.134089 -0.649329,0.642032 3.49033,6.834315 4.585742,6.859554 0.408416,0.0094 0.740362,-0.317049 0.737657,-0.725465 l 0,0 z m 50.49997,-0.247525 c -0.81683,-0.527877 -1.9307,-0.959776 -2.47525,-0.959776 -0.54456,0 -0.32178,0.431899 0.49505,0.959776 0.81683,0.527878 1.93069,0.959777 2.47525,0.959777 0.54455,0 0.32178,-0.431899 -0.49505,-0.959777 z m 4.44995,-0.996169 c -0.98866,-1.092447 -2.01229,-1.771531 -2.27475,-1.509075 -0.66527,0.66528 1.80418,3.495343 3.04998,3.495343 0.56227,0 0.21342,-0.89382 -0.77523,-1.986268 l 0,0 z m -95.539062,-4.19679 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.677909 1.485148,-1.678107 1.485148,-2.222662 z m 92.079212,0.795947 c 0,-2.367417 -1.80911,-2.723191 -2.95546,-0.581213 -0.91594,1.711444 -0.77708,2.007928 0.94043,2.007928 1.10826,0 2.01503,-0.642021 2.01503,-1.426715 z M 43.853324,33.703389 c 0,-0.552304 -0.656693,-0.445093 -1.485148,0.242464 -0.816832,0.67791 -1.485149,1.678108 -1.485149,2.222663 0,0.552304 0.656693,0.445093 1.485149,-0.242465 0.816831,-0.67791 1.485148,-1.678108 1.485148,-2.222662 z m 29.450539,-0.0051 c -0.341635,-3.033194 -0.613818,-3.235945 -4.743791,-3.533678 -2.40975,-0.173719 -4.148989,-0.08348 -3.864976,0.200533 0.746043,0.746042 8.309556,6.402673 8.668673,6.483162 0.166387,0.03729 0.139429,-1.380215 -0.05991,-3.150017 z m 45.796987,1.732673 c -0.67791,-0.816832 -1.70871,-1.485149 -2.29066,-1.485149 -0.58196,0 -0.19325,0.654147 0.8638,1.453661 2.48363,1.878524 2.96864,1.889227 1.42686,0.03148 l 0,3e-6 z m 5.94059,-0.933056 c 0,-0.721181 -1.00247,-1.579892 -2.22772,-1.908245 -3.82044,-1.023837 -4.13152,-0.702262 -1.76134,1.820687 2.31705,2.466393 3.98906,2.503093 3.98906,0.08755 l 0,4e-6 z m 8.8851,-5.657864 c 5.0656,-7.213134 5.95021,-9.230659 3.73867,-8.526659 -1.72171,0.548068 -10.64357,12.438161 -10.64357,14.184592 0,2.924919 2.06665,1.231484 6.9049,-5.657933 z m -54.828018,2.397173 c -0.586902,-0.586901 -3.56203,0.943932 -3.56203,1.832819 0,0.490907 0.870827,0.348719 1.935171,-0.315974 1.064342,-0.664694 1.796429,-1.347273 1.626859,-1.516845 z m -29.622424,0.529501 c 3.007757,-1.087619 4.641314,-3.761497 2.298018,-3.761497 -0.544554,0 -0.990099,0.445545 -0.990099,0.990099 0,0.544555 -0.58316,0.990099 -1.295911,0.990099 -1.477794,0 -5.628481,2.890588 -4.219928,2.938809 0.505892,0.01732 2.399456,-0.503561 4.20792,-1.15751 l 0,0 z m 54.958912,-1.46755 c -0.71473,-0.286011 -1.56869,-0.250836 -1.89769,0.07817 -0.329,0.329002 0.25577,0.563011 1.2995,0.52002 1.15341,-0.0475 1.38802,-0.28212 0.59819,-0.598185 l 0,-3e-6 z M 59.694908,28.005259 c 0,-1.089109 -0.39099,-1.980198 -0.868866,-1.980198 -1.298365,0 -3.17241,2.559384 -2.422873,3.30892 1.355486,1.355487 3.291739,0.573912 3.291739,-1.328722 z m 21.287129,0.990099 c 0.336553,-0.544554 -0.331763,-0.990099 -1.485149,-0.990099 -1.153385,0 -1.821702,0.445545 -1.485148,0.990099 0.336553,0.544555 1.00487,0.990099 1.485148,0.990099 0.480279,0 1.148595,-0.445544 1.485149,-0.990099 z m 29.207923,0 c 0,-0.544554 -0.66832,-0.990099 -1.48515,-0.990099 -0.81683,0 -1.48515,0.445545 -1.48515,0.990099 0,0.544555 0.66832,0.990099 1.48515,0.990099 0.81683,0 1.48515,-0.445544 1.48515,-0.990099 z M 86.427581,28.005259 c 0,-0.544554 -0.694611,-0.990099 -1.543581,-0.990099 -0.848969,0 -1.268219,0.445545 -0.931666,0.990099 0.336553,0.544555 1.031164,0.990099 1.543581,0.990099 0.512417,0 0.931666,-0.445544 0.931666,-0.990099 z m 18.316829,0 c 0.33656,-0.544554 -0.33176,-0.990099 -1.48515,-0.990099 -1.15338,0 -1.8217,0.445545 -1.48514,0.990099 0.33655,0.544555 1.00487,0.990099 1.48514,0.990099 0.48028,0 1.1486,-0.445544 1.48515,-0.990099 z M 53.397761,23.263982 c -2.293369,-2.293369 -3.273717,-0.599352 -1.065339,1.840877 1.180946,1.304931 2.008695,1.63504 2.254066,0.898928 0.213274,-0.63982 -0.321654,-1.872732 -1.188727,-2.739805 l 0,0 z m 41.674343,3.065049 c -0.963333,-0.251033 -2.299967,-0.234524 -2.970297,0.03668 -0.670328,0.271211 0.117854,0.476602 1.751517,0.456424 1.633663,-0.02018 2.182115,-0.242078 1.21878,-0.493111 l 0,4e-6 z M 50.784017,20.160629 c 0,-1.18906 -5.817795,-7.006855 -7.006854,-7.006855 -1.723094,0 -0.911591,1.747528 2.244318,4.833013 3.196159,3.124838 4.762536,3.839805 4.762536,2.173842 z m 99.083553,-7.807387 c -1.32905,-0.443014 -5.95468,4.804941 -5.94174,6.741126 0.006,0.860676 1.47299,-0.172344 3.48946,-2.456779 1.91375,-2.168059 3.01727,-4.096016 2.45228,-4.284347 z m -7.4939,4.754858 c 2.64699,-2.924889 1.22992,-3.38489 -1.49431,-0.485075 -1.27694,1.359238 -1.86755,2.471343 -1.31247,2.471343 0.55508,0 1.81813,-0.893821 2.80678,-1.986268 z m 1.9747,-5.934524 c 2.68184,-2.7227721 4.44726,-4.9364147 3.92318,-4.9192068 -1.79455,0.058926 -11.48794,9.8697018 -9.75161,9.8697018 0.52381,0 3.1466,-2.227723 5.82843,-4.950495 z m 4.99121,-1.055971 c 1.06562,-1.7242011 -0.14804,-2.0893477 -1.506,-0.4531041 -0.78094,0.9409741 -0.85606,1.5090751 -0.19952,1.5090751 0.57909,0 1.34657,-0.475187 1.70552,-1.055971 z m 22.08877,-7.9517764 c 1.71492,-0.5978257 3.11804,-1.51893899 3.11804,-2.04691859 0,-1.07371396 -3.1521,-0.28577416 -6.93069,1.73248789 -3.09382,1.652504 -0.61271,1.8571218 3.81265,0.3144307 l 0,0 z m 6.85154,-0.707599 c 0.59402,-1.78204068 -1.45248,-1.40757811 -2.14309,0.3921386 -0.37003,0.9642713 -0.14875,1.4169139 0.57476,1.1757426 0.64703,-0.2156762 1.35277,-0.9212228 1.56833,-1.5678812 z M 20.090948,0.80296239 c 0,-0.25829297 -1.366838,-1.17644278 -3.037417,-2.04033289 C 13.07504,-3.294728 10.77735,-2.5105441 14.645403,-0.41549494 17.561715,1.1640635 20.090948,1.729987 20.090948,0.80296239 z M 177.51669,-2.5818805 c 0,-1.2146632 -2.78939,-2.1897491 -3.40672,-1.1908861 -0.27491,0.444817 -0.21492,1.0936751 0.1333,1.4419069 0.94359,0.9435791 3.27342,0.7649164 3.27342,-0.2510208 z"
+ transform="translate(0,784.36218)"
+ id="path3782"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 30.061595,110.24748 c -3.028002,-1.91623 -2.918962,-12.207625 0.161986,-15.288574 2.892806,-2.892806 5.380122,-2.029008 6.063557,2.105759 0.787072,4.761775 0.802973,10.540215 0.03451,12.542785 -0.657319,1.71294 -4.021187,2.05687 -6.260057,0.64003 l -1e-6,0 z"
+ transform="translate(0,784.36218)"
+ id="path3784"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 50.118347,74.592462 c -5.270942,-3.20545 -6.839578,-11.64359 -3.245566,-17.458823 3.039395,-4.917846 5.720122,-5.336139 9.002245,-1.404685 3.776278,4.523372 4.477791,9.679447 1.982432,14.570755 -2.972944,5.82745 -4.145768,6.477996 -7.739111,4.292753 z"
+ transform="translate(0,784.36218)"
+ id="path3786"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 77.269166,109.11407 c -1.309679,-0.76282 -1.732674,-2.30682 -1.732674,-6.32456 0,-2.923449 0.270441,-6.020121 0.600979,-6.881491 0.834308,-2.174169 4.068292,-1.961418 5.30478,0.348981 2.014054,3.7633 0.737507,14.00145 -1.732673,13.89637 -0.389257,-0.0166 -1.487442,-0.48424 -2.440412,-1.0393 z"
+ transform="translate(0,784.36218)"
+ id="path3790"
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2.9702971;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <path
+ d="m 974.24531,563.57578 c 0.19068,-0.58412 0.33807,-2.39704 0.32752,-4.02871 -0.0305,-4.72761 -2.16535,-7.80395 -5.35278,-7.71359 -2.82997,0.0802 -4.22476,1.85117 -5.32345,6.75914 -0.31004,1.38498 -0.36786,1.41644 -1.00404,0.54642 -0.37128,-0.50776 -0.8208,-1.89506 -0.99893,-3.08289 -0.55591,-3.70711 1.47155,-7.48719 5.4718,-10.20182 5.59862,-3.79933 13.97103,1.83612 13.9137,9.36528 -0.0236,3.09812 -3.73691,8.46539 -6.32496,9.14218 -0.90462,0.23656 -1.00597,0.12417 -0.70886,-0.78601 l 0,0 z"
+ id="path3811"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 973.90612,561.26286 c 0.21817,-3.86109 -0.81619,-7.47461 -2.37901,-8.31101 -1.45049,-0.77628 -3.83369,-0.56086 -4.83124,0.43669 -0.50664,0.50664 -1.3056,2.10548 -1.77547,3.55298 -1.09585,3.3759 -1.45679,3.72914 -2.36719,2.31667 -2.17253,-3.37066 -1.18174,-8.3045 2.35621,-11.73323 3.80821,-3.69063 6.35633,-4.18204 10.58332,-2.04103 3.18311,1.61228 5.5569,4.81655 6.06163,8.18231 0.27355,1.8242 0.11235,2.73702 -0.85017,4.81416 -1.44283,3.11366 -4.39733,6.23865 -5.8983,6.23865 -1.04834,0 -1.08674,-0.14752 -0.89978,-3.45619 z"
+ id="path3813"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 961.0831,541.36237 c -0.33003,-3.53422 -1.33157,-5.66019 -3.38893,-7.19369 -2.4962,-1.86061 -5.28857,0.24236 -6.51159,4.90394 l -0.62134,2.36827 -0.78337,-1.82202 c -2.59334,-6.03175 2.24127,-13.61508 8.68004,-13.61508 3.86832,0 6.85183,1.90897 8.66997,5.54739 1.62131,3.24451 1.8741,5.90823 0.71742,7.55961 -0.41352,0.59039 -2.03662,2.06204 -3.60688,3.27033 l -2.85504,2.19689 -0.30028,-3.21564 0,0 z"
+ id="path3815"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 951.68986,559.85808 c 0,-3.90068 -0.11817,-4.43649 -1.32841,-6.0232 -1.64739,-2.15984 -3.30885,-2.63488 -5.52968,-1.58103 -1.75544,0.83301 -3.67834,3.97169 -3.67834,6.00402 0,1.57105 -0.80279,1.30413 -1.42226,-0.47288 -1.64201,-4.71028 0.82795,-10.53973 5.50282,-12.98743 1.35025,-0.70698 1.44409,-0.67017 3.72097,1.45958 2.59818,2.4303 4.37239,3.46667 6.84829,4.00031 l 1.66306,0.35844 -0.30803,4.68928 c -0.33193,5.05322 -0.87831,6.12303 -4.09875,8.0254 l -1.36967,0.80908 0,-4.28157 z"
+ id="path3817"
+ style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1.47019994;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 1002.8896,554.75634 c 1.2135,-1.18081 3.0452,-2.70588 3.5885,-2.98777 0.2673,-0.13869 0.3404,-0.13033 0.5377,0.0614 0.2215,0.21519 0.2173,0.22773 -0.139,0.41194 -0.202,0.1045 -1.1682,0.8213 -2.147,1.5929 -3.0623,2.41407 -3.7048,2.73578 -1.8402,0.92149 z"
+ id="path3839"
+ style="fill:#808000;fill-opacity:1;stroke:#ffffff;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 1001.7609,555.81089 c 0.169,-0.31579 2.3506,-2.35144 3.6035,-3.3624 1.093,-0.88192 1.4098,-1.00296 1.7458,-0.66698 0.2354,0.23537 0.2054,0.26324 -2.3615,2.1931 -2.5867,1.94472 -3.2709,2.36525 -2.9878,1.83628 z m 3.223,-2.29188 c 2.1869,-1.64445 2.0774,-1.54607 1.8265,-1.64237 -0.1263,-0.0485 -0.4054,0.0686 -0.7322,0.30704 -0.774,0.56467 -3.1731,2.65442 -3.1815,2.77119 -0.01,0.13752 0.046,0.0993 2.0872,-1.43586 z"
+ id="path3841"
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 1001.5912,556.03181 c -0.1044,-0.16895 0.8478,-1.16015 2.5352,-2.63894 1.8475,-1.6192 1.7341,-1.53116 2.253,-1.748 0.4162,-0.17387 0.4702,-0.17054 0.7369,0.0453 l 0.2877,0.233 -0.2464,0.27229 c -0.2603,0.28767 -3.4968,2.74402 -4.6222,3.50806 -0.707,0.47998 -0.825,0.52102 -0.9442,0.32824 z m 4.6552,-3.67215 c 0.154,-0.18668 0.1439,-0.19204 -0.1086,-0.0575 -0.2879,0.15343 -0.3589,0.26338 -0.1698,0.26338 0.06,0 0.185,-0.0926 0.2784,-0.20587 l 0,0 z"
+ id="path3843"
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ d="m 1002.8311,557.40044 c 0.1343,-0.13117 0.9401,-0.6115 1.7909,-1.06738 0.8507,-0.45589 1.9764,-1.13063 2.5015,-1.49943 0.9671,-0.67921 2.0769,-1.69802 2.0769,-1.90664 0,-0.0627 0.1392,-0.11397 0.3094,-0.11397 1.3509,0 -2.156,2.85903 -5.3392,4.35282 -0.5545,0.26021 -1.1376,0.47311 -1.2958,0.47311 -0.286,0 -0.2863,-10e-4 -0.044,-0.23851 z"
+ id="path3847"
+ style="fill:#008000;fill-opacity:1;stroke:#008000;stroke-width:0.37122548;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <path
+ transform="translate(-369.66666,-307.1008)"
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ d="m 545.47795,569.43686 c 0.16709,-0.66839 0.34267,-1.29362 0.48523,-1.72439 0.14256,-0.43078 0.25181,-0.66597 0.31085,-0.65272 0.059,0.0132 0.0679,0.27495 0.0363,0.73114 -0.0315,0.45619 -0.1032,1.10576 -0.18053,1.7962 -0.002,0.004 -0.003,0.008 -0.005,0.0117 -0.25593,0.64374 -0.49797,1.24996 -0.68464,1.6675 -0.18667,0.41755 -0.31769,0.6453 -0.37624,0.63065 -0.0585,-0.0147 -0.0446,-0.27169 0.0318,-0.7168 0.0765,-0.4451 0.21524,-1.07716 0.38176,-1.74325 0.16652,-0.66609 0.34152,-1.28909 0.48351,-1.71781 0.142,-0.42873 0.25071,-0.66208 0.30928,-0.64744 0.0586,0.0146 0.067,0.27725 0.0351,0.73349 -0.0319,0.45625 -0.10372,1.10502 -0.18105,1.79339 -4.7e-4,0.004 -9.3e-4,0.008 -0.001,0.0125 -0.25647,0.64565 -0.49876,1.25256 -0.68551,1.66995 -0.18676,0.41739 -0.3177,0.64415 -0.37604,0.62805 -0.0584,-0.0161 -0.0441,-0.27503 0.0328,-0.72222 0.0769,-0.44718 0.21618,-1.08149 0.38327,-1.74988 z"
+ id="path3778-7"
+ inkscape:path-effect="#path-effect3780"
+ inkscape:original-d="m 545.47795,569.43686 c 0.56247,0.14061 1.12494,0.28123 0,0 z" />
+ <text
+ xml:space="preserve"
+ style="font-size:26px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="40.550781"
+ y="72.354271"
+ id="text3655"><tspan
+ sodipodi:role="line"
+ id="tspan3663"
+ x="40.550781"
+ y="72.354271"
+ style="font-size:32px">Would you like </tspan><tspan
+ sodipodi:role="line"
+ x="40.550781"
+ y="112.35427"
+ id="tspan2917"
+ style="font-size:32px">to play again?</tspan><tspan
+ sodipodi:role="line"
+ id="tspan3669"
+ x="40.550781"
+ y="146.37378"> </tspan></text>
+ <g
+ transform="matrix(0.66666667,0,0,0.66150756,232.52873,-361.5815)"
+ id="layer1-4"
+ inkscape:label="Layer 1">
+ <g
+ transform="matrix(0.97869659,0,0,0.97869659,0.47308226,22.378026)"
+ id="g3211">
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:none"
+ d="m 37,942.81046 c 0.167098,-0.66843 0.34309,-1.2936 0.486364,-1.7242 0.143274,-0.4306 0.253551,-0.66551 0.31386,-0.65187 0.06031,0.0136 0.07065,0.2758 0.04077,0.73251 -0.02988,0.45671 -0.09969,1.10684 -0.175087,1.79783 -0.0015,0.004 -0.003,0.007 -0.0044,0.0112 -0.257922,0.64338 -0.501864,1.24926 -0.690253,1.66648 -0.188389,0.41721 -0.32095,0.64463 -0.380785,0.62966 -0.05983,-0.015 -0.04694,-0.27232 0.02884,-0.7177 0.07578,-0.44537 0.21418,-1.07766 0.380734,-1.74389 0.166554,-0.66623 0.341982,-1.28926 0.484718,-1.7179 0.142736,-0.42864 0.252501,-0.66177 0.312355,-0.64682 0.05985,0.015 0.06979,0.27801 0.03961,0.73477 -0.03018,0.45676 -0.100211,1.10613 -0.175623,1.79513 -4.36e-4,0.004 -8.73e-4,0.008 -0.0013,0.0119 -0.258431,0.64522 -0.502606,1.25177 -0.691076,1.66883 -0.188471,0.41707 -0.320958,0.64354 -0.380601,0.62718 -0.05964,-0.0163 -0.04644,-0.27553 0.02975,-0.72289 0.07619,-0.44737 0.215079,-1.08182 0.382177,-1.75025 z"
+ id="path3778-9"
+ inkscape:path-effect="#path-effect3780-0"
+ inkscape:original-d="m 37,942.81046 c 0.574713,0.14367 1.149425,0.28735 0,0 z" />
+ <g
+ id="g4020"
+ transform="translate(-184.55172,103.22414)">
+ <g
+ class="spaceship"
+ id="shipBody">
+ <path
+ id="path3154"
+ d="m 235.65719,857.2309 c -5.15468,-1.08647 -10.13216,-2.60614 -11.06105,-3.37705 -1.4687,-1.21891 -1.59942,-3.62164 -1.0026,-18.42851 0.60898,-15.10833 2.82784,-34.89255 4.50742,-40.18992 0.5468,-1.72458 2.1597,-1.86153 18.79408,-1.59574 l 18.19595,0.29073 0.86603,3.19149 c 1.42964,5.26854 4.21348,40.89938 3.86495,49.46809 l -0.32454,7.97872 -6.91489,1.70857 c -11.71067,2.89354 -16.85673,3.0758 -26.92535,0.95362 l 0,0 z"
+ style="fill:#d45500;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ class="spaceship"
+ id="shipBottom">
+ <path
+ id="path3157"
+ d="m 244.48826,894.22212 c -4.2024,-0.66031 -8.30588,-1.6713 -9.34259,-2.30176 -1.50562,-0.91562 -2.96927,-3.83924 -5.28678,-10.56029 -3.38846,-9.8269 -6.66033,-24.37913 -5.69774,-25.34172 0.34613,-0.34613 1.65904,0.0304 4.83607,1.387 l 4.36096,1.86212 8.04349,-0.30495 c 4.42393,-0.16772 9.30427,-0.48845 10.84522,-0.71273 1.54095,-0.22428 5.51724,-0.5933 8.83621,-0.82003 3.31896,-0.22673 6.77423,-0.53583 7.67837,-0.68688 l 1.64389,-0.27464 -0.27403,1.65891 c -1.72541,10.44502 -5.37775,23.19669 -9.194,32.09965 l -0.81901,1.91067 -5.12106,0.9443 c -5.68087,1.04752 -8.8862,1.39534 -10.509,1.14035 z"
+ style="fill:#008000;fill-opacity:0.93984112;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ class="spaceship"
+ id="shipLtWing">
+ <path
+ id="path3160"
+ d="m 207.75862,910.1208 1.2931,-9.48276 3.44828,-6.46552 4.31034,-6.89655 5.17242,-6.03448 4.31034,-2.58621 1.72414,-1.2931 3.87931,12.06896 0.43104,1.72414"
+ style="fill:#ff0000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ class="spaceship"
+ id="shipRtWing">
+ <path
+ id="path3163"
+ d="m 262.06896,892.44839 3.01724,-12.5 9.05172,5.17241 5.17242,6.46552 2.15517,4.74138 3.44827,8.18965 2.58621,10.34483 -8.18965,-9.91379 -6.03449,-5.17242 -4.74138,-3.44827 -6.46551,-3.87931 z"
+ style="fill:#ff0000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ class="spaceship"
+ id="shipCone">
+ <g
+ id="g3822">
+ <path
+ id="path3814"
+ d="m 238.05674,793.18103 c -6.10246,-0.52204 -8.42268,-0.87219 -8.56122,-1.29204 -0.10453,-0.31675 0.30123,-1.48054 0.90169,-2.5862 0.60047,-1.10566 1.46952,-3.46503 1.93123,-5.24305 1.03163,-3.97271 6.17659,-18.26477 6.64632,-18.46264 0.1876,-0.079 0.34109,-0.38714 0.34109,-0.68471 0,-1.96184 7.19772,-16.19748 8.18965,-16.19748 0.56862,0 3.86104,5.678 5.49864,9.48276 2.06526,4.7984 7.19953,18.13611 8.29619,21.55173 4.18191,13.02476 4.23136,13.3315 2.15345,13.35671 -1.19212,0.0144 -10.09252,0.40818 -13.57759,0.60062 -1.89655,0.10473 -7.2153,-0.13184 -11.81945,-0.5257 l 0,0 z"
+ style="fill:#ffff00;fill-opacity:0.93984112;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ id="path3820"
+ d="m 247.84482,749.34494 c -0.43103,-9.91379 -0.43103,-9.91379 -0.43103,-9.91379 l 0,0.43103"
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <g
+ class="spaceship"
+ id="shipLtJet">
+ <path
+ id="path3170"
+ d="m 235.50249,906.17356 c 0,-1.06703 4.59976,-12.40994 5.03247,-12.40994 0.74921,0 3.52178,11.5796 2.85187,11.91094 -1.14852,0.56809 -7.88434,0.9944 -7.88434,0.499 z"
+ style="fill:#800080;fill-opacity:0.93984112;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ <g
+ class="spaceship"
+ id="shipRtJet">
+ <path
+ id="path3173"
+ d="m 252.67238,906.11389 c -1.35952,-0.18394 -1.44042,-0.348 -1.11133,-2.25333 0.1952,-1.1302 0.82906,-3.53453 1.40857,-5.34296 l 1.05363,-3.28807 1.72233,4.60998 c 0.9473,2.53547 1.8799,5.05611 2.07247,5.60139 0.31242,0.88465 0.13311,0.98497 -1.66464,0.93143 -1.10813,-0.033 -2.67459,-0.1493 -3.48103,-0.25844 z"
+ style="fill:#800080;fill-opacity:0.93984112;stroke:#000000;stroke-width:2.81490302;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ </g>
+ </g>
+ <g
+ class="spaceship"
+ id="shipFire1"
+ transform="translate(-171.5,206.5)">
+ <path
+ style="fill:#fefefd"
+ d="m 213.07446,821.01373 0,-15 20,0 20,0 0,15 0,15 -20,0 -20,0 0,-15 z"
+ id="path3024" />
+ <path
+ style="fill:#fdfbf4"
+ d="m 242.07446,835.28173 c -3.61556,-0.66474 -4.70548,-1.87312 -5.45964,-6.05304 -2.27423,-12.60493 -1.42549,-20.52872 2.31719,-21.6331 1.32002,-0.38951 6.93368,-0.22942 11.39245,0.3249 0.4125,0.0513 0.75,1.64168 0.75,3.53422 0,1.89254 0.45,3.7191 1,4.05902 2.54527,1.57306 0.0351,18.5 -2.74348,18.5 -0.69109,0 -1.25652,0.45 -1.25652,1 0,1.01912 -1.54039,1.08792 -6,0.268 z m -21.75,-0.93028 c -0.6875,-0.27741 -1.25689,-1.25439 -1.26531,-2.17105 -0.0124,-1.35224 -0.18204,-1.40336 -0.89908,-0.27095 -0.50392,0.79583 -1.59909,1.12122 -2.54807,0.75706 -1.94705,-0.74715 -1.12949,-2.65278 1.13811,-2.65278 1.15603,0 1.37715,-0.5801 0.85766,-2.25 -2.33632,-7.51012 -1.67256,-19.75 1.07102,-19.75 0.83254,0 1.23559,-0.45 0.89567,-1 -0.87696,-1.41896 2.8546,-1.2454 4.3,0.2 0.93333,0.93333 1.46667,0.93333 2.4,0 1.58906,-1.58906 5.28176,-1.52936 6.6401,0.10734 1.42636,1.71865 1.17235,25.91644 -0.28266,26.92735 -1.17512,0.81645 -10.34907,0.89325 -12.30744,0.10303 z"
+ id="path3022" />
+ <path
+ style="fill:#fef4f3"
+ d="m 243.63248,835.10761 c -0.30801,-0.49837 -1.3785,-0.69208 -2.37887,-0.43048 -2.77871,0.72665 -3.72489,-1.36607 -5.04726,-11.1634 -2.04821,-15.17496 -0.0992,-17.37091 13.86811,-15.625 0.55,0.0688 1,1.925 1,4.125 0,2.2 0.45,4 1,4 0.55445,0 1,2.64699 1,5.94098 0,3.26754 -0.45,6.2191 -1,6.55902 -0.55,0.33992 -1,1.39147 -1,2.33678 0,3.26484 -5.95123,6.66918 -7.44198,4.2571 z m -22.74632,-1.31683 c -4.37516,-3.39748 -6.23457,-22.53224 -2.45791,-25.2938 0.88832,-0.64955 1.32212,-1.47401 0.964,-1.83213 -0.35812,-0.35811 0.23388,-0.65112 1.31554,-0.65112 1.08167,0 2.41295,0.44628 2.95841,0.99174 0.65566,0.65566 2.0518,0.59162 4.11984,-0.18897 5.54377,-2.09255 6.17944,-0.58472 6.01373,14.26467 -0.11976,10.73113 -0.40636,12.99629 -1.68481,13.31597 -3.61444,0.9038 -9.7078,0.57475 -11.2288,-0.60636 z"
+ id="path3020" />
+ <path
+ style="fill:#fdf4eb"
+ d="m 244.07446,834.94634 c 0,-0.58706 -0.83647,-0.8019 -1.85882,-0.47742 -2.45124,0.778 -4.46558,-1.75044 -4.35975,-5.47246 0.0461,-1.62139 -0.33587,-3.20735 -0.84881,-3.52437 -0.51294,-0.31702 -0.93262,-3.69984 -0.93262,-7.51738 0,-5.70987 0.37113,-7.31211 2.09245,-9.03343 1.38572,-1.38572 2.82118,-1.89697 4.25,-1.51366 1.18665,0.31834 3.62005,0.58495 5.40755,0.59246 3.11458,0.0131 3.25,0.17786 3.25,3.95463 0,2.16754 0.45,4.2191 1,4.55902 2.55736,1.58053 0.26642,14.37644 -3.19334,17.8362 -1.86559,1.86559 -4.80666,2.23052 -4.80666,0.59641 z m -23.25021,-1.32568 c -1.57289,-1.57289 -3.54882,-8.77472 -3.87044,-14.10693 -0.37645,-6.24113 0.18337,-9.26629 2.13011,-11.51091 1.80021,-2.07566 2.26525,-2.18003 4.46591,-1.00227 1.95295,1.04519 2.76106,1.06185 3.94255,0.0813 1.957,-1.62417 5.3134,-0.49003 6.12591,2.06997 0.35537,1.11968 0.33438,3.68417 -0.0466,5.69885 -0.38103,2.01468 -0.67234,7.15056 -0.64735,11.41306 0.025,4.2625 -0.0435,7.77018 -0.1522,7.79485 -0.1087,0.0247 -2.49663,0.28103 -5.30652,0.56969 -3.79428,0.38978 -5.50321,0.13051 -6.64132,-1.00761 z"
+ id="path3018" />
+ <path
+ style="fill:#fde9e8"
+ d="m 244.07446,834.94634 c 0,-0.58706 -0.83647,-0.8019 -1.85882,-0.47742 -3.38388,1.074 -4.23225,-1.44367 -5.76062,-17.09567 -0.53162,-5.44427 -0.34995,-6.39014 1.60237,-8.34245 1.47838,-1.47838 2.91097,-2.01178 4.35952,-1.62318 1.18665,0.31834 3.62005,0.58495 5.40755,0.59246 3.11458,0.0131 3.25,0.17786 3.25,3.95463 0,2.16754 0.45,4.2191 1,4.55902 0.55,0.33992 1,2.81492 1,5.5 0,2.68508 -0.45,5.16008 -1,5.5 -0.55,0.33992 -1.01497,1.37898 -1.03327,2.30902 -0.0711,3.61539 -6.96673,8.68668 -6.96673,5.12359 z m -22.64106,-0.66363 c -1.91418,-1.29 -4.35894,-11.2719 -4.35894,-17.79747 0,-4.73983 0.46465,-6.70124 2.00946,-8.48242 1.77348,-2.04484 2.28725,-2.16825 4.375,-1.05093 1.76257,0.94331 2.88873,0.986 4.4181,0.16751 1.1289,-0.60417 2.72536,-0.84032 3.54768,-0.52477 1.72841,0.66326 2.91023,3.18863 2.10325,4.49435 -0.30414,0.49212 -0.57989,5.85151 -0.61276,11.90975 -0.0329,6.05825 -0.12298,11.03518 -0.20025,11.05985 -1.91464,0.61129 -10.45528,0.78097 -11.28154,0.22413 z"
+ id="path3016" />
+ <path
+ style="fill:#fce7d8"
+ d="m 244.57446,835.01373 c -0.33992,-0.55 -1.47564,-1 -2.52383,-1 -1.97232,0 -4.2255,-3.08944 -3.83717,-5.26131 0.12181,-0.68128 -0.36745,-3.1064 -1.08723,-5.38916 -1.49453,-4.73979 -0.72255,-12.54794 1.41606,-14.32284 0.76462,-0.63457 3.72517,-1.00206 6.70099,-0.83176 5.29729,0.30313 5.33322,0.32732 5.65248,3.80507 0.17671,1.925 0.73921,3.9275 1.25,4.45 1.2472,1.2758 1.18916,10.271 -0.0713,11.05 -0.55,0.33992 -1.01497,1.37898 -1.03327,2.30902 -0.0389,1.97564 -3.31937,6.19098 -4.81801,6.19098 -0.56688,0 -1.3088,-0.45 -1.64872,-1 z m -22.84924,-1.35207 c -1.97934,-1.56449 -4.65076,-11.41412 -4.65076,-17.14754 0,-6.75939 3.72786,-12.41603 6.42573,-9.75039 0.41749,0.4125 2.62999,0.75 4.91667,0.75 l 4.1576,0 0,12.33739 c 0,6.78557 -0.225,12.68061 -0.5,13.10011 -0.8974,1.36892 -8.82744,1.91328 -10.34924,0.71043 z"
+ id="path3014" />
+ <path
+ style="fill:#fcd8d7"
+ d="m 244.57446,835.01373 c -0.33992,-0.55 -1.46492,-1 -2.5,-1 -2.41107,0 -3.39583,-1.62821 -3.62887,-6 -0.10262,-1.925 -0.64182,-5.23675 -1.19822,-7.35943 -1.16711,-4.45251 -0.49978,-10.1244 1.37416,-11.67963 0.70982,-0.5891 3.68961,-0.93381 6.62175,-0.76601 5.29729,0.30313 5.33322,0.32732 5.65248,3.80507 0.17671,1.925 0.73921,3.9275 1.25,4.45 1.62476,1.66202 0.89746,9.87212 -1.15604,13.05 -1.06621,1.65 -2.2108,3.7875 -2.54354,4.75 -0.66038,1.91026 -2.88796,2.34176 -3.87172,0.75 z m -22.70147,-1.09287 c -2.10735,-1.17933 -5.26736,-16.59451 -4.37589,-21.34647 0.37824,-2.01617 1.33529,-3.91428 2.12679,-4.218 0.7915,-0.30373 1.14285,-1.03155 0.78078,-1.61738 -0.44012,-0.71214 -0.0239,-0.78737 1.25575,-0.22698 1.05272,0.46099 3.93904,0.87497 6.41404,0.91994 l 4.5,0.0818 0,12.33679 c 0,6.78523 -0.225,12.68028 -0.5,13.1001 -0.78115,1.19253 -8.49355,1.92604 -10.20147,0.97024 z"
+ id="path3012" />
+ <path
+ style="fill:#fcd5ca"
+ d="m 242.57446,833.95903 c -3.20603,-2.03958 -4.16764,-5.04031 -5.16057,-16.10371 -0.72246,-8.04973 0.49024,-9.84159 6.66057,-9.84159 5.32878,0 7,1.49636 7,6.26759 0,1.31949 0.3116,2.71067 0.69244,3.09151 2.0309,2.03091 0.53343,11.77013 -2.17427,14.1409 -0.62816,0.55 -1.4376,1.7875 -1.79876,2.75 -0.80647,2.1493 -1.41806,2.11359 -5.21941,-0.3047 z m -21.40349,-1.32901 c -2.16359,-2.60697 -4.21239,-16.47222 -3.06414,-20.73651 0.5746,-2.13388 1.50393,-3.87978 2.06519,-3.87978 0.56126,0 0.74236,-0.45 0.40244,-1 -0.33992,-0.55 -0.16803,-1 0.38197,-1 0.55,0 1.30476,0.49312 1.67725,1.09581 0.42872,0.69369 2.27301,0.85652 5.02583,0.44371 4.00954,-0.60127 4.39578,-0.4641 4.95383,1.75938 0.33289,1.32633 0.17976,5.51416 -0.34028,9.3063 -0.52004,3.79214 -0.71908,8.40715 -0.4423,10.25559 0.33321,2.22535 0.0371,3.65603 -0.87654,4.23468 -2.15612,1.36563 -8.51049,1.05439 -9.78325,-0.47918 z"
+ id="path3010" />
+ <path
+ style="fill:#fcc9c7"
+ d="m 243.68265,834.51799 c -1.0405,-0.78767 -2.33516,-1.57991 -2.87702,-1.76054 -0.54187,-0.18062 -1.41387,-2.55935 -1.93778,-5.28606 -3.0569,-15.90966 -1.92574,-19.54051 5.94911,-19.09566 4.63102,0.2616 4.78408,0.37335 5.7575,4.20337 0.55,2.16405 1.25034,4.38463 1.5563,4.93463 0.93611,1.68273 1.17286,7.75954 0.28091,7.21035 -0.46047,-0.28352 -0.94017,0.89999 -1.06601,2.63002 -0.12585,1.73002 -0.71743,3.30837 -1.31463,3.50744 -0.5972,0.19907 -1.4956,1.43975 -1.99644,2.75706 -1.04556,2.75002 -1.7225,2.88992 -4.35194,0.89939 z m -23.21506,-4.10579 c -0.82765,-1.98085 -1.76416,-7.27639 -2.08112,-11.76788 -0.69109,-9.79271 0.0645,-10.82627 8.1771,-11.18559 6.36395,-0.28187 6.33231,-0.34421 5.34251,10.52779 -0.37691,4.13996 -0.4504,8.95097 -0.16332,10.69111 0.6047,3.66532 -1.47859,5.3361 -6.65359,5.3361 -2.63353,0 -3.35007,-0.55839 -4.62158,-3.60153 z"
+ id="path3008" />
+ <path
+ style="fill:#fcc5ba"
+ d="m 242.82446,833.6902 c -1.61209,-1.31992 -2.76466,-3.27052 -2.78544,-4.71403 -0.0195,-1.35434 -0.67854,-3.58744 -1.46456,-4.96244 -1.78022,-3.11416 -1.88229,-9.68857 -0.20184,-13 1.05742,-2.08371 1.98633,-2.5 5.57849,-2.5 2.3704,0 4.64398,0.225 5.0524,0.5 0.77148,0.51946 4.08252,12.93329 4.05564,15.20552 -0.0109,0.92215 -0.29413,0.86304 -0.98469,-0.20552 -0.72513,-1.12206 -0.97323,-0.59421 -0.98469,2.09501 -0.01,2.31035 -0.73,4.2418 -2.01531,5.40499 -1.1,0.99549 -2,2.41523 -2,3.15499 0,1.87693 -1.06079,1.6327 -4.25,-0.97852 z m -21.53193,-1.30802 c -1.46348,-2.79289 -3.21807,-11.89557 -3.21807,-16.69516 0,-6.48241 1.72588,-8.19989 8.13495,-8.09535 l 5.36505,0.0875 -0.22431,12.30825 c -0.12337,6.76954 -0.4237,12.50765 -0.66741,12.75135 -0.24371,0.24371 -2.23591,0.68357 -4.42712,0.97748 -3.21272,0.43091 -4.17356,0.17264 -4.96309,-1.33408 z"
+ id="path3006" />
+ <path
+ style="fill:#fcc7ab"
+ d="m 242.72748,833.17345 c -1.45916,-1.52303 -2.65302,-3.77287 -2.65302,-4.99962 0,-1.22676 -0.71048,-3.3148 -1.57885,-4.6401 -1.21102,-1.84824 -1.41802,-3.69689 -0.88852,-7.93489 0.8518,-6.81759 1.87668,-7.75237 7.45543,-6.80001 4.33601,0.74022 4.33744,0.74189 6.17057,7.22764 2.11406,7.4797 2.20996,8.3331 0.84137,7.48726 -0.5944,-0.36736 -1,0.81122 -1,2.9058 0,2.50038 -0.58088,3.83471 -2,4.5942 -1.1,0.5887 -2,1.70298 -2,2.47617 0,2.59556 -1.67384,2.47371 -4.34698,-0.31645 z m -21.75005,-1.90972 c -0.57613,-1.5125 -1.56141,-6.27033 -2.18949,-10.57295 -0.9585,-6.56609 -0.90464,-8.24579 0.33523,-10.45476 1.29461,-2.30651 2.12301,-2.6374 6.70205,-2.67705 3.65715,-0.0317 5.39105,0.38694 5.77872,1.39515 0.30463,0.79221 0.24376,6.34107 -0.13525,12.3308 -0.65213,10.306 -0.81885,10.93975 -3.10677,11.80962 -4.21264,1.60164 -6.27144,1.09121 -7.38449,-1.83081 z"
+ id="path3004" />
+ <path
+ style="fill:#fcbab6"
+ d="m 242.72748,833.17345 c -1.45916,-1.52303 -2.65302,-3.78662 -2.65302,-5.03018 0,-1.24356 -0.50847,-3.21112 -1.12994,-4.37234 -1.56807,-2.92996 -1.34949,-12.70635 0.32145,-14.37728 0.98111,-0.98111 2.56078,-1.1472 5.74345,-0.60388 l 4.39011,0.74945 1.83356,6.48725 c 2.11406,7.4797 2.20996,8.3331 0.84137,7.48726 -0.5944,-0.36736 -1,0.81122 -1,2.9058 0,2.50038 -0.58088,3.83471 -2,4.5942 -1.1,0.5887 -2,1.70298 -2,2.47617 0,2.59556 -1.67384,2.47371 -4.34698,-0.31645 z m -21.16934,-0.40972 c -1.00952,-2.78225 -3.48368,-16.06654 -3.48368,-18.70459 0,-1.55311 0.81514,-3.8305 1.81143,-5.06086 1.59417,-1.96872 2.06504,-2.07864 3.92591,-0.91651 1.63188,1.01913 2.68278,1.06157 4.6045,0.18598 3.50792,-1.59832 3.87749,-0.0223 3.05239,13.01717 -0.65213,10.306 -0.81885,10.93975 -3.10677,11.80962 -3.38037,1.28521 -6.26837,1.14479 -6.80378,-0.33081 z"
+ id="path3002" />
+ <path
+ style="fill:#fbb5a7"
+ d="m 242.73813,833.03845 c -4.45265,-4.50136 -6.26388,-22.81295 -2.40301,-24.2945 0.70285,-0.26971 3.01297,-0.20685 5.1336,0.1397 3.80086,0.62112 3.88065,0.72606 5.61127,7.38008 1.5237,5.8584 1.55892,6.75 0.26662,6.75 -1.07585,0 -1.32041,0.67158 -0.88145,2.42054 0.75665,3.01474 -0.16163,5.57946 -1.99769,5.57946 -0.76616,0 -1.39301,0.9 -1.39301,2 0,2.47359 -1.90323,2.48443 -4.33633,0.0247 z m -20.53807,-0.37338 c -1.73818,-2.09438 -4.37739,-16.49565 -3.69229,-20.14755 0.79299,-4.22701 2.99091,-6.22653 5.00602,-4.55414 0.79163,0.657 2.92913,1.0496 4.75,0.87244 l 3.31067,-0.32209 -0.34477,11 c -0.20547,6.55563 -0.81152,11.45488 -1.5,12.12585 -1.93738,1.8881 -6.31852,2.48479 -7.52963,1.02549 z"
+ id="path3000" />
+ <path
+ style="fill:#fac58e"
+ d="m 242.74941,832.85535 c -1.00378,-1.09545 -2.07693,-3.54387 -2.38478,-5.44095 -0.30786,-1.89708 -0.94908,-3.68987 -1.42495,-3.98397 -0.98296,-0.6075 -1.18061,-10.43123 -0.25823,-12.83491 0.43906,-1.14417 1.9607,-1.58179 5.5,-1.58179 2.69115,0 4.89301,0.11393 4.89301,0.25318 0,0.13925 0.87979,3.32964 1.95508,7.08976 1.63533,5.71845 1.7122,6.74336 0.47002,6.26669 -1.16731,-0.44794 -1.43336,0.19801 -1.24339,3.01886 0.1645,2.4426 -0.30498,3.98848 -1.47001,4.84037 -0.94143,0.68839 -1.7117,1.98952 -1.7117,2.89138 0,2.18799 -2.07266,1.93946 -4.32505,-0.51862 z m -20.55781,-0.20048 c -1.4948,-1.80112 -3.11714,-10.71274 -3.11714,-17.12264 0,-3.84785 0.49654,-5.65789 1.90072,-6.92866 1.33134,-1.20484 2.1105,-1.38071 2.60099,-0.58707 0.38515,0.62319 2.34233,0.99695 4.34928,0.83059 l 3.64901,-0.30248 -0.34477,10.98456 c -0.20539,6.54387 -0.81179,11.4397 -1.5,12.11041 -1.94466,1.8952 -6.31888,2.48436 -7.53809,1.01529 z"
+ id="path2998" />
+ <path
+ style="fill:#fbaaa7"
+ d="m 242.83096,832.93689 c -2.94316,-3.22449 -5.60815,-16.3938 -4.34,-21.4465 0.5574,-2.22086 1.13605,-2.47666 5.60255,-2.47666 2.73952,0 4.98095,0.11393 4.98095,0.25318 0,0.13925 0.87979,3.32964 1.95508,7.08976 1.63533,5.71845 1.7122,6.74336 0.47002,6.26669 -1.16731,-0.44794 -1.43336,0.19801 -1.24339,3.01886 0.1645,2.4426 -0.30498,3.98848 -1.47001,4.84037 -0.94143,0.68839 -1.7117,1.98952 -1.7117,2.89138 0,2.1614 -2.06598,1.94861 -4.2435,-0.43708 z m -20.63936,-0.28202 c -1.47885,-1.7819 -3.11714,-10.68981 -3.11714,-16.94889 0,-6.60802 1.99523,-9.09493 5.73865,-7.15281 1.76179,0.91402 3.1716,1.04377 4.37036,0.40222 1.04167,-0.55749 1.99888,-0.57611 2.32696,-0.0453 0.95894,1.55161 -0.68277,22.06632 -1.83817,22.9696 -2.18264,1.70635 -6.3495,2.13812 -7.48066,0.77515 z"
+ id="path2996" />
+ <path
+ style="fill:#fbb49a"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.0515,-6.01599 1.33352,-7.68426 6.37947,-7.68426 l 4.34174,0 1.57906,6.25 c 0.93854,3.71477 1.19128,6.38521 0.62307,6.58333 -0.52579,0.18334 -0.95599,2.08 -0.95599,4.21482 0,2.90633 -0.52195,4.16082 -2.07756,4.99336 -1.18986,0.63679 -1.84419,1.72003 -1.53138,2.53518 0.75202,1.95974 -0.51507,1.68385 -2.78464,-0.60632 z m -22.50743,-2.65246 c -0.67213,-1.47516 -1.48641,-6.42813 -1.80952,-11.00662 -0.50391,-7.14044 -0.33132,-8.60756 1.21332,-10.31438 1.398,-1.54476 2.11011,-1.73314 3.18364,-0.84218 0.76057,0.63121 2.7832,1.10784 4.49474,1.05918 l 3.1119,-0.0885 -0.67703,11.14712 c -0.71175,11.71885 -1.14547,12.68517 -5.70553,12.71214 -1.84671,0.0109 -2.94001,-0.75403 -3.81152,-2.66678 z"
+ id="path2994" />
+ <path
+ style="fill:#facb7b"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.052,-6.07612 1.23838,-7.55975 6.40123,-7.35994 l 4.44502,0.17203 1.51654,6.00183 c 0.90536,3.58303 1.13127,6.13616 0.56055,6.33515 -0.52579,0.18334 -0.95599,1.98759 -0.95599,4.00946 0,2.64232 -0.58597,4.04206 -2.08368,4.9774 -1.18202,0.73818 -1.84469,1.92409 -1.53139,2.74055 0.75759,1.97424 -0.50224,1.70656 -2.77851,-0.59037 z m -22.4942,-3.07829 c -0.59588,-1.70936 -1.38003,-6.66446 -1.74254,-11.01134 -0.56917,-6.82476 -0.41058,-8.17807 1.16197,-9.91572 1.22799,-1.3569 2.04728,-1.64633 2.51555,-0.88865 0.38194,0.61799 2.39249,1.12363 4.46789,1.12363 l 3.77345,0 -0.67477,11.10983 c -0.71119,11.70969 -1.1381,12.64814 -5.76595,12.67486 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z"
+ id="path2992" />
+ <path
+ style="fill:#fba597"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.052,-6.07612 1.23838,-7.55975 6.40123,-7.35994 l 4.44502,0.17203 1.51654,6.00183 c 0.90536,3.58303 1.13127,6.13616 0.56055,6.33515 -0.52579,0.18334 -0.95599,1.98759 -0.95599,4.00946 0,2.64232 -0.58597,4.04206 -2.08368,4.9774 -1.18202,0.73818 -1.84469,1.92409 -1.53139,2.74055 0.75759,1.97424 -0.50224,1.70656 -2.77851,-0.59037 z m -22.4942,-3.07829 c -0.59588,-1.70936 -1.38003,-6.66446 -1.74254,-11.01134 -0.56214,-6.74048 -0.40015,-8.18959 1.10089,-9.84822 1.56882,-1.73353 1.92387,-1.78093 3.26843,-0.43637 1.04108,1.04107 2.4483,1.30199 4.54198,0.84214 l 3.03355,-0.66628 -0.68776,11.32382 c -0.72485,11.93451 -1.14074,12.86208 -5.77895,12.88886 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z"
+ id="path2990" />
+ <path
+ style="fill:#fba78a"
+ d="m 221.18668,829.90581 c -1.93432,-5.5488 -2.47791,-18.15014 -0.87433,-20.26869 1.20398,-1.59064 1.76544,-1.69198 3.68442,-0.66497 1.24518,0.6664 3.41269,0.92333 4.81668,0.57095 l 2.55271,-0.64069 -0.71434,11.28897 c -0.75006,11.85366 -1.16479,12.78068 -5.72954,12.80704 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z m 22.21513,2.33139 c -3.55171,-2.25917 -6.28879,-19.66203 -3.5268,-22.42402 0.48123,-0.48123 2.70741,-0.58195 4.94705,-0.22382 3.78933,0.60594 4.14652,0.9468 5.14421,4.90901 0.58968,2.34182 1.38173,5.06461 1.76011,6.05065 0.44754,1.16629 0.30896,1.55857 -0.39657,1.12252 -1.47691,-0.91278 -2.08921,1.1788 -1.49071,5.09219 0.39191,2.56254 0.14544,3.25 -1.16518,3.25 -0.91423,0 -1.92125,0.675 -2.23783,1.5 -0.64031,1.66861 -1.30082,1.8261 -3.03428,0.72347 z"
+ id="path2988" />
+ <path
+ style="fill:#fb9996"
+ d="m 221.30293,829.26373 c -1.57713,-5.43533 -2.5527,-14.82202 -1.8369,-17.67401 0.57224,-2.27998 1.02934,-2.44619 6.23753,-2.26813 l 5.62004,0.19214 -0.69305,10.98331 c -0.72599,11.50515 -1.16409,12.47489 -5.6478,12.50138 -2.13974,0.0126 -2.78147,-0.63866 -3.67982,-3.73469 z m 22.11621,2.98418 c -0.63543,-0.40435 -2.10648,-3.55865 -3.26901,-7.00955 -2.51688,-7.47126 -1.88001,-15.78981 1.1975,-15.6413 7.7497,0.37399 7.4344,0.19825 8.59009,4.78792 0.60538,2.40418 1.41028,5.178 1.78866,6.16404 0.45172,1.17717 0.31093,1.55979 -0.40999,1.11423 -1.36162,-0.84153 -2.51515,2.47491 -1.64738,4.73629 0.41694,1.08651 -0.29,2.52937 -2.02884,4.14088 -3.03005,2.80815 -2.70074,2.67493 -4.22103,1.70749 z"
+ id="path2986" />
+ <path
+ style="fill:#fa9787"
+ d="m 221.62624,829.7919 c -1.76556,-4.22558 -2.98504,-17.79554 -1.75988,-19.58342 0.65198,-0.95144 2.30216,-1.1185 6.08784,-0.61632 l 5.19341,0.68894 -0.65991,10.11631 c -0.36295,5.56398 -0.94191,10.42198 -1.28657,10.79556 -0.34467,0.37358 -1.8665,0.98545 -3.38186,1.35971 -2.45245,0.6057 -2.91317,0.30235 -4.19303,-2.76078 z m 21.62804,1.93428 c -2.58899,-3.13045 -5.1869,-12.32814 -4.60314,-16.29701 0.86081,-5.85235 1.39869,-6.36256 6.04992,-5.7387 3.90839,0.52423 4.13392,0.74924 5.13477,5.12293 0.64943,2.83802 0.70299,5.47897 0.14109,6.95688 -0.49815,1.31023 -0.65676,3.37421 -0.35247,4.58662 0.70357,2.80324 -4.71508,7.37051 -6.37017,5.36928 z"
+ id="path2984" />
+ <path
+ style="fill:#faa96f"
+ d="m 222.27764,831.35152 c -0.52864,-1.01079 -1.5183,-5.81903 -2.19925,-10.68499 -1.52422,-10.89173 -0.88679,-12.00968 6.28694,-11.02641 l 4.70142,0.6444 -0.62383,10.11461 c -0.34312,5.56303 -0.90388,10.42026 -1.24615,10.79384 -0.34227,0.37358 -1.82284,0.97558 -3.29015,1.33778 -2.01233,0.49674 -2.90399,0.207 -3.62898,-1.17923 z m 20.13064,-1.08779 c -0.33188,-0.9625 -1.39356,-3.6085 -2.3593,-5.88 -1.89406,-4.45498 -1.65955,-12.55659 0.41327,-14.27687 0.62221,-0.51639 2.67297,-0.62358 4.55724,-0.23821 4.18109,0.85513 5.13433,3.53546 4.65376,13.08549 -0.25668,5.10092 -0.69352,6.63149 -1.96444,6.88291 -0.89889,0.17783 -1.63435,0.74033 -1.63435,1.25 0,1.65938 -3.04599,0.97533 -3.66618,-0.82332 z"
+ id="path2982" />
+ <path
+ style="fill:#fa947a"
+ d="m 222.27764,831.35152 c -0.52864,-1.01079 -1.51335,-5.78416 -2.18825,-10.6075 -1.41648,-10.12316 -0.61986,-12.39505 3.91087,-11.1534 1.41581,0.388 3.58864,0.64681 4.82851,0.57513 2.2392,-0.12946 2.25007,-0.0617 1.62231,10.10883 -0.3476,5.63153 -0.91204,10.54481 -1.25431,10.91839 -0.34227,0.37358 -1.82284,0.97558 -3.29015,1.33778 -2.01233,0.49674 -2.90399,0.207 -3.62898,-1.17923 z m 20.10725,-1.08779 c -0.34474,-0.9625 -1.38391,-3.775 -2.30926,-6.25 -2.75945,-7.3806 -0.64783,-16.8259 3.20502,-14.33609 0.7116,0.45985 2.15925,0.83609 3.21701,0.83609 2.55245,0 3.59591,4.08776 3.17559,12.44041 -0.25668,5.10092 -0.69352,6.63149 -1.96444,6.88291 -0.89889,0.17783 -1.63435,0.74033 -1.63435,1.25 0,1.6564 -3.04476,0.97696 -3.68957,-0.82332 z"
+ id="path2980" />
+ <path
+ style="fill:#fa8884"
+ d="m 222.66421,832.15894 c -0.34565,-0.55926 -1.25123,-5.2066 -2.01241,-10.32743 -1.61694,-10.87789 -0.9927,-13.23232 3.21267,-12.11721 1.49049,0.39522 3.72162,0.67194 4.95807,0.61492 2.22878,-0.10279 2.24271,-0.0166 1.62231,10.04042 -0.34418,5.57925 -0.90581,10.44975 -1.24808,10.82333 -1.17568,1.28323 -5.90434,1.98246 -6.53256,0.96597 z m 19.89554,-1.39521 c -2.76058,-7.63527 -3.48529,-10.70299 -3.48529,-14.75328 0,-4.50991 1.80223,-7.86115 3.3794,-6.28399 0.38246,0.38246 1.88374,0.71606 3.33618,0.74133 2.06745,0.036 2.81953,0.69727 3.46406,3.04594 1.25136,4.56001 -0.12178,14.69032 -2.27042,16.75 -2.14711,2.05821 -3.79329,2.24426 -4.42393,0.5 z"
+ id="path2978" />
+ <path
+ style="fill:#f9af50"
+ d="m 222.50927,830.90824 c -0.37578,-0.60801 -1.25786,-4.99551 -1.96017,-9.75 -1.47709,-9.99943 -0.80155,-12.51565 3.09742,-11.53707 1.37063,0.34401 3.26513,0.68556 4.21,0.75901 0.94487,0.0734 1.99019,0.58355 2.32295,1.13355 0.69333,1.14599 -0.70968,18.05133 -1.62042,19.52494 -0.82187,1.32981 -5.20572,1.2353 -6.04978,-0.13043 z m 18.63704,-4.43202 c -3.37032,-9.00798 -2.33409,-18.74357 1.7617,-16.55157 0.96226,0.51498 2.58779,0.85821 3.61229,0.76271 2.58412,-0.24087 3.68815,4.3302 2.91039,12.05008 -0.50552,5.01758 -1.07846,6.51949 -2.95645,7.75 -1.28118,0.83946 -2.53791,1.52629 -2.79275,1.52629 -0.25483,0 -1.39566,-2.49188 -2.53518,-5.53751 z"
+ id="path2976" />
+ <path
+ style="fill:#fa8678"
+ d="m 222.14477,829.69866 c -0.4841,-1.27328 -1.18483,-4.98578 -1.55716,-8.25 -0.37234,-3.26421 -0.86723,-6.63354 -1.09975,-7.48739 -0.23253,-0.85385 0.17932,-2.37587 0.91522,-3.38227 1.27959,-1.74995 1.45462,-1.75341 4.00969,-0.0793 2.04558,1.34032 2.99469,1.48251 4.04991,0.60676 1.0452,-0.86744 1.4888,-0.83562 1.83589,0.13171 0.56835,1.58395 -0.91478,18.466 -1.73952,19.80046 -1.20642,1.95202 -5.504,1.05422 -6.41428,-1.34001 z m 19.00154,-3.22244 c -3.37032,-9.00798 -2.33409,-18.74357 1.7617,-16.55157 0.96226,0.51498 2.58779,0.85821 3.61229,0.76271 2.58412,-0.24087 3.68815,4.3302 2.91039,12.05008 -0.50552,5.01758 -1.07846,6.51949 -2.95645,7.75 -1.28118,0.83946 -2.53791,1.52629 -2.79275,1.52629 -0.25483,0 -1.39566,-2.49188 -2.53518,-5.53751 z"
+ id="path2974" />
+ <path
+ style="fill:#fa7974"
+ d="m 222.13455,829.67178 c -0.51748,-1.36109 -1.24958,-6.27925 -1.62688,-10.92925 -0.75781,-9.33961 -0.0511,-10.83501 3.89764,-8.24767 1.31304,0.86033 3.12575,1.28089 4.02824,0.93457 1.41077,-0.54137 1.63051,0.19177 1.56679,5.22731 -0.0408,3.22135 -0.37827,7.88199 -0.75,10.35699 -0.59575,3.9665 -1.00185,4.53751 -3.4254,4.81638 -2.15645,0.24813 -2.95245,-0.21741 -3.69039,-2.15833 z m 21.21124,1.06386 c -2.61671,-3.44941 -4.3414,-10.713 -3.69705,-15.5703 l 0.66804,-5.03598 3.89064,0.15515 c 3.48771,0.13908 3.98352,0.49155 4.78753,3.40341 0.49328,1.78655 0.66045,5.85322 0.37148,9.03704 -0.40707,4.485 -1.03985,6.17659 -2.80956,7.51068 -1.75742,1.32483 -2.4979,1.44013 -3.21108,0.5 z"
+ id="path2972" />
+ <path
+ style="fill:#f9836a"
+ d="m 223.91904,831.34262 c -2.03067,-0.53865 -2.56772,-2.56289 -3.43265,-12.93826 -0.749,-8.98473 -0.007,-10.48197 3.91892,-7.9095 1.31304,0.86033 3.09178,1.29392 3.95275,0.96354 1.37808,-0.52882 1.49697,0.57546 0.99348,9.22731 -0.31462,5.40631 -1.068,10.15856 -1.67451,10.56271 -1.16693,0.77757 -1.18043,0.77791 -3.75799,0.0942 z m 17.21699,-5.67718 c -1.71683,-4.23001 -2.02942,-6.41337 -1.49498,-10.44218 l 0.67573,-5.0939 3.89064,0.15515 c 3.50313,0.13969 3.98164,0.48472 4.80431,3.46421 1.26724,4.58956 0.12422,14.46961 -1.84909,15.98321 -2.76378,2.11992 -3.79932,1.42118 -6.02661,-4.06649 z"
+ id="path2970" />
+ <path
+ style="fill:#f97967"
+ d="m 223.64739,830.4438 c -1.85627,-1.85626 -2.25977,-3.57781 -3.06787,-13.08917 -0.68033,-8.00745 0.0825,-9.31245 3.95897,-6.77251 1.38629,0.90833 3.16123,1.40565 3.94431,1.10516 1.19438,-0.45833 1.33299,1.01428 0.86029,9.14005 -0.63404,10.89904 -2.03975,13.27242 -5.6957,9.61647 z m 17.53808,-4.86292 c -1.53151,-4.09332 -1.88195,-6.70559 -1.42132,-10.59489 0.60375,-5.09769 0.64846,-5.15463 3.58584,-4.56715 1.63596,0.32719 3.31348,0.59489 3.72783,0.59489 1.25296,0 2.66967,7.32604 1.9338,10 -0.3784,1.375 -0.4645,3.5355 -0.19134,4.80111 0.49734,2.30428 -1.8953,5.09883 -4.42397,5.16709 -0.64798,0.0175 -2.09286,-2.41298 -3.21084,-5.40105 z"
+ id="path2968" />
+ <path
+ style="fill:#f88c4e"
+ d="m 223.11077,829.55749 c -1.55452,-1.8731 -3.30507,-17.675 -2.09239,-18.88768 0.47651,-0.47651 2.47171,-0.27364 4.49143,0.4567 l 3.63405,1.31409 -0.2847,9.03657 c -0.26128,8.29308 -0.45645,9.0611 -2.37221,9.33482 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.08259,-4.70911 -2.34897,-6.354 -1.66736,-10.29583 0.79337,-4.58811 0.88601,-4.68516 4.21056,-4.41078 1.86963,0.15431 3.64809,0.52919 3.95212,0.83307 0.30403,0.30389 0.58197,4.11797 0.61765,8.47574 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ id="path2966" />
+ <path
+ style="fill:#f8a534"
+ d="m 223.11077,829.55749 c -1.62629,-1.95957 -3.30118,-17.67889 -2.02017,-18.9599 0.57281,-0.57281 1.89956,-0.48767 3.45673,0.22183 1.81036,0.82485 2.53147,1.9375 2.54244,3.92287 0.0121,2.18024 0.22786,2.45146 1.0117,1.27144 0.69439,-1.04537 0.91707,0.92469 0.73469,6.5 -0.23718,7.25032 -0.45732,8.02795 -2.34921,8.29826 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.07784,-4.69837 -2.34887,-6.36299 -1.67637,-10.29583 0.79068,-4.62392 0.85194,-4.68641 4.26334,-4.34864 1.90362,0.18848 3.68613,0.56336 3.96113,0.83307 0.275,0.26971 0.52919,4.05583 0.56487,8.4136 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ id="path2964" />
+ <path
+ style="fill:#f97659"
+ d="m 223.11077,829.55749 c -1.31835,-1.58852 -3.34677,-17.23242 -2.42729,-18.72016 1.14947,-1.85987 3.52557,-0.60922 5.09488,2.68167 1.16822,2.44977 1.91966,3.12729 2.49552,2.25 0.45778,-0.69739 0.70767,2.30017 0.56228,6.74473 -0.23718,7.25032 -0.45732,8.02795 -2.34921,8.29826 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.07784,-4.69837 -2.34887,-6.36299 -1.67637,-10.29583 0.79068,-4.62392 0.85194,-4.68641 4.26334,-4.34864 1.90362,0.18848 3.68613,0.56336 3.96113,0.83307 0.275,0.26971 0.52919,4.05583 0.56487,8.4136 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ id="path2962" />
+ <path
+ style="fill:#f89936"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -0.56031,-0.68049 -0.75752,-1.91799 -0.43825,-2.75 1.07196,-2.79347 3.45238,-1.54832 6.10157,3.1916 2.12264,3.79781 2.57269,5.77112 2.3355,10.24028 -0.23013,4.33611 -0.6731,5.60814 -2.04381,5.869 -1.04668,0.19919 -1.75,-0.27931 -1.75,-1.1906 z m 16.96387,-2.97179 c -2.15555,-4.87296 -2.22449,-5.36902 -1.68889,-12.15122 0.29872,-3.78258 0.47649,-3.98174 3.27046,-3.66399 4.42198,0.5029 4.9771,1.61488 4.71073,9.43636 -0.19008,5.58139 -0.67966,7.59556 -2.22083,9.13674 -1.96934,1.96933 -1.98513,1.95864 -4.07147,-2.75789 z"
+ id="path2960" />
+ <path
+ style="fill:#f88838"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -0.56031,-0.68049 -0.75752,-1.91799 -0.43825,-2.75 0.93035,-2.42444 3.58582,-1.74814 4.85806,1.23727 0.64456,1.5125 1.78388,3.48691 2.53182,4.38759 2.0861,2.51209 1.30446,13.2381 -0.99662,13.67602 -1.04668,0.19919 -1.75,-0.27931 -1.75,-1.1906 z m 16.9435,-3.01782 c -2.14558,-4.85044 -2.22191,-5.41701 -1.631,-12.10519 0.25271,-2.86028 0.75717,-3.88974 1.77045,-3.61301 0.77938,0.21284 2.27824,0.47228 3.33081,0.57652 2.70391,0.2678 3.64683,3.66342 2.92774,10.5433 -0.40811,3.9046 -1.25402,6.50903 -2.47214,7.61142 -1.76446,1.59681 -1.94952,1.45478 -3.92586,-3.01304 z m 4.0565,-8.54617 c 0,-1.06754 -0.45,-2.2191 -1,-2.55902 -0.56716,-0.35052 -1,0.48962 -1,1.94098 0,1.40746 0.45,2.55902 1,2.55902 0.55,0 1,-0.87344 1,-1.94098 z"
+ id="path2958" />
+ <path
+ style="fill:#f96857"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -1.31597,-1.59824 -0.29183,-4.26273 1.63844,-4.26273 1.76019,0 3.56657,3.00556 3.56657,5.93426 0,1.13616 0.5625,1.95324 1.25,1.81574 0.89722,-0.17944 1.25,1.58059 1.25,6.23631 0,5.38237 -0.29784,6.54366 -1.75,6.82332 -1.04842,0.20191 -1.75,-0.27381 -1.75,-1.18662 z m 16.9435,-3.01782 c -1.14075,-2.57888 -2.05392,-5.45754 -2.02925,-6.39703 0.0442,-1.68363 0.77833,-9.28228 0.98141,-10.15816 0.0574,-0.2475 0.64434,0.09 1.30434,0.75 0.66,0.66 2.18252,1.2 3.38337,1.2 2.79309,0 3.52113,2.70677 2.73949,10.1851 -0.39145,3.74518 -1.24893,6.343 -2.4535,7.43313 -1.76446,1.59681 -1.94952,1.45478 -3.92586,-3.01304 z m 4.0565,-7.98275 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ id="path2956" />
+ <path
+ style="fill:#f97448"
+ d="m 224.43035,828.2706 c -2.66558,-3.61935 -4.17153,-18.25687 -1.87832,-18.25687 1.73553,0 3.52243,3.04033 3.52243,5.99328 0,1.16861 0.45,1.84664 1,1.50672 0.58985,-0.36455 1.07513,0.94423 1.18318,3.19098 0.45481,9.45699 -0.72168,11.78271 -3.82729,7.56589 z m 17.31261,-3.28329 c -1.95628,-4.43272 -2.12466,-5.73743 -1.23521,-9.57109 0.71036,-3.06172 1.44872,-4.27801 2.38006,-3.92062 0.74262,0.28497 2.16094,0.51813 3.15181,0.51813 2.38322,0 3.09675,3.11426 2.35015,10.25737 -0.44715,4.27809 -1.11132,6.09827 -2.49554,6.83908 -1.64554,0.88067 -2.17523,0.3546 -4.15127,-4.12287 z m 4.3315,-6.35114 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ id="path2954" />
+ <path
+ style="fill:#f89426"
+ d="m 224.43035,828.2706 c -2.17337,-2.95101 -4.19764,-18.25687 -2.41456,-18.25687 1.73198,0 4.05867,3.14613 4.05867,5.4881 0,1.28988 0.46287,2.49952 1.0286,2.6881 1.39017,0.46339 1.74167,10.4523 0.41453,11.78012 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.71778,0 0.90684,-1.09078 0.52231,-3.01345 -0.57326,-2.86632 -0.46951,-2.98163 2.125,-2.36174 4.2138,1.00677 4.22769,1.03602 4.22769,8.89902 0,6.41491 -0.27118,7.55093 -2.02673,8.49048 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z m 4.00477,-7.17705 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ id="path2952" />
+ <path
+ style="fill:#f8862a"
+ d="m 224.43035,828.2706 c -1.42701,-1.9376 -2.22355,-5.05998 -2.68038,-10.50687 -0.3575,-4.2625 -0.29574,-7.75 0.13724,-7.75 1.38039,0 3.18725,2.3405 3.18725,4.12857 0,0.95072 0.69195,2.42052 1.53766,3.26624 1.80711,1.8071 2.46952,10.99666 0.90547,12.56151 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.72319,0 0.90496,-1.1002 0.50893,-3.08036 -0.44279,-2.21392 -0.26699,-2.96256 0.625,-2.66159 0.8199,0.27666 1.12566,2.00073 0.901,5.08036 -0.27261,3.73691 -0.0247,4.66159 1.25,4.66159 1.22091,0 1.59007,-1.05845 1.59007,-4.55902 0,-2.7847 0.38919,-4.31848 1,-3.94098 0.55,0.33992 1,3.95064 1,8.02383 0,6.41491 -0.27118,7.55093 -2.02673,8.49048 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ id="path2950" />
+ <path
+ style="fill:#f87638"
+ d="m 224.43035,828.2706 c -2.45647,-3.33541 -4.24951,-18.71542 -2.10001,-18.01314 0.68426,0.22357 1.72913,1.87324 2.32193,3.66594 0.5928,1.7927 1.61953,3.59426 2.28162,4.00346 1.52494,0.94246 1.99455,10.63162 0.5837,12.04319 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.71667,0 0.90722,-1.08889 0.525,-3 -0.33846,-1.69231 -0.175,-3 0.375,-3 0.53625,0 0.975,2.25 0.975,5 0,3.74919 0.37048,5 1.48095,5 0.81452,0 1.697,-1.0125 1.96106,-2.25 0.26407,-1.2375 0.67044,-3.15 0.90305,-4.25 0.23262,-1.1 0.47514,1.47167 0.53894,5.71482 0.10212,6.79156 -0.12655,7.84462 -1.91073,8.79949 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ id="path2948" />
+ <path
+ style="fill:#f86647"
+ d="m 224.43035,828.2706 c -2.4567,-3.33573 -4.24905,-18.71274 -2.10001,-18.01662 0.68426,0.22166 1.84937,2.28342 2.58911,4.58169 0.73974,2.29827 1.75224,3.92698 2.25,3.61935 1.53952,-0.95147 1.67063,10.19309 0.13795,11.72577 -0.46567,0.46567 -1.76034,-0.39392 -2.87705,-1.91019 z m 17.63934,-2.45738 c -2.06208,-4.54357 -2.59586,-8.79949 -1.10364,-8.79949 0.49038,0 1.17395,1.125 1.51905,2.5 0.67619,2.69414 2.46533,3.22403 4.38936,1.3 0.93333,-0.93333 1.2,-0.27448 1.2,2.96482 0,3.15967 -0.48914,4.42659 -2.02673,5.24949 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ id="path2946" />
+ <path
+ style="fill:#f85b47"
+ d="m 225.53957,828.73073 c -0.35508,-1.41476 -1.27715,-2.81463 -2.04903,-3.11083 -0.96655,-0.3709 -1.35554,-2.02774 -1.24959,-5.32236 0.0846,-2.63109 -0.19572,-5.79631 -0.62296,-7.03381 -0.59332,-1.71857 -0.39946,-2.25 0.82079,-2.25 0.92147,0 1.86759,1.16381 2.23559,2.75 0.35092,1.5125 1.31914,3.83771 2.15162,5.16714 1.83737,2.93418 2.15539,9.57594 0.53605,11.19528 -0.90249,0.90249 -1.32739,0.57716 -1.82247,-1.39542 z m 17.11275,-1.8764 c -2.21367,-5.29808 -2.8383,-8.5616 -1.76556,-9.2246 0.53589,-0.3312 1.25593,0.51971 1.60008,1.89091 0.65349,2.60373 2.45562,3.22509 4.22421,1.4565 0.71546,-0.71546 1.07635,0.0209 1.16492,2.37676 0.0842,2.23955 -0.54396,4.02176 -1.82663,5.18256 -1.8947,1.71468 -1.9994,1.66283 -3.39702,-1.68213 z"
+ id="path2944" />
+ <path
+ style="fill:#f86639"
+ d="m 224.83638,826.76373 c -0.80746,-1.2375 -1.70473,-4.5 -1.99393,-7.25 -0.2892,-2.75 -0.85346,-5.7875 -1.2539,-6.75 -0.50617,-1.21664 -0.26667,-1.75 0.7858,-1.75 0.99121,0 2.23649,2.30222 3.60698,6.66841 3.1106,9.90994 2.50902,14.68163 -1.14495,9.08159 z m 17.16288,-2.42544 c -1.10227,-2.57149 -1.70889,-5.38399 -1.34804,-6.25 0.50685,-1.2164 0.87603,-0.94902 1.623,1.17544 1.03757,2.95098 2.66105,3.48919 4.61899,1.53125 0.95833,-0.95833 1.08942,-0.47756 0.61347,2.25 -1.33435,7.64681 -2.65142,7.9561 -5.50742,1.29331 z"
+ id="path2942" />
+ <path
+ style="fill:#f7781d"
+ d="m 224.68947,826.54891 c -0.9401,-1.43477 -1.61501,-4.54435 -1.61501,-7.44098 0,-2.73689 -0.45,-5.25428 -1,-5.5942 -1.49608,-0.92463 -1.20529,-2.5 0.46146,-2.5 0.88442,0 1.88498,1.67803 2.53414,4.25 0.58998,2.3375 1.50732,5.28367 2.03854,6.54705 1.2092,2.87578 1.25778,7.20295 0.0809,7.20295 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z m 17.87076,-0.91499 c -1.85558,-4.44103 -1.92346,-6.60102 -0.13038,-4.14884 0.85716,1.17224 1.98303,1.61276 3.06282,1.19841 1.42177,-0.54558 1.65509,-0.12558 1.39461,2.51051 -0.4403,4.4558 -2.5591,4.67122 -4.32705,0.43992 z"
+ id="path2940" />
+ <path
+ style="fill:#f85737"
+ d="m 224.68947,826.54891 c -0.9401,-1.43477 -1.61501,-4.54435 -1.61501,-7.44098 0,-2.73689 -0.45,-5.25428 -1,-5.5942 -1.51136,-0.93407 -1.19817,-2.5 0.5,-2.5 1.04762,0 1.5,1.05556 1.5,3.5 0,1.925 0.3596,3.5 0.79911,3.5 1.02848,0 3.20089,5.98672 3.20089,8.821 0,2.87849 -1.38847,2.76125 -3.38499,-0.28582 z m 17.87076,-0.91499 c -1.85558,-4.44103 -1.92346,-6.60102 -0.13038,-4.14884 0.85716,1.17224 1.98303,1.61276 3.06282,1.19841 1.42177,-0.54558 1.65509,-0.12558 1.39461,2.51051 -0.4403,4.4558 -2.5591,4.67122 -4.32705,0.43992 z"
+ id="path2938" />
+ <path
+ style="fill:#f76727"
+ d="m 224.89116,825.23793 c -1.761,-3.89609 -2.71911,-12.65513 -1.5159,-13.85834 0.38456,-0.38455 0.6992,0.95081 0.6992,2.96747 0,2.01667 0.45,3.66667 1,3.66667 0.55,0 1,1.09844 1,2.44098 0,1.34254 0.45,2.7191 1,3.05902 1.15423,0.71335 1.37341,5.51284 0.25,5.4742 -0.4125,-0.0142 -1.50749,-1.70169 -2.4333,-3.75 z m 18.34208,1.70574 c -0.76367,-2.0394 -0.56828,-2.51979 1.21566,-2.98899 2.66619,-0.70124 3.43951,1.67367 1.25599,3.85719 -1.41566,1.41566 -1.64686,1.33445 -2.47165,-0.8682 z"
+ id="path2936" />
+ <path
+ style="fill:#f84b34"
+ d="m 224.82446,825.16032 c -1.95208,-4.24082 -2.20733,-6.14659 -0.82324,-6.14659 1.19752,0 4.07324,5.75648 4.07324,8.15364 0,2.94344 -1.35701,2.10541 -3.25,-2.00705 z m 18.40878,1.78335 c -0.76367,-2.0394 -0.56828,-2.51979 1.21566,-2.98899 2.66619,-0.70124 3.43951,1.67367 1.25599,3.85719 -1.41566,1.41566 -1.64686,1.33445 -2.47165,-0.8682 z"
+ id="path2934" />
+ <path
+ style="fill:#f75529"
+ d="m 224.82446,824.64094 c -2.00235,-4.2279 -2.1827,-5.62721 -0.72525,-5.62721 1.33504,0 3.14946,4.81045 2.77063,7.34559 -0.23097,1.54565 -0.67698,1.17095 -2.04538,-1.71838 z m 18.73475,2.34812 c -0.40754,-0.65942 -0.12083,-1.58421 0.63713,-2.05509 1.66304,-1.03315 2.55953,0.79835 1.10349,2.25439 -0.66618,0.66618 -1.24681,0.59969 -1.74062,-0.1993 z"
+ id="path2932" />
+ <path
+ style="fill:#f8472b"
+ d="m 226.15341,826.59706 c -0.0434,-1.05416 0.19292,-1.64479 0.52522,-1.3125 0.33229,0.33229 0.36781,1.1948 0.0789,1.91667 -0.31923,0.79773 -0.55619,0.56078 -0.60417,-0.60417 z m 17.4058,0.392 c -0.40754,-0.65942 -0.12083,-1.58421 0.63713,-2.05509 1.66304,-1.03315 2.55953,0.79835 1.10349,2.25439 -0.66618,0.66618 -1.24681,0.59969 -1.74062,-0.1993 z"
+ id="path2930" />
+ <path
+ style="fill:#f83e29"
+ d="m 244.07446,826.57275 c 0,-0.85746 0.45,-1.55902 1,-1.55902 0.55,0 1,0.42344 1,0.94098 0,0.51754 -0.45,1.2191 -1,1.55902 -0.55,0.33992 -1,-0.0835 -1,-0.94098 z"
+ id="path2928" />
+ </g>
+ <g
+ class="spaceship"
+ id="shipFire2"
+ transform="translate(-109.5,132.5)">
+ <path
+ style="fill:#fefefe"
+ d="m 151.57446,902.9436 0,-15 20,0 20,0 0,15 0,15 -20,0 -20,0 0,-15 z"
+ id="path3209" />
+ <path
+ style="fill:#fef4f3"
+ d="m 162.96188,917.12575 c 0.278,-0.44981 -0.42671,-1.46231 -1.56602,-2.25 -6.19532,-4.28325 -6.07193,-4.01046 -6.49663,-14.36377 -0.35012,-8.53525 -0.17217,-9.96019 1.38679,-11.10498 2.07435,-1.52325 11.97013,-1.78746 12.8626,-0.34341 0.37888,0.61304 1.12963,0.5408 2.01487,-0.19388 0.96521,-0.80105 1.80587,-0.85078 2.66097,-0.15738 0.83468,0.67683 3.35475,0.69027 7.58466,0.0404 3.48406,-0.53525 6.57872,-0.72911 6.87702,-0.43081 0.92329,0.92328 2.41041,8.80392 2.9664,15.71969 0.39587,4.92418 0.12314,7.38568 -1.07506,9.70274 -1.54819,2.99387 -1.78393,3.08356 -6.60426,2.51267 -3.41971,-0.40502 -4.99876,-0.23214 -4.99876,0.54726 0,0.62661 -0.66643,1.13929 -1.48095,1.13929 -1.80373,0 -2.9556,-4.04919 -2.00441,-7.04614 0.92344,-2.90948 -1.57556,-2.16889 -3.13355,0.92865 -1.68131,3.34273 -5.03701,6.11749 -7.39829,6.11749 -1.15546,0 -1.87338,-0.36803 -1.59538,-0.81785 z"
+ id="path3207" />
+ <path
+ style="fill:#fef3ea"
+ d="m 163.03741,917.00355 c 0.58394,-0.94485 0.10077,-1.48471 -4.41546,-4.93349 -2.1257,-1.62328 -2.54917,-2.98908 -3.17795,-10.24965 -1.00798,-11.63923 -0.10006,-13.34965 7.14549,-13.46141 3.01673,-0.0465 5.93497,0.23133 6.48497,0.61747 1.17869,0.82751 10.45665,0.51702 15.61683,-0.52263 l 3.61683,-0.7287 1.63317,7.23189 c 2.02661,8.97413 2.06262,13.7145 0.13914,18.31804 -1.48926,3.5643 -1.51001,3.57382 -6.5,2.98283 -3.4256,-0.40571 -5.00597,-0.23321 -5.00597,0.54641 0,1.55847 -2.97681,1.45192 -3.09274,-0.11071 -0.051,-0.6875 -0.0116,-3.25029 0.0875,-5.69508 0.15304,-3.77373 -0.038,-4.26392 -1.26504,-3.24559 -0.79492,0.65972 -2.72404,3.22251 -4.28694,5.69508 -2.05711,3.25444 -3.49307,4.49559 -5.20123,4.49559 -1.29778,0 -2.09816,-0.42302 -1.77862,-0.94005 z"
+ id="path3205" />
+ <path
+ style="fill:#fde8e7"
+ d="m 162.87261,917.31212 c 0.98153,-0.98154 -1.19733,-4.36852 -2.81028,-4.36852 -0.79297,0 -2.1115,-1.02214 -2.93006,-2.27143 -1.9288,-2.94372 -2.45436,-19.23181 -0.67788,-21.00894 1.42194,-1.42246 12.12007,-1.80281 12.12007,-0.4309 0,0.51045 1.09742,0.65265 2.43871,0.31601 1.3413,-0.33665 2.72239,-0.15309 3.0691,0.4079 0.34671,0.56099 1.075,0.7452 1.61842,0.40934 0.54342,-0.33585 1.97483,-0.7608 3.1809,-0.94432 1.20608,-0.18353 3.76787,-0.62898 5.69287,-0.98989 l 3.5,-0.65619 1.7642,7.33421 c 1.93817,8.05746 2.29955,15.83421 0.7358,15.83421 -0.55,0 -1,1.09844 -1,2.44098 0,3.27429 -1.11158,3.76871 -6.00239,2.66982 -3.26275,-0.73309 -4.24406,-0.63213 -4.67105,0.48057 -0.29729,0.77475 -1.16739,1.40863 -1.93355,1.40863 -1.02551,0 -1.39301,-1.48331 -1.39301,-5.62245 0,-5.01744 -0.17049,-5.48095 -1.58439,-4.30751 -0.87142,0.72321 -2.91804,3.25331 -4.54804,5.62244 -1.91866,2.78868 -3.71068,4.30752 -5.08228,4.30752 -1.16524,0 -1.83446,-0.28417 -1.48714,-0.63148 z"
+ id="path3203" />
+ <path
+ style="fill:#fde3db"
+ d="m 163.57446,916.49449 c 0,-0.79701 -1.5347,-2.61968 -3.41045,-4.05039 -3.34087,-2.5482 -3.42503,-2.79562 -4.12458,-12.12631 -0.49318,-6.57819 -0.36781,-9.87135 0.40526,-10.64442 1.58052,-1.58052 11.34374,-1.64763 12.90871,-0.0887 0.70341,0.70069 1.94091,1.01996 2.75,0.70948 0.80908,-0.31047 1.47106,-0.0398 1.47106,0.60151 0,0.69406 0.50594,0.84125 1.25,0.36365 1.48765,-0.95489 9.60478,-3.20883 11.78189,-3.27155 0.89112,-0.0257 1.61132,0.91554 1.72177,2.25013 0.10444,1.26185 0.87759,4.24343 1.71811,6.62573 1.71574,4.86292 2.06153,14.08001 0.52823,14.08001 -0.55,0 -1,0.8449 -1,1.87755 0,3.07992 -2.2104,4.20929 -6.07124,3.10202 -4.50601,-1.29231 -4.92876,-1.24767 -4.92876,0.52043 0,0.825 -0.6681,1.5 -1.48467,1.5 -1.21761,0 -1.37186,-1.07927 -0.85754,-6 0.37978,-3.63355 0.24528,-6 -0.34102,-6 -1.19371,0 -4.13666,3.29088 -7.37163,8.24317 -2.48087,3.79786 -4.94514,4.94785 -4.94514,2.30772 z"
+ id="path3201" />
+ <path
+ style="fill:#fddbda"
+ d="m 163.57446,916.49449 c 0,-0.79701 -1.50777,-2.59914 -3.35059,-4.00473 -3.26039,-2.48682 -3.36819,-2.80345 -4.00402,-11.76116 -0.53554,-7.5447 -0.37779,-9.48118 0.87439,-10.73336 2.05974,-2.05974 11.1787,-2.27977 11.94295,-0.28817 0.32015,0.83429 1.22302,1.18736 2.13824,0.83616 1.0586,-0.40623 1.76151,0.0705 2.11886,1.43701 0.52424,2.00471 0.56124,2.00709 1.88206,0.12136 0.74101,-1.05795 2.59623,-2.18478 4.1227,-2.50408 9.28393,-1.94193 8.81294,-1.97116 9.02241,0.55983 0.1081,1.30613 0.88425,4.32394 1.72477,6.70624 1.71574,4.86292 2.06153,14.08001 0.52823,14.08001 -0.55,0 -1,0.81 -1,1.8 0,3.01516 -1.86706,4.09852 -5.34458,3.10118 -4.40199,-1.26248 -5.65542,-1.12976 -5.65542,0.59882 0,0.825 -0.63233,1.5 -1.40517,1.5 -1.11122,0 -1.29136,-1.25517 -0.86111,-6 0.34639,-3.82005 0.16791,-6 -0.49124,-6 -1.32415,0 -7.06306,6.5121 -8.48052,9.62309 -1.18645,2.60397 -3.76196,3.23916 -3.76196,0.9278 z"
+ id="path3199" />
+ <path
+ style="fill:#fdd4d3"
+ d="m 163.57446,915.96928 c 0,-1.18015 -1.20093,-2.59534 -2.98551,-3.51819 -3.28277,-1.69758 -3.6304,-2.72129 -4.44155,-13.07944 -0.72235,-9.22415 0.366,-10.86052 7.31911,-11.00464 4.13062,-0.0856 5.18438,0.24206 5.66684,1.76214 0.32597,1.02703 1.32706,1.74292 2.22465,1.59089 1.2408,-0.21018 1.71047,0.67881 1.95939,3.70872 0.18006,2.19184 0.74523,4.403 1.25592,4.91369 0.57138,0.57138 0.70687,-0.43744 0.35224,-2.62274 -0.81981,-5.05189 0.66273,-6.92355 6.70993,-8.47114 5.54336,-1.41865 6.86584,-0.905 6.93872,2.69503 0.0167,0.825 0.67885,3.3 1.47142,5.5 2.01176,5.58413 1.86493,10.42872 -0.46204,15.24498 -1.9362,4.00748 -2.08038,4.09285 -5.25,3.10855 -5.15345,-1.60037 -6.28791,-1.52497 -5.96528,0.39647 0.16161,0.9625 -0.30972,1.75 -1.0474,1.75 -1.02652,0 -1.24411,-1.52514 -0.92734,-6.5 0.22764,-3.575 0.024,-6.47871 -0.4526,-6.45269 -1.17866,0.0644 -9.3665,10.39262 -9.3665,11.81503 0,0.62571 -0.675,1.13766 -1.5,1.13766 -0.82683,0 -1.5,-0.88604 -1.5,-1.97432 z"
+ id="path3197" />
+ <path
+ style="fill:#fdd5cb"
+ d="m 164.18103,916.77117 c 0.43565,-0.70489 -0.81465,-2.4647 -3.13534,-4.41305 -3.69469,-3.10187 -3.89194,-3.57553 -4.60717,-11.06331 -1.03988,-10.88663 -0.0358,-12.78139 6.84886,-12.92409 4.71285,-0.0977 5.2995,0.13606 6.23046,2.48252 0.56525,1.4247 1.47635,3.26536 2.02466,4.09036 0.54832,0.825 1.67354,3.075 2.50049,5 l 1.50355,3.5 -0.50478,-5 c -0.27763,-2.75 -0.0824,-5.64324 0.43386,-6.42941 0.79202,-1.20613 11.1128,-4.63899 11.53951,-3.83823 0.0784,0.1472 1.15252,3.4997 2.38686,7.44999 2.43693,7.79905 2.66335,14.72 0.45384,13.87213 -0.93046,-0.35706 -1.14026,0.15958 -0.72945,1.79636 0.92292,3.67722 -1.48563,4.94645 -6.83196,3.60023 -4.34704,-1.0946 -4.4947,-1.26023 -4.98261,-5.58895 -0.52198,-4.63098 -1.67993,-6.79044 -2.46354,-4.59426 -0.24881,0.69732 -1.15193,1.9674 -2.00693,2.8224 -2.2206,2.2206 -6.26688,8.32478 -6.26688,9.45415 0,0.52557 -0.70156,0.95559 -1.55902,0.95559 -0.93755,0 -1.27017,-0.46736 -0.83441,-1.17243 z m 11.39343,0.73145 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z"
+ id="path3195" />
+ <path
+ style="fill:#fcc9c7"
+ d="m 164.1735,916.5461 c 0.31707,-0.82628 -0.88226,-2.47948 -2.93415,-4.04453 -4.03071,-3.07437 -4.57157,-4.70635 -4.77073,-14.39518 -0.1804,-8.77645 0.68336,-10.02859 6.65854,-9.65248 3.86629,0.24336 4.82621,0.76895 6.84943,3.75033 1.29414,1.90703 2.89298,5.10353 3.55298,7.10334 1.63364,4.94999 2.44547,4.57523 1.71016,-0.78944 -0.75035,-5.47444 0.9777,-7.75927 7.18209,-9.49615 2.39104,-0.66935 4.43478,-1.07332 4.54164,-0.8977 0.10686,0.17562 1.20419,3.55137 2.43853,7.50166 2.4293,7.77463 2.66263,14.71972 0.46621,13.87687 -0.87564,-0.33601 -1.29374,0.44385 -1.29374,2.41315 0,3.83982 -0.992,4.28955 -6.31903,2.86479 -4.29403,-1.14848 -4.47943,-1.35674 -4.95371,-5.56454 -0.4947,-4.38896 -1.66671,-6.69837 -2.38712,-4.70377 -0.21232,0.58787 -2.17572,2.98811 -4.36309,5.33386 -2.18738,2.34575 -3.97705,5.12726 -3.97705,6.18114 0,1.05388 -0.66088,1.91615 -1.46862,1.91615 -0.84672,0 -1.24152,-0.59178 -0.93234,-1.3975 z m 11.40096,0.95652 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z"
+ id="path3193" />
+ <path
+ style="fill:#fcbec0"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.04148,-1 1.55902,-1 0.51754,0 0.94098,0.45 0.94098,1 0,0.55 -0.70156,1 -1.55902,1 -0.85746,0 -1.2809,-0.45 -0.94098,-1 z m -2.5,-4.5612 c -3.83318,-2.6976 -4.78539,-5.9 -4.92588,-16.56636 -0.088,-6.68229 0.84499,-7.68093 6.86223,-7.34496 3.62102,0.20218 4.59555,0.6781 5.30265,2.58955 0.47646,1.28801 1.42448,3.0261 2.10671,3.86241 1.94334,2.38227 3.85888,8.87634 3.02775,10.26473 -1.36298,2.27684 -7.78605,9.75683 -8.33522,9.70679 -0.29603,-0.027 -2.11324,-1.15744 -4.03824,-2.51216 z m 18.36759,1.39317 c -1.5582,-0.75458 -2.29225,-2.28472 -2.72598,-5.68232 -1.81186,-14.19307 -1.85608,-15.1863 -0.73618,-16.5357 0.6374,-0.76802 2.38193,-1.62827 3.87674,-1.91168 1.4948,-0.28341 3.73033,-0.83485 4.96783,-1.22541 1.79339,-0.56601 2.25,-0.32428 2.25,1.19117 0,1.04571 0.9243,4.53109 2.05401,7.7453 2.39531,6.81511 2.29483,11.2274 -0.2461,10.80613 -1.40828,-0.23348 -1.59599,0.31162 -1.11915,3.25 0.56258,3.46682 0.51191,3.52932 -2.80792,3.46286 -1.85946,-0.0372 -4.34043,-0.53238 -5.51325,-1.10035 z"
+ id="path3191" />
+ <path
+ style="fill:#fcc6b6"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m 15.867,-3.4555 c -2.13975,-1.49873 -3.49156,-7.8263 -3.74817,-17.5445 l -0.11883,-4.5 5,-1.66983 c 6.5578,-2.19008 6.5,-2.19412 6.5,0.45449 0,1.25656 0.9,4.84532 2,7.97502 2.56186,7.28896 2.57769,9.74032 0.0629,9.74032 -1.65538,0 -1.85452,0.50906 -1.36916,3.5 0.55605,3.4265 0.4964,3.5 -2.84036,3.5 -1.87459,0 -4.34344,-0.65497 -5.48635,-1.4555 z m -18.60545,-1.38463 c -3.43887,-2.08117 -3.72417,-2.86336 -4.4426,-12.17971 -0.78522,-10.18248 0.13117,-11.85397 6.28649,-11.46653 l 4.65321,0.29289 2.84267,6.34674 c 3.65068,8.15076 3.60396,10.13172 -0.35132,14.89597 -3.55811,4.28584 -4.88093,4.59646 -8.98845,2.11064 z"
+ id="path3189" />
+ <path
+ style="fill:#fcb8b7"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m 15.86726,-3.77224 c -1.42817,-1.15698 -2.34597,-3.37956 -2.77818,-6.72776 -0.35499,-2.75 -0.87727,-6.8 -1.16063,-9 -0.63335,-4.91747 0.30316,-6.41121 4.67526,-7.45707 1.86796,-0.44683 4.18379,-1.13743 5.14629,-1.53467 1.38018,-0.56961 1.75,-0.21682 1.75,1.66941 0,1.31541 0.9,4.95231 2,8.08201 1.1,3.12969 2,6.6016 2,7.71534 0,1.35831 -0.65844,2.02498 -2,2.02498 -1.61905,0 -2,0.66667 -2,3.5 0,3.15691 -0.26957,3.49782 -2.75,3.47776 -1.5125,-0.0122 -3.70973,-0.79973 -4.88274,-1.75 z m -18.62479,-1.06919 c -3.28171,-1.97384 -3.41746,-2.3794 -4.2374,-12.65857 -0.80902,-10.14237 0.0964,-11.68239 6.35676,-10.81264 4.18382,0.58125 4.47966,0.85505 7.24921,6.70931 3.85095,8.14012 3.70716,10.04334 -1.11219,14.72035 -4.47969,4.34739 -4.43931,4.33741 -8.25638,2.04155 z"
+ id="path3187" />
+ <path
+ style="fill:#fbb4a7"
+ d="m 180.95274,913.78034 c -1.68968,-0.81858 -2.47019,-2.83106 -3.833,-9.88312 -2.09004,-10.81512 -1.64459,-12.66589 3.26108,-13.54927 2.0315,-0.36582 4.20048,-1.06536 4.81994,-1.55453 0.77792,-0.61429 1.49677,0.58187 2.324,3.8671 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09968,2.7008 1.47131,4.7633 0.60026,3.33127 0.44732,3.75 -1.36961,3.75 -1.71953,0 -2.04531,0.63713 -2.04531,4 0,3.50153 -0.28039,3.99157 -2.25,3.93232 -1.2375,-0.0372 -3.20478,-0.53023 -4.37172,-1.09558 z m -19.9947,-2.63358 c -2.78682,-2.54536 -3.12379,-3.53611 -3.74785,-11.01905 -0.7913,-9.4884 0.22403,-12.72439 3.69989,-11.79201 1.19041,0.31933 3.15582,0.58674 4.36759,0.59425 1.65866,0.0103 2.72727,1.18765 4.32359,4.76365 3.4929,7.82464 3.41122,11.85531 -0.3316,16.3645 -1.75736,2.1172 -3.65741,3.85756 -4.22234,3.86747 -0.56493,0.01 -2.4051,-1.24055 -4.08928,-2.77881 z"
+ id="path3185" />
+ <path
+ style="fill:#fbc693"
+ d="m 181.40888,913.54887 c -1.90156,-0.94762 -2.66716,-2.73407 -4.12887,-9.6343 -2.11431,-9.98096 -1.48228,-12.43122 3.4804,-13.49292 1.82273,-0.38995 3.82089,-1.11594 4.44035,-1.61331 0.78167,-0.6276 1.49279,0.55112 2.324,3.85218 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09346,2.66764 1.45749,4.68962 0.59423,3.30058 0.4287,3.70941 -1.61961,4 -1.89768,0.26923 -2.23157,0.84875 -1.98478,3.44483 0.34701,3.6502 -2.13396,4.89193 -5.96229,2.98412 z m -19.59537,-1.75085 c -3.85286,-2.43946 -4.12485,-3.26446 -4.46668,-13.54855 -0.29145,-8.76823 0.67103,-11.1791 3.91041,-9.79498 0.99947,0.42706 2.70818,0.82431 3.79713,0.88279 2.50572,0.13456 5.98356,6.56952 6.78668,12.55723 0.55271,4.12079 0.33707,4.68072 -3.14285,8.16065 l -3.73629,3.73628 -3.1484,-1.99342 z"
+ id="path3183" />
+ <path
+ style="fill:#fba7a6"
+ d="m 181.40888,913.54887 c -1.90156,-0.94762 -2.66716,-2.73407 -4.12887,-9.6343 -2.11431,-9.98096 -1.48228,-12.43122 3.4804,-13.49292 1.82273,-0.38995 3.82089,-1.11594 4.44035,-1.61331 0.78167,-0.6276 1.49279,0.55112 2.324,3.85218 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09346,2.66764 1.45749,4.68962 0.59423,3.30058 0.4287,3.70941 -1.61961,4 -1.89768,0.26923 -2.23157,0.84875 -1.98478,3.44483 0.34701,3.6502 -2.13396,4.89193 -5.96229,2.98412 z m -19.59537,-1.75085 c -3.85797,-2.44269 -4.12541,-3.25919 -4.46668,-13.63661 -0.21296,-6.47571 0.053,-8.48421 1.21927,-9.20836 0.92359,-0.57346 1.85661,-0.5612 2.45,0.0322 0.5271,0.5271 2.21605,0.95836 3.75324,0.95836 2.32203,0 3.11778,0.71903 4.70349,4.25 1.04975,2.3375 2.1601,6.00739 2.46746,8.15531 0.5041,3.52278 0.18969,4.27446 -3.20977,7.67393 l -3.76861,3.7686 -3.1484,-1.99342 z"
+ id="path3181" />
+ <path
+ style="fill:#fb9fa0"
+ d="m 180.42487,912.6936 c -2.246,-1.83276 -5.24235,-17.14915 -3.86013,-19.73183 0.59405,-1.10999 1.40175,-2.02891 1.7949,-2.04203 0.39315,-0.0131 2.38169,-0.41108 4.41898,-0.88435 l 3.70417,-0.86049 1.20496,5.38435 c 0.66273,2.96139 1.63584,5.38435 2.16247,5.38435 0.52663,0 0.72226,0.89955 0.43475,1.999 -0.28751,1.09946 -0.115,2.25101 0.38337,2.55902 1.72728,1.06752 0.8953,2.41725 -1.34388,2.18019 -1.77357,-0.18777 -2.27296,0.29115 -2.35843,2.26179 -0.20189,4.65475 -0.38835,5 -2.70044,5 -1.26988,0 -2.9982,-0.5625 -3.84072,-1.25 z m -19.64276,-1.72785 c -3.80444,-3.17207 -5.11148,-21.0776 -1.63594,-22.41129 0.75033,-0.28793 1.63021,-0.0932 1.95528,0.43281 0.32508,0.52598 1.92562,0.95633 3.55678,0.95633 3.39807,0 4.50718,2.01814 5.96224,10.84895 0.82009,4.97716 0.69273,5.58534 -1.83233,8.74997 -3.07999,3.86011 -4.73127,4.15366 -8.00603,1.42323 z"
+ id="path3179" />
+ <path
+ style="fill:#fba896"
+ d="m 180.32446,912.8635 c -0.9625,-0.5606 -1.75,-1.98067 -1.75,-3.1557 0,-1.17503 -0.70563,-4.95003 -1.56806,-8.38889 -1.97329,-7.8683 -1.07849,-9.92916 4.82218,-11.10618 l 4.24588,-0.84693 1.23482,4.0389 c 0.67915,2.22139 1.24165,5.24426 1.25,6.71747 0.008,1.47322 0.72232,3.38572 1.58661,4.25 0.86428,0.86429 1.20178,1.62334 0.75,1.68678 -0.45179,0.0634 -1.49643,0.17594 -2.32143,0.25 -0.89743,0.0806 -1.5,1.13894 -1.5,2.63465 0,4.68395 -2.72313,6.26534 -6.75,3.9199 z m -18.59061,-1.52081 c -3.18441,-2.23045 -4.15936,-5.40703 -4.3244,-14.08961 -0.10379,-5.46081 0.23701,-7.73594 1.25286,-8.36377 0.80738,-0.49899 1.7993,-0.45856 2.35379,0.0959 0.5271,0.5271 2.2295,0.95836 3.78311,0.95836 3.22728,0 4.77525,2.79781 4.77525,8.63084 0,1.92535 0.46718,4.37357 1.03817,5.44049 0.83398,1.5583 0.48978,2.62715 -1.75,5.43423 -3.14945,3.94716 -3.90883,4.14887 -7.12878,1.89353 z"
+ id="path3177" />
+ <path
+ style="fill:#fb9997"
+ d="m 180.38153,912.23762 c -1.73595,-1.96787 -4.23706,-14.37731 -3.66592,-18.18864 0.28615,-1.90951 1.28961,-2.62988 4.95335,-3.55593 l 4.5945,-1.16131 1.1555,4.32028 c 0.63553,2.37616 1.1555,5.40668 1.1555,6.7345 0,1.32782 0.70714,3.12137 1.57143,3.98565 0.86428,0.86429 1.20178,1.62334 0.75,1.68678 -0.45179,0.0634 -1.49643,0.17594 -2.32143,0.25 -0.91279,0.0819 -1.69574,1.5048 -2,3.63465 -0.58275,4.07922 -3.62426,5.20588 -6.19293,2.29402 z m -19.3807,-1.60369 c -2.4799,-2.13313 -2.72327,-3.03845 -3.18385,-11.84386 -0.42411,-8.10811 -0.25997,-9.6258 1.09736,-10.14665 0.87784,-0.33686 1.86204,-0.18213 2.18711,0.34385 0.32508,0.52598 1.66397,0.95633 2.97532,0.95633 3.15873,0 5.49769,3.52618 5.49769,8.28825 0,2.11378 0.46554,4.71311 1.03454,5.77629 0.85492,1.59744 0.42667,2.54092 -2.46667,5.43425 -1.92566,1.92567 -3.71611,3.50121 -3.97877,3.50121 -0.26267,0 -1.68589,-1.03935 -3.16273,-2.30967 z"
+ id="path3175" />
+ <path
+ style="fill:#fac868"
+ d="m 180.61925,912.49757 c -1.54558,-1.86231 -3.96316,-11.97209 -4.00917,-16.76543 -0.0337,-3.51238 0.18575,-3.77106 4.09158,-4.82279 2.32002,-0.62472 4.50572,-0.73283 4.99166,-0.24689 0.47544,0.47544 1.39155,3.48908 2.03578,6.69698 0.89078,4.43548 0.89278,6.27859 0.008,7.69478 -0.63959,1.02423 -1.16294,3.1702 -1.16294,4.76882 0,3.89193 -3.60222,5.50971 -5.95521,2.67453 z M 161.2105,910.6419 c -2.67903,-2.14379 -2.89701,-2.87138 -3.37577,-11.26821 -0.41609,-7.29756 -0.2244,-9.21497 1.02493,-10.25182 1.03553,-0.85942 1.74811,-0.9334 2.18479,-0.22683 0.35642,0.57671 1.69139,1.04856 2.96658,1.04856 3.39213,0 4.82534,2.37252 5.16837,8.55569 0.16748,3.01883 0.57322,5.92356 0.90165,6.45497 0.54751,0.8859 -4.35593,7.99571 -5.50659,7.98434 -0.275,-0.003 -1.78878,-1.03623 -3.36396,-2.2967 z"
+ id="path3244" />
+ <path
+ style="fill:#fa9588"
+ d="m 180.61925,912.49757 c -1.54558,-1.86231 -3.96316,-11.97209 -4.00917,-16.76543 -0.0337,-3.51238 0.18575,-3.77106 4.09158,-4.82279 2.32002,-0.62472 4.50572,-0.73283 4.99166,-0.24689 0.47544,0.47544 1.39155,3.48908 2.03578,6.69698 0.89078,4.43548 0.89278,6.27859 0.008,7.69478 -0.63959,1.02423 -1.16294,3.1702 -1.16294,4.76882 0,3.89193 -3.60222,5.50971 -5.95521,2.67453 z m -19.45977,-1.89636 c -2.83469,-2.2682 -2.91733,-2.59171 -3,-11.74503 l -0.085,-9.41258 4,0.33285 c 5.42153,0.45115 6.73448,2.04528 7.09921,8.61958 0.17063,3.07562 0.57895,6.02682 0.90738,6.55823 0.54751,0.8859 -4.35593,7.99571 -5.50659,7.98434 -0.275,-0.003 -1.81174,-1.05454 -3.41498,-2.33739 z"
+ id="path3171" />
+ <path
+ style="fill:#fa8b86"
+ d="m 181.27717,912.6936 c -2.29214,-1.70591 -5.542,-17.19589 -4.09055,-19.49693 1.25861,-1.99531 7.28306,-3.75785 8.54186,-2.49904 1.62734,1.62734 3.20598,13.28597 1.96678,14.52517 -0.61644,0.61644 -1.1208,2.2908 -1.1208,3.7208 0,2.4 -1.56461,5 -3.00887,5 -0.33488,0 -1.36467,-0.5625 -2.28842,-1.25 z m -19.82628,-2.16376 c -2.22007,-2.05857 -2.7042,-3.5724 -3.28996,-10.28744 -0.75026,-8.60077 -0.13895,-11.72478 2.12436,-10.85627 0.79901,0.30661 2.52511,0.55747 3.83577,0.55747 3.1779,0 4.5433,2.83475 4.90988,10.19353 0.23862,4.78997 -0.13818,6.723 -1.82795,9.37775 -1.17069,1.83924 -2.35813,3.36311 -2.63875,3.38639 -0.28062,0.0233 -1.68163,-1.04386 -3.11335,-2.37143 z"
+ id="path3169" />
+ <path
+ style="fill:#f9aa67"
+ d="m 180.07939,911.6936 c -0.96604,-2.79329 -3.50493,-15.00852 -3.50493,-16.86308 0,-1.34263 1.1834,-2.48343 3.64167,-3.51056 5.43653,-2.27153 6.86784,-0.40276 6.82572,8.91194 -0.0454,10.04111 -0.8895,12.7117 -4.01783,12.7117 -1.38178,0 -2.70687,-0.5625 -2.94463,-1.25 z m -19.29027,-2.20424 c -1.3053,-1.65942 -2.14743,-4.84806 -2.60032,-9.84592 -0.87694,-9.67732 -0.44657,-10.69807 4.21367,-9.99407 2.01959,0.30509 4.11891,0.96552 4.66515,1.46762 0.54623,0.50211 1.2459,4.156 1.55481,8.11977 0.48082,6.16945 0.2748,7.60269 -1.43121,9.95684 -2.45809,3.39195 -3.91374,3.4592 -6.4021,0.29576 z"
+ id="path3167" />
+ <path
+ style="fill:#fa8974"
+ d="m 180.23917,912.1936 c -0.24933,-0.4125 -1.26783,-4.68555 -2.26334,-9.49567 -1.97889,-9.5616 -1.79281,-10.20809 3.36397,-11.68703 4.53536,-1.30072 5.74188,0.67547 5.70205,9.33952 -0.0452,9.8259 -0.90819,12.59318 -3.92743,12.59318 -1.33206,0 -2.62592,-0.3375 -2.87525,-0.75 z m -19.45005,-2.70424 c -1.3053,-1.65942 -2.14743,-4.84806 -2.60032,-9.84592 -0.79775,-8.8035 -0.22455,-11.09678 2.41988,-9.68153 1.00886,0.53993 2.95856,0.98169 4.33265,0.98169 2.92589,0 3.40329,1.19686 3.78937,9.5 0.20907,4.49625 -0.18031,6.68922 -1.55363,8.75 -2.26265,3.39527 -3.89059,3.47065 -6.38795,0.29576 z"
+ id="path3165" />
+ <path
+ style="fill:#fa7c74"
+ d="m 180.72006,911.61903 c -1.4979,-1.80485 -4.31584,-15.56371 -3.63009,-17.72428 0.67874,-2.13853 7.23738,-3.59767 8.86474,-1.9722 1.21641,1.215 1.28853,11.23559 0.1243,17.27105 -0.76211,3.95089 -3.18344,5.04676 -5.35895,2.42543 z m -19.6989,-1.73433 c -2.13154,-2.35532 -3.97555,-16.59894 -2.39543,-18.50288 0.51226,-0.61723 0.59778,-1.47929 0.19005,-1.91568 -0.40772,-0.4364 0.2416,-0.28249 1.44294,0.34201 1.20134,0.6245 3.09801,1.13545 4.21481,1.13545 1.11681,0 2.51821,0.91118 3.11423,2.02485 2.07725,3.88138 -0.75392,18.97515 -3.5592,18.97515 -0.62927,0 -1.9826,-0.9265 -3.0074,-2.0589 z"
+ id="path3250" />
+ <path
+ style="fill:#f97568"
+ d="m 180.91399,911.73649 c -0.5371,-0.71109 -1.7753,-4.79608 -2.75154,-9.07776 -1.36171,-5.97223 -1.5043,-8.11105 -0.6124,-9.18572 1.45048,-1.74772 6.93018,-3.02459 8.07048,-1.88057 1.16986,1.17368 1.36105,11.98823 0.29772,16.84039 -0.90326,4.12175 -3.22742,5.65609 -5.00426,3.30366 z M 162.4878,910.6618 c -3.08149,-2.3659 -4.01734,-5.72011 -3.8248,-13.70865 0.17568,-7.28887 0.33626,-7.85257 1.98556,-6.96989 0.98693,0.52818 2.70817,0.96034 3.82497,0.96034 1.11681,0 2.4717,0.82427 3.01086,1.83171 1.24877,2.33334 0.244,12.81559 -1.57376,16.41829 -1.59155,3.15436 -1.35745,3.05394 -3.42283,1.4682 z"
+ id="path3161" />
+ <path
+ style="fill:#f9904b"
+ d="m 181.18872,912.12848 c -1.12357,-1.81798 -3.61426,-12.66104 -3.61426,-15.73446 0,-2.38301 0.60749,-3.40618 2.54705,-4.28991 5.29419,-2.41219 6.50298,-1.14797 6.37883,6.67128 -0.13265,8.35393 -1.29475,13.61677 -3.08264,13.96046 -0.91122,0.17517 -1.91426,-0.0982 -2.22898,-0.60737 z m -20.20927,-3.28761 c -1.53322,-1.69237 -1.9442,-3.84084 -2.10589,-11.00891 -0.19049,-8.44507 -0.10329,-8.85393 1.68426,-7.89726 1.03684,0.55489 2.78818,1.0089 3.89188,1.0089 1.1037,0 2.34895,0.55373 2.76722,1.2305 1.11829,1.80944 0.48625,12.83248 -0.91853,16.0195 -1.4532,3.29687 -2.77301,3.45748 -5.31894,0.64727 z"
+ id="path3159" />
+ <path
+ style="fill:#f96c64"
+ d="m 181.18872,912.12848 c -1.14282,-1.84912 -3.61426,-12.68601 -3.61426,-15.84797 0,-2.88972 0.40359,-3.35434 3.7057,-4.26609 4.58817,-1.26686 5.28526,-0.4058 5.20486,6.42918 -0.10111,8.5965 -1.24846,13.94261 -3.06732,14.29225 -0.91122,0.17517 -1.91426,-0.0982 -2.22898,-0.60737 z m -20.20649,-3.28679 c -1.44296,-1.59445 -1.9879,-3.98904 -2.25717,-9.91855 l -0.35497,-7.81664 4.35218,0.55614 c 2.39371,0.30587 4.5587,0.73823 4.8111,0.96079 0.90854,0.80113 -0.0496,12.88089 -1.23498,15.57017 -1.45309,3.29661 -2.77359,3.45759 -5.31616,0.64809 z"
+ id="path3254" />
+ <path
+ style="fill:#f8a727"
+ d="m 182.00194,912.15744 c -1.28515,-0.85536 -4.42748,-11.79022 -4.42748,-15.407 0,-2.82016 1.32386,-4.22994 4.76309,-5.07221 3.51518,-0.86088 4.61133,2.30777 3.86257,11.16552 -0.62875,7.43814 -2.10279,10.70831 -4.19818,9.31369 z m -19.65615,-2.43812 c -2.51948,-1.91174 -3.77133,-6.20961 -3.77133,-12.94781 0,-5.09857 0.24696,-5.94712 1.58179,-5.4349 0.86998,0.33384 2.89498,0.60699 4.5,0.60699 l 2.91821,0 -0.0222,7.25 c -0.0164,5.34852 -0.4816,7.84686 -1.7737,9.52572 -1.48125,1.92462 -2.01085,2.0789 -3.43274,1 z"
+ id="path3155" />
+ <path
+ style="fill:#f97656"
+ d="m 182.00194,912.15744 c -1.28515,-0.85536 -4.42748,-11.79022 -4.42748,-15.407 0,-2.82016 1.32386,-4.22994 4.76309,-5.07221 3.51518,-0.86088 4.61133,2.30777 3.86257,11.16552 -0.62875,7.43814 -2.10279,10.70831 -4.19818,9.31369 z m -19.65615,-2.43812 c -2.51948,-1.91174 -3.77133,-6.20961 -3.77133,-12.94781 0,-5.09857 0.24696,-5.94712 1.58179,-5.4349 0.86998,0.33384 1.72785,0.60699 1.90638,0.60699 0.17852,0 0.0911,0.89278 -0.19423,1.98395 -0.66163,2.5301 0.44138,7.01605 1.72511,7.01605 0.53952,0 0.98095,-2.025 0.98095,-4.5 0,-3.33333 0.38889,-4.5 1.5,-4.5 2.31179,0 2.07009,13.70149 -0.29594,16.77572 -1.48125,1.92462 -2.01084,2.0789 -3.43273,1 z"
+ id="path3153" />
+ <path
+ style="fill:#f88f2e"
+ d="m 182.00194,912.15744 c -1.30059,-0.86563 -4.42748,-11.8084 -4.42748,-15.49426 0,-2.81806 2.38324,-4.71958 5.91521,-4.71958 2.73688,0 3.51703,3.46196 2.66677,11.83399 -0.68096,6.70511 -2.16705,9.70263 -4.1545,8.37985 z m -19.6862,-2.46009 c -2.64876,-2.01116 -3.61818,-6.01981 -3.02848,-12.52309 0.39024,-4.30358 0.91579,-5.92668 1.80816,-5.58424 0.69191,0.26551 1.03216,1.34646 0.7561,2.40212 -0.64783,2.47728 0.47338,6.95146 1.74199,6.95146 0.53952,0 0.98095,-2.025 0.98095,-4.5 0,-4.55243 1.37549,-6.04303 2.45059,-2.65567 0.719,2.26536 -1.01511,15.12019 -2.19947,16.30455 -0.47815,0.47815 -1.59029,0.30306 -2.50984,-0.39513 z"
+ id="path3151" />
+ <path
+ style="fill:#f96656"
+ d="m 182.00194,912.15744 c -1.30059,-0.86563 -4.42748,-11.8084 -4.42748,-15.49426 0,-2.81806 2.38324,-4.71958 5.91521,-4.71958 2.73688,0 3.51703,3.46196 2.66677,11.83399 -0.68096,6.70511 -2.16705,9.70263 -4.1545,8.37985 z m -19.60247,-2.28383 c -2.66678,-1.50524 -3.80043,-6.75809 -2.89841,-13.43001 0.6194,-4.58155 0.84216,-5.12459 0.94228,-2.29705 0.16099,4.5464 1.99307,8.79705 3.79163,8.79705 0.96049,0 1.34809,-1.62693 1.3699,-5.75 0.0233,-4.40049 0.27006,-5.3385 1.05154,-3.99669 1.11218,1.90963 -0.30428,15.37887 -1.76899,16.82145 -0.44713,0.44038 -1.56671,0.37524 -2.48795,-0.14475 z"
+ id="path3149" />
+ <path
+ style="fill:#f87844"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.21163,-4.031 -2.17681,-8.0411 -1.6772,-6.9684 -1.67641,-7.3778 0.0179,-9.25 0.97502,-1.0774 2.76607,-1.9589 3.98011,-1.9589 1.91826,0 2.28765,0.68753 2.82066,5.25 0.33734,2.8875 0.4264,6.15 0.19791,7.25 -0.22848,1.1 -0.6761,3.2375 -0.9947,4.75 -0.53504,2.53994 -2.86076,3.74965 -3.84508,2 z m -20.1394,-3.47251 c -1.11749,-1.59544 -1.51155,-4.34633 -1.39666,-9.75 0.088,-4.14012 0.32918,-5.95249 0.53592,-4.02749 1.06111,9.88038 5.29481,12.46707 5.31935,3.25 0.0111,-4.14972 0.29159,-5.33254 1.00802,-4.25 1.88648,2.85051 -0.72336,17 -3.13561,17 -0.42587,0 -1.47483,-1.00013 -2.33102,-2.22251 z"
+ id="path3147" />
+ <path
+ style="fill:#f96547"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.22583,-4.08894 -2.20836,-8.16986 l -1.78643,-7.41986 2.26013,-1.83014 c 4.07651,-3.30096 5.69263,-2.4342 6.37653,3.41986 0.33734,2.8875 0.4264,6.15 0.19791,7.25 -0.22848,1.1 -0.6761,3.2375 -0.9947,4.75 -0.53504,2.53994 -2.86076,3.74965 -3.84508,2 z m -20.1394,-3.47251 c -1.68769,-2.40951 -2.14046,-8.77749 -0.62409,-8.77749 0.51294,0 1.21826,0.9 1.56739,2 0.34913,1.1 1.27945,2 2.06739,2 1.48177,0 1.88623,2.65431 0.82562,5.41821 -0.83507,2.17617 -1.9995,1.9817 -3.83631,-0.64072 z m 4.45861,-10.58651 c -0.009,-2.62138 0.37634,-4.06696 0.98469,-3.69098 1.2685,0.78398 1.2685,4.53713 0,6.5 -0.70877,1.09674 -0.97349,0.34157 -0.98469,-2.80902 z"
+ id="path3145" />
+ <path
+ style="fill:#f87637"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.2224,-4.07496 -2.20075,-8.13879 l -1.77881,-7.38879 2.39173,-1.85364 c 1.31545,-1.0195 3.06673,-1.73864 3.89173,-1.59809 2.56229,0.43651 3.33281,10.73419 1.34529,17.97931 -0.48139,1.75482 -2.85813,2.40613 -3.64919,1 z m -20.1394,-3.47251 c -1.71422,-2.44739 -2.08719,-7.33159 -0.6287,-8.23299 0.51041,-0.31545 1.21573,0.33299 1.56739,1.44098 0.35166,1.10799 1.28406,2.01452 2.072,2.01452 1.54518,0 1.75012,1.2133 0.80232,4.75 -0.76127,2.84068 -1.83714,2.84843 -3.81301,0.0275 z m 4.71566,-10.77749 c 0,-2.475 0.19502,-3.4875 0.43337,-2.25 0.23836,1.2375 0.23836,3.2625 0,4.5 -0.23835,1.2375 -0.43337,0.225 -0.43337,-2.25 z"
+ id="path3143" />
+ <path
+ style="fill:#f95947"
+ d="m 181.27056,911.1936 c -1.3015,-2.31344 -3.81424,-15.51051 -3.07198,-16.13419 2.11924,-1.78067 6.32464,-3.00774 6.93324,-2.023 0.89503,1.44819 0.93106,13.97216 0.0479,16.65719 -0.71185,2.16425 -3.03417,3.05535 -3.90918,1.5 z m -20.1394,-3.47251 c -1.89753,-2.7091 -2.11846,-8.13141 -0.3067,-7.52749 0.6875,0.22917 1.25,0.97794 1.25,1.66394 0,0.68601 0.76594,1.80735 1.70209,2.49188 1.09786,0.80278 1.5002,2.01663 1.13337,3.41939 -0.72377,2.76767 -1.81644,2.75388 -3.77876,-0.0477 z"
+ id="path3141" />
+ <path
+ style="fill:#f86636"
+ d="m 181.07693,908.3252 c -0.89888,-2.13488 -1.88744,-5.97767 -2.19679,-8.53953 -0.53507,-4.43117 -0.41126,-4.73611 2.54336,-6.26401 3.06503,-1.58498 3.11446,-1.57168 3.76318,1.01304 0.83773,3.33777 -0.26675,15.46342 -1.52292,16.71959 -0.60332,0.60333 -1.55161,-0.47042 -2.58683,-2.92909 z m -19.94937,-1.9409 c -1.73917,-2.65431 -1.76322,-6.12764 -0.0394,-5.6907 0.54247,0.1375 0.98631,0.73627 0.98631,1.33061 0,0.59434 0.79532,1.66216 1.76737,2.37295 1.05669,0.77267 1.51631,1.94659 1.14301,2.91938 -0.87597,2.28274 -1.91533,2.03154 -3.85728,-0.93224 z"
+ id="path3139" />
+ <path
+ style="fill:#f87625"
+ d="m 181.03879,908.23391 c -0.87791,-2.08467 -1.8542,-5.92781 -2.16955,-8.54031 -0.47898,-3.96811 -0.30352,-4.75 1.06593,-4.75 0.90161,0 1.63929,-0.45 1.63929,-1 0,-0.55 0.61703,-1 1.37117,-1 2.65993,0 3.14174,16.94693 0.52774,18.56248 -0.46111,0.28498 -1.55667,-1.1875 -2.43458,-3.27217 z m -19.84932,-1.75513 c -1.98831,-3.03454 -2.07595,-5.20185 -0.21035,-5.20185 0.77256,0 1.20208,0.52791 0.95449,1.17312 -0.24759,0.64522 0.24531,1.75032 1.09534,2.45578 1.6689,1.38507 2.10285,4.03777 0.66052,4.03777 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z"
+ id="path3137" />
+ <path
+ style="fill:#f84c44"
+ d="m 181.03879,908.23391 c -2.37362,-5.63637 -3.12438,-13.29031 -1.30362,-13.29031 0.79161,0 1.97929,0.54 2.63929,1.2 0.93333,0.93333 1.22435,0.65556 1.30957,-1.25 0.064,-1.43104 0.49036,-0.57843 1.02516,2.05 0.97852,4.80922 0.25046,13.6439 -1.19815,14.5392 -0.48183,0.29778 -1.59434,-1.16422 -2.47225,-3.24889 z m -19.84932,-1.75513 c -0.88826,-1.35565 -1.61277,-3.26815 -1.61004,-4.25 0.004,-1.38626 0.55447,-1.11479 2.46403,1.21482 2.5072,3.05871 3.23781,5.5 1.64601,5.5 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z"
+ id="path3135" />
+ <path
+ style="fill:#f86827"
+ d="m 180.2359,905.85828 c -2.08019,-6.44092 -2.17055,-10.91468 -0.22046,-10.91468 0.79254,0 1.78583,0.55796 2.2073,1.23992 0.51891,0.83962 0.96887,0.43607 1.39375,-1.25 0.46839,-1.85877 0.80267,-0.96902 1.31871,3.51008 0.71114,6.17236 -0.18036,11.60654 -2.00382,12.21436 -0.56872,0.18957 -1.78169,-1.97028 -2.69548,-4.79968 z m -18.5123,-0.55793 c -1.29298,-1.23837 -2.18431,-2.75123 -1.98075,-3.36191 0.20356,-0.61068 1.41357,0.30103 2.68891,2.02602 2.80692,3.79656 2.48839,4.39744 -0.70816,1.33589 z"
+ id="path3133" />
+ <path
+ style="fill:#f8543b"
+ d="m 180.2359,905.85828 c -1.86184,-5.76484 -2.17392,-10.91468 -0.66144,-10.91468 0.55,0 1,0.45 1,1 0,0.55 0.68465,1 1.52144,1 2.50204,0 3.88913,4.40836 2.87647,9.14182 -0.49385,2.30842 -1.38776,4.35915 -1.98647,4.55717 -0.59871,0.19803 -1.83621,-1.95491 -2.75,-4.78431 z m -18.5123,-0.55793 c -1.29298,-1.23837 -2.18431,-2.75123 -1.98075,-3.36191 0.20356,-0.61068 1.41357,0.30103 2.68891,2.02602 2.80692,3.79656 2.48839,4.39744 -0.70816,1.33589 z"
+ id="path3131" />
+ <path
+ style="fill:#f8641b"
+ d="m 180.29865,905.15272 c -0.94831,-3.19444 -1.72419,-6.51091 -1.72419,-7.36993 0,-2.36962 4.94315,-1.05807 6.17129,1.6374 1.14526,2.51357 -0.10153,10.66682 -1.71332,11.20409 -0.55528,0.18509 -1.78548,-2.27711 -2.73378,-5.47156 z"
+ id="path3129" />
+ <path
+ style="fill:#f84936"
+ d="m 180.29609,905.14412 c -0.9469,-3.18971 -1.72163,-6.55059 -1.72163,-7.46861 0,-2.24903 2.73366,-1.14642 3.55227,1.43279 0.39906,1.25732 1.18505,1.76634 2.15355,1.39469 1.29252,-0.49599 1.41642,0.14122 0.81229,4.17768 -1.24083,8.29061 -2.43855,8.40634 -4.79648,0.46345 z"
+ id="path3127" />
+ <path
+ style="fill:#f85818"
+ d="m 181.14286,906.45307 c -1.73239,-4.14621 -2.09098,-9.50947 -0.63579,-9.50947 0.51294,0 1.22859,0.93254 1.59034,2.07232 0.41698,1.31378 1.20605,1.86191 2.15571,1.49749 1.24752,-0.47871 1.38241,0.1362 0.80674,3.67768 -0.9703,5.96925 -2.09631,6.6195 -3.917,2.26198 z"
+ id="path3125" />
+ <path
+ style="fill:#f84528"
+ d="m 181.09683,906.3429 c -0.88794,-2.12514 -1.44768,-5.22186 -1.24388,-6.8816 l 0.37056,-3.0177 0.81643,3.32977 c 0.62382,2.54421 1.24413,3.21792 2.62934,2.85569 1.54861,-0.40498 1.72746,-0.0157 1.22681,2.67022 -0.91755,4.92246 -2.04875,5.23318 -3.79926,1.04362 z"
+ id="path3123" />
+ <path
+ style="fill:#f83b28"
+ d="m 182.18715,908.75698 c -2.04329,-7.19112 -2.31672,-8.87827 -1.51879,-9.37142 0.49836,-0.30799 0.9061,0.36656 0.9061,1.49902 0,1.16357 0.65233,2.05902 1.5,2.05902 0.99331,0 1.5,0.99344 1.5,2.94098 0,3.06564 -1.73817,5.15699 -2.38731,2.8724 z"
+ id="path3121" />
+ <path
+ style="fill:#f8461a"
+ d="m 181.63518,905.09018 c -0.68081,-1.64361 -1.02518,-3.81148 -0.76528,-4.81748 0.38073,-1.47369 0.4951,-1.3919 0.58856,0.4209 0.0661,1.28178 0.76148,2.25 1.616,2.25 1.64633,0 1.93861,1.75999 0.63396,3.81749 -0.60865,0.95987 -1.1714,0.50633 -2.07324,-1.67091 z"
+ id="path3119" />
+ <path
+ style="fill:#f8381c"
+ d="m 182.21283,906.4436 c -0.3471,-0.90455 -0.005,-1.5 0.86163,-1.5 0.86669,0 1.20873,0.59545 0.86163,1.5 -0.31659,0.825 -0.70432,1.5 -0.86163,1.5 -0.15731,0 -0.54504,-0.675 -0.86163,-1.5 z"
+ id="path3117" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="answerYes"
+ transform="matrix(0.54844816,0,0,0.52867521,46.75272,180.67142)">
+ <path
+ style="fill:#5a9908"
+ id="path5"
+ d="m 0,67.872 c 0,34.604 27.145,64.467 61.629,67.638 34.499,3.172 66.779,-21.087 73.093,-55.204 C 141.031,46.197 119.74,11.837 86.312,2.462 52.872,-6.916 16.737,11.293 4.406,43.753 1.485,51.44 0,59.648 0,67.872" />
+ <radialGradient
+ r="63.123501"
+ id="XMLID_2_"
+ gradientUnits="userSpaceOnUse"
+ cy="67.869598"
+ cx="67.9282">
+ <stop
+ style="stop-color:#D1F593"
+ offset="0"
+ id="stop8" />
+ <stop
+ style="stop-color:#81CE09"
+ offset="1"
+ id="stop10" />
+ </radialGradient>
+ <path
+ style="fill:url(#XMLID_2_)"
+ id="path12"
+ d="m 4.805,67.872 c 0,34.4 28.723,63.122 63.124,63.122 34.4,0 63.123,-28.722 63.123,-63.122 0,-34.401 -28.721,-63.125 -63.123,-63.125 -34.402,0 -63.124,28.724 -63.124,63.125" />
+ <path
+ style="fill:#67ba06"
+ id="path14"
+ d="m 10.892,43.334 c -5.097,29.729 12.654,59.589 41.207,69.317 30.282,10.318 64.357,-4.932 77.021,-34.264 -6.086,35.498 -42.582,58.835 -77.36,49.449 C 15.851,118.147 -3.905,77.572 10.892,43.334" />
+ <path
+ style="fill:#b2ed21"
+ id="path16"
+ d="m 28.502,39.848 c 8.729,1.808 18.781,-10.559 26.351,-13.707 14.141,-5.877 31.806,-3.147 44.617,4.857 13.551,8.467 23.19,24.729 24.673,40.692 0.004,0.047 0.004,0.055 0,0.024 -1.001,-9.667 -0.325,-18.753 -4.006,-28.098 C 114.037,28.126 100.845,15.997 84.941,11.124 68.495,6.086 50.512,9.292 36.345,18.893 31.97,21.858 15.131,37.081 28.502,39.848" />
+ <path
+ style="fill:#739b07"
+ id="path18"
+ d="M 98.494,44.133 C 86.456,54.562 74.415,64.986 62.382,75.419 56.471,68.597 50.563,61.775 44.653,54.953 c -2.35,-2.712 -4.534,-5.902 -8.198,-6.885 -5.947,-1.596 -13.654,3.867 -14.911,9.807 -1.695,8.014 9.643,17.108 14.241,22.415 5.265,6.077 10.342,12.396 15.586,18.447 7.188,8.292 13.557,5.293 20.431,-0.663 C 79.525,91.382 87.249,84.691 94.971,78 101.044,72.738 107.116,67.479 113.187,62.218 123.653,53.151 108.883,35.131 98.494,44.133 M 62.877,77.36 c 6.32,-5.475 12.638,-10.949 18.958,-16.424 5.94,-5.146 12.429,-13.128 19.595,-16.615 6.15,-2.99 14.369,4.087 13.905,10.545 -0.28,3.906 -3.333,6.012 -6.002,8.322 -8.16,7.071 -16.32,14.141 -24.481,21.211 C 78.642,89.78 72.43,95.16 66.221,100.54 58.349,107.36 52.325,96.647 47.793,91.416 40.751,83.288 33.71,75.161 26.667,67.034 23.729,63.643 21.563,59.465 24.643,55.201 c 3.501,-4.843 10.741,-8.208 15.394,-2.838 2.859,3.301 20.803,26.339 22.84,24.997" />
+ <path
+ style="fill:#ffffff"
+ id="path20"
+ d="M 114.062,48.424 C 104.437,36.227 94.896,48.434 86.774,55.471 78.614,62.542 70.453,69.613 62.291,76.683 57.247,70.86 52.204,65.038 47.16,59.216 40.872,51.958 35.301,44.496 25.737,52.786 c -8.281,7.179 0.231,14.806 5.142,20.477 6.161,7.11 12.321,14.222 18.484,21.332 4.771,5.508 10.061,13.02 17.857,6.264 5.706,-4.942 11.412,-9.886 17.116,-14.828 7.325,-6.347 14.649,-12.692 21.976,-19.039 5.206,-4.512 14.45,-10.835 7.75,-18.568" />
+ </g>
+ <g
+ id="answerNo"
+ transform="matrix(0.52875705,0,0,0.54826426,149.4278,175.3462)">
+ <path
+ style="fill:#970f00"
+ id="path5-1"
+ d="m 0,67.863 c 0,34.599 27.14,64.461 61.622,67.631 34.495,3.171 66.772,-21.085 73.083,-55.199 C 141.014,46.191 119.727,11.835 86.302,2.461 52.865,-6.917 16.735,11.289 4.405,43.747 1.485,51.434 0,59.64 0,67.863" />
+ <radialGradient
+ r="63.1152"
+ id="XMLID_2_-2"
+ gradientUnits="userSpaceOnUse"
+ cy="67.862297"
+ cx="67.919899">
+ <stop
+ style="stop-color:#F28888"
+ offset="0"
+ id="stop8-2" />
+ <stop
+ style="stop-color:#D82A2A"
+ offset="1"
+ id="stop10-1" />
+ </radialGradient>
+ <path
+ style="fill:url(#XMLID_2_-2)"
+ id="path12-5"
+ d="m 4.804,67.863 c 0,34.395 28.719,63.115 63.115,63.115 34.396,0 63.116,-28.72 63.116,-63.115 0,-34.396 -28.72,-63.116 -63.116,-63.116 -34.396,0 -63.115,28.719 -63.115,63.116" />
+ <path
+ style="fill:#b20d0d"
+ id="path14-0"
+ d="m 10.891,43.33 c -5.1,29.726 12.654,59.582 41.202,69.309 30.278,10.318 64.349,-4.932 77.011,-34.26 -6.084,35.493 -42.578,58.827 -77.351,49.442 C 15.85,118.132 -3.907,77.562 10.891,43.33" />
+ <path
+ style="fill:#ef5656"
+ id="path16-9"
+ d="m 28.499,39.845 c 8.729,1.805 18.779,-10.56 26.347,-13.707 14.14,-5.876 31.802,-3.146 44.611,4.856 13.55,8.466 23.188,24.727 24.67,40.689 0.005,0.046 0.005,0.053 0.001,0.024 -1,-9.667 -0.325,-18.754 -4.006,-28.096 C 114.023,28.123 100.832,15.996 84.93,11.123 68.487,6.084 50.506,9.291 36.34,18.891 31.966,21.857 15.129,37.079 28.499,39.845" />
+ <path
+ style="fill:#ffffff"
+ id="path18-0"
+ d="M 105.449,85.473 C 99.826,79.851 94.203,74.228 88.581,68.603 87.078,67.1 100.904,54.882 102.9,52.886 c 7.668,-7.671 0.39,-12.376 -5.665,-18.431 -2.85,-2.848 -6.832,-7.404 -10.95,-3.286 -3.038,1.911 -5.73,5.731 -8.257,8.257 -2.997,2.997 -5.994,5.994 -8.991,8.993 -0.717,0.717 -4.819,-4.182 -5.51,-4.874 C 59.433,39.451 49.589,25.07 43.046,31.61 c -3.942,3.94 -16.97,12.818 -10.744,19.045 5.749,5.749 11.499,11.499 17.25,17.25 -4.596,4.594 -24.237,18.569 -17.129,25.675 3.683,3.681 7.755,9.715 12.468,12.075 5.366,2.684 11.375,-6.134 14.516,-9.274 1.454,-1.454 8.466,-10.155 10.008,-8.612 4.772,4.772 9.547,9.547 14.321,14.321 4.524,4.523 7.966,4.795 12.61,0.15 3.387,-3.387 14.661,-11.218 9.103,-16.767" />
+ <path
+ style="fill:#970f00"
+ id="path20-4"
+ d="m 47.314,28.939 c -4.432,0 -8.753,6.244 -11.542,9.032 -3.562,3.562 -9.015,8.048 -3.894,13.168 3.525,3.525 7.05,7.052 10.577,10.579 2.586,2.585 7.481,4.89 4.503,7.865 -4.685,4.688 -22.354,17.082 -14.989,24.451 3.37,3.369 6.739,6.738 10.108,10.108 4.631,4.631 8.562,1.91 12.281,-1.808 3.98,-3.979 7.96,-7.958 11.938,-11.937 3.588,-3.586 4.155,-0.684 7.575,2.736 3.733,3.731 7.467,7.463 11.198,11.196 4.87,4.871 8.912,1.183 12.622,-2.526 2.864,-2.861 7.924,-6.298 9.531,-10.177 2.192,-5.292 -4.755,-10.05 -7.932,-13.228 -3.437,-3.433 -6.868,-6.864 -10.303,-10.299 -0.411,-0.411 8.378,-8.773 9.227,-9.622 3.609,-3.609 13.422,-10.526 7.69,-16.267 C 103.16,38.128 98.331,34.638 94.842,31.151 87.236,23.548 73.593,42.932 68.714,47.822 65.214,44.323 61.715,40.826 58.215,37.327 55.521,34.632 51.582,28.986 47.314,28.939 m -3.375,75.243 C 39.305,99.549 26.84,91.528 33.586,84.78 35.78,82.585 51.21,68.653 49.794,67.24 46.325,63.769 42.854,60.3 39.385,56.829 37.013,54.456 31.042,50.344 31.042,46.502 c 0,-3.947 6.2,-8.181 8.653,-10.633 2.969,-2.967 6.924,-8.312 11.298,-3.94 1.706,1.706 17.645,17.799 17.802,17.642 5.612,-5.612 11.313,-13.639 17.944,-17.944 4.365,-4.359 9.224,2.469 12,5.243 2.848,2.85 10.823,8.436 6.254,13.011 -4.306,6.634 -12.334,12.334 -17.947,17.948 -0.024,0.025 -0.051,0.051 -0.077,0.077 5.64,5.64 13.694,11.361 18.024,18.023 4.577,4.568 -3.408,10.163 -6.254,13.011 -3.092,3.092 -7.644,9.6 -12.303,4.938 -2.348,-2.348 -16.979,-18.46 -18.385,-17.054 -3.655,3.655 -18.307,23.185 -24.112,17.358" />
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="51.333321"
+ y="288.88"
+ id="text3723"><tspan
+ sodipodi:role="line"
+ id="tspan3725"
+ x="51.333321"
+ y="288.88">Yes</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+ x="157.33333"
+ y="288.88"
+ id="text3727"><tspan
+ sodipodi:role="line"
+ id="tspan3729"
+ x="157.33333"
+ y="288.88">No</tspan></text>
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/quitIcon.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/quitIcon.svg
new file mode 100755
index 0000000..51d8cdb
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/quitIcon.svg
@@ -0,0 +1,369 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml-stylesheet href="../../css/lesson.css" type="text/css"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ id="quitIcon"
+ class="iconSVG"
+ inkscape:label="PozadĂ­"
+ sodipodi:version="0.32"
+ inkscape:version="0.45"
+ version="1.0"
+ sodipodi:docname="application-exit.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions">
+ <defs
+ id="defs3">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5837">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop5839" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop5841" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5771">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5773" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop5775" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5757">
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:1;"
+ offset="0"
+ id="stop5759" />
+ <stop
+ style="stop-color:#b6b9b2;stop-opacity:1"
+ offset="1"
+ id="stop5761" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5749">
+ <stop
+ style="stop-color:#555753;stop-opacity:1;"
+ offset="0"
+ id="stop5751" />
+ <stop
+ style="stop-color:#d3d7cf;stop-opacity:1"
+ offset="1"
+ id="stop5753" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient5031"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,444.1734,-872.88106)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5060">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop5062" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5064" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient5029"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.7182065,0,0,1.969706,-1790.093,-872.88106)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ id="linearGradient5048">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop5050" />
+ <stop
+ id="stop5056"
+ offset="0.5"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5052" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient5027"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.242688,0,0,1.969706,-1503.9583,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5551">
+ <stop
+ style="stop-color:#d80000;stop-opacity:1;"
+ offset="0"
+ id="stop5553" />
+ <stop
+ style="stop-color:#ff1919;stop-opacity:1"
+ offset="1"
+ id="stop5555" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4962">
+ <stop
+ style="stop-color:#4f7633;stop-opacity:1;"
+ offset="0"
+ id="stop4964" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="1"
+ id="stop4966" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4962"
+ id="linearGradient4968"
+ x1="36"
+ y1="24"
+ x2="36"
+ y2="6.8892298"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.8011917,0,0,1.8095239,-36.032773,-5.4523814)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5551"
+ id="linearGradient5569"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.8216585,0,0,1.8541455,19.808292,-28.322168)"
+ x1="-5"
+ y1="30.485746"
+ x2="-5"
+ y2="28" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5749"
+ id="linearGradient5755"
+ x1="20.736568"
+ y1="8"
+ x2="12.734337"
+ y2="8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.1250002,0,0,1.8421053,-12.062503,-6.4736843)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5757"
+ id="linearGradient5763"
+ x1="15"
+ y1="10"
+ x2="20"
+ y2="10"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.888889,0,0,1.8421053,-9.1111132,-6.4736842)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5771"
+ id="linearGradient5777"
+ x1="19"
+ y1="3"
+ x2="19"
+ y2="10"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.4863836,0,0,1.5000001,-25.26852,-4.0000006)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5837"
+ id="linearGradient5848"
+ gradientUnits="userSpaceOnUse"
+ x1="10"
+ y1="44.016026"
+ x2="10"
+ y2="12.805173"
+ gradientTransform="matrix(0.9130435,0,0,0.9130435,1.7173913,2.2608696)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="13.455176"
+ inkscape:cx="39.875591"
+ inkscape:cy="17.816185"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ width="48px"
+ height="48px"
+ inkscape:showpageshadow="false"
+ gridtolerance="10000"
+ inkscape:window-width="1278"
+ inkscape:window-height="965"
+ inkscape:window-x="0"
+ inkscape:window-y="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4948" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata6">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Vrstva 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ style="display:inline"
+ id="g5022"
+ transform="matrix(2.080446e-2,0,0,1.7667008e-2,41.56675,40.26266)">
+ <rect
+ y="-150.69685"
+ x="-1234.8357"
+ height="478.35718"
+ width="1082.8979"
+ id="rect4173"
+ style="opacity:0.39195981;color:#000000;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path5058"
+ d="M -151.93764,-150.67604 C -151.93764,-150.67604 -151.93764,327.65475 -151.93764,327.65475 C -11.956731,328.5552 186.46809,220.48509 186.46801,88.458574 C 186.46801,-43.567963 30.259854,-150.67602 -151.93764,-150.67604 z"
+ style="opacity:0.40206185;color:#000000;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="opacity:0.40206185;color:#000000;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M -1227.8411,-150.67604 C -1227.8411,-150.67604 -1227.8411,327.65475 -1227.8411,327.65475 C -1370.7153,328.5552 -1573.2413,220.48509 -1573.2413,88.458573 C -1573.2413,-43.567964 -1413.8045,-150.67602 -1227.8411,-150.67604 z"
+ id="path5018"
+ sodipodi:nodetypes="cccc" />
+ </g>
+ <rect
+ style="opacity:1;color:#000000;fill:url(#linearGradient4968);fill-opacity:1;fill-rule:nonzero;stroke:#2e3436;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect4960"
+ width="27.017878"
+ height="38"
+ x="13.5"
+ y="4.5" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#73d216;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.36486487"
+ d="M 15.574321,41.529642 L 39.5115,41.529642 L 39.5115,5.7229624"
+ id="path5547"
+ sodipodi:nodetypes="ccc" />
+ <path
+ style="color:#000000;fill:url(#linearGradient5763);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5755);stroke-width:0.99999987999999995px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 14.5,5.5000001 L 31.5,5.5000001 L 31.5,33.131579 L 14.5,40.5 L 14.5,5.5000001 z"
+ id="rect5746"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#linearGradient5569);fill-opacity:1;fill-rule:nonzero;stroke:#a60f11;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 13.482087,14.5 L 13.482087,20.466898 L 2.5025365,20.466898 L 2.5025365,31.574563 L 13.482087,31.574563 L 13.482087,37.499999 L 26.500001,26.375127 L 13.482087,14.5 z"
+ id="rect5549"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999988px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.23873877;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 14.503737,16.777476 L 14.503737,21.515111 L 3.5201752,21.515111 L 3.5201752,30.552669 L 14.503737,30.552669 L 14.503737,35.259942 L 24.866255,26.31942 L 14.503737,16.777476 z"
+ id="path5561"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.61261261"
+ d="M 30.546104,7.3868349 L 30.528133,32.373144 L 15.500001,38.969853"
+ id="path5765"
+ sodipodi:nodetypes="ccc" />
+ <path
+ style="fill:url(#linearGradient5777);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 17,5 L 29.431919,11 L 36.89107,11 L 36.89107,5 L 17,5 z"
+ id="path5769" />
+ <rect
+ style="opacity:1;color:#000000;fill:#555753;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5797"
+ width="1"
+ height="1"
+ x="28"
+ y="19" />
+ <rect
+ y="20"
+ x="29"
+ height="1"
+ width="1"
+ id="rect5799"
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5805"
+ width="0.99999976"
+ height="1"
+ x="29"
+ y="21" />
+ <rect
+ y="21"
+ x="28"
+ height="1"
+ width="0.99999976"
+ id="rect5807"
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5829"
+ width="0.99999976"
+ height="1"
+ x="27"
+ y="22" />
+ <rect
+ y="20"
+ x="28"
+ height="1"
+ width="1"
+ id="rect5831"
+ style="opacity:1;color:#000000;fill:#555753;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <rect
+ style="opacity:1;color:#000000;fill:#555753;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ id="rect5833"
+ width="1"
+ height="1"
+ x="28"
+ y="22" />
+ <path
+ style="opacity:0.52401747;color:#000000;fill:url(#linearGradient5848);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.23873876999999999;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 14.014946,15.5 L 14.014946,20.949728 L 4,20.949728 L 4,23.432065 C 6.3080298,24.978602 10.143561,26 14.5,26 C 18.0582,26 21.283715,25.321421 23.601902,24.230978 L 14.014946,15.5 z"
+ id="path5835" />
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship1.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship1.svg
new file mode 100755
index 0000000..0572a51
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship1.svg
@@ -0,0 +1,597 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="120"
+ height="220"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="spaceship1.svg">
+ <defs
+ id="defs4">
+ <inkscape:path-effect
+ effect="skeletal"
+ id="path-effect3784"
+ is_visible="true"
+ pattern="M 0,5 C 0,2.24 2.24,0 5,0 7.76,0 10,2.24 10,5 10,7.76 7.76,10 5,10 2.24,10 0,7.76 0,5 z"
+ copytype="single_stretched"
+ prop_scale="1"
+ scale_y_rel="false"
+ spacing="0"
+ normal_offset="0"
+ tang_offset="0"
+ prop_units="false"
+ vertical_pattern="false"
+ fuse_tolerance="0" />
+ <inkscape:path-effect
+ effect="skeletal"
+ id="path-effect3780"
+ is_visible="true"
+ pattern="m -38,719.36218 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 z"
+ copytype="single_stretched"
+ prop_scale="1"
+ scale_y_rel="false"
+ spacing="0"
+ normal_offset="0"
+ tang_offset="0"
+ prop_units="false"
+ vertical_pattern="false"
+ fuse_tolerance="0" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <inkscape:perspective
+ id="perspective2923"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective3930"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4003"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4133"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4204"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2913"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective3053"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2898"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective3109"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="73.574468"
+ inkscape:cy="105.41855"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-832.36218)">
+ <g
+ id="g3211">
+ <path
+ inkscape:original-d="m 37,942.81046 c 0.574713,0.14367 1.149425,0.28735 0,0 z"
+ inkscape:path-effect="#path-effect3780"
+ id="path3778"
+ d="m 37,942.81046 c 0.167098,-0.66843 0.34309,-1.2936 0.486364,-1.7242 0.143274,-0.4306 0.253551,-0.66551 0.31386,-0.65187 0.06031,0.0136 0.07065,0.2758 0.04077,0.73251 -0.02988,0.45671 -0.09969,1.10684 -0.175087,1.79783 -0.0015,0.004 -0.003,0.007 -0.0044,0.0112 -0.257922,0.64338 -0.501864,1.24926 -0.690253,1.66648 -0.188389,0.41721 -0.32095,0.64463 -0.380785,0.62966 -0.05983,-0.015 -0.04694,-0.27232 0.02884,-0.7177 0.07578,-0.44537 0.21418,-1.07766 0.380734,-1.74389 0.166554,-0.66623 0.341982,-1.28926 0.484718,-1.7179 0.142736,-0.42864 0.252501,-0.66177 0.312355,-0.64682 0.05985,0.015 0.06979,0.27801 0.03961,0.73477 -0.03018,0.45676 -0.100211,1.10613 -0.175623,1.79513 -4.36e-4,0.004 -8.73e-4,0.008 -0.0013,0.0119 -0.258431,0.64522 -0.502606,1.25177 -0.691076,1.66883 -0.188471,0.41707 -0.320958,0.64354 -0.380601,0.62718 -0.05964,-0.0163 -0.04644,-0.27553 0.02975,-0.72289 0.07619,-0.44737 0.215079,-1.08182 0.382177,-1.75025 z"
+ style="fill:#000000;fill-rule:evenodd;stroke:none" />
+ <g
+ transform="translate(-184.55172,103.22414)"
+ id="g4020">
+ <path
+ style="fill:#d45500;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 235.65719,857.2309 c -5.15468,-1.08647 -10.13216,-2.60614 -11.06105,-3.37705 -1.4687,-1.21891 -1.59942,-3.62164 -1.0026,-18.42851 0.60898,-15.10833 2.82784,-34.89255 4.50742,-40.18992 0.5468,-1.72458 2.1597,-1.86153 18.79408,-1.59574 l 18.19595,0.29073 0.86603,3.19149 c 1.42964,5.26854 4.21348,40.89938 3.86495,49.46809 l -0.32454,7.97872 -6.91489,1.70857 c -11.71067,2.89354 -16.85673,3.0758 -26.92535,0.95362 l 0,0 z"
+ id="shipBody" />
+ <path
+ style="fill:#008000;fill-opacity:0.93984112;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 244.48826,894.22212 c -4.2024,-0.66031 -8.30588,-1.6713 -9.34259,-2.30176 -1.50562,-0.91562 -2.96927,-3.83924 -5.28678,-10.56029 -3.38846,-9.8269 -6.66033,-24.37913 -5.69774,-25.34172 0.34613,-0.34613 1.65904,0.0304 4.83607,1.387 l 4.36096,1.86212 8.04349,-0.30495 c 4.42393,-0.16772 9.30427,-0.48845 10.84522,-0.71273 1.54095,-0.22428 5.51724,-0.5933 8.83621,-0.82003 3.31896,-0.22673 6.77423,-0.53583 7.67837,-0.68688 l 1.64389,-0.27464 -0.27403,1.65891 c -1.72541,10.44502 -5.37775,23.19669 -9.194,32.09965 l -0.81901,1.91067 -5.12106,0.9443 c -5.68087,1.04752 -8.8862,1.39534 -10.509,1.14035 z"
+ id="shipBottom" />
+ <path
+ style="fill:#ff0000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 207.75862,910.1208 1.2931,-9.48276 3.44828,-6.46552 4.31034,-6.89655 5.17242,-6.03448 4.31034,-2.58621 1.72414,-1.2931 3.87931,12.06896 0.43104,1.72414"
+ id="shipLtWing" />
+ <path
+ style="fill:#ff0000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 262.06896,892.44839 3.01724,-12.5 9.05172,5.17241 5.17242,6.46552 2.15517,4.74138 3.44827,8.18965 2.58621,10.34483 -8.18965,-9.91379 -6.03449,-5.17242 -4.74138,-3.44827 -6.46551,-3.87931 z"
+ id="shipRtWing" />
+ <g
+ id="shipCone">
+ <g
+ id="g3822">
+ <path
+ style="fill:#ffff00;fill-opacity:0.93984112;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 238.05674,793.18103 c -6.10246,-0.52204 -8.42268,-0.87219 -8.56122,-1.29204 -0.10453,-0.31675 0.30123,-1.48054 0.90169,-2.5862 0.60047,-1.10566 1.46952,-3.46503 1.93123,-5.24305 1.03163,-3.97271 6.17659,-18.26477 6.64632,-18.46264 0.1876,-0.079 0.34109,-0.38714 0.34109,-0.68471 0,-1.96184 7.19772,-16.19748 8.18965,-16.19748 0.56862,0 3.86104,5.678 5.49864,9.48276 2.06526,4.7984 7.19953,18.13611 8.29619,21.55173 4.18191,13.02476 4.23136,13.3315 2.15345,13.35671 -1.19212,0.0144 -10.09252,0.40818 -13.57759,0.60062 -1.89655,0.10473 -7.2153,-0.13184 -11.81945,-0.5257 l 0,0 z"
+ id="path3814" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 247.84482,749.34494 c -0.43103,-9.91379 -0.43103,-9.91379 -0.43103,-9.91379 l 0,0.43103"
+ id="path3820" />
+ </g>
+ </g>
+ <path
+ style="fill:#800080;fill-opacity:0.93984112;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 235.50249,906.17356 c 0,-1.06703 4.59976,-12.40994 5.03247,-12.40994 0.74921,0 3.52178,11.5796 2.85187,11.91094 -1.14852,0.56809 -7.88434,0.9944 -7.88434,0.499 z"
+ id="shipLtJet" />
+ <path
+ style="fill:#800080;fill-opacity:0.93984112;stroke:#000000;stroke-width:2.81490302;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 252.67238,906.11389 c -1.35952,-0.18394 -1.44042,-0.348 -1.11133,-2.25333 0.1952,-1.1302 0.82906,-3.53453 1.40857,-5.34296 l 1.05363,-3.28807 1.72233,4.60998 c 0.9473,2.53547 1.8799,5.05611 2.07247,5.60139 0.31242,0.88465 0.13311,0.98497 -1.66464,0.93143 -1.10813,-0.033 -2.67459,-0.1493 -3.48103,-0.25844 z"
+ id="shipRtJet" />
+ </g>
+ <g
+ transform="translate(-171.5,206.5)"
+ id="shipFire1">
+ <path
+ id="path3024"
+ d="m 213.07446,821.01373 0,-15 20,0 20,0 0,15 0,15 -20,0 -20,0 0,-15 z"
+ style="fill:#fefefd" />
+ <path
+ id="path3022"
+ d="m 242.07446,835.28173 c -3.61556,-0.66474 -4.70548,-1.87312 -5.45964,-6.05304 -2.27423,-12.60493 -1.42549,-20.52872 2.31719,-21.6331 1.32002,-0.38951 6.93368,-0.22942 11.39245,0.3249 0.4125,0.0513 0.75,1.64168 0.75,3.53422 0,1.89254 0.45,3.7191 1,4.05902 2.54527,1.57306 0.0351,18.5 -2.74348,18.5 -0.69109,0 -1.25652,0.45 -1.25652,1 0,1.01912 -1.54039,1.08792 -6,0.268 z m -21.75,-0.93028 c -0.6875,-0.27741 -1.25689,-1.25439 -1.26531,-2.17105 -0.0124,-1.35224 -0.18204,-1.40336 -0.89908,-0.27095 -0.50392,0.79583 -1.59909,1.12122 -2.54807,0.75706 -1.94705,-0.74715 -1.12949,-2.65278 1.13811,-2.65278 1.15603,0 1.37715,-0.5801 0.85766,-2.25 -2.33632,-7.51012 -1.67256,-19.75 1.07102,-19.75 0.83254,0 1.23559,-0.45 0.89567,-1 -0.87696,-1.41896 2.8546,-1.2454 4.3,0.2 0.93333,0.93333 1.46667,0.93333 2.4,0 1.58906,-1.58906 5.28176,-1.52936 6.6401,0.10734 1.42636,1.71865 1.17235,25.91644 -0.28266,26.92735 -1.17512,0.81645 -10.34907,0.89325 -12.30744,0.10303 z"
+ style="fill:#fdfbf4" />
+ <path
+ id="path3020"
+ d="m 243.63248,835.10761 c -0.30801,-0.49837 -1.3785,-0.69208 -2.37887,-0.43048 -2.77871,0.72665 -3.72489,-1.36607 -5.04726,-11.1634 -2.04821,-15.17496 -0.0992,-17.37091 13.86811,-15.625 0.55,0.0688 1,1.925 1,4.125 0,2.2 0.45,4 1,4 0.55445,0 1,2.64699 1,5.94098 0,3.26754 -0.45,6.2191 -1,6.55902 -0.55,0.33992 -1,1.39147 -1,2.33678 0,3.26484 -5.95123,6.66918 -7.44198,4.2571 z m -22.74632,-1.31683 c -4.37516,-3.39748 -6.23457,-22.53224 -2.45791,-25.2938 0.88832,-0.64955 1.32212,-1.47401 0.964,-1.83213 -0.35812,-0.35811 0.23388,-0.65112 1.31554,-0.65112 1.08167,0 2.41295,0.44628 2.95841,0.99174 0.65566,0.65566 2.0518,0.59162 4.11984,-0.18897 5.54377,-2.09255 6.17944,-0.58472 6.01373,14.26467 -0.11976,10.73113 -0.40636,12.99629 -1.68481,13.31597 -3.61444,0.9038 -9.7078,0.57475 -11.2288,-0.60636 z"
+ style="fill:#fef4f3" />
+ <path
+ id="path3018"
+ d="m 244.07446,834.94634 c 0,-0.58706 -0.83647,-0.8019 -1.85882,-0.47742 -2.45124,0.778 -4.46558,-1.75044 -4.35975,-5.47246 0.0461,-1.62139 -0.33587,-3.20735 -0.84881,-3.52437 -0.51294,-0.31702 -0.93262,-3.69984 -0.93262,-7.51738 0,-5.70987 0.37113,-7.31211 2.09245,-9.03343 1.38572,-1.38572 2.82118,-1.89697 4.25,-1.51366 1.18665,0.31834 3.62005,0.58495 5.40755,0.59246 3.11458,0.0131 3.25,0.17786 3.25,3.95463 0,2.16754 0.45,4.2191 1,4.55902 2.55736,1.58053 0.26642,14.37644 -3.19334,17.8362 -1.86559,1.86559 -4.80666,2.23052 -4.80666,0.59641 z m -23.25021,-1.32568 c -1.57289,-1.57289 -3.54882,-8.77472 -3.87044,-14.10693 -0.37645,-6.24113 0.18337,-9.26629 2.13011,-11.51091 1.80021,-2.07566 2.26525,-2.18003 4.46591,-1.00227 1.95295,1.04519 2.76106,1.06185 3.94255,0.0813 1.957,-1.62417 5.3134,-0.49003 6.12591,2.06997 0.35537,1.11968 0.33438,3.68417 -0.0466,5.69885 -0.38103,2.01468 -0.67234,7.15056 -0.64735,11.41306 0.025,4.2625 -0.0435,7.77018 -0.1522,7.79485 -0.1087,0.0247 -2.49663,0.28103 -5.30652,0.56969 -3.79428,0.38978 -5.50321,0.13051 -6.64132,-1.00761 z"
+ style="fill:#fdf4eb" />
+ <path
+ id="path3016"
+ d="m 244.07446,834.94634 c 0,-0.58706 -0.83647,-0.8019 -1.85882,-0.47742 -3.38388,1.074 -4.23225,-1.44367 -5.76062,-17.09567 -0.53162,-5.44427 -0.34995,-6.39014 1.60237,-8.34245 1.47838,-1.47838 2.91097,-2.01178 4.35952,-1.62318 1.18665,0.31834 3.62005,0.58495 5.40755,0.59246 3.11458,0.0131 3.25,0.17786 3.25,3.95463 0,2.16754 0.45,4.2191 1,4.55902 0.55,0.33992 1,2.81492 1,5.5 0,2.68508 -0.45,5.16008 -1,5.5 -0.55,0.33992 -1.01497,1.37898 -1.03327,2.30902 -0.0711,3.61539 -6.96673,8.68668 -6.96673,5.12359 z m -22.64106,-0.66363 c -1.91418,-1.29 -4.35894,-11.2719 -4.35894,-17.79747 0,-4.73983 0.46465,-6.70124 2.00946,-8.48242 1.77348,-2.04484 2.28725,-2.16825 4.375,-1.05093 1.76257,0.94331 2.88873,0.986 4.4181,0.16751 1.1289,-0.60417 2.72536,-0.84032 3.54768,-0.52477 1.72841,0.66326 2.91023,3.18863 2.10325,4.49435 -0.30414,0.49212 -0.57989,5.85151 -0.61276,11.90975 -0.0329,6.05825 -0.12298,11.03518 -0.20025,11.05985 -1.91464,0.61129 -10.45528,0.78097 -11.28154,0.22413 z"
+ style="fill:#fde9e8" />
+ <path
+ id="path3014"
+ d="m 244.57446,835.01373 c -0.33992,-0.55 -1.47564,-1 -2.52383,-1 -1.97232,0 -4.2255,-3.08944 -3.83717,-5.26131 0.12181,-0.68128 -0.36745,-3.1064 -1.08723,-5.38916 -1.49453,-4.73979 -0.72255,-12.54794 1.41606,-14.32284 0.76462,-0.63457 3.72517,-1.00206 6.70099,-0.83176 5.29729,0.30313 5.33322,0.32732 5.65248,3.80507 0.17671,1.925 0.73921,3.9275 1.25,4.45 1.2472,1.2758 1.18916,10.271 -0.0713,11.05 -0.55,0.33992 -1.01497,1.37898 -1.03327,2.30902 -0.0389,1.97564 -3.31937,6.19098 -4.81801,6.19098 -0.56688,0 -1.3088,-0.45 -1.64872,-1 z m -22.84924,-1.35207 c -1.97934,-1.56449 -4.65076,-11.41412 -4.65076,-17.14754 0,-6.75939 3.72786,-12.41603 6.42573,-9.75039 0.41749,0.4125 2.62999,0.75 4.91667,0.75 l 4.1576,0 0,12.33739 c 0,6.78557 -0.225,12.68061 -0.5,13.10011 -0.8974,1.36892 -8.82744,1.91328 -10.34924,0.71043 z"
+ style="fill:#fce7d8" />
+ <path
+ id="path3012"
+ d="m 244.57446,835.01373 c -0.33992,-0.55 -1.46492,-1 -2.5,-1 -2.41107,0 -3.39583,-1.62821 -3.62887,-6 -0.10262,-1.925 -0.64182,-5.23675 -1.19822,-7.35943 -1.16711,-4.45251 -0.49978,-10.1244 1.37416,-11.67963 0.70982,-0.5891 3.68961,-0.93381 6.62175,-0.76601 5.29729,0.30313 5.33322,0.32732 5.65248,3.80507 0.17671,1.925 0.73921,3.9275 1.25,4.45 1.62476,1.66202 0.89746,9.87212 -1.15604,13.05 -1.06621,1.65 -2.2108,3.7875 -2.54354,4.75 -0.66038,1.91026 -2.88796,2.34176 -3.87172,0.75 z m -22.70147,-1.09287 c -2.10735,-1.17933 -5.26736,-16.59451 -4.37589,-21.34647 0.37824,-2.01617 1.33529,-3.91428 2.12679,-4.218 0.7915,-0.30373 1.14285,-1.03155 0.78078,-1.61738 -0.44012,-0.71214 -0.0239,-0.78737 1.25575,-0.22698 1.05272,0.46099 3.93904,0.87497 6.41404,0.91994 l 4.5,0.0818 0,12.33679 c 0,6.78523 -0.225,12.68028 -0.5,13.1001 -0.78115,1.19253 -8.49355,1.92604 -10.20147,0.97024 z"
+ style="fill:#fcd8d7" />
+ <path
+ id="path3010"
+ d="m 242.57446,833.95903 c -3.20603,-2.03958 -4.16764,-5.04031 -5.16057,-16.10371 -0.72246,-8.04973 0.49024,-9.84159 6.66057,-9.84159 5.32878,0 7,1.49636 7,6.26759 0,1.31949 0.3116,2.71067 0.69244,3.09151 2.0309,2.03091 0.53343,11.77013 -2.17427,14.1409 -0.62816,0.55 -1.4376,1.7875 -1.79876,2.75 -0.80647,2.1493 -1.41806,2.11359 -5.21941,-0.3047 z m -21.40349,-1.32901 c -2.16359,-2.60697 -4.21239,-16.47222 -3.06414,-20.73651 0.5746,-2.13388 1.50393,-3.87978 2.06519,-3.87978 0.56126,0 0.74236,-0.45 0.40244,-1 -0.33992,-0.55 -0.16803,-1 0.38197,-1 0.55,0 1.30476,0.49312 1.67725,1.09581 0.42872,0.69369 2.27301,0.85652 5.02583,0.44371 4.00954,-0.60127 4.39578,-0.4641 4.95383,1.75938 0.33289,1.32633 0.17976,5.51416 -0.34028,9.3063 -0.52004,3.79214 -0.71908,8.40715 -0.4423,10.25559 0.33321,2.22535 0.0371,3.65603 -0.87654,4.23468 -2.15612,1.36563 -8.51049,1.05439 -9.78325,-0.47918 z"
+ style="fill:#fcd5ca" />
+ <path
+ id="path3008"
+ d="m 243.68265,834.51799 c -1.0405,-0.78767 -2.33516,-1.57991 -2.87702,-1.76054 -0.54187,-0.18062 -1.41387,-2.55935 -1.93778,-5.28606 -3.0569,-15.90966 -1.92574,-19.54051 5.94911,-19.09566 4.63102,0.2616 4.78408,0.37335 5.7575,4.20337 0.55,2.16405 1.25034,4.38463 1.5563,4.93463 0.93611,1.68273 1.17286,7.75954 0.28091,7.21035 -0.46047,-0.28352 -0.94017,0.89999 -1.06601,2.63002 -0.12585,1.73002 -0.71743,3.30837 -1.31463,3.50744 -0.5972,0.19907 -1.4956,1.43975 -1.99644,2.75706 -1.04556,2.75002 -1.7225,2.88992 -4.35194,0.89939 z m -23.21506,-4.10579 c -0.82765,-1.98085 -1.76416,-7.27639 -2.08112,-11.76788 -0.69109,-9.79271 0.0645,-10.82627 8.1771,-11.18559 6.36395,-0.28187 6.33231,-0.34421 5.34251,10.52779 -0.37691,4.13996 -0.4504,8.95097 -0.16332,10.69111 0.6047,3.66532 -1.47859,5.3361 -6.65359,5.3361 -2.63353,0 -3.35007,-0.55839 -4.62158,-3.60153 z"
+ style="fill:#fcc9c7" />
+ <path
+ id="path3006"
+ d="m 242.82446,833.6902 c -1.61209,-1.31992 -2.76466,-3.27052 -2.78544,-4.71403 -0.0195,-1.35434 -0.67854,-3.58744 -1.46456,-4.96244 -1.78022,-3.11416 -1.88229,-9.68857 -0.20184,-13 1.05742,-2.08371 1.98633,-2.5 5.57849,-2.5 2.3704,0 4.64398,0.225 5.0524,0.5 0.77148,0.51946 4.08252,12.93329 4.05564,15.20552 -0.0109,0.92215 -0.29413,0.86304 -0.98469,-0.20552 -0.72513,-1.12206 -0.97323,-0.59421 -0.98469,2.09501 -0.01,2.31035 -0.73,4.2418 -2.01531,5.40499 -1.1,0.99549 -2,2.41523 -2,3.15499 0,1.87693 -1.06079,1.6327 -4.25,-0.97852 z m -21.53193,-1.30802 c -1.46348,-2.79289 -3.21807,-11.89557 -3.21807,-16.69516 0,-6.48241 1.72588,-8.19989 8.13495,-8.09535 l 5.36505,0.0875 -0.22431,12.30825 c -0.12337,6.76954 -0.4237,12.50765 -0.66741,12.75135 -0.24371,0.24371 -2.23591,0.68357 -4.42712,0.97748 -3.21272,0.43091 -4.17356,0.17264 -4.96309,-1.33408 z"
+ style="fill:#fcc5ba" />
+ <path
+ id="path3004"
+ d="m 242.72748,833.17345 c -1.45916,-1.52303 -2.65302,-3.77287 -2.65302,-4.99962 0,-1.22676 -0.71048,-3.3148 -1.57885,-4.6401 -1.21102,-1.84824 -1.41802,-3.69689 -0.88852,-7.93489 0.8518,-6.81759 1.87668,-7.75237 7.45543,-6.80001 4.33601,0.74022 4.33744,0.74189 6.17057,7.22764 2.11406,7.4797 2.20996,8.3331 0.84137,7.48726 -0.5944,-0.36736 -1,0.81122 -1,2.9058 0,2.50038 -0.58088,3.83471 -2,4.5942 -1.1,0.5887 -2,1.70298 -2,2.47617 0,2.59556 -1.67384,2.47371 -4.34698,-0.31645 z m -21.75005,-1.90972 c -0.57613,-1.5125 -1.56141,-6.27033 -2.18949,-10.57295 -0.9585,-6.56609 -0.90464,-8.24579 0.33523,-10.45476 1.29461,-2.30651 2.12301,-2.6374 6.70205,-2.67705 3.65715,-0.0317 5.39105,0.38694 5.77872,1.39515 0.30463,0.79221 0.24376,6.34107 -0.13525,12.3308 -0.65213,10.306 -0.81885,10.93975 -3.10677,11.80962 -4.21264,1.60164 -6.27144,1.09121 -7.38449,-1.83081 z"
+ style="fill:#fcc7ab" />
+ <path
+ id="path3002"
+ d="m 242.72748,833.17345 c -1.45916,-1.52303 -2.65302,-3.78662 -2.65302,-5.03018 0,-1.24356 -0.50847,-3.21112 -1.12994,-4.37234 -1.56807,-2.92996 -1.34949,-12.70635 0.32145,-14.37728 0.98111,-0.98111 2.56078,-1.1472 5.74345,-0.60388 l 4.39011,0.74945 1.83356,6.48725 c 2.11406,7.4797 2.20996,8.3331 0.84137,7.48726 -0.5944,-0.36736 -1,0.81122 -1,2.9058 0,2.50038 -0.58088,3.83471 -2,4.5942 -1.1,0.5887 -2,1.70298 -2,2.47617 0,2.59556 -1.67384,2.47371 -4.34698,-0.31645 z m -21.16934,-0.40972 c -1.00952,-2.78225 -3.48368,-16.06654 -3.48368,-18.70459 0,-1.55311 0.81514,-3.8305 1.81143,-5.06086 1.59417,-1.96872 2.06504,-2.07864 3.92591,-0.91651 1.63188,1.01913 2.68278,1.06157 4.6045,0.18598 3.50792,-1.59832 3.87749,-0.0223 3.05239,13.01717 -0.65213,10.306 -0.81885,10.93975 -3.10677,11.80962 -3.38037,1.28521 -6.26837,1.14479 -6.80378,-0.33081 z"
+ style="fill:#fcbab6" />
+ <path
+ id="path3000"
+ d="m 242.73813,833.03845 c -4.45265,-4.50136 -6.26388,-22.81295 -2.40301,-24.2945 0.70285,-0.26971 3.01297,-0.20685 5.1336,0.1397 3.80086,0.62112 3.88065,0.72606 5.61127,7.38008 1.5237,5.8584 1.55892,6.75 0.26662,6.75 -1.07585,0 -1.32041,0.67158 -0.88145,2.42054 0.75665,3.01474 -0.16163,5.57946 -1.99769,5.57946 -0.76616,0 -1.39301,0.9 -1.39301,2 0,2.47359 -1.90323,2.48443 -4.33633,0.0247 z m -20.53807,-0.37338 c -1.73818,-2.09438 -4.37739,-16.49565 -3.69229,-20.14755 0.79299,-4.22701 2.99091,-6.22653 5.00602,-4.55414 0.79163,0.657 2.92913,1.0496 4.75,0.87244 l 3.31067,-0.32209 -0.34477,11 c -0.20547,6.55563 -0.81152,11.45488 -1.5,12.12585 -1.93738,1.8881 -6.31852,2.48479 -7.52963,1.02549 z"
+ style="fill:#fbb5a7" />
+ <path
+ id="path2998"
+ d="m 242.74941,832.85535 c -1.00378,-1.09545 -2.07693,-3.54387 -2.38478,-5.44095 -0.30786,-1.89708 -0.94908,-3.68987 -1.42495,-3.98397 -0.98296,-0.6075 -1.18061,-10.43123 -0.25823,-12.83491 0.43906,-1.14417 1.9607,-1.58179 5.5,-1.58179 2.69115,0 4.89301,0.11393 4.89301,0.25318 0,0.13925 0.87979,3.32964 1.95508,7.08976 1.63533,5.71845 1.7122,6.74336 0.47002,6.26669 -1.16731,-0.44794 -1.43336,0.19801 -1.24339,3.01886 0.1645,2.4426 -0.30498,3.98848 -1.47001,4.84037 -0.94143,0.68839 -1.7117,1.98952 -1.7117,2.89138 0,2.18799 -2.07266,1.93946 -4.32505,-0.51862 z m -20.55781,-0.20048 c -1.4948,-1.80112 -3.11714,-10.71274 -3.11714,-17.12264 0,-3.84785 0.49654,-5.65789 1.90072,-6.92866 1.33134,-1.20484 2.1105,-1.38071 2.60099,-0.58707 0.38515,0.62319 2.34233,0.99695 4.34928,0.83059 l 3.64901,-0.30248 -0.34477,10.98456 c -0.20539,6.54387 -0.81179,11.4397 -1.5,12.11041 -1.94466,1.8952 -6.31888,2.48436 -7.53809,1.01529 z"
+ style="fill:#fac58e" />
+ <path
+ id="path2996"
+ d="m 242.83096,832.93689 c -2.94316,-3.22449 -5.60815,-16.3938 -4.34,-21.4465 0.5574,-2.22086 1.13605,-2.47666 5.60255,-2.47666 2.73952,0 4.98095,0.11393 4.98095,0.25318 0,0.13925 0.87979,3.32964 1.95508,7.08976 1.63533,5.71845 1.7122,6.74336 0.47002,6.26669 -1.16731,-0.44794 -1.43336,0.19801 -1.24339,3.01886 0.1645,2.4426 -0.30498,3.98848 -1.47001,4.84037 -0.94143,0.68839 -1.7117,1.98952 -1.7117,2.89138 0,2.1614 -2.06598,1.94861 -4.2435,-0.43708 z m -20.63936,-0.28202 c -1.47885,-1.7819 -3.11714,-10.68981 -3.11714,-16.94889 0,-6.60802 1.99523,-9.09493 5.73865,-7.15281 1.76179,0.91402 3.1716,1.04377 4.37036,0.40222 1.04167,-0.55749 1.99888,-0.57611 2.32696,-0.0453 0.95894,1.55161 -0.68277,22.06632 -1.83817,22.9696 -2.18264,1.70635 -6.3495,2.13812 -7.48066,0.77515 z"
+ style="fill:#fbaaa7" />
+ <path
+ id="path2994"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.0515,-6.01599 1.33352,-7.68426 6.37947,-7.68426 l 4.34174,0 1.57906,6.25 c 0.93854,3.71477 1.19128,6.38521 0.62307,6.58333 -0.52579,0.18334 -0.95599,2.08 -0.95599,4.21482 0,2.90633 -0.52195,4.16082 -2.07756,4.99336 -1.18986,0.63679 -1.84419,1.72003 -1.53138,2.53518 0.75202,1.95974 -0.51507,1.68385 -2.78464,-0.60632 z m -22.50743,-2.65246 c -0.67213,-1.47516 -1.48641,-6.42813 -1.80952,-11.00662 -0.50391,-7.14044 -0.33132,-8.60756 1.21332,-10.31438 1.398,-1.54476 2.11011,-1.73314 3.18364,-0.84218 0.76057,0.63121 2.7832,1.10784 4.49474,1.05918 l 3.1119,-0.0885 -0.67703,11.14712 c -0.71175,11.71885 -1.14547,12.68517 -5.70553,12.71214 -1.84671,0.0109 -2.94001,-0.75403 -3.81152,-2.66678 z"
+ style="fill:#fbb49a" />
+ <path
+ id="path2992"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.052,-6.07612 1.23838,-7.55975 6.40123,-7.35994 l 4.44502,0.17203 1.51654,6.00183 c 0.90536,3.58303 1.13127,6.13616 0.56055,6.33515 -0.52579,0.18334 -0.95599,1.98759 -0.95599,4.00946 0,2.64232 -0.58597,4.04206 -2.08368,4.9774 -1.18202,0.73818 -1.84469,1.92409 -1.53139,2.74055 0.75759,1.97424 -0.50224,1.70656 -2.77851,-0.59037 z m -22.4942,-3.07829 c -0.59588,-1.70936 -1.38003,-6.66446 -1.74254,-11.01134 -0.56917,-6.82476 -0.41058,-8.17807 1.16197,-9.91572 1.22799,-1.3569 2.04728,-1.64633 2.51555,-0.88865 0.38194,0.61799 2.39249,1.12363 4.46789,1.12363 l 3.77345,0 -0.67477,11.10983 c -0.71119,11.70969 -1.1381,12.64814 -5.76595,12.67486 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z"
+ style="fill:#facb7b" />
+ <path
+ id="path2990"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.052,-6.07612 1.23838,-7.55975 6.40123,-7.35994 l 4.44502,0.17203 1.51654,6.00183 c 0.90536,3.58303 1.13127,6.13616 0.56055,6.33515 -0.52579,0.18334 -0.95599,1.98759 -0.95599,4.00946 0,2.64232 -0.58597,4.04206 -2.08368,4.9774 -1.18202,0.73818 -1.84469,1.92409 -1.53139,2.74055 0.75759,1.97424 -0.50224,1.70656 -2.77851,-0.59037 z m -22.4942,-3.07829 c -0.59588,-1.70936 -1.38003,-6.66446 -1.74254,-11.01134 -0.56214,-6.74048 -0.40015,-8.18959 1.10089,-9.84822 1.56882,-1.73353 1.92387,-1.78093 3.26843,-0.43637 1.04108,1.04107 2.4483,1.30199 4.54198,0.84214 l 3.03355,-0.66628 -0.68776,11.32382 c -0.72485,11.93451 -1.14074,12.86208 -5.77895,12.88886 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z"
+ style="fill:#fba597" />
+ <path
+ id="path2988"
+ d="m 221.18668,829.90581 c -1.93432,-5.5488 -2.47791,-18.15014 -0.87433,-20.26869 1.20398,-1.59064 1.76544,-1.69198 3.68442,-0.66497 1.24518,0.6664 3.41269,0.92333 4.81668,0.57095 l 2.55271,-0.64069 -0.71434,11.28897 c -0.75006,11.85366 -1.16479,12.78068 -5.72954,12.80704 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z m 22.21513,2.33139 c -3.55171,-2.25917 -6.28879,-19.66203 -3.5268,-22.42402 0.48123,-0.48123 2.70741,-0.58195 4.94705,-0.22382 3.78933,0.60594 4.14652,0.9468 5.14421,4.90901 0.58968,2.34182 1.38173,5.06461 1.76011,6.05065 0.44754,1.16629 0.30896,1.55857 -0.39657,1.12252 -1.47691,-0.91278 -2.08921,1.1788 -1.49071,5.09219 0.39191,2.56254 0.14544,3.25 -1.16518,3.25 -0.91423,0 -1.92125,0.675 -2.23783,1.5 -0.64031,1.66861 -1.30082,1.8261 -3.03428,0.72347 z"
+ style="fill:#fba78a" />
+ <path
+ id="path2986"
+ d="m 221.30293,829.26373 c -1.57713,-5.43533 -2.5527,-14.82202 -1.8369,-17.67401 0.57224,-2.27998 1.02934,-2.44619 6.23753,-2.26813 l 5.62004,0.19214 -0.69305,10.98331 c -0.72599,11.50515 -1.16409,12.47489 -5.6478,12.50138 -2.13974,0.0126 -2.78147,-0.63866 -3.67982,-3.73469 z m 22.11621,2.98418 c -0.63543,-0.40435 -2.10648,-3.55865 -3.26901,-7.00955 -2.51688,-7.47126 -1.88001,-15.78981 1.1975,-15.6413 7.7497,0.37399 7.4344,0.19825 8.59009,4.78792 0.60538,2.40418 1.41028,5.178 1.78866,6.16404 0.45172,1.17717 0.31093,1.55979 -0.40999,1.11423 -1.36162,-0.84153 -2.51515,2.47491 -1.64738,4.73629 0.41694,1.08651 -0.29,2.52937 -2.02884,4.14088 -3.03005,2.80815 -2.70074,2.67493 -4.22103,1.70749 z"
+ style="fill:#fb9996" />
+ <path
+ id="path2984"
+ d="m 221.62624,829.7919 c -1.76556,-4.22558 -2.98504,-17.79554 -1.75988,-19.58342 0.65198,-0.95144 2.30216,-1.1185 6.08784,-0.61632 l 5.19341,0.68894 -0.65991,10.11631 c -0.36295,5.56398 -0.94191,10.42198 -1.28657,10.79556 -0.34467,0.37358 -1.8665,0.98545 -3.38186,1.35971 -2.45245,0.6057 -2.91317,0.30235 -4.19303,-2.76078 z m 21.62804,1.93428 c -2.58899,-3.13045 -5.1869,-12.32814 -4.60314,-16.29701 0.86081,-5.85235 1.39869,-6.36256 6.04992,-5.7387 3.90839,0.52423 4.13392,0.74924 5.13477,5.12293 0.64943,2.83802 0.70299,5.47897 0.14109,6.95688 -0.49815,1.31023 -0.65676,3.37421 -0.35247,4.58662 0.70357,2.80324 -4.71508,7.37051 -6.37017,5.36928 z"
+ style="fill:#fa9787" />
+ <path
+ id="path2982"
+ d="m 222.27764,831.35152 c -0.52864,-1.01079 -1.5183,-5.81903 -2.19925,-10.68499 -1.52422,-10.89173 -0.88679,-12.00968 6.28694,-11.02641 l 4.70142,0.6444 -0.62383,10.11461 c -0.34312,5.56303 -0.90388,10.42026 -1.24615,10.79384 -0.34227,0.37358 -1.82284,0.97558 -3.29015,1.33778 -2.01233,0.49674 -2.90399,0.207 -3.62898,-1.17923 z m 20.13064,-1.08779 c -0.33188,-0.9625 -1.39356,-3.6085 -2.3593,-5.88 -1.89406,-4.45498 -1.65955,-12.55659 0.41327,-14.27687 0.62221,-0.51639 2.67297,-0.62358 4.55724,-0.23821 4.18109,0.85513 5.13433,3.53546 4.65376,13.08549 -0.25668,5.10092 -0.69352,6.63149 -1.96444,6.88291 -0.89889,0.17783 -1.63435,0.74033 -1.63435,1.25 0,1.65938 -3.04599,0.97533 -3.66618,-0.82332 z"
+ style="fill:#faa96f" />
+ <path
+ id="path2980"
+ d="m 222.27764,831.35152 c -0.52864,-1.01079 -1.51335,-5.78416 -2.18825,-10.6075 -1.41648,-10.12316 -0.61986,-12.39505 3.91087,-11.1534 1.41581,0.388 3.58864,0.64681 4.82851,0.57513 2.2392,-0.12946 2.25007,-0.0617 1.62231,10.10883 -0.3476,5.63153 -0.91204,10.54481 -1.25431,10.91839 -0.34227,0.37358 -1.82284,0.97558 -3.29015,1.33778 -2.01233,0.49674 -2.90399,0.207 -3.62898,-1.17923 z m 20.10725,-1.08779 c -0.34474,-0.9625 -1.38391,-3.775 -2.30926,-6.25 -2.75945,-7.3806 -0.64783,-16.8259 3.20502,-14.33609 0.7116,0.45985 2.15925,0.83609 3.21701,0.83609 2.55245,0 3.59591,4.08776 3.17559,12.44041 -0.25668,5.10092 -0.69352,6.63149 -1.96444,6.88291 -0.89889,0.17783 -1.63435,0.74033 -1.63435,1.25 0,1.6564 -3.04476,0.97696 -3.68957,-0.82332 z"
+ style="fill:#fa947a" />
+ <path
+ id="path2978"
+ d="m 222.66421,832.15894 c -0.34565,-0.55926 -1.25123,-5.2066 -2.01241,-10.32743 -1.61694,-10.87789 -0.9927,-13.23232 3.21267,-12.11721 1.49049,0.39522 3.72162,0.67194 4.95807,0.61492 2.22878,-0.10279 2.24271,-0.0166 1.62231,10.04042 -0.34418,5.57925 -0.90581,10.44975 -1.24808,10.82333 -1.17568,1.28323 -5.90434,1.98246 -6.53256,0.96597 z m 19.89554,-1.39521 c -2.76058,-7.63527 -3.48529,-10.70299 -3.48529,-14.75328 0,-4.50991 1.80223,-7.86115 3.3794,-6.28399 0.38246,0.38246 1.88374,0.71606 3.33618,0.74133 2.06745,0.036 2.81953,0.69727 3.46406,3.04594 1.25136,4.56001 -0.12178,14.69032 -2.27042,16.75 -2.14711,2.05821 -3.79329,2.24426 -4.42393,0.5 z"
+ style="fill:#fa8884" />
+ <path
+ id="path2976"
+ d="m 222.50927,830.90824 c -0.37578,-0.60801 -1.25786,-4.99551 -1.96017,-9.75 -1.47709,-9.99943 -0.80155,-12.51565 3.09742,-11.53707 1.37063,0.34401 3.26513,0.68556 4.21,0.75901 0.94487,0.0734 1.99019,0.58355 2.32295,1.13355 0.69333,1.14599 -0.70968,18.05133 -1.62042,19.52494 -0.82187,1.32981 -5.20572,1.2353 -6.04978,-0.13043 z m 18.63704,-4.43202 c -3.37032,-9.00798 -2.33409,-18.74357 1.7617,-16.55157 0.96226,0.51498 2.58779,0.85821 3.61229,0.76271 2.58412,-0.24087 3.68815,4.3302 2.91039,12.05008 -0.50552,5.01758 -1.07846,6.51949 -2.95645,7.75 -1.28118,0.83946 -2.53791,1.52629 -2.79275,1.52629 -0.25483,0 -1.39566,-2.49188 -2.53518,-5.53751 z"
+ style="fill:#f9af50" />
+ <path
+ id="path2974"
+ d="m 222.14477,829.69866 c -0.4841,-1.27328 -1.18483,-4.98578 -1.55716,-8.25 -0.37234,-3.26421 -0.86723,-6.63354 -1.09975,-7.48739 -0.23253,-0.85385 0.17932,-2.37587 0.91522,-3.38227 1.27959,-1.74995 1.45462,-1.75341 4.00969,-0.0793 2.04558,1.34032 2.99469,1.48251 4.04991,0.60676 1.0452,-0.86744 1.4888,-0.83562 1.83589,0.13171 0.56835,1.58395 -0.91478,18.466 -1.73952,19.80046 -1.20642,1.95202 -5.504,1.05422 -6.41428,-1.34001 z m 19.00154,-3.22244 c -3.37032,-9.00798 -2.33409,-18.74357 1.7617,-16.55157 0.96226,0.51498 2.58779,0.85821 3.61229,0.76271 2.58412,-0.24087 3.68815,4.3302 2.91039,12.05008 -0.50552,5.01758 -1.07846,6.51949 -2.95645,7.75 -1.28118,0.83946 -2.53791,1.52629 -2.79275,1.52629 -0.25483,0 -1.39566,-2.49188 -2.53518,-5.53751 z"
+ style="fill:#fa8678" />
+ <path
+ id="path2972"
+ d="m 222.13455,829.67178 c -0.51748,-1.36109 -1.24958,-6.27925 -1.62688,-10.92925 -0.75781,-9.33961 -0.0511,-10.83501 3.89764,-8.24767 1.31304,0.86033 3.12575,1.28089 4.02824,0.93457 1.41077,-0.54137 1.63051,0.19177 1.56679,5.22731 -0.0408,3.22135 -0.37827,7.88199 -0.75,10.35699 -0.59575,3.9665 -1.00185,4.53751 -3.4254,4.81638 -2.15645,0.24813 -2.95245,-0.21741 -3.69039,-2.15833 z m 21.21124,1.06386 c -2.61671,-3.44941 -4.3414,-10.713 -3.69705,-15.5703 l 0.66804,-5.03598 3.89064,0.15515 c 3.48771,0.13908 3.98352,0.49155 4.78753,3.40341 0.49328,1.78655 0.66045,5.85322 0.37148,9.03704 -0.40707,4.485 -1.03985,6.17659 -2.80956,7.51068 -1.75742,1.32483 -2.4979,1.44013 -3.21108,0.5 z"
+ style="fill:#fa7974" />
+ <path
+ id="path2970"
+ d="m 223.91904,831.34262 c -2.03067,-0.53865 -2.56772,-2.56289 -3.43265,-12.93826 -0.749,-8.98473 -0.007,-10.48197 3.91892,-7.9095 1.31304,0.86033 3.09178,1.29392 3.95275,0.96354 1.37808,-0.52882 1.49697,0.57546 0.99348,9.22731 -0.31462,5.40631 -1.068,10.15856 -1.67451,10.56271 -1.16693,0.77757 -1.18043,0.77791 -3.75799,0.0942 z m 17.21699,-5.67718 c -1.71683,-4.23001 -2.02942,-6.41337 -1.49498,-10.44218 l 0.67573,-5.0939 3.89064,0.15515 c 3.50313,0.13969 3.98164,0.48472 4.80431,3.46421 1.26724,4.58956 0.12422,14.46961 -1.84909,15.98321 -2.76378,2.11992 -3.79932,1.42118 -6.02661,-4.06649 z"
+ style="fill:#f9836a" />
+ <path
+ id="path2968"
+ d="m 223.64739,830.4438 c -1.85627,-1.85626 -2.25977,-3.57781 -3.06787,-13.08917 -0.68033,-8.00745 0.0825,-9.31245 3.95897,-6.77251 1.38629,0.90833 3.16123,1.40565 3.94431,1.10516 1.19438,-0.45833 1.33299,1.01428 0.86029,9.14005 -0.63404,10.89904 -2.03975,13.27242 -5.6957,9.61647 z m 17.53808,-4.86292 c -1.53151,-4.09332 -1.88195,-6.70559 -1.42132,-10.59489 0.60375,-5.09769 0.64846,-5.15463 3.58584,-4.56715 1.63596,0.32719 3.31348,0.59489 3.72783,0.59489 1.25296,0 2.66967,7.32604 1.9338,10 -0.3784,1.375 -0.4645,3.5355 -0.19134,4.80111 0.49734,2.30428 -1.8953,5.09883 -4.42397,5.16709 -0.64798,0.0175 -2.09286,-2.41298 -3.21084,-5.40105 z"
+ style="fill:#f97967" />
+ <path
+ id="path2966"
+ d="m 223.11077,829.55749 c -1.55452,-1.8731 -3.30507,-17.675 -2.09239,-18.88768 0.47651,-0.47651 2.47171,-0.27364 4.49143,0.4567 l 3.63405,1.31409 -0.2847,9.03657 c -0.26128,8.29308 -0.45645,9.0611 -2.37221,9.33482 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.08259,-4.70911 -2.34897,-6.354 -1.66736,-10.29583 0.79337,-4.58811 0.88601,-4.68516 4.21056,-4.41078 1.86963,0.15431 3.64809,0.52919 3.95212,0.83307 0.30403,0.30389 0.58197,4.11797 0.61765,8.47574 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f88c4e" />
+ <path
+ id="path2964"
+ d="m 223.11077,829.55749 c -1.62629,-1.95957 -3.30118,-17.67889 -2.02017,-18.9599 0.57281,-0.57281 1.89956,-0.48767 3.45673,0.22183 1.81036,0.82485 2.53147,1.9375 2.54244,3.92287 0.0121,2.18024 0.22786,2.45146 1.0117,1.27144 0.69439,-1.04537 0.91707,0.92469 0.73469,6.5 -0.23718,7.25032 -0.45732,8.02795 -2.34921,8.29826 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.07784,-4.69837 -2.34887,-6.36299 -1.67637,-10.29583 0.79068,-4.62392 0.85194,-4.68641 4.26334,-4.34864 1.90362,0.18848 3.68613,0.56336 3.96113,0.83307 0.275,0.26971 0.52919,4.05583 0.56487,8.4136 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f8a534" />
+ <path
+ id="path2962"
+ d="m 223.11077,829.55749 c -1.31835,-1.58852 -3.34677,-17.23242 -2.42729,-18.72016 1.14947,-1.85987 3.52557,-0.60922 5.09488,2.68167 1.16822,2.44977 1.91966,3.12729 2.49552,2.25 0.45778,-0.69739 0.70767,2.30017 0.56228,6.74473 -0.23718,7.25032 -0.45732,8.02795 -2.34921,8.29826 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.07784,-4.69837 -2.34887,-6.36299 -1.67637,-10.29583 0.79068,-4.62392 0.85194,-4.68641 4.26334,-4.34864 1.90362,0.18848 3.68613,0.56336 3.96113,0.83307 0.275,0.26971 0.52919,4.05583 0.56487,8.4136 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f97659" />
+ <path
+ id="path2960"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -0.56031,-0.68049 -0.75752,-1.91799 -0.43825,-2.75 1.07196,-2.79347 3.45238,-1.54832 6.10157,3.1916 2.12264,3.79781 2.57269,5.77112 2.3355,10.24028 -0.23013,4.33611 -0.6731,5.60814 -2.04381,5.869 -1.04668,0.19919 -1.75,-0.27931 -1.75,-1.1906 z m 16.96387,-2.97179 c -2.15555,-4.87296 -2.22449,-5.36902 -1.68889,-12.15122 0.29872,-3.78258 0.47649,-3.98174 3.27046,-3.66399 4.42198,0.5029 4.9771,1.61488 4.71073,9.43636 -0.19008,5.58139 -0.67966,7.59556 -2.22083,9.13674 -1.96934,1.96933 -1.98513,1.95864 -4.07147,-2.75789 z"
+ style="fill:#f89936" />
+ <path
+ id="path2958"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -0.56031,-0.68049 -0.75752,-1.91799 -0.43825,-2.75 0.93035,-2.42444 3.58582,-1.74814 4.85806,1.23727 0.64456,1.5125 1.78388,3.48691 2.53182,4.38759 2.0861,2.51209 1.30446,13.2381 -0.99662,13.67602 -1.04668,0.19919 -1.75,-0.27931 -1.75,-1.1906 z m 16.9435,-3.01782 c -2.14558,-4.85044 -2.22191,-5.41701 -1.631,-12.10519 0.25271,-2.86028 0.75717,-3.88974 1.77045,-3.61301 0.77938,0.21284 2.27824,0.47228 3.33081,0.57652 2.70391,0.2678 3.64683,3.66342 2.92774,10.5433 -0.40811,3.9046 -1.25402,6.50903 -2.47214,7.61142 -1.76446,1.59681 -1.94952,1.45478 -3.92586,-3.01304 z m 4.0565,-8.54617 c 0,-1.06754 -0.45,-2.2191 -1,-2.55902 -0.56716,-0.35052 -1,0.48962 -1,1.94098 0,1.40746 0.45,2.55902 1,2.55902 0.55,0 1,-0.87344 1,-1.94098 z"
+ style="fill:#f88838" />
+ <path
+ id="path2956"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -1.31597,-1.59824 -0.29183,-4.26273 1.63844,-4.26273 1.76019,0 3.56657,3.00556 3.56657,5.93426 0,1.13616 0.5625,1.95324 1.25,1.81574 0.89722,-0.17944 1.25,1.58059 1.25,6.23631 0,5.38237 -0.29784,6.54366 -1.75,6.82332 -1.04842,0.20191 -1.75,-0.27381 -1.75,-1.18662 z m 16.9435,-3.01782 c -1.14075,-2.57888 -2.05392,-5.45754 -2.02925,-6.39703 0.0442,-1.68363 0.77833,-9.28228 0.98141,-10.15816 0.0574,-0.2475 0.64434,0.09 1.30434,0.75 0.66,0.66 2.18252,1.2 3.38337,1.2 2.79309,0 3.52113,2.70677 2.73949,10.1851 -0.39145,3.74518 -1.24893,6.343 -2.4535,7.43313 -1.76446,1.59681 -1.94952,1.45478 -3.92586,-3.01304 z m 4.0565,-7.98275 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f96857" />
+ <path
+ id="path2954"
+ d="m 224.43035,828.2706 c -2.66558,-3.61935 -4.17153,-18.25687 -1.87832,-18.25687 1.73553,0 3.52243,3.04033 3.52243,5.99328 0,1.16861 0.45,1.84664 1,1.50672 0.58985,-0.36455 1.07513,0.94423 1.18318,3.19098 0.45481,9.45699 -0.72168,11.78271 -3.82729,7.56589 z m 17.31261,-3.28329 c -1.95628,-4.43272 -2.12466,-5.73743 -1.23521,-9.57109 0.71036,-3.06172 1.44872,-4.27801 2.38006,-3.92062 0.74262,0.28497 2.16094,0.51813 3.15181,0.51813 2.38322,0 3.09675,3.11426 2.35015,10.25737 -0.44715,4.27809 -1.11132,6.09827 -2.49554,6.83908 -1.64554,0.88067 -2.17523,0.3546 -4.15127,-4.12287 z m 4.3315,-6.35114 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f97448" />
+ <path
+ id="path2952"
+ d="m 224.43035,828.2706 c -2.17337,-2.95101 -4.19764,-18.25687 -2.41456,-18.25687 1.73198,0 4.05867,3.14613 4.05867,5.4881 0,1.28988 0.46287,2.49952 1.0286,2.6881 1.39017,0.46339 1.74167,10.4523 0.41453,11.78012 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.71778,0 0.90684,-1.09078 0.52231,-3.01345 -0.57326,-2.86632 -0.46951,-2.98163 2.125,-2.36174 4.2138,1.00677 4.22769,1.03602 4.22769,8.89902 0,6.41491 -0.27118,7.55093 -2.02673,8.49048 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z m 4.00477,-7.17705 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f89426" />
+ <path
+ id="path2950"
+ d="m 224.43035,828.2706 c -1.42701,-1.9376 -2.22355,-5.05998 -2.68038,-10.50687 -0.3575,-4.2625 -0.29574,-7.75 0.13724,-7.75 1.38039,0 3.18725,2.3405 3.18725,4.12857 0,0.95072 0.69195,2.42052 1.53766,3.26624 1.80711,1.8071 2.46952,10.99666 0.90547,12.56151 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.72319,0 0.90496,-1.1002 0.50893,-3.08036 -0.44279,-2.21392 -0.26699,-2.96256 0.625,-2.66159 0.8199,0.27666 1.12566,2.00073 0.901,5.08036 -0.27261,3.73691 -0.0247,4.66159 1.25,4.66159 1.22091,0 1.59007,-1.05845 1.59007,-4.55902 0,-2.7847 0.38919,-4.31848 1,-3.94098 0.55,0.33992 1,3.95064 1,8.02383 0,6.41491 -0.27118,7.55093 -2.02673,8.49048 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f8862a" />
+ <path
+ id="path2948"
+ d="m 224.43035,828.2706 c -2.45647,-3.33541 -4.24951,-18.71542 -2.10001,-18.01314 0.68426,0.22357 1.72913,1.87324 2.32193,3.66594 0.5928,1.7927 1.61953,3.59426 2.28162,4.00346 1.52494,0.94246 1.99455,10.63162 0.5837,12.04319 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.71667,0 0.90722,-1.08889 0.525,-3 -0.33846,-1.69231 -0.175,-3 0.375,-3 0.53625,0 0.975,2.25 0.975,5 0,3.74919 0.37048,5 1.48095,5 0.81452,0 1.697,-1.0125 1.96106,-2.25 0.26407,-1.2375 0.67044,-3.15 0.90305,-4.25 0.23262,-1.1 0.47514,1.47167 0.53894,5.71482 0.10212,6.79156 -0.12655,7.84462 -1.91073,8.79949 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f87638" />
+ <path
+ id="path2946"
+ d="m 224.43035,828.2706 c -2.4567,-3.33573 -4.24905,-18.71274 -2.10001,-18.01662 0.68426,0.22166 1.84937,2.28342 2.58911,4.58169 0.73974,2.29827 1.75224,3.92698 2.25,3.61935 1.53952,-0.95147 1.67063,10.19309 0.13795,11.72577 -0.46567,0.46567 -1.76034,-0.39392 -2.87705,-1.91019 z m 17.63934,-2.45738 c -2.06208,-4.54357 -2.59586,-8.79949 -1.10364,-8.79949 0.49038,0 1.17395,1.125 1.51905,2.5 0.67619,2.69414 2.46533,3.22403 4.38936,1.3 0.93333,-0.93333 1.2,-0.27448 1.2,2.96482 0,3.15967 -0.48914,4.42659 -2.02673,5.24949 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f86647" />
+ <path
+ id="path2944"
+ d="m 225.53957,828.73073 c -0.35508,-1.41476 -1.27715,-2.81463 -2.04903,-3.11083 -0.96655,-0.3709 -1.35554,-2.02774 -1.24959,-5.32236 0.0846,-2.63109 -0.19572,-5.79631 -0.62296,-7.03381 -0.59332,-1.71857 -0.39946,-2.25 0.82079,-2.25 0.92147,0 1.86759,1.16381 2.23559,2.75 0.35092,1.5125 1.31914,3.83771 2.15162,5.16714 1.83737,2.93418 2.15539,9.57594 0.53605,11.19528 -0.90249,0.90249 -1.32739,0.57716 -1.82247,-1.39542 z m 17.11275,-1.8764 c -2.21367,-5.29808 -2.8383,-8.5616 -1.76556,-9.2246 0.53589,-0.3312 1.25593,0.51971 1.60008,1.89091 0.65349,2.60373 2.45562,3.22509 4.22421,1.4565 0.71546,-0.71546 1.07635,0.0209 1.16492,2.37676 0.0842,2.23955 -0.54396,4.02176 -1.82663,5.18256 -1.8947,1.71468 -1.9994,1.66283 -3.39702,-1.68213 z"
+ style="fill:#f85b47" />
+ <path
+ id="path2942"
+ d="m 224.83638,826.76373 c -0.80746,-1.2375 -1.70473,-4.5 -1.99393,-7.25 -0.2892,-2.75 -0.85346,-5.7875 -1.2539,-6.75 -0.50617,-1.21664 -0.26667,-1.75 0.7858,-1.75 0.99121,0 2.23649,2.30222 3.60698,6.66841 3.1106,9.90994 2.50902,14.68163 -1.14495,9.08159 z m 17.16288,-2.42544 c -1.10227,-2.57149 -1.70889,-5.38399 -1.34804,-6.25 0.50685,-1.2164 0.87603,-0.94902 1.623,1.17544 1.03757,2.95098 2.66105,3.48919 4.61899,1.53125 0.95833,-0.95833 1.08942,-0.47756 0.61347,2.25 -1.33435,7.64681 -2.65142,7.9561 -5.50742,1.29331 z"
+ style="fill:#f86639" />
+ <path
+ id="path2940"
+ d="m 224.68947,826.54891 c -0.9401,-1.43477 -1.61501,-4.54435 -1.61501,-7.44098 0,-2.73689 -0.45,-5.25428 -1,-5.5942 -1.49608,-0.92463 -1.20529,-2.5 0.46146,-2.5 0.88442,0 1.88498,1.67803 2.53414,4.25 0.58998,2.3375 1.50732,5.28367 2.03854,6.54705 1.2092,2.87578 1.25778,7.20295 0.0809,7.20295 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z m 17.87076,-0.91499 c -1.85558,-4.44103 -1.92346,-6.60102 -0.13038,-4.14884 0.85716,1.17224 1.98303,1.61276 3.06282,1.19841 1.42177,-0.54558 1.65509,-0.12558 1.39461,2.51051 -0.4403,4.4558 -2.5591,4.67122 -4.32705,0.43992 z"
+ style="fill:#f7781d" />
+ <path
+ id="path2938"
+ d="m 224.68947,826.54891 c -0.9401,-1.43477 -1.61501,-4.54435 -1.61501,-7.44098 0,-2.73689 -0.45,-5.25428 -1,-5.5942 -1.51136,-0.93407 -1.19817,-2.5 0.5,-2.5 1.04762,0 1.5,1.05556 1.5,3.5 0,1.925 0.3596,3.5 0.79911,3.5 1.02848,0 3.20089,5.98672 3.20089,8.821 0,2.87849 -1.38847,2.76125 -3.38499,-0.28582 z m 17.87076,-0.91499 c -1.85558,-4.44103 -1.92346,-6.60102 -0.13038,-4.14884 0.85716,1.17224 1.98303,1.61276 3.06282,1.19841 1.42177,-0.54558 1.65509,-0.12558 1.39461,2.51051 -0.4403,4.4558 -2.5591,4.67122 -4.32705,0.43992 z"
+ style="fill:#f85737" />
+ <path
+ id="path2936"
+ d="m 224.89116,825.23793 c -1.761,-3.89609 -2.71911,-12.65513 -1.5159,-13.85834 0.38456,-0.38455 0.6992,0.95081 0.6992,2.96747 0,2.01667 0.45,3.66667 1,3.66667 0.55,0 1,1.09844 1,2.44098 0,1.34254 0.45,2.7191 1,3.05902 1.15423,0.71335 1.37341,5.51284 0.25,5.4742 -0.4125,-0.0142 -1.50749,-1.70169 -2.4333,-3.75 z m 18.34208,1.70574 c -0.76367,-2.0394 -0.56828,-2.51979 1.21566,-2.98899 2.66619,-0.70124 3.43951,1.67367 1.25599,3.85719 -1.41566,1.41566 -1.64686,1.33445 -2.47165,-0.8682 z"
+ style="fill:#f76727" />
+ <path
+ id="path2934"
+ d="m 224.82446,825.16032 c -1.95208,-4.24082 -2.20733,-6.14659 -0.82324,-6.14659 1.19752,0 4.07324,5.75648 4.07324,8.15364 0,2.94344 -1.35701,2.10541 -3.25,-2.00705 z m 18.40878,1.78335 c -0.76367,-2.0394 -0.56828,-2.51979 1.21566,-2.98899 2.66619,-0.70124 3.43951,1.67367 1.25599,3.85719 -1.41566,1.41566 -1.64686,1.33445 -2.47165,-0.8682 z"
+ style="fill:#f84b34" />
+ <path
+ id="path2932"
+ d="m 224.82446,824.64094 c -2.00235,-4.2279 -2.1827,-5.62721 -0.72525,-5.62721 1.33504,0 3.14946,4.81045 2.77063,7.34559 -0.23097,1.54565 -0.67698,1.17095 -2.04538,-1.71838 z m 18.73475,2.34812 c -0.40754,-0.65942 -0.12083,-1.58421 0.63713,-2.05509 1.66304,-1.03315 2.55953,0.79835 1.10349,2.25439 -0.66618,0.66618 -1.24681,0.59969 -1.74062,-0.1993 z"
+ style="fill:#f75529" />
+ <path
+ id="path2930"
+ d="m 226.15341,826.59706 c -0.0434,-1.05416 0.19292,-1.64479 0.52522,-1.3125 0.33229,0.33229 0.36781,1.1948 0.0789,1.91667 -0.31923,0.79773 -0.55619,0.56078 -0.60417,-0.60417 z m 17.4058,0.392 c -0.40754,-0.65942 -0.12083,-1.58421 0.63713,-2.05509 1.66304,-1.03315 2.55953,0.79835 1.10349,2.25439 -0.66618,0.66618 -1.24681,0.59969 -1.74062,-0.1993 z"
+ style="fill:#f8472b" />
+ <path
+ id="path2928"
+ d="m 244.07446,826.57275 c 0,-0.85746 0.45,-1.55902 1,-1.55902 0.55,0 1,0.42344 1,0.94098 0,0.51754 -0.45,1.2191 -1,1.55902 -0.55,0.33992 -1,-0.0835 -1,-0.94098 z"
+ style="fill:#f83e29" />
+ </g>
+ <g
+ transform="translate(-109.5,132.5)"
+ id="shipFire2">
+ <path
+ id="path3209"
+ d="m 151.57446,902.9436 0,-15 20,0 20,0 0,15 0,15 -20,0 -20,0 0,-15 z"
+ style="fill:#fefefe" />
+ <path
+ id="path3207"
+ d="m 162.96188,917.12575 c 0.278,-0.44981 -0.42671,-1.46231 -1.56602,-2.25 -6.19532,-4.28325 -6.07193,-4.01046 -6.49663,-14.36377 -0.35012,-8.53525 -0.17217,-9.96019 1.38679,-11.10498 2.07435,-1.52325 11.97013,-1.78746 12.8626,-0.34341 0.37888,0.61304 1.12963,0.5408 2.01487,-0.19388 0.96521,-0.80105 1.80587,-0.85078 2.66097,-0.15738 0.83468,0.67683 3.35475,0.69027 7.58466,0.0404 3.48406,-0.53525 6.57872,-0.72911 6.87702,-0.43081 0.92329,0.92328 2.41041,8.80392 2.9664,15.71969 0.39587,4.92418 0.12314,7.38568 -1.07506,9.70274 -1.54819,2.99387 -1.78393,3.08356 -6.60426,2.51267 -3.41971,-0.40502 -4.99876,-0.23214 -4.99876,0.54726 0,0.62661 -0.66643,1.13929 -1.48095,1.13929 -1.80373,0 -2.9556,-4.04919 -2.00441,-7.04614 0.92344,-2.90948 -1.57556,-2.16889 -3.13355,0.92865 -1.68131,3.34273 -5.03701,6.11749 -7.39829,6.11749 -1.15546,0 -1.87338,-0.36803 -1.59538,-0.81785 z"
+ style="fill:#fef4f3" />
+ <path
+ id="path3205"
+ d="m 163.03741,917.00355 c 0.58394,-0.94485 0.10077,-1.48471 -4.41546,-4.93349 -2.1257,-1.62328 -2.54917,-2.98908 -3.17795,-10.24965 -1.00798,-11.63923 -0.10006,-13.34965 7.14549,-13.46141 3.01673,-0.0465 5.93497,0.23133 6.48497,0.61747 1.17869,0.82751 10.45665,0.51702 15.61683,-0.52263 l 3.61683,-0.7287 1.63317,7.23189 c 2.02661,8.97413 2.06262,13.7145 0.13914,18.31804 -1.48926,3.5643 -1.51001,3.57382 -6.5,2.98283 -3.4256,-0.40571 -5.00597,-0.23321 -5.00597,0.54641 0,1.55847 -2.97681,1.45192 -3.09274,-0.11071 -0.051,-0.6875 -0.0116,-3.25029 0.0875,-5.69508 0.15304,-3.77373 -0.038,-4.26392 -1.26504,-3.24559 -0.79492,0.65972 -2.72404,3.22251 -4.28694,5.69508 -2.05711,3.25444 -3.49307,4.49559 -5.20123,4.49559 -1.29778,0 -2.09816,-0.42302 -1.77862,-0.94005 z"
+ style="fill:#fef3ea" />
+ <path
+ id="path3203"
+ d="m 162.87261,917.31212 c 0.98153,-0.98154 -1.19733,-4.36852 -2.81028,-4.36852 -0.79297,0 -2.1115,-1.02214 -2.93006,-2.27143 -1.9288,-2.94372 -2.45436,-19.23181 -0.67788,-21.00894 1.42194,-1.42246 12.12007,-1.80281 12.12007,-0.4309 0,0.51045 1.09742,0.65265 2.43871,0.31601 1.3413,-0.33665 2.72239,-0.15309 3.0691,0.4079 0.34671,0.56099 1.075,0.7452 1.61842,0.40934 0.54342,-0.33585 1.97483,-0.7608 3.1809,-0.94432 1.20608,-0.18353 3.76787,-0.62898 5.69287,-0.98989 l 3.5,-0.65619 1.7642,7.33421 c 1.93817,8.05746 2.29955,15.83421 0.7358,15.83421 -0.55,0 -1,1.09844 -1,2.44098 0,3.27429 -1.11158,3.76871 -6.00239,2.66982 -3.26275,-0.73309 -4.24406,-0.63213 -4.67105,0.48057 -0.29729,0.77475 -1.16739,1.40863 -1.93355,1.40863 -1.02551,0 -1.39301,-1.48331 -1.39301,-5.62245 0,-5.01744 -0.17049,-5.48095 -1.58439,-4.30751 -0.87142,0.72321 -2.91804,3.25331 -4.54804,5.62244 -1.91866,2.78868 -3.71068,4.30752 -5.08228,4.30752 -1.16524,0 -1.83446,-0.28417 -1.48714,-0.63148 z"
+ style="fill:#fde8e7" />
+ <path
+ id="path3201"
+ d="m 163.57446,916.49449 c 0,-0.79701 -1.5347,-2.61968 -3.41045,-4.05039 -3.34087,-2.5482 -3.42503,-2.79562 -4.12458,-12.12631 -0.49318,-6.57819 -0.36781,-9.87135 0.40526,-10.64442 1.58052,-1.58052 11.34374,-1.64763 12.90871,-0.0887 0.70341,0.70069 1.94091,1.01996 2.75,0.70948 0.80908,-0.31047 1.47106,-0.0398 1.47106,0.60151 0,0.69406 0.50594,0.84125 1.25,0.36365 1.48765,-0.95489 9.60478,-3.20883 11.78189,-3.27155 0.89112,-0.0257 1.61132,0.91554 1.72177,2.25013 0.10444,1.26185 0.87759,4.24343 1.71811,6.62573 1.71574,4.86292 2.06153,14.08001 0.52823,14.08001 -0.55,0 -1,0.8449 -1,1.87755 0,3.07992 -2.2104,4.20929 -6.07124,3.10202 -4.50601,-1.29231 -4.92876,-1.24767 -4.92876,0.52043 0,0.825 -0.6681,1.5 -1.48467,1.5 -1.21761,0 -1.37186,-1.07927 -0.85754,-6 0.37978,-3.63355 0.24528,-6 -0.34102,-6 -1.19371,0 -4.13666,3.29088 -7.37163,8.24317 -2.48087,3.79786 -4.94514,4.94785 -4.94514,2.30772 z"
+ style="fill:#fde3db" />
+ <path
+ id="path3199"
+ d="m 163.57446,916.49449 c 0,-0.79701 -1.50777,-2.59914 -3.35059,-4.00473 -3.26039,-2.48682 -3.36819,-2.80345 -4.00402,-11.76116 -0.53554,-7.5447 -0.37779,-9.48118 0.87439,-10.73336 2.05974,-2.05974 11.1787,-2.27977 11.94295,-0.28817 0.32015,0.83429 1.22302,1.18736 2.13824,0.83616 1.0586,-0.40623 1.76151,0.0705 2.11886,1.43701 0.52424,2.00471 0.56124,2.00709 1.88206,0.12136 0.74101,-1.05795 2.59623,-2.18478 4.1227,-2.50408 9.28393,-1.94193 8.81294,-1.97116 9.02241,0.55983 0.1081,1.30613 0.88425,4.32394 1.72477,6.70624 1.71574,4.86292 2.06153,14.08001 0.52823,14.08001 -0.55,0 -1,0.81 -1,1.8 0,3.01516 -1.86706,4.09852 -5.34458,3.10118 -4.40199,-1.26248 -5.65542,-1.12976 -5.65542,0.59882 0,0.825 -0.63233,1.5 -1.40517,1.5 -1.11122,0 -1.29136,-1.25517 -0.86111,-6 0.34639,-3.82005 0.16791,-6 -0.49124,-6 -1.32415,0 -7.06306,6.5121 -8.48052,9.62309 -1.18645,2.60397 -3.76196,3.23916 -3.76196,0.9278 z"
+ style="fill:#fddbda" />
+ <path
+ id="path3197"
+ d="m 163.57446,915.96928 c 0,-1.18015 -1.20093,-2.59534 -2.98551,-3.51819 -3.28277,-1.69758 -3.6304,-2.72129 -4.44155,-13.07944 -0.72235,-9.22415 0.366,-10.86052 7.31911,-11.00464 4.13062,-0.0856 5.18438,0.24206 5.66684,1.76214 0.32597,1.02703 1.32706,1.74292 2.22465,1.59089 1.2408,-0.21018 1.71047,0.67881 1.95939,3.70872 0.18006,2.19184 0.74523,4.403 1.25592,4.91369 0.57138,0.57138 0.70687,-0.43744 0.35224,-2.62274 -0.81981,-5.05189 0.66273,-6.92355 6.70993,-8.47114 5.54336,-1.41865 6.86584,-0.905 6.93872,2.69503 0.0167,0.825 0.67885,3.3 1.47142,5.5 2.01176,5.58413 1.86493,10.42872 -0.46204,15.24498 -1.9362,4.00748 -2.08038,4.09285 -5.25,3.10855 -5.15345,-1.60037 -6.28791,-1.52497 -5.96528,0.39647 0.16161,0.9625 -0.30972,1.75 -1.0474,1.75 -1.02652,0 -1.24411,-1.52514 -0.92734,-6.5 0.22764,-3.575 0.024,-6.47871 -0.4526,-6.45269 -1.17866,0.0644 -9.3665,10.39262 -9.3665,11.81503 0,0.62571 -0.675,1.13766 -1.5,1.13766 -0.82683,0 -1.5,-0.88604 -1.5,-1.97432 z"
+ style="fill:#fdd4d3" />
+ <path
+ id="path3195"
+ d="m 164.18103,916.77117 c 0.43565,-0.70489 -0.81465,-2.4647 -3.13534,-4.41305 -3.69469,-3.10187 -3.89194,-3.57553 -4.60717,-11.06331 -1.03988,-10.88663 -0.0358,-12.78139 6.84886,-12.92409 4.71285,-0.0977 5.2995,0.13606 6.23046,2.48252 0.56525,1.4247 1.47635,3.26536 2.02466,4.09036 0.54832,0.825 1.67354,3.075 2.50049,5 l 1.50355,3.5 -0.50478,-5 c -0.27763,-2.75 -0.0824,-5.64324 0.43386,-6.42941 0.79202,-1.20613 11.1128,-4.63899 11.53951,-3.83823 0.0784,0.1472 1.15252,3.4997 2.38686,7.44999 2.43693,7.79905 2.66335,14.72 0.45384,13.87213 -0.93046,-0.35706 -1.14026,0.15958 -0.72945,1.79636 0.92292,3.67722 -1.48563,4.94645 -6.83196,3.60023 -4.34704,-1.0946 -4.4947,-1.26023 -4.98261,-5.58895 -0.52198,-4.63098 -1.67993,-6.79044 -2.46354,-4.59426 -0.24881,0.69732 -1.15193,1.9674 -2.00693,2.8224 -2.2206,2.2206 -6.26688,8.32478 -6.26688,9.45415 0,0.52557 -0.70156,0.95559 -1.55902,0.95559 -0.93755,0 -1.27017,-0.46736 -0.83441,-1.17243 z m 11.39343,0.73145 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z"
+ style="fill:#fdd5cb" />
+ <path
+ id="path3193"
+ d="m 164.1735,916.5461 c 0.31707,-0.82628 -0.88226,-2.47948 -2.93415,-4.04453 -4.03071,-3.07437 -4.57157,-4.70635 -4.77073,-14.39518 -0.1804,-8.77645 0.68336,-10.02859 6.65854,-9.65248 3.86629,0.24336 4.82621,0.76895 6.84943,3.75033 1.29414,1.90703 2.89298,5.10353 3.55298,7.10334 1.63364,4.94999 2.44547,4.57523 1.71016,-0.78944 -0.75035,-5.47444 0.9777,-7.75927 7.18209,-9.49615 2.39104,-0.66935 4.43478,-1.07332 4.54164,-0.8977 0.10686,0.17562 1.20419,3.55137 2.43853,7.50166 2.4293,7.77463 2.66263,14.71972 0.46621,13.87687 -0.87564,-0.33601 -1.29374,0.44385 -1.29374,2.41315 0,3.83982 -0.992,4.28955 -6.31903,2.86479 -4.29403,-1.14848 -4.47943,-1.35674 -4.95371,-5.56454 -0.4947,-4.38896 -1.66671,-6.69837 -2.38712,-4.70377 -0.21232,0.58787 -2.17572,2.98811 -4.36309,5.33386 -2.18738,2.34575 -3.97705,5.12726 -3.97705,6.18114 0,1.05388 -0.66088,1.91615 -1.46862,1.91615 -0.84672,0 -1.24152,-0.59178 -0.93234,-1.3975 z m 11.40096,0.95652 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z"
+ style="fill:#fcc9c7" />
+ <path
+ id="path3191"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.04148,-1 1.55902,-1 0.51754,0 0.94098,0.45 0.94098,1 0,0.55 -0.70156,1 -1.55902,1 -0.85746,0 -1.2809,-0.45 -0.94098,-1 z m -2.5,-4.5612 c -3.83318,-2.6976 -4.78539,-5.9 -4.92588,-16.56636 -0.088,-6.68229 0.84499,-7.68093 6.86223,-7.34496 3.62102,0.20218 4.59555,0.6781 5.30265,2.58955 0.47646,1.28801 1.42448,3.0261 2.10671,3.86241 1.94334,2.38227 3.85888,8.87634 3.02775,10.26473 -1.36298,2.27684 -7.78605,9.75683 -8.33522,9.70679 -0.29603,-0.027 -2.11324,-1.15744 -4.03824,-2.51216 z m 18.36759,1.39317 c -1.5582,-0.75458 -2.29225,-2.28472 -2.72598,-5.68232 -1.81186,-14.19307 -1.85608,-15.1863 -0.73618,-16.5357 0.6374,-0.76802 2.38193,-1.62827 3.87674,-1.91168 1.4948,-0.28341 3.73033,-0.83485 4.96783,-1.22541 1.79339,-0.56601 2.25,-0.32428 2.25,1.19117 0,1.04571 0.9243,4.53109 2.05401,7.7453 2.39531,6.81511 2.29483,11.2274 -0.2461,10.80613 -1.40828,-0.23348 -1.59599,0.31162 -1.11915,3.25 0.56258,3.46682 0.51191,3.52932 -2.80792,3.46286 -1.85946,-0.0372 -4.34043,-0.53238 -5.51325,-1.10035 z"
+ style="fill:#fcbec0" />
+ <path
+ id="path3189"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m 15.867,-3.4555 c -2.13975,-1.49873 -3.49156,-7.8263 -3.74817,-17.5445 l -0.11883,-4.5 5,-1.66983 c 6.5578,-2.19008 6.5,-2.19412 6.5,0.45449 0,1.25656 0.9,4.84532 2,7.97502 2.56186,7.28896 2.57769,9.74032 0.0629,9.74032 -1.65538,0 -1.85452,0.50906 -1.36916,3.5 0.55605,3.4265 0.4964,3.5 -2.84036,3.5 -1.87459,0 -4.34344,-0.65497 -5.48635,-1.4555 z m -18.60545,-1.38463 c -3.43887,-2.08117 -3.72417,-2.86336 -4.4426,-12.17971 -0.78522,-10.18248 0.13117,-11.85397 6.28649,-11.46653 l 4.65321,0.29289 2.84267,6.34674 c 3.65068,8.15076 3.60396,10.13172 -0.35132,14.89597 -3.55811,4.28584 -4.88093,4.59646 -8.98845,2.11064 z"
+ style="fill:#fcc6b6" />
+ <path
+ id="path3187"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m 15.86726,-3.77224 c -1.42817,-1.15698 -2.34597,-3.37956 -2.77818,-6.72776 -0.35499,-2.75 -0.87727,-6.8 -1.16063,-9 -0.63335,-4.91747 0.30316,-6.41121 4.67526,-7.45707 1.86796,-0.44683 4.18379,-1.13743 5.14629,-1.53467 1.38018,-0.56961 1.75,-0.21682 1.75,1.66941 0,1.31541 0.9,4.95231 2,8.08201 1.1,3.12969 2,6.6016 2,7.71534 0,1.35831 -0.65844,2.02498 -2,2.02498 -1.61905,0 -2,0.66667 -2,3.5 0,3.15691 -0.26957,3.49782 -2.75,3.47776 -1.5125,-0.0122 -3.70973,-0.79973 -4.88274,-1.75 z m -18.62479,-1.06919 c -3.28171,-1.97384 -3.41746,-2.3794 -4.2374,-12.65857 -0.80902,-10.14237 0.0964,-11.68239 6.35676,-10.81264 4.18382,0.58125 4.47966,0.85505 7.24921,6.70931 3.85095,8.14012 3.70716,10.04334 -1.11219,14.72035 -4.47969,4.34739 -4.43931,4.33741 -8.25638,2.04155 z"
+ style="fill:#fcb8b7" />
+ <path
+ id="path3185"
+ d="m 180.95274,913.78034 c -1.68968,-0.81858 -2.47019,-2.83106 -3.833,-9.88312 -2.09004,-10.81512 -1.64459,-12.66589 3.26108,-13.54927 2.0315,-0.36582 4.20048,-1.06536 4.81994,-1.55453 0.77792,-0.61429 1.49677,0.58187 2.324,3.8671 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09968,2.7008 1.47131,4.7633 0.60026,3.33127 0.44732,3.75 -1.36961,3.75 -1.71953,0 -2.04531,0.63713 -2.04531,4 0,3.50153 -0.28039,3.99157 -2.25,3.93232 -1.2375,-0.0372 -3.20478,-0.53023 -4.37172,-1.09558 z m -19.9947,-2.63358 c -2.78682,-2.54536 -3.12379,-3.53611 -3.74785,-11.01905 -0.7913,-9.4884 0.22403,-12.72439 3.69989,-11.79201 1.19041,0.31933 3.15582,0.58674 4.36759,0.59425 1.65866,0.0103 2.72727,1.18765 4.32359,4.76365 3.4929,7.82464 3.41122,11.85531 -0.3316,16.3645 -1.75736,2.1172 -3.65741,3.85756 -4.22234,3.86747 -0.56493,0.01 -2.4051,-1.24055 -4.08928,-2.77881 z"
+ style="fill:#fbb4a7" />
+ <path
+ id="path3183"
+ d="m 181.40888,913.54887 c -1.90156,-0.94762 -2.66716,-2.73407 -4.12887,-9.6343 -2.11431,-9.98096 -1.48228,-12.43122 3.4804,-13.49292 1.82273,-0.38995 3.82089,-1.11594 4.44035,-1.61331 0.78167,-0.6276 1.49279,0.55112 2.324,3.85218 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09346,2.66764 1.45749,4.68962 0.59423,3.30058 0.4287,3.70941 -1.61961,4 -1.89768,0.26923 -2.23157,0.84875 -1.98478,3.44483 0.34701,3.6502 -2.13396,4.89193 -5.96229,2.98412 z m -19.59537,-1.75085 c -3.85286,-2.43946 -4.12485,-3.26446 -4.46668,-13.54855 -0.29145,-8.76823 0.67103,-11.1791 3.91041,-9.79498 0.99947,0.42706 2.70818,0.82431 3.79713,0.88279 2.50572,0.13456 5.98356,6.56952 6.78668,12.55723 0.55271,4.12079 0.33707,4.68072 -3.14285,8.16065 l -3.73629,3.73628 -3.1484,-1.99342 z"
+ style="fill:#fbc693" />
+ <path
+ id="path3181"
+ d="m 181.40888,913.54887 c -1.90156,-0.94762 -2.66716,-2.73407 -4.12887,-9.6343 -2.11431,-9.98096 -1.48228,-12.43122 3.4804,-13.49292 1.82273,-0.38995 3.82089,-1.11594 4.44035,-1.61331 0.78167,-0.6276 1.49279,0.55112 2.324,3.85218 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09346,2.66764 1.45749,4.68962 0.59423,3.30058 0.4287,3.70941 -1.61961,4 -1.89768,0.26923 -2.23157,0.84875 -1.98478,3.44483 0.34701,3.6502 -2.13396,4.89193 -5.96229,2.98412 z m -19.59537,-1.75085 c -3.85797,-2.44269 -4.12541,-3.25919 -4.46668,-13.63661 -0.21296,-6.47571 0.053,-8.48421 1.21927,-9.20836 0.92359,-0.57346 1.85661,-0.5612 2.45,0.0322 0.5271,0.5271 2.21605,0.95836 3.75324,0.95836 2.32203,0 3.11778,0.71903 4.70349,4.25 1.04975,2.3375 2.1601,6.00739 2.46746,8.15531 0.5041,3.52278 0.18969,4.27446 -3.20977,7.67393 l -3.76861,3.7686 -3.1484,-1.99342 z"
+ style="fill:#fba7a6" />
+ <path
+ id="path3179"
+ d="m 180.42487,912.6936 c -2.246,-1.83276 -5.24235,-17.14915 -3.86013,-19.73183 0.59405,-1.10999 1.40175,-2.02891 1.7949,-2.04203 0.39315,-0.0131 2.38169,-0.41108 4.41898,-0.88435 l 3.70417,-0.86049 1.20496,5.38435 c 0.66273,2.96139 1.63584,5.38435 2.16247,5.38435 0.52663,0 0.72226,0.89955 0.43475,1.999 -0.28751,1.09946 -0.115,2.25101 0.38337,2.55902 1.72728,1.06752 0.8953,2.41725 -1.34388,2.18019 -1.77357,-0.18777 -2.27296,0.29115 -2.35843,2.26179 -0.20189,4.65475 -0.38835,5 -2.70044,5 -1.26988,0 -2.9982,-0.5625 -3.84072,-1.25 z m -19.64276,-1.72785 c -3.80444,-3.17207 -5.11148,-21.0776 -1.63594,-22.41129 0.75033,-0.28793 1.63021,-0.0932 1.95528,0.43281 0.32508,0.52598 1.92562,0.95633 3.55678,0.95633 3.39807,0 4.50718,2.01814 5.96224,10.84895 0.82009,4.97716 0.69273,5.58534 -1.83233,8.74997 -3.07999,3.86011 -4.73127,4.15366 -8.00603,1.42323 z"
+ style="fill:#fb9fa0" />
+ <path
+ id="path3177"
+ d="m 180.32446,912.8635 c -0.9625,-0.5606 -1.75,-1.98067 -1.75,-3.1557 0,-1.17503 -0.70563,-4.95003 -1.56806,-8.38889 -1.97329,-7.8683 -1.07849,-9.92916 4.82218,-11.10618 l 4.24588,-0.84693 1.23482,4.0389 c 0.67915,2.22139 1.24165,5.24426 1.25,6.71747 0.008,1.47322 0.72232,3.38572 1.58661,4.25 0.86428,0.86429 1.20178,1.62334 0.75,1.68678 -0.45179,0.0634 -1.49643,0.17594 -2.32143,0.25 -0.89743,0.0806 -1.5,1.13894 -1.5,2.63465 0,4.68395 -2.72313,6.26534 -6.75,3.9199 z m -18.59061,-1.52081 c -3.18441,-2.23045 -4.15936,-5.40703 -4.3244,-14.08961 -0.10379,-5.46081 0.23701,-7.73594 1.25286,-8.36377 0.80738,-0.49899 1.7993,-0.45856 2.35379,0.0959 0.5271,0.5271 2.2295,0.95836 3.78311,0.95836 3.22728,0 4.77525,2.79781 4.77525,8.63084 0,1.92535 0.46718,4.37357 1.03817,5.44049 0.83398,1.5583 0.48978,2.62715 -1.75,5.43423 -3.14945,3.94716 -3.90883,4.14887 -7.12878,1.89353 z"
+ style="fill:#fba896" />
+ <path
+ id="path3175"
+ d="m 180.38153,912.23762 c -1.73595,-1.96787 -4.23706,-14.37731 -3.66592,-18.18864 0.28615,-1.90951 1.28961,-2.62988 4.95335,-3.55593 l 4.5945,-1.16131 1.1555,4.32028 c 0.63553,2.37616 1.1555,5.40668 1.1555,6.7345 0,1.32782 0.70714,3.12137 1.57143,3.98565 0.86428,0.86429 1.20178,1.62334 0.75,1.68678 -0.45179,0.0634 -1.49643,0.17594 -2.32143,0.25 -0.91279,0.0819 -1.69574,1.5048 -2,3.63465 -0.58275,4.07922 -3.62426,5.20588 -6.19293,2.29402 z m -19.3807,-1.60369 c -2.4799,-2.13313 -2.72327,-3.03845 -3.18385,-11.84386 -0.42411,-8.10811 -0.25997,-9.6258 1.09736,-10.14665 0.87784,-0.33686 1.86204,-0.18213 2.18711,0.34385 0.32508,0.52598 1.66397,0.95633 2.97532,0.95633 3.15873,0 5.49769,3.52618 5.49769,8.28825 0,2.11378 0.46554,4.71311 1.03454,5.77629 0.85492,1.59744 0.42667,2.54092 -2.46667,5.43425 -1.92566,1.92567 -3.71611,3.50121 -3.97877,3.50121 -0.26267,0 -1.68589,-1.03935 -3.16273,-2.30967 z"
+ style="fill:#fb9997" />
+ <path
+ id="path3173"
+ d="m 180.61925,912.49757 c -1.54558,-1.86231 -3.96316,-11.97209 -4.00917,-16.76543 -0.0337,-3.51238 0.18575,-3.77106 4.09158,-4.82279 2.32002,-0.62472 4.50572,-0.73283 4.99166,-0.24689 0.47544,0.47544 1.39155,3.48908 2.03578,6.69698 0.89078,4.43548 0.89278,6.27859 0.008,7.69478 -0.63959,1.02423 -1.16294,3.1702 -1.16294,4.76882 0,3.89193 -3.60222,5.50971 -5.95521,2.67453 z M 161.2105,910.6419 c -2.67903,-2.14379 -2.89701,-2.87138 -3.37577,-11.26821 -0.41609,-7.29756 -0.2244,-9.21497 1.02493,-10.25182 1.03553,-0.85942 1.74811,-0.9334 2.18479,-0.22683 0.35642,0.57671 1.69139,1.04856 2.96658,1.04856 3.39213,0 4.82534,2.37252 5.16837,8.55569 0.16748,3.01883 0.57322,5.92356 0.90165,6.45497 0.54751,0.8859 -4.35593,7.99571 -5.50659,7.98434 -0.275,-0.003 -1.78878,-1.03623 -3.36396,-2.2967 z"
+ style="fill:#fac868" />
+ <path
+ id="path3171"
+ d="m 180.61925,912.49757 c -1.54558,-1.86231 -3.96316,-11.97209 -4.00917,-16.76543 -0.0337,-3.51238 0.18575,-3.77106 4.09158,-4.82279 2.32002,-0.62472 4.50572,-0.73283 4.99166,-0.24689 0.47544,0.47544 1.39155,3.48908 2.03578,6.69698 0.89078,4.43548 0.89278,6.27859 0.008,7.69478 -0.63959,1.02423 -1.16294,3.1702 -1.16294,4.76882 0,3.89193 -3.60222,5.50971 -5.95521,2.67453 z m -19.45977,-1.89636 c -2.83469,-2.2682 -2.91733,-2.59171 -3,-11.74503 l -0.085,-9.41258 4,0.33285 c 5.42153,0.45115 6.73448,2.04528 7.09921,8.61958 0.17063,3.07562 0.57895,6.02682 0.90738,6.55823 0.54751,0.8859 -4.35593,7.99571 -5.50659,7.98434 -0.275,-0.003 -1.81174,-1.05454 -3.41498,-2.33739 z"
+ style="fill:#fa9588" />
+ <path
+ id="path3169"
+ d="m 181.27717,912.6936 c -2.29214,-1.70591 -5.542,-17.19589 -4.09055,-19.49693 1.25861,-1.99531 7.28306,-3.75785 8.54186,-2.49904 1.62734,1.62734 3.20598,13.28597 1.96678,14.52517 -0.61644,0.61644 -1.1208,2.2908 -1.1208,3.7208 0,2.4 -1.56461,5 -3.00887,5 -0.33488,0 -1.36467,-0.5625 -2.28842,-1.25 z m -19.82628,-2.16376 c -2.22007,-2.05857 -2.7042,-3.5724 -3.28996,-10.28744 -0.75026,-8.60077 -0.13895,-11.72478 2.12436,-10.85627 0.79901,0.30661 2.52511,0.55747 3.83577,0.55747 3.1779,0 4.5433,2.83475 4.90988,10.19353 0.23862,4.78997 -0.13818,6.723 -1.82795,9.37775 -1.17069,1.83924 -2.35813,3.36311 -2.63875,3.38639 -0.28062,0.0233 -1.68163,-1.04386 -3.11335,-2.37143 z"
+ style="fill:#fa8b86" />
+ <path
+ id="path3167"
+ d="m 180.07939,911.6936 c -0.96604,-2.79329 -3.50493,-15.00852 -3.50493,-16.86308 0,-1.34263 1.1834,-2.48343 3.64167,-3.51056 5.43653,-2.27153 6.86784,-0.40276 6.82572,8.91194 -0.0454,10.04111 -0.8895,12.7117 -4.01783,12.7117 -1.38178,0 -2.70687,-0.5625 -2.94463,-1.25 z m -19.29027,-2.20424 c -1.3053,-1.65942 -2.14743,-4.84806 -2.60032,-9.84592 -0.87694,-9.67732 -0.44657,-10.69807 4.21367,-9.99407 2.01959,0.30509 4.11891,0.96552 4.66515,1.46762 0.54623,0.50211 1.2459,4.156 1.55481,8.11977 0.48082,6.16945 0.2748,7.60269 -1.43121,9.95684 -2.45809,3.39195 -3.91374,3.4592 -6.4021,0.29576 z"
+ style="fill:#f9aa67" />
+ <path
+ id="path3165"
+ d="m 180.23917,912.1936 c -0.24933,-0.4125 -1.26783,-4.68555 -2.26334,-9.49567 -1.97889,-9.5616 -1.79281,-10.20809 3.36397,-11.68703 4.53536,-1.30072 5.74188,0.67547 5.70205,9.33952 -0.0452,9.8259 -0.90819,12.59318 -3.92743,12.59318 -1.33206,0 -2.62592,-0.3375 -2.87525,-0.75 z m -19.45005,-2.70424 c -1.3053,-1.65942 -2.14743,-4.84806 -2.60032,-9.84592 -0.79775,-8.8035 -0.22455,-11.09678 2.41988,-9.68153 1.00886,0.53993 2.95856,0.98169 4.33265,0.98169 2.92589,0 3.40329,1.19686 3.78937,9.5 0.20907,4.49625 -0.18031,6.68922 -1.55363,8.75 -2.26265,3.39527 -3.89059,3.47065 -6.38795,0.29576 z"
+ style="fill:#fa8974" />
+ <path
+ id="path3163"
+ d="m 180.72006,911.61903 c -1.4979,-1.80485 -4.31584,-15.56371 -3.63009,-17.72428 0.67874,-2.13853 7.23738,-3.59767 8.86474,-1.9722 1.21641,1.215 1.28853,11.23559 0.1243,17.27105 -0.76211,3.95089 -3.18344,5.04676 -5.35895,2.42543 z m -19.6989,-1.73433 c -2.13154,-2.35532 -3.97555,-16.59894 -2.39543,-18.50288 0.51226,-0.61723 0.59778,-1.47929 0.19005,-1.91568 -0.40772,-0.4364 0.2416,-0.28249 1.44294,0.34201 1.20134,0.6245 3.09801,1.13545 4.21481,1.13545 1.11681,0 2.51821,0.91118 3.11423,2.02485 2.07725,3.88138 -0.75392,18.97515 -3.5592,18.97515 -0.62927,0 -1.9826,-0.9265 -3.0074,-2.0589 z"
+ style="fill:#fa7c74" />
+ <path
+ id="path3161"
+ d="m 180.91399,911.73649 c -0.5371,-0.71109 -1.7753,-4.79608 -2.75154,-9.07776 -1.36171,-5.97223 -1.5043,-8.11105 -0.6124,-9.18572 1.45048,-1.74772 6.93018,-3.02459 8.07048,-1.88057 1.16986,1.17368 1.36105,11.98823 0.29772,16.84039 -0.90326,4.12175 -3.22742,5.65609 -5.00426,3.30366 z M 162.4878,910.6618 c -3.08149,-2.3659 -4.01734,-5.72011 -3.8248,-13.70865 0.17568,-7.28887 0.33626,-7.85257 1.98556,-6.96989 0.98693,0.52818 2.70817,0.96034 3.82497,0.96034 1.11681,0 2.4717,0.82427 3.01086,1.83171 1.24877,2.33334 0.244,12.81559 -1.57376,16.41829 -1.59155,3.15436 -1.35745,3.05394 -3.42283,1.4682 z"
+ style="fill:#f97568" />
+ <path
+ id="path3159"
+ d="m 181.18872,912.12848 c -1.12357,-1.81798 -3.61426,-12.66104 -3.61426,-15.73446 0,-2.38301 0.60749,-3.40618 2.54705,-4.28991 5.29419,-2.41219 6.50298,-1.14797 6.37883,6.67128 -0.13265,8.35393 -1.29475,13.61677 -3.08264,13.96046 -0.91122,0.17517 -1.91426,-0.0982 -2.22898,-0.60737 z m -20.20927,-3.28761 c -1.53322,-1.69237 -1.9442,-3.84084 -2.10589,-11.00891 -0.19049,-8.44507 -0.10329,-8.85393 1.68426,-7.89726 1.03684,0.55489 2.78818,1.0089 3.89188,1.0089 1.1037,0 2.34895,0.55373 2.76722,1.2305 1.11829,1.80944 0.48625,12.83248 -0.91853,16.0195 -1.4532,3.29687 -2.77301,3.45748 -5.31894,0.64727 z"
+ style="fill:#f9904b" />
+ <path
+ id="path3157"
+ d="m 181.18872,912.12848 c -1.14282,-1.84912 -3.61426,-12.68601 -3.61426,-15.84797 0,-2.88972 0.40359,-3.35434 3.7057,-4.26609 4.58817,-1.26686 5.28526,-0.4058 5.20486,6.42918 -0.10111,8.5965 -1.24846,13.94261 -3.06732,14.29225 -0.91122,0.17517 -1.91426,-0.0982 -2.22898,-0.60737 z m -20.20649,-3.28679 c -1.44296,-1.59445 -1.9879,-3.98904 -2.25717,-9.91855 l -0.35497,-7.81664 4.35218,0.55614 c 2.39371,0.30587 4.5587,0.73823 4.8111,0.96079 0.90854,0.80113 -0.0496,12.88089 -1.23498,15.57017 -1.45309,3.29661 -2.77359,3.45759 -5.31616,0.64809 z"
+ style="fill:#f96c64" />
+ <path
+ id="path3155"
+ d="m 182.00194,912.15744 c -1.28515,-0.85536 -4.42748,-11.79022 -4.42748,-15.407 0,-2.82016 1.32386,-4.22994 4.76309,-5.07221 3.51518,-0.86088 4.61133,2.30777 3.86257,11.16552 -0.62875,7.43814 -2.10279,10.70831 -4.19818,9.31369 z m -19.65615,-2.43812 c -2.51948,-1.91174 -3.77133,-6.20961 -3.77133,-12.94781 0,-5.09857 0.24696,-5.94712 1.58179,-5.4349 0.86998,0.33384 2.89498,0.60699 4.5,0.60699 l 2.91821,0 -0.0222,7.25 c -0.0164,5.34852 -0.4816,7.84686 -1.7737,9.52572 -1.48125,1.92462 -2.01085,2.0789 -3.43274,1 z"
+ style="fill:#f8a727" />
+ <path
+ id="path3153"
+ d="m 182.00194,912.15744 c -1.28515,-0.85536 -4.42748,-11.79022 -4.42748,-15.407 0,-2.82016 1.32386,-4.22994 4.76309,-5.07221 3.51518,-0.86088 4.61133,2.30777 3.86257,11.16552 -0.62875,7.43814 -2.10279,10.70831 -4.19818,9.31369 z m -19.65615,-2.43812 c -2.51948,-1.91174 -3.77133,-6.20961 -3.77133,-12.94781 0,-5.09857 0.24696,-5.94712 1.58179,-5.4349 0.86998,0.33384 1.72785,0.60699 1.90638,0.60699 0.17852,0 0.0911,0.89278 -0.19423,1.98395 -0.66163,2.5301 0.44138,7.01605 1.72511,7.01605 0.53952,0 0.98095,-2.025 0.98095,-4.5 0,-3.33333 0.38889,-4.5 1.5,-4.5 2.31179,0 2.07009,13.70149 -0.29594,16.77572 -1.48125,1.92462 -2.01084,2.0789 -3.43273,1 z"
+ style="fill:#f97656" />
+ <path
+ id="path3151"
+ d="m 182.00194,912.15744 c -1.30059,-0.86563 -4.42748,-11.8084 -4.42748,-15.49426 0,-2.81806 2.38324,-4.71958 5.91521,-4.71958 2.73688,0 3.51703,3.46196 2.66677,11.83399 -0.68096,6.70511 -2.16705,9.70263 -4.1545,8.37985 z m -19.6862,-2.46009 c -2.64876,-2.01116 -3.61818,-6.01981 -3.02848,-12.52309 0.39024,-4.30358 0.91579,-5.92668 1.80816,-5.58424 0.69191,0.26551 1.03216,1.34646 0.7561,2.40212 -0.64783,2.47728 0.47338,6.95146 1.74199,6.95146 0.53952,0 0.98095,-2.025 0.98095,-4.5 0,-4.55243 1.37549,-6.04303 2.45059,-2.65567 0.719,2.26536 -1.01511,15.12019 -2.19947,16.30455 -0.47815,0.47815 -1.59029,0.30306 -2.50984,-0.39513 z"
+ style="fill:#f88f2e" />
+ <path
+ id="path3149"
+ d="m 182.00194,912.15744 c -1.30059,-0.86563 -4.42748,-11.8084 -4.42748,-15.49426 0,-2.81806 2.38324,-4.71958 5.91521,-4.71958 2.73688,0 3.51703,3.46196 2.66677,11.83399 -0.68096,6.70511 -2.16705,9.70263 -4.1545,8.37985 z m -19.60247,-2.28383 c -2.66678,-1.50524 -3.80043,-6.75809 -2.89841,-13.43001 0.6194,-4.58155 0.84216,-5.12459 0.94228,-2.29705 0.16099,4.5464 1.99307,8.79705 3.79163,8.79705 0.96049,0 1.34809,-1.62693 1.3699,-5.75 0.0233,-4.40049 0.27006,-5.3385 1.05154,-3.99669 1.11218,1.90963 -0.30428,15.37887 -1.76899,16.82145 -0.44713,0.44038 -1.56671,0.37524 -2.48795,-0.14475 z"
+ style="fill:#f96656" />
+ <path
+ id="path3147"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.21163,-4.031 -2.17681,-8.0411 -1.6772,-6.9684 -1.67641,-7.3778 0.0179,-9.25 0.97502,-1.0774 2.76607,-1.9589 3.98011,-1.9589 1.91826,0 2.28765,0.68753 2.82066,5.25 0.33734,2.8875 0.4264,6.15 0.19791,7.25 -0.22848,1.1 -0.6761,3.2375 -0.9947,4.75 -0.53504,2.53994 -2.86076,3.74965 -3.84508,2 z m -20.1394,-3.47251 c -1.11749,-1.59544 -1.51155,-4.34633 -1.39666,-9.75 0.088,-4.14012 0.32918,-5.95249 0.53592,-4.02749 1.06111,9.88038 5.29481,12.46707 5.31935,3.25 0.0111,-4.14972 0.29159,-5.33254 1.00802,-4.25 1.88648,2.85051 -0.72336,17 -3.13561,17 -0.42587,0 -1.47483,-1.00013 -2.33102,-2.22251 z"
+ style="fill:#f87844" />
+ <path
+ id="path3145"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.22583,-4.08894 -2.20836,-8.16986 l -1.78643,-7.41986 2.26013,-1.83014 c 4.07651,-3.30096 5.69263,-2.4342 6.37653,3.41986 0.33734,2.8875 0.4264,6.15 0.19791,7.25 -0.22848,1.1 -0.6761,3.2375 -0.9947,4.75 -0.53504,2.53994 -2.86076,3.74965 -3.84508,2 z m -20.1394,-3.47251 c -1.68769,-2.40951 -2.14046,-8.77749 -0.62409,-8.77749 0.51294,0 1.21826,0.9 1.56739,2 0.34913,1.1 1.27945,2 2.06739,2 1.48177,0 1.88623,2.65431 0.82562,5.41821 -0.83507,2.17617 -1.9995,1.9817 -3.83631,-0.64072 z m 4.45861,-10.58651 c -0.009,-2.62138 0.37634,-4.06696 0.98469,-3.69098 1.2685,0.78398 1.2685,4.53713 0,6.5 -0.70877,1.09674 -0.97349,0.34157 -0.98469,-2.80902 z"
+ style="fill:#f96547" />
+ <path
+ id="path3143"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.2224,-4.07496 -2.20075,-8.13879 l -1.77881,-7.38879 2.39173,-1.85364 c 1.31545,-1.0195 3.06673,-1.73864 3.89173,-1.59809 2.56229,0.43651 3.33281,10.73419 1.34529,17.97931 -0.48139,1.75482 -2.85813,2.40613 -3.64919,1 z m -20.1394,-3.47251 c -1.71422,-2.44739 -2.08719,-7.33159 -0.6287,-8.23299 0.51041,-0.31545 1.21573,0.33299 1.56739,1.44098 0.35166,1.10799 1.28406,2.01452 2.072,2.01452 1.54518,0 1.75012,1.2133 0.80232,4.75 -0.76127,2.84068 -1.83714,2.84843 -3.81301,0.0275 z m 4.71566,-10.77749 c 0,-2.475 0.19502,-3.4875 0.43337,-2.25 0.23836,1.2375 0.23836,3.2625 0,4.5 -0.23835,1.2375 -0.43337,0.225 -0.43337,-2.25 z"
+ style="fill:#f87637" />
+ <path
+ id="path3141"
+ d="m 181.27056,911.1936 c -1.3015,-2.31344 -3.81424,-15.51051 -3.07198,-16.13419 2.11924,-1.78067 6.32464,-3.00774 6.93324,-2.023 0.89503,1.44819 0.93106,13.97216 0.0479,16.65719 -0.71185,2.16425 -3.03417,3.05535 -3.90918,1.5 z m -20.1394,-3.47251 c -1.89753,-2.7091 -2.11846,-8.13141 -0.3067,-7.52749 0.6875,0.22917 1.25,0.97794 1.25,1.66394 0,0.68601 0.76594,1.80735 1.70209,2.49188 1.09786,0.80278 1.5002,2.01663 1.13337,3.41939 -0.72377,2.76767 -1.81644,2.75388 -3.77876,-0.0477 z"
+ style="fill:#f95947" />
+ <path
+ id="path3139"
+ d="m 181.07693,908.3252 c -0.89888,-2.13488 -1.88744,-5.97767 -2.19679,-8.53953 -0.53507,-4.43117 -0.41126,-4.73611 2.54336,-6.26401 3.06503,-1.58498 3.11446,-1.57168 3.76318,1.01304 0.83773,3.33777 -0.26675,15.46342 -1.52292,16.71959 -0.60332,0.60333 -1.55161,-0.47042 -2.58683,-2.92909 z m -19.94937,-1.9409 c -1.73917,-2.65431 -1.76322,-6.12764 -0.0394,-5.6907 0.54247,0.1375 0.98631,0.73627 0.98631,1.33061 0,0.59434 0.79532,1.66216 1.76737,2.37295 1.05669,0.77267 1.51631,1.94659 1.14301,2.91938 -0.87597,2.28274 -1.91533,2.03154 -3.85728,-0.93224 z"
+ style="fill:#f86636" />
+ <path
+ id="path3137"
+ d="m 181.03879,908.23391 c -0.87791,-2.08467 -1.8542,-5.92781 -2.16955,-8.54031 -0.47898,-3.96811 -0.30352,-4.75 1.06593,-4.75 0.90161,0 1.63929,-0.45 1.63929,-1 0,-0.55 0.61703,-1 1.37117,-1 2.65993,0 3.14174,16.94693 0.52774,18.56248 -0.46111,0.28498 -1.55667,-1.1875 -2.43458,-3.27217 z m -19.84932,-1.75513 c -1.98831,-3.03454 -2.07595,-5.20185 -0.21035,-5.20185 0.77256,0 1.20208,0.52791 0.95449,1.17312 -0.24759,0.64522 0.24531,1.75032 1.09534,2.45578 1.6689,1.38507 2.10285,4.03777 0.66052,4.03777 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z"
+ style="fill:#f87625" />
+ <path
+ id="path3135"
+ d="m 181.03879,908.23391 c -2.37362,-5.63637 -3.12438,-13.29031 -1.30362,-13.29031 0.79161,0 1.97929,0.54 2.63929,1.2 0.93333,0.93333 1.22435,0.65556 1.30957,-1.25 0.064,-1.43104 0.49036,-0.57843 1.02516,2.05 0.97852,4.80922 0.25046,13.6439 -1.19815,14.5392 -0.48183,0.29778 -1.59434,-1.16422 -2.47225,-3.24889 z m -19.84932,-1.75513 c -0.88826,-1.35565 -1.61277,-3.26815 -1.61004,-4.25 0.004,-1.38626 0.55447,-1.11479 2.46403,1.21482 2.5072,3.05871 3.23781,5.5 1.64601,5.5 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z"
+ style="fill:#f84c44" />
+ <path
+ id="path3133"
+ d="m 180.2359,905.85828 c -2.08019,-6.44092 -2.17055,-10.91468 -0.22046,-10.91468 0.79254,0 1.78583,0.55796 2.2073,1.23992 0.51891,0.83962 0.96887,0.43607 1.39375,-1.25 0.46839,-1.85877 0.80267,-0.96902 1.31871,3.51008 0.71114,6.17236 -0.18036,11.60654 -2.00382,12.21436 -0.56872,0.18957 -1.78169,-1.97028 -2.69548,-4.79968 z m -18.5123,-0.55793 c -1.29298,-1.23837 -2.18431,-2.75123 -1.98075,-3.36191 0.20356,-0.61068 1.41357,0.30103 2.68891,2.02602 2.80692,3.79656 2.48839,4.39744 -0.70816,1.33589 z"
+ style="fill:#f86827" />
+ <path
+ id="path3131"
+ d="m 180.2359,905.85828 c -1.86184,-5.76484 -2.17392,-10.91468 -0.66144,-10.91468 0.55,0 1,0.45 1,1 0,0.55 0.68465,1 1.52144,1 2.50204,0 3.88913,4.40836 2.87647,9.14182 -0.49385,2.30842 -1.38776,4.35915 -1.98647,4.55717 -0.59871,0.19803 -1.83621,-1.95491 -2.75,-4.78431 z m -18.5123,-0.55793 c -1.29298,-1.23837 -2.18431,-2.75123 -1.98075,-3.36191 0.20356,-0.61068 1.41357,0.30103 2.68891,2.02602 2.80692,3.79656 2.48839,4.39744 -0.70816,1.33589 z"
+ style="fill:#f8543b" />
+ <path
+ id="path3129"
+ d="m 180.29865,905.15272 c -0.94831,-3.19444 -1.72419,-6.51091 -1.72419,-7.36993 0,-2.36962 4.94315,-1.05807 6.17129,1.6374 1.14526,2.51357 -0.10153,10.66682 -1.71332,11.20409 -0.55528,0.18509 -1.78548,-2.27711 -2.73378,-5.47156 z"
+ style="fill:#f8641b" />
+ <path
+ id="path3127"
+ d="m 180.29609,905.14412 c -0.9469,-3.18971 -1.72163,-6.55059 -1.72163,-7.46861 0,-2.24903 2.73366,-1.14642 3.55227,1.43279 0.39906,1.25732 1.18505,1.76634 2.15355,1.39469 1.29252,-0.49599 1.41642,0.14122 0.81229,4.17768 -1.24083,8.29061 -2.43855,8.40634 -4.79648,0.46345 z"
+ style="fill:#f84936" />
+ <path
+ id="path3125"
+ d="m 181.14286,906.45307 c -1.73239,-4.14621 -2.09098,-9.50947 -0.63579,-9.50947 0.51294,0 1.22859,0.93254 1.59034,2.07232 0.41698,1.31378 1.20605,1.86191 2.15571,1.49749 1.24752,-0.47871 1.38241,0.1362 0.80674,3.67768 -0.9703,5.96925 -2.09631,6.6195 -3.917,2.26198 z"
+ style="fill:#f85818" />
+ <path
+ id="path3123"
+ d="m 181.09683,906.3429 c -0.88794,-2.12514 -1.44768,-5.22186 -1.24388,-6.8816 l 0.37056,-3.0177 0.81643,3.32977 c 0.62382,2.54421 1.24413,3.21792 2.62934,2.85569 1.54861,-0.40498 1.72746,-0.0157 1.22681,2.67022 -0.91755,4.92246 -2.04875,5.23318 -3.79926,1.04362 z"
+ style="fill:#f84528" />
+ <path
+ id="path3121"
+ d="m 182.18715,908.75698 c -2.04329,-7.19112 -2.31672,-8.87827 -1.51879,-9.37142 0.49836,-0.30799 0.9061,0.36656 0.9061,1.49902 0,1.16357 0.65233,2.05902 1.5,2.05902 0.99331,0 1.5,0.99344 1.5,2.94098 0,3.06564 -1.73817,5.15699 -2.38731,2.8724 z"
+ style="fill:#f83b28" />
+ <path
+ id="path3119"
+ d="m 181.63518,905.09018 c -0.68081,-1.64361 -1.02518,-3.81148 -0.76528,-4.81748 0.38073,-1.47369 0.4951,-1.3919 0.58856,0.4209 0.0661,1.28178 0.76148,2.25 1.616,2.25 1.64633,0 1.93861,1.75999 0.63396,3.81749 -0.60865,0.95987 -1.1714,0.50633 -2.07324,-1.67091 z"
+ style="fill:#f8461a" />
+ <path
+ id="path3117"
+ d="m 182.21283,906.4436 c -0.3471,-0.90455 -0.005,-1.5 0.86163,-1.5 0.86669,0 1.20873,0.59545 0.86163,1.5 -0.31659,0.825 -0.70432,1.5 -0.86163,1.5 -0.15731,0 -0.54504,-0.675 -0.86163,-1.5 z"
+ style="fill:#f8381c" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship2.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship2.svg
new file mode 100755
index 0000000..4288c2e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship2.svg
@@ -0,0 +1,599 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="40"
+ height="102.41489"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="spaceship2.svg">
+ <defs
+ id="defs4">
+ <inkscape:path-effect
+ effect="skeletal"
+ id="path-effect3784"
+ is_visible="true"
+ pattern="M 0,5 C 0,2.24 2.24,0 5,0 7.76,0 10,2.24 10,5 10,7.76 7.76,10 5,10 2.24,10 0,7.76 0,5 z"
+ copytype="single_stretched"
+ prop_scale="1"
+ scale_y_rel="false"
+ spacing="0"
+ normal_offset="0"
+ tang_offset="0"
+ prop_units="false"
+ vertical_pattern="false"
+ fuse_tolerance="0" />
+ <inkscape:path-effect
+ effect="skeletal"
+ id="path-effect3780"
+ is_visible="true"
+ pattern="m -38,719.36218 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 z"
+ copytype="single_stretched"
+ prop_scale="1"
+ scale_y_rel="false"
+ spacing="0"
+ normal_offset="0"
+ tang_offset="0"
+ prop_units="false"
+ vertical_pattern="false"
+ fuse_tolerance="0" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ id="perspective10" />
+ <inkscape:perspective
+ id="perspective2923"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective3930"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4003"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4133"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective4204"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2913"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective3053"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective2898"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ id="perspective3109"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="51.367568"
+ inkscape:cy="103.49999"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-22.2069,-948.02873)">
+ <g
+ id="g3211"
+ transform="matrix(0.48934829,0,0,0.48934829,11.339991,536.41083)">
+ <path
+ inkscape:original-d="m 37,942.81046 c 0.574713,0.14367 1.149425,0.28735 0,0 z"
+ inkscape:path-effect="#path-effect3780"
+ id="path3778"
+ d="m 37,942.81046 c 0.167098,-0.66843 0.34309,-1.2936 0.486364,-1.7242 0.143274,-0.4306 0.253551,-0.66551 0.31386,-0.65187 0.06031,0.0136 0.07065,0.2758 0.04077,0.73251 -0.02988,0.45671 -0.09969,1.10684 -0.175087,1.79783 -0.0015,0.004 -0.003,0.007 -0.0044,0.0112 -0.257922,0.64338 -0.501864,1.24926 -0.690253,1.66648 -0.188389,0.41721 -0.32095,0.64463 -0.380785,0.62966 -0.05983,-0.015 -0.04694,-0.27232 0.02884,-0.7177 0.07578,-0.44537 0.21418,-1.07766 0.380734,-1.74389 0.166554,-0.66623 0.341982,-1.28926 0.484718,-1.7179 0.142736,-0.42864 0.252501,-0.66177 0.312355,-0.64682 0.05985,0.015 0.06979,0.27801 0.03961,0.73477 -0.03018,0.45676 -0.100211,1.10613 -0.175623,1.79513 -4.36e-4,0.004 -8.73e-4,0.008 -0.0013,0.0119 -0.258431,0.64522 -0.502606,1.25177 -0.691076,1.66883 -0.188471,0.41707 -0.320958,0.64354 -0.380601,0.62718 -0.05964,-0.0163 -0.04644,-0.27553 0.02975,-0.72289 0.07619,-0.44737 0.215079,-1.08182 0.382177,-1.75025 z"
+ style="fill:#000000;fill-rule:evenodd;stroke:none" />
+ <g
+ transform="translate(-184.55172,103.22414)"
+ id="g4020">
+ <path
+ style="fill:#d45500;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 235.65719,857.2309 c -5.15468,-1.08647 -10.13216,-2.60614 -11.06105,-3.37705 -1.4687,-1.21891 -1.59942,-3.62164 -1.0026,-18.42851 0.60898,-15.10833 2.82784,-34.89255 4.50742,-40.18992 0.5468,-1.72458 2.1597,-1.86153 18.79408,-1.59574 l 18.19595,0.29073 0.86603,3.19149 c 1.42964,5.26854 4.21348,40.89938 3.86495,49.46809 l -0.32454,7.97872 -6.91489,1.70857 c -11.71067,2.89354 -16.85673,3.0758 -26.92535,0.95362 l 0,0 z"
+ id="shipBody" />
+ <path
+ style="fill:#008000;fill-opacity:0.93984112;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 244.48826,894.22212 c -4.2024,-0.66031 -8.30588,-1.6713 -9.34259,-2.30176 -1.50562,-0.91562 -2.96927,-3.83924 -5.28678,-10.56029 -3.38846,-9.8269 -6.66033,-24.37913 -5.69774,-25.34172 0.34613,-0.34613 1.65904,0.0304 4.83607,1.387 l 4.36096,1.86212 8.04349,-0.30495 c 4.42393,-0.16772 9.30427,-0.48845 10.84522,-0.71273 1.54095,-0.22428 5.51724,-0.5933 8.83621,-0.82003 3.31896,-0.22673 6.77423,-0.53583 7.67837,-0.68688 l 1.64389,-0.27464 -0.27403,1.65891 c -1.72541,10.44502 -5.37775,23.19669 -9.194,32.09965 l -0.81901,1.91067 -5.12106,0.9443 c -5.68087,1.04752 -8.8862,1.39534 -10.509,1.14035 z"
+ id="shipBottom" />
+ <path
+ style="fill:#ff0000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 207.75862,910.1208 1.2931,-9.48276 3.44828,-6.46552 4.31034,-6.89655 5.17242,-6.03448 4.31034,-2.58621 1.72414,-1.2931 3.87931,12.06896 0.43104,1.72414"
+ id="shipLtWing" />
+ <path
+ style="fill:#ff0000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 262.06896,892.44839 3.01724,-12.5 9.05172,5.17241 5.17242,6.46552 2.15517,4.74138 3.44827,8.18965 2.58621,10.34483 -8.18965,-9.91379 -6.03449,-5.17242 -4.74138,-3.44827 -6.46551,-3.87931 z"
+ id="shipRtWing" />
+ <g
+ id="shipCone">
+ <g
+ id="g3822">
+ <path
+ style="fill:#ffff00;fill-opacity:0.93984112;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 238.05674,793.18103 c -6.10246,-0.52204 -8.42268,-0.87219 -8.56122,-1.29204 -0.10453,-0.31675 0.30123,-1.48054 0.90169,-2.5862 0.60047,-1.10566 1.46952,-3.46503 1.93123,-5.24305 1.03163,-3.97271 6.17659,-18.26477 6.64632,-18.46264 0.1876,-0.079 0.34109,-0.38714 0.34109,-0.68471 0,-1.96184 7.19772,-16.19748 8.18965,-16.19748 0.56862,0 3.86104,5.678 5.49864,9.48276 2.06526,4.7984 7.19953,18.13611 8.29619,21.55173 4.18191,13.02476 4.23136,13.3315 2.15345,13.35671 -1.19212,0.0144 -10.09252,0.40818 -13.57759,0.60062 -1.89655,0.10473 -7.2153,-0.13184 -11.81945,-0.5257 l 0,0 z"
+ id="path3814" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 247.84482,749.34494 c -0.43103,-9.91379 -0.43103,-9.91379 -0.43103,-9.91379 l 0,0.43103"
+ id="path3820" />
+ </g>
+ </g>
+ <path
+ style="fill:#800080;fill-opacity:0.93984112;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 235.50249,906.17356 c 0,-1.06703 4.59976,-12.40994 5.03247,-12.40994 0.74921,0 3.52178,11.5796 2.85187,11.91094 -1.14852,0.56809 -7.88434,0.9944 -7.88434,0.499 z"
+ id="shipLtJet" />
+ <path
+ style="fill:#800080;fill-opacity:0.93984112;stroke:#000000;stroke-width:2.81490302;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 252.67238,906.11389 c -1.35952,-0.18394 -1.44042,-0.348 -1.11133,-2.25333 0.1952,-1.1302 0.82906,-3.53453 1.40857,-5.34296 l 1.05363,-3.28807 1.72233,4.60998 c 0.9473,2.53547 1.8799,5.05611 2.07247,5.60139 0.31242,0.88465 0.13311,0.98497 -1.66464,0.93143 -1.10813,-0.033 -2.67459,-0.1493 -3.48103,-0.25844 z"
+ id="shipRtJet" />
+ </g>
+ <g
+ transform="translate(-171.5,206.5)"
+ id="shipFire1">
+ <path
+ id="path3024"
+ d="m 213.07446,821.01373 0,-15 20,0 20,0 0,15 0,15 -20,0 -20,0 0,-15 z"
+ style="fill:#fefefd" />
+ <path
+ id="path3022"
+ d="m 242.07446,835.28173 c -3.61556,-0.66474 -4.70548,-1.87312 -5.45964,-6.05304 -2.27423,-12.60493 -1.42549,-20.52872 2.31719,-21.6331 1.32002,-0.38951 6.93368,-0.22942 11.39245,0.3249 0.4125,0.0513 0.75,1.64168 0.75,3.53422 0,1.89254 0.45,3.7191 1,4.05902 2.54527,1.57306 0.0351,18.5 -2.74348,18.5 -0.69109,0 -1.25652,0.45 -1.25652,1 0,1.01912 -1.54039,1.08792 -6,0.268 z m -21.75,-0.93028 c -0.6875,-0.27741 -1.25689,-1.25439 -1.26531,-2.17105 -0.0124,-1.35224 -0.18204,-1.40336 -0.89908,-0.27095 -0.50392,0.79583 -1.59909,1.12122 -2.54807,0.75706 -1.94705,-0.74715 -1.12949,-2.65278 1.13811,-2.65278 1.15603,0 1.37715,-0.5801 0.85766,-2.25 -2.33632,-7.51012 -1.67256,-19.75 1.07102,-19.75 0.83254,0 1.23559,-0.45 0.89567,-1 -0.87696,-1.41896 2.8546,-1.2454 4.3,0.2 0.93333,0.93333 1.46667,0.93333 2.4,0 1.58906,-1.58906 5.28176,-1.52936 6.6401,0.10734 1.42636,1.71865 1.17235,25.91644 -0.28266,26.92735 -1.17512,0.81645 -10.34907,0.89325 -12.30744,0.10303 z"
+ style="fill:#fdfbf4" />
+ <path
+ id="path3020"
+ d="m 243.63248,835.10761 c -0.30801,-0.49837 -1.3785,-0.69208 -2.37887,-0.43048 -2.77871,0.72665 -3.72489,-1.36607 -5.04726,-11.1634 -2.04821,-15.17496 -0.0992,-17.37091 13.86811,-15.625 0.55,0.0688 1,1.925 1,4.125 0,2.2 0.45,4 1,4 0.55445,0 1,2.64699 1,5.94098 0,3.26754 -0.45,6.2191 -1,6.55902 -0.55,0.33992 -1,1.39147 -1,2.33678 0,3.26484 -5.95123,6.66918 -7.44198,4.2571 z m -22.74632,-1.31683 c -4.37516,-3.39748 -6.23457,-22.53224 -2.45791,-25.2938 0.88832,-0.64955 1.32212,-1.47401 0.964,-1.83213 -0.35812,-0.35811 0.23388,-0.65112 1.31554,-0.65112 1.08167,0 2.41295,0.44628 2.95841,0.99174 0.65566,0.65566 2.0518,0.59162 4.11984,-0.18897 5.54377,-2.09255 6.17944,-0.58472 6.01373,14.26467 -0.11976,10.73113 -0.40636,12.99629 -1.68481,13.31597 -3.61444,0.9038 -9.7078,0.57475 -11.2288,-0.60636 z"
+ style="fill:#fef4f3" />
+ <path
+ id="path3018"
+ d="m 244.07446,834.94634 c 0,-0.58706 -0.83647,-0.8019 -1.85882,-0.47742 -2.45124,0.778 -4.46558,-1.75044 -4.35975,-5.47246 0.0461,-1.62139 -0.33587,-3.20735 -0.84881,-3.52437 -0.51294,-0.31702 -0.93262,-3.69984 -0.93262,-7.51738 0,-5.70987 0.37113,-7.31211 2.09245,-9.03343 1.38572,-1.38572 2.82118,-1.89697 4.25,-1.51366 1.18665,0.31834 3.62005,0.58495 5.40755,0.59246 3.11458,0.0131 3.25,0.17786 3.25,3.95463 0,2.16754 0.45,4.2191 1,4.55902 2.55736,1.58053 0.26642,14.37644 -3.19334,17.8362 -1.86559,1.86559 -4.80666,2.23052 -4.80666,0.59641 z m -23.25021,-1.32568 c -1.57289,-1.57289 -3.54882,-8.77472 -3.87044,-14.10693 -0.37645,-6.24113 0.18337,-9.26629 2.13011,-11.51091 1.80021,-2.07566 2.26525,-2.18003 4.46591,-1.00227 1.95295,1.04519 2.76106,1.06185 3.94255,0.0813 1.957,-1.62417 5.3134,-0.49003 6.12591,2.06997 0.35537,1.11968 0.33438,3.68417 -0.0466,5.69885 -0.38103,2.01468 -0.67234,7.15056 -0.64735,11.41306 0.025,4.2625 -0.0435,7.77018 -0.1522,7.79485 -0.1087,0.0247 -2.49663,0.28103 -5.30652,0.56969 -3.79428,0.38978 -5.50321,0.13051 -6.64132,-1.00761 z"
+ style="fill:#fdf4eb" />
+ <path
+ id="path3016"
+ d="m 244.07446,834.94634 c 0,-0.58706 -0.83647,-0.8019 -1.85882,-0.47742 -3.38388,1.074 -4.23225,-1.44367 -5.76062,-17.09567 -0.53162,-5.44427 -0.34995,-6.39014 1.60237,-8.34245 1.47838,-1.47838 2.91097,-2.01178 4.35952,-1.62318 1.18665,0.31834 3.62005,0.58495 5.40755,0.59246 3.11458,0.0131 3.25,0.17786 3.25,3.95463 0,2.16754 0.45,4.2191 1,4.55902 0.55,0.33992 1,2.81492 1,5.5 0,2.68508 -0.45,5.16008 -1,5.5 -0.55,0.33992 -1.01497,1.37898 -1.03327,2.30902 -0.0711,3.61539 -6.96673,8.68668 -6.96673,5.12359 z m -22.64106,-0.66363 c -1.91418,-1.29 -4.35894,-11.2719 -4.35894,-17.79747 0,-4.73983 0.46465,-6.70124 2.00946,-8.48242 1.77348,-2.04484 2.28725,-2.16825 4.375,-1.05093 1.76257,0.94331 2.88873,0.986 4.4181,0.16751 1.1289,-0.60417 2.72536,-0.84032 3.54768,-0.52477 1.72841,0.66326 2.91023,3.18863 2.10325,4.49435 -0.30414,0.49212 -0.57989,5.85151 -0.61276,11.90975 -0.0329,6.05825 -0.12298,11.03518 -0.20025,11.05985 -1.91464,0.61129 -10.45528,0.78097 -11.28154,0.22413 z"
+ style="fill:#fde9e8" />
+ <path
+ id="path3014"
+ d="m 244.57446,835.01373 c -0.33992,-0.55 -1.47564,-1 -2.52383,-1 -1.97232,0 -4.2255,-3.08944 -3.83717,-5.26131 0.12181,-0.68128 -0.36745,-3.1064 -1.08723,-5.38916 -1.49453,-4.73979 -0.72255,-12.54794 1.41606,-14.32284 0.76462,-0.63457 3.72517,-1.00206 6.70099,-0.83176 5.29729,0.30313 5.33322,0.32732 5.65248,3.80507 0.17671,1.925 0.73921,3.9275 1.25,4.45 1.2472,1.2758 1.18916,10.271 -0.0713,11.05 -0.55,0.33992 -1.01497,1.37898 -1.03327,2.30902 -0.0389,1.97564 -3.31937,6.19098 -4.81801,6.19098 -0.56688,0 -1.3088,-0.45 -1.64872,-1 z m -22.84924,-1.35207 c -1.97934,-1.56449 -4.65076,-11.41412 -4.65076,-17.14754 0,-6.75939 3.72786,-12.41603 6.42573,-9.75039 0.41749,0.4125 2.62999,0.75 4.91667,0.75 l 4.1576,0 0,12.33739 c 0,6.78557 -0.225,12.68061 -0.5,13.10011 -0.8974,1.36892 -8.82744,1.91328 -10.34924,0.71043 z"
+ style="fill:#fce7d8" />
+ <path
+ id="path3012"
+ d="m 244.57446,835.01373 c -0.33992,-0.55 -1.46492,-1 -2.5,-1 -2.41107,0 -3.39583,-1.62821 -3.62887,-6 -0.10262,-1.925 -0.64182,-5.23675 -1.19822,-7.35943 -1.16711,-4.45251 -0.49978,-10.1244 1.37416,-11.67963 0.70982,-0.5891 3.68961,-0.93381 6.62175,-0.76601 5.29729,0.30313 5.33322,0.32732 5.65248,3.80507 0.17671,1.925 0.73921,3.9275 1.25,4.45 1.62476,1.66202 0.89746,9.87212 -1.15604,13.05 -1.06621,1.65 -2.2108,3.7875 -2.54354,4.75 -0.66038,1.91026 -2.88796,2.34176 -3.87172,0.75 z m -22.70147,-1.09287 c -2.10735,-1.17933 -5.26736,-16.59451 -4.37589,-21.34647 0.37824,-2.01617 1.33529,-3.91428 2.12679,-4.218 0.7915,-0.30373 1.14285,-1.03155 0.78078,-1.61738 -0.44012,-0.71214 -0.0239,-0.78737 1.25575,-0.22698 1.05272,0.46099 3.93904,0.87497 6.41404,0.91994 l 4.5,0.0818 0,12.33679 c 0,6.78523 -0.225,12.68028 -0.5,13.1001 -0.78115,1.19253 -8.49355,1.92604 -10.20147,0.97024 z"
+ style="fill:#fcd8d7" />
+ <path
+ id="path3010"
+ d="m 242.57446,833.95903 c -3.20603,-2.03958 -4.16764,-5.04031 -5.16057,-16.10371 -0.72246,-8.04973 0.49024,-9.84159 6.66057,-9.84159 5.32878,0 7,1.49636 7,6.26759 0,1.31949 0.3116,2.71067 0.69244,3.09151 2.0309,2.03091 0.53343,11.77013 -2.17427,14.1409 -0.62816,0.55 -1.4376,1.7875 -1.79876,2.75 -0.80647,2.1493 -1.41806,2.11359 -5.21941,-0.3047 z m -21.40349,-1.32901 c -2.16359,-2.60697 -4.21239,-16.47222 -3.06414,-20.73651 0.5746,-2.13388 1.50393,-3.87978 2.06519,-3.87978 0.56126,0 0.74236,-0.45 0.40244,-1 -0.33992,-0.55 -0.16803,-1 0.38197,-1 0.55,0 1.30476,0.49312 1.67725,1.09581 0.42872,0.69369 2.27301,0.85652 5.02583,0.44371 4.00954,-0.60127 4.39578,-0.4641 4.95383,1.75938 0.33289,1.32633 0.17976,5.51416 -0.34028,9.3063 -0.52004,3.79214 -0.71908,8.40715 -0.4423,10.25559 0.33321,2.22535 0.0371,3.65603 -0.87654,4.23468 -2.15612,1.36563 -8.51049,1.05439 -9.78325,-0.47918 z"
+ style="fill:#fcd5ca" />
+ <path
+ id="path3008"
+ d="m 243.68265,834.51799 c -1.0405,-0.78767 -2.33516,-1.57991 -2.87702,-1.76054 -0.54187,-0.18062 -1.41387,-2.55935 -1.93778,-5.28606 -3.0569,-15.90966 -1.92574,-19.54051 5.94911,-19.09566 4.63102,0.2616 4.78408,0.37335 5.7575,4.20337 0.55,2.16405 1.25034,4.38463 1.5563,4.93463 0.93611,1.68273 1.17286,7.75954 0.28091,7.21035 -0.46047,-0.28352 -0.94017,0.89999 -1.06601,2.63002 -0.12585,1.73002 -0.71743,3.30837 -1.31463,3.50744 -0.5972,0.19907 -1.4956,1.43975 -1.99644,2.75706 -1.04556,2.75002 -1.7225,2.88992 -4.35194,0.89939 z m -23.21506,-4.10579 c -0.82765,-1.98085 -1.76416,-7.27639 -2.08112,-11.76788 -0.69109,-9.79271 0.0645,-10.82627 8.1771,-11.18559 6.36395,-0.28187 6.33231,-0.34421 5.34251,10.52779 -0.37691,4.13996 -0.4504,8.95097 -0.16332,10.69111 0.6047,3.66532 -1.47859,5.3361 -6.65359,5.3361 -2.63353,0 -3.35007,-0.55839 -4.62158,-3.60153 z"
+ style="fill:#fcc9c7" />
+ <path
+ id="path3006"
+ d="m 242.82446,833.6902 c -1.61209,-1.31992 -2.76466,-3.27052 -2.78544,-4.71403 -0.0195,-1.35434 -0.67854,-3.58744 -1.46456,-4.96244 -1.78022,-3.11416 -1.88229,-9.68857 -0.20184,-13 1.05742,-2.08371 1.98633,-2.5 5.57849,-2.5 2.3704,0 4.64398,0.225 5.0524,0.5 0.77148,0.51946 4.08252,12.93329 4.05564,15.20552 -0.0109,0.92215 -0.29413,0.86304 -0.98469,-0.20552 -0.72513,-1.12206 -0.97323,-0.59421 -0.98469,2.09501 -0.01,2.31035 -0.73,4.2418 -2.01531,5.40499 -1.1,0.99549 -2,2.41523 -2,3.15499 0,1.87693 -1.06079,1.6327 -4.25,-0.97852 z m -21.53193,-1.30802 c -1.46348,-2.79289 -3.21807,-11.89557 -3.21807,-16.69516 0,-6.48241 1.72588,-8.19989 8.13495,-8.09535 l 5.36505,0.0875 -0.22431,12.30825 c -0.12337,6.76954 -0.4237,12.50765 -0.66741,12.75135 -0.24371,0.24371 -2.23591,0.68357 -4.42712,0.97748 -3.21272,0.43091 -4.17356,0.17264 -4.96309,-1.33408 z"
+ style="fill:#fcc5ba" />
+ <path
+ id="path3004"
+ d="m 242.72748,833.17345 c -1.45916,-1.52303 -2.65302,-3.77287 -2.65302,-4.99962 0,-1.22676 -0.71048,-3.3148 -1.57885,-4.6401 -1.21102,-1.84824 -1.41802,-3.69689 -0.88852,-7.93489 0.8518,-6.81759 1.87668,-7.75237 7.45543,-6.80001 4.33601,0.74022 4.33744,0.74189 6.17057,7.22764 2.11406,7.4797 2.20996,8.3331 0.84137,7.48726 -0.5944,-0.36736 -1,0.81122 -1,2.9058 0,2.50038 -0.58088,3.83471 -2,4.5942 -1.1,0.5887 -2,1.70298 -2,2.47617 0,2.59556 -1.67384,2.47371 -4.34698,-0.31645 z m -21.75005,-1.90972 c -0.57613,-1.5125 -1.56141,-6.27033 -2.18949,-10.57295 -0.9585,-6.56609 -0.90464,-8.24579 0.33523,-10.45476 1.29461,-2.30651 2.12301,-2.6374 6.70205,-2.67705 3.65715,-0.0317 5.39105,0.38694 5.77872,1.39515 0.30463,0.79221 0.24376,6.34107 -0.13525,12.3308 -0.65213,10.306 -0.81885,10.93975 -3.10677,11.80962 -4.21264,1.60164 -6.27144,1.09121 -7.38449,-1.83081 z"
+ style="fill:#fcc7ab" />
+ <path
+ id="path3002"
+ d="m 242.72748,833.17345 c -1.45916,-1.52303 -2.65302,-3.78662 -2.65302,-5.03018 0,-1.24356 -0.50847,-3.21112 -1.12994,-4.37234 -1.56807,-2.92996 -1.34949,-12.70635 0.32145,-14.37728 0.98111,-0.98111 2.56078,-1.1472 5.74345,-0.60388 l 4.39011,0.74945 1.83356,6.48725 c 2.11406,7.4797 2.20996,8.3331 0.84137,7.48726 -0.5944,-0.36736 -1,0.81122 -1,2.9058 0,2.50038 -0.58088,3.83471 -2,4.5942 -1.1,0.5887 -2,1.70298 -2,2.47617 0,2.59556 -1.67384,2.47371 -4.34698,-0.31645 z m -21.16934,-0.40972 c -1.00952,-2.78225 -3.48368,-16.06654 -3.48368,-18.70459 0,-1.55311 0.81514,-3.8305 1.81143,-5.06086 1.59417,-1.96872 2.06504,-2.07864 3.92591,-0.91651 1.63188,1.01913 2.68278,1.06157 4.6045,0.18598 3.50792,-1.59832 3.87749,-0.0223 3.05239,13.01717 -0.65213,10.306 -0.81885,10.93975 -3.10677,11.80962 -3.38037,1.28521 -6.26837,1.14479 -6.80378,-0.33081 z"
+ style="fill:#fcbab6" />
+ <path
+ id="path3000"
+ d="m 242.73813,833.03845 c -4.45265,-4.50136 -6.26388,-22.81295 -2.40301,-24.2945 0.70285,-0.26971 3.01297,-0.20685 5.1336,0.1397 3.80086,0.62112 3.88065,0.72606 5.61127,7.38008 1.5237,5.8584 1.55892,6.75 0.26662,6.75 -1.07585,0 -1.32041,0.67158 -0.88145,2.42054 0.75665,3.01474 -0.16163,5.57946 -1.99769,5.57946 -0.76616,0 -1.39301,0.9 -1.39301,2 0,2.47359 -1.90323,2.48443 -4.33633,0.0247 z m -20.53807,-0.37338 c -1.73818,-2.09438 -4.37739,-16.49565 -3.69229,-20.14755 0.79299,-4.22701 2.99091,-6.22653 5.00602,-4.55414 0.79163,0.657 2.92913,1.0496 4.75,0.87244 l 3.31067,-0.32209 -0.34477,11 c -0.20547,6.55563 -0.81152,11.45488 -1.5,12.12585 -1.93738,1.8881 -6.31852,2.48479 -7.52963,1.02549 z"
+ style="fill:#fbb5a7" />
+ <path
+ id="path2998"
+ d="m 242.74941,832.85535 c -1.00378,-1.09545 -2.07693,-3.54387 -2.38478,-5.44095 -0.30786,-1.89708 -0.94908,-3.68987 -1.42495,-3.98397 -0.98296,-0.6075 -1.18061,-10.43123 -0.25823,-12.83491 0.43906,-1.14417 1.9607,-1.58179 5.5,-1.58179 2.69115,0 4.89301,0.11393 4.89301,0.25318 0,0.13925 0.87979,3.32964 1.95508,7.08976 1.63533,5.71845 1.7122,6.74336 0.47002,6.26669 -1.16731,-0.44794 -1.43336,0.19801 -1.24339,3.01886 0.1645,2.4426 -0.30498,3.98848 -1.47001,4.84037 -0.94143,0.68839 -1.7117,1.98952 -1.7117,2.89138 0,2.18799 -2.07266,1.93946 -4.32505,-0.51862 z m -20.55781,-0.20048 c -1.4948,-1.80112 -3.11714,-10.71274 -3.11714,-17.12264 0,-3.84785 0.49654,-5.65789 1.90072,-6.92866 1.33134,-1.20484 2.1105,-1.38071 2.60099,-0.58707 0.38515,0.62319 2.34233,0.99695 4.34928,0.83059 l 3.64901,-0.30248 -0.34477,10.98456 c -0.20539,6.54387 -0.81179,11.4397 -1.5,12.11041 -1.94466,1.8952 -6.31888,2.48436 -7.53809,1.01529 z"
+ style="fill:#fac58e" />
+ <path
+ id="path2996"
+ d="m 242.83096,832.93689 c -2.94316,-3.22449 -5.60815,-16.3938 -4.34,-21.4465 0.5574,-2.22086 1.13605,-2.47666 5.60255,-2.47666 2.73952,0 4.98095,0.11393 4.98095,0.25318 0,0.13925 0.87979,3.32964 1.95508,7.08976 1.63533,5.71845 1.7122,6.74336 0.47002,6.26669 -1.16731,-0.44794 -1.43336,0.19801 -1.24339,3.01886 0.1645,2.4426 -0.30498,3.98848 -1.47001,4.84037 -0.94143,0.68839 -1.7117,1.98952 -1.7117,2.89138 0,2.1614 -2.06598,1.94861 -4.2435,-0.43708 z m -20.63936,-0.28202 c -1.47885,-1.7819 -3.11714,-10.68981 -3.11714,-16.94889 0,-6.60802 1.99523,-9.09493 5.73865,-7.15281 1.76179,0.91402 3.1716,1.04377 4.37036,0.40222 1.04167,-0.55749 1.99888,-0.57611 2.32696,-0.0453 0.95894,1.55161 -0.68277,22.06632 -1.83817,22.9696 -2.18264,1.70635 -6.3495,2.13812 -7.48066,0.77515 z"
+ style="fill:#fbaaa7" />
+ <path
+ id="path2994"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.0515,-6.01599 1.33352,-7.68426 6.37947,-7.68426 l 4.34174,0 1.57906,6.25 c 0.93854,3.71477 1.19128,6.38521 0.62307,6.58333 -0.52579,0.18334 -0.95599,2.08 -0.95599,4.21482 0,2.90633 -0.52195,4.16082 -2.07756,4.99336 -1.18986,0.63679 -1.84419,1.72003 -1.53138,2.53518 0.75202,1.95974 -0.51507,1.68385 -2.78464,-0.60632 z m -22.50743,-2.65246 c -0.67213,-1.47516 -1.48641,-6.42813 -1.80952,-11.00662 -0.50391,-7.14044 -0.33132,-8.60756 1.21332,-10.31438 1.398,-1.54476 2.11011,-1.73314 3.18364,-0.84218 0.76057,0.63121 2.7832,1.10784 4.49474,1.05918 l 3.1119,-0.0885 -0.67703,11.14712 c -0.71175,11.71885 -1.14547,12.68517 -5.70553,12.71214 -1.84671,0.0109 -2.94001,-0.75403 -3.81152,-2.66678 z"
+ style="fill:#fbb49a" />
+ <path
+ id="path2992"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.052,-6.07612 1.23838,-7.55975 6.40123,-7.35994 l 4.44502,0.17203 1.51654,6.00183 c 0.90536,3.58303 1.13127,6.13616 0.56055,6.33515 -0.52579,0.18334 -0.95599,1.98759 -0.95599,4.00946 0,2.64232 -0.58597,4.04206 -2.08368,4.9774 -1.18202,0.73818 -1.84469,1.92409 -1.53139,2.74055 0.75759,1.97424 -0.50224,1.70656 -2.77851,-0.59037 z m -22.4942,-3.07829 c -0.59588,-1.70936 -1.38003,-6.66446 -1.74254,-11.01134 -0.56917,-6.82476 -0.41058,-8.17807 1.16197,-9.91572 1.22799,-1.3569 2.04728,-1.64633 2.51555,-0.88865 0.38194,0.61799 2.39249,1.12363 4.46789,1.12363 l 3.77345,0 -0.67477,11.10983 c -0.71119,11.70969 -1.1381,12.64814 -5.76595,12.67486 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z"
+ style="fill:#facb7b" />
+ <path
+ id="path2990"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.052,-6.07612 1.23838,-7.55975 6.40123,-7.35994 l 4.44502,0.17203 1.51654,6.00183 c 0.90536,3.58303 1.13127,6.13616 0.56055,6.33515 -0.52579,0.18334 -0.95599,1.98759 -0.95599,4.00946 0,2.64232 -0.58597,4.04206 -2.08368,4.9774 -1.18202,0.73818 -1.84469,1.92409 -1.53139,2.74055 0.75759,1.97424 -0.50224,1.70656 -2.77851,-0.59037 z m -22.4942,-3.07829 c -0.59588,-1.70936 -1.38003,-6.66446 -1.74254,-11.01134 -0.56214,-6.74048 -0.40015,-8.18959 1.10089,-9.84822 1.56882,-1.73353 1.92387,-1.78093 3.26843,-0.43637 1.04108,1.04107 2.4483,1.30199 4.54198,0.84214 l 3.03355,-0.66628 -0.68776,11.32382 c -0.72485,11.93451 -1.14074,12.86208 -5.77895,12.88886 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z"
+ style="fill:#fba597" />
+ <path
+ id="path2988"
+ d="m 221.18668,829.90581 c -1.93432,-5.5488 -2.47791,-18.15014 -0.87433,-20.26869 1.20398,-1.59064 1.76544,-1.69198 3.68442,-0.66497 1.24518,0.6664 3.41269,0.92333 4.81668,0.57095 l 2.55271,-0.64069 -0.71434,11.28897 c -0.75006,11.85366 -1.16479,12.78068 -5.72954,12.80704 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z m 22.21513,2.33139 c -3.55171,-2.25917 -6.28879,-19.66203 -3.5268,-22.42402 0.48123,-0.48123 2.70741,-0.58195 4.94705,-0.22382 3.78933,0.60594 4.14652,0.9468 5.14421,4.90901 0.58968,2.34182 1.38173,5.06461 1.76011,6.05065 0.44754,1.16629 0.30896,1.55857 -0.39657,1.12252 -1.47691,-0.91278 -2.08921,1.1788 -1.49071,5.09219 0.39191,2.56254 0.14544,3.25 -1.16518,3.25 -0.91423,0 -1.92125,0.675 -2.23783,1.5 -0.64031,1.66861 -1.30082,1.8261 -3.03428,0.72347 z"
+ style="fill:#fba78a" />
+ <path
+ id="path2986"
+ d="m 221.30293,829.26373 c -1.57713,-5.43533 -2.5527,-14.82202 -1.8369,-17.67401 0.57224,-2.27998 1.02934,-2.44619 6.23753,-2.26813 l 5.62004,0.19214 -0.69305,10.98331 c -0.72599,11.50515 -1.16409,12.47489 -5.6478,12.50138 -2.13974,0.0126 -2.78147,-0.63866 -3.67982,-3.73469 z m 22.11621,2.98418 c -0.63543,-0.40435 -2.10648,-3.55865 -3.26901,-7.00955 -2.51688,-7.47126 -1.88001,-15.78981 1.1975,-15.6413 7.7497,0.37399 7.4344,0.19825 8.59009,4.78792 0.60538,2.40418 1.41028,5.178 1.78866,6.16404 0.45172,1.17717 0.31093,1.55979 -0.40999,1.11423 -1.36162,-0.84153 -2.51515,2.47491 -1.64738,4.73629 0.41694,1.08651 -0.29,2.52937 -2.02884,4.14088 -3.03005,2.80815 -2.70074,2.67493 -4.22103,1.70749 z"
+ style="fill:#fb9996" />
+ <path
+ id="path2984"
+ d="m 221.62624,829.7919 c -1.76556,-4.22558 -2.98504,-17.79554 -1.75988,-19.58342 0.65198,-0.95144 2.30216,-1.1185 6.08784,-0.61632 l 5.19341,0.68894 -0.65991,10.11631 c -0.36295,5.56398 -0.94191,10.42198 -1.28657,10.79556 -0.34467,0.37358 -1.8665,0.98545 -3.38186,1.35971 -2.45245,0.6057 -2.91317,0.30235 -4.19303,-2.76078 z m 21.62804,1.93428 c -2.58899,-3.13045 -5.1869,-12.32814 -4.60314,-16.29701 0.86081,-5.85235 1.39869,-6.36256 6.04992,-5.7387 3.90839,0.52423 4.13392,0.74924 5.13477,5.12293 0.64943,2.83802 0.70299,5.47897 0.14109,6.95688 -0.49815,1.31023 -0.65676,3.37421 -0.35247,4.58662 0.70357,2.80324 -4.71508,7.37051 -6.37017,5.36928 z"
+ style="fill:#fa9787" />
+ <path
+ id="path2982"
+ d="m 222.27764,831.35152 c -0.52864,-1.01079 -1.5183,-5.81903 -2.19925,-10.68499 -1.52422,-10.89173 -0.88679,-12.00968 6.28694,-11.02641 l 4.70142,0.6444 -0.62383,10.11461 c -0.34312,5.56303 -0.90388,10.42026 -1.24615,10.79384 -0.34227,0.37358 -1.82284,0.97558 -3.29015,1.33778 -2.01233,0.49674 -2.90399,0.207 -3.62898,-1.17923 z m 20.13064,-1.08779 c -0.33188,-0.9625 -1.39356,-3.6085 -2.3593,-5.88 -1.89406,-4.45498 -1.65955,-12.55659 0.41327,-14.27687 0.62221,-0.51639 2.67297,-0.62358 4.55724,-0.23821 4.18109,0.85513 5.13433,3.53546 4.65376,13.08549 -0.25668,5.10092 -0.69352,6.63149 -1.96444,6.88291 -0.89889,0.17783 -1.63435,0.74033 -1.63435,1.25 0,1.65938 -3.04599,0.97533 -3.66618,-0.82332 z"
+ style="fill:#faa96f" />
+ <path
+ id="path2980"
+ d="m 222.27764,831.35152 c -0.52864,-1.01079 -1.51335,-5.78416 -2.18825,-10.6075 -1.41648,-10.12316 -0.61986,-12.39505 3.91087,-11.1534 1.41581,0.388 3.58864,0.64681 4.82851,0.57513 2.2392,-0.12946 2.25007,-0.0617 1.62231,10.10883 -0.3476,5.63153 -0.91204,10.54481 -1.25431,10.91839 -0.34227,0.37358 -1.82284,0.97558 -3.29015,1.33778 -2.01233,0.49674 -2.90399,0.207 -3.62898,-1.17923 z m 20.10725,-1.08779 c -0.34474,-0.9625 -1.38391,-3.775 -2.30926,-6.25 -2.75945,-7.3806 -0.64783,-16.8259 3.20502,-14.33609 0.7116,0.45985 2.15925,0.83609 3.21701,0.83609 2.55245,0 3.59591,4.08776 3.17559,12.44041 -0.25668,5.10092 -0.69352,6.63149 -1.96444,6.88291 -0.89889,0.17783 -1.63435,0.74033 -1.63435,1.25 0,1.6564 -3.04476,0.97696 -3.68957,-0.82332 z"
+ style="fill:#fa947a" />
+ <path
+ id="path2978"
+ d="m 222.66421,832.15894 c -0.34565,-0.55926 -1.25123,-5.2066 -2.01241,-10.32743 -1.61694,-10.87789 -0.9927,-13.23232 3.21267,-12.11721 1.49049,0.39522 3.72162,0.67194 4.95807,0.61492 2.22878,-0.10279 2.24271,-0.0166 1.62231,10.04042 -0.34418,5.57925 -0.90581,10.44975 -1.24808,10.82333 -1.17568,1.28323 -5.90434,1.98246 -6.53256,0.96597 z m 19.89554,-1.39521 c -2.76058,-7.63527 -3.48529,-10.70299 -3.48529,-14.75328 0,-4.50991 1.80223,-7.86115 3.3794,-6.28399 0.38246,0.38246 1.88374,0.71606 3.33618,0.74133 2.06745,0.036 2.81953,0.69727 3.46406,3.04594 1.25136,4.56001 -0.12178,14.69032 -2.27042,16.75 -2.14711,2.05821 -3.79329,2.24426 -4.42393,0.5 z"
+ style="fill:#fa8884" />
+ <path
+ id="path2976"
+ d="m 222.50927,830.90824 c -0.37578,-0.60801 -1.25786,-4.99551 -1.96017,-9.75 -1.47709,-9.99943 -0.80155,-12.51565 3.09742,-11.53707 1.37063,0.34401 3.26513,0.68556 4.21,0.75901 0.94487,0.0734 1.99019,0.58355 2.32295,1.13355 0.69333,1.14599 -0.70968,18.05133 -1.62042,19.52494 -0.82187,1.32981 -5.20572,1.2353 -6.04978,-0.13043 z m 18.63704,-4.43202 c -3.37032,-9.00798 -2.33409,-18.74357 1.7617,-16.55157 0.96226,0.51498 2.58779,0.85821 3.61229,0.76271 2.58412,-0.24087 3.68815,4.3302 2.91039,12.05008 -0.50552,5.01758 -1.07846,6.51949 -2.95645,7.75 -1.28118,0.83946 -2.53791,1.52629 -2.79275,1.52629 -0.25483,0 -1.39566,-2.49188 -2.53518,-5.53751 z"
+ style="fill:#f9af50" />
+ <path
+ id="path2974"
+ d="m 222.14477,829.69866 c -0.4841,-1.27328 -1.18483,-4.98578 -1.55716,-8.25 -0.37234,-3.26421 -0.86723,-6.63354 -1.09975,-7.48739 -0.23253,-0.85385 0.17932,-2.37587 0.91522,-3.38227 1.27959,-1.74995 1.45462,-1.75341 4.00969,-0.0793 2.04558,1.34032 2.99469,1.48251 4.04991,0.60676 1.0452,-0.86744 1.4888,-0.83562 1.83589,0.13171 0.56835,1.58395 -0.91478,18.466 -1.73952,19.80046 -1.20642,1.95202 -5.504,1.05422 -6.41428,-1.34001 z m 19.00154,-3.22244 c -3.37032,-9.00798 -2.33409,-18.74357 1.7617,-16.55157 0.96226,0.51498 2.58779,0.85821 3.61229,0.76271 2.58412,-0.24087 3.68815,4.3302 2.91039,12.05008 -0.50552,5.01758 -1.07846,6.51949 -2.95645,7.75 -1.28118,0.83946 -2.53791,1.52629 -2.79275,1.52629 -0.25483,0 -1.39566,-2.49188 -2.53518,-5.53751 z"
+ style="fill:#fa8678" />
+ <path
+ id="path2972"
+ d="m 222.13455,829.67178 c -0.51748,-1.36109 -1.24958,-6.27925 -1.62688,-10.92925 -0.75781,-9.33961 -0.0511,-10.83501 3.89764,-8.24767 1.31304,0.86033 3.12575,1.28089 4.02824,0.93457 1.41077,-0.54137 1.63051,0.19177 1.56679,5.22731 -0.0408,3.22135 -0.37827,7.88199 -0.75,10.35699 -0.59575,3.9665 -1.00185,4.53751 -3.4254,4.81638 -2.15645,0.24813 -2.95245,-0.21741 -3.69039,-2.15833 z m 21.21124,1.06386 c -2.61671,-3.44941 -4.3414,-10.713 -3.69705,-15.5703 l 0.66804,-5.03598 3.89064,0.15515 c 3.48771,0.13908 3.98352,0.49155 4.78753,3.40341 0.49328,1.78655 0.66045,5.85322 0.37148,9.03704 -0.40707,4.485 -1.03985,6.17659 -2.80956,7.51068 -1.75742,1.32483 -2.4979,1.44013 -3.21108,0.5 z"
+ style="fill:#fa7974" />
+ <path
+ id="path2970"
+ d="m 223.91904,831.34262 c -2.03067,-0.53865 -2.56772,-2.56289 -3.43265,-12.93826 -0.749,-8.98473 -0.007,-10.48197 3.91892,-7.9095 1.31304,0.86033 3.09178,1.29392 3.95275,0.96354 1.37808,-0.52882 1.49697,0.57546 0.99348,9.22731 -0.31462,5.40631 -1.068,10.15856 -1.67451,10.56271 -1.16693,0.77757 -1.18043,0.77791 -3.75799,0.0942 z m 17.21699,-5.67718 c -1.71683,-4.23001 -2.02942,-6.41337 -1.49498,-10.44218 l 0.67573,-5.0939 3.89064,0.15515 c 3.50313,0.13969 3.98164,0.48472 4.80431,3.46421 1.26724,4.58956 0.12422,14.46961 -1.84909,15.98321 -2.76378,2.11992 -3.79932,1.42118 -6.02661,-4.06649 z"
+ style="fill:#f9836a" />
+ <path
+ id="path2968"
+ d="m 223.64739,830.4438 c -1.85627,-1.85626 -2.25977,-3.57781 -3.06787,-13.08917 -0.68033,-8.00745 0.0825,-9.31245 3.95897,-6.77251 1.38629,0.90833 3.16123,1.40565 3.94431,1.10516 1.19438,-0.45833 1.33299,1.01428 0.86029,9.14005 -0.63404,10.89904 -2.03975,13.27242 -5.6957,9.61647 z m 17.53808,-4.86292 c -1.53151,-4.09332 -1.88195,-6.70559 -1.42132,-10.59489 0.60375,-5.09769 0.64846,-5.15463 3.58584,-4.56715 1.63596,0.32719 3.31348,0.59489 3.72783,0.59489 1.25296,0 2.66967,7.32604 1.9338,10 -0.3784,1.375 -0.4645,3.5355 -0.19134,4.80111 0.49734,2.30428 -1.8953,5.09883 -4.42397,5.16709 -0.64798,0.0175 -2.09286,-2.41298 -3.21084,-5.40105 z"
+ style="fill:#f97967" />
+ <path
+ id="path2966"
+ d="m 223.11077,829.55749 c -1.55452,-1.8731 -3.30507,-17.675 -2.09239,-18.88768 0.47651,-0.47651 2.47171,-0.27364 4.49143,0.4567 l 3.63405,1.31409 -0.2847,9.03657 c -0.26128,8.29308 -0.45645,9.0611 -2.37221,9.33482 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.08259,-4.70911 -2.34897,-6.354 -1.66736,-10.29583 0.79337,-4.58811 0.88601,-4.68516 4.21056,-4.41078 1.86963,0.15431 3.64809,0.52919 3.95212,0.83307 0.30403,0.30389 0.58197,4.11797 0.61765,8.47574 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f88c4e" />
+ <path
+ id="path2964"
+ d="m 223.11077,829.55749 c -1.62629,-1.95957 -3.30118,-17.67889 -2.02017,-18.9599 0.57281,-0.57281 1.89956,-0.48767 3.45673,0.22183 1.81036,0.82485 2.53147,1.9375 2.54244,3.92287 0.0121,2.18024 0.22786,2.45146 1.0117,1.27144 0.69439,-1.04537 0.91707,0.92469 0.73469,6.5 -0.23718,7.25032 -0.45732,8.02795 -2.34921,8.29826 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.07784,-4.69837 -2.34887,-6.36299 -1.67637,-10.29583 0.79068,-4.62392 0.85194,-4.68641 4.26334,-4.34864 1.90362,0.18848 3.68613,0.56336 3.96113,0.83307 0.275,0.26971 0.52919,4.05583 0.56487,8.4136 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f8a534" />
+ <path
+ id="path2962"
+ d="m 223.11077,829.55749 c -1.31835,-1.58852 -3.34677,-17.23242 -2.42729,-18.72016 1.14947,-1.85987 3.52557,-0.60922 5.09488,2.68167 1.16822,2.44977 1.91966,3.12729 2.49552,2.25 0.45778,-0.69739 0.70767,2.30017 0.56228,6.74473 -0.23718,7.25032 -0.45732,8.02795 -2.34921,8.29826 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.07784,-4.69837 -2.34887,-6.36299 -1.67637,-10.29583 0.79068,-4.62392 0.85194,-4.68641 4.26334,-4.34864 1.90362,0.18848 3.68613,0.56336 3.96113,0.83307 0.275,0.26971 0.52919,4.05583 0.56487,8.4136 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f97659" />
+ <path
+ id="path2960"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -0.56031,-0.68049 -0.75752,-1.91799 -0.43825,-2.75 1.07196,-2.79347 3.45238,-1.54832 6.10157,3.1916 2.12264,3.79781 2.57269,5.77112 2.3355,10.24028 -0.23013,4.33611 -0.6731,5.60814 -2.04381,5.869 -1.04668,0.19919 -1.75,-0.27931 -1.75,-1.1906 z m 16.96387,-2.97179 c -2.15555,-4.87296 -2.22449,-5.36902 -1.68889,-12.15122 0.29872,-3.78258 0.47649,-3.98174 3.27046,-3.66399 4.42198,0.5029 4.9771,1.61488 4.71073,9.43636 -0.19008,5.58139 -0.67966,7.59556 -2.22083,9.13674 -1.96934,1.96933 -1.98513,1.95864 -4.07147,-2.75789 z"
+ style="fill:#f89936" />
+ <path
+ id="path2958"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -0.56031,-0.68049 -0.75752,-1.91799 -0.43825,-2.75 0.93035,-2.42444 3.58582,-1.74814 4.85806,1.23727 0.64456,1.5125 1.78388,3.48691 2.53182,4.38759 2.0861,2.51209 1.30446,13.2381 -0.99662,13.67602 -1.04668,0.19919 -1.75,-0.27931 -1.75,-1.1906 z m 16.9435,-3.01782 c -2.14558,-4.85044 -2.22191,-5.41701 -1.631,-12.10519 0.25271,-2.86028 0.75717,-3.88974 1.77045,-3.61301 0.77938,0.21284 2.27824,0.47228 3.33081,0.57652 2.70391,0.2678 3.64683,3.66342 2.92774,10.5433 -0.40811,3.9046 -1.25402,6.50903 -2.47214,7.61142 -1.76446,1.59681 -1.94952,1.45478 -3.92586,-3.01304 z m 4.0565,-8.54617 c 0,-1.06754 -0.45,-2.2191 -1,-2.55902 -0.56716,-0.35052 -1,0.48962 -1,1.94098 0,1.40746 0.45,2.55902 1,2.55902 0.55,0 1,-0.87344 1,-1.94098 z"
+ style="fill:#f88838" />
+ <path
+ id="path2956"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -1.31597,-1.59824 -0.29183,-4.26273 1.63844,-4.26273 1.76019,0 3.56657,3.00556 3.56657,5.93426 0,1.13616 0.5625,1.95324 1.25,1.81574 0.89722,-0.17944 1.25,1.58059 1.25,6.23631 0,5.38237 -0.29784,6.54366 -1.75,6.82332 -1.04842,0.20191 -1.75,-0.27381 -1.75,-1.18662 z m 16.9435,-3.01782 c -1.14075,-2.57888 -2.05392,-5.45754 -2.02925,-6.39703 0.0442,-1.68363 0.77833,-9.28228 0.98141,-10.15816 0.0574,-0.2475 0.64434,0.09 1.30434,0.75 0.66,0.66 2.18252,1.2 3.38337,1.2 2.79309,0 3.52113,2.70677 2.73949,10.1851 -0.39145,3.74518 -1.24893,6.343 -2.4535,7.43313 -1.76446,1.59681 -1.94952,1.45478 -3.92586,-3.01304 z m 4.0565,-7.98275 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f96857" />
+ <path
+ id="path2954"
+ d="m 224.43035,828.2706 c -2.66558,-3.61935 -4.17153,-18.25687 -1.87832,-18.25687 1.73553,0 3.52243,3.04033 3.52243,5.99328 0,1.16861 0.45,1.84664 1,1.50672 0.58985,-0.36455 1.07513,0.94423 1.18318,3.19098 0.45481,9.45699 -0.72168,11.78271 -3.82729,7.56589 z m 17.31261,-3.28329 c -1.95628,-4.43272 -2.12466,-5.73743 -1.23521,-9.57109 0.71036,-3.06172 1.44872,-4.27801 2.38006,-3.92062 0.74262,0.28497 2.16094,0.51813 3.15181,0.51813 2.38322,0 3.09675,3.11426 2.35015,10.25737 -0.44715,4.27809 -1.11132,6.09827 -2.49554,6.83908 -1.64554,0.88067 -2.17523,0.3546 -4.15127,-4.12287 z m 4.3315,-6.35114 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f97448" />
+ <path
+ id="path2952"
+ d="m 224.43035,828.2706 c -2.17337,-2.95101 -4.19764,-18.25687 -2.41456,-18.25687 1.73198,0 4.05867,3.14613 4.05867,5.4881 0,1.28988 0.46287,2.49952 1.0286,2.6881 1.39017,0.46339 1.74167,10.4523 0.41453,11.78012 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.71778,0 0.90684,-1.09078 0.52231,-3.01345 -0.57326,-2.86632 -0.46951,-2.98163 2.125,-2.36174 4.2138,1.00677 4.22769,1.03602 4.22769,8.89902 0,6.41491 -0.27118,7.55093 -2.02673,8.49048 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z m 4.00477,-7.17705 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f89426" />
+ <path
+ id="path2950"
+ d="m 224.43035,828.2706 c -1.42701,-1.9376 -2.22355,-5.05998 -2.68038,-10.50687 -0.3575,-4.2625 -0.29574,-7.75 0.13724,-7.75 1.38039,0 3.18725,2.3405 3.18725,4.12857 0,0.95072 0.69195,2.42052 1.53766,3.26624 1.80711,1.8071 2.46952,10.99666 0.90547,12.56151 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.72319,0 0.90496,-1.1002 0.50893,-3.08036 -0.44279,-2.21392 -0.26699,-2.96256 0.625,-2.66159 0.8199,0.27666 1.12566,2.00073 0.901,5.08036 -0.27261,3.73691 -0.0247,4.66159 1.25,4.66159 1.22091,0 1.59007,-1.05845 1.59007,-4.55902 0,-2.7847 0.38919,-4.31848 1,-3.94098 0.55,0.33992 1,3.95064 1,8.02383 0,6.41491 -0.27118,7.55093 -2.02673,8.49048 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f8862a" />
+ <path
+ id="path2948"
+ d="m 224.43035,828.2706 c -2.45647,-3.33541 -4.24951,-18.71542 -2.10001,-18.01314 0.68426,0.22357 1.72913,1.87324 2.32193,3.66594 0.5928,1.7927 1.61953,3.59426 2.28162,4.00346 1.52494,0.94246 1.99455,10.63162 0.5837,12.04319 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.71667,0 0.90722,-1.08889 0.525,-3 -0.33846,-1.69231 -0.175,-3 0.375,-3 0.53625,0 0.975,2.25 0.975,5 0,3.74919 0.37048,5 1.48095,5 0.81452,0 1.697,-1.0125 1.96106,-2.25 0.26407,-1.2375 0.67044,-3.15 0.90305,-4.25 0.23262,-1.1 0.47514,1.47167 0.53894,5.71482 0.10212,6.79156 -0.12655,7.84462 -1.91073,8.79949 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f87638" />
+ <path
+ id="path2946"
+ d="m 224.43035,828.2706 c -2.4567,-3.33573 -4.24905,-18.71274 -2.10001,-18.01662 0.68426,0.22166 1.84937,2.28342 2.58911,4.58169 0.73974,2.29827 1.75224,3.92698 2.25,3.61935 1.53952,-0.95147 1.67063,10.19309 0.13795,11.72577 -0.46567,0.46567 -1.76034,-0.39392 -2.87705,-1.91019 z m 17.63934,-2.45738 c -2.06208,-4.54357 -2.59586,-8.79949 -1.10364,-8.79949 0.49038,0 1.17395,1.125 1.51905,2.5 0.67619,2.69414 2.46533,3.22403 4.38936,1.3 0.93333,-0.93333 1.2,-0.27448 1.2,2.96482 0,3.15967 -0.48914,4.42659 -2.02673,5.24949 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f86647" />
+ <path
+ id="path2944"
+ d="m 225.53957,828.73073 c -0.35508,-1.41476 -1.27715,-2.81463 -2.04903,-3.11083 -0.96655,-0.3709 -1.35554,-2.02774 -1.24959,-5.32236 0.0846,-2.63109 -0.19572,-5.79631 -0.62296,-7.03381 -0.59332,-1.71857 -0.39946,-2.25 0.82079,-2.25 0.92147,0 1.86759,1.16381 2.23559,2.75 0.35092,1.5125 1.31914,3.83771 2.15162,5.16714 1.83737,2.93418 2.15539,9.57594 0.53605,11.19528 -0.90249,0.90249 -1.32739,0.57716 -1.82247,-1.39542 z m 17.11275,-1.8764 c -2.21367,-5.29808 -2.8383,-8.5616 -1.76556,-9.2246 0.53589,-0.3312 1.25593,0.51971 1.60008,1.89091 0.65349,2.60373 2.45562,3.22509 4.22421,1.4565 0.71546,-0.71546 1.07635,0.0209 1.16492,2.37676 0.0842,2.23955 -0.54396,4.02176 -1.82663,5.18256 -1.8947,1.71468 -1.9994,1.66283 -3.39702,-1.68213 z"
+ style="fill:#f85b47" />
+ <path
+ id="path2942"
+ d="m 224.83638,826.76373 c -0.80746,-1.2375 -1.70473,-4.5 -1.99393,-7.25 -0.2892,-2.75 -0.85346,-5.7875 -1.2539,-6.75 -0.50617,-1.21664 -0.26667,-1.75 0.7858,-1.75 0.99121,0 2.23649,2.30222 3.60698,6.66841 3.1106,9.90994 2.50902,14.68163 -1.14495,9.08159 z m 17.16288,-2.42544 c -1.10227,-2.57149 -1.70889,-5.38399 -1.34804,-6.25 0.50685,-1.2164 0.87603,-0.94902 1.623,1.17544 1.03757,2.95098 2.66105,3.48919 4.61899,1.53125 0.95833,-0.95833 1.08942,-0.47756 0.61347,2.25 -1.33435,7.64681 -2.65142,7.9561 -5.50742,1.29331 z"
+ style="fill:#f86639" />
+ <path
+ id="path2940"
+ d="m 224.68947,826.54891 c -0.9401,-1.43477 -1.61501,-4.54435 -1.61501,-7.44098 0,-2.73689 -0.45,-5.25428 -1,-5.5942 -1.49608,-0.92463 -1.20529,-2.5 0.46146,-2.5 0.88442,0 1.88498,1.67803 2.53414,4.25 0.58998,2.3375 1.50732,5.28367 2.03854,6.54705 1.2092,2.87578 1.25778,7.20295 0.0809,7.20295 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z m 17.87076,-0.91499 c -1.85558,-4.44103 -1.92346,-6.60102 -0.13038,-4.14884 0.85716,1.17224 1.98303,1.61276 3.06282,1.19841 1.42177,-0.54558 1.65509,-0.12558 1.39461,2.51051 -0.4403,4.4558 -2.5591,4.67122 -4.32705,0.43992 z"
+ style="fill:#f7781d" />
+ <path
+ id="path2938"
+ d="m 224.68947,826.54891 c -0.9401,-1.43477 -1.61501,-4.54435 -1.61501,-7.44098 0,-2.73689 -0.45,-5.25428 -1,-5.5942 -1.51136,-0.93407 -1.19817,-2.5 0.5,-2.5 1.04762,0 1.5,1.05556 1.5,3.5 0,1.925 0.3596,3.5 0.79911,3.5 1.02848,0 3.20089,5.98672 3.20089,8.821 0,2.87849 -1.38847,2.76125 -3.38499,-0.28582 z m 17.87076,-0.91499 c -1.85558,-4.44103 -1.92346,-6.60102 -0.13038,-4.14884 0.85716,1.17224 1.98303,1.61276 3.06282,1.19841 1.42177,-0.54558 1.65509,-0.12558 1.39461,2.51051 -0.4403,4.4558 -2.5591,4.67122 -4.32705,0.43992 z"
+ style="fill:#f85737" />
+ <path
+ id="path2936"
+ d="m 224.89116,825.23793 c -1.761,-3.89609 -2.71911,-12.65513 -1.5159,-13.85834 0.38456,-0.38455 0.6992,0.95081 0.6992,2.96747 0,2.01667 0.45,3.66667 1,3.66667 0.55,0 1,1.09844 1,2.44098 0,1.34254 0.45,2.7191 1,3.05902 1.15423,0.71335 1.37341,5.51284 0.25,5.4742 -0.4125,-0.0142 -1.50749,-1.70169 -2.4333,-3.75 z m 18.34208,1.70574 c -0.76367,-2.0394 -0.56828,-2.51979 1.21566,-2.98899 2.66619,-0.70124 3.43951,1.67367 1.25599,3.85719 -1.41566,1.41566 -1.64686,1.33445 -2.47165,-0.8682 z"
+ style="fill:#f76727" />
+ <path
+ id="path2934"
+ d="m 224.82446,825.16032 c -1.95208,-4.24082 -2.20733,-6.14659 -0.82324,-6.14659 1.19752,0 4.07324,5.75648 4.07324,8.15364 0,2.94344 -1.35701,2.10541 -3.25,-2.00705 z m 18.40878,1.78335 c -0.76367,-2.0394 -0.56828,-2.51979 1.21566,-2.98899 2.66619,-0.70124 3.43951,1.67367 1.25599,3.85719 -1.41566,1.41566 -1.64686,1.33445 -2.47165,-0.8682 z"
+ style="fill:#f84b34" />
+ <path
+ id="path2932"
+ d="m 224.82446,824.64094 c -2.00235,-4.2279 -2.1827,-5.62721 -0.72525,-5.62721 1.33504,0 3.14946,4.81045 2.77063,7.34559 -0.23097,1.54565 -0.67698,1.17095 -2.04538,-1.71838 z m 18.73475,2.34812 c -0.40754,-0.65942 -0.12083,-1.58421 0.63713,-2.05509 1.66304,-1.03315 2.55953,0.79835 1.10349,2.25439 -0.66618,0.66618 -1.24681,0.59969 -1.74062,-0.1993 z"
+ style="fill:#f75529" />
+ <path
+ id="path2930"
+ d="m 226.15341,826.59706 c -0.0434,-1.05416 0.19292,-1.64479 0.52522,-1.3125 0.33229,0.33229 0.36781,1.1948 0.0789,1.91667 -0.31923,0.79773 -0.55619,0.56078 -0.60417,-0.60417 z m 17.4058,0.392 c -0.40754,-0.65942 -0.12083,-1.58421 0.63713,-2.05509 1.66304,-1.03315 2.55953,0.79835 1.10349,2.25439 -0.66618,0.66618 -1.24681,0.59969 -1.74062,-0.1993 z"
+ style="fill:#f8472b" />
+ <path
+ id="path2928"
+ d="m 244.07446,826.57275 c 0,-0.85746 0.45,-1.55902 1,-1.55902 0.55,0 1,0.42344 1,0.94098 0,0.51754 -0.45,1.2191 -1,1.55902 -0.55,0.33992 -1,-0.0835 -1,-0.94098 z"
+ style="fill:#f83e29" />
+ </g>
+ <g
+ transform="translate(-109.5,132.5)"
+ id="shipFire2">
+ <path
+ id="path3209"
+ d="m 151.57446,902.9436 0,-15 20,0 20,0 0,15 0,15 -20,0 -20,0 0,-15 z"
+ style="fill:#fefefe" />
+ <path
+ id="path3207"
+ d="m 162.96188,917.12575 c 0.278,-0.44981 -0.42671,-1.46231 -1.56602,-2.25 -6.19532,-4.28325 -6.07193,-4.01046 -6.49663,-14.36377 -0.35012,-8.53525 -0.17217,-9.96019 1.38679,-11.10498 2.07435,-1.52325 11.97013,-1.78746 12.8626,-0.34341 0.37888,0.61304 1.12963,0.5408 2.01487,-0.19388 0.96521,-0.80105 1.80587,-0.85078 2.66097,-0.15738 0.83468,0.67683 3.35475,0.69027 7.58466,0.0404 3.48406,-0.53525 6.57872,-0.72911 6.87702,-0.43081 0.92329,0.92328 2.41041,8.80392 2.9664,15.71969 0.39587,4.92418 0.12314,7.38568 -1.07506,9.70274 -1.54819,2.99387 -1.78393,3.08356 -6.60426,2.51267 -3.41971,-0.40502 -4.99876,-0.23214 -4.99876,0.54726 0,0.62661 -0.66643,1.13929 -1.48095,1.13929 -1.80373,0 -2.9556,-4.04919 -2.00441,-7.04614 0.92344,-2.90948 -1.57556,-2.16889 -3.13355,0.92865 -1.68131,3.34273 -5.03701,6.11749 -7.39829,6.11749 -1.15546,0 -1.87338,-0.36803 -1.59538,-0.81785 z"
+ style="fill:#fef4f3" />
+ <path
+ id="path3205"
+ d="m 163.03741,917.00355 c 0.58394,-0.94485 0.10077,-1.48471 -4.41546,-4.93349 -2.1257,-1.62328 -2.54917,-2.98908 -3.17795,-10.24965 -1.00798,-11.63923 -0.10006,-13.34965 7.14549,-13.46141 3.01673,-0.0465 5.93497,0.23133 6.48497,0.61747 1.17869,0.82751 10.45665,0.51702 15.61683,-0.52263 l 3.61683,-0.7287 1.63317,7.23189 c 2.02661,8.97413 2.06262,13.7145 0.13914,18.31804 -1.48926,3.5643 -1.51001,3.57382 -6.5,2.98283 -3.4256,-0.40571 -5.00597,-0.23321 -5.00597,0.54641 0,1.55847 -2.97681,1.45192 -3.09274,-0.11071 -0.051,-0.6875 -0.0116,-3.25029 0.0875,-5.69508 0.15304,-3.77373 -0.038,-4.26392 -1.26504,-3.24559 -0.79492,0.65972 -2.72404,3.22251 -4.28694,5.69508 -2.05711,3.25444 -3.49307,4.49559 -5.20123,4.49559 -1.29778,0 -2.09816,-0.42302 -1.77862,-0.94005 z"
+ style="fill:#fef3ea" />
+ <path
+ id="path3203"
+ d="m 162.87261,917.31212 c 0.98153,-0.98154 -1.19733,-4.36852 -2.81028,-4.36852 -0.79297,0 -2.1115,-1.02214 -2.93006,-2.27143 -1.9288,-2.94372 -2.45436,-19.23181 -0.67788,-21.00894 1.42194,-1.42246 12.12007,-1.80281 12.12007,-0.4309 0,0.51045 1.09742,0.65265 2.43871,0.31601 1.3413,-0.33665 2.72239,-0.15309 3.0691,0.4079 0.34671,0.56099 1.075,0.7452 1.61842,0.40934 0.54342,-0.33585 1.97483,-0.7608 3.1809,-0.94432 1.20608,-0.18353 3.76787,-0.62898 5.69287,-0.98989 l 3.5,-0.65619 1.7642,7.33421 c 1.93817,8.05746 2.29955,15.83421 0.7358,15.83421 -0.55,0 -1,1.09844 -1,2.44098 0,3.27429 -1.11158,3.76871 -6.00239,2.66982 -3.26275,-0.73309 -4.24406,-0.63213 -4.67105,0.48057 -0.29729,0.77475 -1.16739,1.40863 -1.93355,1.40863 -1.02551,0 -1.39301,-1.48331 -1.39301,-5.62245 0,-5.01744 -0.17049,-5.48095 -1.58439,-4.30751 -0.87142,0.72321 -2.91804,3.25331 -4.54804,5.62244 -1.91866,2.78868 -3.71068,4.30752 -5.08228,4.30752 -1.16524,0 -1.83446,-0.28417 -1.48714,-0.63148 z"
+ style="fill:#fde8e7" />
+ <path
+ id="path3201"
+ d="m 163.57446,916.49449 c 0,-0.79701 -1.5347,-2.61968 -3.41045,-4.05039 -3.34087,-2.5482 -3.42503,-2.79562 -4.12458,-12.12631 -0.49318,-6.57819 -0.36781,-9.87135 0.40526,-10.64442 1.58052,-1.58052 11.34374,-1.64763 12.90871,-0.0887 0.70341,0.70069 1.94091,1.01996 2.75,0.70948 0.80908,-0.31047 1.47106,-0.0398 1.47106,0.60151 0,0.69406 0.50594,0.84125 1.25,0.36365 1.48765,-0.95489 9.60478,-3.20883 11.78189,-3.27155 0.89112,-0.0257 1.61132,0.91554 1.72177,2.25013 0.10444,1.26185 0.87759,4.24343 1.71811,6.62573 1.71574,4.86292 2.06153,14.08001 0.52823,14.08001 -0.55,0 -1,0.8449 -1,1.87755 0,3.07992 -2.2104,4.20929 -6.07124,3.10202 -4.50601,-1.29231 -4.92876,-1.24767 -4.92876,0.52043 0,0.825 -0.6681,1.5 -1.48467,1.5 -1.21761,0 -1.37186,-1.07927 -0.85754,-6 0.37978,-3.63355 0.24528,-6 -0.34102,-6 -1.19371,0 -4.13666,3.29088 -7.37163,8.24317 -2.48087,3.79786 -4.94514,4.94785 -4.94514,2.30772 z"
+ style="fill:#fde3db" />
+ <path
+ id="path3199"
+ d="m 163.57446,916.49449 c 0,-0.79701 -1.50777,-2.59914 -3.35059,-4.00473 -3.26039,-2.48682 -3.36819,-2.80345 -4.00402,-11.76116 -0.53554,-7.5447 -0.37779,-9.48118 0.87439,-10.73336 2.05974,-2.05974 11.1787,-2.27977 11.94295,-0.28817 0.32015,0.83429 1.22302,1.18736 2.13824,0.83616 1.0586,-0.40623 1.76151,0.0705 2.11886,1.43701 0.52424,2.00471 0.56124,2.00709 1.88206,0.12136 0.74101,-1.05795 2.59623,-2.18478 4.1227,-2.50408 9.28393,-1.94193 8.81294,-1.97116 9.02241,0.55983 0.1081,1.30613 0.88425,4.32394 1.72477,6.70624 1.71574,4.86292 2.06153,14.08001 0.52823,14.08001 -0.55,0 -1,0.81 -1,1.8 0,3.01516 -1.86706,4.09852 -5.34458,3.10118 -4.40199,-1.26248 -5.65542,-1.12976 -5.65542,0.59882 0,0.825 -0.63233,1.5 -1.40517,1.5 -1.11122,0 -1.29136,-1.25517 -0.86111,-6 0.34639,-3.82005 0.16791,-6 -0.49124,-6 -1.32415,0 -7.06306,6.5121 -8.48052,9.62309 -1.18645,2.60397 -3.76196,3.23916 -3.76196,0.9278 z"
+ style="fill:#fddbda" />
+ <path
+ id="path3197"
+ d="m 163.57446,915.96928 c 0,-1.18015 -1.20093,-2.59534 -2.98551,-3.51819 -3.28277,-1.69758 -3.6304,-2.72129 -4.44155,-13.07944 -0.72235,-9.22415 0.366,-10.86052 7.31911,-11.00464 4.13062,-0.0856 5.18438,0.24206 5.66684,1.76214 0.32597,1.02703 1.32706,1.74292 2.22465,1.59089 1.2408,-0.21018 1.71047,0.67881 1.95939,3.70872 0.18006,2.19184 0.74523,4.403 1.25592,4.91369 0.57138,0.57138 0.70687,-0.43744 0.35224,-2.62274 -0.81981,-5.05189 0.66273,-6.92355 6.70993,-8.47114 5.54336,-1.41865 6.86584,-0.905 6.93872,2.69503 0.0167,0.825 0.67885,3.3 1.47142,5.5 2.01176,5.58413 1.86493,10.42872 -0.46204,15.24498 -1.9362,4.00748 -2.08038,4.09285 -5.25,3.10855 -5.15345,-1.60037 -6.28791,-1.52497 -5.96528,0.39647 0.16161,0.9625 -0.30972,1.75 -1.0474,1.75 -1.02652,0 -1.24411,-1.52514 -0.92734,-6.5 0.22764,-3.575 0.024,-6.47871 -0.4526,-6.45269 -1.17866,0.0644 -9.3665,10.39262 -9.3665,11.81503 0,0.62571 -0.675,1.13766 -1.5,1.13766 -0.82683,0 -1.5,-0.88604 -1.5,-1.97432 z"
+ style="fill:#fdd4d3" />
+ <path
+ id="path3195"
+ d="m 164.18103,916.77117 c 0.43565,-0.70489 -0.81465,-2.4647 -3.13534,-4.41305 -3.69469,-3.10187 -3.89194,-3.57553 -4.60717,-11.06331 -1.03988,-10.88663 -0.0358,-12.78139 6.84886,-12.92409 4.71285,-0.0977 5.2995,0.13606 6.23046,2.48252 0.56525,1.4247 1.47635,3.26536 2.02466,4.09036 0.54832,0.825 1.67354,3.075 2.50049,5 l 1.50355,3.5 -0.50478,-5 c -0.27763,-2.75 -0.0824,-5.64324 0.43386,-6.42941 0.79202,-1.20613 11.1128,-4.63899 11.53951,-3.83823 0.0784,0.1472 1.15252,3.4997 2.38686,7.44999 2.43693,7.79905 2.66335,14.72 0.45384,13.87213 -0.93046,-0.35706 -1.14026,0.15958 -0.72945,1.79636 0.92292,3.67722 -1.48563,4.94645 -6.83196,3.60023 -4.34704,-1.0946 -4.4947,-1.26023 -4.98261,-5.58895 -0.52198,-4.63098 -1.67993,-6.79044 -2.46354,-4.59426 -0.24881,0.69732 -1.15193,1.9674 -2.00693,2.8224 -2.2206,2.2206 -6.26688,8.32478 -6.26688,9.45415 0,0.52557 -0.70156,0.95559 -1.55902,0.95559 -0.93755,0 -1.27017,-0.46736 -0.83441,-1.17243 z m 11.39343,0.73145 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z"
+ style="fill:#fdd5cb" />
+ <path
+ id="path3193"
+ d="m 164.1735,916.5461 c 0.31707,-0.82628 -0.88226,-2.47948 -2.93415,-4.04453 -4.03071,-3.07437 -4.57157,-4.70635 -4.77073,-14.39518 -0.1804,-8.77645 0.68336,-10.02859 6.65854,-9.65248 3.86629,0.24336 4.82621,0.76895 6.84943,3.75033 1.29414,1.90703 2.89298,5.10353 3.55298,7.10334 1.63364,4.94999 2.44547,4.57523 1.71016,-0.78944 -0.75035,-5.47444 0.9777,-7.75927 7.18209,-9.49615 2.39104,-0.66935 4.43478,-1.07332 4.54164,-0.8977 0.10686,0.17562 1.20419,3.55137 2.43853,7.50166 2.4293,7.77463 2.66263,14.71972 0.46621,13.87687 -0.87564,-0.33601 -1.29374,0.44385 -1.29374,2.41315 0,3.83982 -0.992,4.28955 -6.31903,2.86479 -4.29403,-1.14848 -4.47943,-1.35674 -4.95371,-5.56454 -0.4947,-4.38896 -1.66671,-6.69837 -2.38712,-4.70377 -0.21232,0.58787 -2.17572,2.98811 -4.36309,5.33386 -2.18738,2.34575 -3.97705,5.12726 -3.97705,6.18114 0,1.05388 -0.66088,1.91615 -1.46862,1.91615 -0.84672,0 -1.24152,-0.59178 -0.93234,-1.3975 z m 11.40096,0.95652 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z"
+ style="fill:#fcc9c7" />
+ <path
+ id="path3191"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.04148,-1 1.55902,-1 0.51754,0 0.94098,0.45 0.94098,1 0,0.55 -0.70156,1 -1.55902,1 -0.85746,0 -1.2809,-0.45 -0.94098,-1 z m -2.5,-4.5612 c -3.83318,-2.6976 -4.78539,-5.9 -4.92588,-16.56636 -0.088,-6.68229 0.84499,-7.68093 6.86223,-7.34496 3.62102,0.20218 4.59555,0.6781 5.30265,2.58955 0.47646,1.28801 1.42448,3.0261 2.10671,3.86241 1.94334,2.38227 3.85888,8.87634 3.02775,10.26473 -1.36298,2.27684 -7.78605,9.75683 -8.33522,9.70679 -0.29603,-0.027 -2.11324,-1.15744 -4.03824,-2.51216 z m 18.36759,1.39317 c -1.5582,-0.75458 -2.29225,-2.28472 -2.72598,-5.68232 -1.81186,-14.19307 -1.85608,-15.1863 -0.73618,-16.5357 0.6374,-0.76802 2.38193,-1.62827 3.87674,-1.91168 1.4948,-0.28341 3.73033,-0.83485 4.96783,-1.22541 1.79339,-0.56601 2.25,-0.32428 2.25,1.19117 0,1.04571 0.9243,4.53109 2.05401,7.7453 2.39531,6.81511 2.29483,11.2274 -0.2461,10.80613 -1.40828,-0.23348 -1.59599,0.31162 -1.11915,3.25 0.56258,3.46682 0.51191,3.52932 -2.80792,3.46286 -1.85946,-0.0372 -4.34043,-0.53238 -5.51325,-1.10035 z"
+ style="fill:#fcbec0" />
+ <path
+ id="path3189"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m 15.867,-3.4555 c -2.13975,-1.49873 -3.49156,-7.8263 -3.74817,-17.5445 l -0.11883,-4.5 5,-1.66983 c 6.5578,-2.19008 6.5,-2.19412 6.5,0.45449 0,1.25656 0.9,4.84532 2,7.97502 2.56186,7.28896 2.57769,9.74032 0.0629,9.74032 -1.65538,0 -1.85452,0.50906 -1.36916,3.5 0.55605,3.4265 0.4964,3.5 -2.84036,3.5 -1.87459,0 -4.34344,-0.65497 -5.48635,-1.4555 z m -18.60545,-1.38463 c -3.43887,-2.08117 -3.72417,-2.86336 -4.4426,-12.17971 -0.78522,-10.18248 0.13117,-11.85397 6.28649,-11.46653 l 4.65321,0.29289 2.84267,6.34674 c 3.65068,8.15076 3.60396,10.13172 -0.35132,14.89597 -3.55811,4.28584 -4.88093,4.59646 -8.98845,2.11064 z"
+ style="fill:#fcc6b6" />
+ <path
+ id="path3187"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m 15.86726,-3.77224 c -1.42817,-1.15698 -2.34597,-3.37956 -2.77818,-6.72776 -0.35499,-2.75 -0.87727,-6.8 -1.16063,-9 -0.63335,-4.91747 0.30316,-6.41121 4.67526,-7.45707 1.86796,-0.44683 4.18379,-1.13743 5.14629,-1.53467 1.38018,-0.56961 1.75,-0.21682 1.75,1.66941 0,1.31541 0.9,4.95231 2,8.08201 1.1,3.12969 2,6.6016 2,7.71534 0,1.35831 -0.65844,2.02498 -2,2.02498 -1.61905,0 -2,0.66667 -2,3.5 0,3.15691 -0.26957,3.49782 -2.75,3.47776 -1.5125,-0.0122 -3.70973,-0.79973 -4.88274,-1.75 z m -18.62479,-1.06919 c -3.28171,-1.97384 -3.41746,-2.3794 -4.2374,-12.65857 -0.80902,-10.14237 0.0964,-11.68239 6.35676,-10.81264 4.18382,0.58125 4.47966,0.85505 7.24921,6.70931 3.85095,8.14012 3.70716,10.04334 -1.11219,14.72035 -4.47969,4.34739 -4.43931,4.33741 -8.25638,2.04155 z"
+ style="fill:#fcb8b7" />
+ <path
+ id="path3185"
+ d="m 180.95274,913.78034 c -1.68968,-0.81858 -2.47019,-2.83106 -3.833,-9.88312 -2.09004,-10.81512 -1.64459,-12.66589 3.26108,-13.54927 2.0315,-0.36582 4.20048,-1.06536 4.81994,-1.55453 0.77792,-0.61429 1.49677,0.58187 2.324,3.8671 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09968,2.7008 1.47131,4.7633 0.60026,3.33127 0.44732,3.75 -1.36961,3.75 -1.71953,0 -2.04531,0.63713 -2.04531,4 0,3.50153 -0.28039,3.99157 -2.25,3.93232 -1.2375,-0.0372 -3.20478,-0.53023 -4.37172,-1.09558 z m -19.9947,-2.63358 c -2.78682,-2.54536 -3.12379,-3.53611 -3.74785,-11.01905 -0.7913,-9.4884 0.22403,-12.72439 3.69989,-11.79201 1.19041,0.31933 3.15582,0.58674 4.36759,0.59425 1.65866,0.0103 2.72727,1.18765 4.32359,4.76365 3.4929,7.82464 3.41122,11.85531 -0.3316,16.3645 -1.75736,2.1172 -3.65741,3.85756 -4.22234,3.86747 -0.56493,0.01 -2.4051,-1.24055 -4.08928,-2.77881 z"
+ style="fill:#fbb4a7" />
+ <path
+ id="path3183"
+ d="m 181.40888,913.54887 c -1.90156,-0.94762 -2.66716,-2.73407 -4.12887,-9.6343 -2.11431,-9.98096 -1.48228,-12.43122 3.4804,-13.49292 1.82273,-0.38995 3.82089,-1.11594 4.44035,-1.61331 0.78167,-0.6276 1.49279,0.55112 2.324,3.85218 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09346,2.66764 1.45749,4.68962 0.59423,3.30058 0.4287,3.70941 -1.61961,4 -1.89768,0.26923 -2.23157,0.84875 -1.98478,3.44483 0.34701,3.6502 -2.13396,4.89193 -5.96229,2.98412 z m -19.59537,-1.75085 c -3.85286,-2.43946 -4.12485,-3.26446 -4.46668,-13.54855 -0.29145,-8.76823 0.67103,-11.1791 3.91041,-9.79498 0.99947,0.42706 2.70818,0.82431 3.79713,0.88279 2.50572,0.13456 5.98356,6.56952 6.78668,12.55723 0.55271,4.12079 0.33707,4.68072 -3.14285,8.16065 l -3.73629,3.73628 -3.1484,-1.99342 z"
+ style="fill:#fbc693" />
+ <path
+ id="path3181"
+ d="m 181.40888,913.54887 c -1.90156,-0.94762 -2.66716,-2.73407 -4.12887,-9.6343 -2.11431,-9.98096 -1.48228,-12.43122 3.4804,-13.49292 1.82273,-0.38995 3.82089,-1.11594 4.44035,-1.61331 0.78167,-0.6276 1.49279,0.55112 2.324,3.85218 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09346,2.66764 1.45749,4.68962 0.59423,3.30058 0.4287,3.70941 -1.61961,4 -1.89768,0.26923 -2.23157,0.84875 -1.98478,3.44483 0.34701,3.6502 -2.13396,4.89193 -5.96229,2.98412 z m -19.59537,-1.75085 c -3.85797,-2.44269 -4.12541,-3.25919 -4.46668,-13.63661 -0.21296,-6.47571 0.053,-8.48421 1.21927,-9.20836 0.92359,-0.57346 1.85661,-0.5612 2.45,0.0322 0.5271,0.5271 2.21605,0.95836 3.75324,0.95836 2.32203,0 3.11778,0.71903 4.70349,4.25 1.04975,2.3375 2.1601,6.00739 2.46746,8.15531 0.5041,3.52278 0.18969,4.27446 -3.20977,7.67393 l -3.76861,3.7686 -3.1484,-1.99342 z"
+ style="fill:#fba7a6" />
+ <path
+ id="path3179"
+ d="m 180.42487,912.6936 c -2.246,-1.83276 -5.24235,-17.14915 -3.86013,-19.73183 0.59405,-1.10999 1.40175,-2.02891 1.7949,-2.04203 0.39315,-0.0131 2.38169,-0.41108 4.41898,-0.88435 l 3.70417,-0.86049 1.20496,5.38435 c 0.66273,2.96139 1.63584,5.38435 2.16247,5.38435 0.52663,0 0.72226,0.89955 0.43475,1.999 -0.28751,1.09946 -0.115,2.25101 0.38337,2.55902 1.72728,1.06752 0.8953,2.41725 -1.34388,2.18019 -1.77357,-0.18777 -2.27296,0.29115 -2.35843,2.26179 -0.20189,4.65475 -0.38835,5 -2.70044,5 -1.26988,0 -2.9982,-0.5625 -3.84072,-1.25 z m -19.64276,-1.72785 c -3.80444,-3.17207 -5.11148,-21.0776 -1.63594,-22.41129 0.75033,-0.28793 1.63021,-0.0932 1.95528,0.43281 0.32508,0.52598 1.92562,0.95633 3.55678,0.95633 3.39807,0 4.50718,2.01814 5.96224,10.84895 0.82009,4.97716 0.69273,5.58534 -1.83233,8.74997 -3.07999,3.86011 -4.73127,4.15366 -8.00603,1.42323 z"
+ style="fill:#fb9fa0" />
+ <path
+ id="path3177"
+ d="m 180.32446,912.8635 c -0.9625,-0.5606 -1.75,-1.98067 -1.75,-3.1557 0,-1.17503 -0.70563,-4.95003 -1.56806,-8.38889 -1.97329,-7.8683 -1.07849,-9.92916 4.82218,-11.10618 l 4.24588,-0.84693 1.23482,4.0389 c 0.67915,2.22139 1.24165,5.24426 1.25,6.71747 0.008,1.47322 0.72232,3.38572 1.58661,4.25 0.86428,0.86429 1.20178,1.62334 0.75,1.68678 -0.45179,0.0634 -1.49643,0.17594 -2.32143,0.25 -0.89743,0.0806 -1.5,1.13894 -1.5,2.63465 0,4.68395 -2.72313,6.26534 -6.75,3.9199 z m -18.59061,-1.52081 c -3.18441,-2.23045 -4.15936,-5.40703 -4.3244,-14.08961 -0.10379,-5.46081 0.23701,-7.73594 1.25286,-8.36377 0.80738,-0.49899 1.7993,-0.45856 2.35379,0.0959 0.5271,0.5271 2.2295,0.95836 3.78311,0.95836 3.22728,0 4.77525,2.79781 4.77525,8.63084 0,1.92535 0.46718,4.37357 1.03817,5.44049 0.83398,1.5583 0.48978,2.62715 -1.75,5.43423 -3.14945,3.94716 -3.90883,4.14887 -7.12878,1.89353 z"
+ style="fill:#fba896" />
+ <path
+ id="path3175"
+ d="m 180.38153,912.23762 c -1.73595,-1.96787 -4.23706,-14.37731 -3.66592,-18.18864 0.28615,-1.90951 1.28961,-2.62988 4.95335,-3.55593 l 4.5945,-1.16131 1.1555,4.32028 c 0.63553,2.37616 1.1555,5.40668 1.1555,6.7345 0,1.32782 0.70714,3.12137 1.57143,3.98565 0.86428,0.86429 1.20178,1.62334 0.75,1.68678 -0.45179,0.0634 -1.49643,0.17594 -2.32143,0.25 -0.91279,0.0819 -1.69574,1.5048 -2,3.63465 -0.58275,4.07922 -3.62426,5.20588 -6.19293,2.29402 z m -19.3807,-1.60369 c -2.4799,-2.13313 -2.72327,-3.03845 -3.18385,-11.84386 -0.42411,-8.10811 -0.25997,-9.6258 1.09736,-10.14665 0.87784,-0.33686 1.86204,-0.18213 2.18711,0.34385 0.32508,0.52598 1.66397,0.95633 2.97532,0.95633 3.15873,0 5.49769,3.52618 5.49769,8.28825 0,2.11378 0.46554,4.71311 1.03454,5.77629 0.85492,1.59744 0.42667,2.54092 -2.46667,5.43425 -1.92566,1.92567 -3.71611,3.50121 -3.97877,3.50121 -0.26267,0 -1.68589,-1.03935 -3.16273,-2.30967 z"
+ style="fill:#fb9997" />
+ <path
+ id="path3173"
+ d="m 180.61925,912.49757 c -1.54558,-1.86231 -3.96316,-11.97209 -4.00917,-16.76543 -0.0337,-3.51238 0.18575,-3.77106 4.09158,-4.82279 2.32002,-0.62472 4.50572,-0.73283 4.99166,-0.24689 0.47544,0.47544 1.39155,3.48908 2.03578,6.69698 0.89078,4.43548 0.89278,6.27859 0.008,7.69478 -0.63959,1.02423 -1.16294,3.1702 -1.16294,4.76882 0,3.89193 -3.60222,5.50971 -5.95521,2.67453 z M 161.2105,910.6419 c -2.67903,-2.14379 -2.89701,-2.87138 -3.37577,-11.26821 -0.41609,-7.29756 -0.2244,-9.21497 1.02493,-10.25182 1.03553,-0.85942 1.74811,-0.9334 2.18479,-0.22683 0.35642,0.57671 1.69139,1.04856 2.96658,1.04856 3.39213,0 4.82534,2.37252 5.16837,8.55569 0.16748,3.01883 0.57322,5.92356 0.90165,6.45497 0.54751,0.8859 -4.35593,7.99571 -5.50659,7.98434 -0.275,-0.003 -1.78878,-1.03623 -3.36396,-2.2967 z"
+ style="fill:#fac868" />
+ <path
+ id="path3171"
+ d="m 180.61925,912.49757 c -1.54558,-1.86231 -3.96316,-11.97209 -4.00917,-16.76543 -0.0337,-3.51238 0.18575,-3.77106 4.09158,-4.82279 2.32002,-0.62472 4.50572,-0.73283 4.99166,-0.24689 0.47544,0.47544 1.39155,3.48908 2.03578,6.69698 0.89078,4.43548 0.89278,6.27859 0.008,7.69478 -0.63959,1.02423 -1.16294,3.1702 -1.16294,4.76882 0,3.89193 -3.60222,5.50971 -5.95521,2.67453 z m -19.45977,-1.89636 c -2.83469,-2.2682 -2.91733,-2.59171 -3,-11.74503 l -0.085,-9.41258 4,0.33285 c 5.42153,0.45115 6.73448,2.04528 7.09921,8.61958 0.17063,3.07562 0.57895,6.02682 0.90738,6.55823 0.54751,0.8859 -4.35593,7.99571 -5.50659,7.98434 -0.275,-0.003 -1.81174,-1.05454 -3.41498,-2.33739 z"
+ style="fill:#fa9588" />
+ <path
+ id="path3169"
+ d="m 181.27717,912.6936 c -2.29214,-1.70591 -5.542,-17.19589 -4.09055,-19.49693 1.25861,-1.99531 7.28306,-3.75785 8.54186,-2.49904 1.62734,1.62734 3.20598,13.28597 1.96678,14.52517 -0.61644,0.61644 -1.1208,2.2908 -1.1208,3.7208 0,2.4 -1.56461,5 -3.00887,5 -0.33488,0 -1.36467,-0.5625 -2.28842,-1.25 z m -19.82628,-2.16376 c -2.22007,-2.05857 -2.7042,-3.5724 -3.28996,-10.28744 -0.75026,-8.60077 -0.13895,-11.72478 2.12436,-10.85627 0.79901,0.30661 2.52511,0.55747 3.83577,0.55747 3.1779,0 4.5433,2.83475 4.90988,10.19353 0.23862,4.78997 -0.13818,6.723 -1.82795,9.37775 -1.17069,1.83924 -2.35813,3.36311 -2.63875,3.38639 -0.28062,0.0233 -1.68163,-1.04386 -3.11335,-2.37143 z"
+ style="fill:#fa8b86" />
+ <path
+ id="path3167"
+ d="m 180.07939,911.6936 c -0.96604,-2.79329 -3.50493,-15.00852 -3.50493,-16.86308 0,-1.34263 1.1834,-2.48343 3.64167,-3.51056 5.43653,-2.27153 6.86784,-0.40276 6.82572,8.91194 -0.0454,10.04111 -0.8895,12.7117 -4.01783,12.7117 -1.38178,0 -2.70687,-0.5625 -2.94463,-1.25 z m -19.29027,-2.20424 c -1.3053,-1.65942 -2.14743,-4.84806 -2.60032,-9.84592 -0.87694,-9.67732 -0.44657,-10.69807 4.21367,-9.99407 2.01959,0.30509 4.11891,0.96552 4.66515,1.46762 0.54623,0.50211 1.2459,4.156 1.55481,8.11977 0.48082,6.16945 0.2748,7.60269 -1.43121,9.95684 -2.45809,3.39195 -3.91374,3.4592 -6.4021,0.29576 z"
+ style="fill:#f9aa67" />
+ <path
+ id="path3165"
+ d="m 180.23917,912.1936 c -0.24933,-0.4125 -1.26783,-4.68555 -2.26334,-9.49567 -1.97889,-9.5616 -1.79281,-10.20809 3.36397,-11.68703 4.53536,-1.30072 5.74188,0.67547 5.70205,9.33952 -0.0452,9.8259 -0.90819,12.59318 -3.92743,12.59318 -1.33206,0 -2.62592,-0.3375 -2.87525,-0.75 z m -19.45005,-2.70424 c -1.3053,-1.65942 -2.14743,-4.84806 -2.60032,-9.84592 -0.79775,-8.8035 -0.22455,-11.09678 2.41988,-9.68153 1.00886,0.53993 2.95856,0.98169 4.33265,0.98169 2.92589,0 3.40329,1.19686 3.78937,9.5 0.20907,4.49625 -0.18031,6.68922 -1.55363,8.75 -2.26265,3.39527 -3.89059,3.47065 -6.38795,0.29576 z"
+ style="fill:#fa8974" />
+ <path
+ id="path3163"
+ d="m 180.72006,911.61903 c -1.4979,-1.80485 -4.31584,-15.56371 -3.63009,-17.72428 0.67874,-2.13853 7.23738,-3.59767 8.86474,-1.9722 1.21641,1.215 1.28853,11.23559 0.1243,17.27105 -0.76211,3.95089 -3.18344,5.04676 -5.35895,2.42543 z m -19.6989,-1.73433 c -2.13154,-2.35532 -3.97555,-16.59894 -2.39543,-18.50288 0.51226,-0.61723 0.59778,-1.47929 0.19005,-1.91568 -0.40772,-0.4364 0.2416,-0.28249 1.44294,0.34201 1.20134,0.6245 3.09801,1.13545 4.21481,1.13545 1.11681,0 2.51821,0.91118 3.11423,2.02485 2.07725,3.88138 -0.75392,18.97515 -3.5592,18.97515 -0.62927,0 -1.9826,-0.9265 -3.0074,-2.0589 z"
+ style="fill:#fa7c74" />
+ <path
+ id="path3161"
+ d="m 180.91399,911.73649 c -0.5371,-0.71109 -1.7753,-4.79608 -2.75154,-9.07776 -1.36171,-5.97223 -1.5043,-8.11105 -0.6124,-9.18572 1.45048,-1.74772 6.93018,-3.02459 8.07048,-1.88057 1.16986,1.17368 1.36105,11.98823 0.29772,16.84039 -0.90326,4.12175 -3.22742,5.65609 -5.00426,3.30366 z M 162.4878,910.6618 c -3.08149,-2.3659 -4.01734,-5.72011 -3.8248,-13.70865 0.17568,-7.28887 0.33626,-7.85257 1.98556,-6.96989 0.98693,0.52818 2.70817,0.96034 3.82497,0.96034 1.11681,0 2.4717,0.82427 3.01086,1.83171 1.24877,2.33334 0.244,12.81559 -1.57376,16.41829 -1.59155,3.15436 -1.35745,3.05394 -3.42283,1.4682 z"
+ style="fill:#f97568" />
+ <path
+ id="path3159"
+ d="m 181.18872,912.12848 c -1.12357,-1.81798 -3.61426,-12.66104 -3.61426,-15.73446 0,-2.38301 0.60749,-3.40618 2.54705,-4.28991 5.29419,-2.41219 6.50298,-1.14797 6.37883,6.67128 -0.13265,8.35393 -1.29475,13.61677 -3.08264,13.96046 -0.91122,0.17517 -1.91426,-0.0982 -2.22898,-0.60737 z m -20.20927,-3.28761 c -1.53322,-1.69237 -1.9442,-3.84084 -2.10589,-11.00891 -0.19049,-8.44507 -0.10329,-8.85393 1.68426,-7.89726 1.03684,0.55489 2.78818,1.0089 3.89188,1.0089 1.1037,0 2.34895,0.55373 2.76722,1.2305 1.11829,1.80944 0.48625,12.83248 -0.91853,16.0195 -1.4532,3.29687 -2.77301,3.45748 -5.31894,0.64727 z"
+ style="fill:#f9904b" />
+ <path
+ id="path3157"
+ d="m 181.18872,912.12848 c -1.14282,-1.84912 -3.61426,-12.68601 -3.61426,-15.84797 0,-2.88972 0.40359,-3.35434 3.7057,-4.26609 4.58817,-1.26686 5.28526,-0.4058 5.20486,6.42918 -0.10111,8.5965 -1.24846,13.94261 -3.06732,14.29225 -0.91122,0.17517 -1.91426,-0.0982 -2.22898,-0.60737 z m -20.20649,-3.28679 c -1.44296,-1.59445 -1.9879,-3.98904 -2.25717,-9.91855 l -0.35497,-7.81664 4.35218,0.55614 c 2.39371,0.30587 4.5587,0.73823 4.8111,0.96079 0.90854,0.80113 -0.0496,12.88089 -1.23498,15.57017 -1.45309,3.29661 -2.77359,3.45759 -5.31616,0.64809 z"
+ style="fill:#f96c64" />
+ <path
+ id="path3155"
+ d="m 182.00194,912.15744 c -1.28515,-0.85536 -4.42748,-11.79022 -4.42748,-15.407 0,-2.82016 1.32386,-4.22994 4.76309,-5.07221 3.51518,-0.86088 4.61133,2.30777 3.86257,11.16552 -0.62875,7.43814 -2.10279,10.70831 -4.19818,9.31369 z m -19.65615,-2.43812 c -2.51948,-1.91174 -3.77133,-6.20961 -3.77133,-12.94781 0,-5.09857 0.24696,-5.94712 1.58179,-5.4349 0.86998,0.33384 2.89498,0.60699 4.5,0.60699 l 2.91821,0 -0.0222,7.25 c -0.0164,5.34852 -0.4816,7.84686 -1.7737,9.52572 -1.48125,1.92462 -2.01085,2.0789 -3.43274,1 z"
+ style="fill:#f8a727" />
+ <path
+ id="path3153"
+ d="m 182.00194,912.15744 c -1.28515,-0.85536 -4.42748,-11.79022 -4.42748,-15.407 0,-2.82016 1.32386,-4.22994 4.76309,-5.07221 3.51518,-0.86088 4.61133,2.30777 3.86257,11.16552 -0.62875,7.43814 -2.10279,10.70831 -4.19818,9.31369 z m -19.65615,-2.43812 c -2.51948,-1.91174 -3.77133,-6.20961 -3.77133,-12.94781 0,-5.09857 0.24696,-5.94712 1.58179,-5.4349 0.86998,0.33384 1.72785,0.60699 1.90638,0.60699 0.17852,0 0.0911,0.89278 -0.19423,1.98395 -0.66163,2.5301 0.44138,7.01605 1.72511,7.01605 0.53952,0 0.98095,-2.025 0.98095,-4.5 0,-3.33333 0.38889,-4.5 1.5,-4.5 2.31179,0 2.07009,13.70149 -0.29594,16.77572 -1.48125,1.92462 -2.01084,2.0789 -3.43273,1 z"
+ style="fill:#f97656" />
+ <path
+ id="path3151"
+ d="m 182.00194,912.15744 c -1.30059,-0.86563 -4.42748,-11.8084 -4.42748,-15.49426 0,-2.81806 2.38324,-4.71958 5.91521,-4.71958 2.73688,0 3.51703,3.46196 2.66677,11.83399 -0.68096,6.70511 -2.16705,9.70263 -4.1545,8.37985 z m -19.6862,-2.46009 c -2.64876,-2.01116 -3.61818,-6.01981 -3.02848,-12.52309 0.39024,-4.30358 0.91579,-5.92668 1.80816,-5.58424 0.69191,0.26551 1.03216,1.34646 0.7561,2.40212 -0.64783,2.47728 0.47338,6.95146 1.74199,6.95146 0.53952,0 0.98095,-2.025 0.98095,-4.5 0,-4.55243 1.37549,-6.04303 2.45059,-2.65567 0.719,2.26536 -1.01511,15.12019 -2.19947,16.30455 -0.47815,0.47815 -1.59029,0.30306 -2.50984,-0.39513 z"
+ style="fill:#f88f2e" />
+ <path
+ id="path3149"
+ d="m 182.00194,912.15744 c -1.30059,-0.86563 -4.42748,-11.8084 -4.42748,-15.49426 0,-2.81806 2.38324,-4.71958 5.91521,-4.71958 2.73688,0 3.51703,3.46196 2.66677,11.83399 -0.68096,6.70511 -2.16705,9.70263 -4.1545,8.37985 z m -19.60247,-2.28383 c -2.66678,-1.50524 -3.80043,-6.75809 -2.89841,-13.43001 0.6194,-4.58155 0.84216,-5.12459 0.94228,-2.29705 0.16099,4.5464 1.99307,8.79705 3.79163,8.79705 0.96049,0 1.34809,-1.62693 1.3699,-5.75 0.0233,-4.40049 0.27006,-5.3385 1.05154,-3.99669 1.11218,1.90963 -0.30428,15.37887 -1.76899,16.82145 -0.44713,0.44038 -1.56671,0.37524 -2.48795,-0.14475 z"
+ style="fill:#f96656" />
+ <path
+ id="path3147"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.21163,-4.031 -2.17681,-8.0411 -1.6772,-6.9684 -1.67641,-7.3778 0.0179,-9.25 0.97502,-1.0774 2.76607,-1.9589 3.98011,-1.9589 1.91826,0 2.28765,0.68753 2.82066,5.25 0.33734,2.8875 0.4264,6.15 0.19791,7.25 -0.22848,1.1 -0.6761,3.2375 -0.9947,4.75 -0.53504,2.53994 -2.86076,3.74965 -3.84508,2 z m -20.1394,-3.47251 c -1.11749,-1.59544 -1.51155,-4.34633 -1.39666,-9.75 0.088,-4.14012 0.32918,-5.95249 0.53592,-4.02749 1.06111,9.88038 5.29481,12.46707 5.31935,3.25 0.0111,-4.14972 0.29159,-5.33254 1.00802,-4.25 1.88648,2.85051 -0.72336,17 -3.13561,17 -0.42587,0 -1.47483,-1.00013 -2.33102,-2.22251 z"
+ style="fill:#f87844" />
+ <path
+ id="path3145"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.22583,-4.08894 -2.20836,-8.16986 l -1.78643,-7.41986 2.26013,-1.83014 c 4.07651,-3.30096 5.69263,-2.4342 6.37653,3.41986 0.33734,2.8875 0.4264,6.15 0.19791,7.25 -0.22848,1.1 -0.6761,3.2375 -0.9947,4.75 -0.53504,2.53994 -2.86076,3.74965 -3.84508,2 z m -20.1394,-3.47251 c -1.68769,-2.40951 -2.14046,-8.77749 -0.62409,-8.77749 0.51294,0 1.21826,0.9 1.56739,2 0.34913,1.1 1.27945,2 2.06739,2 1.48177,0 1.88623,2.65431 0.82562,5.41821 -0.83507,2.17617 -1.9995,1.9817 -3.83631,-0.64072 z m 4.45861,-10.58651 c -0.009,-2.62138 0.37634,-4.06696 0.98469,-3.69098 1.2685,0.78398 1.2685,4.53713 0,6.5 -0.70877,1.09674 -0.97349,0.34157 -0.98469,-2.80902 z"
+ style="fill:#f96547" />
+ <path
+ id="path3143"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.2224,-4.07496 -2.20075,-8.13879 l -1.77881,-7.38879 2.39173,-1.85364 c 1.31545,-1.0195 3.06673,-1.73864 3.89173,-1.59809 2.56229,0.43651 3.33281,10.73419 1.34529,17.97931 -0.48139,1.75482 -2.85813,2.40613 -3.64919,1 z m -20.1394,-3.47251 c -1.71422,-2.44739 -2.08719,-7.33159 -0.6287,-8.23299 0.51041,-0.31545 1.21573,0.33299 1.56739,1.44098 0.35166,1.10799 1.28406,2.01452 2.072,2.01452 1.54518,0 1.75012,1.2133 0.80232,4.75 -0.76127,2.84068 -1.83714,2.84843 -3.81301,0.0275 z m 4.71566,-10.77749 c 0,-2.475 0.19502,-3.4875 0.43337,-2.25 0.23836,1.2375 0.23836,3.2625 0,4.5 -0.23835,1.2375 -0.43337,0.225 -0.43337,-2.25 z"
+ style="fill:#f87637" />
+ <path
+ id="path3141"
+ d="m 181.27056,911.1936 c -1.3015,-2.31344 -3.81424,-15.51051 -3.07198,-16.13419 2.11924,-1.78067 6.32464,-3.00774 6.93324,-2.023 0.89503,1.44819 0.93106,13.97216 0.0479,16.65719 -0.71185,2.16425 -3.03417,3.05535 -3.90918,1.5 z m -20.1394,-3.47251 c -1.89753,-2.7091 -2.11846,-8.13141 -0.3067,-7.52749 0.6875,0.22917 1.25,0.97794 1.25,1.66394 0,0.68601 0.76594,1.80735 1.70209,2.49188 1.09786,0.80278 1.5002,2.01663 1.13337,3.41939 -0.72377,2.76767 -1.81644,2.75388 -3.77876,-0.0477 z"
+ style="fill:#f95947" />
+ <path
+ id="path3139"
+ d="m 181.07693,908.3252 c -0.89888,-2.13488 -1.88744,-5.97767 -2.19679,-8.53953 -0.53507,-4.43117 -0.41126,-4.73611 2.54336,-6.26401 3.06503,-1.58498 3.11446,-1.57168 3.76318,1.01304 0.83773,3.33777 -0.26675,15.46342 -1.52292,16.71959 -0.60332,0.60333 -1.55161,-0.47042 -2.58683,-2.92909 z m -19.94937,-1.9409 c -1.73917,-2.65431 -1.76322,-6.12764 -0.0394,-5.6907 0.54247,0.1375 0.98631,0.73627 0.98631,1.33061 0,0.59434 0.79532,1.66216 1.76737,2.37295 1.05669,0.77267 1.51631,1.94659 1.14301,2.91938 -0.87597,2.28274 -1.91533,2.03154 -3.85728,-0.93224 z"
+ style="fill:#f86636" />
+ <path
+ id="path3137"
+ d="m 181.03879,908.23391 c -0.87791,-2.08467 -1.8542,-5.92781 -2.16955,-8.54031 -0.47898,-3.96811 -0.30352,-4.75 1.06593,-4.75 0.90161,0 1.63929,-0.45 1.63929,-1 0,-0.55 0.61703,-1 1.37117,-1 2.65993,0 3.14174,16.94693 0.52774,18.56248 -0.46111,0.28498 -1.55667,-1.1875 -2.43458,-3.27217 z m -19.84932,-1.75513 c -1.98831,-3.03454 -2.07595,-5.20185 -0.21035,-5.20185 0.77256,0 1.20208,0.52791 0.95449,1.17312 -0.24759,0.64522 0.24531,1.75032 1.09534,2.45578 1.6689,1.38507 2.10285,4.03777 0.66052,4.03777 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z"
+ style="fill:#f87625" />
+ <path
+ id="path3135"
+ d="m 181.03879,908.23391 c -2.37362,-5.63637 -3.12438,-13.29031 -1.30362,-13.29031 0.79161,0 1.97929,0.54 2.63929,1.2 0.93333,0.93333 1.22435,0.65556 1.30957,-1.25 0.064,-1.43104 0.49036,-0.57843 1.02516,2.05 0.97852,4.80922 0.25046,13.6439 -1.19815,14.5392 -0.48183,0.29778 -1.59434,-1.16422 -2.47225,-3.24889 z m -19.84932,-1.75513 c -0.88826,-1.35565 -1.61277,-3.26815 -1.61004,-4.25 0.004,-1.38626 0.55447,-1.11479 2.46403,1.21482 2.5072,3.05871 3.23781,5.5 1.64601,5.5 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z"
+ style="fill:#f84c44" />
+ <path
+ id="path3133"
+ d="m 180.2359,905.85828 c -2.08019,-6.44092 -2.17055,-10.91468 -0.22046,-10.91468 0.79254,0 1.78583,0.55796 2.2073,1.23992 0.51891,0.83962 0.96887,0.43607 1.39375,-1.25 0.46839,-1.85877 0.80267,-0.96902 1.31871,3.51008 0.71114,6.17236 -0.18036,11.60654 -2.00382,12.21436 -0.56872,0.18957 -1.78169,-1.97028 -2.69548,-4.79968 z m -18.5123,-0.55793 c -1.29298,-1.23837 -2.18431,-2.75123 -1.98075,-3.36191 0.20356,-0.61068 1.41357,0.30103 2.68891,2.02602 2.80692,3.79656 2.48839,4.39744 -0.70816,1.33589 z"
+ style="fill:#f86827" />
+ <path
+ id="path3131"
+ d="m 180.2359,905.85828 c -1.86184,-5.76484 -2.17392,-10.91468 -0.66144,-10.91468 0.55,0 1,0.45 1,1 0,0.55 0.68465,1 1.52144,1 2.50204,0 3.88913,4.40836 2.87647,9.14182 -0.49385,2.30842 -1.38776,4.35915 -1.98647,4.55717 -0.59871,0.19803 -1.83621,-1.95491 -2.75,-4.78431 z m -18.5123,-0.55793 c -1.29298,-1.23837 -2.18431,-2.75123 -1.98075,-3.36191 0.20356,-0.61068 1.41357,0.30103 2.68891,2.02602 2.80692,3.79656 2.48839,4.39744 -0.70816,1.33589 z"
+ style="fill:#f8543b" />
+ <path
+ id="path3129"
+ d="m 180.29865,905.15272 c -0.94831,-3.19444 -1.72419,-6.51091 -1.72419,-7.36993 0,-2.36962 4.94315,-1.05807 6.17129,1.6374 1.14526,2.51357 -0.10153,10.66682 -1.71332,11.20409 -0.55528,0.18509 -1.78548,-2.27711 -2.73378,-5.47156 z"
+ style="fill:#f8641b" />
+ <path
+ id="path3127"
+ d="m 180.29609,905.14412 c -0.9469,-3.18971 -1.72163,-6.55059 -1.72163,-7.46861 0,-2.24903 2.73366,-1.14642 3.55227,1.43279 0.39906,1.25732 1.18505,1.76634 2.15355,1.39469 1.29252,-0.49599 1.41642,0.14122 0.81229,4.17768 -1.24083,8.29061 -2.43855,8.40634 -4.79648,0.46345 z"
+ style="fill:#f84936" />
+ <path
+ id="path3125"
+ d="m 181.14286,906.45307 c -1.73239,-4.14621 -2.09098,-9.50947 -0.63579,-9.50947 0.51294,0 1.22859,0.93254 1.59034,2.07232 0.41698,1.31378 1.20605,1.86191 2.15571,1.49749 1.24752,-0.47871 1.38241,0.1362 0.80674,3.67768 -0.9703,5.96925 -2.09631,6.6195 -3.917,2.26198 z"
+ style="fill:#f85818" />
+ <path
+ id="path3123"
+ d="m 181.09683,906.3429 c -0.88794,-2.12514 -1.44768,-5.22186 -1.24388,-6.8816 l 0.37056,-3.0177 0.81643,3.32977 c 0.62382,2.54421 1.24413,3.21792 2.62934,2.85569 1.54861,-0.40498 1.72746,-0.0157 1.22681,2.67022 -0.91755,4.92246 -2.04875,5.23318 -3.79926,1.04362 z"
+ style="fill:#f84528" />
+ <path
+ id="path3121"
+ d="m 182.18715,908.75698 c -2.04329,-7.19112 -2.31672,-8.87827 -1.51879,-9.37142 0.49836,-0.30799 0.9061,0.36656 0.9061,1.49902 0,1.16357 0.65233,2.05902 1.5,2.05902 0.99331,0 1.5,0.99344 1.5,2.94098 0,3.06564 -1.73817,5.15699 -2.38731,2.8724 z"
+ style="fill:#f83b28" />
+ <path
+ id="path3119"
+ d="m 181.63518,905.09018 c -0.68081,-1.64361 -1.02518,-3.81148 -0.76528,-4.81748 0.38073,-1.47369 0.4951,-1.3919 0.58856,0.4209 0.0661,1.28178 0.76148,2.25 1.616,2.25 1.64633,0 1.93861,1.75999 0.63396,3.81749 -0.60865,0.95987 -1.1714,0.50633 -2.07324,-1.67091 z"
+ style="fill:#f8461a" />
+ <path
+ id="path3117"
+ d="m 182.21283,906.4436 c -0.3471,-0.90455 -0.005,-1.5 0.86163,-1.5 0.86669,0 1.20873,0.59545 0.86163,1.5 -0.31659,0.825 -0.70432,1.5 -0.86163,1.5 -0.15731,0 -0.54504,-0.675 -0.86163,-1.5 z"
+ style="fill:#f8381c" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship80x200.svg b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship80x200.svg
new file mode 100755
index 0000000..e7d84eb
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/assets/svg/spaceship80x200.svg
@@ -0,0 +1,542 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?xml-stylesheet href="../../css/lesson.css" type="text/css"?><!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="80"
+ height="204.82979"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.47pre4 r22446"
+ sodipodi:docname="spaceship80x200.svg">
+ <defs
+ id="defs4">
+ <inkscape:path-effect
+ effect="skeletal"
+ id="path-effect3780"
+ is_visible="true"
+ pattern="m -38,719.36218 c 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 z"
+ copytype="single_stretched"
+ prop_scale="1"
+ scale_y_rel="false"
+ spacing="0"
+ normal_offset="0"
+ tang_offset="0"
+ prop_units="false"
+ vertical_pattern="false"
+ fuse_tolerance="0" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="51.367568"
+ inkscape:cy="103.5"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1024"
+ inkscape:window-height="551"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-22.2069,-845.61384)">
+ <g
+ id="g3211"
+ transform="matrix(0.97869659,0,0,0.97869659,0.47308226,22.378026)">
+ <path
+ inkscape:original-d="m 37,942.81046 c 0.574713,0.14367 1.149425,0.28735 0,0 z"
+ inkscape:path-effect="#path-effect3780"
+ id="path3778"
+ d="m 37,942.81046 c 0.167098,-0.66843 0.34309,-1.2936 0.486364,-1.7242 0.143274,-0.4306 0.253551,-0.66551 0.31386,-0.65187 0.06031,0.0136 0.07065,0.2758 0.04077,0.73251 -0.02988,0.45671 -0.09969,1.10684 -0.175087,1.79783 -0.0015,0.004 -0.003,0.007 -0.0044,0.0112 -0.257922,0.64338 -0.501864,1.24926 -0.690253,1.66648 -0.188389,0.41721 -0.32095,0.64463 -0.380785,0.62966 -0.05983,-0.015 -0.04694,-0.27232 0.02884,-0.7177 0.07578,-0.44537 0.21418,-1.07766 0.380734,-1.74389 0.166554,-0.66623 0.341982,-1.28926 0.484718,-1.7179 0.142736,-0.42864 0.252501,-0.66177 0.312355,-0.64682 0.05985,0.015 0.06979,0.27801 0.03961,0.73477 -0.03018,0.45676 -0.100211,1.10613 -0.175623,1.79513 -4.36e-4,0.004 -8.73e-4,0.008 -0.0013,0.0119 -0.258431,0.64522 -0.502606,1.25177 -0.691076,1.66883 -0.188471,0.41707 -0.320958,0.64354 -0.380601,0.62718 -0.05964,-0.0163 -0.04644,-0.27553 0.02975,-0.72289 0.07619,-0.44737 0.215079,-1.08182 0.382177,-1.75025 z"
+ style="fill:#000000;fill-rule:evenodd;stroke:none" />
+ <g
+ transform="translate(-184.55172,103.22414)"
+ id="g4020">
+ <g
+ id="shipBody"
+ class="spaceship">
+ <path
+ style="fill:#d45500;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 235.65719,857.2309 c -5.15468,-1.08647 -10.13216,-2.60614 -11.06105,-3.37705 -1.4687,-1.21891 -1.59942,-3.62164 -1.0026,-18.42851 0.60898,-15.10833 2.82784,-34.89255 4.50742,-40.18992 0.5468,-1.72458 2.1597,-1.86153 18.79408,-1.59574 l 18.19595,0.29073 0.86603,3.19149 c 1.42964,5.26854 4.21348,40.89938 3.86495,49.46809 l -0.32454,7.97872 -6.91489,1.70857 c -11.71067,2.89354 -16.85673,3.0758 -26.92535,0.95362 l 0,0 z"
+ id="path23" />
+ </g>
+ <g
+ id="shipBottom"
+ class="spaceship">
+ <path
+ style="fill:#008000;fill-opacity:0.93984112;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 244.48826,894.22212 c -4.2024,-0.66031 -8.30588,-1.6713 -9.34259,-2.30176 -1.50562,-0.91562 -2.96927,-3.83924 -5.28678,-10.56029 -3.38846,-9.8269 -6.66033,-24.37913 -5.69774,-25.34172 0.34613,-0.34613 1.65904,0.0304 4.83607,1.387 l 4.36096,1.86212 8.04349,-0.30495 c 4.42393,-0.16772 9.30427,-0.48845 10.84522,-0.71273 1.54095,-0.22428 5.51724,-0.5933 8.83621,-0.82003 3.31896,-0.22673 6.77423,-0.53583 7.67837,-0.68688 l 1.64389,-0.27464 -0.27403,1.65891 c -1.72541,10.44502 -5.37775,23.19669 -9.194,32.09965 l -0.81901,1.91067 -5.12106,0.9443 c -5.68087,1.04752 -8.8862,1.39534 -10.509,1.14035 z"
+ id="path26" />
+ </g>
+ <g
+ id="shipLtWing"
+ class="spaceship">
+ <path
+ style="fill:#ff0000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 207.75862,910.1208 1.2931,-9.48276 3.44828,-6.46552 4.31034,-6.89655 5.17242,-6.03448 4.31034,-2.58621 1.72414,-1.2931 3.87931,12.06896 0.43104,1.72414"
+ id="path29" />
+ </g>
+ <g
+ id="shipRtWing"
+ class="spaceship">
+ <path
+ style="fill:#ff0000;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 262.06896,892.44839 3.01724,-12.5 9.05172,5.17241 5.17242,6.46552 2.15517,4.74138 3.44827,8.18965 2.58621,10.34483 -8.18965,-9.91379 -6.03449,-5.17242 -4.74138,-3.44827 -6.46551,-3.87931 z"
+ id="path32" />
+ </g>
+ <g
+ id="shipCone"
+ class="spaceship">
+ <g
+ id="g3822">
+ <path
+ style="fill:#ffff00;fill-opacity:0.93984112;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 238.05674,793.18103 c -6.10246,-0.52204 -8.42268,-0.87219 -8.56122,-1.29204 -0.10453,-0.31675 0.30123,-1.48054 0.90169,-2.5862 0.60047,-1.10566 1.46952,-3.46503 1.93123,-5.24305 1.03163,-3.97271 6.17659,-18.26477 6.64632,-18.46264 0.1876,-0.079 0.34109,-0.38714 0.34109,-0.68471 0,-1.96184 7.19772,-16.19748 8.18965,-16.19748 0.56862,0 3.86104,5.678 5.49864,9.48276 2.06526,4.7984 7.19953,18.13611 8.29619,21.55173 4.18191,13.02476 4.23136,13.3315 2.15345,13.35671 -1.19212,0.0144 -10.09252,0.40818 -13.57759,0.60062 -1.89655,0.10473 -7.2153,-0.13184 -11.81945,-0.5257 l 0,0 z"
+ id="path3814" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 247.84482,749.34494 c -0.43103,-9.91379 -0.43103,-9.91379 -0.43103,-9.91379 l 0,0.43103"
+ id="path3820" />
+ </g>
+ </g>
+ <g
+ id="shipLtJet"
+ class="spaceship">
+ <path
+ style="fill:#800080;fill-opacity:0.93984112;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 235.50249,906.17356 c 0,-1.06703 4.59976,-12.40994 5.03247,-12.40994 0.74921,0 3.52178,11.5796 2.85187,11.91094 -1.14852,0.56809 -7.88434,0.9944 -7.88434,0.499 z"
+ id="path39" />
+ </g>
+ <g
+ id="shipRtJet"
+ class="spaceship">
+ <path
+ style="fill:#800080;fill-opacity:0.93984112;stroke:#000000;stroke-width:2.81490302;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 252.67238,906.11389 c -1.35952,-0.18394 -1.44042,-0.348 -1.11133,-2.25333 0.1952,-1.1302 0.82906,-3.53453 1.40857,-5.34296 l 1.05363,-3.28807 1.72233,4.60998 c 0.9473,2.53547 1.8799,5.05611 2.07247,5.60139 0.31242,0.88465 0.13311,0.98497 -1.66464,0.93143 -1.10813,-0.033 -2.67459,-0.1493 -3.48103,-0.25844 z"
+ id="path42" />
+ </g>
+ </g>
+ <g
+ transform="translate(-171.5,206.5)"
+ id="shipFire1"
+ class="spaceship">
+ <path
+ id="path3024"
+ d="m 213.07446,821.01373 0,-15 20,0 20,0 0,15 0,15 -20,0 -20,0 0,-15 z"
+ style="fill:#fefefd" />
+ <path
+ id="path3022"
+ d="m 242.07446,835.28173 c -3.61556,-0.66474 -4.70548,-1.87312 -5.45964,-6.05304 -2.27423,-12.60493 -1.42549,-20.52872 2.31719,-21.6331 1.32002,-0.38951 6.93368,-0.22942 11.39245,0.3249 0.4125,0.0513 0.75,1.64168 0.75,3.53422 0,1.89254 0.45,3.7191 1,4.05902 2.54527,1.57306 0.0351,18.5 -2.74348,18.5 -0.69109,0 -1.25652,0.45 -1.25652,1 0,1.01912 -1.54039,1.08792 -6,0.268 z m -21.75,-0.93028 c -0.6875,-0.27741 -1.25689,-1.25439 -1.26531,-2.17105 -0.0124,-1.35224 -0.18204,-1.40336 -0.89908,-0.27095 -0.50392,0.79583 -1.59909,1.12122 -2.54807,0.75706 -1.94705,-0.74715 -1.12949,-2.65278 1.13811,-2.65278 1.15603,0 1.37715,-0.5801 0.85766,-2.25 -2.33632,-7.51012 -1.67256,-19.75 1.07102,-19.75 0.83254,0 1.23559,-0.45 0.89567,-1 -0.87696,-1.41896 2.8546,-1.2454 4.3,0.2 0.93333,0.93333 1.46667,0.93333 2.4,0 1.58906,-1.58906 5.28176,-1.52936 6.6401,0.10734 1.42636,1.71865 1.17235,25.91644 -0.28266,26.92735 -1.17512,0.81645 -10.34907,0.89325 -12.30744,0.10303 z"
+ style="fill:#fdfbf4" />
+ <path
+ id="path3020"
+ d="m 243.63248,835.10761 c -0.30801,-0.49837 -1.3785,-0.69208 -2.37887,-0.43048 -2.77871,0.72665 -3.72489,-1.36607 -5.04726,-11.1634 -2.04821,-15.17496 -0.0992,-17.37091 13.86811,-15.625 0.55,0.0688 1,1.925 1,4.125 0,2.2 0.45,4 1,4 0.55445,0 1,2.64699 1,5.94098 0,3.26754 -0.45,6.2191 -1,6.55902 -0.55,0.33992 -1,1.39147 -1,2.33678 0,3.26484 -5.95123,6.66918 -7.44198,4.2571 z m -22.74632,-1.31683 c -4.37516,-3.39748 -6.23457,-22.53224 -2.45791,-25.2938 0.88832,-0.64955 1.32212,-1.47401 0.964,-1.83213 -0.35812,-0.35811 0.23388,-0.65112 1.31554,-0.65112 1.08167,0 2.41295,0.44628 2.95841,0.99174 0.65566,0.65566 2.0518,0.59162 4.11984,-0.18897 5.54377,-2.09255 6.17944,-0.58472 6.01373,14.26467 -0.11976,10.73113 -0.40636,12.99629 -1.68481,13.31597 -3.61444,0.9038 -9.7078,0.57475 -11.2288,-0.60636 z"
+ style="fill:#fef4f3" />
+ <path
+ id="path3018"
+ d="m 244.07446,834.94634 c 0,-0.58706 -0.83647,-0.8019 -1.85882,-0.47742 -2.45124,0.778 -4.46558,-1.75044 -4.35975,-5.47246 0.0461,-1.62139 -0.33587,-3.20735 -0.84881,-3.52437 -0.51294,-0.31702 -0.93262,-3.69984 -0.93262,-7.51738 0,-5.70987 0.37113,-7.31211 2.09245,-9.03343 1.38572,-1.38572 2.82118,-1.89697 4.25,-1.51366 1.18665,0.31834 3.62005,0.58495 5.40755,0.59246 3.11458,0.0131 3.25,0.17786 3.25,3.95463 0,2.16754 0.45,4.2191 1,4.55902 2.55736,1.58053 0.26642,14.37644 -3.19334,17.8362 -1.86559,1.86559 -4.80666,2.23052 -4.80666,0.59641 z m -23.25021,-1.32568 c -1.57289,-1.57289 -3.54882,-8.77472 -3.87044,-14.10693 -0.37645,-6.24113 0.18337,-9.26629 2.13011,-11.51091 1.80021,-2.07566 2.26525,-2.18003 4.46591,-1.00227 1.95295,1.04519 2.76106,1.06185 3.94255,0.0813 1.957,-1.62417 5.3134,-0.49003 6.12591,2.06997 0.35537,1.11968 0.33438,3.68417 -0.0466,5.69885 -0.38103,2.01468 -0.67234,7.15056 -0.64735,11.41306 0.025,4.2625 -0.0435,7.77018 -0.1522,7.79485 -0.1087,0.0247 -2.49663,0.28103 -5.30652,0.56969 -3.79428,0.38978 -5.50321,0.13051 -6.64132,-1.00761 z"
+ style="fill:#fdf4eb" />
+ <path
+ id="path3016"
+ d="m 244.07446,834.94634 c 0,-0.58706 -0.83647,-0.8019 -1.85882,-0.47742 -3.38388,1.074 -4.23225,-1.44367 -5.76062,-17.09567 -0.53162,-5.44427 -0.34995,-6.39014 1.60237,-8.34245 1.47838,-1.47838 2.91097,-2.01178 4.35952,-1.62318 1.18665,0.31834 3.62005,0.58495 5.40755,0.59246 3.11458,0.0131 3.25,0.17786 3.25,3.95463 0,2.16754 0.45,4.2191 1,4.55902 0.55,0.33992 1,2.81492 1,5.5 0,2.68508 -0.45,5.16008 -1,5.5 -0.55,0.33992 -1.01497,1.37898 -1.03327,2.30902 -0.0711,3.61539 -6.96673,8.68668 -6.96673,5.12359 z m -22.64106,-0.66363 c -1.91418,-1.29 -4.35894,-11.2719 -4.35894,-17.79747 0,-4.73983 0.46465,-6.70124 2.00946,-8.48242 1.77348,-2.04484 2.28725,-2.16825 4.375,-1.05093 1.76257,0.94331 2.88873,0.986 4.4181,0.16751 1.1289,-0.60417 2.72536,-0.84032 3.54768,-0.52477 1.72841,0.66326 2.91023,3.18863 2.10325,4.49435 -0.30414,0.49212 -0.57989,5.85151 -0.61276,11.90975 -0.0329,6.05825 -0.12298,11.03518 -0.20025,11.05985 -1.91464,0.61129 -10.45528,0.78097 -11.28154,0.22413 z"
+ style="fill:#fde9e8" />
+ <path
+ id="path3014"
+ d="m 244.57446,835.01373 c -0.33992,-0.55 -1.47564,-1 -2.52383,-1 -1.97232,0 -4.2255,-3.08944 -3.83717,-5.26131 0.12181,-0.68128 -0.36745,-3.1064 -1.08723,-5.38916 -1.49453,-4.73979 -0.72255,-12.54794 1.41606,-14.32284 0.76462,-0.63457 3.72517,-1.00206 6.70099,-0.83176 5.29729,0.30313 5.33322,0.32732 5.65248,3.80507 0.17671,1.925 0.73921,3.9275 1.25,4.45 1.2472,1.2758 1.18916,10.271 -0.0713,11.05 -0.55,0.33992 -1.01497,1.37898 -1.03327,2.30902 -0.0389,1.97564 -3.31937,6.19098 -4.81801,6.19098 -0.56688,0 -1.3088,-0.45 -1.64872,-1 z m -22.84924,-1.35207 c -1.97934,-1.56449 -4.65076,-11.41412 -4.65076,-17.14754 0,-6.75939 3.72786,-12.41603 6.42573,-9.75039 0.41749,0.4125 2.62999,0.75 4.91667,0.75 l 4.1576,0 0,12.33739 c 0,6.78557 -0.225,12.68061 -0.5,13.10011 -0.8974,1.36892 -8.82744,1.91328 -10.34924,0.71043 z"
+ style="fill:#fce7d8" />
+ <path
+ id="path3012"
+ d="m 244.57446,835.01373 c -0.33992,-0.55 -1.46492,-1 -2.5,-1 -2.41107,0 -3.39583,-1.62821 -3.62887,-6 -0.10262,-1.925 -0.64182,-5.23675 -1.19822,-7.35943 -1.16711,-4.45251 -0.49978,-10.1244 1.37416,-11.67963 0.70982,-0.5891 3.68961,-0.93381 6.62175,-0.76601 5.29729,0.30313 5.33322,0.32732 5.65248,3.80507 0.17671,1.925 0.73921,3.9275 1.25,4.45 1.62476,1.66202 0.89746,9.87212 -1.15604,13.05 -1.06621,1.65 -2.2108,3.7875 -2.54354,4.75 -0.66038,1.91026 -2.88796,2.34176 -3.87172,0.75 z m -22.70147,-1.09287 c -2.10735,-1.17933 -5.26736,-16.59451 -4.37589,-21.34647 0.37824,-2.01617 1.33529,-3.91428 2.12679,-4.218 0.7915,-0.30373 1.14285,-1.03155 0.78078,-1.61738 -0.44012,-0.71214 -0.0239,-0.78737 1.25575,-0.22698 1.05272,0.46099 3.93904,0.87497 6.41404,0.91994 l 4.5,0.0818 0,12.33679 c 0,6.78523 -0.225,12.68028 -0.5,13.1001 -0.78115,1.19253 -8.49355,1.92604 -10.20147,0.97024 z"
+ style="fill:#fcd8d7" />
+ <path
+ id="path3010"
+ d="m 242.57446,833.95903 c -3.20603,-2.03958 -4.16764,-5.04031 -5.16057,-16.10371 -0.72246,-8.04973 0.49024,-9.84159 6.66057,-9.84159 5.32878,0 7,1.49636 7,6.26759 0,1.31949 0.3116,2.71067 0.69244,3.09151 2.0309,2.03091 0.53343,11.77013 -2.17427,14.1409 -0.62816,0.55 -1.4376,1.7875 -1.79876,2.75 -0.80647,2.1493 -1.41806,2.11359 -5.21941,-0.3047 z m -21.40349,-1.32901 c -2.16359,-2.60697 -4.21239,-16.47222 -3.06414,-20.73651 0.5746,-2.13388 1.50393,-3.87978 2.06519,-3.87978 0.56126,0 0.74236,-0.45 0.40244,-1 -0.33992,-0.55 -0.16803,-1 0.38197,-1 0.55,0 1.30476,0.49312 1.67725,1.09581 0.42872,0.69369 2.27301,0.85652 5.02583,0.44371 4.00954,-0.60127 4.39578,-0.4641 4.95383,1.75938 0.33289,1.32633 0.17976,5.51416 -0.34028,9.3063 -0.52004,3.79214 -0.71908,8.40715 -0.4423,10.25559 0.33321,2.22535 0.0371,3.65603 -0.87654,4.23468 -2.15612,1.36563 -8.51049,1.05439 -9.78325,-0.47918 z"
+ style="fill:#fcd5ca" />
+ <path
+ id="path3008"
+ d="m 243.68265,834.51799 c -1.0405,-0.78767 -2.33516,-1.57991 -2.87702,-1.76054 -0.54187,-0.18062 -1.41387,-2.55935 -1.93778,-5.28606 -3.0569,-15.90966 -1.92574,-19.54051 5.94911,-19.09566 4.63102,0.2616 4.78408,0.37335 5.7575,4.20337 0.55,2.16405 1.25034,4.38463 1.5563,4.93463 0.93611,1.68273 1.17286,7.75954 0.28091,7.21035 -0.46047,-0.28352 -0.94017,0.89999 -1.06601,2.63002 -0.12585,1.73002 -0.71743,3.30837 -1.31463,3.50744 -0.5972,0.19907 -1.4956,1.43975 -1.99644,2.75706 -1.04556,2.75002 -1.7225,2.88992 -4.35194,0.89939 z m -23.21506,-4.10579 c -0.82765,-1.98085 -1.76416,-7.27639 -2.08112,-11.76788 -0.69109,-9.79271 0.0645,-10.82627 8.1771,-11.18559 6.36395,-0.28187 6.33231,-0.34421 5.34251,10.52779 -0.37691,4.13996 -0.4504,8.95097 -0.16332,10.69111 0.6047,3.66532 -1.47859,5.3361 -6.65359,5.3361 -2.63353,0 -3.35007,-0.55839 -4.62158,-3.60153 z"
+ style="fill:#fcc9c7" />
+ <path
+ id="path3006"
+ d="m 242.82446,833.6902 c -1.61209,-1.31992 -2.76466,-3.27052 -2.78544,-4.71403 -0.0195,-1.35434 -0.67854,-3.58744 -1.46456,-4.96244 -1.78022,-3.11416 -1.88229,-9.68857 -0.20184,-13 1.05742,-2.08371 1.98633,-2.5 5.57849,-2.5 2.3704,0 4.64398,0.225 5.0524,0.5 0.77148,0.51946 4.08252,12.93329 4.05564,15.20552 -0.0109,0.92215 -0.29413,0.86304 -0.98469,-0.20552 -0.72513,-1.12206 -0.97323,-0.59421 -0.98469,2.09501 -0.01,2.31035 -0.73,4.2418 -2.01531,5.40499 -1.1,0.99549 -2,2.41523 -2,3.15499 0,1.87693 -1.06079,1.6327 -4.25,-0.97852 z m -21.53193,-1.30802 c -1.46348,-2.79289 -3.21807,-11.89557 -3.21807,-16.69516 0,-6.48241 1.72588,-8.19989 8.13495,-8.09535 l 5.36505,0.0875 -0.22431,12.30825 c -0.12337,6.76954 -0.4237,12.50765 -0.66741,12.75135 -0.24371,0.24371 -2.23591,0.68357 -4.42712,0.97748 -3.21272,0.43091 -4.17356,0.17264 -4.96309,-1.33408 z"
+ style="fill:#fcc5ba" />
+ <path
+ id="path3004"
+ d="m 242.72748,833.17345 c -1.45916,-1.52303 -2.65302,-3.77287 -2.65302,-4.99962 0,-1.22676 -0.71048,-3.3148 -1.57885,-4.6401 -1.21102,-1.84824 -1.41802,-3.69689 -0.88852,-7.93489 0.8518,-6.81759 1.87668,-7.75237 7.45543,-6.80001 4.33601,0.74022 4.33744,0.74189 6.17057,7.22764 2.11406,7.4797 2.20996,8.3331 0.84137,7.48726 -0.5944,-0.36736 -1,0.81122 -1,2.9058 0,2.50038 -0.58088,3.83471 -2,4.5942 -1.1,0.5887 -2,1.70298 -2,2.47617 0,2.59556 -1.67384,2.47371 -4.34698,-0.31645 z m -21.75005,-1.90972 c -0.57613,-1.5125 -1.56141,-6.27033 -2.18949,-10.57295 -0.9585,-6.56609 -0.90464,-8.24579 0.33523,-10.45476 1.29461,-2.30651 2.12301,-2.6374 6.70205,-2.67705 3.65715,-0.0317 5.39105,0.38694 5.77872,1.39515 0.30463,0.79221 0.24376,6.34107 -0.13525,12.3308 -0.65213,10.306 -0.81885,10.93975 -3.10677,11.80962 -4.21264,1.60164 -6.27144,1.09121 -7.38449,-1.83081 z"
+ style="fill:#fcc7ab" />
+ <path
+ id="path3002"
+ d="m 242.72748,833.17345 c -1.45916,-1.52303 -2.65302,-3.78662 -2.65302,-5.03018 0,-1.24356 -0.50847,-3.21112 -1.12994,-4.37234 -1.56807,-2.92996 -1.34949,-12.70635 0.32145,-14.37728 0.98111,-0.98111 2.56078,-1.1472 5.74345,-0.60388 l 4.39011,0.74945 1.83356,6.48725 c 2.11406,7.4797 2.20996,8.3331 0.84137,7.48726 -0.5944,-0.36736 -1,0.81122 -1,2.9058 0,2.50038 -0.58088,3.83471 -2,4.5942 -1.1,0.5887 -2,1.70298 -2,2.47617 0,2.59556 -1.67384,2.47371 -4.34698,-0.31645 z m -21.16934,-0.40972 c -1.00952,-2.78225 -3.48368,-16.06654 -3.48368,-18.70459 0,-1.55311 0.81514,-3.8305 1.81143,-5.06086 1.59417,-1.96872 2.06504,-2.07864 3.92591,-0.91651 1.63188,1.01913 2.68278,1.06157 4.6045,0.18598 3.50792,-1.59832 3.87749,-0.0223 3.05239,13.01717 -0.65213,10.306 -0.81885,10.93975 -3.10677,11.80962 -3.38037,1.28521 -6.26837,1.14479 -6.80378,-0.33081 z"
+ style="fill:#fcbab6" />
+ <path
+ id="path3000"
+ d="m 242.73813,833.03845 c -4.45265,-4.50136 -6.26388,-22.81295 -2.40301,-24.2945 0.70285,-0.26971 3.01297,-0.20685 5.1336,0.1397 3.80086,0.62112 3.88065,0.72606 5.61127,7.38008 1.5237,5.8584 1.55892,6.75 0.26662,6.75 -1.07585,0 -1.32041,0.67158 -0.88145,2.42054 0.75665,3.01474 -0.16163,5.57946 -1.99769,5.57946 -0.76616,0 -1.39301,0.9 -1.39301,2 0,2.47359 -1.90323,2.48443 -4.33633,0.0247 z m -20.53807,-0.37338 c -1.73818,-2.09438 -4.37739,-16.49565 -3.69229,-20.14755 0.79299,-4.22701 2.99091,-6.22653 5.00602,-4.55414 0.79163,0.657 2.92913,1.0496 4.75,0.87244 l 3.31067,-0.32209 -0.34477,11 c -0.20547,6.55563 -0.81152,11.45488 -1.5,12.12585 -1.93738,1.8881 -6.31852,2.48479 -7.52963,1.02549 z"
+ style="fill:#fbb5a7" />
+ <path
+ id="path2998"
+ d="m 242.74941,832.85535 c -1.00378,-1.09545 -2.07693,-3.54387 -2.38478,-5.44095 -0.30786,-1.89708 -0.94908,-3.68987 -1.42495,-3.98397 -0.98296,-0.6075 -1.18061,-10.43123 -0.25823,-12.83491 0.43906,-1.14417 1.9607,-1.58179 5.5,-1.58179 2.69115,0 4.89301,0.11393 4.89301,0.25318 0,0.13925 0.87979,3.32964 1.95508,7.08976 1.63533,5.71845 1.7122,6.74336 0.47002,6.26669 -1.16731,-0.44794 -1.43336,0.19801 -1.24339,3.01886 0.1645,2.4426 -0.30498,3.98848 -1.47001,4.84037 -0.94143,0.68839 -1.7117,1.98952 -1.7117,2.89138 0,2.18799 -2.07266,1.93946 -4.32505,-0.51862 z m -20.55781,-0.20048 c -1.4948,-1.80112 -3.11714,-10.71274 -3.11714,-17.12264 0,-3.84785 0.49654,-5.65789 1.90072,-6.92866 1.33134,-1.20484 2.1105,-1.38071 2.60099,-0.58707 0.38515,0.62319 2.34233,0.99695 4.34928,0.83059 l 3.64901,-0.30248 -0.34477,10.98456 c -0.20539,6.54387 -0.81179,11.4397 -1.5,12.11041 -1.94466,1.8952 -6.31888,2.48436 -7.53809,1.01529 z"
+ style="fill:#fac58e" />
+ <path
+ id="path2996"
+ d="m 242.83096,832.93689 c -2.94316,-3.22449 -5.60815,-16.3938 -4.34,-21.4465 0.5574,-2.22086 1.13605,-2.47666 5.60255,-2.47666 2.73952,0 4.98095,0.11393 4.98095,0.25318 0,0.13925 0.87979,3.32964 1.95508,7.08976 1.63533,5.71845 1.7122,6.74336 0.47002,6.26669 -1.16731,-0.44794 -1.43336,0.19801 -1.24339,3.01886 0.1645,2.4426 -0.30498,3.98848 -1.47001,4.84037 -0.94143,0.68839 -1.7117,1.98952 -1.7117,2.89138 0,2.1614 -2.06598,1.94861 -4.2435,-0.43708 z m -20.63936,-0.28202 c -1.47885,-1.7819 -3.11714,-10.68981 -3.11714,-16.94889 0,-6.60802 1.99523,-9.09493 5.73865,-7.15281 1.76179,0.91402 3.1716,1.04377 4.37036,0.40222 1.04167,-0.55749 1.99888,-0.57611 2.32696,-0.0453 0.95894,1.55161 -0.68277,22.06632 -1.83817,22.9696 -2.18264,1.70635 -6.3495,2.13812 -7.48066,0.77515 z"
+ style="fill:#fbaaa7" />
+ <path
+ id="path2994"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.0515,-6.01599 1.33352,-7.68426 6.37947,-7.68426 l 4.34174,0 1.57906,6.25 c 0.93854,3.71477 1.19128,6.38521 0.62307,6.58333 -0.52579,0.18334 -0.95599,2.08 -0.95599,4.21482 0,2.90633 -0.52195,4.16082 -2.07756,4.99336 -1.18986,0.63679 -1.84419,1.72003 -1.53138,2.53518 0.75202,1.95974 -0.51507,1.68385 -2.78464,-0.60632 z m -22.50743,-2.65246 c -0.67213,-1.47516 -1.48641,-6.42813 -1.80952,-11.00662 -0.50391,-7.14044 -0.33132,-8.60756 1.21332,-10.31438 1.398,-1.54476 2.11011,-1.73314 3.18364,-0.84218 0.76057,0.63121 2.7832,1.10784 4.49474,1.05918 l 3.1119,-0.0885 -0.67703,11.14712 c -0.71175,11.71885 -1.14547,12.68517 -5.70553,12.71214 -1.84671,0.0109 -2.94001,-0.75403 -3.81152,-2.66678 z"
+ style="fill:#fbb49a" />
+ <path
+ id="path2992"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.052,-6.07612 1.23838,-7.55975 6.40123,-7.35994 l 4.44502,0.17203 1.51654,6.00183 c 0.90536,3.58303 1.13127,6.13616 0.56055,6.33515 -0.52579,0.18334 -0.95599,1.98759 -0.95599,4.00946 0,2.64232 -0.58597,4.04206 -2.08368,4.9774 -1.18202,0.73818 -1.84469,1.92409 -1.53139,2.74055 0.75759,1.97424 -0.50224,1.70656 -2.77851,-0.59037 z m -22.4942,-3.07829 c -0.59588,-1.70936 -1.38003,-6.66446 -1.74254,-11.01134 -0.56917,-6.82476 -0.41058,-8.17807 1.16197,-9.91572 1.22799,-1.3569 2.04728,-1.64633 2.51555,-0.88865 0.38194,0.61799 2.39249,1.12363 4.46789,1.12363 l 3.77345,0 -0.67477,11.10983 c -0.71119,11.70969 -1.1381,12.64814 -5.76595,12.67486 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z"
+ style="fill:#facb7b" />
+ <path
+ id="path2990"
+ d="m 243.68088,832.9841 c -2.46917,-2.49159 -5.53233,-11.44188 -5.57377,-16.28611 -0.052,-6.07612 1.23838,-7.55975 6.40123,-7.35994 l 4.44502,0.17203 1.51654,6.00183 c 0.90536,3.58303 1.13127,6.13616 0.56055,6.33515 -0.52579,0.18334 -0.95599,1.98759 -0.95599,4.00946 0,2.64232 -0.58597,4.04206 -2.08368,4.9774 -1.18202,0.73818 -1.84469,1.92409 -1.53139,2.74055 0.75759,1.97424 -0.50224,1.70656 -2.77851,-0.59037 z m -22.4942,-3.07829 c -0.59588,-1.70936 -1.38003,-6.66446 -1.74254,-11.01134 -0.56214,-6.74048 -0.40015,-8.18959 1.10089,-9.84822 1.56882,-1.73353 1.92387,-1.78093 3.26843,-0.43637 1.04108,1.04107 2.4483,1.30199 4.54198,0.84214 l 3.03355,-0.66628 -0.68776,11.32382 c -0.72485,11.93451 -1.14074,12.86208 -5.77895,12.88886 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z"
+ style="fill:#fba597" />
+ <path
+ id="path2988"
+ d="m 221.18668,829.90581 c -1.93432,-5.5488 -2.47791,-18.15014 -0.87433,-20.26869 1.20398,-1.59064 1.76544,-1.69198 3.68442,-0.66497 1.24518,0.6664 3.41269,0.92333 4.81668,0.57095 l 2.55271,-0.64069 -0.71434,11.28897 c -0.75006,11.85366 -1.16479,12.78068 -5.72954,12.80704 -2.07448,0.012 -2.88816,-0.66165 -3.7356,-3.09261 z m 22.21513,2.33139 c -3.55171,-2.25917 -6.28879,-19.66203 -3.5268,-22.42402 0.48123,-0.48123 2.70741,-0.58195 4.94705,-0.22382 3.78933,0.60594 4.14652,0.9468 5.14421,4.90901 0.58968,2.34182 1.38173,5.06461 1.76011,6.05065 0.44754,1.16629 0.30896,1.55857 -0.39657,1.12252 -1.47691,-0.91278 -2.08921,1.1788 -1.49071,5.09219 0.39191,2.56254 0.14544,3.25 -1.16518,3.25 -0.91423,0 -1.92125,0.675 -2.23783,1.5 -0.64031,1.66861 -1.30082,1.8261 -3.03428,0.72347 z"
+ style="fill:#fba78a" />
+ <path
+ id="path2986"
+ d="m 221.30293,829.26373 c -1.57713,-5.43533 -2.5527,-14.82202 -1.8369,-17.67401 0.57224,-2.27998 1.02934,-2.44619 6.23753,-2.26813 l 5.62004,0.19214 -0.69305,10.98331 c -0.72599,11.50515 -1.16409,12.47489 -5.6478,12.50138 -2.13974,0.0126 -2.78147,-0.63866 -3.67982,-3.73469 z m 22.11621,2.98418 c -0.63543,-0.40435 -2.10648,-3.55865 -3.26901,-7.00955 -2.51688,-7.47126 -1.88001,-15.78981 1.1975,-15.6413 7.7497,0.37399 7.4344,0.19825 8.59009,4.78792 0.60538,2.40418 1.41028,5.178 1.78866,6.16404 0.45172,1.17717 0.31093,1.55979 -0.40999,1.11423 -1.36162,-0.84153 -2.51515,2.47491 -1.64738,4.73629 0.41694,1.08651 -0.29,2.52937 -2.02884,4.14088 -3.03005,2.80815 -2.70074,2.67493 -4.22103,1.70749 z"
+ style="fill:#fb9996" />
+ <path
+ id="path2984"
+ d="m 221.62624,829.7919 c -1.76556,-4.22558 -2.98504,-17.79554 -1.75988,-19.58342 0.65198,-0.95144 2.30216,-1.1185 6.08784,-0.61632 l 5.19341,0.68894 -0.65991,10.11631 c -0.36295,5.56398 -0.94191,10.42198 -1.28657,10.79556 -0.34467,0.37358 -1.8665,0.98545 -3.38186,1.35971 -2.45245,0.6057 -2.91317,0.30235 -4.19303,-2.76078 z m 21.62804,1.93428 c -2.58899,-3.13045 -5.1869,-12.32814 -4.60314,-16.29701 0.86081,-5.85235 1.39869,-6.36256 6.04992,-5.7387 3.90839,0.52423 4.13392,0.74924 5.13477,5.12293 0.64943,2.83802 0.70299,5.47897 0.14109,6.95688 -0.49815,1.31023 -0.65676,3.37421 -0.35247,4.58662 0.70357,2.80324 -4.71508,7.37051 -6.37017,5.36928 z"
+ style="fill:#fa9787" />
+ <path
+ id="path2982"
+ d="m 222.27764,831.35152 c -0.52864,-1.01079 -1.5183,-5.81903 -2.19925,-10.68499 -1.52422,-10.89173 -0.88679,-12.00968 6.28694,-11.02641 l 4.70142,0.6444 -0.62383,10.11461 c -0.34312,5.56303 -0.90388,10.42026 -1.24615,10.79384 -0.34227,0.37358 -1.82284,0.97558 -3.29015,1.33778 -2.01233,0.49674 -2.90399,0.207 -3.62898,-1.17923 z m 20.13064,-1.08779 c -0.33188,-0.9625 -1.39356,-3.6085 -2.3593,-5.88 -1.89406,-4.45498 -1.65955,-12.55659 0.41327,-14.27687 0.62221,-0.51639 2.67297,-0.62358 4.55724,-0.23821 4.18109,0.85513 5.13433,3.53546 4.65376,13.08549 -0.25668,5.10092 -0.69352,6.63149 -1.96444,6.88291 -0.89889,0.17783 -1.63435,0.74033 -1.63435,1.25 0,1.65938 -3.04599,0.97533 -3.66618,-0.82332 z"
+ style="fill:#faa96f" />
+ <path
+ id="path2980"
+ d="m 222.27764,831.35152 c -0.52864,-1.01079 -1.51335,-5.78416 -2.18825,-10.6075 -1.41648,-10.12316 -0.61986,-12.39505 3.91087,-11.1534 1.41581,0.388 3.58864,0.64681 4.82851,0.57513 2.2392,-0.12946 2.25007,-0.0617 1.62231,10.10883 -0.3476,5.63153 -0.91204,10.54481 -1.25431,10.91839 -0.34227,0.37358 -1.82284,0.97558 -3.29015,1.33778 -2.01233,0.49674 -2.90399,0.207 -3.62898,-1.17923 z m 20.10725,-1.08779 c -0.34474,-0.9625 -1.38391,-3.775 -2.30926,-6.25 -2.75945,-7.3806 -0.64783,-16.8259 3.20502,-14.33609 0.7116,0.45985 2.15925,0.83609 3.21701,0.83609 2.55245,0 3.59591,4.08776 3.17559,12.44041 -0.25668,5.10092 -0.69352,6.63149 -1.96444,6.88291 -0.89889,0.17783 -1.63435,0.74033 -1.63435,1.25 0,1.6564 -3.04476,0.97696 -3.68957,-0.82332 z"
+ style="fill:#fa947a" />
+ <path
+ id="path2978"
+ d="m 222.66421,832.15894 c -0.34565,-0.55926 -1.25123,-5.2066 -2.01241,-10.32743 -1.61694,-10.87789 -0.9927,-13.23232 3.21267,-12.11721 1.49049,0.39522 3.72162,0.67194 4.95807,0.61492 2.22878,-0.10279 2.24271,-0.0166 1.62231,10.04042 -0.34418,5.57925 -0.90581,10.44975 -1.24808,10.82333 -1.17568,1.28323 -5.90434,1.98246 -6.53256,0.96597 z m 19.89554,-1.39521 c -2.76058,-7.63527 -3.48529,-10.70299 -3.48529,-14.75328 0,-4.50991 1.80223,-7.86115 3.3794,-6.28399 0.38246,0.38246 1.88374,0.71606 3.33618,0.74133 2.06745,0.036 2.81953,0.69727 3.46406,3.04594 1.25136,4.56001 -0.12178,14.69032 -2.27042,16.75 -2.14711,2.05821 -3.79329,2.24426 -4.42393,0.5 z"
+ style="fill:#fa8884" />
+ <path
+ id="path2976"
+ d="m 222.50927,830.90824 c -0.37578,-0.60801 -1.25786,-4.99551 -1.96017,-9.75 -1.47709,-9.99943 -0.80155,-12.51565 3.09742,-11.53707 1.37063,0.34401 3.26513,0.68556 4.21,0.75901 0.94487,0.0734 1.99019,0.58355 2.32295,1.13355 0.69333,1.14599 -0.70968,18.05133 -1.62042,19.52494 -0.82187,1.32981 -5.20572,1.2353 -6.04978,-0.13043 z m 18.63704,-4.43202 c -3.37032,-9.00798 -2.33409,-18.74357 1.7617,-16.55157 0.96226,0.51498 2.58779,0.85821 3.61229,0.76271 2.58412,-0.24087 3.68815,4.3302 2.91039,12.05008 -0.50552,5.01758 -1.07846,6.51949 -2.95645,7.75 -1.28118,0.83946 -2.53791,1.52629 -2.79275,1.52629 -0.25483,0 -1.39566,-2.49188 -2.53518,-5.53751 z"
+ style="fill:#f9af50" />
+ <path
+ id="path2974"
+ d="m 222.14477,829.69866 c -0.4841,-1.27328 -1.18483,-4.98578 -1.55716,-8.25 -0.37234,-3.26421 -0.86723,-6.63354 -1.09975,-7.48739 -0.23253,-0.85385 0.17932,-2.37587 0.91522,-3.38227 1.27959,-1.74995 1.45462,-1.75341 4.00969,-0.0793 2.04558,1.34032 2.99469,1.48251 4.04991,0.60676 1.0452,-0.86744 1.4888,-0.83562 1.83589,0.13171 0.56835,1.58395 -0.91478,18.466 -1.73952,19.80046 -1.20642,1.95202 -5.504,1.05422 -6.41428,-1.34001 z m 19.00154,-3.22244 c -3.37032,-9.00798 -2.33409,-18.74357 1.7617,-16.55157 0.96226,0.51498 2.58779,0.85821 3.61229,0.76271 2.58412,-0.24087 3.68815,4.3302 2.91039,12.05008 -0.50552,5.01758 -1.07846,6.51949 -2.95645,7.75 -1.28118,0.83946 -2.53791,1.52629 -2.79275,1.52629 -0.25483,0 -1.39566,-2.49188 -2.53518,-5.53751 z"
+ style="fill:#fa8678" />
+ <path
+ id="path2972"
+ d="m 222.13455,829.67178 c -0.51748,-1.36109 -1.24958,-6.27925 -1.62688,-10.92925 -0.75781,-9.33961 -0.0511,-10.83501 3.89764,-8.24767 1.31304,0.86033 3.12575,1.28089 4.02824,0.93457 1.41077,-0.54137 1.63051,0.19177 1.56679,5.22731 -0.0408,3.22135 -0.37827,7.88199 -0.75,10.35699 -0.59575,3.9665 -1.00185,4.53751 -3.4254,4.81638 -2.15645,0.24813 -2.95245,-0.21741 -3.69039,-2.15833 z m 21.21124,1.06386 c -2.61671,-3.44941 -4.3414,-10.713 -3.69705,-15.5703 l 0.66804,-5.03598 3.89064,0.15515 c 3.48771,0.13908 3.98352,0.49155 4.78753,3.40341 0.49328,1.78655 0.66045,5.85322 0.37148,9.03704 -0.40707,4.485 -1.03985,6.17659 -2.80956,7.51068 -1.75742,1.32483 -2.4979,1.44013 -3.21108,0.5 z"
+ style="fill:#fa7974" />
+ <path
+ id="path2970"
+ d="m 223.91904,831.34262 c -2.03067,-0.53865 -2.56772,-2.56289 -3.43265,-12.93826 -0.749,-8.98473 -0.007,-10.48197 3.91892,-7.9095 1.31304,0.86033 3.09178,1.29392 3.95275,0.96354 1.37808,-0.52882 1.49697,0.57546 0.99348,9.22731 -0.31462,5.40631 -1.068,10.15856 -1.67451,10.56271 -1.16693,0.77757 -1.18043,0.77791 -3.75799,0.0942 z m 17.21699,-5.67718 c -1.71683,-4.23001 -2.02942,-6.41337 -1.49498,-10.44218 l 0.67573,-5.0939 3.89064,0.15515 c 3.50313,0.13969 3.98164,0.48472 4.80431,3.46421 1.26724,4.58956 0.12422,14.46961 -1.84909,15.98321 -2.76378,2.11992 -3.79932,1.42118 -6.02661,-4.06649 z"
+ style="fill:#f9836a" />
+ <path
+ id="path2968"
+ d="m 223.64739,830.4438 c -1.85627,-1.85626 -2.25977,-3.57781 -3.06787,-13.08917 -0.68033,-8.00745 0.0825,-9.31245 3.95897,-6.77251 1.38629,0.90833 3.16123,1.40565 3.94431,1.10516 1.19438,-0.45833 1.33299,1.01428 0.86029,9.14005 -0.63404,10.89904 -2.03975,13.27242 -5.6957,9.61647 z m 17.53808,-4.86292 c -1.53151,-4.09332 -1.88195,-6.70559 -1.42132,-10.59489 0.60375,-5.09769 0.64846,-5.15463 3.58584,-4.56715 1.63596,0.32719 3.31348,0.59489 3.72783,0.59489 1.25296,0 2.66967,7.32604 1.9338,10 -0.3784,1.375 -0.4645,3.5355 -0.19134,4.80111 0.49734,2.30428 -1.8953,5.09883 -4.42397,5.16709 -0.64798,0.0175 -2.09286,-2.41298 -3.21084,-5.40105 z"
+ style="fill:#f97967" />
+ <path
+ id="path2966"
+ d="m 223.11077,829.55749 c -1.55452,-1.8731 -3.30507,-17.675 -2.09239,-18.88768 0.47651,-0.47651 2.47171,-0.27364 4.49143,0.4567 l 3.63405,1.31409 -0.2847,9.03657 c -0.26128,8.29308 -0.45645,9.0611 -2.37221,9.33482 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.08259,-4.70911 -2.34897,-6.354 -1.66736,-10.29583 0.79337,-4.58811 0.88601,-4.68516 4.21056,-4.41078 1.86963,0.15431 3.64809,0.52919 3.95212,0.83307 0.30403,0.30389 0.58197,4.11797 0.61765,8.47574 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f88c4e" />
+ <path
+ id="path2964"
+ d="m 223.11077,829.55749 c -1.62629,-1.95957 -3.30118,-17.67889 -2.02017,-18.9599 0.57281,-0.57281 1.89956,-0.48767 3.45673,0.22183 1.81036,0.82485 2.53147,1.9375 2.54244,3.92287 0.0121,2.18024 0.22786,2.45146 1.0117,1.27144 0.69439,-1.04537 0.91707,0.92469 0.73469,6.5 -0.23718,7.25032 -0.45732,8.02795 -2.34921,8.29826 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.07784,-4.69837 -2.34887,-6.36299 -1.67637,-10.29583 0.79068,-4.62392 0.85194,-4.68641 4.26334,-4.34864 1.90362,0.18848 3.68613,0.56336 3.96113,0.83307 0.275,0.26971 0.52919,4.05583 0.56487,8.4136 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f8a534" />
+ <path
+ id="path2962"
+ d="m 223.11077,829.55749 c -1.31835,-1.58852 -3.34677,-17.23242 -2.42729,-18.72016 1.14947,-1.85987 3.52557,-0.60922 5.09488,2.68167 1.16822,2.44977 1.91966,3.12729 2.49552,2.25 0.45778,-0.69739 0.70767,2.30017 0.56228,6.74473 -0.23718,7.25032 -0.45732,8.02795 -2.34921,8.29826 -1.14812,0.16404 -2.66741,-0.40049 -3.37618,-1.2545 z m 18.41559,-4.0566 c -2.07784,-4.69837 -2.34887,-6.36299 -1.67637,-10.29583 0.79068,-4.62392 0.85194,-4.68641 4.26334,-4.34864 1.90362,0.18848 3.68613,0.56336 3.96113,0.83307 0.275,0.26971 0.52919,4.05583 0.56487,8.4136 0.0593,7.24893 -0.1351,8.05425 -2.28476,9.46276 -2.31265,1.51531 -2.38865,1.45133 -4.82821,-4.06496 z"
+ style="fill:#f97659" />
+ <path
+ id="path2960"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -0.56031,-0.68049 -0.75752,-1.91799 -0.43825,-2.75 1.07196,-2.79347 3.45238,-1.54832 6.10157,3.1916 2.12264,3.79781 2.57269,5.77112 2.3355,10.24028 -0.23013,4.33611 -0.6731,5.60814 -2.04381,5.869 -1.04668,0.19919 -1.75,-0.27931 -1.75,-1.1906 z m 16.96387,-2.97179 c -2.15555,-4.87296 -2.22449,-5.36902 -1.68889,-12.15122 0.29872,-3.78258 0.47649,-3.98174 3.27046,-3.66399 4.42198,0.5029 4.9771,1.61488 4.71073,9.43636 -0.19008,5.58139 -0.67966,7.59556 -2.22083,9.13674 -1.96934,1.96933 -1.98513,1.95864 -4.07147,-2.75789 z"
+ style="fill:#f89936" />
+ <path
+ id="path2958"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -0.56031,-0.68049 -0.75752,-1.91799 -0.43825,-2.75 0.93035,-2.42444 3.58582,-1.74814 4.85806,1.23727 0.64456,1.5125 1.78388,3.48691 2.53182,4.38759 2.0861,2.51209 1.30446,13.2381 -0.99662,13.67602 -1.04668,0.19919 -1.75,-0.27931 -1.75,-1.1906 z m 16.9435,-3.01782 c -2.14558,-4.85044 -2.22191,-5.41701 -1.631,-12.10519 0.25271,-2.86028 0.75717,-3.88974 1.77045,-3.61301 0.77938,0.21284 2.27824,0.47228 3.33081,0.57652 2.70391,0.2678 3.64683,3.66342 2.92774,10.5433 -0.40811,3.9046 -1.25402,6.50903 -2.47214,7.61142 -1.76446,1.59681 -1.94952,1.45478 -3.92586,-3.01304 z m 4.0565,-8.54617 c 0,-1.06754 -0.45,-2.2191 -1,-2.55902 -0.56716,-0.35052 -1,0.48962 -1,1.94098 0,1.40746 0.45,2.55902 1,2.55902 0.55,0 1,-0.87344 1,-1.94098 z"
+ style="fill:#f88838" />
+ <path
+ id="path2956"
+ d="m 225.07446,829.63674 c 0,-0.83799 -0.70014,-1.91545 -1.55587,-2.39434 -1.10154,-0.61645 -1.56676,-2.45604 -1.59314,-6.29969 -0.0205,-2.98594 -0.49569,-5.98575 -1.056,-6.66625 -1.31597,-1.59824 -0.29183,-4.26273 1.63844,-4.26273 1.76019,0 3.56657,3.00556 3.56657,5.93426 0,1.13616 0.5625,1.95324 1.25,1.81574 0.89722,-0.17944 1.25,1.58059 1.25,6.23631 0,5.38237 -0.29784,6.54366 -1.75,6.82332 -1.04842,0.20191 -1.75,-0.27381 -1.75,-1.18662 z m 16.9435,-3.01782 c -1.14075,-2.57888 -2.05392,-5.45754 -2.02925,-6.39703 0.0442,-1.68363 0.77833,-9.28228 0.98141,-10.15816 0.0574,-0.2475 0.64434,0.09 1.30434,0.75 0.66,0.66 2.18252,1.2 3.38337,1.2 2.79309,0 3.52113,2.70677 2.73949,10.1851 -0.39145,3.74518 -1.24893,6.343 -2.4535,7.43313 -1.76446,1.59681 -1.94952,1.45478 -3.92586,-3.01304 z m 4.0565,-7.98275 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f96857" />
+ <path
+ id="path2954"
+ d="m 224.43035,828.2706 c -2.66558,-3.61935 -4.17153,-18.25687 -1.87832,-18.25687 1.73553,0 3.52243,3.04033 3.52243,5.99328 0,1.16861 0.45,1.84664 1,1.50672 0.58985,-0.36455 1.07513,0.94423 1.18318,3.19098 0.45481,9.45699 -0.72168,11.78271 -3.82729,7.56589 z m 17.31261,-3.28329 c -1.95628,-4.43272 -2.12466,-5.73743 -1.23521,-9.57109 0.71036,-3.06172 1.44872,-4.27801 2.38006,-3.92062 0.74262,0.28497 2.16094,0.51813 3.15181,0.51813 2.38322,0 3.09675,3.11426 2.35015,10.25737 -0.44715,4.27809 -1.11132,6.09827 -2.49554,6.83908 -1.64554,0.88067 -2.17523,0.3546 -4.15127,-4.12287 z m 4.3315,-6.35114 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f97448" />
+ <path
+ id="path2952"
+ d="m 224.43035,828.2706 c -2.17337,-2.95101 -4.19764,-18.25687 -2.41456,-18.25687 1.73198,0 4.05867,3.14613 4.05867,5.4881 0,1.28988 0.46287,2.49952 1.0286,2.6881 1.39017,0.46339 1.74167,10.4523 0.41453,11.78012 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.71778,0 0.90684,-1.09078 0.52231,-3.01345 -0.57326,-2.86632 -0.46951,-2.98163 2.125,-2.36174 4.2138,1.00677 4.22769,1.03602 4.22769,8.89902 0,6.41491 -0.27118,7.55093 -2.02673,8.49048 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z m 4.00477,-7.17705 c 0,-1.30765 -0.675,-2.93775 -1.5,-3.62244 -1.28638,-1.0676 -1.5,-0.72901 -1.5,2.37756 0,2.55328 0.44272,3.62244 1.5,3.62244 0.91273,0 1.5,-0.93084 1.5,-2.37756 z"
+ style="fill:#f89426" />
+ <path
+ id="path2950"
+ d="m 224.43035,828.2706 c -1.42701,-1.9376 -2.22355,-5.05998 -2.68038,-10.50687 -0.3575,-4.2625 -0.29574,-7.75 0.13724,-7.75 1.38039,0 3.18725,2.3405 3.18725,4.12857 0,0.95072 0.69195,2.42052 1.53766,3.26624 1.80711,1.8071 2.46952,10.99666 0.90547,12.56151 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.72319,0 0.90496,-1.1002 0.50893,-3.08036 -0.44279,-2.21392 -0.26699,-2.96256 0.625,-2.66159 0.8199,0.27666 1.12566,2.00073 0.901,5.08036 -0.27261,3.73691 -0.0247,4.66159 1.25,4.66159 1.22091,0 1.59007,-1.05845 1.59007,-4.55902 0,-2.7847 0.38919,-4.31848 1,-3.94098 0.55,0.33992 1,3.95064 1,8.02383 0,6.41491 -0.27118,7.55093 -2.02673,8.49048 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f8862a" />
+ <path
+ id="path2948"
+ d="m 224.43035,828.2706 c -2.45647,-3.33541 -4.24951,-18.71542 -2.10001,-18.01314 0.68426,0.22357 1.72913,1.87324 2.32193,3.66594 0.5928,1.7927 1.61953,3.59426 2.28162,4.00346 1.52494,0.94246 1.99455,10.63162 0.5837,12.04319 -0.7427,0.74309 -1.6604,0.23792 -3.08724,-1.69945 z m 17.63934,-2.45738 c -2.18068,-4.8049 -2.57573,-8.79949 -0.87023,-8.79949 0.71667,0 0.90722,-1.08889 0.525,-3 -0.33846,-1.69231 -0.175,-3 0.375,-3 0.53625,0 0.975,2.25 0.975,5 0,3.74919 0.37048,5 1.48095,5 0.81452,0 1.697,-1.0125 1.96106,-2.25 0.26407,-1.2375 0.67044,-3.15 0.90305,-4.25 0.23262,-1.1 0.47514,1.47167 0.53894,5.71482 0.10212,6.79156 -0.12655,7.84462 -1.91073,8.79949 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f87638" />
+ <path
+ id="path2946"
+ d="m 224.43035,828.2706 c -2.4567,-3.33573 -4.24905,-18.71274 -2.10001,-18.01662 0.68426,0.22166 1.84937,2.28342 2.58911,4.58169 0.73974,2.29827 1.75224,3.92698 2.25,3.61935 1.53952,-0.95147 1.67063,10.19309 0.13795,11.72577 -0.46567,0.46567 -1.76034,-0.39392 -2.87705,-1.91019 z m 17.63934,-2.45738 c -2.06208,-4.54357 -2.59586,-8.79949 -1.10364,-8.79949 0.49038,0 1.17395,1.125 1.51905,2.5 0.67619,2.69414 2.46533,3.22403 4.38936,1.3 0.93333,-0.93333 1.2,-0.27448 1.2,2.96482 0,3.15967 -0.48914,4.42659 -2.02673,5.24949 -1.80497,0.96599 -2.24025,0.61422 -3.97804,-3.21482 z"
+ style="fill:#f86647" />
+ <path
+ id="path2944"
+ d="m 225.53957,828.73073 c -0.35508,-1.41476 -1.27715,-2.81463 -2.04903,-3.11083 -0.96655,-0.3709 -1.35554,-2.02774 -1.24959,-5.32236 0.0846,-2.63109 -0.19572,-5.79631 -0.62296,-7.03381 -0.59332,-1.71857 -0.39946,-2.25 0.82079,-2.25 0.92147,0 1.86759,1.16381 2.23559,2.75 0.35092,1.5125 1.31914,3.83771 2.15162,5.16714 1.83737,2.93418 2.15539,9.57594 0.53605,11.19528 -0.90249,0.90249 -1.32739,0.57716 -1.82247,-1.39542 z m 17.11275,-1.8764 c -2.21367,-5.29808 -2.8383,-8.5616 -1.76556,-9.2246 0.53589,-0.3312 1.25593,0.51971 1.60008,1.89091 0.65349,2.60373 2.45562,3.22509 4.22421,1.4565 0.71546,-0.71546 1.07635,0.0209 1.16492,2.37676 0.0842,2.23955 -0.54396,4.02176 -1.82663,5.18256 -1.8947,1.71468 -1.9994,1.66283 -3.39702,-1.68213 z"
+ style="fill:#f85b47" />
+ <path
+ id="path2942"
+ d="m 224.83638,826.76373 c -0.80746,-1.2375 -1.70473,-4.5 -1.99393,-7.25 -0.2892,-2.75 -0.85346,-5.7875 -1.2539,-6.75 -0.50617,-1.21664 -0.26667,-1.75 0.7858,-1.75 0.99121,0 2.23649,2.30222 3.60698,6.66841 3.1106,9.90994 2.50902,14.68163 -1.14495,9.08159 z m 17.16288,-2.42544 c -1.10227,-2.57149 -1.70889,-5.38399 -1.34804,-6.25 0.50685,-1.2164 0.87603,-0.94902 1.623,1.17544 1.03757,2.95098 2.66105,3.48919 4.61899,1.53125 0.95833,-0.95833 1.08942,-0.47756 0.61347,2.25 -1.33435,7.64681 -2.65142,7.9561 -5.50742,1.29331 z"
+ style="fill:#f86639" />
+ <path
+ id="path2940"
+ d="m 224.68947,826.54891 c -0.9401,-1.43477 -1.61501,-4.54435 -1.61501,-7.44098 0,-2.73689 -0.45,-5.25428 -1,-5.5942 -1.49608,-0.92463 -1.20529,-2.5 0.46146,-2.5 0.88442,0 1.88498,1.67803 2.53414,4.25 0.58998,2.3375 1.50732,5.28367 2.03854,6.54705 1.2092,2.87578 1.25778,7.20295 0.0809,7.20295 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z m 17.87076,-0.91499 c -1.85558,-4.44103 -1.92346,-6.60102 -0.13038,-4.14884 0.85716,1.17224 1.98303,1.61276 3.06282,1.19841 1.42177,-0.54558 1.65509,-0.12558 1.39461,2.51051 -0.4403,4.4558 -2.5591,4.67122 -4.32705,0.43992 z"
+ style="fill:#f7781d" />
+ <path
+ id="path2938"
+ d="m 224.68947,826.54891 c -0.9401,-1.43477 -1.61501,-4.54435 -1.61501,-7.44098 0,-2.73689 -0.45,-5.25428 -1,-5.5942 -1.51136,-0.93407 -1.19817,-2.5 0.5,-2.5 1.04762,0 1.5,1.05556 1.5,3.5 0,1.925 0.3596,3.5 0.79911,3.5 1.02848,0 3.20089,5.98672 3.20089,8.821 0,2.87849 -1.38847,2.76125 -3.38499,-0.28582 z m 17.87076,-0.91499 c -1.85558,-4.44103 -1.92346,-6.60102 -0.13038,-4.14884 0.85716,1.17224 1.98303,1.61276 3.06282,1.19841 1.42177,-0.54558 1.65509,-0.12558 1.39461,2.51051 -0.4403,4.4558 -2.5591,4.67122 -4.32705,0.43992 z"
+ style="fill:#f85737" />
+ <path
+ id="path2936"
+ d="m 224.89116,825.23793 c -1.761,-3.89609 -2.71911,-12.65513 -1.5159,-13.85834 0.38456,-0.38455 0.6992,0.95081 0.6992,2.96747 0,2.01667 0.45,3.66667 1,3.66667 0.55,0 1,1.09844 1,2.44098 0,1.34254 0.45,2.7191 1,3.05902 1.15423,0.71335 1.37341,5.51284 0.25,5.4742 -0.4125,-0.0142 -1.50749,-1.70169 -2.4333,-3.75 z m 18.34208,1.70574 c -0.76367,-2.0394 -0.56828,-2.51979 1.21566,-2.98899 2.66619,-0.70124 3.43951,1.67367 1.25599,3.85719 -1.41566,1.41566 -1.64686,1.33445 -2.47165,-0.8682 z"
+ style="fill:#f76727" />
+ <path
+ id="path2934"
+ d="m 224.82446,825.16032 c -1.95208,-4.24082 -2.20733,-6.14659 -0.82324,-6.14659 1.19752,0 4.07324,5.75648 4.07324,8.15364 0,2.94344 -1.35701,2.10541 -3.25,-2.00705 z m 18.40878,1.78335 c -0.76367,-2.0394 -0.56828,-2.51979 1.21566,-2.98899 2.66619,-0.70124 3.43951,1.67367 1.25599,3.85719 -1.41566,1.41566 -1.64686,1.33445 -2.47165,-0.8682 z"
+ style="fill:#f84b34" />
+ <path
+ id="path2932"
+ d="m 224.82446,824.64094 c -2.00235,-4.2279 -2.1827,-5.62721 -0.72525,-5.62721 1.33504,0 3.14946,4.81045 2.77063,7.34559 -0.23097,1.54565 -0.67698,1.17095 -2.04538,-1.71838 z m 18.73475,2.34812 c -0.40754,-0.65942 -0.12083,-1.58421 0.63713,-2.05509 1.66304,-1.03315 2.55953,0.79835 1.10349,2.25439 -0.66618,0.66618 -1.24681,0.59969 -1.74062,-0.1993 z"
+ style="fill:#f75529" />
+ <path
+ id="path2930"
+ d="m 226.15341,826.59706 c -0.0434,-1.05416 0.19292,-1.64479 0.52522,-1.3125 0.33229,0.33229 0.36781,1.1948 0.0789,1.91667 -0.31923,0.79773 -0.55619,0.56078 -0.60417,-0.60417 z m 17.4058,0.392 c -0.40754,-0.65942 -0.12083,-1.58421 0.63713,-2.05509 1.66304,-1.03315 2.55953,0.79835 1.10349,2.25439 -0.66618,0.66618 -1.24681,0.59969 -1.74062,-0.1993 z"
+ style="fill:#f8472b" />
+ <path
+ id="path2928"
+ d="m 244.07446,826.57275 c 0,-0.85746 0.45,-1.55902 1,-1.55902 0.55,0 1,0.42344 1,0.94098 0,0.51754 -0.45,1.2191 -1,1.55902 -0.55,0.33992 -1,-0.0835 -1,-0.94098 z"
+ style="fill:#f83e29" />
+ </g>
+ <g
+ transform="translate(-109.5,132.5)"
+ id="shipFire2"
+ class="spaceship">
+ <path
+ id="path3209"
+ d="m 151.57446,902.9436 0,-15 20,0 20,0 0,15 0,15 -20,0 -20,0 0,-15 z"
+ style="fill:#fefefe" />
+ <path
+ id="path3207"
+ d="m 162.96188,917.12575 c 0.278,-0.44981 -0.42671,-1.46231 -1.56602,-2.25 -6.19532,-4.28325 -6.07193,-4.01046 -6.49663,-14.36377 -0.35012,-8.53525 -0.17217,-9.96019 1.38679,-11.10498 2.07435,-1.52325 11.97013,-1.78746 12.8626,-0.34341 0.37888,0.61304 1.12963,0.5408 2.01487,-0.19388 0.96521,-0.80105 1.80587,-0.85078 2.66097,-0.15738 0.83468,0.67683 3.35475,0.69027 7.58466,0.0404 3.48406,-0.53525 6.57872,-0.72911 6.87702,-0.43081 0.92329,0.92328 2.41041,8.80392 2.9664,15.71969 0.39587,4.92418 0.12314,7.38568 -1.07506,9.70274 -1.54819,2.99387 -1.78393,3.08356 -6.60426,2.51267 -3.41971,-0.40502 -4.99876,-0.23214 -4.99876,0.54726 0,0.62661 -0.66643,1.13929 -1.48095,1.13929 -1.80373,0 -2.9556,-4.04919 -2.00441,-7.04614 0.92344,-2.90948 -1.57556,-2.16889 -3.13355,0.92865 -1.68131,3.34273 -5.03701,6.11749 -7.39829,6.11749 -1.15546,0 -1.87338,-0.36803 -1.59538,-0.81785 z"
+ style="fill:#fef4f3" />
+ <path
+ id="path3205"
+ d="m 163.03741,917.00355 c 0.58394,-0.94485 0.10077,-1.48471 -4.41546,-4.93349 -2.1257,-1.62328 -2.54917,-2.98908 -3.17795,-10.24965 -1.00798,-11.63923 -0.10006,-13.34965 7.14549,-13.46141 3.01673,-0.0465 5.93497,0.23133 6.48497,0.61747 1.17869,0.82751 10.45665,0.51702 15.61683,-0.52263 l 3.61683,-0.7287 1.63317,7.23189 c 2.02661,8.97413 2.06262,13.7145 0.13914,18.31804 -1.48926,3.5643 -1.51001,3.57382 -6.5,2.98283 -3.4256,-0.40571 -5.00597,-0.23321 -5.00597,0.54641 0,1.55847 -2.97681,1.45192 -3.09274,-0.11071 -0.051,-0.6875 -0.0116,-3.25029 0.0875,-5.69508 0.15304,-3.77373 -0.038,-4.26392 -1.26504,-3.24559 -0.79492,0.65972 -2.72404,3.22251 -4.28694,5.69508 -2.05711,3.25444 -3.49307,4.49559 -5.20123,4.49559 -1.29778,0 -2.09816,-0.42302 -1.77862,-0.94005 z"
+ style="fill:#fef3ea" />
+ <path
+ id="path3203"
+ d="m 162.87261,917.31212 c 0.98153,-0.98154 -1.19733,-4.36852 -2.81028,-4.36852 -0.79297,0 -2.1115,-1.02214 -2.93006,-2.27143 -1.9288,-2.94372 -2.45436,-19.23181 -0.67788,-21.00894 1.42194,-1.42246 12.12007,-1.80281 12.12007,-0.4309 0,0.51045 1.09742,0.65265 2.43871,0.31601 1.3413,-0.33665 2.72239,-0.15309 3.0691,0.4079 0.34671,0.56099 1.075,0.7452 1.61842,0.40934 0.54342,-0.33585 1.97483,-0.7608 3.1809,-0.94432 1.20608,-0.18353 3.76787,-0.62898 5.69287,-0.98989 l 3.5,-0.65619 1.7642,7.33421 c 1.93817,8.05746 2.29955,15.83421 0.7358,15.83421 -0.55,0 -1,1.09844 -1,2.44098 0,3.27429 -1.11158,3.76871 -6.00239,2.66982 -3.26275,-0.73309 -4.24406,-0.63213 -4.67105,0.48057 -0.29729,0.77475 -1.16739,1.40863 -1.93355,1.40863 -1.02551,0 -1.39301,-1.48331 -1.39301,-5.62245 0,-5.01744 -0.17049,-5.48095 -1.58439,-4.30751 -0.87142,0.72321 -2.91804,3.25331 -4.54804,5.62244 -1.91866,2.78868 -3.71068,4.30752 -5.08228,4.30752 -1.16524,0 -1.83446,-0.28417 -1.48714,-0.63148 z"
+ style="fill:#fde8e7" />
+ <path
+ id="path3201"
+ d="m 163.57446,916.49449 c 0,-0.79701 -1.5347,-2.61968 -3.41045,-4.05039 -3.34087,-2.5482 -3.42503,-2.79562 -4.12458,-12.12631 -0.49318,-6.57819 -0.36781,-9.87135 0.40526,-10.64442 1.58052,-1.58052 11.34374,-1.64763 12.90871,-0.0887 0.70341,0.70069 1.94091,1.01996 2.75,0.70948 0.80908,-0.31047 1.47106,-0.0398 1.47106,0.60151 0,0.69406 0.50594,0.84125 1.25,0.36365 1.48765,-0.95489 9.60478,-3.20883 11.78189,-3.27155 0.89112,-0.0257 1.61132,0.91554 1.72177,2.25013 0.10444,1.26185 0.87759,4.24343 1.71811,6.62573 1.71574,4.86292 2.06153,14.08001 0.52823,14.08001 -0.55,0 -1,0.8449 -1,1.87755 0,3.07992 -2.2104,4.20929 -6.07124,3.10202 -4.50601,-1.29231 -4.92876,-1.24767 -4.92876,0.52043 0,0.825 -0.6681,1.5 -1.48467,1.5 -1.21761,0 -1.37186,-1.07927 -0.85754,-6 0.37978,-3.63355 0.24528,-6 -0.34102,-6 -1.19371,0 -4.13666,3.29088 -7.37163,8.24317 -2.48087,3.79786 -4.94514,4.94785 -4.94514,2.30772 z"
+ style="fill:#fde3db" />
+ <path
+ id="path3199"
+ d="m 163.57446,916.49449 c 0,-0.79701 -1.50777,-2.59914 -3.35059,-4.00473 -3.26039,-2.48682 -3.36819,-2.80345 -4.00402,-11.76116 -0.53554,-7.5447 -0.37779,-9.48118 0.87439,-10.73336 2.05974,-2.05974 11.1787,-2.27977 11.94295,-0.28817 0.32015,0.83429 1.22302,1.18736 2.13824,0.83616 1.0586,-0.40623 1.76151,0.0705 2.11886,1.43701 0.52424,2.00471 0.56124,2.00709 1.88206,0.12136 0.74101,-1.05795 2.59623,-2.18478 4.1227,-2.50408 9.28393,-1.94193 8.81294,-1.97116 9.02241,0.55983 0.1081,1.30613 0.88425,4.32394 1.72477,6.70624 1.71574,4.86292 2.06153,14.08001 0.52823,14.08001 -0.55,0 -1,0.81 -1,1.8 0,3.01516 -1.86706,4.09852 -5.34458,3.10118 -4.40199,-1.26248 -5.65542,-1.12976 -5.65542,0.59882 0,0.825 -0.63233,1.5 -1.40517,1.5 -1.11122,0 -1.29136,-1.25517 -0.86111,-6 0.34639,-3.82005 0.16791,-6 -0.49124,-6 -1.32415,0 -7.06306,6.5121 -8.48052,9.62309 -1.18645,2.60397 -3.76196,3.23916 -3.76196,0.9278 z"
+ style="fill:#fddbda" />
+ <path
+ id="path3197"
+ d="m 163.57446,915.96928 c 0,-1.18015 -1.20093,-2.59534 -2.98551,-3.51819 -3.28277,-1.69758 -3.6304,-2.72129 -4.44155,-13.07944 -0.72235,-9.22415 0.366,-10.86052 7.31911,-11.00464 4.13062,-0.0856 5.18438,0.24206 5.66684,1.76214 0.32597,1.02703 1.32706,1.74292 2.22465,1.59089 1.2408,-0.21018 1.71047,0.67881 1.95939,3.70872 0.18006,2.19184 0.74523,4.403 1.25592,4.91369 0.57138,0.57138 0.70687,-0.43744 0.35224,-2.62274 -0.81981,-5.05189 0.66273,-6.92355 6.70993,-8.47114 5.54336,-1.41865 6.86584,-0.905 6.93872,2.69503 0.0167,0.825 0.67885,3.3 1.47142,5.5 2.01176,5.58413 1.86493,10.42872 -0.46204,15.24498 -1.9362,4.00748 -2.08038,4.09285 -5.25,3.10855 -5.15345,-1.60037 -6.28791,-1.52497 -5.96528,0.39647 0.16161,0.9625 -0.30972,1.75 -1.0474,1.75 -1.02652,0 -1.24411,-1.52514 -0.92734,-6.5 0.22764,-3.575 0.024,-6.47871 -0.4526,-6.45269 -1.17866,0.0644 -9.3665,10.39262 -9.3665,11.81503 0,0.62571 -0.675,1.13766 -1.5,1.13766 -0.82683,0 -1.5,-0.88604 -1.5,-1.97432 z"
+ style="fill:#fdd4d3" />
+ <path
+ id="path3195"
+ d="m 164.18103,916.77117 c 0.43565,-0.70489 -0.81465,-2.4647 -3.13534,-4.41305 -3.69469,-3.10187 -3.89194,-3.57553 -4.60717,-11.06331 -1.03988,-10.88663 -0.0358,-12.78139 6.84886,-12.92409 4.71285,-0.0977 5.2995,0.13606 6.23046,2.48252 0.56525,1.4247 1.47635,3.26536 2.02466,4.09036 0.54832,0.825 1.67354,3.075 2.50049,5 l 1.50355,3.5 -0.50478,-5 c -0.27763,-2.75 -0.0824,-5.64324 0.43386,-6.42941 0.79202,-1.20613 11.1128,-4.63899 11.53951,-3.83823 0.0784,0.1472 1.15252,3.4997 2.38686,7.44999 2.43693,7.79905 2.66335,14.72 0.45384,13.87213 -0.93046,-0.35706 -1.14026,0.15958 -0.72945,1.79636 0.92292,3.67722 -1.48563,4.94645 -6.83196,3.60023 -4.34704,-1.0946 -4.4947,-1.26023 -4.98261,-5.58895 -0.52198,-4.63098 -1.67993,-6.79044 -2.46354,-4.59426 -0.24881,0.69732 -1.15193,1.9674 -2.00693,2.8224 -2.2206,2.2206 -6.26688,8.32478 -6.26688,9.45415 0,0.52557 -0.70156,0.95559 -1.55902,0.95559 -0.93755,0 -1.27017,-0.46736 -0.83441,-1.17243 z m 11.39343,0.73145 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z"
+ style="fill:#fdd5cb" />
+ <path
+ id="path3193"
+ d="m 164.1735,916.5461 c 0.31707,-0.82628 -0.88226,-2.47948 -2.93415,-4.04453 -4.03071,-3.07437 -4.57157,-4.70635 -4.77073,-14.39518 -0.1804,-8.77645 0.68336,-10.02859 6.65854,-9.65248 3.86629,0.24336 4.82621,0.76895 6.84943,3.75033 1.29414,1.90703 2.89298,5.10353 3.55298,7.10334 1.63364,4.94999 2.44547,4.57523 1.71016,-0.78944 -0.75035,-5.47444 0.9777,-7.75927 7.18209,-9.49615 2.39104,-0.66935 4.43478,-1.07332 4.54164,-0.8977 0.10686,0.17562 1.20419,3.55137 2.43853,7.50166 2.4293,7.77463 2.66263,14.71972 0.46621,13.87687 -0.87564,-0.33601 -1.29374,0.44385 -1.29374,2.41315 0,3.83982 -0.992,4.28955 -6.31903,2.86479 -4.29403,-1.14848 -4.47943,-1.35674 -4.95371,-5.56454 -0.4947,-4.38896 -1.66671,-6.69837 -2.38712,-4.70377 -0.21232,0.58787 -2.17572,2.98811 -4.36309,5.33386 -2.18738,2.34575 -3.97705,5.12726 -3.97705,6.18114 0,1.05388 -0.66088,1.91615 -1.46862,1.91615 -0.84672,0 -1.24152,-0.59178 -0.93234,-1.3975 z m 11.40096,0.95652 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z"
+ style="fill:#fcc9c7" />
+ <path
+ id="path3191"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.04148,-1 1.55902,-1 0.51754,0 0.94098,0.45 0.94098,1 0,0.55 -0.70156,1 -1.55902,1 -0.85746,0 -1.2809,-0.45 -0.94098,-1 z m -2.5,-4.5612 c -3.83318,-2.6976 -4.78539,-5.9 -4.92588,-16.56636 -0.088,-6.68229 0.84499,-7.68093 6.86223,-7.34496 3.62102,0.20218 4.59555,0.6781 5.30265,2.58955 0.47646,1.28801 1.42448,3.0261 2.10671,3.86241 1.94334,2.38227 3.85888,8.87634 3.02775,10.26473 -1.36298,2.27684 -7.78605,9.75683 -8.33522,9.70679 -0.29603,-0.027 -2.11324,-1.15744 -4.03824,-2.51216 z m 18.36759,1.39317 c -1.5582,-0.75458 -2.29225,-2.28472 -2.72598,-5.68232 -1.81186,-14.19307 -1.85608,-15.1863 -0.73618,-16.5357 0.6374,-0.76802 2.38193,-1.62827 3.87674,-1.91168 1.4948,-0.28341 3.73033,-0.83485 4.96783,-1.22541 1.79339,-0.56601 2.25,-0.32428 2.25,1.19117 0,1.04571 0.9243,4.53109 2.05401,7.7453 2.39531,6.81511 2.29483,11.2274 -0.2461,10.80613 -1.40828,-0.23348 -1.59599,0.31162 -1.11915,3.25 0.56258,3.46682 0.51191,3.52932 -2.80792,3.46286 -1.85946,-0.0372 -4.34043,-0.53238 -5.51325,-1.10035 z"
+ style="fill:#fcbec0" />
+ <path
+ id="path3189"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m 15.867,-3.4555 c -2.13975,-1.49873 -3.49156,-7.8263 -3.74817,-17.5445 l -0.11883,-4.5 5,-1.66983 c 6.5578,-2.19008 6.5,-2.19412 6.5,0.45449 0,1.25656 0.9,4.84532 2,7.97502 2.56186,7.28896 2.57769,9.74032 0.0629,9.74032 -1.65538,0 -1.85452,0.50906 -1.36916,3.5 0.55605,3.4265 0.4964,3.5 -2.84036,3.5 -1.87459,0 -4.34344,-0.65497 -5.48635,-1.4555 z m -18.60545,-1.38463 c -3.43887,-2.08117 -3.72417,-2.86336 -4.4426,-12.17971 -0.78522,-10.18248 0.13117,-11.85397 6.28649,-11.46653 l 4.65321,0.29289 2.84267,6.34674 c 3.65068,8.15076 3.60396,10.13172 -0.35132,14.89597 -3.55811,4.28584 -4.88093,4.59646 -8.98845,2.11064 z"
+ style="fill:#fcc6b6" />
+ <path
+ id="path3187"
+ d="m 164.07446,916.9436 c 0.33992,-0.55 1.06803,-1 1.61803,-1 0.55,0 0.72189,0.45 0.38197,1 -0.33992,0.55 -1.06803,1 -1.61803,1 -0.55,0 -0.72189,-0.45 -0.38197,-1 z m 15.86726,-3.77224 c -1.42817,-1.15698 -2.34597,-3.37956 -2.77818,-6.72776 -0.35499,-2.75 -0.87727,-6.8 -1.16063,-9 -0.63335,-4.91747 0.30316,-6.41121 4.67526,-7.45707 1.86796,-0.44683 4.18379,-1.13743 5.14629,-1.53467 1.38018,-0.56961 1.75,-0.21682 1.75,1.66941 0,1.31541 0.9,4.95231 2,8.08201 1.1,3.12969 2,6.6016 2,7.71534 0,1.35831 -0.65844,2.02498 -2,2.02498 -1.61905,0 -2,0.66667 -2,3.5 0,3.15691 -0.26957,3.49782 -2.75,3.47776 -1.5125,-0.0122 -3.70973,-0.79973 -4.88274,-1.75 z m -18.62479,-1.06919 c -3.28171,-1.97384 -3.41746,-2.3794 -4.2374,-12.65857 -0.80902,-10.14237 0.0964,-11.68239 6.35676,-10.81264 4.18382,0.58125 4.47966,0.85505 7.24921,6.70931 3.85095,8.14012 3.70716,10.04334 -1.11219,14.72035 -4.47969,4.34739 -4.43931,4.33741 -8.25638,2.04155 z"
+ style="fill:#fcb8b7" />
+ <path
+ id="path3185"
+ d="m 180.95274,913.78034 c -1.68968,-0.81858 -2.47019,-2.83106 -3.833,-9.88312 -2.09004,-10.81512 -1.64459,-12.66589 3.26108,-13.54927 2.0315,-0.36582 4.20048,-1.06536 4.81994,-1.55453 0.77792,-0.61429 1.49677,0.58187 2.324,3.8671 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09968,2.7008 1.47131,4.7633 0.60026,3.33127 0.44732,3.75 -1.36961,3.75 -1.71953,0 -2.04531,0.63713 -2.04531,4 0,3.50153 -0.28039,3.99157 -2.25,3.93232 -1.2375,-0.0372 -3.20478,-0.53023 -4.37172,-1.09558 z m -19.9947,-2.63358 c -2.78682,-2.54536 -3.12379,-3.53611 -3.74785,-11.01905 -0.7913,-9.4884 0.22403,-12.72439 3.69989,-11.79201 1.19041,0.31933 3.15582,0.58674 4.36759,0.59425 1.65866,0.0103 2.72727,1.18765 4.32359,4.76365 3.4929,7.82464 3.41122,11.85531 -0.3316,16.3645 -1.75736,2.1172 -3.65741,3.85756 -4.22234,3.86747 -0.56493,0.01 -2.4051,-1.24055 -4.08928,-2.77881 z"
+ style="fill:#fbb4a7" />
+ <path
+ id="path3183"
+ d="m 181.40888,913.54887 c -1.90156,-0.94762 -2.66716,-2.73407 -4.12887,-9.6343 -2.11431,-9.98096 -1.48228,-12.43122 3.4804,-13.49292 1.82273,-0.38995 3.82089,-1.11594 4.44035,-1.61331 0.78167,-0.6276 1.49279,0.55112 2.324,3.85218 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09346,2.66764 1.45749,4.68962 0.59423,3.30058 0.4287,3.70941 -1.61961,4 -1.89768,0.26923 -2.23157,0.84875 -1.98478,3.44483 0.34701,3.6502 -2.13396,4.89193 -5.96229,2.98412 z m -19.59537,-1.75085 c -3.85286,-2.43946 -4.12485,-3.26446 -4.46668,-13.54855 -0.29145,-8.76823 0.67103,-11.1791 3.91041,-9.79498 0.99947,0.42706 2.70818,0.82431 3.79713,0.88279 2.50572,0.13456 5.98356,6.56952 6.78668,12.55723 0.55271,4.12079 0.33707,4.68072 -3.14285,8.16065 l -3.73629,3.73628 -3.1484,-1.99342 z"
+ style="fill:#fbc693" />
+ <path
+ id="path3181"
+ d="m 181.40888,913.54887 c -1.90156,-0.94762 -2.66716,-2.73407 -4.12887,-9.6343 -2.11431,-9.98096 -1.48228,-12.43122 3.4804,-13.49292 1.82273,-0.38995 3.82089,-1.11594 4.44035,-1.61331 0.78167,-0.6276 1.49279,0.55112 2.324,3.85218 0.65874,2.61606 1.55572,5.21247 1.99331,5.76978 0.43758,0.55732 1.09346,2.66764 1.45749,4.68962 0.59423,3.30058 0.4287,3.70941 -1.61961,4 -1.89768,0.26923 -2.23157,0.84875 -1.98478,3.44483 0.34701,3.6502 -2.13396,4.89193 -5.96229,2.98412 z m -19.59537,-1.75085 c -3.85797,-2.44269 -4.12541,-3.25919 -4.46668,-13.63661 -0.21296,-6.47571 0.053,-8.48421 1.21927,-9.20836 0.92359,-0.57346 1.85661,-0.5612 2.45,0.0322 0.5271,0.5271 2.21605,0.95836 3.75324,0.95836 2.32203,0 3.11778,0.71903 4.70349,4.25 1.04975,2.3375 2.1601,6.00739 2.46746,8.15531 0.5041,3.52278 0.18969,4.27446 -3.20977,7.67393 l -3.76861,3.7686 -3.1484,-1.99342 z"
+ style="fill:#fba7a6" />
+ <path
+ id="path3179"
+ d="m 180.42487,912.6936 c -2.246,-1.83276 -5.24235,-17.14915 -3.86013,-19.73183 0.59405,-1.10999 1.40175,-2.02891 1.7949,-2.04203 0.39315,-0.0131 2.38169,-0.41108 4.41898,-0.88435 l 3.70417,-0.86049 1.20496,5.38435 c 0.66273,2.96139 1.63584,5.38435 2.16247,5.38435 0.52663,0 0.72226,0.89955 0.43475,1.999 -0.28751,1.09946 -0.115,2.25101 0.38337,2.55902 1.72728,1.06752 0.8953,2.41725 -1.34388,2.18019 -1.77357,-0.18777 -2.27296,0.29115 -2.35843,2.26179 -0.20189,4.65475 -0.38835,5 -2.70044,5 -1.26988,0 -2.9982,-0.5625 -3.84072,-1.25 z m -19.64276,-1.72785 c -3.80444,-3.17207 -5.11148,-21.0776 -1.63594,-22.41129 0.75033,-0.28793 1.63021,-0.0932 1.95528,0.43281 0.32508,0.52598 1.92562,0.95633 3.55678,0.95633 3.39807,0 4.50718,2.01814 5.96224,10.84895 0.82009,4.97716 0.69273,5.58534 -1.83233,8.74997 -3.07999,3.86011 -4.73127,4.15366 -8.00603,1.42323 z"
+ style="fill:#fb9fa0" />
+ <path
+ id="path3177"
+ d="m 180.32446,912.8635 c -0.9625,-0.5606 -1.75,-1.98067 -1.75,-3.1557 0,-1.17503 -0.70563,-4.95003 -1.56806,-8.38889 -1.97329,-7.8683 -1.07849,-9.92916 4.82218,-11.10618 l 4.24588,-0.84693 1.23482,4.0389 c 0.67915,2.22139 1.24165,5.24426 1.25,6.71747 0.008,1.47322 0.72232,3.38572 1.58661,4.25 0.86428,0.86429 1.20178,1.62334 0.75,1.68678 -0.45179,0.0634 -1.49643,0.17594 -2.32143,0.25 -0.89743,0.0806 -1.5,1.13894 -1.5,2.63465 0,4.68395 -2.72313,6.26534 -6.75,3.9199 z m -18.59061,-1.52081 c -3.18441,-2.23045 -4.15936,-5.40703 -4.3244,-14.08961 -0.10379,-5.46081 0.23701,-7.73594 1.25286,-8.36377 0.80738,-0.49899 1.7993,-0.45856 2.35379,0.0959 0.5271,0.5271 2.2295,0.95836 3.78311,0.95836 3.22728,0 4.77525,2.79781 4.77525,8.63084 0,1.92535 0.46718,4.37357 1.03817,5.44049 0.83398,1.5583 0.48978,2.62715 -1.75,5.43423 -3.14945,3.94716 -3.90883,4.14887 -7.12878,1.89353 z"
+ style="fill:#fba896" />
+ <path
+ id="path3175"
+ d="m 180.38153,912.23762 c -1.73595,-1.96787 -4.23706,-14.37731 -3.66592,-18.18864 0.28615,-1.90951 1.28961,-2.62988 4.95335,-3.55593 l 4.5945,-1.16131 1.1555,4.32028 c 0.63553,2.37616 1.1555,5.40668 1.1555,6.7345 0,1.32782 0.70714,3.12137 1.57143,3.98565 0.86428,0.86429 1.20178,1.62334 0.75,1.68678 -0.45179,0.0634 -1.49643,0.17594 -2.32143,0.25 -0.91279,0.0819 -1.69574,1.5048 -2,3.63465 -0.58275,4.07922 -3.62426,5.20588 -6.19293,2.29402 z m -19.3807,-1.60369 c -2.4799,-2.13313 -2.72327,-3.03845 -3.18385,-11.84386 -0.42411,-8.10811 -0.25997,-9.6258 1.09736,-10.14665 0.87784,-0.33686 1.86204,-0.18213 2.18711,0.34385 0.32508,0.52598 1.66397,0.95633 2.97532,0.95633 3.15873,0 5.49769,3.52618 5.49769,8.28825 0,2.11378 0.46554,4.71311 1.03454,5.77629 0.85492,1.59744 0.42667,2.54092 -2.46667,5.43425 -1.92566,1.92567 -3.71611,3.50121 -3.97877,3.50121 -0.26267,0 -1.68589,-1.03935 -3.16273,-2.30967 z"
+ style="fill:#fb9997" />
+ <path
+ id="path3173"
+ d="m 180.61925,912.49757 c -1.54558,-1.86231 -3.96316,-11.97209 -4.00917,-16.76543 -0.0337,-3.51238 0.18575,-3.77106 4.09158,-4.82279 2.32002,-0.62472 4.50572,-0.73283 4.99166,-0.24689 0.47544,0.47544 1.39155,3.48908 2.03578,6.69698 0.89078,4.43548 0.89278,6.27859 0.008,7.69478 -0.63959,1.02423 -1.16294,3.1702 -1.16294,4.76882 0,3.89193 -3.60222,5.50971 -5.95521,2.67453 z M 161.2105,910.6419 c -2.67903,-2.14379 -2.89701,-2.87138 -3.37577,-11.26821 -0.41609,-7.29756 -0.2244,-9.21497 1.02493,-10.25182 1.03553,-0.85942 1.74811,-0.9334 2.18479,-0.22683 0.35642,0.57671 1.69139,1.04856 2.96658,1.04856 3.39213,0 4.82534,2.37252 5.16837,8.55569 0.16748,3.01883 0.57322,5.92356 0.90165,6.45497 0.54751,0.8859 -4.35593,7.99571 -5.50659,7.98434 -0.275,-0.003 -1.78878,-1.03623 -3.36396,-2.2967 z"
+ style="fill:#fac868" />
+ <path
+ id="path3171"
+ d="m 180.61925,912.49757 c -1.54558,-1.86231 -3.96316,-11.97209 -4.00917,-16.76543 -0.0337,-3.51238 0.18575,-3.77106 4.09158,-4.82279 2.32002,-0.62472 4.50572,-0.73283 4.99166,-0.24689 0.47544,0.47544 1.39155,3.48908 2.03578,6.69698 0.89078,4.43548 0.89278,6.27859 0.008,7.69478 -0.63959,1.02423 -1.16294,3.1702 -1.16294,4.76882 0,3.89193 -3.60222,5.50971 -5.95521,2.67453 z m -19.45977,-1.89636 c -2.83469,-2.2682 -2.91733,-2.59171 -3,-11.74503 l -0.085,-9.41258 4,0.33285 c 5.42153,0.45115 6.73448,2.04528 7.09921,8.61958 0.17063,3.07562 0.57895,6.02682 0.90738,6.55823 0.54751,0.8859 -4.35593,7.99571 -5.50659,7.98434 -0.275,-0.003 -1.81174,-1.05454 -3.41498,-2.33739 z"
+ style="fill:#fa9588" />
+ <path
+ id="path3169"
+ d="m 181.27717,912.6936 c -2.29214,-1.70591 -5.542,-17.19589 -4.09055,-19.49693 1.25861,-1.99531 7.28306,-3.75785 8.54186,-2.49904 1.62734,1.62734 3.20598,13.28597 1.96678,14.52517 -0.61644,0.61644 -1.1208,2.2908 -1.1208,3.7208 0,2.4 -1.56461,5 -3.00887,5 -0.33488,0 -1.36467,-0.5625 -2.28842,-1.25 z m -19.82628,-2.16376 c -2.22007,-2.05857 -2.7042,-3.5724 -3.28996,-10.28744 -0.75026,-8.60077 -0.13895,-11.72478 2.12436,-10.85627 0.79901,0.30661 2.52511,0.55747 3.83577,0.55747 3.1779,0 4.5433,2.83475 4.90988,10.19353 0.23862,4.78997 -0.13818,6.723 -1.82795,9.37775 -1.17069,1.83924 -2.35813,3.36311 -2.63875,3.38639 -0.28062,0.0233 -1.68163,-1.04386 -3.11335,-2.37143 z"
+ style="fill:#fa8b86" />
+ <path
+ id="path3167"
+ d="m 180.07939,911.6936 c -0.96604,-2.79329 -3.50493,-15.00852 -3.50493,-16.86308 0,-1.34263 1.1834,-2.48343 3.64167,-3.51056 5.43653,-2.27153 6.86784,-0.40276 6.82572,8.91194 -0.0454,10.04111 -0.8895,12.7117 -4.01783,12.7117 -1.38178,0 -2.70687,-0.5625 -2.94463,-1.25 z m -19.29027,-2.20424 c -1.3053,-1.65942 -2.14743,-4.84806 -2.60032,-9.84592 -0.87694,-9.67732 -0.44657,-10.69807 4.21367,-9.99407 2.01959,0.30509 4.11891,0.96552 4.66515,1.46762 0.54623,0.50211 1.2459,4.156 1.55481,8.11977 0.48082,6.16945 0.2748,7.60269 -1.43121,9.95684 -2.45809,3.39195 -3.91374,3.4592 -6.4021,0.29576 z"
+ style="fill:#f9aa67" />
+ <path
+ id="path3165"
+ d="m 180.23917,912.1936 c -0.24933,-0.4125 -1.26783,-4.68555 -2.26334,-9.49567 -1.97889,-9.5616 -1.79281,-10.20809 3.36397,-11.68703 4.53536,-1.30072 5.74188,0.67547 5.70205,9.33952 -0.0452,9.8259 -0.90819,12.59318 -3.92743,12.59318 -1.33206,0 -2.62592,-0.3375 -2.87525,-0.75 z m -19.45005,-2.70424 c -1.3053,-1.65942 -2.14743,-4.84806 -2.60032,-9.84592 -0.79775,-8.8035 -0.22455,-11.09678 2.41988,-9.68153 1.00886,0.53993 2.95856,0.98169 4.33265,0.98169 2.92589,0 3.40329,1.19686 3.78937,9.5 0.20907,4.49625 -0.18031,6.68922 -1.55363,8.75 -2.26265,3.39527 -3.89059,3.47065 -6.38795,0.29576 z"
+ style="fill:#fa8974" />
+ <path
+ id="path3163"
+ d="m 180.72006,911.61903 c -1.4979,-1.80485 -4.31584,-15.56371 -3.63009,-17.72428 0.67874,-2.13853 7.23738,-3.59767 8.86474,-1.9722 1.21641,1.215 1.28853,11.23559 0.1243,17.27105 -0.76211,3.95089 -3.18344,5.04676 -5.35895,2.42543 z m -19.6989,-1.73433 c -2.13154,-2.35532 -3.97555,-16.59894 -2.39543,-18.50288 0.51226,-0.61723 0.59778,-1.47929 0.19005,-1.91568 -0.40772,-0.4364 0.2416,-0.28249 1.44294,0.34201 1.20134,0.6245 3.09801,1.13545 4.21481,1.13545 1.11681,0 2.51821,0.91118 3.11423,2.02485 2.07725,3.88138 -0.75392,18.97515 -3.5592,18.97515 -0.62927,0 -1.9826,-0.9265 -3.0074,-2.0589 z"
+ style="fill:#fa7c74" />
+ <path
+ id="path3161"
+ d="m 180.91399,911.73649 c -0.5371,-0.71109 -1.7753,-4.79608 -2.75154,-9.07776 -1.36171,-5.97223 -1.5043,-8.11105 -0.6124,-9.18572 1.45048,-1.74772 6.93018,-3.02459 8.07048,-1.88057 1.16986,1.17368 1.36105,11.98823 0.29772,16.84039 -0.90326,4.12175 -3.22742,5.65609 -5.00426,3.30366 z M 162.4878,910.6618 c -3.08149,-2.3659 -4.01734,-5.72011 -3.8248,-13.70865 0.17568,-7.28887 0.33626,-7.85257 1.98556,-6.96989 0.98693,0.52818 2.70817,0.96034 3.82497,0.96034 1.11681,0 2.4717,0.82427 3.01086,1.83171 1.24877,2.33334 0.244,12.81559 -1.57376,16.41829 -1.59155,3.15436 -1.35745,3.05394 -3.42283,1.4682 z"
+ style="fill:#f97568" />
+ <path
+ id="path3159"
+ d="m 181.18872,912.12848 c -1.12357,-1.81798 -3.61426,-12.66104 -3.61426,-15.73446 0,-2.38301 0.60749,-3.40618 2.54705,-4.28991 5.29419,-2.41219 6.50298,-1.14797 6.37883,6.67128 -0.13265,8.35393 -1.29475,13.61677 -3.08264,13.96046 -0.91122,0.17517 -1.91426,-0.0982 -2.22898,-0.60737 z m -20.20927,-3.28761 c -1.53322,-1.69237 -1.9442,-3.84084 -2.10589,-11.00891 -0.19049,-8.44507 -0.10329,-8.85393 1.68426,-7.89726 1.03684,0.55489 2.78818,1.0089 3.89188,1.0089 1.1037,0 2.34895,0.55373 2.76722,1.2305 1.11829,1.80944 0.48625,12.83248 -0.91853,16.0195 -1.4532,3.29687 -2.77301,3.45748 -5.31894,0.64727 z"
+ style="fill:#f9904b" />
+ <path
+ id="path3157"
+ d="m 181.18872,912.12848 c -1.14282,-1.84912 -3.61426,-12.68601 -3.61426,-15.84797 0,-2.88972 0.40359,-3.35434 3.7057,-4.26609 4.58817,-1.26686 5.28526,-0.4058 5.20486,6.42918 -0.10111,8.5965 -1.24846,13.94261 -3.06732,14.29225 -0.91122,0.17517 -1.91426,-0.0982 -2.22898,-0.60737 z m -20.20649,-3.28679 c -1.44296,-1.59445 -1.9879,-3.98904 -2.25717,-9.91855 l -0.35497,-7.81664 4.35218,0.55614 c 2.39371,0.30587 4.5587,0.73823 4.8111,0.96079 0.90854,0.80113 -0.0496,12.88089 -1.23498,15.57017 -1.45309,3.29661 -2.77359,3.45759 -5.31616,0.64809 z"
+ style="fill:#f96c64" />
+ <path
+ id="path3155"
+ d="m 182.00194,912.15744 c -1.28515,-0.85536 -4.42748,-11.79022 -4.42748,-15.407 0,-2.82016 1.32386,-4.22994 4.76309,-5.07221 3.51518,-0.86088 4.61133,2.30777 3.86257,11.16552 -0.62875,7.43814 -2.10279,10.70831 -4.19818,9.31369 z m -19.65615,-2.43812 c -2.51948,-1.91174 -3.77133,-6.20961 -3.77133,-12.94781 0,-5.09857 0.24696,-5.94712 1.58179,-5.4349 0.86998,0.33384 2.89498,0.60699 4.5,0.60699 l 2.91821,0 -0.0222,7.25 c -0.0164,5.34852 -0.4816,7.84686 -1.7737,9.52572 -1.48125,1.92462 -2.01085,2.0789 -3.43274,1 z"
+ style="fill:#f8a727" />
+ <path
+ id="path3153"
+ d="m 182.00194,912.15744 c -1.28515,-0.85536 -4.42748,-11.79022 -4.42748,-15.407 0,-2.82016 1.32386,-4.22994 4.76309,-5.07221 3.51518,-0.86088 4.61133,2.30777 3.86257,11.16552 -0.62875,7.43814 -2.10279,10.70831 -4.19818,9.31369 z m -19.65615,-2.43812 c -2.51948,-1.91174 -3.77133,-6.20961 -3.77133,-12.94781 0,-5.09857 0.24696,-5.94712 1.58179,-5.4349 0.86998,0.33384 1.72785,0.60699 1.90638,0.60699 0.17852,0 0.0911,0.89278 -0.19423,1.98395 -0.66163,2.5301 0.44138,7.01605 1.72511,7.01605 0.53952,0 0.98095,-2.025 0.98095,-4.5 0,-3.33333 0.38889,-4.5 1.5,-4.5 2.31179,0 2.07009,13.70149 -0.29594,16.77572 -1.48125,1.92462 -2.01084,2.0789 -3.43273,1 z"
+ style="fill:#f97656" />
+ <path
+ id="path3151"
+ d="m 182.00194,912.15744 c -1.30059,-0.86563 -4.42748,-11.8084 -4.42748,-15.49426 0,-2.81806 2.38324,-4.71958 5.91521,-4.71958 2.73688,0 3.51703,3.46196 2.66677,11.83399 -0.68096,6.70511 -2.16705,9.70263 -4.1545,8.37985 z m -19.6862,-2.46009 c -2.64876,-2.01116 -3.61818,-6.01981 -3.02848,-12.52309 0.39024,-4.30358 0.91579,-5.92668 1.80816,-5.58424 0.69191,0.26551 1.03216,1.34646 0.7561,2.40212 -0.64783,2.47728 0.47338,6.95146 1.74199,6.95146 0.53952,0 0.98095,-2.025 0.98095,-4.5 0,-4.55243 1.37549,-6.04303 2.45059,-2.65567 0.719,2.26536 -1.01511,15.12019 -2.19947,16.30455 -0.47815,0.47815 -1.59029,0.30306 -2.50984,-0.39513 z"
+ style="fill:#f88f2e" />
+ <path
+ id="path3149"
+ d="m 182.00194,912.15744 c -1.30059,-0.86563 -4.42748,-11.8084 -4.42748,-15.49426 0,-2.81806 2.38324,-4.71958 5.91521,-4.71958 2.73688,0 3.51703,3.46196 2.66677,11.83399 -0.68096,6.70511 -2.16705,9.70263 -4.1545,8.37985 z m -19.60247,-2.28383 c -2.66678,-1.50524 -3.80043,-6.75809 -2.89841,-13.43001 0.6194,-4.58155 0.84216,-5.12459 0.94228,-2.29705 0.16099,4.5464 1.99307,8.79705 3.79163,8.79705 0.96049,0 1.34809,-1.62693 1.3699,-5.75 0.0233,-4.40049 0.27006,-5.3385 1.05154,-3.99669 1.11218,1.90963 -0.30428,15.37887 -1.76899,16.82145 -0.44713,0.44038 -1.56671,0.37524 -2.48795,-0.14475 z"
+ style="fill:#f96656" />
+ <path
+ id="path3147"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.21163,-4.031 -2.17681,-8.0411 -1.6772,-6.9684 -1.67641,-7.3778 0.0179,-9.25 0.97502,-1.0774 2.76607,-1.9589 3.98011,-1.9589 1.91826,0 2.28765,0.68753 2.82066,5.25 0.33734,2.8875 0.4264,6.15 0.19791,7.25 -0.22848,1.1 -0.6761,3.2375 -0.9947,4.75 -0.53504,2.53994 -2.86076,3.74965 -3.84508,2 z m -20.1394,-3.47251 c -1.11749,-1.59544 -1.51155,-4.34633 -1.39666,-9.75 0.088,-4.14012 0.32918,-5.95249 0.53592,-4.02749 1.06111,9.88038 5.29481,12.46707 5.31935,3.25 0.0111,-4.14972 0.29159,-5.33254 1.00802,-4.25 1.88648,2.85051 -0.72336,17 -3.13561,17 -0.42587,0 -1.47483,-1.00013 -2.33102,-2.22251 z"
+ style="fill:#f87844" />
+ <path
+ id="path3145"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.22583,-4.08894 -2.20836,-8.16986 l -1.78643,-7.41986 2.26013,-1.83014 c 4.07651,-3.30096 5.69263,-2.4342 6.37653,3.41986 0.33734,2.8875 0.4264,6.15 0.19791,7.25 -0.22848,1.1 -0.6761,3.2375 -0.9947,4.75 -0.53504,2.53994 -2.86076,3.74965 -3.84508,2 z m -20.1394,-3.47251 c -1.68769,-2.40951 -2.14046,-8.77749 -0.62409,-8.77749 0.51294,0 1.21826,0.9 1.56739,2 0.34913,1.1 1.27945,2 2.06739,2 1.48177,0 1.88623,2.65431 0.82562,5.41821 -0.83507,2.17617 -1.9995,1.9817 -3.83631,-0.64072 z m 4.45861,-10.58651 c -0.009,-2.62138 0.37634,-4.06696 0.98469,-3.69098 1.2685,0.78398 1.2685,4.53713 0,6.5 -0.70877,1.09674 -0.97349,0.34157 -0.98469,-2.80902 z"
+ style="fill:#f96547" />
+ <path
+ id="path3143"
+ d="m 181.27056,911.1936 c -0.23207,-0.4125 -1.2224,-4.07496 -2.20075,-8.13879 l -1.77881,-7.38879 2.39173,-1.85364 c 1.31545,-1.0195 3.06673,-1.73864 3.89173,-1.59809 2.56229,0.43651 3.33281,10.73419 1.34529,17.97931 -0.48139,1.75482 -2.85813,2.40613 -3.64919,1 z m -20.1394,-3.47251 c -1.71422,-2.44739 -2.08719,-7.33159 -0.6287,-8.23299 0.51041,-0.31545 1.21573,0.33299 1.56739,1.44098 0.35166,1.10799 1.28406,2.01452 2.072,2.01452 1.54518,0 1.75012,1.2133 0.80232,4.75 -0.76127,2.84068 -1.83714,2.84843 -3.81301,0.0275 z m 4.71566,-10.77749 c 0,-2.475 0.19502,-3.4875 0.43337,-2.25 0.23836,1.2375 0.23836,3.2625 0,4.5 -0.23835,1.2375 -0.43337,0.225 -0.43337,-2.25 z"
+ style="fill:#f87637" />
+ <path
+ id="path3141"
+ d="m 181.27056,911.1936 c -1.3015,-2.31344 -3.81424,-15.51051 -3.07198,-16.13419 2.11924,-1.78067 6.32464,-3.00774 6.93324,-2.023 0.89503,1.44819 0.93106,13.97216 0.0479,16.65719 -0.71185,2.16425 -3.03417,3.05535 -3.90918,1.5 z m -20.1394,-3.47251 c -1.89753,-2.7091 -2.11846,-8.13141 -0.3067,-7.52749 0.6875,0.22917 1.25,0.97794 1.25,1.66394 0,0.68601 0.76594,1.80735 1.70209,2.49188 1.09786,0.80278 1.5002,2.01663 1.13337,3.41939 -0.72377,2.76767 -1.81644,2.75388 -3.77876,-0.0477 z"
+ style="fill:#f95947" />
+ <path
+ id="path3139"
+ d="m 181.07693,908.3252 c -0.89888,-2.13488 -1.88744,-5.97767 -2.19679,-8.53953 -0.53507,-4.43117 -0.41126,-4.73611 2.54336,-6.26401 3.06503,-1.58498 3.11446,-1.57168 3.76318,1.01304 0.83773,3.33777 -0.26675,15.46342 -1.52292,16.71959 -0.60332,0.60333 -1.55161,-0.47042 -2.58683,-2.92909 z m -19.94937,-1.9409 c -1.73917,-2.65431 -1.76322,-6.12764 -0.0394,-5.6907 0.54247,0.1375 0.98631,0.73627 0.98631,1.33061 0,0.59434 0.79532,1.66216 1.76737,2.37295 1.05669,0.77267 1.51631,1.94659 1.14301,2.91938 -0.87597,2.28274 -1.91533,2.03154 -3.85728,-0.93224 z"
+ style="fill:#f86636" />
+ <path
+ id="path3137"
+ d="m 181.03879,908.23391 c -0.87791,-2.08467 -1.8542,-5.92781 -2.16955,-8.54031 -0.47898,-3.96811 -0.30352,-4.75 1.06593,-4.75 0.90161,0 1.63929,-0.45 1.63929,-1 0,-0.55 0.61703,-1 1.37117,-1 2.65993,0 3.14174,16.94693 0.52774,18.56248 -0.46111,0.28498 -1.55667,-1.1875 -2.43458,-3.27217 z m -19.84932,-1.75513 c -1.98831,-3.03454 -2.07595,-5.20185 -0.21035,-5.20185 0.77256,0 1.20208,0.52791 0.95449,1.17312 -0.24759,0.64522 0.24531,1.75032 1.09534,2.45578 1.6689,1.38507 2.10285,4.03777 0.66052,4.03777 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z"
+ style="fill:#f87625" />
+ <path
+ id="path3135"
+ d="m 181.03879,908.23391 c -2.37362,-5.63637 -3.12438,-13.29031 -1.30362,-13.29031 0.79161,0 1.97929,0.54 2.63929,1.2 0.93333,0.93333 1.22435,0.65556 1.30957,-1.25 0.064,-1.43104 0.49036,-0.57843 1.02516,2.05 0.97852,4.80922 0.25046,13.6439 -1.19815,14.5392 -0.48183,0.29778 -1.59434,-1.16422 -2.47225,-3.24889 z m -19.84932,-1.75513 c -0.88826,-1.35565 -1.61277,-3.26815 -1.61004,-4.25 0.004,-1.38626 0.55447,-1.11479 2.46403,1.21482 2.5072,3.05871 3.23781,5.5 1.64601,5.5 -0.48675,0 -1.61175,-1.10917 -2.5,-2.46482 z"
+ style="fill:#f84c44" />
+ <path
+ id="path3133"
+ d="m 180.2359,905.85828 c -2.08019,-6.44092 -2.17055,-10.91468 -0.22046,-10.91468 0.79254,0 1.78583,0.55796 2.2073,1.23992 0.51891,0.83962 0.96887,0.43607 1.39375,-1.25 0.46839,-1.85877 0.80267,-0.96902 1.31871,3.51008 0.71114,6.17236 -0.18036,11.60654 -2.00382,12.21436 -0.56872,0.18957 -1.78169,-1.97028 -2.69548,-4.79968 z m -18.5123,-0.55793 c -1.29298,-1.23837 -2.18431,-2.75123 -1.98075,-3.36191 0.20356,-0.61068 1.41357,0.30103 2.68891,2.02602 2.80692,3.79656 2.48839,4.39744 -0.70816,1.33589 z"
+ style="fill:#f86827" />
+ <path
+ id="path3131"
+ d="m 180.2359,905.85828 c -1.86184,-5.76484 -2.17392,-10.91468 -0.66144,-10.91468 0.55,0 1,0.45 1,1 0,0.55 0.68465,1 1.52144,1 2.50204,0 3.88913,4.40836 2.87647,9.14182 -0.49385,2.30842 -1.38776,4.35915 -1.98647,4.55717 -0.59871,0.19803 -1.83621,-1.95491 -2.75,-4.78431 z m -18.5123,-0.55793 c -1.29298,-1.23837 -2.18431,-2.75123 -1.98075,-3.36191 0.20356,-0.61068 1.41357,0.30103 2.68891,2.02602 2.80692,3.79656 2.48839,4.39744 -0.70816,1.33589 z"
+ style="fill:#f8543b" />
+ <path
+ id="path3129"
+ d="m 180.29865,905.15272 c -0.94831,-3.19444 -1.72419,-6.51091 -1.72419,-7.36993 0,-2.36962 4.94315,-1.05807 6.17129,1.6374 1.14526,2.51357 -0.10153,10.66682 -1.71332,11.20409 -0.55528,0.18509 -1.78548,-2.27711 -2.73378,-5.47156 z"
+ style="fill:#f8641b" />
+ <path
+ id="path3127"
+ d="m 180.29609,905.14412 c -0.9469,-3.18971 -1.72163,-6.55059 -1.72163,-7.46861 0,-2.24903 2.73366,-1.14642 3.55227,1.43279 0.39906,1.25732 1.18505,1.76634 2.15355,1.39469 1.29252,-0.49599 1.41642,0.14122 0.81229,4.17768 -1.24083,8.29061 -2.43855,8.40634 -4.79648,0.46345 z"
+ style="fill:#f84936" />
+ <path
+ id="path3125"
+ d="m 181.14286,906.45307 c -1.73239,-4.14621 -2.09098,-9.50947 -0.63579,-9.50947 0.51294,0 1.22859,0.93254 1.59034,2.07232 0.41698,1.31378 1.20605,1.86191 2.15571,1.49749 1.24752,-0.47871 1.38241,0.1362 0.80674,3.67768 -0.9703,5.96925 -2.09631,6.6195 -3.917,2.26198 z"
+ style="fill:#f85818" />
+ <path
+ id="path3123"
+ d="m 181.09683,906.3429 c -0.88794,-2.12514 -1.44768,-5.22186 -1.24388,-6.8816 l 0.37056,-3.0177 0.81643,3.32977 c 0.62382,2.54421 1.24413,3.21792 2.62934,2.85569 1.54861,-0.40498 1.72746,-0.0157 1.22681,2.67022 -0.91755,4.92246 -2.04875,5.23318 -3.79926,1.04362 z"
+ style="fill:#f84528" />
+ <path
+ id="path3121"
+ d="m 182.18715,908.75698 c -2.04329,-7.19112 -2.31672,-8.87827 -1.51879,-9.37142 0.49836,-0.30799 0.9061,0.36656 0.9061,1.49902 0,1.16357 0.65233,2.05902 1.5,2.05902 0.99331,0 1.5,0.99344 1.5,2.94098 0,3.06564 -1.73817,5.15699 -2.38731,2.8724 z"
+ style="fill:#f83b28" />
+ <path
+ id="path3119"
+ d="m 181.63518,905.09018 c -0.68081,-1.64361 -1.02518,-3.81148 -0.76528,-4.81748 0.38073,-1.47369 0.4951,-1.3919 0.58856,0.4209 0.0661,1.28178 0.76148,2.25 1.616,2.25 1.64633,0 1.93861,1.75999 0.63396,3.81749 -0.60865,0.95987 -1.1714,0.50633 -2.07324,-1.67091 z"
+ style="fill:#f8461a" />
+ <path
+ id="path3117"
+ d="m 182.21283,906.4436 c -0.3471,-0.90455 -0.005,-1.5 0.86163,-1.5 0.86669,0 1.20873,0.59545 0.86163,1.5 -0.31659,0.825 -0.70432,1.5 -0.86163,1.5 -0.15731,0 -0.54504,-0.675 -0.86163,-1.5 z"
+ style="fill:#f8381c" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/css/jquery.svg.css b/bundles/XO/karma/lessons/Conozco-Uruguay/css/jquery.svg.css
new file mode 100755
index 0000000..c409af9
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/css/jquery.svg.css
@@ -0,0 +1,15 @@
+/* http://keith-wood.name/svg.html
+ SVG for jQuery v1.4.2.
+ Written by Keith Wood (kbwood{at}iinet.com.au) August 2007.
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
+ Please attribute the author if you use it. */
+
+:svg {
+ display: none;
+}
+
+.svg_error {
+ color: red;
+ font-weight: bold;
+}
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/css/lesson.css b/bundles/XO/karma/lessons/Conozco-Uruguay/css/lesson.css
new file mode 100755
index 0000000..1c24338
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/css/lesson.css
@@ -0,0 +1,76 @@
+body {
+ position: relative;
+}
+
+#map {
+display:inline;
+float:left;
+height:100%;
+width:60%;
+}
+#capitals {
+height:450px;
+width:450px;
+}
+#side {
+display:inline;
+float:left;
+height:450px;
+position:relative;
+width:40%;
+}
+#sideTop {
+display:block;
+float:left;
+width:100%;
+}
+
+.icon {
+ width: 50px;
+ height: 50px;
+ display: inline;
+ float:left;
+ padding: 10px;
+ cursor: pointer;
+}
+
+.iconSVG {
+ cursor: pointer;
+}
+
+#alien {
+display:block;
+float:left;
+height:300px;
+width:204px;
+}
+#spaceship {
+left:-80px;
+position:absolute;
+width:100px;
+height:205px;
+bottom:0px;
+}
+
+#playAgain {
+ position: absolute;
+ opacity: 0;
+}
+
+#helpScreen{
+ position: absolute;
+ z-index:20;
+}
+
+
+/* CSS Rules for SVG images */
+.text { display: none; }
+.capital.city { cursor: pointer;}
+
+.spaceship { display: none;}
+
+#answerYes,#answerNo{
+ cursor: pointer;
+}
+
+
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/index.html b/bundles/XO/karma/lessons/Conozco-Uruguay/index.html
new file mode 100755
index 0000000..fba0dc8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/index.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Conozco a Uruguay</title>
+ <meta name="keywords"
+ content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,urugay" />
+ <link rel="stylesheet" type="text/css" href="jquery.svg.css" />
+ <link rel="stylesheet" type="text/css" href="css/lesson.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="../../js/jquery.svg.js"></script>
+ <script type="text/javascript" src="../../js/jquery.svgdom.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+
+
+ </head>
+ <body>
+ <div id="map">
+ <object id="capitals" data="assets/svg/capitals2.svg" type="image/svg+xml">
+ </object>
+
+ </div>
+ <div id="side">
+
+ <div id="sideTop">
+ <object id="helpIcon" class="icon" title="Click for Help"
+ data="assets/svg/helpIcon.svg" type="image/svg+xml">
+ </object>
+ <object id="quitIcon" class="icon" title="Click to Quit"
+ data="assets/svg/quitIcon.svg" type="image/svg+xml">
+ </object>
+ </div>
+ <object id="alien" data="assets/svg/alien5.svg" type="image/svg+xml">
+ </object>
+ <object id="spaceship" data="assets/svg/spaceship80x200.svg" type="image/svg+xml">
+ </object>
+ </div>
+ <div id="overlay"></div>
+ <object id="helpScreen" data="assets/svg/helpScreen.svg"
+ type="image/svg+xml">
+ </object>
+ <object id="playAgain" data="assets/svg/playAgain.svg"
+ type="image/svg+xml">
+ </object>
+ <div id="helpOverlay"></div>
+ </body>
+</html>
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/js/lesson.js b/bundles/XO/karma/lessons/Conozco-Uruguay/js/lesson.js
new file mode 100755
index 0000000..5e8e890
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/js/lesson.js
@@ -0,0 +1,337 @@
+$(document).ready(
+ function(){
+ var k = Karma({
+ svg :[
+ {name:'capitals', domId: 'capitals'},
+ {name:'alien', domId: 'alien'},
+ {name:'spaceship', domId: 'spaceship'},
+ {name: 'help', domId: 'helpScreen'},
+ {name:'playAgain', domId:'playAgain'},
+ {name:'helpIcon', domId:'helpIcon'},
+ {name:'quitIcon', domId:'quitIcon'}
+ ],
+ audio:[
+ {name:'correct', file:'correct.ogg'},
+ {name:'incorrect', file:'incorrect.ogg'}
+ ]
+ });
+
+ k.ready(function() {
+ //Program constants
+ var MAX_SCREEN_X = 800, MAX_SCREEN_Y = 500;
+
+ var CAPITALS = [{dept:'artigas', capital:'artigas',
+ deptName:'Artigas', capitalName:'Artigas'},
+ {dept:'rivera', capital:'rivera', deptName:'Rivera', capitalName:'Rivera'},
+ {dept:'salto', capital:'salto', deptName:'Salto', capitalName:'Salto'},
+ {dept:'paysandu', capital:'paysandu', deptName:'Paysandu',
+ capitalName:'Paysandu'},
+ {dept:'rioNegro', capital:'frayBentos', deptName:'Rio Negro',
+ capitalName:'Fray Bentos'},
+ {dept:'tacuarembo', capital:'tacuarembo', deptName:'Tacuarembo',
+ capitalName:'Tacuarembo'},
+ {dept:'cerroLargo', capital:'melo', deptName:'Cerro Largo',
+ capitalName:'Melo'},
+ {dept:'durazno', capital:'durazno', deptName:'Durazno', capitalName:'Durazno'},
+ {dept:'treintaYTres', capital:'treintaYTres', deptName:'Treinta Y Tres',
+ capitalName:'Treinta Y Tres'},
+ {dept:'soriano', capital:'mercedes', deptName:'Soriano',
+ capitalName:'Mercedes'},
+ {dept:'flores', capital:'trinidad', deptName:'Flores', capitalName:'Trinidad'},
+ {dept:'colonia', capital:'colonia', deptName:'Colonia', capitalName:'Colonia'},
+ {dept:'sanJose', capital:'sanJose', deptName:'San Jose',
+ capitalName:'San Jose de Mayo'},
+ {dept:'montevideo', capital:'montevideo', deptName:'Montevideo',
+ capitalName:'Montevideo'},
+ {dept:'lavalleja', capital:'minas', deptName:'Lavalleja',
+ capitalName:'Minas'},
+ {dept:'rocha', capital:'rocha', deptName:'Rocha', capitalName:'Rocha'},
+ {dept:'canelones', capital:'canelones', deptName:'Canelones',
+ capitalName:'Canelones'},
+ {dept:'maldonado', capital:'maldonado', deptName:'Maldonado',
+ capitalName:'Maldonado'}
+ ];
+ var parts = ['shipLtWing', 'shipRtWing', 'shipBottom', 'shipBody',
+ 'shipCone', 'shipLtJet', 'shipRtJet'];
+ var fires = ['shipFire1', 'shipFire2'];
+
+ //Game Control
+ var isActive = false;
+ var shouldShowHelp = false;
+ var question = [];
+ var questions = CAPITALS;
+ var lastQuestion = '';
+ var displayedItems = [];
+ var capRoot = k.svg.capitals.root;
+ var alienRoot = k.svg.alien.root;
+ var spaceshipRoot = k.svg.spaceship.root;
+
+ var alienBubble = $('foreignObject #alienQuestion', alienRoot);
+
+ var hideSpaceship = function() {
+ var hideElems = function(id){
+ $("#" + id, spaceshipRoot).css('display','none');
+ };
+ parts.map(hideElems);
+ fires.map(hideElems);
+ };
+
+ //hideSpaceship();
+
+ var scaleSvgs = function(svgs) {
+ var scaleView = function (svgRoot) {
+
+
+ var width = window.innerWidth;
+ var height = window.innerHeight;
+ var newRatio = 1;
+ var xRatio = width/MAX_SCREEN_X;
+ var yRatio = height/MAX_SCREEN_Y;
+
+ //get the smallest ratio
+ newRatio = xRatio > yRatio ? yRatio : xRatio;
+
+ if (newRatio < 1) {
+ svgRoot.currentScale = newRatio - 0.05;
+ return newRatio;
+ } else {
+ //do nothing
+ return newRatio;
+ }
+ };
+
+ for (var svg in svgs){
+ if (svgs.hasOwnProperty(svg)){
+ scaleView(svgs[svg].root);
+ }
+ }
+
+ };
+
+ //scaleSvgs(k.svg);
+
+
+ //gameplay functions
+ var changeQuestion = function (questions){
+ var index = Math.round(Math.random() * (questions.length - 1));
+ var question = questions[index];
+
+ //drop the city used from the list of answers
+ if (index === 0 ){
+ questions.shift();
+ } else {
+ questions.splice(index, 1);
+ }
+
+ return question;
+ };
+
+
+ var askQuestion = function (questions, isWrong) {
+ if (isWrong){
+ alienBubble.text(lastQuestion);
+ return;
+ }
+
+ question = changeQuestion(questions);
+ alienBubble.text("Where is the \n capital of \n " +
+ question.deptName + "?");
+ lastQuestion = "Where is the \n capital of \n " +
+ question.deptName + "?";
+ };
+
+
+ var checkAnswer = function (mapElem) {
+
+ var askNextQuestion = function(){
+ var timerID = setTimeout(function() {
+ alienBubble.text('');
+ askQuestion(questions);
+ }, 3000);
+ };
+
+ if(isActive){
+ if ( ("cap" + question.capital).toLowerCase() ===
+ mapElem.id.toLowerCase()){
+
+ var part = parts.splice(0,1)[0];
+ $('#' + part, spaceshipRoot).css('display', 'block');
+ alienBubble.text("Correct! " + question.capitalName +
+ " is the capital of " + question.deptName);
+ k.audio.correct.play();
+
+ var text = $('.text.' + question.dept, capRoot);
+ text.css('display', "block");
+ displayedItems.push(text);
+
+ if (parts.length === 0){
+ // We're done!
+ isActive = false;
+ alienBubble.text("Great Job! I can go home now.");
+ setTimeout(function(){
+ $('#alien').hide();
+ flyAway();
+ }, 1000);
+
+ } else {
+ askNextQuestion();
+ }
+
+ } else {
+ alienBubble.text("Incorrect. Please try again.");
+ k.audio.incorrect.play();
+
+ setTimeout(function(){
+ askQuestion(questions, true);
+ },1000);
+ }
+ }
+
+ };
+
+ var flyAway = function(){
+ var isLaunching = true;
+
+ var startEngines = function(){
+ var shipFire1 = $('#shipFire1', spaceshipRoot);
+ var shipFire2 = $('#shipFire2', spaceshipRoot);
+ var toggle = true;
+
+ var toggleFires = function(){
+ if(isLaunching){
+ if(toggle){
+ shipFire1.css('display', "none");
+ shipFire2.css('display', "block");
+ }else{
+ shipFire1.css('display', "block");
+ shipFire2.css('display', "none");
+ }
+ //toggle fires
+ toggle = !toggle;
+ setTimeout(toggleFires, 400);
+ }
+ };
+
+ toggleFires();
+ };
+
+
+ var fly = function(){
+ $('#spaceship').animate({"bottom":"550px"},
+ {"duration":8000,
+ "complete": function(){
+ isLaunching = false;
+ showPlayAgain();
+ }});
+ };
+
+ var blastOff = function(){
+ startEngines();
+ setTimeout(fly, 2000);
+ };
+
+ blastOff();
+
+
+ };
+
+
+
+ var showHelpMessage = function(){
+ shouldShowHelp = true;
+ $('#overlay').css({"position": "absolute",
+ "background": "white", "opacity": "0.8",
+ 'width': 800, 'height': 500,
+ 'display':'block', "z-index": 10});
+ $('#helpScreen').css({"position": "absolute",
+ "width": "420px", "height": "360px",
+ 'top': '25px', 'left': '20%',
+ 'z-index' : 20, 'display':'block', "opacity": 1});
+
+ //Chromium HACK: for some reason chromium
+ //won't let me bind a click event to the #help SVG
+ //so I am using a transparent overlay instead,
+ //the opposite is true for Firefox
+ $('#helpOverlay').css({"position": "absolute",
+ "width": "420px", "height": "360px",
+ 'top': '25px', 'left': '20%',
+ 'z-index' : 21, 'display':'', "opacity": 0});
+
+ //Important u need to hide the playAgain screen too
+ $('#helpOverlay,#helpScreen')
+ .bind('click', function(){
+ if (shouldShowHelp === false){
+ return;
+ } else if(!isActive){
+ $('#overlay,#helpScreen,#playAgain,#helpOverlay')
+ .css({"opacity":0, 'display': 'none'});
+ isActive = true;
+ shouldShowHelp = false;
+ askQuestion(questions);
+ } else {
+ $('#overlay,#helpScreen,#helpOverlay')
+ .css({"opacity":0, 'display': 'none'});
+ return;
+ }
+ });
+
+ };
+
+ var showPlayAgain = function(){
+ //$('#overlay').css({"position": "absolute",
+ // "background": "white", "opacity": "0.8",
+ // 'width': 800, 'height': 500,
+ // 'display':'', "z-index": 10});
+ $('#playAgain').css({"position": "absolute",
+ "width": "420px", "height": "360px",
+ 'top': '25px', 'left': '20%',
+ 'z-index' : 22, 'display':'block', "opacity": 1});
+
+ var playAgain = function () {
+ console.log('inside playagain');
+ var hideDisplayedItems = function(){
+ for (var i = 0; i < displayedItems.length; i++){
+ displayedItems[i].css('display','none');
+ }
+ };
+
+ hideDisplayedItems();
+
+ $('#alien').show();
+ $('#playAgain').css('display', 'none');
+ askQuestion(questions);
+ };
+
+ var quit = function () {
+ $('#playAgain').css('opacity', 0);
+
+ };
+
+ //jQuery SVG bind doesn't seem to work on chromium
+ $('#answerYes', k.svg.playAgain.root)[0]
+ .addEventListener('click', playAgain, false);
+ $('#answerNo', k.svg.playAgain.root)[0]
+ .addEventListener('click', quit, false);
+
+
+ };
+
+
+ //binding Event Handlers
+
+ $('#helpIcon', k.svg.helpIcon.root).bind('click', function(){
+ showHelpMessage();
+ });
+
+ $.map($('.capital.city', capRoot), function(elem){
+ $(elem, capRoot).bind('click', function(event) {
+ checkAnswer(event.target);
+ });
+ });
+
+
+ showHelpMessage();
+ });
+
+});
+
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/tests.html b/bundles/XO/karma/lessons/Conozco-Uruguay/tests.html
new file mode 100755
index 0000000..cb1f7c7
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/tests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Tests for conozco Uruguay</title>
+
+</head>
+<body>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/tests/index.html b/bundles/XO/karma/lessons/Conozco-Uruguay/tests/index.html
new file mode 100755
index 0000000..cb1f7c7
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/tests/index.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Tests for conozco Uruguay</title>
+
+</head>
+<body>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Conozco-Uruguay/tests/tests.js b/bundles/XO/karma/lessons/Conozco-Uruguay/tests/tests.js
new file mode 100755
index 0000000..540473e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Conozco-Uruguay/tests/tests.js
@@ -0,0 +1,2 @@
+//tests for Conozco Uruguay
+
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/audio/correct.ogg b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/1.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/1.png
new file mode 100755
index 0000000..228dee5
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/10.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/10.png
new file mode 100755
index 0000000..fe2fcd5
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/10.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/11.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/11.png
new file mode 100755
index 0000000..1ee13fa
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/11.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/12.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/12.png
new file mode 100755
index 0000000..26bfe83
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/12.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/13.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/13.png
new file mode 100755
index 0000000..520e86b
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/13.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/14.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/14.png
new file mode 100755
index 0000000..b9fe502
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/14.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/15.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/15.png
new file mode 100755
index 0000000..3240769
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/15.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/16.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/16.png
new file mode 100755
index 0000000..60d1ba0
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/16.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/2.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/2.png
new file mode 100755
index 0000000..ce9ac3c
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/3.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/3.png
new file mode 100755
index 0000000..9531865
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/4.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/4.png
new file mode 100755
index 0000000..f436bcd
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/5.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/5.png
new file mode 100755
index 0000000..af7f7c4
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/6.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/6.png
new file mode 100755
index 0000000..ed048ae
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/7.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/7.png
new file mode 100755
index 0000000..b71da02
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/8.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/8.png
new file mode 100755
index 0000000..5b32426
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/9.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/9.png
new file mode 100755
index 0000000..ca2c60d
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/img1.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/img1.png
new file mode 100755
index 0000000..4d0c15b
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img1/img1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/1.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/1.png
new file mode 100755
index 0000000..b85d3cf
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/10.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/10.png
new file mode 100755
index 0000000..5b05c21
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/10.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/11.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/11.png
new file mode 100755
index 0000000..2ad0a9d
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/11.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/12.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/12.png
new file mode 100755
index 0000000..405154e
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/12.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/13.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/13.png
new file mode 100755
index 0000000..21d5408
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/13.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/14.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/14.png
new file mode 100755
index 0000000..632d9c8
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/14.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/15.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/15.png
new file mode 100755
index 0000000..2acc8e3
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/15.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/16.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/16.png
new file mode 100755
index 0000000..55603f1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/16.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/2.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/2.png
new file mode 100755
index 0000000..f9cecf8
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/3.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/3.png
new file mode 100755
index 0000000..f72c8c9
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/4.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/4.png
new file mode 100755
index 0000000..3baa0f1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/5.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/5.png
new file mode 100755
index 0000000..21e35dd
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/6.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/6.png
new file mode 100755
index 0000000..96cbb6e
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/7.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/7.png
new file mode 100755
index 0000000..b009529
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/8.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/8.png
new file mode 100755
index 0000000..6e6d65e
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/9.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/9.png
new file mode 100755
index 0000000..98b54eb
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/img2.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/img2.png
new file mode 100755
index 0000000..cf91a83
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img2/img2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/1.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/1.png
new file mode 100755
index 0000000..d8aa161
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/10.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/10.png
new file mode 100755
index 0000000..e5aa0b6
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/10.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/11.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/11.png
new file mode 100755
index 0000000..a0006f3
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/11.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/12.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/12.png
new file mode 100755
index 0000000..1ae0a06
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/12.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/13.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/13.png
new file mode 100755
index 0000000..5018862
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/13.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/14.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/14.png
new file mode 100755
index 0000000..f96e47a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/14.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/15.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/15.png
new file mode 100755
index 0000000..57fc10c
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/15.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/16.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/16.png
new file mode 100755
index 0000000..67d4454
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/16.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/2.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/2.png
new file mode 100755
index 0000000..782c956
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/3.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/3.png
new file mode 100755
index 0000000..c9d9cd3
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/4.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/4.png
new file mode 100755
index 0000000..741c750
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/5.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/5.png
new file mode 100755
index 0000000..9babc2f
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/6.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/6.png
new file mode 100755
index 0000000..de13592
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/7.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/7.png
new file mode 100755
index 0000000..7689919
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/8.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/8.png
new file mode 100755
index 0000000..fa5daba
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/9.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/9.png
new file mode 100755
index 0000000..88cd312
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/img3.png b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/img3.png
new file mode 100755
index 0000000..21099d1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/assets/image/img3/img3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/css/lesson.css b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/css/lesson.css
new file mode 100755
index 0000000..a77a19b
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/css/lesson.css
@@ -0,0 +1,51 @@
+body {
+ background: #affafc;
+ }
+
+#gamearea{
+ float:right;
+ width: 664px;
+ border: 5px gold dashed;
+ padding: 10px;
+}
+
+#feedback_image #img1,#img2,#img3 {
+ display: none;
+}
+
+.dragme {
+ width: 160px;
+ height: 120px;
+ padding: 1px 3px 0px 3px; /*top right bottom left*/
+ cursor: move;
+
+}
+
+#imageBar{
+ margin-left: 20px;
+ margin-top:15px;
+ float:left;
+ width: 225px;
+ height: 495px;
+ border: 2px solid red;
+
+}
+
+.imageThumb{
+ margin: 5px;
+ width: 200px;
+ height: 138px;
+ border: 2px groove #00FF00;
+ padding: 5px;
+ margin 1em;
+}
+
+.imgMain{
+ width: 640px;
+ height: 480px;
+ float : right;
+ padding : 10px;
+ visibility: hidden;
+ position:relative;
+}
+ \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/index.html b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/index.html
new file mode 100755
index 0000000..f0cc0fa
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/index.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title> English_Alphabet Puzzle Solving Game </title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en-us" />
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,image puzzle" />
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link rel="stylesheet" type="text/css" href="css/lesson.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+ </head>
+ <body>
+ <div id = "imageBar">
+ <a href="#" id="anchorImg1"><img class="imageThumb" src="assets/image/img1/img1.png" alt="" /></a>
+ <a href="#" id="anchorImg2"><img class="imageThumb" src="assets/image/img2/img2.png" alt="" /></a>
+ <a href="#" id="anchorImg3"><img class="imageThumb" src="assets/image/img3/img3.png" alt="" /></a>
+ </div>
+ <div id="gamearea">
+ <div id="feedback_image">
+ <img id="img1" src="assets/image/img1/img1.png" alt=""/>
+ <img id="img2" src="assets/image/img2/img2.png" alt=""/>
+ <img id="img3" src="assets/image/img3/img3.png" alt=""/>
+ </div>
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/js/lesson.js b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/js/lesson.js
new file mode 100755
index 0000000..2e2018a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Alphabet_Puzzle_Solving/js/lesson.js
@@ -0,0 +1,218 @@
+$(document).ready(function() {
+ var k = Karma({
+ audio: [{'name':'correct','file':'correct.ogg'}]});
+
+ k.ready(function(){
+
+ //initialize the variables used and display initial value
+ var drag_no = 0; //store the current dragged no
+ var drop_no = 0; //store the current dropped on no
+ var imgrand = []; //stores the random variables generated
+ var imgPosition = []; //stores the position of the random variable
+ var drag_position = 0; //position of dragged object
+ var drop_position = 0; //position of dropped object
+ var flag, i ,j;
+ var moves_count = 0;
+ var imgPath;
+
+
+ var feedbackImage = $('#feedback_image');
+ for(var i=0; i<16; i++){
+ feedbackImage.append("<img class='dragme' id='imgdrag" +
+ i + "' draggable='true' src='' alt='' />");
+ }
+
+
+ game("img1");
+
+ $('a#anchorImg1').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img1");
+
+
+ });
+
+ $('a#anchorImg2').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img2");
+
+ });
+
+ $('a#anchorImg3').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img3");
+
+ });
+
+ function generate_random_no() { //generate random number
+ var rand_no = Math.ceil(16*Math.random());
+ return rand_no;
+ }
+
+ //update the Random variable number according to the position
+ //update number according to the position and the value
+ function update_Numbers_position(){
+ imgrand[drag_position] = drop_no;
+ imgrand[drop_position] = drag_no;
+ }
+
+ //Check the game over
+ function check_game_over(){
+ var x = 0;
+ for(i=0;i<16;i++){
+ if(imgrand[i] == i+1){
+ x++;
+ }
+ }
+ if(x == 16){ //puzzle solved . Hurray
+ k.audio.correct.play();
+ $(".dragme").hide();
+ $("#"+imgPath+"").fadeIn(5000);
+
+
+ }
+ }
+
+ function game(imgPuzzle){ //draws the necessary random numbers for the game
+ imgPath = imgPuzzle;
+ imgrand[0]=generate_random_no(); //1 number generated, 3 different numbers to be generated
+ for(i=1; i<16; i++){
+ do{
+ flag = 0;
+ imgrand[i] = generate_random_no();
+ for(j=0; j<i; j++){
+ if(imgrand[i]===imgrand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+ for(i=0; i<16; i++){
+ imgPosition[i] = i;
+ document.getElementById("imgdrag"+i+"").src = "assets/image/"+imgPath+"/"+imgrand[i]+".png";
+ }
+
+ } //end of game()
+ $('#feedback_image').bind('dragstart', function(ev) {
+ if (!$(ev.target).hasClass('dragme'))
+ return true;
+ switch (ev.target.id) {
+ case 'imgdrag0':
+ drag_no = imgrand[0]; drag_position = 0; break;
+ case 'imgdrag1':
+ drag_no = imgrand[1]; drag_position = 1; break;
+ case 'imgdrag2':
+ drag_no = imgrand[2]; drag_position = 2; break;
+ case 'imgdrag3':
+ drag_no = imgrand[3]; drag_position = 3; break;
+ case 'imgdrag4':
+ drag_no = imgrand[4]; drag_position = 4; break;
+ case 'imgdrag5':
+ drag_no = imgrand[5]; drag_position = 5; break;
+ case 'imgdrag6':
+ drag_no = imgrand[6]; drag_position = 6; break;
+ case 'imgdrag7':
+ drag_no = imgrand[7]; drag_position = 7; break;
+ case 'imgdrag8':
+ drag_no = imgrand[8]; drag_position = 8; break;
+ case 'imgdrag9':
+ drag_no = imgrand[9]; drag_position = 9; break;
+ case 'imgdrag10':
+ drag_no = imgrand[10]; drag_position = 10; break;
+ case 'imgdrag11':
+ drag_no = imgrand[11]; drag_position = 11; break;
+ case 'imgdrag12':
+ drag_no = imgrand[12]; drag_position = 12; break;
+ case 'imgdrag13':
+ drag_no = imgrand[13]; drag_position = 13; break;
+ case 'imgdrag14':
+ drag_no = imgrand[14]; drag_position = 14; break;
+ case 'imgdrag15':
+ drag_no = imgrand[15]; drag_position = 15; break;
+ }
+
+ //document.display.dragBox.value = drag_no;
+ //document.display.dragPos.value = drag_position;
+
+ return true;
+ });
+
+ // Set up the drop zone.
+ $('#feedback_image').bind('dragenter', function(ev) { // Update the drop zone class on drag enter/leave
+ if (!$(ev.target).hasClass('dragme')) return true;
+ $(ev.target).addClass('dragover'); return false;
+ })
+
+ .bind('dragleave', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ $(ev.target).removeClass('dragover'); return false;
+ })
+
+ // Allow drops of any kind into the zone.
+ .bind('dragover', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ return false;
+ })
+
+ // Handle the final drop...
+ .bind('drop', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ switch (ev.target.id) {
+ case 'imgdrag0':
+ drop_no = imgrand[0]; drop_position = 0; break;
+ case 'imgdrag1':
+ drop_no = imgrand[1]; drop_position = 1; break;
+ case 'imgdrag2':
+ drop_no = imgrand[2]; drop_position = 2; break;
+ case 'imgdrag3':
+ drop_no = imgrand[3]; drop_position = 3; break;
+ case 'imgdrag4':
+ drop_no = imgrand[4]; drop_position = 4; break;
+ case 'imgdrag5':
+ drop_no = imgrand[5]; drop_position = 5; break;
+ case 'imgdrag6':
+ drop_no = imgrand[6]; drop_position = 6; break;
+ case 'imgdrag7':
+ drop_no = imgrand[7]; drop_position = 7; break;
+ case 'imgdrag8':
+ drop_no = imgrand[8]; drop_position = 8; break;
+ case 'imgdrag9':
+ drop_no = imgrand[9]; drop_position = 9; break;
+ case 'imgdrag10':
+ drop_no = imgrand[10]; drop_position = 10; break;
+ case 'imgdrag11':
+ drop_no = imgrand[11]; drop_position = 11; break;
+ case 'imgdrag12':
+ drop_no = imgrand[12]; drop_position = 12; break;
+ case 'imgdrag13':
+ drop_no = imgrand[13]; drop_position = 13; break;
+ case 'imgdrag14':
+ drop_no = imgrand[14]; drop_position = 14; break;
+ case 'imgdrag15':
+ drop_no = imgrand[15]; drop_position = 15; break;
+ }
+
+ moves_count++;
+ //document.display.dropBox.value = drop_no;
+ //document.display.dropPos.value = drop_position;
+ //document.display.moves.value = moves_count;
+
+ document.getElementById("imgdrag"+imgPosition[drag_position]+"").src = "assets/image/"+imgPath+"/"+drop_no+".png";
+ document.getElementById("imgdrag"+imgPosition[drop_position]+"").src = "assets/image/"+imgPath+"/"+drag_no+".png";
+
+ update_Numbers_position();
+
+
+ //Game over condition
+ check_game_over();
+
+ ev.stopPropagation();
+ return false;
+ });
+
+ });
+}); //end of document.ready
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/audio/correct.ogg b/bundles/XO/karma/lessons/English_Animal_Identification/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/English_Animal_Identification/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/1.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/1.png
new file mode 100755
index 0000000..fe825da
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/2.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/2.png
new file mode 100755
index 0000000..758d6f5
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/3.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/3.png
new file mode 100755
index 0000000..2c86afb
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/4.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/4.png
new file mode 100755
index 0000000..8253cc5
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/5.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/5.png
new file mode 100755
index 0000000..609ab6e
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/6.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/6.png
new file mode 100755
index 0000000..ccc9cf1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/background.jpg b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/background.jpg
new file mode 100755
index 0000000..ca0ae47
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/background.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/correct.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/correct.png
new file mode 100755
index 0000000..d6e54a8
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/correct.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/1.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/1.png
new file mode 100755
index 0000000..6f01040
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/10.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/10.png
new file mode 100755
index 0000000..788fda4
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/10.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/2.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/2.png
new file mode 100755
index 0000000..143ae9d
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/3.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/3.png
new file mode 100755
index 0000000..eb0bfdf
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/4.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/4.png
new file mode 100755
index 0000000..c602d76
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/5.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/5.png
new file mode 100755
index 0000000..6211dd2
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/6.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/6.png
new file mode 100755
index 0000000..8e63238
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/7.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/7.png
new file mode 100755
index 0000000..9be09b3
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/8.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/8.png
new file mode 100755
index 0000000..efc190e
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/9.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/9.png
new file mode 100755
index 0000000..3e22423
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/image_name/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/incorrect.png b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/incorrect.png
new file mode 100755
index 0000000..789db87
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/incorrect.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/main.jpg b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/main.jpg
new file mode 100755
index 0000000..c764a7a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/main.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/orginal.jpg b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/orginal.jpg
new file mode 100755
index 0000000..869a3c1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/orginal.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/play_again.jpg b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/play_again.jpg
new file mode 100755
index 0000000..db3ae56
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/assets/image/play_again.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/css/lesson.css b/bundles/XO/karma/lessons/English_Animal_Identification/css/lesson.css
new file mode 100755
index 0000000..e11fb25
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/css/lesson.css
@@ -0,0 +1,87 @@
+@CHARSET "UTF-8";
+body {
+ background: url(../assets/image/background.jpg) no-repeat;
+}
+
+
+#gameArea{
+ margin-top:5%;
+ margin-left: 10%;
+ float: left;
+ width: 50%
+ padding:10px;
+}
+
+
+#questionBox{
+ color: red;
+ border: 3px outset #0AF9dd;
+ width: 150px;
+ padding: 5px;
+ background: #2EFEF7;
+ font: 20px "Helvetica", Verdana, Geneva, Arial, sans-serif;
+ font-weight: bold;
+
+}
+.imageBox{
+ margin-top: 25px;
+ margin-left: 30px;
+ width: 220px;
+ height: 220px;
+ padding: 10px;
+}
+
+.checkedOption{
+ margin-top: 100px;
+ width:120px;
+ height:120px;
+ padding: 5px;
+}
+
+#options{
+ margin-left:25px;
+ margin-top:50px;
+ width:600px;
+ height:80px;
+ padding: 10px;
+}
+
+.optImg{
+ width:120px;
+ height: 40px;
+ background-color: yellow;
+ padding:5px;
+ border: 2px solid green;
+}
+
+#scoreArea{
+ color: red;
+ width: 40%;
+ padding: 5px;;
+ background: #FFFFFF;
+ border: 2px solid red;
+ background: black;
+ padding: 10px;
+}
+.playAgain{
+ position:absolute;
+ top: 10px;
+ margin-left:220px;
+ width:115px;
+ height: 30px;
+ padding: 2px 2px 2px 2px;
+ }
+input{
+ color:green;
+
+}
+#gameOver{
+ margin-left:300px;
+ width: 180px;
+ height: 20px;
+ display: none;
+ font: 25px "Rockwell Extra Bold", Geneva, Arial, Helvetica, sans-serif,Times New Roman;
+ font-weight: bold;
+ background-color: #ccc;
+ padding: 10px;
+}
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/index.html b/bundles/XO/karma/lessons/English_Animal_Identification/index.html
new file mode 100755
index 0000000..e57dc72
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/index.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>English_Animal Identification</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,animals identification" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+</head>
+<body>
+ <div id ="scoreArea">
+ <form name="scoreDisplay">
+ <b>Score:</b> <input type="text" size="1" name="score"/>
+ <b>Total:</b> <input type="text" size="1" name="total"/>
+ </form>
+ <a href="#" id="anchorPlayAgain"><img class="playAgain" src="assets/image/play_again.jpg" alt="" /></a>
+ </div>
+ <div id="gameArea">
+ <div id="questionBox">What is this?</div>
+ <img class = "imageBox" id="imgObject" src="" alt=""/>
+ <img class="checkedOption" id="check" src="" alt=""/>
+
+ <div id="options">
+ <a href="#" id="anchorOpt0"><img class="optImg" id="option0" src="" alt=""/></a>
+ <a href="#" id="anchorOpt1"><img class="optImg" id="option1" src="" alt=""/></a>
+ <a href="#" id="anchorOpt2"><img class="optImg" id="option2" src="" alt=""/></a>
+ <a href="#" id="anchorOpt3"><img class="optImg" id="option3" src="" alt=""/></a>
+ </div>
+
+ <div id="gameOver">
+ Game Over
+ </div>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Animal_Identification/js/lesson.js b/bundles/XO/karma/lessons/English_Animal_Identification/js/lesson.js
new file mode 100755
index 0000000..6e59d3d
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Animal_Identification/js/lesson.js
@@ -0,0 +1,198 @@
+$(document).ready(
+ function(){
+ var k = Karma({
+ audio: [{'name':'correct','file':'correct.ogg'},
+ {'name':'incorrect','file':'incorrect.ogg'}
+ ]});
+
+ k.ready(
+ function(){
+
+ var flag, i ,j;
+ var object_counter = 1;
+ var imgNameRand = [];
+ var optPosition = [];
+ var optOtherPos = [];
+ var imageObject = [];
+ var correctPosition;
+ var selectedOption;
+ var score = 0;
+ var wrong_selected = 0; //wrong option selected so don't score up
+ var pos;
+ var t;
+ var current_image;
+
+
+ load_images(); //load the image numbers for random display
+ display_score();
+ game(); //let the game begin
+
+
+ function display_score(){
+ document.scoreDisplay.score.value = score;
+ if(object_counter > 6)
+ document.scoreDisplay.total.value = 6;
+ else
+ document.scoreDisplay.total.value = object_counter;
+ }
+
+ function checkDisplay(){ //Displays the correct and incorrect info
+ if(wrong_selected == 1){
+ $('.checkedOption').show();
+ document.getElementById("check").src =
+ "assets/image/incorrect.png";
+ k.audio.incorrect.play();
+ $('.checkedOption').fadeOut(1000);
+ }
+ else{
+ $('.checkedOption').hide();
+ document.getElementById("check").src = "assets/image/correct.png";
+ k.audio.correct.play();
+ $('.checkedOption').fadeOut(2000);
+ //needs timer for holding on for abt a sec
+ }
+ }
+
+ $("#anchorPlayAgain").click(function(){
+ $('#gameOver').hide();
+ $('.optImg').show();
+ $('.imageBox').show();
+ load_images();
+ score = 0;
+ object_counter = 1;
+ wrong_selected = 0;
+ display_score();
+
+ game();
+
+ });
+ $("#anchorOpt0").click(function(){
+ selected_Option_Process('0');
+ });
+ $("#anchorOpt1").click(function(){
+ selected_Option_Process('1');
+ });
+ $("#anchorOpt2").click(function(){
+ selected_Option_Process('2');
+ });
+ $("#anchorOpt3").click(function(){
+ selected_Option_Process('3');
+ });
+
+ function generate_random_no(no_limit) { //generate random number
+ var rand_no = Math.ceil(no_limit*Math.random());
+ return rand_no;
+ }
+
+ function get_random_position(){ //generate random number between 0-3
+ var rand_pos = Math.floor(Math.random()*4);
+ return rand_pos;
+ }
+
+ function load_images(){
+
+ imageObject[0] = generate_random_no("6");
+ for(i=1; i<6; i++){
+ do{
+ flag = 0;
+ imageObject[i] = generate_random_no("6");
+ for(j=0; j<i; j++){
+ if(imageObject[i]===imageObject[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+
+ }
+ function selected_Option_Process(selectedOption){
+
+ if(selectedOption == correctPosition){
+ object_counter++;
+ if(wrong_selected == 0){
+ score++;
+ }
+ wrong_selected = 0;
+ display_score();
+ checkDisplay();
+ //t=setTimeout('game()',1000);
+ game();
+ }
+ else {
+ wrong_selected = 1;
+ checkDisplay();
+ }
+
+ }
+ function game(){
+
+
+ //clearTimeout(t);
+ wrong_selected = 0;
+ current_image = object_counter-1;
+ document.getElementById("imgObject").src = "assets/image/"+imageObject[current_image]+".png";
+
+ //find correct answer and apply it to the position
+ var currentImage = imageObject[current_image];
+ imgNameRand[0] = currentImage;
+ //generate choices
+
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ imgNameRand[i] = generate_random_no("6");
+ for(j=0; j<i; j++){
+ if(imgNameRand[i]===imgNameRand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+
+ correctPosition = get_random_position();
+
+ optOtherPos[0] = correctPosition;
+
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ optOtherPos[i] = get_random_position();
+ for(j=0; j<i; j++){ //chek repeat within optOtherPos array
+ if(optOtherPos[i] === optOtherPos[j]){
+ flag++;
+ }
+ }
+
+ }while(flag != 0);
+
+ }
+
+ for(i=0; i<4; i++){
+ pos = optOtherPos[i];
+ optPosition[pos] = imgNameRand[i];
+ }
+
+
+ //random positions are stored in optOtherPos array. Great
+
+
+ for(i=0; i<4; i++){
+ document.getElementById("option"+i+"").src = "assets/image/image_name/"+optPosition[i]+".png";
+ }
+
+ //check for the correctness
+ if(object_counter > 6){
+
+ $('.optImg').hide();
+ $('.imageBox').hide();
+ $('#gameOver').show();
+
+
+ }
+
+ //else
+ } //no change
+ }); //end of games
+}); //end of DOM \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/audio/correct.ogg b/bundles/XO/karma/lessons/English_Color_Identification/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/English_Color_Identification/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/1.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/1.png
new file mode 100755
index 0000000..5c2a9a3
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/2.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/2.png
new file mode 100755
index 0000000..50b4bd1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/3.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/3.png
new file mode 100755
index 0000000..12cc585
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/4.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/4.png
new file mode 100755
index 0000000..becb133
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/5.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/5.png
new file mode 100755
index 0000000..7a81f85
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/6.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/6.png
new file mode 100755
index 0000000..433fc60
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/7.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/7.png
new file mode 100755
index 0000000..76f7c4c
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/8.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/8.png
new file mode 100755
index 0000000..144f674
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/Thumbs.db b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/Thumbs.db
new file mode 100755
index 0000000..de2c1e6
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/Thumbs.db
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/background.jpg b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/background.jpg
new file mode 100755
index 0000000..cedaf11
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/background.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/correct.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/correct.png
new file mode 100755
index 0000000..d6e54a8
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/correct.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/1.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/1.png
new file mode 100755
index 0000000..8f516a1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/2.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/2.png
new file mode 100755
index 0000000..e9aa48e
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/3.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/3.png
new file mode 100755
index 0000000..45ac0f6
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/4.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/4.png
new file mode 100755
index 0000000..7156cef
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/5.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/5.png
new file mode 100755
index 0000000..05fd757
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/6.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/6.png
new file mode 100755
index 0000000..76946a0
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/7.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/7.png
new file mode 100755
index 0000000..052ee62
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/8.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/8.png
new file mode 100755
index 0000000..db62889
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/9.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/9.png
new file mode 100755
index 0000000..5ac1c08
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/image_name/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/incorrect.png b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/incorrect.png
new file mode 100755
index 0000000..789db87
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/incorrect.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/assets/image/play_again.jpg b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/play_again.jpg
new file mode 100755
index 0000000..db3ae56
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/assets/image/play_again.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/css/lesson.css b/bundles/XO/karma/lessons/English_Color_Identification/css/lesson.css
new file mode 100755
index 0000000..63e0b39
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/css/lesson.css
@@ -0,0 +1,84 @@
+@CHARSET "UTF-8";
+body {
+ background: url(../assets/image/background.jpg) no-repeat;
+}
+
+
+#gameArea{
+ margin-top: 10px auto;
+ margin-left: 10%;
+ float: left;
+ width: 500px;
+ padding:10px;
+}
+
+
+
+.imageBox{
+
+ margin-top: 0px;
+ margin-left: 350px;
+ width: 220px;
+ height: 220px;
+ padding: 10px;
+}
+
+.checkedOption{
+ position: absolute;
+ top: 40%;
+ left: 70%;
+ width:120px;
+ height:120px;
+ padding: 5px;
+}
+
+#options{
+ margin-left:25px;
+ margin-top:50px;
+ width:650px;
+ height:80px;
+ padding: 10px;
+}
+
+.optImg{
+ width:120px;
+ height: 40px;
+ background-color: yellow;
+ padding:5px;
+ border: 2px solid green;
+ margin: 0.5em;
+}
+
+#scoreArea{
+ margin-left:5%;
+ color: red;
+ width: 45px;
+ padding: 5px;
+ background: #FFFFFF;
+ border: 2px solid red;
+ background: black;
+ padding: 10px;
+}
+
+.playAgain{
+ position:absolute;
+ top: 10px;
+ margin-left: 100px;
+ width:115px;
+ height: 30px;
+ padding: 2px;
+ }
+input{
+ color:green;
+
+}
+#gameOver{
+ margin-left:300px;
+ width: 180px;
+ height: 20px;
+ display:none;
+ font: 25px "Rockwell Extra Bold", Geneva, Arial, Helvetica, sans-serif,Times New Roman;
+ font-weight: bold;
+ background-color: #ccc;
+ padding: 10px;
+}
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/index.html b/bundles/XO/karma/lessons/English_Color_Identification/index.html
new file mode 100755
index 0000000..7f7deeb
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/index.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>English_Animal Identification</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,animals identification" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+</head>
+<body>
+ <div id ="scoreArea">
+ <form name="scoreDisplay">
+ <b>Score:</b><input type="text" size="1" name="score"/>
+ <b>Total:</b><input type="text" size="1" name="total"/>
+ </form>
+ </div>
+ <a href="#" id="anchorPlayAgain"><img class="playAgain" src="assets/image/play_again.jpg" alt=""/></a>
+
+ <div id="gameArea">
+ <img class = "imageBox" id="imgObject" src="" alt=""/>
+ <img class="checkedOption" id="check" src="" alt=""/>
+
+ <div id="options">
+ <a href="#" id="anchorOpt0"><img class="optImg" id="option0" src="" alt=""/></a>
+ <a href="#" id="anchorOpt1"><img class="optImg" id="option1" src="" alt=""/></a>
+ <a href="#" id="anchorOpt2"><img class="optImg" id="option2" src="" alt=""/></a>
+ <a href="#" id="anchorOpt3"><img class="optImg" id="option3" src="" alt=""/></a>
+ </div>
+
+ <div id="gameOver">
+ Game Over
+ </div>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Color_Identification/js/lesson.js b/bundles/XO/karma/lessons/English_Color_Identification/js/lesson.js
new file mode 100755
index 0000000..b3333fc
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Color_Identification/js/lesson.js
@@ -0,0 +1,197 @@
+$(document).ready(
+ function(){
+ var k = Karma({
+ audio: [{'name':'correct','file':'correct.ogg'},
+ {'name':'incorrect','file':'incorrect.ogg'}
+ ]});
+
+ k.ready(function(){
+ var flag, i ,j;
+ var object_counter = 1;
+ var imgNameRand = [];
+ var optPosition = [];
+ var optOtherPos = [];
+ var imageObject = [];
+ var correctPosition;
+ var selectedOption;
+ var score = 0;
+ var wrong_selected = 0; //wrong option selected so don't score up
+ var pos;
+ var t;
+ var current_image;
+
+
+ load_images(); //load the image numbers for random display
+ display_score();
+ game(); //let the game begin
+
+
+ function display_score(){
+ document.scoreDisplay.score.value = score;
+ if(object_counter > 8)
+ document.scoreDisplay.total.value = 8;
+ else
+ document.scoreDisplay.total.value = object_counter;
+ }
+
+ function checkDisplay(){ //Displays the correct and incorrect info
+ if(wrong_selected == 1){
+ $('.checkedOption').show();
+ document.getElementById("check").src = "assets/image/incorrect.png";
+ $('.checkedOption').fadeOut(1000);
+ }
+ else{
+ $('.checkedOption').hide();
+ document.getElementById("check").src = "assets/image/correct.png";
+ $('.checkedOption').fadeOut(2000);
+ //needs timer for holding on for abt a sec
+ }
+ }
+
+ $("#anchorPlayAgain").click(function(){
+ $('#gameOver').hide();
+ $('.optImg').show();
+ $('.imageBox').show();
+ load_images();
+ score = 0;
+ object_counter = 1;
+ wrong_selected = 0;
+ display_score();
+
+ game();
+
+ });
+ $("#anchorOpt0").click(function(){
+ selected_Option_Process('0');
+ });
+ $("#anchorOpt1").click(function(){
+ selected_Option_Process('1');
+ });
+ $("#anchorOpt2").click(function(){
+ selected_Option_Process('2');
+ });
+ $("#anchorOpt3").click(function(){
+ selected_Option_Process('3');
+ });
+
+ function generate_random_no(no_limit) { //generate random number
+ var rand_no = Math.ceil(no_limit*Math.random());
+ return rand_no;
+ }
+
+ function get_random_position(){ //generate random number between 0-3
+ var rand_pos = Math.floor(Math.random()*4);
+ return rand_pos;
+ }
+
+ function load_images(){
+
+ imageObject[0] = generate_random_no("8");
+ for(i=1; i<8; i++){
+ do{
+ flag = 0;
+ imageObject[i] = generate_random_no("8");
+ for(j=0; j<i; j++){
+ if(imageObject[i]===imageObject[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+
+ }
+ function selected_Option_Process(selectedOption){
+
+ if(selectedOption == correctPosition){
+ object_counter++;
+ if(wrong_selected == 0){
+ score++;
+ }
+ wrong_selected = 0;
+ display_score();
+ k.audio.correct.play();
+ checkDisplay();
+ //t=setTimeout('game()',1000);
+ game();
+ }
+ else {
+ wrong_selected = 1;
+ k.audio.incorrect.play();
+ checkDisplay();
+ }
+
+ }
+ function game(){
+
+
+ //clearTimeout(t);
+ wrong_selected = 0;
+ current_image = object_counter-1;
+ document.getElementById("imgObject").src = "assets/image/"+imageObject[current_image]+".png";
+
+ //find correct answer and apply it to the position
+ var currentImage = imageObject[current_image];
+ imgNameRand[0] = currentImage;
+ //generate choices
+
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ imgNameRand[i] = generate_random_no("8");
+ for(j=0; j<i; j++){
+ if(imgNameRand[i]===imgNameRand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+
+ correctPosition = get_random_position();
+
+ optOtherPos[0] = correctPosition;
+
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ optOtherPos[i] = get_random_position();
+ for(j=0; j<i; j++){ //chek repeat within optOtherPos array
+ if(optOtherPos[i] === optOtherPos[j]){
+ flag++;
+ }
+ }
+
+ }while(flag != 0);
+
+ }
+
+ for(i=0; i<4; i++){
+ pos = optOtherPos[i];
+ optPosition[pos] = imgNameRand[i];
+ }
+
+
+ //random positions are stored in optOtherPos array. Great
+
+
+ for(i=0; i<4; i++){
+ document.getElementById("option"+i+"").src = "assets/image/image_name/"+optPosition[i]+".png";
+ }
+
+ //check for the correctness
+ if(object_counter > 8){
+
+ $('.optImg').hide();
+ $('.imageBox').hide();
+ $('#gameOver').show();
+
+
+ }
+
+ //else
+ //no change
+ }
+}); //end of game
+
+}); //end of DOM \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/audio/correct.ogg b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/1.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/1.png
new file mode 100755
index 0000000..8610680
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/2.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/2.png
new file mode 100755
index 0000000..eadbc19
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/3.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/3.png
new file mode 100755
index 0000000..c8cd20b
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/4.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/4.png
new file mode 100755
index 0000000..d02c23f
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/5.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/5.png
new file mode 100755
index 0000000..4a79bd3
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/6.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/6.png
new file mode 100755
index 0000000..2b5a263
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/7.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/7.png
new file mode 100755
index 0000000..efb88f2
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/8.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/8.png
new file mode 100755
index 0000000..ad64eb2
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/background.jpg b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/background.jpg
new file mode 100755
index 0000000..2dd9a67
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/background.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/correct.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/correct.png
new file mode 100755
index 0000000..d6e54a8
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/correct.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/incorrect.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/incorrect.png
new file mode 100755
index 0000000..789db87
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/incorrect.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/optionBox.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/optionBox.png
new file mode 100755
index 0000000..87d19a6
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/optionBox.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/play_again.jpg b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/play_again.jpg
new file mode 100755
index 0000000..db3ae56
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/play_again.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/questionBox.png b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/questionBox.png
new file mode 100755
index 0000000..57c7883
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/assets/image/questionBox.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/css/lesson.css b/bundles/XO/karma/lessons/English_Direction_of_Arrows/css/lesson.css
new file mode 100755
index 0000000..82c0654
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/css/lesson.css
@@ -0,0 +1,88 @@
+@CHARSET "UTF-8";
+body {
+ background: url(../assets/image/background.jpg) no-repeat;
+}
+
+
+#gameArea{
+ margin-top: 10px auto;
+ margin-left: 5%;
+ float: left;
+ width: 800px;
+ padding:10px;
+}
+
+#questionBox{
+ width:174px;
+ height:176px;
+ margin-top: 100px;
+ margin-left: 20px;
+ background-image: url(../assets/image/questionBox.png);
+
+}
+.imageBox{
+ margin: 50px;
+
+}
+
+.checkedOption{
+ position: absolute;
+ top: 60%;
+ left: 60%;
+ width:120px;
+ height:120px;
+ padding: 5px;
+
+}
+
+#options{
+ width:564px;
+ height:176px;
+ background-image: url(../assets/image/optionBox.png);
+ position: absolute;
+ left:400px;
+ top: 115px;
+
+}
+
+.optImg{
+
+ margin: 35px 0px 5px 40px;
+
+}
+
+#scoreArea{
+ position:absolute;
+ margin-left:5%;
+ top: 520px;
+ color: red;
+ width: 175px;
+ padding: 5px;
+ background: #FFFFFF;
+ border: 2px solid red;
+ background: black;
+ padding: 10px;
+}
+
+.playAgain{
+ position:absolute;
+ top: 520px;
+ left: 75%;
+ width:115px;
+ height: 30px;
+ padding: 2px;
+ }
+input{
+ color:green;
+
+}
+#gameOver{
+ margin-left:300px;
+ width: 180px;
+ height: 20px;
+ display: none;
+ font: 25px "Rockwell Extra Bold", Geneva, Arial, Helvetica, sans-serif,Times New Roman;
+ font-weight: bold;
+ background-color: #ccc;
+ padding: 10px;
+}
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/index.html b/bundles/XO/karma/lessons/English_Direction_of_Arrows/index.html
new file mode 100755
index 0000000..a15b09a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/index.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>English_Direction of Arrows</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,arrows direction" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+</head>
+<body>
+
+
+
+ <div id="gameArea">
+ <div id="questionBox">
+ <img class = "imageBox" id="imgObject" src="" alt=""/>
+
+ </div>
+ <div id="options">
+ <a href="#" id="anchorOpt0"><img class="optImg" id="option0" src="" alt=""/></a>
+ <a href="#" id="anchorOpt1"><img class="optImg" id="option1" src="" alt=""/></a>
+ <a href="#" id="anchorOpt2"><img class="optImg" id="option2" src="" alt=""/></a>
+ <a href="#" id="anchorOpt3"><img class="optImg" id="option3" src="" alt=""/></a>
+ </div>
+ <img class="checkedOption" id="check" src="" alt=""/>
+ <div id ="scoreArea">
+ <form name="scoreDisplay">
+ <b>Score:</b> <input type="text" size="1" name="score"/>
+ <b>Total:</b> <input type="text" size="1" name="total"/>
+ </form>
+ </div>
+ <a href="#" id="anchorPlayAgain"><img class="playAgain" src="assets/image/play_again.jpg" alt=""/></a>
+ <div id="gameOver">
+ Game Over
+ </div>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Direction_of_Arrows/js/lesson.js b/bundles/XO/karma/lessons/English_Direction_of_Arrows/js/lesson.js
new file mode 100755
index 0000000..df3dacc
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Direction_of_Arrows/js/lesson.js
@@ -0,0 +1,196 @@
+$(document).ready(function(){
+ var k = Karma({
+ audio: [{'name':'correct','file':'correct.ogg'},
+ {'name':'incorrect','file':'incorrect.ogg'}
+ ]});
+
+ k.ready(function(){
+
+ var flag, i ,j;
+ var object_counter = 1;
+ var imgNameRand = [];
+ var optPosition = [];
+ var optOtherPos = [];
+ var imageObject = [];
+ var correctPosition;
+ var selectedOption;
+ var score = 0;
+ var wrong_selected = 0; //wrong option selected so don't score up
+ var pos;
+ var t;
+ var current_image;
+
+
+ load_images(); //load the image numbers for random display
+ display_score();
+ game(); //let the game begin
+
+
+ function display_score(){
+ document.scoreDisplay.score.value = score;
+ if(object_counter > 8)
+ document.scoreDisplay.total.value = 8;
+ else
+ document.scoreDisplay.total.value = object_counter;
+ }
+
+ function checkDisplay(){ //Displays the correct and incorrect info
+ if(wrong_selected == 1){
+ $('.checkedOption').show();
+ document.getElementById("check").src = "assets/image/incorrect.png";
+ $('.checkedOption').fadeOut(1000);
+ }
+ else{
+ $('.checkedOption').hide();
+ document.getElementById("check").src = "assets/image/correct.png";
+ $('.checkedOption').fadeOut(2000);
+ //needs timer for holding on for abt a sec
+ }
+ }
+
+ $("#anchorPlayAgain").click(function(){
+ $('#gameOver').hide();
+ $('.optImg').show();
+ $('.imageBox').show();
+ load_images();
+ score = 0;
+ object_counter = 1;
+ wrong_selected = 0;
+ display_score();
+
+ game();
+
+ });
+ $("#anchorOpt0").click(function(){
+ selected_Option_Process('0');
+ });
+ $("#anchorOpt1").click(function(){
+ selected_Option_Process('1');
+ });
+ $("#anchorOpt2").click(function(){
+ selected_Option_Process('2');
+ });
+ $("#anchorOpt3").click(function(){
+ selected_Option_Process('3');
+ });
+
+ function generate_random_no(no_limit) { //generate random number
+ var rand_no = Math.ceil(no_limit*Math.random());
+ return rand_no;
+ }
+
+ function get_random_position(){ //generate random number between 0-3
+ var rand_pos = Math.floor(Math.random()*4);
+ return rand_pos;
+ }
+
+ function load_images(){
+
+ imageObject[0] = generate_random_no("8");
+ for(i=1; i<8; i++){
+ do{
+ flag = 0;
+ imageObject[i] = generate_random_no("8");
+ for(j=0; j<i; j++){
+ if(imageObject[i]===imageObject[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+
+ }
+ function selected_Option_Process(selectedOption){
+
+ if(selectedOption == correctPosition){
+ object_counter++;
+ if(wrong_selected == 0){
+ score++;
+ }
+ wrong_selected = 0;
+ k.audio.correct.play();
+ display_score();
+ checkDisplay();
+ //t=setTimeout('game()',1000);
+ game();
+ }
+ else {
+ wrong_selected = 1;
+ k.audio.incorrect.play();
+ checkDisplay();
+ }
+
+ }
+ function game(){
+
+
+ //clearTimeout(t);
+ wrong_selected = 0;
+ current_image = object_counter-1;
+ document.getElementById("imgObject").src = "assets/image/"+imageObject[current_image]+".png";
+
+ //find correct answer and apply it to the position
+ var currentImage = imageObject[current_image];
+ imgNameRand[0] = currentImage;
+ //generate choices
+
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ imgNameRand[i] = generate_random_no("8");
+ for(j=0; j<i; j++){
+ if(imgNameRand[i]===imgNameRand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+
+ correctPosition = get_random_position();
+
+ optOtherPos[0] = correctPosition;
+
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ optOtherPos[i] = get_random_position();
+ for(j=0; j<i; j++){ //check repeat within optOtherPos array
+ if(optOtherPos[i] === optOtherPos[j]){
+ flag++;
+ }
+ }
+
+ }while(flag != 0);
+
+ }
+
+ for(i=0; i<4; i++){
+ pos = optOtherPos[i];
+ optPosition[pos] = imgNameRand[i];
+ }
+
+
+ //random positions are stored in optOtherPos array. Great
+
+
+ for(i=0; i<4; i++){
+ document.getElementById("option"+i+"").src = "assets/image/"+optPosition[i]+".png";
+ }
+
+ //check for the correctness
+ if(object_counter > 8){
+
+ $('.optImg').hide();
+ $('.imageBox').hide();
+ $('#gameOver').show();
+
+
+ }
+
+ //else
+ //no change
+ } //end of game
+ });
+}); //end of DOM \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/audio/correct.ogg b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/1.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/1.png
new file mode 100755
index 0000000..7c78dd2
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/10.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/10.png
new file mode 100755
index 0000000..be2f64d
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/10.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/11.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/11.png
new file mode 100755
index 0000000..9aaaed0
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/11.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/12.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/12.png
new file mode 100755
index 0000000..c7b89fe
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/12.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/13.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/13.png
new file mode 100755
index 0000000..6ff85d4
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/13.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/14.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/14.png
new file mode 100755
index 0000000..0c0e2a9
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/14.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/15.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/15.png
new file mode 100755
index 0000000..0d26e23
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/15.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/16.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/16.png
new file mode 100755
index 0000000..5ef7bb3
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/16.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/17.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/17.png
new file mode 100755
index 0000000..9d3729b
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/17.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/18.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/18.png
new file mode 100755
index 0000000..a3490c5
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/18.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/19.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/19.png
new file mode 100755
index 0000000..9dab844
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/19.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/2.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/2.png
new file mode 100755
index 0000000..71dbad9
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/20.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/20.png
new file mode 100755
index 0000000..0400c3b
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/20.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/21.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/21.png
new file mode 100755
index 0000000..0eda363
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/21.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/22.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/22.png
new file mode 100755
index 0000000..68c80ab
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/22.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/23.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/23.png
new file mode 100755
index 0000000..50940b1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/23.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/24.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/24.png
new file mode 100755
index 0000000..441f012
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/24.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/25.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/25.png
new file mode 100755
index 0000000..4194534
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/25.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/26.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/26.png
new file mode 100755
index 0000000..bf2b657
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/26.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/27.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/27.png
new file mode 100755
index 0000000..cf8380e
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/27.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/28.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/28.png
new file mode 100755
index 0000000..94ba36b
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/28.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/29.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/29.png
new file mode 100755
index 0000000..d4e1dfe
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/29.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/3.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/3.png
new file mode 100755
index 0000000..5263bbf
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/30.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/30.png
new file mode 100755
index 0000000..4daafaf
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/30.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/4.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/4.png
new file mode 100755
index 0000000..4c32dfa
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/5.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/5.png
new file mode 100755
index 0000000..af1c580
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/6.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/6.png
new file mode 100755
index 0000000..24fcd77
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/7.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/7.png
new file mode 100755
index 0000000..80c300c
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/8.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/8.png
new file mode 100755
index 0000000..8e4f39a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/9.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/9.png
new file mode 100755
index 0000000..8c971d0
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/default.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/default.png
new file mode 100755
index 0000000..031f8bc
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/default.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/home.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/home.png
new file mode 100755
index 0000000..1a7c5ba
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/home.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/info.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/info.png
new file mode 100755
index 0000000..795c0cd
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/info.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/matched.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/matched.png
new file mode 100755
index 0000000..46d995a
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/matched.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/pause.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/pause.png
new file mode 100755
index 0000000..3db0573
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/pause.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/play.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/play.png
new file mode 100755
index 0000000..76538a3
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/play.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/play_again.jpg b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/play_again.jpg
new file mode 100755
index 0000000..db3ae56
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/play_again.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/repeat.png b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/repeat.png
new file mode 100755
index 0000000..396335c
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/assets/image/repeat.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/css/lesson.css b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/css/lesson.css
new file mode 100755
index 0000000..bb40254
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/css/lesson.css
@@ -0,0 +1,124 @@
+@CHARSET "ISO-8859-1";
+body {
+ background: #ccc;
+ }
+h1{
+position: absolute;
+float:right;
+right: 5px;
+top: 5px;
+width: 300px;
+height:25px;
+font: 18px Arial Black;
+color: purple;
+border-bottom: 5px dotted red;
+}
+#gameArea{
+ margin: 0px 0px 0px 50px;
+ width: 700px;
+}
+
+.notMatched{
+ width: 95px;
+ height: 95px;
+ padding: 0px; /*top right bottom left**/
+ margin: 0.25em;
+}
+
+
+#sideBar{
+position: absolute;
+float:right;
+right: 50px;
+top: 100px;
+border: 2px solid red;
+width: 210px;
+height:70px;
+background: yellow;
+}
+
+
+#timerBox1{ /* Show the timer running after the game has began.... */
+float:right;
+width: 35px;
+height: 35px;
+border: 2px dotted green;
+padding: 3px;
+margin: 0.5em;
+color: blue;
+font : bold 25px Arial Black, Times New Roman;
+background: #ACC;
+
+}
+
+#timerBox2{ /* Show the timer running after the game has began.... */
+float:right;
+width: 35px;
+height: 35px;
+border: 2px dotted green;
+padding: 3px;
+margin: 0.5em;
+color: blue;
+font : bold 25px Arial Black, Times New Roman;
+background: #ACC;
+}
+
+#timerBox3{ /* Show the timer running after the game has began.... */
+float:right;
+width: 35px;
+height: 35px;
+border: 2px dotted green;
+padding: 3px;
+margin: 0.5em;
+color: blue;
+font : bold 25px Arial Black, Times New Roman;
+background: #ACC;
+}
+
+#clickDisplay{
+position: absolute;
+float:right;
+right: 25px;
+top: 250px;
+width: 300px;
+height:80px;
+font: 20px Rockwell Bold,Arial Black, Verdana, Georgia;
+}
+#textBox{
+float:right;
+width: 150px;
+height: 35px;
+padding: 3px;
+color: red;
+font : bold 18px Verdana, Times New Roman;
+}
+#clickBox{
+float:right;
+width: auto;
+height: 35px;
+border: 2px dotted green;
+padding: 5px;
+margin: 0.5em;
+color: red;
+font : bold 25px Arial Black, Times New Roman;
+background: #ACC;
+}
+
+
+#playOptions{
+position: absolute;
+float:right;
+right: 25px;
+top: 400px;
+width: 250px;
+height:80px;
+
+}
+.imgButton{
+width: 64px;
+height: 64px;
+padding:2px;
+margin: 0.1em;
+}
+
+
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/index.html b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/index.html
new file mode 100755
index 0000000..a6c60a1
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/index.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Math_Matching Words and Objects</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,Match, Words, Objects" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/images/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+</head>
+<body>
+ <div id="gameArea"></div>
+ <h1>Matching Words and Objects</h1>
+ <div id ="sideBar">
+
+ <div id="timerBox1"></div>
+ <div id="timerBox2"></div>
+ <div id="timerBox3"></div>
+ </div>
+ <div id="clickDisplay">
+
+ <div id="clickBox"></div>
+ <div id="textBox"> <br />Click Counter:-</div>
+ </div>
+ <div id="playOptions">
+ <a href="#" id="anchorPlay"><img class="imgButton"id="imgPlay" src="assets/image/play.png"></a>
+ <a href="#" id="anchorPause"><img class="imgButton"id="imgPause" src="assets/image/pause.png"></a>
+ <a href="#" id="anchorRestart"><img class="imgButton"id="imgRepeat" src="assets/image/repeat.png"></a>
+ </div>
+ <form name="delayForm">
+ <input type="hidden" name="delayval" size="5">
+ </form>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/js/lesson.js b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/js/lesson.js
new file mode 100755
index 0000000..2ec1018
--- /dev/null
+++ b/bundles/XO/karma/lessons/English_Matching_Words_and_Objects/js/lesson.js
@@ -0,0 +1,260 @@
+$(document).ready(function() {
+var k = Karma({
+ audio: [{'name':'correct','file':'correct.ogg'},
+ {'name':'incorrect','file':'incorrect.ogg'}
+ ]});
+
+k.ready(function(){
+
+ var i,j,flag;
+ var s=0; var m=0; var h=0; //varoiables for timer
+ var clickedObjects = []; //array storing the clicks of the two succesive clicks
+ var clickedObject = 0; //store the clicked image id
+ var matchedObjects = [];//store the matched images
+ var objrand = [];
+ var numClicked = 0; // If click on image it is incremnted by 1
+ var numMatched = 0; //how many matched objects
+ var play =0; //not played yet pause
+ var restart = 0; //not restarted
+ var clickCounter = 0;
+ var gameArea = $('#gameArea');
+
+
+
+ function startTimer(){
+ s=checkTime(s);
+ m=checkTime(m);
+ h=checkTime(h);
+ clickCounter = checkTime(clickCounter);
+ document.getElementById('clickBox').innerHTML=clickCounter;
+ document.getElementById('timerBox1').innerHTML=s;
+ document.getElementById('timerBox2').innerHTML=m;
+ document.getElementById('timerBox3').innerHTML=h;
+
+ }
+
+ var increaseTime = function(){
+ if(play == 1){
+ if(restart == 1){
+ s = 0;
+ m = 0;
+ h = 0;
+ }
+ s++;
+ if(s>60){
+ m++;
+ m=checkTime(m);
+ document.getElementById('timerBox2').innerHTML=m;
+ s = 0;
+ }
+ if(m>60){
+ h++;
+ h=checkTime(h);
+ document.getElementById('timerBox3').innerHTML=h;
+
+ m=0;
+
+ }
+ s=checkTime(s);
+
+ document.getElementById('timerBox1').innerHTML=s;
+ var t=setTimeout(
+ function(){
+ increaseTime();},1000);
+ }
+ };
+
+ function checkTime(timePara){
+ if (timePara<10 )
+ {
+ timePara="0" + timePara;
+ }
+ return timePara;
+ };
+
+
+
+
+ function generate_random_no() { //generate random number
+ var rand_no = Math.ceil(30*Math.random());
+ return rand_no;
+ }
+
+ function generate_random_objects_no(){
+ objrand[0]=generate_random_no(); //1 number generated, 3 different numbers to be generated
+ for(i=1; i<30; i++){
+ do{
+ flag = 0;
+ objrand[i] = generate_random_no();
+ for(j=0; j<i; j++){
+ if(objrand[i]===objrand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+ }
+ //alert(objrand);
+
+
+
+ function load_default_images(){
+ for(i=0; i<30; i++){
+ document.getElementById("object"+objrand[i]+"").src = "assets/image/default.png";
+ }
+ }
+
+
+
+function check_game_over(){
+ if(numMatched ==30){ //show all
+ for(i = 1; i<31; i++){
+ document.getElementById("object"+i+"").src = "assets/image/"+i+".png";
+ }
+ play = 0;
+
+ }
+}
+ function store_clicked_object(objectClicked){
+ if(play === 1){
+ clickedObject = objectClicked;
+ clickedObjects[numClicked] = clickedObject;
+ numClicked++;
+ clickCounter++;
+ clickCounter = checkTime(clickCounter);
+ document.getElementById('clickBox').innerHTML=clickCounter;
+ show_processed_image();
+ check_game_over();
+ return true;
+ }
+ else{
+ return false;
+
+ }
+
+ }
+
+ function process_object(){
+ //alert("test");
+ var matchedCondition = 0; //not matched
+ if(clickedObjects[0]%2 == 0 && clickedObjects[1] == clickedObjects[0]-1) //even 1st number
+ matchedCondition = 1;
+ else if(clickedObjects[0]%2 != 0 && clickedObjects[1] == clickedObjects[0]+1) //odd first number
+ matchedCondition = 1;
+ else if(clickedObjects[1]%2 == 0 && clickedObjects[0] == clickedObjects[1]-1) //even 2nd number
+ matchedCondition = 1;
+ else if(clickedObjects[1]%2 != 0 && clickedObjects[0] == clickedObjects[1]+1) //odd 2nd number
+ matchedCondition = 1;
+
+
+
+ if(matchedCondition!=0){ //matches
+ //if even clicked -1
+ //if odd clicked +1 should be the answer
+ //alert("Matched");
+ k.audio.correct.play();
+ document.getElementById("object"+clickedObjects[0]+"").src = "assets/image/matched.png";
+ document.getElementById("object"+clickedObjects[1]+"").src = "assets/image/matched.png";
+ matchedObjects[numMatched] = clickedObjects[0];
+ numMatched++;
+ matchedObjects[numMatched] = clickedObjects[1];
+ numMatched++;
+ //alert("Matched,Matched Objects="+matchedObjects+",No.match="+numMatched+"");
+ numClicked = 0;
+
+
+ }
+ else{
+ //alert("not matched");
+ document.getElementById("object"+clickedObjects[0]+"").src = "assets/image/default.png";
+ document.getElementById("object"+clickedObjects[1]+"").src = "assets/image/default.png";
+ numClicked = 0;
+
+ }
+
+
+ }
+
+ function delay(){
+
+ document.delayForm.delayval.value = 1;
+ process_object();
+ }
+
+ function show_processed_image(){ //Show the click Image
+ var t;
+ if (numMatched !=0){ //some pairs has matched so be sure not to show them again
+ var flag = 0; //if matched already it is set to 1
+ for(i = 0; i<numMatched; i++){
+ if(clickedObject == matchedObjects[i] ){
+ flag = 1;
+ }
+ }
+
+ if(flag == 0){ //no matches found
+ document.getElementById("object"+clickedObject+"").src = "assets/image/"+clickedObject+".png";
+ if(numClicked == 2){
+ t=setTimeout(function(){delay();},1000);
+
+ }
+ }
+ else{ //matched already so don't show
+ document.getElementById("object"+clickedObject+"").src = "assets/image/matched.png";
+ numClicked = 0;
+ }
+
+ }
+
+ else if(numClicked == 2){ //process the image after 2 successive clicks
+ document.getElementById("object"+clickedObject+"").src = "assets/image/"+clickedObject+".png";
+ //window.setTimeout('process_object()', 5000);
+ t=setTimeout(function(){delay();},1000);
+
+ }
+ else{
+ document.getElementById("object"+clickedObject+"").src = "assets/image/"+clickedObject+".png";
+ }
+ }
+
+ var assignSquares = function (square){
+
+ gameArea.append('<a href="#"></a>');
+ $('#gameArea a:last-of-type').append('<img class="notMatched" id="object' +
+ square + '" src="" alt="" />');
+
+ $('#gameArea a:last-of-type').click(
+ function(){
+ store_clicked_object(square);
+ });
+ };
+
+ generate_random_objects_no();
+
+ startTimer();
+
+ var square;
+
+ for(i=0; i<30; i++){
+ square = objrand[i];
+ assignSquares(square);
+ }
+
+
+ $('a#anchorPlay').click(function(){
+ play = 1;
+ increaseTime();
+ });
+ $('a#anchorPause').click(function(){
+ play = 0;
+ increaseTime();
+ });
+ $('a#anchorRestart').click(function(){
+ location.reload(true);
+ });
+
+ load_default_images();
+
+
+
+ });
+});//end of DOM
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/correct.ogg b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/trigger.ogg b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/trigger.ogg
new file mode 100755
index 0000000..f22512a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/audio/trigger.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/0.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/0.png
new file mode 100755
index 0000000..3da86fc
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/0.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/1.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/1.png
new file mode 100755
index 0000000..0a1eb04
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/10.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/10.png
new file mode 100755
index 0000000..c245212
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/10.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/11.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/11.png
new file mode 100755
index 0000000..6c20471
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/11.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/12.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/12.png
new file mode 100755
index 0000000..a6034a9
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/12.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/13.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/13.png
new file mode 100755
index 0000000..707c486
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/13.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/14.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/14.png
new file mode 100755
index 0000000..5ab548a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/14.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/15.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/15.png
new file mode 100755
index 0000000..970b97b
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/15.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/16.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/16.png
new file mode 100755
index 0000000..fd9034d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/16.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/17.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/17.png
new file mode 100755
index 0000000..a348448
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/17.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/18.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/18.png
new file mode 100755
index 0000000..3507cd9
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/18.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/19.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/19.png
new file mode 100755
index 0000000..5f3a97c
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/19.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/2.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/2.png
new file mode 100755
index 0000000..c193aea
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/20.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/20.png
new file mode 100755
index 0000000..31d85ec
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/20.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/21.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/21.png
new file mode 100755
index 0000000..aab5dd6
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/21.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/22.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/22.png
new file mode 100755
index 0000000..087455a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/22.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/23.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/23.png
new file mode 100755
index 0000000..1e60b08
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/23.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/24.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/24.png
new file mode 100755
index 0000000..ee6dd62
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/24.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/25.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/25.png
new file mode 100755
index 0000000..f98f1b8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/25.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/26.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/26.png
new file mode 100755
index 0000000..6284143
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/26.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/27.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/27.png
new file mode 100755
index 0000000..08ceeff
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/27.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/28.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/28.png
new file mode 100755
index 0000000..36a3240
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/28.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/29.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/29.png
new file mode 100755
index 0000000..6b76a4c
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/29.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/3.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/3.png
new file mode 100755
index 0000000..72b37de
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/30.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/30.png
new file mode 100755
index 0000000..860e274
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/30.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/31.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/31.png
new file mode 100755
index 0000000..88f50c9
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/31.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/32.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/32.png
new file mode 100755
index 0000000..caa6d5f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/32.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/33.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/33.png
new file mode 100755
index 0000000..8c9c5b8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/33.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/34.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/34.png
new file mode 100755
index 0000000..347b3dd
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/34.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/35.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/35.png
new file mode 100755
index 0000000..a109c98
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/35.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/36.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/36.png
new file mode 100755
index 0000000..82bb15e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/36.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/37.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/37.png
new file mode 100755
index 0000000..18294ab
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/37.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/38.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/38.png
new file mode 100755
index 0000000..a6d5a4a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/38.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/39.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/39.png
new file mode 100755
index 0000000..d6e5b23
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/39.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/4.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/4.png
new file mode 100755
index 0000000..0def1cb
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/40.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/40.png
new file mode 100755
index 0000000..62fc121
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/40.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/41.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/41.png
new file mode 100755
index 0000000..6e44320
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/41.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/42.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/42.png
new file mode 100755
index 0000000..0b57f13
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/42.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/43.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/43.png
new file mode 100755
index 0000000..6b062f1
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/43.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/44.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/44.png
new file mode 100755
index 0000000..239c462
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/44.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/45.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/45.png
new file mode 100755
index 0000000..2134d3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/45.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/46.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/46.png
new file mode 100755
index 0000000..b936c64
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/46.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/47.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/47.png
new file mode 100755
index 0000000..92ee82f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/47.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/48.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/48.png
new file mode 100755
index 0000000..ceda92a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/48.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/49.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/49.png
new file mode 100755
index 0000000..c9aef3d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/49.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/5.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/5.png
new file mode 100755
index 0000000..51cc2b0
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/50.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/50.png
new file mode 100755
index 0000000..df5fdbe
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/50.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/51.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/51.png
new file mode 100755
index 0000000..14ef3c1
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/51.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/52.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/52.png
new file mode 100755
index 0000000..8d10c98
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/52.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/53.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/53.png
new file mode 100755
index 0000000..d7f255d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/53.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/54.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/54.png
new file mode 100755
index 0000000..736d39a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/54.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/55.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/55.png
new file mode 100755
index 0000000..02a6dc4
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/55.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/56.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/56.png
new file mode 100755
index 0000000..1436a0c
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/56.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/57.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/57.png
new file mode 100755
index 0000000..a0ddf5c
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/57.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/58.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/58.png
new file mode 100755
index 0000000..e37db21
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/58.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/59.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/59.png
new file mode 100755
index 0000000..7a6c335
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/59.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/6.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/6.png
new file mode 100755
index 0000000..96fb917
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/60.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/60.png
new file mode 100755
index 0000000..a4fe43e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/60.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/61.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/61.png
new file mode 100755
index 0000000..fb0a152
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/61.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/62.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/62.png
new file mode 100755
index 0000000..c526a88
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/62.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/63.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/63.png
new file mode 100755
index 0000000..5d60f3e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/63.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/64.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/64.png
new file mode 100755
index 0000000..de89371
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/64.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/65.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/65.png
new file mode 100755
index 0000000..058a1ac
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/65.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/66.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/66.png
new file mode 100755
index 0000000..6934f94
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/66.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/67.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/67.png
new file mode 100755
index 0000000..19fd631
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/67.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/68.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/68.png
new file mode 100755
index 0000000..fc9dfb2
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/68.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/69.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/69.png
new file mode 100755
index 0000000..9610722
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/69.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/7.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/7.png
new file mode 100755
index 0000000..537d30f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/70.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/70.png
new file mode 100755
index 0000000..a8f4e53
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/70.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/71.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/71.png
new file mode 100755
index 0000000..0d82bf7
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/71.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/72.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/72.png
new file mode 100755
index 0000000..1879387
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/72.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/73.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/73.png
new file mode 100755
index 0000000..4e97b09
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/73.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/74.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/74.png
new file mode 100755
index 0000000..4afe9b4
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/74.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/75.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/75.png
new file mode 100755
index 0000000..d23a4e2
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/75.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/76.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/76.png
new file mode 100755
index 0000000..8177e86
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/76.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/77.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/77.png
new file mode 100755
index 0000000..9a12739
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/77.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/78.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/78.png
new file mode 100755
index 0000000..b6b6b96
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/78.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/79.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/79.png
new file mode 100755
index 0000000..49eb8c4
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/79.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/8.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/8.png
new file mode 100755
index 0000000..92b8f07
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/80.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/80.png
new file mode 100755
index 0000000..e61cc25
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/80.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/81.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/81.png
new file mode 100755
index 0000000..ca42a6e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/81.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/82.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/82.png
new file mode 100755
index 0000000..d53ab7e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/82.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/83.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/83.png
new file mode 100755
index 0000000..ac82c71
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/83.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/84.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/84.png
new file mode 100755
index 0000000..48a850c
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/84.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/85.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/85.png
new file mode 100755
index 0000000..b6a1237
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/85.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/86.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/86.png
new file mode 100755
index 0000000..f504c7d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/86.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/87.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/87.png
new file mode 100755
index 0000000..9f3ae68
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/87.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/88.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/88.png
new file mode 100755
index 0000000..98928ff
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/88.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/89.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/89.png
new file mode 100755
index 0000000..ada779a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/89.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/9.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/9.png
new file mode 100755
index 0000000..195f3a7
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/90.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/90.png
new file mode 100755
index 0000000..fcf127f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/90.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/91.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/91.png
new file mode 100755
index 0000000..05b025c
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/91.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/92.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/92.png
new file mode 100755
index 0000000..9e6aee0
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/92.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/93.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/93.png
new file mode 100755
index 0000000..57e68fe
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/93.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/94.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/94.png
new file mode 100755
index 0000000..2169fab
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/94.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/95.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/95.png
new file mode 100755
index 0000000..1ea65cd
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/95.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/96.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/96.png
new file mode 100755
index 0000000..8042a2a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/96.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/97.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/97.png
new file mode 100755
index 0000000..17350a9
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/97.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/98.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/98.png
new file mode 100755
index 0000000..4c1423b
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/98.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/99.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/99.png
new file mode 100755
index 0000000..a950188
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/99.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/main.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/main.png
new file mode 100755
index 0000000..dfd111f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/drag_images/main.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/Exit.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/Exit.png
new file mode 100755
index 0000000..89df410
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/Exit.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/Info.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/Info.png
new file mode 100755
index 0000000..e5580f6
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/Info.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/help.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/help.png
new file mode 100755
index 0000000..d60425f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/help.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/refresh.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/refresh.png
new file mode 100755
index 0000000..606ea9e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/refresh.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/volumeDisabled.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/volumeDisabled.png
new file mode 100755
index 0000000..7f36157
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/volumeDisabled.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/volumeEnabled.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/volumeEnabled.png
new file mode 100755
index 0000000..b1852ed
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/icons/volumeEnabled.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0.gif
new file mode 100755
index 0000000..5df490b
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/09_9b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/09_9b.gif
new file mode 100755
index 0000000..6ade287
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/09_9b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0a.gif
new file mode 100755
index 0000000..2b80a93
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0b.gif
new file mode 100755
index 0000000..5e97b45
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/0b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1.gif
new file mode 100755
index 0000000..83707e1
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1a.gif
new file mode 100755
index 0000000..45a8789
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1b.gif
new file mode 100755
index 0000000..ac1cf40
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/1b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2.gif
new file mode 100755
index 0000000..01b5073
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2a.gif
new file mode 100755
index 0000000..34ff9c5
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2b.gif
new file mode 100755
index 0000000..3e05237
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/2b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3.gif
new file mode 100755
index 0000000..f51c794
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3a.gif
new file mode 100755
index 0000000..a124ddc
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3b.gif
new file mode 100755
index 0000000..0d7ce72
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/3b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4.gif
new file mode 100755
index 0000000..6dd7ff2
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4a.gif
new file mode 100755
index 0000000..83982ee
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4b.gif
new file mode 100755
index 0000000..b590d5a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/4b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5.gif
new file mode 100755
index 0000000..a3598cb
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5a.gif
new file mode 100755
index 0000000..df91f6a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5b.gif
new file mode 100755
index 0000000..532d010
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/5b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6.gif
new file mode 100755
index 0000000..5170134
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6a.gif
new file mode 100755
index 0000000..e09642e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6b.gif
new file mode 100755
index 0000000..8ab50db
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/6b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7.gif
new file mode 100755
index 0000000..f1baa0a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7a.gif
new file mode 100755
index 0000000..f22034d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7b.gif
new file mode 100755
index 0000000..e75a04a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/7b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8.gif
new file mode 100755
index 0000000..0d04cab
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8a.gif
new file mode 100755
index 0000000..0dcee2e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8b.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8b.gif
new file mode 100755
index 0000000..ba4fac8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/8b.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/9.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/9.gif
new file mode 100755
index 0000000..d9b3d17
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/9.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/9a.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/9a.gif
new file mode 100755
index 0000000..3fb910c
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/other_numbers/9a.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/0.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/0.gif
new file mode 100755
index 0000000..10f4379
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/0.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/1.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/1.gif
new file mode 100755
index 0000000..ced78e1
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/1.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/2.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/2.gif
new file mode 100755
index 0000000..0a27917
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/2.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/3.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/3.gif
new file mode 100755
index 0000000..61c5cde
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/3.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/4.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/4.gif
new file mode 100755
index 0000000..c57b94d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/4.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/5.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/5.gif
new file mode 100755
index 0000000..c239dc3
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/5.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/6.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/6.gif
new file mode 100755
index 0000000..0bc0c6f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/6.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/7.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/7.gif
new file mode 100755
index 0000000..d2a29c3
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/7.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/8.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/8.gif
new file mode 100755
index 0000000..782bcde
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/8.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/9.gif b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/9.gif
new file mode 100755
index 0000000..6c3dc28
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/score_images/9.gif
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/scorebox.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/scorebox.png
new file mode 100755
index 0000000..424b60b
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/scorebox.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/yellowBox.png b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/yellowBox.png
new file mode 100755
index 0000000..4ae710e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/assets/image/yellowBox.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/css/lesson.css b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/css/lesson.css
new file mode 100755
index 0000000..3221ba4
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/css/lesson.css
@@ -0,0 +1,269 @@
+body {
+ font-family: sans-serif;
+ font-size: 95%;
+ margin: 1em 1.5em;
+ background: #affafc;
+
+}
+
+
+#gamearea{
+ border: 5px gold dashed;
+ width : 570px;
+ padding: 5px 5px 20px 5px;
+
+}
+#content {
+}
+.template {
+ display: none;ffont: 15px "Verdana",Arial,Times New Roman;ont: 15px "Verdana",Arial,Times New Roman;
+}
+p, h2 {
+}
+h1 {
+ border-bottom: 3px solid #333;
+}
+h3{
+ color: #FF0000;
+ font: 18px "Agency FB",Verdana,Arial,Times New Roman;
+}
+#toc {
+}
+#toc li {
+ padding: 0 0 0.5em 0;
+ font-size: 1em;
+}
+h2 {
+ border-top: 2px solid #FF00FF;
+ border-bottom: 2px solid #FF00FF;
+ padding: 0.25em 0;
+ margin: 0 0 1em 0;
+ color : red;
+ text-align : center;
+}
+.toclink {
+ padding-left: 1em;
+ font-size: 0.5em;
+}
+p.srclink {
+ border-top: 1px solid #666;
+ padding: 0.5em 0 0 0;
+ margin: 0 0 2em 0;
+}
+.dragme {
+ width: 89px;
+ height: 82px;
+ border: 1px solfont: 15px "Verdana",Arial,Times New Roman;id #666;
+ background: #acf;
+ margin: 1em;
+ padding: 0.5em;
+ cursor: move;
+}
+.drophere {
+ margin-top : 125px;
+ padding: 0.25em;
+ width: 20ex;
+ height: 20ex;
+ border: 5px solid #777;
+ background: #eee;
+ font : 15px "Arial Black", Arial, Helvetica, sans-serif;
+ color: #181;
+ /*margin: 0 0 0 15ex;*/
+}
+.dragover {
+ background: #8f8;
+}
+
+#drop_area{
+ margin-left:190px;
+}
+
+#helpBar{ /*Hfont: 15px "Verdana",Arial,Times New Roman;elp and Exit*/
+ float : right;
+ top : 10px;
+ width: 170px;
+}
+#gameInfo{ /* pop ups the help for the game*/
+ top: 70px;
+ display: none;
+ border : 2px solid green;
+ margin-left:9px;
+ margin-right: 38px;
+ font: 14px "Verdana",Arial,Times New Roman;
+ /*width : 555px;*/
+ padding: 10px 20px 10px 20px; /*Top right bottom left*/
+ background-color: #1090F2;
+ color: #620606;
+ text-align:left;
+ position:absolute;
+ text-justify:newspaper;
+ opacity: 0.8; /* For IE "value" for firefox fraction value 0-1*/
+ cursor: help;
+}
+
+.helpme{
+ margin: 0.25em;
+ padding: 0.05em;
+ cursor: help;
+}
+.exitProgram{
+ margin: 0.25em;
+ padding: 0.05em;
+}
+
+.imgVolume{
+ margin: 0.25em;
+ padding: 0.05em;
+}
+
+
+#sidebar { /* Score Area */
+ float:right;
+ margin-right: 50px;
+
+ width: 25ex;
+ height: 30ex;
+
+ border: 5px solidfont: 15px "Verdana",Arial,Times New Roman; #F56;
+ background: #CFA;
+ font : 15px "Trebuchet MS", Arial, Helvetica, sans-serif;
+ border : 2px solid black;
+ padding : 2px;
+
+}
+
+#minussign{
+ position:absolute;
+ display: none;
+ border: 10px solid red;
+ width: 15px;
+ margin-top: 40px;
+
+}
+
+.scoreBox{
+ /*margin-top : 10px;*/
+ /*border: 5px solid #000;*/
+ /*background-image: url(../assets/image/scorebox.png);*/
+ /*padding:0px 0px 134px 195px;*/
+ width: 89px;
+ height: 82px;
+ border: 1px solid #123;
+ background: #aAf;
+ margin-left: 2.75em;
+ padding: 1em;
+}
+
+#difficulty{
+ padding: 20px 0 0 0;
+ font: 18px "Arial Rounded MT Bold",Arial, Helvetica,sans-serif;
+ color: #FF0000;
+}
+#diffulty .option{
+ font: 15px;
+}
+
+ul.draglist {
+ float: left;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+ul.draglist li {
+ margin: 0 0 10px 0;
+}
+ul.draglist li.dragme {
+ height: 32px;
+}
+ul.droplist {
+ list-style: none;
+ padding: 0;
+ margin: 0 0 0 15ex;
+}
+ul.droplist li {
+ margin: 0 0 10px 0;
+}
+ul.droplist li.drophere {
+ height: 32px;
+}
+
+#feedback_image .drophere {
+ margin: 0 0 0 22ex;
+}
+
+
+
+.events_monitor {
+ float: left;
+ margin: 0.25em;
+ padding: 0.25em;
+}
+.events_monitor dt {
+ font-family: monospace;
+ font-size: 1.2em;
+ font-weight: bold;
+ text-decoration: underline;
+}
+.events_monitor dd {
+ font-family: monospace;
+ margin: 0; padding: 0 0 1em 0;
+}
+.toys {
+ margin: 0.25em 0.25em 0.25em 310px;
+ padding: 0.25em;
+}
+.toys div.draggable {
+ float: left;
+ width: 64px;
+ height: 64px;
+ border: 1px solid #666;
+ background: #acf;
+ margin: 0.25em;
+ padding: 0.25em;
+ cursor: pointer;
+}
+.toys img {
+ float: left;
+ display: block;
+ margin: 0.25em;
+ padding: 0.25em;
+}
+.toys form {
+ display: block;
+ margin: 0.25em;
+ padding: 0.25em;
+}
+
+.boxes {
+ margin: 0.25em 0.25em 0.25em 310px;
+ padding: 0.25em;
+}
+.boxes .droparea {
+ float: left;
+ width: 128px;
+ height: 96px;
+ border: 1px solid #666;
+ background: #eee;
+ margin: 0.25em;
+ padding: 0.25em;
+}
+.boxes #delegated {
+ clear: both;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+.boxes #delegated li {
+ float: left;
+ width: 128px;
+ height: 96px;
+ border: 1px solid #666;
+ background: #eee;
+ margin: 0.25em;
+ padding: 0.25em;
+}
+
+
+#volDisabled {
+ display: none;
+} \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/index.html b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/index.html
new file mode 100755
index 0000000..1edf92d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/index.html
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title> Largest Number Identification </title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <meta http-equiv="Content-Language" content="en-us" />
+ <meta name="keywords" content="karma,javascript,html5,sugar,largest number,gsoc,ole,nepal" />
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link rel="stylesheet" type="text/css" href="css/lesson.css"/>
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+</head>
+<body>
+ <div id ="helpBar">
+ <a href="#" id="anchorInfo"><img class="helpme" id="imgInfo" src="assets/image/icons/help.png"></a>
+ <a href="#" id="exitNow"><img class="exitProgram" src="assets/image/icons/refresh.png"></a>
+ <a href="#" id="volControl">
+ <img class="imgVolume" src="assets/image/icons/volumeEnabled.png" />
+ <img id="volDisabled" class="imgVolume" src="assets/image/icons/volumeDisabled.png" />
+ </a>
+ </div>
+ <center>
+ <div id="gameInfo">
+ <h3>Title:</h3>
+ <p>Largest Number Identification Game</p>
+ <h3>Objective:</h3>
+ <p>Identify the Largest number among the four numbers and drag and drop to the box.</p>
+ <h3>Description:</h3>
+ <p>
+ The game is basically intended for the students who have knowlege of the numbers from 1-100
+ The game consists of the four boxes where random numbers between the 1-99 appears.
+ The students have to select the largest number among these numbers and drag it to the box
+ and drop there. After the drop has been completed, next set of numbers appears and the
+ same steps has to be followed.<br />
+ The score system is that you will be awarded 1 point for each correct answer. If the
+ wrong answer is choosen, 1 point is deducted. The game will be completed
+ after the player has scored 99.
+
+ </p>
+ <h3>Instructions: </h3>
+ <p>
+ The game is self instructive. Just pick the right choice i.e. the greatest
+ number among four of the numbers and drag and drop to the box right below:
+ </p>
+ <h4> Have a great time...</h4>
+ </div>
+ </center>
+ <div id="sidebar">
+ <br />
+ <h2> Score </h2>
+ <div id="minussign"></div>
+ <img class="scoreBox" id="scoreDisplay" src= "" alt="" />
+ </div>
+
+ <div id = "gamearea">
+ <h2> Largest Number Identification Game </h2>
+ <div id="feedback_images">
+ <div class="drag_delegates draglist">
+ <img class="dragme" id="imgdrag0" draggable="true" src="" alt="" />
+ <img class="dragme" id="imgdrag1" draggable="true" src="" alt="" />
+ <img class="dragme" id="imgdrag2" draggable="true" src="" alt="" />
+ <img class="dragme" id="imgdrag3" draggable="true" src="" alt="" />
+ </div>
+ </div>
+ <div id="drop_area">
+ <div class="drophere" id="imgdrop">
+ <br />Pick up the largest number among the four numbers above and drop it to the box below.
+ </div>
+ </div>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/info.txt b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/info.txt
new file mode 100755
index 0000000..c9414d6
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/info.txt
@@ -0,0 +1,15 @@
+Title: Largest Number Identification Game
+Objective: Identify the Largest number among the four numbers and drag and drop to the box.
+Description: The game is basically intended for the students who have knowlege of the numbers from 1-100
+ The game consists of the four boxes where random numbers between the 1-99 appears.
+ The students have to select the largest number among these numbers and drag it to the box
+ and drop there. After the drop has been completed, next set of numbers appears and the
+ same steps has to be followed.
+ The score system is that you will be awarded 1 point for each correct answer. If the
+ wrong answer is choosen, 1 point is deducted. The game will be completed
+ after the player has scored 99.
+Instructions: The game is self instructive. Just pick the right choice i.e. the greatest
+ number among four of the numbers and drag and drop to the box right below:
+
+
+ Have a great time... \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Math_Largest_Number_Identification/js/lesson.js b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/js/lesson.js
new file mode 100755
index 0000000..769b7b4
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Largest_Number_Identification/js/lesson.js
@@ -0,0 +1,194 @@
+$(document).ready(function() {
+ var k = Karma({
+ audio: [{'name':'correct','file':'correct.ogg'},
+ {'name':'incorrect','file':'incorrect.ogg'},
+ {'name':'trigger', 'file':'trigger.ogg'}
+ ]});
+
+ k.ready(function(){
+
+
+ //initialize the variables used and display initial value
+ var selected_box = "not selected";
+ var score_value = 0;
+ var greatest;
+ var imgrand=[];
+ var flag, i ,j;
+ var volValue = 1; //value of volume 1 means volume on 0 means volume off
+ var score_sign = 1; //0 means the sign is negative and 1 means it is positive
+
+ /*
+ document.display.selectedBox.value = selected_box;
+ document.display.droppedBox.value = "not dropped";
+ document.display.score.value = score_value;
+ */
+ document.getElementById("scoreDisplay").src = "assets/image/drag_images/"+score_value+".png";
+ game();
+
+ $('a#anchorInfo').click(function(){ //Show the info of game
+ $('#gameInfo').toggle(5000);
+ });
+
+ $('a#exitNow').click(function(){ //Restart The Game
+ var confirmVal = confirm("Do you really want to restart the game.");
+ if(confirmVal == true)
+ location.reload(true);
+ });
+ $('a#volControl').click(function(){ //Show the info of game
+ $('.imgVolume').toggle();
+ if(volValue == 1)
+ volValue = 0;
+ else
+ volValue = 1;
+ if(volValue == 1){
+ k.audio.trigger.play();
+ alert("Volume On");
+
+ }
+ else{
+ k.audio.trigger.play();
+ alert("Volume is Off");
+ }
+ });
+
+
+
+ function generate_random_no() { //generate random number
+ var rand_no = Math.ceil(99*Math.random());
+ return rand_no;
+ }
+
+ function sortNumber(a,b){ //find the greatest number
+ return a - b;
+ }
+
+
+ function getRadioCheckedValue(radio_name) {
+ var oRadio = document.diffLevel.elements[radio_name];
+ for(var i = 0; i < oRadio.length; i++) {
+ if(oRadio[i].checked) {
+ return oRadio[i].value;
+ }
+
+ }
+
+ return '';
+ }
+
+ function displayNumbers(){
+ for(i=0; i<4; i++){
+ document.getElementById("imgdrag"+i+"").src = "assets/image/drag_images/"+imgrand[i]+".png";
+
+ }
+ }
+
+
+ function game(){ //draws the necessary random numbers for the game
+
+ //var selected_radio = getRadioCheckedValue("levelBtn");
+ //alert(selected_radio);
+
+ //generate random numbers w/o repitition
+ imgrand[0]=generate_random_no(); //1 number generated, 3 different numbers to be generated
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ imgrand[i] = generate_random_no();
+ for(j=0; j<i; j++){
+ if(imgrand[i]===imgrand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+ displayNumbers(); //display the random numbers in the respective boxes.
+ } //end of game()
+
+ // Set up the dragable element.
+ $('#feedback_images .drag_delegates').bind('dragstart', function(ev) {
+ if (!$(ev.target).hasClass('dragme'))
+ return true;
+ switch (ev.target.id) {
+ case 'imgdrag0':
+ selected_box = imgrand[0]; //the box is selected
+ break;
+ case 'imgdrag1':
+ selected_box = imgrand[1]; //the box is selected
+ break;
+ case 'imgdrag2':
+ selected_box = imgrand[2]; //the box is selected
+ break;
+ case 'imgdrag3':
+ selected_box = imgrand[3]; //the box is selected
+ break;
+ }
+ //document.display.selectedBox.value = selected_box;
+
+ return true;
+ });
+
+ // Set up the drop zone.
+ $('#drop_area .drophere').bind('dragenter', function(ev) { // Update the drop zone class on drag enter/leave
+ if (!$(ev.target).hasClass('drophere')) return true;
+ $(ev.target).addClass('dragover'); return false;
+ })
+
+ .bind('dragleave', function(ev) {
+ if (!$(ev.target).hasClass('drophere')) return true;
+ $(ev.target).removeClass('dragover'); return false;
+ })
+
+ // Allow drops of any kind into the zone.
+ .bind('dragover', function(ev) {
+ if (!$(ev.target).hasClass('drophere')) return true;
+ return false;
+ })
+
+ // Handle the final drop...
+ .bind('drop', function(ev) {
+ if (!$(ev.target).hasClass('drophere')) return true;
+
+ /** the box is dropped and now the calculation begins **/
+ // document.display.droppedBox.value = selected_box;
+
+ //finding the greatest among the 4 random numbers
+ imgrand.sort(sortNumber);
+ greatest = imgrand[3];
+ console.log(greatest);
+ if(selected_box < greatest){
+ score_value -=1;
+ if(volValue==1)
+ k.audio.incorrect.play();
+ }
+ else{
+ score_value +=1;
+ if(volValue==1)
+ k.audio.correct.play();
+ }
+
+ //NEgative number display technique
+ if(score_value<0)
+ document.getElementById("minussign").style.display = 'block';
+ else
+ document.getElementById("minussign").style.display = 'none';
+
+ resultval = Math.abs(score_value); //change the negative value to positive
+ document.getElementById("scoreDisplay").src = "assets/image/drag_images/"+resultval+".png";
+ if(score_value == 99){
+ alert("Congratulations!!! You have won the game. Press Ok to Continue...");
+ var gameVal = confirm("Press Ok To restart or Cancel to stay in page.");
+ if(gameVal == true){
+ location.reload(true);
+ score_value =0;
+ }
+ }
+ // document.display.score.value = score_value;
+ game();
+
+ ev.stopPropagation();
+ return false;
+ });
+
+
+ });
+}); //end of document.ready
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/correct.ogg b/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/trigger.ogg b/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/trigger.ogg
new file mode 100755
index 0000000..f22512a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/audio/trigger.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/1.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/1.png
new file mode 100755
index 0000000..22f359f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/10.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/10.png
new file mode 100755
index 0000000..bce11f0
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/10.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/2.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/2.png
new file mode 100755
index 0000000..39c8e32
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/3.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/3.png
new file mode 100755
index 0000000..328755e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/4.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/4.png
new file mode 100755
index 0000000..682a321
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/5.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/5.png
new file mode 100755
index 0000000..c626399
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/6.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/6.png
new file mode 100755
index 0000000..32a6080
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/7.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/7.png
new file mode 100755
index 0000000..f2fdfe8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/8.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/8.png
new file mode 100755
index 0000000..d5567f2
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/9.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/9.png
new file mode 100755
index 0000000..50b289d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/correct.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/correct.png
new file mode 100755
index 0000000..d6e54a8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/correct.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/1.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/1.png
new file mode 100755
index 0000000..713a668
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/1.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/10.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/10.png
new file mode 100755
index 0000000..8d9a506
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/10.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/2.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/2.png
new file mode 100755
index 0000000..55fc4a7
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/2.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/3.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/3.png
new file mode 100755
index 0000000..c1b404c
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/3.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/4.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/4.png
new file mode 100755
index 0000000..c9283f8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/4.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/5.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/5.png
new file mode 100755
index 0000000..7c30b90
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/5.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/6.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/6.png
new file mode 100755
index 0000000..11d3a50
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/6.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/7.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/7.png
new file mode 100755
index 0000000..92c500d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/7.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/8.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/8.png
new file mode 100755
index 0000000..9dbf94b
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/8.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/9.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/9.png
new file mode 100755
index 0000000..dc771ea
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/image_name/9.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/incorrect.png b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/incorrect.png
new file mode 100755
index 0000000..789db87
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/incorrect.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/play_again.jpg b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/play_again.jpg
new file mode 100755
index 0000000..db3ae56
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/assets/image/play_again.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/css/lesson.css b/bundles/XO/karma/lessons/Math_Money_Identification/css/lesson.css
new file mode 100755
index 0000000..d306784
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/css/lesson.css
@@ -0,0 +1,91 @@
+@CHARSET "UTF-8";
+body {
+ background-color: #ccc;
+}
+
+
+#gameArea{
+ margin-top:5%;
+ margin-left: 10%;
+ float: left;
+ width: 60%
+ padding:10px;
+
+}
+
+
+#questionBox{
+ color: red;
+ border: 3px outset #0AF9dd;
+ width: 150px;
+ padding: 5px;
+ background: #2EFEF7;
+ font: 20px "Helvetica", Verdana, Geneva, Arial, sans-serif;
+ font-weight: bold;
+
+}
+.imageBox{
+ margin-left: 25%;
+ margin-top: 25px;
+ padding: 10px;
+}
+
+.checkedOption{
+ position: absolute;
+ float:right;
+ right: 20%;
+ top: 25%;
+
+ width:120px;
+ height:120px;
+ padding: 5px;
+}
+
+#options{
+ position: absolute;
+ margin-left:50px;
+ top:80%;
+ width:800px;
+ height:80px;
+ padding: 10px;
+}
+
+.optImg{
+ padding:5px;
+}
+
+#scoreArea{
+ margin-left: 10%;
+ margin-right: 10%;
+ color: red;
+
+ padding: 5px;;
+ background: #FFFFFF;
+ border: 2px solid red;
+ background: black;
+ padding: 10px;
+ font: 18px "Lucida Sans Typewriter",Verdana,Times New Roman;
+}
+.playAgain{
+ position:absolute;
+ top: 10px;
+ margin-left:60%;
+ width:115px;
+ height: 30px;
+ padding: 2px 2px 2px 2px;
+ }
+
+input{
+ color:green;
+
+}
+#gameOver{
+ display: none;
+ margin-left:300px;
+ width: 180px;
+ height: 20px;
+ font: 25px "Rockwell Extra Bold", Geneva, Arial, Helvetica, sans-serif,Times New Roman;
+ font-weight: bold;
+ background-color: #ccc;
+ padding: 10px;
+}
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/index.html b/bundles/XO/karma/lessons/Math_Money_Identification/index.html
new file mode 100755
index 0000000..0c349ec
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Math_Money Identification</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,Money identification" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+</head>
+<body>
+ <div id ="scoreArea">
+ <form name="scoreDisplay">
+ <b>Score:</b> <input type="text" size="1" name="score"/>
+ <b>Total:</b> <input type="text" size="1" name="total"/>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|Identify Money |
+ </form>
+
+ <a href="#" id="anchorPlayAgain"><img class="playAgain" src="assets/image/play_again.jpg" alt=""/></a>
+ </div>
+ <div id="gameArea">
+ <!--
+ <div id="questionBox">How Many Rupees is This?</div>
+ -->
+ <img class="imageBox" id="imgObject" src="" alt=""/>
+ <img class="checkedOption" id="check" src="" alt=""/>
+
+ <div id="options">
+ <a href="#" id="anchorOpt0"><img class="optImg" id="option0" src="" alt=""/></a>
+ <a href="#" id="anchorOpt1"><img class="optImg" id="option1" src="" alt=""/></a>
+ <a href="#" id="anchorOpt2"><img class="optImg" id="option2" src="" alt=""/></a>
+ <a href="#" id="anchorOpt3"><img class="optImg" id="option3" src="" alt=""/></a>
+ </div>
+
+ <div id="gameOver">
+ Game Over
+ </div>
+ </div>
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Math_Money_Identification/js/lesson.js b/bundles/XO/karma/lessons/Math_Money_Identification/js/lesson.js
new file mode 100755
index 0000000..9012805
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Money_Identification/js/lesson.js
@@ -0,0 +1,197 @@
+$(document).ready(function(){
+ var k = Karma({
+ audio: [{'name':'correct','file':'correct.ogg'},
+ {'name':'incorrect','file':'incorrect.ogg'},
+ {'name':'trigger', 'file':'trigger.ogg'}
+ ]});
+
+ k.ready(function(){
+
+ var flag, i ,j;
+ var object_counter = 1;
+ var imgNameRand = [];
+ var optPosition = [];
+ var optOtherPos = [];
+ var imageObject = [];
+ var correctPosition;
+ var selectedOption;
+ var score = 0;
+ var wrong_selected = 0; //wrong option selected so don't score up
+ var pos;
+ var t;
+ var current_image;
+
+
+ load_images(); //load the image numbers for random display
+ display_score();
+ game(); //let the game begin
+
+
+ function display_score(){
+ document.scoreDisplay.score.value = score;
+ if(object_counter > 10)
+ document.scoreDisplay.total.value = 10;
+ else
+ document.scoreDisplay.total.value = object_counter;
+ }
+
+ function checkDisplay(){ //Displays the correct and incorrect info
+ if(wrong_selected == 1){
+ $('.checkedOption').show();
+ k.audio.incorrect.play();
+ document.getElementById("check").src = "assets/image/incorrect.png";
+ $('.checkedOption').fadeOut(1000);
+ }
+ else{
+ $('.checkedOption').hide();
+ k.audio.correct.play();
+ document.getElementById("check").src = "assets/image/correct.png";
+ $('.checkedOption').fadeOut(2000);
+ //needs timer for holding on for abt a sec
+ }
+ }
+
+ $("#anchorPlayAgain").click(function(){
+ $('#gameOver').hide();
+ $('.optImg').show();
+ $('.imageBox').show();
+ load_images();
+ score = 0;
+ object_counter = 1;
+ wrong_selected = 0;
+ display_score();
+
+ game();
+
+ });
+ $("#anchorOpt0").click(function(){
+ selected_Option_Process('0');
+ });
+ $("#anchorOpt1").click(function(){
+ selected_Option_Process('1');
+ });
+ $("#anchorOpt2").click(function(){
+ selected_Option_Process('2');
+ });
+ $("#anchorOpt3").click(function(){
+ selected_Option_Process('3');
+ });
+
+ function generate_random_no(no_limit) { //generate random number
+ var rand_no = Math.ceil(no_limit*Math.random());
+ return rand_no;
+ }
+
+ function get_random_position(){ //generate random number between 0-3
+ var rand_pos = Math.floor(Math.random()*4);
+ return rand_pos;
+ }
+
+ function load_images(){
+
+ imageObject[0] = generate_random_no("10");
+ for(i=1; i<10; i++){
+ do{
+ flag = 0;
+ imageObject[i] = generate_random_no("10");
+ for(j=0; j<i; j++){
+ if(imageObject[i]===imageObject[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+
+ }
+ function selected_Option_Process(selectedOption){
+
+ if(selectedOption == correctPosition){
+ object_counter++;
+ if(wrong_selected == 0){
+ score++;
+ }
+ wrong_selected = 0;
+ display_score();
+ checkDisplay();
+ //t=setTimeout('game()',1000);
+ game();
+ }
+ else {
+ wrong_selected = 1;
+ checkDisplay();
+ }
+
+ }
+ function game(){
+
+
+ //clearTimeout(t);
+ wrong_selected = 0;
+ current_image = object_counter-1;
+ document.getElementById("imgObject").src = "assets/image/"+imageObject[current_image]+".png";
+
+ //find correct answer and apply it to the position
+ currentImage = imageObject[current_image];
+ imgNameRand[0] = currentImage;
+ //generate choices
+
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ imgNameRand[i] = generate_random_no("10");
+ for(j=0; j<i; j++){
+ if(imgNameRand[i]===imgNameRand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+
+ correctPosition = get_random_position();
+
+ optOtherPos[0] = correctPosition;
+
+ for(i=1; i<4; i++){
+ do{
+ flag = 0;
+ optOtherPos[i] = get_random_position();
+ for(j=0; j<i; j++){ //chek repeat within optOtherPos array
+ if(optOtherPos[i] === optOtherPos[j]){
+ flag++;
+ }
+ }
+
+ }while(flag != 0);
+
+ }
+
+ for(i=0; i<4; i++){
+ pos = optOtherPos[i];
+ optPosition[pos] = imgNameRand[i];
+ }
+
+
+ //random positions are stored in optOtherPos array. Great
+
+
+ for(i=0; i<4; i++){
+ document.getElementById("option"+i+"").src = "assets/image/image_name/"+optPosition[i]+".png";
+ }
+
+ //check for the correctness
+ if(object_counter > 10){
+
+ $('.optImg').hide();
+ $('.imageBox').hide();
+ $('#gameOver').show();
+
+
+ }
+
+ //else
+ //no change
+ } //end of game
+});
+}); //end of DOM \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/audio/correct.ogg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/1.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/1.jpg
new file mode 100755
index 0000000..5ba21a7
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/1.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/10.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/10.jpg
new file mode 100755
index 0000000..068daa0
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/10.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/11.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/11.jpg
new file mode 100755
index 0000000..262686e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/11.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/12.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/12.jpg
new file mode 100755
index 0000000..a71df3e
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/12.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/13.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/13.jpg
new file mode 100755
index 0000000..cc66d15
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/13.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/14.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/14.jpg
new file mode 100755
index 0000000..0dfb936
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/14.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/15.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/15.jpg
new file mode 100755
index 0000000..1d66c52
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/15.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/16.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/16.jpg
new file mode 100755
index 0000000..610585a
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/16.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/2.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/2.jpg
new file mode 100755
index 0000000..21c70e2
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/2.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/3.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/3.jpg
new file mode 100755
index 0000000..51b09f7
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/3.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/4.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/4.jpg
new file mode 100755
index 0000000..120a8ee
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/4.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/5.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/5.jpg
new file mode 100755
index 0000000..1d500ac
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/5.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/6.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/6.jpg
new file mode 100755
index 0000000..0fa2d17
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/6.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/7.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/7.jpg
new file mode 100755
index 0000000..bd80ca4
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/7.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/8.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/8.jpg
new file mode 100755
index 0000000..a11eb62
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/8.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/9.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/9.jpg
new file mode 100755
index 0000000..909ffe4
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/9.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/img1.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/img1.jpg
new file mode 100755
index 0000000..fb02cdb
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img1/img1.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/1.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/1.jpg
new file mode 100755
index 0000000..90513fa
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/1.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/10.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/10.jpg
new file mode 100755
index 0000000..de844ca
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/10.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/11.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/11.jpg
new file mode 100755
index 0000000..4a5aeea
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/11.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/12.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/12.jpg
new file mode 100755
index 0000000..0f3cf52
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/12.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/13.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/13.jpg
new file mode 100755
index 0000000..cc9d0fc
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/13.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/14.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/14.jpg
new file mode 100755
index 0000000..e4c4a0f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/14.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/15.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/15.jpg
new file mode 100755
index 0000000..bf83d0f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/15.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/16.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/16.jpg
new file mode 100755
index 0000000..1080368
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/16.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/2.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/2.jpg
new file mode 100755
index 0000000..af7673d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/2.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/3.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/3.jpg
new file mode 100755
index 0000000..eaef3e8
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/3.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/4.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/4.jpg
new file mode 100755
index 0000000..205f421
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/4.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/5.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/5.jpg
new file mode 100755
index 0000000..7b6c352
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/5.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/6.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/6.jpg
new file mode 100755
index 0000000..6e8c67d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/6.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/7.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/7.jpg
new file mode 100755
index 0000000..85c408b
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/7.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/8.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/8.jpg
new file mode 100755
index 0000000..3095538
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/8.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/9.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/9.jpg
new file mode 100755
index 0000000..f13bb3d
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/9.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/img2.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/img2.jpg
new file mode 100755
index 0000000..bbb2f21
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img2/img2.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/1.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/1.jpg
new file mode 100755
index 0000000..f5861bf
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/1.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/10.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/10.jpg
new file mode 100755
index 0000000..b147651
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/10.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/11.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/11.jpg
new file mode 100755
index 0000000..4a15a09
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/11.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/12.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/12.jpg
new file mode 100755
index 0000000..456e363
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/12.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/13.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/13.jpg
new file mode 100755
index 0000000..1a343d0
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/13.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/14.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/14.jpg
new file mode 100755
index 0000000..bc70c5f
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/14.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/15.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/15.jpg
new file mode 100755
index 0000000..efc1e20
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/15.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/16.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/16.jpg
new file mode 100755
index 0000000..d57c384
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/16.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/2.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/2.jpg
new file mode 100755
index 0000000..ade0137
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/2.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/3.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/3.jpg
new file mode 100755
index 0000000..16f4cbb
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/3.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/4.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/4.jpg
new file mode 100755
index 0000000..38feace
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/4.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/5.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/5.jpg
new file mode 100755
index 0000000..da06517
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/5.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/6.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/6.jpg
new file mode 100755
index 0000000..7455c27
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/6.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/7.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/7.jpg
new file mode 100755
index 0000000..ad7c5ed
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/7.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/8.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/8.jpg
new file mode 100755
index 0000000..c4126fb
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/8.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/9.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/9.jpg
new file mode 100755
index 0000000..b97c313
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/9.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/img3.jpg b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/img3.jpg
new file mode 100755
index 0000000..eb4b6fc
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/assets/image/img3/img3.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/css/lesson.css b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/css/lesson.css
new file mode 100755
index 0000000..28e9985
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/css/lesson.css
@@ -0,0 +1,50 @@
+body {
+ background: #affafc;
+ }
+
+#gamearea{
+ float:right;
+ width: 664px;
+ border: 5px gold dashed;
+ padding: 10px;
+}
+
+.dragme {
+ width: 160px;
+ height: 120px;
+ padding: 1px 3px 0px 3px; /*top right bottom left*/
+ cursor: move;
+
+}
+
+#imageBar{
+ margin-left: 20px;
+ margin-top:15px;
+ float:left;
+ width: 225px;
+ height: 495px;
+ border: 2px solid red;
+
+}
+
+.imageThumb{
+ margin: 5px;
+ width: 200px;
+ height: 138px;
+ border: 2px groove #00FF00;
+ padding: 5px;
+ margin 1em;
+}
+
+.imgMain{
+ width: 640px;
+ height: 480px;
+ float : right;
+ padding : 10px;
+ visibility: hidden;
+ position:relative;
+}
+
+#img1,#img2,#img3 {
+ display:none;
+} \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/index.html b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/index.html
new file mode 100755
index 0000000..0660bce
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/index.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title> Math_Numeric Puzzle Solving Game </title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <meta http-equiv="Content-Language" content="en-us"/>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal,numeric,math, puzzle" />
+ <link type="image/ico" rel="icon" href="../../../assets/default/images/favicon.ico" />
+ <link rel="stylesheet" type="text/css" href="css/lesson.css"/>
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+ </head>
+ <body>
+ <div id = "imageBar">
+ <a href="#" id="anchorImg1"><img class="imageThumb" src="assets/image/img1/img1.jpg" alt="" /></a>
+ <a href="#" id="anchorImg2"><img class="imageThumb" src="assets/image/img2/img2.jpg" alt="" /></a>
+ <a href="#" id="anchorImg3"><img class="imageThumb" src="assets/image/img3/img3.jpg" alt="" /></a>
+ </div>
+ <div id = "gamearea">
+ <div id="feedback_image">
+ <img id="img1" src="assets/image/img1/img1.jpg" alt=""/>
+ <img id="img2" src="assets/image/img2/img2.jpg" alt=""/>
+ <img id="img3" src="assets/image/img3/img3.jpg" alt=""/>
+ </div>
+ </div>
+ </body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-1.3.2.js b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-1.3.2.js
new file mode 100755
index 0000000..9263574
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-1.3.2.js
@@ -0,0 +1,4376 @@
+/*!
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){
+
+var
+ // Will speed up references to window, and allows munging its name.
+ window = this,
+ // Will speed up references to undefined, and allows munging its name.
+ undefined,
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ jQuery = window.jQuery = window.$ = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this[0] = selector;
+ this.length = 1;
+ this.context = selector;
+ return this;
+ }
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ var match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] )
+ selector = jQuery.clean( [ match[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var elem = document.getElementById( match[3] );
+
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem && elem.id != match[3] )
+ return jQuery().find( selector );
+
+ // Otherwise, we inject the element directly into the jQuery object
+ var ret = jQuery( elem || [] );
+ ret.context = document;
+ ret.selector = selector;
+ return ret;
+ }
+
+ // HANDLE: $(expr, [context])
+ // (which is just equivalent to: $(content).find(expr)
+ } else
+ return jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) )
+ return jQuery( document ).ready( selector );
+
+ // Make sure that old selector state is passed along
+ if ( selector.selector && selector.context ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return this.setArray(jQuery.isArray( selector ) ?
+ selector :
+ jQuery.makeArray(selector));
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.3.2",
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num === undefined ?
+
+ // Return a 'clean' array
+ Array.prototype.slice.call( this ) :
+
+ // Return just the object
+ this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" )
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ else if ( name )
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ Array.prototype.push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem && elem.jquery ? elem[0] : elem
+ , this );
+ },
+
+ attr: function( name, value, type ) {
+ var options = name;
+
+ // Look for the case where we're accessing a style value
+ if ( typeof name === "string" )
+ if ( value === undefined )
+ return this[0] && jQuery[ type || "attr" ]( this[0], name );
+
+ else {
+ options = {};
+ options[ name ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(i){
+ // Set all the styles
+ for ( name in options )
+ jQuery.attr(
+ type ?
+ this.style :
+ this,
+ name, jQuery.prop( this, options[ name ], type, i, name )
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ // ignore negative width and height values
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+ value = undefined;
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function( text ) {
+ if ( typeof text !== "object" && text != null )
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+ var ret = "";
+
+ jQuery.each( text || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ ret += this.nodeType != 1 ?
+ this.nodeValue :
+ jQuery.fn.text( [ this ] );
+ });
+ });
+
+ return ret;
+ },
+
+ wrapAll: function( html ) {
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).clone();
+
+ if ( this[0].parentNode )
+ wrap.insertBefore( this[0] );
+
+ wrap.map(function(){
+ var elem = this;
+
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ return this.each(function(){
+ jQuery( this ).contents().wrapAll( html );
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function(){
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function(elem){
+ if (this.nodeType == 1)
+ this.appendChild( elem );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function(elem){
+ if (this.nodeType == 1)
+ this.insertBefore( elem, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, function(elem){
+ this.parentNode.insertBefore( elem, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, function(elem){
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery( [] );
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: [].push,
+ sort: [].sort,
+ splice: [].splice,
+
+ find: function( selector ) {
+ if ( this.length === 1 ) {
+ var ret = this.pushStack( [], "find", selector );
+ ret.length = 0;
+ jQuery.find( selector, this[0], ret );
+ return ret;
+ } else {
+ return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
+ return jQuery.find( selector, elem );
+ })), "find", selector );
+ }
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function(){
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var html = this.outerHTML;
+ if ( !html ) {
+ var div = this.ownerDocument.createElement("div");
+ div.appendChild( this.cloneNode(true) );
+ html = div.innerHTML;
+ }
+
+ return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
+ } else
+ return this.cloneNode(true);
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true ) {
+ var orig = this.find("*").andSelf(), i = 0;
+
+ ret.find("*").andSelf().each(function(){
+ if ( this.nodeName !== orig[i].nodeName )
+ return;
+
+ var events = jQuery.data( orig[i], "events" );
+
+ for ( var type in events ) {
+ for ( var handler in events[ type ] ) {
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ }
+ }
+
+ i++;
+ });
+ }
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function( selector ) {
+ return this.pushStack(
+ jQuery.isFunction( selector ) &&
+ jQuery.grep(this, function(elem, i){
+ return selector.call( elem, i );
+ }) ||
+
+ jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
+ return elem.nodeType === 1;
+ }) ), "filter", selector );
+ },
+
+ closest: function( selector ) {
+ var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
+ closer = 0;
+
+ return this.map(function(){
+ var cur = this;
+ while ( cur && cur.ownerDocument ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
+ jQuery.data(cur, "closest", closer);
+ return cur;
+ }
+ cur = cur.parentNode;
+ closer++;
+ }
+ });
+ },
+
+ not: function( selector ) {
+ if ( typeof selector === "string" )
+ // test special case where just one selector is passed in
+ if ( isSimple.test( selector ) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
+ else
+ selector = jQuery.multiFilter( selector, this );
+
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+ return this.filter(function() {
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+ });
+ },
+
+ add: function( selector ) {
+ return this.pushStack( jQuery.unique( jQuery.merge(
+ this.get(),
+ typeof selector === "string" ?
+ jQuery( selector ) :
+ jQuery.makeArray( selector )
+ )));
+ },
+
+ is: function( selector ) {
+ return !!selector && jQuery.multiFilter( selector, this ).length > 0;
+ },
+
+ hasClass: function( selector ) {
+ return !!selector && this.is( "." + selector );
+ },
+
+ val: function( value ) {
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if( jQuery.nodeName( elem, 'option' ) )
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one )
+ return value;
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(/\r/g, "");
+
+ }
+
+ return undefined;
+ }
+
+ if ( typeof value === "number" )
+ value += '';
+
+ return this.each(function(){
+ if ( this.nodeType != 1 )
+ return;
+
+ if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+ jQuery.inArray(this.name, value) >= 0);
+
+ else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(value);
+
+ jQuery( "option", this ).each(function(){
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+ jQuery.inArray( this.text, values ) >= 0);
+ });
+
+ if ( !values.length )
+ this.selectedIndex = -1;
+
+ } else
+ this.value = value;
+ });
+ },
+
+ html: function( value ) {
+ return value === undefined ?
+ (this[0] ?
+ this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
+ null) :
+ this.empty().append( value );
+ },
+
+ replaceWith: function( value ) {
+ return this.after( value ).remove();
+ },
+
+ eq: function( i ) {
+ return this.slice( i, +i + 1 );
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ),
+ "slice", Array.prototype.slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function(elem, i){
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function( args, table, callback ) {
+ if ( this[0] ) {
+ var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
+ scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
+ first = fragment.firstChild;
+
+ if ( first )
+ for ( var i = 0, l = this.length; i < l; i++ )
+ callback.call( root(this[i], first), this.length > 1 || i > 0 ?
+ fragment.cloneNode(true) : fragment );
+
+ if ( scripts )
+ jQuery.each( scripts, evalScript );
+ }
+
+ return this;
+
+ function root( elem, cur ) {
+ return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+ }
+ }
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+function evalScript( i, elem ) {
+ if ( elem.src )
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild( elem );
+}
+
+function now(){
+ return +new Date;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) )
+ target = {};
+
+ // extend jQuery itself if only one argument is passed
+ if ( length == i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ )
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null )
+ // Extend the base object
+ for ( var name in options ) {
+ var src = target[ name ], copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && copy && typeof copy === "object" && !copy.nodeType )
+ target[ name ] = jQuery.extend( deep,
+ // Never move original objects, clone them
+ src || ( copy.length != null ? [ ] : { } )
+ , copy );
+
+ // Don't bring in undefined values
+ else if ( copy !== undefined )
+ target[ name ] = copy;
+
+ }
+
+ // Return the modified object
+ return target;
+};
+
+// exclude the following css properties to add px
+var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+ // cache defaultView
+ defaultView = document.defaultView || {},
+ toString = Object.prototype.toString;
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep )
+ window.jQuery = _jQuery;
+
+ return jQuery;
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return toString.call(obj) === "[object Function]";
+ },
+
+ isArray: function( obj ) {
+ return toString.call(obj) === "[object Array]";
+ },
+
+ // check if an element is in a (or is an) XML document
+ isXMLDoc: function( elem ) {
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
+ },
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ if ( data && /\S/.test(data) ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+ if ( jQuery.support.scriptEval )
+ script.appendChild( document.createTextNode( data ) );
+ else
+ script.text = data;
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0, length = object.length;
+
+ if ( args ) {
+ if ( length === undefined ) {
+ for ( name in object )
+ if ( callback.apply( object[ name ], args ) === false )
+ break;
+ } else
+ for ( ; i < length; )
+ if ( callback.apply( object[ i++ ], args ) === false )
+ break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( length === undefined ) {
+ for ( name in object )
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ break;
+ } else
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+ }
+
+ return object;
+ },
+
+ prop: function( elem, value, type, i, name ) {
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, i );
+
+ // Handle passing in a number to a CSS property
+ return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, classNames ) {
+ if (elem.nodeType == 1)
+ elem.className = classNames !== undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+ "";
+ },
+
+ // internal only, use hasClass("class")
+ has: function( elem, className ) {
+ return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options )
+ elem.style[ name ] = old[ name ];
+ },
+
+ css: function( elem, name, force, extra ) {
+ if ( name == "width" || name == "height" ) {
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+ function getWH() {
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" )
+ return;
+
+ jQuery.each( which, function() {
+ if ( !extra )
+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ if ( extra === "margin" )
+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+ else
+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ });
+ }
+
+ if ( elem.offsetWidth !== 0 )
+ getWH();
+ else
+ jQuery.swap( elem, props, getWH );
+
+ return Math.max(0, Math.round(val));
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret, style = elem.style;
+
+ // We need to handle opacity special in IE
+ if ( name == "opacity" && !jQuery.support.opacity ) {
+ ret = jQuery.attr( style, "opacity" );
+
+ return ret == "" ?
+ "1" :
+ ret;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( name.match( /float/i ) )
+ name = styleFloat;
+
+ if ( !force && style && style[ name ] )
+ ret = style[ name ];
+
+ else if ( defaultView.getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( name.match( /float/i ) )
+ name = "float";
+
+ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+
+ var computedStyle = defaultView.getComputedStyle( elem, null );
+
+ if ( computedStyle )
+ ret = computedStyle.getPropertyValue( name );
+
+ // We should always get a number back from opacity
+ if ( name == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+ // Remember the original values
+ var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = ret || 0;
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function( elems, context, fragment ) {
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" )
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
+ var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
+ if ( match )
+ return [ context.createElement( match[1] ) ];
+ }
+
+ var ret = [], scripts = [], div = context.createElement("div");
+
+ jQuery.each(elems, function(i, elem){
+ if ( typeof elem === "number" )
+ elem += '';
+
+ if ( !elem )
+ return;
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+ all :
+ front + "></" + tag + ">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
+
+ var wrap =
+ // option or optgroup
+ !tags.indexOf("<opt") &&
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||
+
+ !tags.indexOf("<leg") &&
+ [ 1, "<fieldset>", "</fieldset>" ] ||
+
+ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [ 1, "<table>", "</table>" ] ||
+
+ !tags.indexOf("<tr") &&
+ [ 2, "<table><tbody>", "</tbody></table>" ] ||
+
+ // <thead> matched above
+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
+
+ !tags.indexOf("<col") &&
+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ !jQuery.support.htmlSerialize &&
+ [ 1, "div<div>", "</div>" ] ||
+
+ [ 0, "", "" ];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = /<tbody/i.test(elem),
+ tbody = !tags.indexOf("<table") && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] == "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j )
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.nodeType )
+ ret.push( elem );
+ else
+ ret = jQuery.merge( ret, elem );
+
+ });
+
+ if ( fragment ) {
+ for ( var i = 0; ret[i]; i++ ) {
+ if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+ } else {
+ if ( ret[i].nodeType === 1 )
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ fragment.appendChild( ret[i] );
+ }
+ }
+
+ return scripts;
+ }
+
+ return ret;
+ },
+
+ attr: function( elem, name, value ) {
+ // don't set attributes on text and comment nodes
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+ return undefined;
+
+ var notxml = !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ // IE elem.getAttribute passes even for style
+ if ( elem.tagName ) {
+
+ // These attributes require special treatment
+ var special = /href|src|style/.test( name );
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && elem.parentNode )
+ elem.parentNode.selectedIndex;
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ){
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
+ throw "type property can't be changed";
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
+ return elem.getAttributeNode( name ).nodeValue;
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ if ( name == "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+ return attributeNode && attributeNode.specified
+ ? attributeNode.value
+ : elem.nodeName.match(/(button|input|object|select|textarea)/i)
+ ? 0
+ : elem.nodeName.match(/^(a|area)$/i) && elem.href
+ ? 0
+ : undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ if ( set )
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special
+ // Some attributes require a special call on IE
+ ? elem.getAttribute( name, 2 )
+ : elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name == "opacity" ) {
+ if ( set ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+ (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
+ "";
+ }
+
+ name = name.replace(/-([a-z])/ig, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ if ( set )
+ elem[ name ] = value;
+
+ return elem[ name ];
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( /^\s+|\s+$/g, "" );
+ },
+
+ makeArray: function( array ) {
+ var ret = [];
+
+ if( array != null ){
+ var i = array.length;
+ // The window, strings (and functions) also have 'length'
+ if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
+ ret[0] = array;
+ else
+ while( i )
+ ret[--i] = array[i];
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ for ( var i = 0, length = array.length; i < length; i++ )
+ // Use === because on IE, window == document
+ if ( array[ i ] === elem )
+ return i;
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+ var i = 0, elem, pos = first.length;
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( !jQuery.support.getAll ) {
+ while ( (elem = second[ i++ ]) != null )
+ if ( elem.nodeType != 8 )
+ first[ pos++ ] = elem;
+
+ } else
+ while ( (elem = second[ i++ ]) != null )
+ first[ pos++ ] = elem;
+
+ return first;
+ },
+
+ unique: function( array ) {
+ var ret = [], done = {};
+
+ try {
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ var id = jQuery.data( array[ i ] );
+
+ if ( !done[ id ] ) {
+ done[ id ] = true;
+ ret.push( array[ i ] );
+ }
+ }
+
+ } catch( e ) {
+ ret = array;
+ }
+
+ return ret;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ )
+ if ( !inv != !callback( elems[ i ], i ) )
+ ret.push( elems[ i ] );
+
+ return ret;
+ },
+
+ map: function( elems, callback ) {
+ var ret = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ var value = callback( elems[ i ], i );
+
+ if ( value != null )
+ ret[ ret.length ] = value;
+ }
+
+ return ret.concat.apply( [], ret );
+ }
+});
+
+// Use of jQuery.browser is deprecated.
+// It's included for backwards compatibility and plugins,
+// although they should work to migrate away.
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
+ safari: /webkit/.test( userAgent ),
+ opera: /opera/.test( userAgent ),
+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+};
+
+jQuery.each({
+ parent: function(elem){return elem.parentNode;},
+ parents: function(elem){return jQuery.dir(elem,"parentNode");},
+ next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
+ prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
+ nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
+ prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
+ siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
+ children: function(elem){return jQuery.sibling(elem.firstChild);},
+ contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
+}, function(name, fn){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = jQuery.map( this, fn );
+
+ if ( selector && typeof selector == "string" )
+ ret = jQuery.multiFilter( selector, ret );
+
+ return this.pushStack( jQuery.unique( ret ), name, selector );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(name, original){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, selector );
+ };
+});
+
+jQuery.each({
+ removeAttr: function( name ) {
+ jQuery.attr( this, name, "" );
+ if (this.nodeType == 1)
+ this.removeAttribute( name );
+ },
+
+ addClass: function( classNames ) {
+ jQuery.className.add( this, classNames );
+ },
+
+ removeClass: function( classNames ) {
+ jQuery.className.remove( this, classNames );
+ },
+
+ toggleClass: function( classNames, state ) {
+ if( typeof state !== "boolean" )
+ state = !jQuery.className.has( this, classNames );
+ jQuery.className[ state ? "add" : "remove" ]( this, classNames );
+ },
+
+ remove: function( selector ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
+ // Prevent memory leaks
+ jQuery( "*", this ).add([this]).each(function(){
+ jQuery.event.remove(this);
+ jQuery.removeData(this);
+ });
+ if (this.parentNode)
+ this.parentNode.removeChild( this );
+ }
+ },
+
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ jQuery(this).children().remove();
+
+ // Remove any remaining nodes
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(name, fn){
+ jQuery.fn[ name ] = function(){
+ return this.each( fn, arguments );
+ };
+});
+
+// Helper function used by the dimensions and offset modules
+function num(elem, prop) {
+ return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
+}
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ?
+ jQuery.cache[ id ][ name ] :
+ id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+
+ for ( name in jQuery.cache[ id ] )
+ break;
+
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+ queue: function( elem, type, data ) {
+ if ( elem ){
+
+ type = (type || "fx") + "queue";
+
+ var q = jQuery.data( elem, type );
+
+ if ( !q || jQuery.isArray(data) )
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+ else if( data )
+ q.push( data );
+
+ }
+ return q;
+ },
+
+ dequeue: function( elem, type ){
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift();
+
+ if( !type || type === "fx" )
+ fn = queue[0];
+
+ if( fn !== undefined )
+ fn.call(elem);
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ){
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length )
+ data = jQuery.data( this[0], key );
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
+ jQuery.data( this, key, value );
+ });
+ },
+
+ removeData: function( key ){
+ return this.each(function(){
+ jQuery.removeData( this, key );
+ });
+ },
+ queue: function(type, data){
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined )
+ return jQuery.queue( this[0], type );
+
+ return this.each(function(){
+ var queue = jQuery.queue( this, type, data );
+
+ if( type == "fx" && queue.length == 1 )
+ queue[0].call(this);
+ });
+ },
+ dequeue: function(type){
+ return this.each(function(){
+ jQuery.dequeue( this, type );
+ });
+ }
+});/*!
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
+ done = 0,
+ toString = Object.prototype.toString;
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 )
+ return [];
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true;
+
+ // Reset the position of the chunker regexp (start from head)
+ chunker.lastIndex = 0;
+
+ while ( (m = chunker.exec(selector)) !== null ) {
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = RegExp.rightContext;
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] )
+ selector += parts.shift();
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
+ set = Sizzle.filter( ret.expr, ret.set );
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, isXML(context) );
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, context, results, seed );
+
+ if ( sortOrder ) {
+ hasDuplicate = false;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.match[ type ].exec( expr )) ) {
+ var left = RegExp.leftContext;
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+ var filter = Expr.filter[ type ], found, item;
+ anyFound = false;
+
+ if ( curLoop == result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr == old ) {
+ if ( anyFound == null ) {
+ throw "Syntax error, unrecognized expression: " + expr;
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+ },
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag && !isXML ) {
+ part = part.toUpperCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = isXML ? part : part.toUpperCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( !part.match(/\W/) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !part.match(/\W/) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context, isXML){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
+ if ( !inplace )
+ result.push( elem );
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ for ( var i = 0; curLoop[i] === false; i++ ){}
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+ },
+ CHILD: function(match){
+ if ( match[1] == "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 == i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 == i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while (node = node.previousSibling) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ if ( type == 'first') return true;
+ node = elem;
+ case 'last':
+ while (node = node.nextSibling) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first == 1 && last == 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first == 0 ) {
+ return diff == 0;
+ } else {
+ return ( diff % first == 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value != check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes );
+
+// Provide a fallback method if it does not work
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.selectNode(a);
+ aRange.collapse(true);
+ bRange.selectNode(b);
+ bRange.collapse(true);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("form"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<input name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( !!document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+})();
+
+if ( document.querySelectorAll ) (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ Sizzle.find = oldSizzle.find;
+ Sizzle.filter = oldSizzle.filter;
+ Sizzle.selectors = oldSizzle.selectors;
+ Sizzle.matches = oldSizzle.matches;
+})();
+
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
+ var div = document.createElement("div");
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ if ( div.getElementsByClassName("e").length === 0 )
+ return;
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 )
+ return;
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && isXML( elem.ownerDocument );
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.filter = Sizzle.filter;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+
+Sizzle.selectors.filters.hidden = function(elem){
+ return elem.offsetWidth === 0 || elem.offsetHeight === 0;
+};
+
+Sizzle.selectors.filters.visible = function(elem){
+ return elem.offsetWidth > 0 || elem.offsetHeight > 0;
+};
+
+Sizzle.selectors.filters.animated = function(elem){
+ return jQuery.grep(jQuery.timers, function(fn){
+ return elem === fn.elem;
+ }).length;
+};
+
+jQuery.multiFilter = function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return Sizzle.matches(expr, elems);
+};
+
+jQuery.dir = function( elem, dir ){
+ var matched = [], cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+};
+
+jQuery.nth = function(cur, result, dir, elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+};
+
+jQuery.sibling = function(n, elem){
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && n != elem )
+ r.push( n );
+ }
+
+ return r;
+};
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(elem, types, handler, data) {
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && elem != window )
+ elem = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if ( data !== undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = this.proxy( fn );
+
+ // Store data in unique handler
+ handler.data = data;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply(arguments.callee.elem, arguments) :
+ undefined;
+ });
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type) {
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ handler.type = namespaces.slice().sort().join(".");
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ if ( jQuery.event.specialAll[type] )
+ jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener)
+ elem.addEventListener(type, handle, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[type] = true;
+ });
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(elem, types, handler) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ var events = jQuery.data(elem, "events"), ret, index;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
+ for ( var type in events )
+ this.remove( elem, type + (types || "") );
+ else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type){
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
+
+ if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( var handle in events[type] )
+ // Handle the removal of namespaced events
+ if ( namespace.test(events[type][handle].type) )
+ delete events[type][handle];
+
+ if ( jQuery.event.specialAll[type] )
+ jQuery.event.specialAll[type].teardown.call(elem, namespaces);
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
+ if (elem.removeEventListener)
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ else if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ ret = null;
+ delete events[type];
+ }
+ }
+ });
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) handle.elem = null;
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem, bubbling ) {
+ // Event object or event type
+ var type = event.type || event;
+
+ if( !bubbling ){
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery.each( jQuery.cache, function(){
+ if ( this.events && this.events[type] )
+ jQuery.event.trigger( event, data, this.handle.elem );
+ });
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
+ return undefined;
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data);
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data(elem, "handle");
+ if ( handle )
+ handle.apply( elem, data );
+
+ // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
+ if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+ event.result = false;
+
+ // Trigger the native events (except for clicks on links)
+ if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+ this.triggered = true;
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
+ }
+
+ this.triggered = false;
+
+ if ( !event.isPropagationStopped() ) {
+ var parent = elem.parentNode || elem.ownerDocument;
+ if ( parent )
+ jQuery.event.trigger(event, data, parent, true);
+ }
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var all, handlers;
+
+ event = arguments[0] = jQuery.event.fix( event || window.event );
+ event.currentTarget = this;
+
+ // Namespaced event handlers
+ var namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+
+ // Cache this now, all = true means, any handler
+ all = !namespaces.length && !event.exclusive;
+
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
+
+ handlers = ( jQuery.data(this, "events") || {} )[event.type];
+
+ for ( var j in handlers ) {
+ var handler = handlers[j];
+
+ // Filter the functions by class
+ if ( all || namespace.test(handler.type) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handler;
+ event.data = handler.data;
+
+ var ret = handler.apply(this, arguments);
+
+ if( ret !== undefined ){
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if( event.isImmediatePropagationStopped() )
+ break;
+
+ }
+ }
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function(event) {
+ if ( event[expando] )
+ return event;
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ){
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target )
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType == 3 )
+ event.target = event.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ },
+
+ proxy: function( fn, proxy ){
+ proxy = proxy || function(){ return fn.apply(this, arguments); };
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: bindReady,
+ teardown: function() {}
+ }
+ },
+
+ specialAll: {
+ live: {
+ setup: function( selector, namespaces ){
+ jQuery.event.add( this, namespaces[0], liveHandler );
+ },
+ teardown: function( namespaces ){
+ if ( namespaces.length ) {
+ var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
+
+ jQuery.each( (jQuery.data(this, "events").live || {}), function(){
+ if ( name.test(this.type) )
+ remove++;
+ });
+
+ if ( remove < 1 )
+ jQuery.event.remove( this, namespaces[0], liveHandler );
+ }
+ }
+ }
+ }
+};
+
+jQuery.Event = function( src ){
+ // Allow instantiation without the 'new' keyword
+ if( !this.preventDefault )
+ return new jQuery.Event(src);
+
+ // Event object
+ if( src && src.type ){
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ }else
+ this.type = src;
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = now();
+
+ // Mark it as fixed
+ this[expando] = true;
+};
+
+function returnFalse(){
+ return false;
+}
+function returnTrue(){
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if( !e )
+ return;
+ // if preventDefault exists run it on the original event
+ if (e.preventDefault)
+ e.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ e.returnValue = false;
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if( !e )
+ return;
+ // if stopPropagation exists run it on the original event
+ if (e.stopPropagation)
+ e.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation:function(){
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+ // Traverse up the tree
+ while ( parent && parent != this )
+ try { parent = parent.parentNode; }
+ catch(e) { parent = this; }
+
+ if( parent != this ){
+ // set the correct event type
+ event.type = event.data;
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+};
+
+jQuery.each({
+ mouseover: 'mouseenter',
+ mouseout: 'mouseleave'
+}, function( orig, fix ){
+ jQuery.event.special[ fix ] = {
+ setup: function(){
+ jQuery.event.add( this, orig, withinElement, fix );
+ },
+ teardown: function(){
+ jQuery.event.remove( this, orig, withinElement );
+ }
+ };
+});
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ var one = jQuery.event.proxy( fn || data, function(event) {
+ jQuery(this).unbind(event, one);
+ return (fn || data).apply( this, arguments );
+ });
+ return this.each(function(){
+ jQuery.event.add( this, type, one, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if( this[0] ){
+ var event = jQuery.Event(type);
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments, i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while( i < args.length )
+ jQuery.event.proxy( fn, args[i++] );
+
+ return this.click( jQuery.event.proxy( fn, function(event) {
+ // Figure out which function to execute
+ this.lastToggle = ( this.lastToggle || 0 ) % i;
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ this.lastToggle++ ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function(fnOver, fnOut) {
+ return this.mouseenter(fnOver).mouseleave(fnOut);
+ },
+
+ ready: function(fn) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( fn );
+
+ return this;
+ },
+
+ live: function( type, fn ){
+ var proxy = jQuery.event.proxy( fn );
+ proxy.guid += this.selector + type;
+
+ jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
+
+ return this;
+ },
+
+ die: function( type, fn ){
+ jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
+ return this;
+ }
+});
+
+function liveHandler( event ){
+ var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
+ stop = true,
+ elems = [];
+
+ jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
+ if ( check.test(fn.type) ) {
+ var elem = jQuery(event.target).closest(fn.data)[0];
+ if ( elem )
+ elems.push({ elem: elem, fn: fn });
+ }
+ });
+
+ elems.sort(function(a,b) {
+ return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
+ });
+
+ jQuery.each(elems, function(){
+ if ( this.fn.call(this.elem, event, this.fn.data) === false )
+ return (stop = false);
+ });
+
+ return stop;
+}
+
+function liveConvert(type, selector){
+ return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
+}
+
+jQuery.extend({
+ isReady: false,
+ readyList: [],
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.call( document, jQuery );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+
+ // Trigger any bound ready events
+ jQuery(document).triggerHandler("ready");
+ }
+ }
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", function(){
+ document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
+ jQuery.ready();
+ }, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", function(){
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", arguments.callee );
+ jQuery.ready();
+ }
+ });
+
+ // If IE and not an iframe
+ // continually check to see if the document is ready
+ if ( document.documentElement.doScroll && window == window.top ) (function(){
+ if ( jQuery.isReady ) return;
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+ }
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
+ "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+ // Handle event binding
+ jQuery.fn[name] = function(fn){
+ return fn ? this.bind(name, fn) : this.trigger(name);
+ };
+});
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery( window ).bind( 'unload', function(){
+ for ( var id in jQuery.cache )
+ // Skip the window
+ if ( id != 1 && jQuery.cache[ id ].handle )
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+});
+(function(){
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+
+ div.style.display = "none";
+ div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType == 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that you can get all elements in an <object> element
+ // IE 7 always returns no results
+ objectAll: !!div.getElementsByTagName("object")[0]
+ .getElementsByTagName("*").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ opacity: a.style.opacity === "0.5",
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Will be defined later
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null
+ };
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e){}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function(){
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", arguments.callee);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function(){
+ var div = document.createElement("div");
+ div.style.width = div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ document.body.removeChild( div ).style.display = 'none';
+ });
+})();
+
+var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ tabindex: "tabIndex"
+};
+jQuery.fn.extend({
+ // Keep a copy of the old load
+ _load: jQuery.fn.load,
+
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" )
+ return this._load( url );
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if( typeof params === "object" ) {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ if( callback )
+ self.each( callback, [res.responseText, status, res] );
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password|search/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = now();
+
+jQuery.extend({
+
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ */
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr:function(){
+ return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ var jsonp, jsre = /=\?(&|$)/g, status, data,
+ type = s.type.toUpperCase();
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( type == "GET" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ if ( head )
+ head.removeChild( script );
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && type == "GET" ) {
+ var ts = now();
+ // try replacing _= if it is there
+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && type == "GET" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // Matches an absolute URL, and saves the domain
+ var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType == "script" && type == "GET" && parts
+ && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
+
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+ if (s.scriptCharset)
+ script.charset = s.scriptCharset;
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if( s.username )
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ else
+ xhr.open(type, s.url, s.async);
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xhr.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xhr.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e){}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xhr, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The request was aborted, clear the interval and decrement jQuery.active
+ if (xhr.readyState == 0) {
+ if (ival) {
+ // clear poll interval
+ clearInterval(ival);
+ ival = null;
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" ? "timeout" :
+ !jQuery.httpSuccess( xhr ) ? "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xhr.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xhr, status);
+
+ // Fire the complete handlers
+ complete();
+
+ if ( isTimeout )
+ xhr.abort();
+
+ // Stop memory leaks
+ if ( s.async )
+ xhr = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone )
+ onreadystatechange( "timeout" );
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xhr, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xhr, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xhr, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ handleError: function( s, xhr, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xhr, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xhr, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol == "file:" ||
+ ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ try {
+ var xhrRes = xhr.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( xhr, type, s ) {
+ var ct = xhr.getResponseHeader("content-type"),
+ xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // Allow a pre-filtering function to sanitize the response
+ // s != null is checked to keep backwards compatibility
+ if( s && s.dataFilter )
+ data = s.dataFilter( data, type );
+
+ // The filter can actually parse the response
+ if( typeof data === "string" ){
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = window["eval"]("(" + data + ")");
+ }
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [ ];
+
+ function add( key, value ){
+ s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
+ };
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( jQuery.isArray(a) || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ add( this.name, this.value );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( jQuery.isArray(a[j]) )
+ jQuery.each( a[j], function(){
+ add( j, this );
+ });
+ else
+ add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+var elemdisplay = {},
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+function genFx( type, num ){
+ var obj = {};
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
+ obj[ this ] = type;
+ });
+ return obj;
+}
+
+jQuery.fn.extend({
+ show: function(speed,callback){
+ if ( speed ) {
+ return this.animate( genFx("show", 3), speed, callback);
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ var old = jQuery.data(this[i], "olddisplay");
+
+ this[i].style.display = old || "";
+
+ if ( jQuery.css(this[i], "display") === "none" ) {
+ var tagName = this[i].tagName, display;
+
+ if ( elemdisplay[ tagName ] ) {
+ display = elemdisplay[ tagName ];
+ } else {
+ var elem = jQuery("<" + tagName + " />").appendTo("body");
+
+ display = elem.css("display");
+ if ( display === "none" )
+ display = "block";
+
+ elem.remove();
+
+ elemdisplay[ tagName ] = display;
+ }
+
+ jQuery.data(this[i], "olddisplay", display);
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
+ }
+
+ return this;
+ }
+ },
+
+ hide: function(speed,callback){
+ if ( speed ) {
+ return this.animate( genFx("hide", 3), speed, callback);
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ var old = jQuery.data(this[i], "olddisplay");
+ if ( !old && old !== "none" )
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ this[i].style.display = "none";
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ var bool = typeof fn === "boolean";
+
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle.apply( this, arguments ) :
+ fn == null || bool ?
+ this.each(function(){
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ }) :
+ this.animate(genFx("toggle", 3), fn, fn2);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ return this[ optall.queue === false ? "each" : "queue" ](function(){
+
+ var opt = jQuery.extend({}, optall), p,
+ hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return opt.complete.call(this);
+
+ if ( ( p == "height" || p == "width" ) && this.style ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function(clearQueue, gotoEnd){
+ var timers = jQuery.timers;
+
+ if (clearQueue)
+ this.queue([]);
+
+ this.each(function(){
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- )
+ if ( timers[i].elem == this ) {
+ if (gotoEnd)
+ // force the next step to be the last
+ timers[i](true);
+ timers.splice(i, 1);
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if (!gotoEnd)
+ this.dequeue();
+
+ return this;
+ }
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" }
+}, function( name, props ){
+ jQuery.fn[ name ] = function( speed, callback ){
+ return this.animate( props, speed, callback );
+ };
+});
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = typeof speed === "object" ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ if ( opt.queue !== false )
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.call( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.call( this.elem, this.now, this );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ var self = this;
+ function t(gotoEnd){
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length ) {
+ clearInterval( timerId );
+ timerId = undefined;
+ }
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(gotoEnd){
+ var t = now();
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ jQuery(this.elem).hide();
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.extend( jQuery.fx, {
+ speeds:{
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+ step: {
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ else
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+});
+if ( document.documentElement["getBoundingClientRect"] )
+ jQuery.fn.offset = function() {
+ if ( !this[0] ) return { top: 0, left: 0 };
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
+ var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
+ left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+ return { top: top, left: left };
+ };
+else
+ jQuery.fn.offset = function() {
+ if ( !this[0] ) return { top: 0, left: 0 };
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
+ jQuery.offset.initialized || jQuery.offset.initialize();
+
+ var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+ body = doc.body, defaultView = doc.defaultView,
+ prevComputedStyle = defaultView.getComputedStyle(elem, null),
+ top = elem.offsetTop, left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ computedStyle = defaultView.getComputedStyle(elem, null);
+ top -= elem.scrollTop, left -= elem.scrollLeft;
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop, left += elem.offsetLeft;
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+ }
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
+ top += body.offsetTop,
+ left += body.offsetLeft;
+
+ if ( prevComputedStyle.position === "fixed" )
+ top += Math.max(docElem.scrollTop, body.scrollTop),
+ left += Math.max(docElem.scrollLeft, body.scrollLeft);
+
+ return { top: top, left: left };
+ };
+
+jQuery.offset = {
+ initialize: function() {
+ if ( this.initialized ) return;
+ var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
+ html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
+
+ rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
+ for ( prop in rules ) container.style[prop] = rules[prop];
+
+ container.innerHTML = html;
+ body.insertBefore(container, body.firstChild);
+ innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ body.style.marginTop = '1px';
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
+ body.style.marginTop = bodyMarginTop;
+
+ body.removeChild(container);
+ this.initialized = true;
+ },
+
+ bodyOffset: function(body) {
+ jQuery.offset.initialized || jQuery.offset.initialize();
+ var top = body.offsetTop, left = body.offsetLeft;
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
+ top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0,
+ left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
+ return { top: top, left: left };
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ var left = 0, top = 0, results;
+
+ if ( this[0] ) {
+ // Get *real* offsetParent
+ var offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= num( this, 'marginTop' );
+ offset.left -= num( this, 'marginLeft' );
+
+ // Add offsetParent borders
+ parentOffset.top += num( offsetParent, 'borderTopWidth' );
+ parentOffset.left += num( offsetParent, 'borderLeftWidth' );
+
+ // Subtract the two offsets
+ results = {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ }
+
+ return results;
+ },
+
+ offsetParent: function() {
+ var offsetParent = this[0].offsetParent || document.body;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
+ offsetParent = offsetParent.offsetParent;
+ return jQuery(offsetParent);
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ['Left', 'Top'], function(i, name) {
+ var method = 'scroll' + name;
+
+ jQuery.fn[ method ] = function(val) {
+ if (!this[0]) return null;
+
+ return val !== undefined ?
+
+ // Set the scroll offset
+ this.each(function() {
+ this == window || this == document ?
+ window.scrollTo(
+ !i ? val : jQuery(window).scrollLeft(),
+ i ? val : jQuery(window).scrollTop()
+ ) :
+ this[ method ] = val;
+ }) :
+
+ // Return the scroll offset
+ this[0] == window || this[0] == document ?
+ self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
+ jQuery.boxModel && document.documentElement[ method ] ||
+ document.body[ method ] :
+ this[0][ method ];
+ };
+});
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function(i, name){
+
+ var tl = i ? "Left" : "Top", // top or left
+ br = i ? "Right" : "Bottom", // bottom or right
+ lower = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function(){
+ return this[0] ?
+ jQuery.css( this[0], lower, false, "padding" ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function(margin) {
+ return this[0] ?
+ jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
+ null;
+ };
+
+ var type = name.toLowerCase();
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ return this[0] == window ?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
+ document.body[ "client" + name ] :
+
+ // Get document width or height
+ this[0] == document ?
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ document.documentElement["client" + name],
+ document.body["scroll" + name], document.documentElement["scroll" + name],
+ document.body["offset" + name], document.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ (this.length ? jQuery.css( this[0], type ) : null) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});
+})();
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-1.js b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-1.js
new file mode 100755
index 0000000..9263574
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-1.js
@@ -0,0 +1,4376 @@
+/*!
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){
+
+var
+ // Will speed up references to window, and allows munging its name.
+ window = this,
+ // Will speed up references to undefined, and allows munging its name.
+ undefined,
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ jQuery = window.jQuery = window.$ = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ // Make sure that a selection was provided
+ selector = selector || document;
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this[0] = selector;
+ this.length = 1;
+ this.context = selector;
+ return this;
+ }
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ var match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] )
+ selector = jQuery.clean( [ match[1] ], context );
+
+ // HANDLE: $("#id")
+ else {
+ var elem = document.getElementById( match[3] );
+
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem && elem.id != match[3] )
+ return jQuery().find( selector );
+
+ // Otherwise, we inject the element directly into the jQuery object
+ var ret = jQuery( elem || [] );
+ ret.context = document;
+ ret.selector = selector;
+ return ret;
+ }
+
+ // HANDLE: $(expr, [context])
+ // (which is just equivalent to: $(content).find(expr)
+ } else
+ return jQuery( context ).find( selector );
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) )
+ return jQuery( document ).ready( selector );
+
+ // Make sure that old selector state is passed along
+ if ( selector.selector && selector.context ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return this.setArray(jQuery.isArray( selector ) ?
+ selector :
+ jQuery.makeArray(selector));
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.3.2",
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num === undefined ?
+
+ // Return a 'clean' array
+ Array.prototype.slice.call( this ) :
+
+ // Return just the object
+ this[ num ];
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" )
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ else if ( name )
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ Array.prototype.push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem && elem.jquery ? elem[0] : elem
+ , this );
+ },
+
+ attr: function( name, value, type ) {
+ var options = name;
+
+ // Look for the case where we're accessing a style value
+ if ( typeof name === "string" )
+ if ( value === undefined )
+ return this[0] && jQuery[ type || "attr" ]( this[0], name );
+
+ else {
+ options = {};
+ options[ name ] = value;
+ }
+
+ // Check to see if we're setting style values
+ return this.each(function(i){
+ // Set all the styles
+ for ( name in options )
+ jQuery.attr(
+ type ?
+ this.style :
+ this,
+ name, jQuery.prop( this, options[ name ], type, i, name )
+ );
+ });
+ },
+
+ css: function( key, value ) {
+ // ignore negative width and height values
+ if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
+ value = undefined;
+ return this.attr( key, value, "curCSS" );
+ },
+
+ text: function( text ) {
+ if ( typeof text !== "object" && text != null )
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+
+ var ret = "";
+
+ jQuery.each( text || this, function(){
+ jQuery.each( this.childNodes, function(){
+ if ( this.nodeType != 8 )
+ ret += this.nodeType != 1 ?
+ this.nodeValue :
+ jQuery.fn.text( [ this ] );
+ });
+ });
+
+ return ret;
+ },
+
+ wrapAll: function( html ) {
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).clone();
+
+ if ( this[0].parentNode )
+ wrap.insertBefore( this[0] );
+
+ wrap.map(function(){
+ var elem = this;
+
+ while ( elem.firstChild )
+ elem = elem.firstChild;
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ return this.each(function(){
+ jQuery( this ).contents().wrapAll( html );
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function(){
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function(elem){
+ if (this.nodeType == 1)
+ this.appendChild( elem );
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function(elem){
+ if (this.nodeType == 1)
+ this.insertBefore( elem, this.firstChild );
+ });
+ },
+
+ before: function() {
+ return this.domManip(arguments, false, function(elem){
+ this.parentNode.insertBefore( elem, this );
+ });
+ },
+
+ after: function() {
+ return this.domManip(arguments, false, function(elem){
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ },
+
+ end: function() {
+ return this.prevObject || jQuery( [] );
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: [].push,
+ sort: [].sort,
+ splice: [].splice,
+
+ find: function( selector ) {
+ if ( this.length === 1 ) {
+ var ret = this.pushStack( [], "find", selector );
+ ret.length = 0;
+ jQuery.find( selector, this[0], ret );
+ return ret;
+ } else {
+ return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
+ return jQuery.find( selector, elem );
+ })), "find", selector );
+ }
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function(){
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var html = this.outerHTML;
+ if ( !html ) {
+ var div = this.ownerDocument.createElement("div");
+ div.appendChild( this.cloneNode(true) );
+ html = div.innerHTML;
+ }
+
+ return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0];
+ } else
+ return this.cloneNode(true);
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true ) {
+ var orig = this.find("*").andSelf(), i = 0;
+
+ ret.find("*").andSelf().each(function(){
+ if ( this.nodeName !== orig[i].nodeName )
+ return;
+
+ var events = jQuery.data( orig[i], "events" );
+
+ for ( var type in events ) {
+ for ( var handler in events[ type ] ) {
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ }
+ }
+
+ i++;
+ });
+ }
+
+ // Return the cloned set
+ return ret;
+ },
+
+ filter: function( selector ) {
+ return this.pushStack(
+ jQuery.isFunction( selector ) &&
+ jQuery.grep(this, function(elem, i){
+ return selector.call( elem, i );
+ }) ||
+
+ jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
+ return elem.nodeType === 1;
+ }) ), "filter", selector );
+ },
+
+ closest: function( selector ) {
+ var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
+ closer = 0;
+
+ return this.map(function(){
+ var cur = this;
+ while ( cur && cur.ownerDocument ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
+ jQuery.data(cur, "closest", closer);
+ return cur;
+ }
+ cur = cur.parentNode;
+ closer++;
+ }
+ });
+ },
+
+ not: function( selector ) {
+ if ( typeof selector === "string" )
+ // test special case where just one selector is passed in
+ if ( isSimple.test( selector ) )
+ return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
+ else
+ selector = jQuery.multiFilter( selector, this );
+
+ var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
+ return this.filter(function() {
+ return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
+ });
+ },
+
+ add: function( selector ) {
+ return this.pushStack( jQuery.unique( jQuery.merge(
+ this.get(),
+ typeof selector === "string" ?
+ jQuery( selector ) :
+ jQuery.makeArray( selector )
+ )));
+ },
+
+ is: function( selector ) {
+ return !!selector && jQuery.multiFilter( selector, this ).length > 0;
+ },
+
+ hasClass: function( selector ) {
+ return !!selector && this.is( "." + selector );
+ },
+
+ val: function( value ) {
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if( jQuery.nodeName( elem, 'option' ) )
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type == "select-one";
+
+ // Nothing was selected
+ if ( index < 0 )
+ return null;
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one )
+ return value;
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(/\r/g, "");
+
+ }
+
+ return undefined;
+ }
+
+ if ( typeof value === "number" )
+ value += '';
+
+ return this.each(function(){
+ if ( this.nodeType != 1 )
+ return;
+
+ if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
+ this.checked = (jQuery.inArray(this.value, value) >= 0 ||
+ jQuery.inArray(this.name, value) >= 0);
+
+ else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(value);
+
+ jQuery( "option", this ).each(function(){
+ this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
+ jQuery.inArray( this.text, values ) >= 0);
+ });
+
+ if ( !values.length )
+ this.selectedIndex = -1;
+
+ } else
+ this.value = value;
+ });
+ },
+
+ html: function( value ) {
+ return value === undefined ?
+ (this[0] ?
+ this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") :
+ null) :
+ this.empty().append( value );
+ },
+
+ replaceWith: function( value ) {
+ return this.after( value ).remove();
+ },
+
+ eq: function( i ) {
+ return this.slice( i, +i + 1 );
+ },
+
+ slice: function() {
+ return this.pushStack( Array.prototype.slice.apply( this, arguments ),
+ "slice", Array.prototype.slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function(elem, i){
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ },
+
+ domManip: function( args, table, callback ) {
+ if ( this[0] ) {
+ var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
+ scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
+ first = fragment.firstChild;
+
+ if ( first )
+ for ( var i = 0, l = this.length; i < l; i++ )
+ callback.call( root(this[i], first), this.length > 1 || i > 0 ?
+ fragment.cloneNode(true) : fragment );
+
+ if ( scripts )
+ jQuery.each( scripts, evalScript );
+ }
+
+ return this;
+
+ function root( elem, cur ) {
+ return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+ }
+ }
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+function evalScript( i, elem ) {
+ if ( elem.src )
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+
+ else
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+
+ if ( elem.parentNode )
+ elem.parentNode.removeChild( elem );
+}
+
+function now(){
+ return +new Date;
+}
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) )
+ target = {};
+
+ // extend jQuery itself if only one argument is passed
+ if ( length == i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ )
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null )
+ // Extend the base object
+ for ( var name in options ) {
+ var src = target[ name ], copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy )
+ continue;
+
+ // Recurse if we're merging object values
+ if ( deep && copy && typeof copy === "object" && !copy.nodeType )
+ target[ name ] = jQuery.extend( deep,
+ // Never move original objects, clone them
+ src || ( copy.length != null ? [ ] : { } )
+ , copy );
+
+ // Don't bring in undefined values
+ else if ( copy !== undefined )
+ target[ name ] = copy;
+
+ }
+
+ // Return the modified object
+ return target;
+};
+
+// exclude the following css properties to add px
+var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+ // cache defaultView
+ defaultView = document.defaultView || {},
+ toString = Object.prototype.toString;
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep )
+ window.jQuery = _jQuery;
+
+ return jQuery;
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return toString.call(obj) === "[object Function]";
+ },
+
+ isArray: function( obj ) {
+ return toString.call(obj) === "[object Array]";
+ },
+
+ // check if an element is in a (or is an) XML document
+ isXMLDoc: function( elem ) {
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument );
+ },
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ if ( data && /\S/.test(data) ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+ if ( jQuery.support.scriptEval )
+ script.appendChild( document.createTextNode( data ) );
+ else
+ script.text = data;
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0, length = object.length;
+
+ if ( args ) {
+ if ( length === undefined ) {
+ for ( name in object )
+ if ( callback.apply( object[ name ], args ) === false )
+ break;
+ } else
+ for ( ; i < length; )
+ if ( callback.apply( object[ i++ ], args ) === false )
+ break;
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( length === undefined ) {
+ for ( name in object )
+ if ( callback.call( object[ name ], name, object[ name ] ) === false )
+ break;
+ } else
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
+ }
+
+ return object;
+ },
+
+ prop: function( elem, value, type, i, name ) {
+ // Handle executable functions
+ if ( jQuery.isFunction( value ) )
+ value = value.call( elem, i );
+
+ // Handle passing in a number to a CSS property
+ return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
+ value + "px" :
+ value;
+ },
+
+ className: {
+ // internal only, use addClass("class")
+ add: function( elem, classNames ) {
+ jQuery.each((classNames || "").split(/\s+/), function(i, className){
+ if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
+ elem.className += (elem.className ? " " : "") + className;
+ });
+ },
+
+ // internal only, use removeClass("class")
+ remove: function( elem, classNames ) {
+ if (elem.nodeType == 1)
+ elem.className = classNames !== undefined ?
+ jQuery.grep(elem.className.split(/\s+/), function(className){
+ return !jQuery.className.has( classNames, className );
+ }).join(" ") :
+ "";
+ },
+
+ // internal only, use hasClass("class")
+ has: function( elem, className ) {
+ return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options )
+ elem.style[ name ] = old[ name ];
+ },
+
+ css: function( elem, name, force, extra ) {
+ if ( name == "width" || name == "height" ) {
+ var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
+
+ function getWH() {
+ val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" )
+ return;
+
+ jQuery.each( which, function() {
+ if ( !extra )
+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ if ( extra === "margin" )
+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+ else
+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ });
+ }
+
+ if ( elem.offsetWidth !== 0 )
+ getWH();
+ else
+ jQuery.swap( elem, props, getWH );
+
+ return Math.max(0, Math.round(val));
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret, style = elem.style;
+
+ // We need to handle opacity special in IE
+ if ( name == "opacity" && !jQuery.support.opacity ) {
+ ret = jQuery.attr( style, "opacity" );
+
+ return ret == "" ?
+ "1" :
+ ret;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( name.match( /float/i ) )
+ name = styleFloat;
+
+ if ( !force && style && style[ name ] )
+ ret = style[ name ];
+
+ else if ( defaultView.getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( name.match( /float/i ) )
+ name = "float";
+
+ name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
+
+ var computedStyle = defaultView.getComputedStyle( elem, null );
+
+ if ( computedStyle )
+ ret = computedStyle.getPropertyValue( name );
+
+ // We should always get a number back from opacity
+ if ( name == "opacity" && ret == "" )
+ ret = "1";
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(/\-(\w)/g, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
+ // Remember the original values
+ var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = ret || 0;
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret;
+ },
+
+ clean: function( elems, context, fragment ) {
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" )
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
+ var match = /^<(\w+)\s*\/?>$/.exec(elems[0]);
+ if ( match )
+ return [ context.createElement( match[1] ) ];
+ }
+
+ var ret = [], scripts = [], div = context.createElement("div");
+
+ jQuery.each(elems, function(i, elem){
+ if ( typeof elem === "number" )
+ elem += '';
+
+ if ( !elem )
+ return;
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
+ return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
+ all :
+ front + "></" + tag + ">";
+ });
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase();
+
+ var wrap =
+ // option or optgroup
+ !tags.indexOf("<opt") &&
+ [ 1, "<select multiple='multiple'>", "</select>" ] ||
+
+ !tags.indexOf("<leg") &&
+ [ 1, "<fieldset>", "</fieldset>" ] ||
+
+ tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
+ [ 1, "<table>", "</table>" ] ||
+
+ !tags.indexOf("<tr") &&
+ [ 2, "<table><tbody>", "</tbody></table>" ] ||
+
+ // <thead> matched above
+ (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
+ [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
+
+ !tags.indexOf("<col") &&
+ [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
+
+ // IE can't serialize <link> and <script> tags normally
+ !jQuery.support.htmlSerialize &&
+ [ 1, "div<div>", "</div>" ] ||
+
+ [ 0, "", "" ];
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( wrap[0]-- )
+ div = div.lastChild;
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = /<tbody/i.test(elem),
+ tbody = !tags.indexOf("<table") && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] == "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j )
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && /^\s/.test( elem ) )
+ div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.nodeType )
+ ret.push( elem );
+ else
+ ret = jQuery.merge( ret, elem );
+
+ });
+
+ if ( fragment ) {
+ for ( var i = 0; ret[i]; i++ ) {
+ if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+ } else {
+ if ( ret[i].nodeType === 1 )
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ fragment.appendChild( ret[i] );
+ }
+ }
+
+ return scripts;
+ }
+
+ return ret;
+ },
+
+ attr: function( elem, name, value ) {
+ // don't set attributes on text and comment nodes
+ if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
+ return undefined;
+
+ var notxml = !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ // IE elem.getAttribute passes even for style
+ if ( elem.tagName ) {
+
+ // These attributes require special treatment
+ var special = /href|src|style/.test( name );
+
+ // Safari mis-reports the default selected property of a hidden option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name == "selected" && elem.parentNode )
+ elem.parentNode.selectedIndex;
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ){
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
+ throw "type property can't be changed";
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
+ return elem.getAttributeNode( name ).nodeValue;
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ if ( name == "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+ return attributeNode && attributeNode.specified
+ ? attributeNode.value
+ : elem.nodeName.match(/(button|input|object|select|textarea)/i)
+ ? 0
+ : elem.nodeName.match(/^(a|area)$/i) && elem.href
+ ? 0
+ : undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name == "style" )
+ return jQuery.attr( elem.style, "cssText", value );
+
+ if ( set )
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special
+ // Some attributes require a special call on IE
+ ? elem.getAttribute( name, 2 )
+ : elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name == "opacity" ) {
+ if ( set ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ elem.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
+ (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
+ }
+
+ return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
+ "";
+ }
+
+ name = name.replace(/-([a-z])/ig, function(all, letter){
+ return letter.toUpperCase();
+ });
+
+ if ( set )
+ elem[ name ] = value;
+
+ return elem[ name ];
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( /^\s+|\s+$/g, "" );
+ },
+
+ makeArray: function( array ) {
+ var ret = [];
+
+ if( array != null ){
+ var i = array.length;
+ // The window, strings (and functions) also have 'length'
+ if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
+ ret[0] = array;
+ else
+ while( i )
+ ret[--i] = array[i];
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ for ( var i = 0, length = array.length; i < length; i++ )
+ // Use === because on IE, window == document
+ if ( array[ i ] === elem )
+ return i;
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ // We have to loop this way because IE & Opera overwrite the length
+ // expando of getElementsByTagName
+ var i = 0, elem, pos = first.length;
+ // Also, we need to make sure that the correct elements are being returned
+ // (IE returns comment nodes in a '*' query)
+ if ( !jQuery.support.getAll ) {
+ while ( (elem = second[ i++ ]) != null )
+ if ( elem.nodeType != 8 )
+ first[ pos++ ] = elem;
+
+ } else
+ while ( (elem = second[ i++ ]) != null )
+ first[ pos++ ] = elem;
+
+ return first;
+ },
+
+ unique: function( array ) {
+ var ret = [], done = {};
+
+ try {
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ var id = jQuery.data( array[ i ] );
+
+ if ( !done[ id ] ) {
+ done[ id ] = true;
+ ret.push( array[ i ] );
+ }
+ }
+
+ } catch( e ) {
+ ret = array;
+ }
+
+ return ret;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ )
+ if ( !inv != !callback( elems[ i ], i ) )
+ ret.push( elems[ i ] );
+
+ return ret;
+ },
+
+ map: function( elems, callback ) {
+ var ret = [];
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ var value = callback( elems[ i ], i );
+
+ if ( value != null )
+ ret[ ret.length ] = value;
+ }
+
+ return ret.concat.apply( [], ret );
+ }
+});
+
+// Use of jQuery.browser is deprecated.
+// It's included for backwards compatibility and plugins,
+// although they should work to migrate away.
+
+var userAgent = navigator.userAgent.toLowerCase();
+
+// Figure out what browser is being used
+jQuery.browser = {
+ version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
+ safari: /webkit/.test( userAgent ),
+ opera: /opera/.test( userAgent ),
+ msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
+ mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
+};
+
+jQuery.each({
+ parent: function(elem){return elem.parentNode;},
+ parents: function(elem){return jQuery.dir(elem,"parentNode");},
+ next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
+ prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
+ nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
+ prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
+ siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
+ children: function(elem){return jQuery.sibling(elem.firstChild);},
+ contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
+}, function(name, fn){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = jQuery.map( this, fn );
+
+ if ( selector && typeof selector == "string" )
+ ret = jQuery.multiFilter( selector, ret );
+
+ return this.pushStack( jQuery.unique( ret ), name, selector );
+ };
+});
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function(name, original){
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, selector );
+ };
+});
+
+jQuery.each({
+ removeAttr: function( name ) {
+ jQuery.attr( this, name, "" );
+ if (this.nodeType == 1)
+ this.removeAttribute( name );
+ },
+
+ addClass: function( classNames ) {
+ jQuery.className.add( this, classNames );
+ },
+
+ removeClass: function( classNames ) {
+ jQuery.className.remove( this, classNames );
+ },
+
+ toggleClass: function( classNames, state ) {
+ if( typeof state !== "boolean" )
+ state = !jQuery.className.has( this, classNames );
+ jQuery.className[ state ? "add" : "remove" ]( this, classNames );
+ },
+
+ remove: function( selector ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
+ // Prevent memory leaks
+ jQuery( "*", this ).add([this]).each(function(){
+ jQuery.event.remove(this);
+ jQuery.removeData(this);
+ });
+ if (this.parentNode)
+ this.parentNode.removeChild( this );
+ }
+ },
+
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ jQuery(this).children().remove();
+
+ // Remove any remaining nodes
+ while ( this.firstChild )
+ this.removeChild( this.firstChild );
+ }
+}, function(name, fn){
+ jQuery.fn[ name ] = function(){
+ return this.each( fn, arguments );
+ };
+});
+
+// Helper function used by the dimensions and offset modules
+function num(elem, prop) {
+ return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
+}
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+
+jQuery.extend({
+ cache: {},
+
+ data: function( elem, name, data ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // Compute a unique ID for the element
+ if ( !id )
+ id = elem[ expando ] = ++uuid;
+
+ // Only generate the data cache if we're
+ // trying to access or manipulate it
+ if ( name && !jQuery.cache[ id ] )
+ jQuery.cache[ id ] = {};
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined )
+ jQuery.cache[ id ][ name ] = data;
+
+ // Return the named cache data, or the ID for the element
+ return name ?
+ jQuery.cache[ id ][ name ] :
+ id;
+ },
+
+ removeData: function( elem, name ) {
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( jQuery.cache[ id ] ) {
+ // Remove the section of cache data
+ delete jQuery.cache[ id ][ name ];
+
+ // If we've removed all the data, remove the element's cache
+ name = "";
+
+ for ( name in jQuery.cache[ id ] )
+ break;
+
+ if ( !name )
+ jQuery.removeData( elem );
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch(e){
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute )
+ elem.removeAttribute( expando );
+ }
+
+ // Completely remove the data cache
+ delete jQuery.cache[ id ];
+ }
+ },
+ queue: function( elem, type, data ) {
+ if ( elem ){
+
+ type = (type || "fx") + "queue";
+
+ var q = jQuery.data( elem, type );
+
+ if ( !q || jQuery.isArray(data) )
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+ else if( data )
+ q.push( data );
+
+ }
+ return q;
+ },
+
+ dequeue: function( elem, type ){
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift();
+
+ if( !type || type === "fx" )
+ fn = queue[0];
+
+ if( fn !== undefined )
+ fn.call(elem);
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ){
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length )
+ data = jQuery.data( this[0], key );
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
+ jQuery.data( this, key, value );
+ });
+ },
+
+ removeData: function( key ){
+ return this.each(function(){
+ jQuery.removeData( this, key );
+ });
+ },
+ queue: function(type, data){
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined )
+ return jQuery.queue( this[0], type );
+
+ return this.each(function(){
+ var queue = jQuery.queue( this, type, data );
+
+ if( type == "fx" && queue.length == 1 )
+ queue[0].call(this);
+ });
+ },
+ dequeue: function(type){
+ return this.each(function(){
+ jQuery.dequeue( this, type );
+ });
+ }
+});/*!
+ * Sizzle CSS Selector Engine - v0.9.3
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,
+ done = 0,
+ toString = Object.prototype.toString;
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 )
+ return [];
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true;
+
+ // Reset the position of the chunker regexp (start from head)
+ chunker.lastIndex = 0;
+
+ while ( (m = chunker.exec(selector)) !== null ) {
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = RegExp.rightContext;
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] )
+ selector += parts.shift();
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
+ set = Sizzle.filter( ret.expr, ret.set );
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, isXML(context) );
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, context, results, seed );
+
+ if ( sortOrder ) {
+ hasDuplicate = false;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.match[ type ].exec( expr )) ) {
+ var left = RegExp.leftContext;
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+ var filter = Expr.filter[ type ], found, item;
+ anyFound = false;
+
+ if ( curLoop == result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr == old ) {
+ if ( anyFound == null ) {
+ throw "Syntax error, unrecognized expression: " + expr;
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+ },
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag && !isXML ) {
+ part = part.toUpperCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part, isXML){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = isXML ? part : part.toUpperCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( !part.match(/\W/) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !part.match(/\W/) ) {
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context, isXML){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
+ if ( !inplace )
+ result.push( elem );
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ for ( var i = 0; curLoop[i] === false; i++ ){}
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+ },
+ CHILD: function(match){
+ if ( match[1] == "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( match[3].match(chunker).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 == i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 == i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while (node = node.previousSibling) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ if ( type == 'first') return true;
+ node = elem;
+ case 'last':
+ while (node = node.nextSibling) {
+ if ( node.nodeType === 1 ) return false;
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first == 1 && last == 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first == 0 ) {
+ return diff == 0;
+ } else {
+ return ( diff % first == 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value != check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes );
+
+// Provide a fallback method if it does not work
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.selectNode(a);
+ aRange.collapse(true);
+ bRange.selectNode(b);
+ bRange.collapse(true);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("form"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<input name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( !!document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+})();
+
+if ( document.querySelectorAll ) (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ Sizzle.find = oldSizzle.find;
+ Sizzle.filter = oldSizzle.filter;
+ Sizzle.selectors = oldSizzle.selectors;
+ Sizzle.matches = oldSizzle.matches;
+})();
+
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
+ var div = document.createElement("div");
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ if ( div.getElementsByClassName("e").length === 0 )
+ return;
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 )
+ return;
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ var sibDir = dir == "previousSibling" && !isXML;
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ if ( sibDir && elem.nodeType === 1 ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+ !!elem.ownerDocument && isXML( elem.ownerDocument );
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.filter = Sizzle.filter;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+
+Sizzle.selectors.filters.hidden = function(elem){
+ return elem.offsetWidth === 0 || elem.offsetHeight === 0;
+};
+
+Sizzle.selectors.filters.visible = function(elem){
+ return elem.offsetWidth > 0 || elem.offsetHeight > 0;
+};
+
+Sizzle.selectors.filters.animated = function(elem){
+ return jQuery.grep(jQuery.timers, function(fn){
+ return elem === fn.elem;
+ }).length;
+};
+
+jQuery.multiFilter = function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return Sizzle.matches(expr, elems);
+};
+
+jQuery.dir = function( elem, dir ){
+ var matched = [], cur = elem[dir];
+ while ( cur && cur != document ) {
+ if ( cur.nodeType == 1 )
+ matched.push( cur );
+ cur = cur[dir];
+ }
+ return matched;
+};
+
+jQuery.nth = function(cur, result, dir, elem){
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] )
+ if ( cur.nodeType == 1 && ++num == result )
+ break;
+
+ return cur;
+};
+
+jQuery.sibling = function(n, elem){
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType == 1 && n != elem )
+ r.push( n );
+ }
+
+ return r;
+};
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function(elem, types, handler, data) {
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && elem != window )
+ elem = window;
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid )
+ handler.guid = this.guid++;
+
+ // if data is passed, bind to handler
+ if ( data !== undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = this.proxy( fn );
+
+ // Store data in unique handler
+ handler.data = data;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
+ handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply(arguments.callee.elem, arguments) :
+ undefined;
+ });
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type) {
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ handler.type = namespaces.slice().sort().join(".");
+
+ // Get the current list of functions bound to this event
+ var handlers = events[type];
+
+ if ( jQuery.event.specialAll[type] )
+ jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
+
+ // Init the event handler queue
+ if (!handlers) {
+ handlers = events[type] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) {
+ // Bind the global event handler to the element
+ if (elem.addEventListener)
+ elem.addEventListener(type, handle, false);
+ else if (elem.attachEvent)
+ elem.attachEvent("on" + type, handle);
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[handler.guid] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[type] = true;
+ });
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ guid: 1,
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function(elem, types, handler) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType == 3 || elem.nodeType == 8 )
+ return;
+
+ var events = jQuery.data(elem, "events"), ret, index;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types === undefined || (typeof types === "string" && types.charAt(0) == ".") )
+ for ( var type in events )
+ this.remove( elem, type + (types || "") );
+ else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events seperated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ jQuery.each(types.split(/\s+/), function(index, type){
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
+
+ if ( events[type] ) {
+ // remove the given handler for the given type
+ if ( handler )
+ delete events[type][handler.guid];
+
+ // remove all handlers for the given type
+ else
+ for ( var handle in events[type] )
+ // Handle the removal of namespaced events
+ if ( namespace.test(events[type][handle].type) )
+ delete events[type][handle];
+
+ if ( jQuery.event.specialAll[type] )
+ jQuery.event.specialAll[type].teardown.call(elem, namespaces);
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[type] ) break;
+ if ( !ret ) {
+ if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) {
+ if (elem.removeEventListener)
+ elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
+ else if (elem.detachEvent)
+ elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
+ }
+ ret = null;
+ delete events[type];
+ }
+ }
+ });
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) break;
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) handle.elem = null;
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem, bubbling ) {
+ // Event object or event type
+ var type = event.type || event;
+
+ if( !bubbling ){
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery.each( jQuery.cache, function(){
+ if ( this.events && this.events[type] )
+ jQuery.event.trigger( event, data, this.handle.elem );
+ });
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType == 3 || elem.nodeType == 8 )
+ return undefined;
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray(data);
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data(elem, "handle");
+ if ( handle )
+ handle.apply( elem, data );
+
+ // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
+ if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+ event.result = false;
+
+ // Trigger the native events (except for clicks on links)
+ if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+ this.triggered = true;
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
+ }
+
+ this.triggered = false;
+
+ if ( !event.isPropagationStopped() ) {
+ var parent = elem.parentNode || elem.ownerDocument;
+ if ( parent )
+ jQuery.event.trigger(event, data, parent, true);
+ }
+ },
+
+ handle: function(event) {
+ // returned undefined or false
+ var all, handlers;
+
+ event = arguments[0] = jQuery.event.fix( event || window.event );
+ event.currentTarget = this;
+
+ // Namespaced event handlers
+ var namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+
+ // Cache this now, all = true means, any handler
+ all = !namespaces.length && !event.exclusive;
+
+ var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)");
+
+ handlers = ( jQuery.data(this, "events") || {} )[event.type];
+
+ for ( var j in handlers ) {
+ var handler = handlers[j];
+
+ // Filter the functions by class
+ if ( all || namespace.test(handler.type) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handler;
+ event.data = handler.data;
+
+ var ret = handler.apply(this, arguments);
+
+ if( ret !== undefined ){
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if( event.isImmediatePropagationStopped() )
+ break;
+
+ }
+ }
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function(event) {
+ if ( event[expando] )
+ return event;
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ){
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target )
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType == 3 )
+ event.target = event.target.parentNode;
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement )
+ event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
+ event.which = event.charCode || event.keyCode;
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey )
+ event.metaKey = event.ctrlKey;
+
+ // Add which for click: 1 == left; 2 == middle; 3 == right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button )
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+
+ return event;
+ },
+
+ proxy: function( fn, proxy ){
+ proxy = proxy || function(){ return fn.apply(this, arguments); };
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: bindReady,
+ teardown: function() {}
+ }
+ },
+
+ specialAll: {
+ live: {
+ setup: function( selector, namespaces ){
+ jQuery.event.add( this, namespaces[0], liveHandler );
+ },
+ teardown: function( namespaces ){
+ if ( namespaces.length ) {
+ var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
+
+ jQuery.each( (jQuery.data(this, "events").live || {}), function(){
+ if ( name.test(this.type) )
+ remove++;
+ });
+
+ if ( remove < 1 )
+ jQuery.event.remove( this, namespaces[0], liveHandler );
+ }
+ }
+ }
+ }
+};
+
+jQuery.Event = function( src ){
+ // Allow instantiation without the 'new' keyword
+ if( !this.preventDefault )
+ return new jQuery.Event(src);
+
+ // Event object
+ if( src && src.type ){
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ }else
+ this.type = src;
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = now();
+
+ // Mark it as fixed
+ this[expando] = true;
+};
+
+function returnFalse(){
+ return false;
+}
+function returnTrue(){
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if( !e )
+ return;
+ // if preventDefault exists run it on the original event
+ if (e.preventDefault)
+ e.preventDefault();
+ // otherwise set the returnValue property of the original event to false (IE)
+ e.returnValue = false;
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if( !e )
+ return;
+ // if stopPropagation exists run it on the original event
+ if (e.stopPropagation)
+ e.stopPropagation();
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation:function(){
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function(event) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+ // Traverse up the tree
+ while ( parent && parent != this )
+ try { parent = parent.parentNode; }
+ catch(e) { parent = this; }
+
+ if( parent != this ){
+ // set the correct event type
+ event.type = event.data;
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+};
+
+jQuery.each({
+ mouseover: 'mouseenter',
+ mouseout: 'mouseleave'
+}, function( orig, fix ){
+ jQuery.event.special[ fix ] = {
+ setup: function(){
+ jQuery.event.add( this, orig, withinElement, fix );
+ },
+ teardown: function(){
+ jQuery.event.remove( this, orig, withinElement );
+ }
+ };
+});
+
+jQuery.fn.extend({
+ bind: function( type, data, fn ) {
+ return type == "unload" ? this.one(type, data, fn) : this.each(function(){
+ jQuery.event.add( this, type, fn || data, fn && data );
+ });
+ },
+
+ one: function( type, data, fn ) {
+ var one = jQuery.event.proxy( fn || data, function(event) {
+ jQuery(this).unbind(event, one);
+ return (fn || data).apply( this, arguments );
+ });
+ return this.each(function(){
+ jQuery.event.add( this, type, one, fn && data);
+ });
+ },
+
+ unbind: function( type, fn ) {
+ return this.each(function(){
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function(){
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if( this[0] ){
+ var event = jQuery.Event(type);
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments, i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while( i < args.length )
+ jQuery.event.proxy( fn, args[i++] );
+
+ return this.click( jQuery.event.proxy( fn, function(event) {
+ // Figure out which function to execute
+ this.lastToggle = ( this.lastToggle || 0 ) % i;
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ this.lastToggle++ ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function(fnOver, fnOut) {
+ return this.mouseenter(fnOver).mouseleave(fnOut);
+ },
+
+ ready: function(fn) {
+ // Attach the listeners
+ bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady )
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ else
+ // Add the function to the wait list
+ jQuery.readyList.push( fn );
+
+ return this;
+ },
+
+ live: function( type, fn ){
+ var proxy = jQuery.event.proxy( fn );
+ proxy.guid += this.selector + type;
+
+ jQuery(document).bind( liveConvert(type, this.selector), this.selector, proxy );
+
+ return this;
+ },
+
+ die: function( type, fn ){
+ jQuery(document).unbind( liveConvert(type, this.selector), fn ? { guid: fn.guid + this.selector + type } : null );
+ return this;
+ }
+});
+
+function liveHandler( event ){
+ var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"),
+ stop = true,
+ elems = [];
+
+ jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
+ if ( check.test(fn.type) ) {
+ var elem = jQuery(event.target).closest(fn.data)[0];
+ if ( elem )
+ elems.push({ elem: elem, fn: fn });
+ }
+ });
+
+ elems.sort(function(a,b) {
+ return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
+ });
+
+ jQuery.each(elems, function(){
+ if ( this.fn.call(this.elem, event, this.fn.data) === false )
+ return (stop = false);
+ });
+
+ return stop;
+}
+
+function liveConvert(type, selector){
+ return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
+}
+
+jQuery.extend({
+ isReady: false,
+ readyList: [],
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( jQuery.readyList ) {
+ // Execute all of them
+ jQuery.each( jQuery.readyList, function(){
+ this.call( document, jQuery );
+ });
+
+ // Reset the list of functions
+ jQuery.readyList = null;
+ }
+
+ // Trigger any bound ready events
+ jQuery(document).triggerHandler("ready");
+ }
+ }
+});
+
+var readyBound = false;
+
+function bindReady(){
+ if ( readyBound ) return;
+ readyBound = true;
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", function(){
+ document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
+ jQuery.ready();
+ }, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", function(){
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", arguments.callee );
+ jQuery.ready();
+ }
+ });
+
+ // If IE and not an iframe
+ // continually check to see if the document is ready
+ if ( document.documentElement.doScroll && window == window.top ) (function(){
+ if ( jQuery.isReady ) return;
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( arguments.callee, 0 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+ })();
+ }
+
+ // A fallback to window.onload, that will always work
+ jQuery.event.add( window, "load", jQuery.ready );
+}
+
+jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
+ "mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave," +
+ "change,select,submit,keydown,keypress,keyup,error").split(","), function(i, name){
+
+ // Handle event binding
+ jQuery.fn[name] = function(fn){
+ return fn ? this.bind(name, fn) : this.trigger(name);
+ };
+});
+
+// Prevent memory leaks in IE
+// And prevent errors on refresh with events like mouseover in other browsers
+// Window isn't included so as not to unbind existing unload events
+jQuery( window ).bind( 'unload', function(){
+ for ( var id in jQuery.cache )
+ // Skip the window
+ if ( id != 1 && jQuery.cache[ id ].handle )
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+});
+(function(){
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+
+ div.style.display = "none";
+ div.innerHTML = ' <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType == 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that you can get all elements in an <object> element
+ // IE 7 always returns no results
+ objectAll: !!div.getElementsByTagName("object")[0]
+ .getElementsByTagName("*").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ opacity: a.style.opacity === "0.5",
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Will be defined later
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null
+ };
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e){}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function(){
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", arguments.callee);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function(){
+ var div = document.createElement("div");
+ div.style.width = div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ document.body.removeChild( div ).style.display = 'none';
+ });
+})();
+
+var styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat";
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ "float": styleFloat,
+ cssFloat: styleFloat,
+ styleFloat: styleFloat,
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ tabindex: "tabIndex"
+};
+jQuery.fn.extend({
+ // Keep a copy of the old load
+ _load: jQuery.fn.load,
+
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" )
+ return this._load( url );
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params )
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if( typeof params === "object" ) {
+ params = jQuery.param( params );
+ type = "POST";
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function(res, status){
+ // If successful, inject the HTML into all the matched elements
+ if ( status == "success" || status == "notmodified" )
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div/>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+
+ if( callback )
+ self.each( callback, [res.responseText, status, res] );
+ }
+ });
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function(){
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ (this.checked || /select|textarea/i.test(this.nodeName) ||
+ /text|hidden|password|search/i.test(this.type));
+ })
+ .map(function(i, elem){
+ var val = jQuery(this).val();
+ return val == null ? null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function(val, i){
+ return {name: elem.name, value: val};
+ }) :
+ {name: elem.name, value: val};
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
+ jQuery.fn[o] = function(f){
+ return this.bind(o, f);
+ };
+});
+
+var jsc = now();
+
+jQuery.extend({
+
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was ommited
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ if ( jQuery.isFunction( data ) ) {
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ */
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr:function(){
+ return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+
+ ajax: function( s ) {
+ // Extend the settings, but re-extend 's' so that it can be
+ // checked again later (in the test suite, specifically)
+ s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));
+
+ var jsonp, jsre = /=\?(&|$)/g, status, data,
+ type = s.type.toUpperCase();
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" )
+ s.data = jQuery.param(s.data);
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType == "jsonp" ) {
+ if ( type == "GET" ) {
+ if ( !s.url.match(jsre) )
+ s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ } else if ( !s.data || !s.data.match(jsre) )
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
+ jsonp = "jsonp" + jsc++;
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data )
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = function(tmp){
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+ try{ delete window[ jsonp ]; } catch(e){}
+ if ( head )
+ head.removeChild( script );
+ };
+ }
+
+ if ( s.dataType == "script" && s.cache == null )
+ s.cache = false;
+
+ if ( s.cache === false && type == "GET" ) {
+ var ts = now();
+ // try replacing _= if it is there
+ var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && type == "GET" ) {
+ s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;
+
+ // IE likes to send both get and post data, prevent this
+ s.data = null;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ )
+ jQuery.event.trigger( "ajaxStart" );
+
+ // Matches an absolute URL, and saves the domain
+ var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec( s.url );
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType == "script" && type == "GET" && parts
+ && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host )){
+
+ var head = document.getElementsByTagName("head")[0];
+ var script = document.createElement("script");
+ script.src = s.url;
+ if (s.scriptCharset)
+ script.charset = s.scriptCharset;
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState ||
+ this.readyState == "loaded" || this.readyState == "complete") ) {
+ done = true;
+ success();
+ complete();
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+ head.removeChild( script );
+ }
+ };
+ }
+
+ head.appendChild(script);
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if( s.username )
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ else
+ xhr.open(type, s.url, s.async);
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data )
+ xhr.setRequestHeader("Content-Type", s.contentType);
+
+ // Set the If-Modified-Since header, if ifModified mode.
+ if ( s.ifModified )
+ xhr.setRequestHeader("If-Modified-Since",
+ jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e){}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global )
+ jQuery.event.trigger("ajaxSend", [xhr, s]);
+
+ // Wait for a response to come back
+ var onreadystatechange = function(isTimeout){
+ // The request was aborted, clear the interval and decrement jQuery.active
+ if (xhr.readyState == 0) {
+ if (ival) {
+ // clear poll interval
+ clearInterval(ival);
+ ival = null;
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
+ requestDone = true;
+
+ // clear poll interval
+ if (ival) {
+ clearInterval(ival);
+ ival = null;
+ }
+
+ status = isTimeout == "timeout" ? "timeout" :
+ !jQuery.httpSuccess( xhr ) ? "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" :
+ "success";
+
+ if ( status == "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch(e) {
+ status = "parsererror";
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status == "success" ) {
+ // Cache Last-Modified header, if ifModified mode.
+ var modRes;
+ try {
+ modRes = xhr.getResponseHeader("Last-Modified");
+ } catch(e) {} // swallow exception thrown by FF if header is not available
+
+ if ( s.ifModified && modRes )
+ jQuery.lastModified[s.url] = modRes;
+
+ // JSONP handles its own success callback
+ if ( !jsonp )
+ success();
+ } else
+ jQuery.handleError(s, xhr, status);
+
+ // Fire the complete handlers
+ complete();
+
+ if ( isTimeout )
+ xhr.abort();
+
+ // Stop memory leaks
+ if ( s.async )
+ xhr = null;
+ }
+ };
+
+ if ( s.async ) {
+ // don't attach the handler to the request, just poll it instead
+ var ival = setInterval(onreadystatechange, 13);
+
+ // Timeout checker
+ if ( s.timeout > 0 )
+ setTimeout(function(){
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone )
+ onreadystatechange( "timeout" );
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send(s.data);
+ } catch(e) {
+ jQuery.handleError(s, xhr, null, e);
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async )
+ onreadystatechange();
+
+ function success(){
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success )
+ s.success( data, status );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
+ }
+
+ function complete(){
+ // Process result
+ if ( s.complete )
+ s.complete(xhr, status);
+
+ // The request was completed
+ if ( s.global )
+ jQuery.event.trigger( "ajaxComplete", [xhr, s] );
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active )
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ handleError: function( s, xhr, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) s.error( xhr, status, e );
+
+ // Fire the global callback
+ if ( s.global )
+ jQuery.event.trigger( "ajaxError", [xhr, s, e] );
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol == "file:" ||
+ ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223;
+ } catch(e){}
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ try {
+ var xhrRes = xhr.getResponseHeader("Last-Modified");
+
+ // Firefox always returns 200. check Last-Modified date
+ return xhr.status == 304 || xhrRes == jQuery.lastModified[url];
+ } catch(e){}
+ return false;
+ },
+
+ httpData: function( xhr, type, s ) {
+ var ct = xhr.getResponseHeader("content-type"),
+ xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.tagName == "parsererror" )
+ throw "parsererror";
+
+ // Allow a pre-filtering function to sanitize the response
+ // s != null is checked to keep backwards compatibility
+ if( s && s.dataFilter )
+ data = s.dataFilter( data, type );
+
+ // The filter can actually parse the response
+ if( typeof data === "string" ){
+
+ // If the type is "script", eval it in global context
+ if ( type == "script" )
+ jQuery.globalEval( data );
+
+ // Get the JavaScript object, if JSON is used.
+ if ( type == "json" )
+ data = window["eval"]("(" + data + ")");
+ }
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a ) {
+ var s = [ ];
+
+ function add( key, value ){
+ s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
+ };
+
+ // If an array was passed in, assume that it is an array
+ // of form elements
+ if ( jQuery.isArray(a) || a.jquery )
+ // Serialize the form elements
+ jQuery.each( a, function(){
+ add( this.name, this.value );
+ });
+
+ // Otherwise, assume that it's an object of key/value pairs
+ else
+ // Serialize the key/values
+ for ( var j in a )
+ // If the value is an array then the key names need to be repeated
+ if ( jQuery.isArray(a[j]) )
+ jQuery.each( a[j], function(){
+ add( j, this );
+ });
+ else
+ add( j, jQuery.isFunction(a[j]) ? a[j]() : a[j] );
+
+ // Return the resulting serialization
+ return s.join("&").replace(/%20/g, "+");
+ }
+
+});
+var elemdisplay = {},
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+function genFx( type, num ){
+ var obj = {};
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function(){
+ obj[ this ] = type;
+ });
+ return obj;
+}
+
+jQuery.fn.extend({
+ show: function(speed,callback){
+ if ( speed ) {
+ return this.animate( genFx("show", 3), speed, callback);
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ var old = jQuery.data(this[i], "olddisplay");
+
+ this[i].style.display = old || "";
+
+ if ( jQuery.css(this[i], "display") === "none" ) {
+ var tagName = this[i].tagName, display;
+
+ if ( elemdisplay[ tagName ] ) {
+ display = elemdisplay[ tagName ];
+ } else {
+ var elem = jQuery("<" + tagName + " />").appendTo("body");
+
+ display = elem.css("display");
+ if ( display === "none" )
+ display = "block";
+
+ elem.remove();
+
+ elemdisplay[ tagName ] = display;
+ }
+
+ jQuery.data(this[i], "olddisplay", display);
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
+ }
+
+ return this;
+ }
+ },
+
+ hide: function(speed,callback){
+ if ( speed ) {
+ return this.animate( genFx("hide", 3), speed, callback);
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ var old = jQuery.data(this[i], "olddisplay");
+ if ( !old && old !== "none" )
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var i = 0, l = this.length; i < l; i++ ){
+ this[i].style.display = "none";
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ){
+ var bool = typeof fn === "boolean";
+
+ return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
+ this._toggle.apply( this, arguments ) :
+ fn == null || bool ?
+ this.each(function(){
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ }) :
+ this.animate(genFx("toggle", 3), fn, fn2);
+ },
+
+ fadeTo: function(speed,to,callback){
+ return this.animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ return this[ optall.queue === false ? "each" : "queue" ](function(){
+
+ var opt = jQuery.extend({}, optall), p,
+ hidden = this.nodeType == 1 && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
+ return opt.complete.call(this);
+
+ if ( ( p == "height" || p == "width" ) && this.style ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+ }
+
+ if ( opt.overflow != null )
+ this.style.overflow = "hidden";
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function(name, val){
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( /toggle|show|hide/.test(val) )
+ e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+ else {
+ var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat(parts[2]),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit != "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] )
+ end = ((parts[1] == "-=" ? -1 : 1) * end) + start;
+
+ e.custom( start, end, unit );
+ } else
+ e.custom( start, val, "" );
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function(clearQueue, gotoEnd){
+ var timers = jQuery.timers;
+
+ if (clearQueue)
+ this.queue([]);
+
+ this.each(function(){
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- )
+ if ( timers[i].elem == this ) {
+ if (gotoEnd)
+ // force the next step to be the last
+ timers[i](true);
+ timers.splice(i, 1);
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if (!gotoEnd)
+ this.dequeue();
+
+ return this;
+ }
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" }
+}, function( name, props ){
+ jQuery.fn[ name ] = function( speed, callback ){
+ return this.animate( props, speed, callback );
+ };
+});
+
+jQuery.extend({
+
+ speed: function(speed, easing, fn) {
+ var opt = typeof speed === "object" ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function(){
+ if ( opt.queue !== false )
+ jQuery(this).dequeue();
+ if ( jQuery.isFunction( opt.old ) )
+ opt.old.call( this );
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ){
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig )
+ options.orig = {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+
+ // Simple function for setting a style value
+ update: function(){
+ if ( this.options.step )
+ this.options.step.call( this.elem, this.now, this );
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop == "height" || this.prop == "width" ) && this.elem.style )
+ this.elem.style.display = "block";
+ },
+
+ // Get the current size
+ cur: function(force){
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) )
+ return this.elem[ this.prop ];
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function(from, to, unit){
+ this.startTime = now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ var self = this;
+ function t(gotoEnd){
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval(function(){
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ )
+ if ( !timers[i]() )
+ timers.splice(i--, 1);
+
+ if ( !timers.length ) {
+ clearInterval( timerId );
+ timerId = undefined;
+ }
+ }, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop == "width" || this.prop == "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery(this.elem).show();
+ },
+
+ // Simple 'hide' function
+ hide: function(){
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function(gotoEnd){
+ var t = now();
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ var done = true;
+ for ( var i in this.options.curAnim )
+ if ( this.options.curAnim[i] !== true )
+ done = false;
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ this.elem.style.display = this.options.display;
+ if ( jQuery.css(this.elem, "display") == "none" )
+ this.elem.style.display = "block";
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide )
+ jQuery(this.elem).hide();
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show )
+ for ( var p in this.options.curAnim )
+ jQuery.attr(this.elem.style, p, this.options.orig[p]);
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+
+};
+
+jQuery.extend( jQuery.fx, {
+ speeds:{
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+ step: {
+
+ opacity: function(fx){
+ jQuery.attr(fx.elem.style, "opacity", fx.now);
+ },
+
+ _default: function(fx){
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
+ fx.elem.style[ fx.prop ] = fx.now + fx.unit;
+ else
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+});
+if ( document.documentElement["getBoundingClientRect"] )
+ jQuery.fn.offset = function() {
+ if ( !this[0] ) return { top: 0, left: 0 };
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
+ var box = this[0].getBoundingClientRect(), doc = this[0].ownerDocument, body = doc.body, docElem = doc.documentElement,
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ top = box.top + (self.pageYOffset || jQuery.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
+ left = box.left + (self.pageXOffset || jQuery.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+ return { top: top, left: left };
+ };
+else
+ jQuery.fn.offset = function() {
+ if ( !this[0] ) return { top: 0, left: 0 };
+ if ( this[0] === this[0].ownerDocument.body ) return jQuery.offset.bodyOffset( this[0] );
+ jQuery.offset.initialized || jQuery.offset.initialize();
+
+ var elem = this[0], offsetParent = elem.offsetParent, prevOffsetParent = elem,
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+ body = doc.body, defaultView = doc.defaultView,
+ prevComputedStyle = defaultView.getComputedStyle(elem, null),
+ top = elem.offsetTop, left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ computedStyle = defaultView.getComputedStyle(elem, null);
+ top -= elem.scrollTop, left -= elem.scrollLeft;
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop, left += elem.offsetLeft;
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.tagName)) )
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+ }
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" )
+ top += parseInt( computedStyle.borderTopWidth, 10) || 0,
+ left += parseInt( computedStyle.borderLeftWidth, 10) || 0;
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" )
+ top += body.offsetTop,
+ left += body.offsetLeft;
+
+ if ( prevComputedStyle.position === "fixed" )
+ top += Math.max(docElem.scrollTop, body.scrollTop),
+ left += Math.max(docElem.scrollLeft, body.scrollLeft);
+
+ return { top: top, left: left };
+ };
+
+jQuery.offset = {
+ initialize: function() {
+ if ( this.initialized ) return;
+ var body = document.body, container = document.createElement('div'), innerDiv, checkDiv, table, td, rules, prop, bodyMarginTop = body.style.marginTop,
+ html = '<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';
+
+ rules = { position: 'absolute', top: 0, left: 0, margin: 0, border: 0, width: '1px', height: '1px', visibility: 'hidden' };
+ for ( prop in rules ) container.style[prop] = rules[prop];
+
+ container.innerHTML = html;
+ body.insertBefore(container, body.firstChild);
+ innerDiv = container.firstChild, checkDiv = innerDiv.firstChild, td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ innerDiv.style.overflow = 'hidden', innerDiv.style.position = 'relative';
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ body.style.marginTop = '1px';
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop === 0);
+ body.style.marginTop = bodyMarginTop;
+
+ body.removeChild(container);
+ this.initialized = true;
+ },
+
+ bodyOffset: function(body) {
+ jQuery.offset.initialized || jQuery.offset.initialize();
+ var top = body.offsetTop, left = body.offsetLeft;
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset )
+ top += parseInt( jQuery.curCSS(body, 'marginTop', true), 10 ) || 0,
+ left += parseInt( jQuery.curCSS(body, 'marginLeft', true), 10 ) || 0;
+ return { top: top, left: left };
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ var left = 0, top = 0, results;
+
+ if ( this[0] ) {
+ // Get *real* offsetParent
+ var offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= num( this, 'marginTop' );
+ offset.left -= num( this, 'marginLeft' );
+
+ // Add offsetParent borders
+ parentOffset.top += num( offsetParent, 'borderTopWidth' );
+ parentOffset.left += num( offsetParent, 'borderLeftWidth' );
+
+ // Subtract the two offsets
+ results = {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ }
+
+ return results;
+ },
+
+ offsetParent: function() {
+ var offsetParent = this[0].offsetParent || document.body;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
+ offsetParent = offsetParent.offsetParent;
+ return jQuery(offsetParent);
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ['Left', 'Top'], function(i, name) {
+ var method = 'scroll' + name;
+
+ jQuery.fn[ method ] = function(val) {
+ if (!this[0]) return null;
+
+ return val !== undefined ?
+
+ // Set the scroll offset
+ this.each(function() {
+ this == window || this == document ?
+ window.scrollTo(
+ !i ? val : jQuery(window).scrollLeft(),
+ i ? val : jQuery(window).scrollTop()
+ ) :
+ this[ method ] = val;
+ }) :
+
+ // Return the scroll offset
+ this[0] == window || this[0] == document ?
+ self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
+ jQuery.boxModel && document.documentElement[ method ] ||
+ document.body[ method ] :
+ this[0][ method ];
+ };
+});
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function(i, name){
+
+ var tl = i ? "Left" : "Top", // top or left
+ br = i ? "Right" : "Bottom", // bottom or right
+ lower = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function(){
+ return this[0] ?
+ jQuery.css( this[0], lower, false, "padding" ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function(margin) {
+ return this[0] ?
+ jQuery.css( this[0], lower, false, margin ? "margin" : "border" ) :
+ null;
+ };
+
+ var type = name.toLowerCase();
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ return this[0] == window ?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] ||
+ document.body[ "client" + name ] :
+
+ // Get document width or height
+ this[0] == document ?
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ document.documentElement["client" + name],
+ document.body["scroll" + name], document.documentElement["scroll" + name],
+ document.body["offset" + name], document.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ (this.length ? jQuery.css( this[0], type ) : null) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});
+})();
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-ui-1.js b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-ui-1.js
new file mode 100755
index 0000000..cf19f30
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/jquery-ui-1.js
@@ -0,0 +1,298 @@
+/*
+ * jQuery UI 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI
+ */
+jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.2",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m<n.length;m++){if(j.options[n[m][0]]){n[m][1].apply(j.element,k)}}}},contains:function(k,j){return document.compareDocumentPosition?k.compareDocumentPosition(j)&16:k!==j&&k.contains(j)},hasScroll:function(m,k){if(c(m).css("overflow")=="hidden"){return false}var j=(k&&k=="left")?"scrollLeft":"scrollTop",l=false;if(m[j]>0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;/*
+ * jQuery UI Draggable 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Draggables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function(a){a.widget("ui.draggable",a.extend({},a.ui.mouse,{_init:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.addClasses&&this.element.addClass("ui-draggable"));(this.options.disabled&&this.element.addClass("ui-draggable-disabled"));this._mouseInit()},destroy:function(){if(!this.element.data("draggable")){return}this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")){return false}this.handle=this._getHandle(b);if(!this.handle){return false}return true},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b);this._cacheHelperProportions();if(a.ui.ddmanager){a.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(b);this.originalPageX=b.pageX;this.originalPageY=b.pageY;if(c.cursorAt){this._adjustOffsetFromHelper(c.cursorAt)}if(c.containment){this._setContainment()}this._trigger("start",b);this._cacheHelperProportions();if(a.ui.ddmanager&&!c.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,b)}this.helper.addClass("ui-draggable-dragging");this._mouseDrag(b,true);return true},_mouseDrag:function(b,d){this.position=this._generatePosition(b);this.positionAbs=this._convertPositionTo("absolute");if(!d){var c=this._uiHash();this._trigger("drag",b,c);this.position=c.position}if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(a.ui.ddmanager){a.ui.ddmanager.drag(this,b)}return false},_mouseStop:function(c){var d=false;if(a.ui.ddmanager&&!this.options.dropBehaviour){d=a.ui.ddmanager.drop(this,c)}if(this.dropped){d=this.dropped;this.dropped=false}if((this.options.revert=="invalid"&&!d)||(this.options.revert=="valid"&&d)||this.options.revert===true||(a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d))){var b=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){b._trigger("stop",c);b._clear()})}else{this._trigger("stop",c);this._clear()}return false},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==b.target){c=true}});return c},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c])):(d.helper=="clone"?this.element.clone():this.element);if(!b.parents("body").length){b.appendTo((d.appendTo=="parent"?this.element[0].parentNode:d.appendTo))}if(b[0]!=this.element[0]&&!(/(fixed|absolute)/).test(b.css("position"))){b.css("position","absolute")}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.element.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)&&e.containment.constructor!=Array){var c=a(e.containment)[0];if(!c){return}var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}else{if(e.containment.constructor==Array){this.containment=e.containment}}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(i?0:b.scrollTop())))),left:(d-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:b.scrollLeft())))}},_clear:function(){this.helper.removeClass("ui-draggable-dragging");if(this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval){this.helper.remove()}this.helper=null;this.cancelHelperRemoval=false},_trigger:function(b,c,d){d=d||this._uiHash();a.ui.plugin.call(this,b,[c,d]);if(b=="drag"){this.positionAbs=this._convertPositionTo("absolute")}return a.widget.prototype._trigger.call(this,b,c,d)},plugins:{},_uiHash:function(b){return{helper:this.helper,position:this.position,absolutePosition:this.positionAbs,offset:this.positionAbs}}}));a.extend(a.ui.draggable,{version:"1.7.2",eventPrefix:"drag",defaults:{addClasses:true,appendTo:"parent",axis:false,cancel:":input,option",connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,delay:0,distance:1,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false}});a.ui.plugin.add("draggable","connectToSortable",{start:function(c,e){var d=a(this).data("draggable"),f=d.options,b=a.extend({},e,{item:d.element});d.sortables=[];a(f.connectToSortable).each(function(){var g=a.data(this,"sortable");if(g&&!g.options.disabled){d.sortables.push({instance:g,shouldRevert:g.options.revert});g._refreshItems();g._trigger("activate",c,b)}})},stop:function(c,e){var d=a(this).data("draggable"),b=a.extend({},e,{item:d.element});a.each(d.sortables,function(){if(this.instance.isOver){this.instance.isOver=0;d.cancelHelperRemoval=true;this.instance.cancelHelperRemoval=false;if(this.shouldRevert){this.instance.options.revert=true}this.instance._mouseStop(c);this.instance.options.helper=this.instance.options._helper;if(d.options.helper=="original"){this.instance.currentItem.css({top:"auto",left:"auto"})}}else{this.instance.cancelHelperRemoval=false;this.instance._trigger("deactivate",c,b)}})},drag:function(c,f){var e=a(this).data("draggable"),b=this;var d=function(i){var n=this.offset.click.top,m=this.offset.click.left;var g=this.positionAbs.top,k=this.positionAbs.left;var j=i.height,l=i.width;var p=i.top,h=i.left;return a.ui.isOver(g+n,k+m,p,h,j,l)};a.each(e.sortables,function(g){this.instance.positionAbs=e.positionAbs;this.instance.helperProportions=e.helperProportions;this.instance.offset.click=e.offset.click;if(this.instance._intersectsWith(this.instance.containerCache)){if(!this.instance.isOver){this.instance.isOver=1;this.instance.currentItem=a(b).clone().appendTo(this.instance.element).data("sortable-item",true);this.instance.options._helper=this.instance.options.helper;this.instance.options.helper=function(){return f.helper[0]};c.target=this.instance.currentItem[0];this.instance._mouseCapture(c,true);this.instance._mouseStart(c,true,true);this.instance.offset.click.top=e.offset.click.top;this.instance.offset.click.left=e.offset.click.left;this.instance.offset.parent.left-=e.offset.parent.left-this.instance.offset.parent.left;this.instance.offset.parent.top-=e.offset.parent.top-this.instance.offset.parent.top;e._trigger("toSortable",c);e.dropped=this.instance.element;e.currentItem=e.element;this.instance.fromOutside=e}if(this.instance.currentItem){this.instance._mouseDrag(c)}}else{if(this.instance.isOver){this.instance.isOver=0;this.instance.cancelHelperRemoval=true;this.instance.options.revert=false;this.instance._trigger("out",c,this.instance._uiHash(this.instance));this.instance._mouseStop(c,true);this.instance.options.helper=this.instance.options._helper;this.instance.currentItem.remove();if(this.instance.placeholder){this.instance.placeholder.remove()}e._trigger("fromSortable",c);e.dropped=false}}})}});a.ui.plugin.add("draggable","cursor",{start:function(c,d){var b=a("body"),e=a(this).data("draggable").options;if(b.css("cursor")){e._cursor=b.css("cursor")}b.css("cursor",e.cursor)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._cursor){a("body").css("cursor",d._cursor)}}});a.ui.plugin.add("draggable","iframeFix",{start:function(b,c){var d=a(this).data("draggable").options;a(d.iframeFix===true?"iframe":d.iframeFix).each(function(){a('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(a(this).offset()).appendTo("body")})},stop:function(b,c){a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});a.ui.plugin.add("draggable","opacity",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("opacity")){e._opacity=b.css("opacity")}b.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._opacity){a(c.helper).css("opacity",d._opacity)}}});a.ui.plugin.add("draggable","scroll",{start:function(c,d){var b=a(this).data("draggable");if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){b.overflowOffset=b.scrollParent.offset()}},drag:function(d,e){var c=a(this).data("draggable"),f=c.options,b=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!f.axis||f.axis!="x"){if((c.overflowOffset.top+c.scrollParent[0].offsetHeight)-d.pageY<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop+f.scrollSpeed}else{if(d.pageY-c.overflowOffset.top<f.scrollSensitivity){c.scrollParent[0].scrollTop=b=c.scrollParent[0].scrollTop-f.scrollSpeed}}}if(!f.axis||f.axis!="y"){if((c.overflowOffset.left+c.scrollParent[0].offsetWidth)-d.pageX<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft+f.scrollSpeed}else{if(d.pageX-c.overflowOffset.left<f.scrollSensitivity){c.scrollParent[0].scrollLeft=b=c.scrollParent[0].scrollLeft-f.scrollSpeed}}}}else{if(!f.axis||f.axis!="x"){if(d.pageY-a(document).scrollTop()<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-f.scrollSpeed)}else{if(a(window).height()-(d.pageY-a(document).scrollTop())<f.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+f.scrollSpeed)}}}if(!f.axis||f.axis!="y"){if(d.pageX-a(document).scrollLeft()<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-f.scrollSpeed)}else{if(a(window).width()-(d.pageX-a(document).scrollLeft())<f.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+f.scrollSpeed)}}}}if(b!==false&&a.ui.ddmanager&&!f.dropBehaviour){a.ui.ddmanager.prepareOffsets(c,d)}}});a.ui.plugin.add("draggable","snap",{start:function(c,d){var b=a(this).data("draggable"),e=b.options;b.snapElements=[];a(e.snap.constructor!=String?(e.snap.items||":data(draggable)"):e.snap).each(function(){var g=a(this);var f=g.offset();if(this!=b.element[0]){b.snapElements.push({item:this,width:g.outerWidth(),height:g.outerHeight(),top:f.top,left:f.left})}})},drag:function(u,p){var g=a(this).data("draggable"),q=g.options;var y=q.snapTolerance;var x=p.offset.left,w=x+g.helperProportions.width,f=p.offset.top,e=f+g.helperProportions.height;for(var v=g.snapElements.length-1;v>=0;v--){var s=g.snapElements[v].left,n=s+g.snapElements[v].width,m=g.snapElements[v].top,A=m+g.snapElements[v].height;if(!((s-y<x&&x<n+y&&m-y<f&&f<A+y)||(s-y<x&&x<n+y&&m-y<e&&e<A+y)||(s-y<w&&w<n+y&&m-y<f&&f<A+y)||(s-y<w&&w<n+y&&m-y<e&&e<A+y))){if(g.snapElements[v].snapping){(g.options.snap.release&&g.options.snap.release.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=false;continue}if(q.snapMode!="inner"){var c=Math.abs(m-e)<=y;var z=Math.abs(A-f)<=y;var j=Math.abs(s-w)<=y;var k=Math.abs(n-x)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m-g.helperProportions.height,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s-g.helperProportions.width}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n}).left-g.margins.left}}var h=(c||z||j||k);if(q.snapMode!="outer"){var c=Math.abs(m-f)<=y;var z=Math.abs(A-e)<=y;var j=Math.abs(s-x)<=y;var k=Math.abs(n-w)<=y;if(c){p.position.top=g._convertPositionTo("relative",{top:m,left:0}).top-g.margins.top}if(z){p.position.top=g._convertPositionTo("relative",{top:A-g.helperProportions.height,left:0}).top-g.margins.top}if(j){p.position.left=g._convertPositionTo("relative",{top:0,left:s}).left-g.margins.left}if(k){p.position.left=g._convertPositionTo("relative",{top:0,left:n-g.helperProportions.width}).left-g.margins.left}}if(!g.snapElements[v].snapping&&(c||z||j||k||h)){(g.options.snap.snap&&g.options.snap.snap.call(g.element,u,a.extend(g._uiHash(),{snapItem:g.snapElements[v].item})))}g.snapElements[v].snapping=(c||z||j||k||h)}}});a.ui.plugin.add("draggable","stack",{start:function(b,c){var e=a(this).data("draggable").options;var d=a.makeArray(a(e.stack.group)).sort(function(g,f){return(parseInt(a(g).css("zIndex"),10)||e.stack.min)-(parseInt(a(f).css("zIndex"),10)||e.stack.min)});a(d).each(function(f){this.style.zIndex=e.stack.min+f});this[0].style.zIndex=e.stack.min+d.length}});a.ui.plugin.add("draggable","zIndex",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("zIndex")){e._zIndex=b.css("zIndex")}b.css("zIndex",e.zIndex)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._zIndex){a(c.helper).css("zIndex",d._zIndex)}}})})(jQuery);;/*
+ * jQuery UI Droppable 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Droppables
+ *
+ * Depends:
+ * ui.core.js
+ * ui.draggable.js
+ */
+(function(a){a.widget("ui.droppable",{_init:function(){var c=this.options,b=c.accept;this.isover=0;this.isout=1;this.options.accept=this.options.accept&&a.isFunction(this.options.accept)?this.options.accept:function(e){return e.is(b)};this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight};a.ui.ddmanager.droppables[this.options.scope]=a.ui.ddmanager.droppables[this.options.scope]||[];a.ui.ddmanager.droppables[this.options.scope].push(this);(this.options.addClasses&&this.element.addClass("ui-droppable"))},destroy:function(){var b=a.ui.ddmanager.droppables[this.options.scope];for(var c=0;c<b.length;c++){if(b[c]==this){b.splice(c,1)}}this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable")},_setData:function(b,c){if(b=="accept"){this.options.accept=c&&a.isFunction(c)?c:function(e){return e.is(c)}}else{a.widget.prototype._setData.apply(this,arguments)}},_activate:function(c){var b=a.ui.ddmanager.current;if(this.options.activeClass){this.element.addClass(this.options.activeClass)}(b&&this._trigger("activate",c,this.ui(b)))},_deactivate:function(c){var b=a.ui.ddmanager.current;if(this.options.activeClass){this.element.removeClass(this.options.activeClass)}(b&&this._trigger("deactivate",c,this.ui(b)))},_over:function(c){var b=a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.hoverClass){this.element.addClass(this.options.hoverClass)}this._trigger("over",c,this.ui(b))}},_out:function(c){var b=a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.hoverClass){this.element.removeClass(this.options.hoverClass)}this._trigger("out",c,this.ui(b))}},_drop:function(c,d){var b=d||a.ui.ddmanager.current;if(!b||(b.currentItem||b.element)[0]==this.element[0]){return false}var e=false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function(){var f=a.data(this,"droppable");if(f.options.greedy&&a.ui.intersect(b,a.extend(f,{offset:f.element.offset()}),f.options.tolerance)){e=true;return false}});if(e){return false}if(this.options.accept.call(this.element[0],(b.currentItem||b.element))){if(this.options.activeClass){this.element.removeClass(this.options.activeClass)}if(this.options.hoverClass){this.element.removeClass(this.options.hoverClass)}this._trigger("drop",c,this.ui(b));return this.element}return false},ui:function(b){return{draggable:(b.currentItem||b.element),helper:b.helper,position:b.position,absolutePosition:b.positionAbs,offset:b.positionAbs}}});a.extend(a.ui.droppable,{version:"1.7.2",eventPrefix:"drop",defaults:{accept:"*",activeClass:false,addClasses:true,greedy:false,hoverClass:false,scope:"default",tolerance:"intersect"}});a.ui.intersect=function(q,j,o){if(!j.offset){return false}var e=(q.positionAbs||q.position.absolute).left,d=e+q.helperProportions.width,n=(q.positionAbs||q.position.absolute).top,m=n+q.helperProportions.height;var g=j.offset.left,c=g+j.proportions.width,p=j.offset.top,k=p+j.proportions.height;switch(o){case"fit":return(g<e&&d<c&&p<n&&m<k);break;case"intersect":return(g<e+(q.helperProportions.width/2)&&d-(q.helperProportions.width/2)<c&&p<n+(q.helperProportions.height/2)&&m-(q.helperProportions.height/2)<k);break;case"pointer":var h=((q.positionAbs||q.position.absolute).left+(q.clickOffset||q.offset.click).left),i=((q.positionAbs||q.position.absolute).top+(q.clickOffset||q.offset.click).top),f=a.ui.isOver(i,h,p,g,j.proportions.height,j.proportions.width);return f;break;case"touch":return((n>=p&&n<=k)||(m>=p&&m<=k)||(n<p&&m>k))&&((e>=g&&e<=c)||(d>=g&&d<=c)||(e<g&&d>c));break;default:return false;break}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,g){var b=a.ui.ddmanager.droppables[e.options.scope];var f=g?g.type:null;var h=(e.currentItem||e.element).find(":data(droppable)").andSelf();droppablesLoop:for(var d=0;d<b.length;d++){if(b[d].options.disabled||(e&&!b[d].options.accept.call(b[d].element[0],(e.currentItem||e.element)))){continue}for(var c=0;c<h.length;c++){if(h[c]==b[d].element[0]){b[d].proportions.height=0;continue droppablesLoop}}b[d].visible=b[d].element.css("display")!="none";if(!b[d].visible){continue}b[d].offset=b[d].element.offset();b[d].proportions={width:b[d].element[0].offsetWidth,height:b[d].element[0].offsetHeight};if(f=="mousedown"){b[d]._activate.call(b[d],g)}}},drop:function(b,c){var d=false;a.each(a.ui.ddmanager.droppables[b.options.scope],function(){if(!this.options){return}if(!this.options.disabled&&this.visible&&a.ui.intersect(b,this,this.options.tolerance)){d=this._drop.call(this,c)}if(!this.options.disabled&&this.visible&&this.options.accept.call(this.element[0],(b.currentItem||b.element))){this.isout=1;this.isover=0;this._deactivate.call(this,c)}});return d},drag:function(b,c){if(b.options.refreshPositions){a.ui.ddmanager.prepareOffsets(b,c)}a.each(a.ui.ddmanager.droppables[b.options.scope],function(){if(this.options.disabled||this.greedyChild||!this.visible){return}var e=a.ui.intersect(b,this,this.options.tolerance);var g=!e&&this.isover==1?"isout":(e&&this.isover==0?"isover":null);if(!g){return}var f;if(this.options.greedy){var d=this.element.parents(":data(droppable):eq(0)");if(d.length){f=a.data(d[0],"droppable");f.greedyChild=(g=="isover"?1:0)}}if(f&&g=="isover"){f.isover=0;f.isout=1;f._out.call(f,c)}this[g]=1;this[g=="isout"?"isover":"isout"]=0;this[g=="isover"?"_over":"_out"].call(this,c);if(f&&g=="isout"){f.isout=0;f.isover=1;f._over.call(f,c)}})}}})(jQuery);;/*
+ * jQuery UI Resizable 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Resizables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function(c){c.widget("ui.resizable",c.extend({},c.ui.mouse,{_init:function(){var e=this,j=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(j.aspectRatio),aspectRatio:j.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:j.helper||j.ghost||j.animate?j.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&c.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(c('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=j.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var k=this.handles.split(",");this.handles={};for(var f=0;f<k.length;f++){var h=c.trim(k[f]),d="ui-resizable-"+h;var g=c('<div class="ui-resizable-handle '+d+'"></div>');if(/sw|se|ne|nw/.test(h)){g.css({zIndex:++j.zIndex})}if("se"==h){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[h]=".ui-resizable-"+h;this.element.append(g)}}this._renderAxis=function(p){p=p||this.element;for(var m in this.handles){if(this.handles[m].constructor==String){this.handles[m]=c(this.handles[m],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var n=c(this.handles[m],this.element),o=0;o=/sw|ne|nw|se|n|s/.test(m)?n.outerHeight():n.outerWidth();var l=["padding",/ne|nw|n/.test(m)?"Top":/se|sw|s/.test(m)?"Bottom":/^e$/.test(m)?"Right":"Left"].join("");p.css(l,o);this._proportionallyResize()}if(!c(this.handles[m]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!e.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}e.axis=i&&i[1]?i[1]:"se"}});if(j.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){c(this).removeClass("ui-resizable-autohide");e._handles.show()},function(){if(!e.resizing){c(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var d=function(f){c(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){d(this.element);var e=this.element;e.parent().append(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).end().remove()}this.originalElement.css("resize",this.originalResizeStyle);d(this.originalElement)},_mouseCapture:function(e){var f=false;for(var d in this.handles){if(c(this.handles[d])[0]==e.target){f=true}}return this.options.disabled||!!f},_mouseStart:function(f){var i=this.options,e=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(d.is(".ui-draggable")||(/absolute/).test(d.css("position"))){d.css({position:"absolute",top:e.top,left:e.left})}if(c.browser.opera&&(/relative/).test(d.css("position"))){d.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var j=b(this.helper.css("left")),g=b(this.helper.css("top"));if(i.containment){j+=c(i.containment).scrollLeft()||0;g+=c(i.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:j,top:g};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:j,top:g};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:f.pageX,top:f.pageY};this.aspectRatio=(typeof i.aspectRatio=="number")?i.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var h=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",h=="auto"?this.axis+"-resize":h);d.addClass("ui-resizable-resizing");this._propagate("start",f);return true},_mouseDrag:function(d){var g=this.helper,f=this.options,l={},p=this,i=this.originalMousePosition,m=this.axis;var q=(d.pageX-i.left)||0,n=(d.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var k=h.apply(this,[d,q,n]),j=c.browser.msie&&c.browser.version<7,e=this.sizeDiff;if(this._aspectRatio||d.shiftKey){k=this._updateRatio(k,d)}k=this._respectSize(k,d);this._propagate("resize",d);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(k);this._trigger("resize",d,this.ui());return false},_mouseStop:function(g){this.resizing=false;var h=this.options,l=this;if(this._helper){var f=this._proportionallyResizeElements,d=f.length&&(/textarea/i).test(f[0].nodeName),e=d&&c.ui.hasScroll(f[0],"left")?0:l.sizeDiff.height,j=d?0:l.sizeDiff.width;var m={width:(l.size.width-j),height:(l.size.height-e)},i=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,k=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!h.animate){this.element.css(c.extend(m,{top:k,left:i}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!h.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",g);if(this._helper){this.helper.remove()}return false},_updateCache:function(d){var e=this.options;this.offset=this.helper.offset();if(a(d.left)){this.position.left=d.left}if(a(d.top)){this.position.top=d.top}if(a(d.height)){this.size.height=d.height}if(a(d.width)){this.size.width=d.width}},_updateRatio:function(g,f){var h=this.options,i=this.position,e=this.size,d=this.axis;if(g.height){g.width=(e.height*this.aspectRatio)}else{if(g.width){g.height=(e.width/this.aspectRatio)}}if(d=="sw"){g.left=i.left+(e.width-g.width);g.top=null}if(d=="nw"){g.top=i.top+(e.height-g.height);g.left=i.left+(e.width-g.width)}return g},_respectSize:function(k,f){var i=this.helper,h=this.options,q=this._aspectRatio||f.shiftKey,p=this.axis,s=a(k.width)&&h.maxWidth&&(h.maxWidth<k.width),l=a(k.height)&&h.maxHeight&&(h.maxHeight<k.height),g=a(k.width)&&h.minWidth&&(h.minWidth>k.width),r=a(k.height)&&h.minHeight&&(h.minHeight>k.height);if(g){k.width=h.minWidth}if(r){k.height=h.minHeight}if(s){k.width=h.maxWidth}if(l){k.height=h.maxHeight}var e=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height;var j=/sw|nw|w/.test(p),d=/nw|ne|n/.test(p);if(g&&j){k.left=e-h.minWidth}if(s&&j){k.left=e-h.maxWidth}if(r&&d){k.top=n-h.minHeight}if(l&&d){k.top=n-h.maxHeight}var m=!k.width&&!k.height;if(m&&!k.left&&k.top){k.top=null}else{if(m&&!k.top&&k.left){k.left=null}}return k},_proportionallyResize:function(){var j=this.options;if(!this._proportionallyResizeElements.length){return}var f=this.helper||this.element;for(var e=0;e<this._proportionallyResizeElements.length;e++){var g=this._proportionallyResizeElements[e];if(!this.borderDif){var d=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],h=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=c.map(d,function(k,m){var l=parseInt(k,10)||0,n=parseInt(h[m],10)||0;return l+n})}if(c.browser.msie&&!(!(c(f).is(":hidden")||c(f).parents(":hidden").length))){continue}g.css({height:(f.height()-this.borderDif[0]-this.borderDif[2])||0,width:(f.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var e=this.element,h=this.options;this.elementOffset=e.offset();if(this._helper){this.helper=this.helper||c('<div style="overflow:hidden;"></div>');var d=c.browser.msie&&c.browser.version<7,f=(d?1:0),g=(d?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(f,e,d){return{width:this.originalSize.width+e}},w:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{left:h.left+e,width:f.width-e}},n:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{top:h.top+d,height:f.height-d}},s:function(f,e,d){return{height:this.originalSize.height+d}},se:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},sw:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[f,e,d]))},ne:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},nw:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[f,e,d]))}},_propagate:function(e,d){c.ui.plugin.call(this,e,[d,this.ui()]);(e!="resize"&&this._trigger(e,d,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));c.extend(c.ui.resizable,{version:"1.7.2",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000}});c.ui.plugin.add("resizable","alsoResize",{start:function(e,f){var d=c(this).data("resizable"),g=d.options;_store=function(h){c(h).each(function(){c(this).data("resizable-alsoresize",{width:parseInt(c(this).width(),10),height:parseInt(c(this).height(),10),left:parseInt(c(this).css("left"),10),top:parseInt(c(this).css("top"),10)})})};if(typeof(g.alsoResize)=="object"&&!g.alsoResize.parentNode){if(g.alsoResize.length){g.alsoResize=g.alsoResize[0];_store(g.alsoResize)}else{c.each(g.alsoResize,function(h,i){_store(h)})}}else{_store(g.alsoResize)}},resize:function(f,h){var e=c(this).data("resizable"),i=e.options,g=e.originalSize,k=e.originalPosition;var j={height:(e.size.height-g.height)||0,width:(e.size.width-g.width)||0,top:(e.position.top-k.top)||0,left:(e.position.left-k.left)||0},d=function(l,m){c(l).each(function(){var p=c(this),q=c(this).data("resizable-alsoresize"),o={},n=m&&m.length?m:["width","height","top","left"];c.each(n||["width","height","top","left"],function(r,t){var s=(q[t]||0)+(j[t]||0);if(s&&s>=0){o[t]=s||null}});if(/relative/.test(p.css("position"))&&c.browser.opera){e._revertToRelativePosition=true;p.css({position:"absolute",top:"auto",left:"auto"})}p.css(o)})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.nodeType){c.each(i.alsoResize,function(l,m){d(l,m)})}else{d(i.alsoResize)}},stop:function(e,f){var d=c(this).data("resizable");if(d._revertToRelativePosition&&c.browser.opera){d._revertToRelativePosition=false;el.css({position:"relative"})}c(this).removeData("resizable-alsoresize-start")}});c.ui.plugin.add("resizable","animate",{stop:function(h,m){var n=c(this).data("resizable"),i=n.options;var g=n._proportionallyResizeElements,d=g.length&&(/textarea/i).test(g[0].nodeName),e=d&&c.ui.hasScroll(g[0],"left")?0:n.sizeDiff.height,k=d?0:n.sizeDiff.width;var f={width:(n.size.width-k),height:(n.size.height-e)},j=(parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left))||null,l=(parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top))||null;n.element.animate(c.extend(f,l&&j?{top:l,left:j}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var o={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};if(g&&g.length){c(g[0]).css({width:o.width,height:o.height})}n._updateCache(o);n._propagate("resize",h)}})}});c.ui.plugin.add("resizable","containment",{start:function(e,q){var s=c(this).data("resizable"),i=s.options,k=s.element;var f=i.containment,j=(f instanceof c)?f.get(0):(/parent/.test(f))?k.parent().get(0):f;if(!j){return}s.containerElement=c(j);if(/document/.test(f)||f==document){s.containerOffset={left:0,top:0};s.containerPosition={left:0,top:0};s.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var m=c(j),h=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){h[p]=b(m.css("padding"+o))});s.containerOffset=m.offset();s.containerPosition=m.position();s.containerSize={height:(m.innerHeight()-h[3]),width:(m.innerWidth()-h[1])};var n=s.containerOffset,d=s.containerSize.height,l=s.containerSize.width,g=(c.ui.hasScroll(j,"left")?j.scrollWidth:l),r=(c.ui.hasScroll(j)?j.scrollHeight:d);s.parentData={element:j,left:n.left,top:n.top,width:g,height:r}}},resize:function(f,p){var s=c(this).data("resizable"),h=s.options,e=s.containerSize,n=s.containerOffset,l=s.size,m=s.position,q=s._aspectRatio||f.shiftKey,d={top:0,left:0},g=s.containerElement;if(g[0]!=document&&(/static/).test(g.css("position"))){d=n}if(m.left<(s._helper?n.left:0)){s.size.width=s.size.width+(s._helper?(s.position.left-n.left):(s.position.left-d.left));if(q){s.size.height=s.size.width/h.aspectRatio}s.position.left=h.helper?n.left:0}if(m.top<(s._helper?n.top:0)){s.size.height=s.size.height+(s._helper?(s.position.top-n.top):s.position.top);if(q){s.size.width=s.size.height*h.aspectRatio}s.position.top=s._helper?n.top:0}s.offset.left=s.parentData.left+s.position.left;s.offset.top=s.parentData.top+s.position.top;var k=Math.abs((s._helper?s.offset.left-d.left:(s.offset.left-d.left))+s.sizeDiff.width),r=Math.abs((s._helper?s.offset.top-d.top:(s.offset.top-n.top))+s.sizeDiff.height);var j=s.containerElement.get(0)==s.element.parent().get(0),i=/relative|absolute/.test(s.containerElement.css("position"));if(j&&i){k-=s.parentData.left}if(k+s.size.width>=s.parentData.width){s.size.width=s.parentData.width-k;if(q){s.size.height=s.size.width/s.aspectRatio}}if(r+s.size.height>=s.parentData.height){s.size.height=s.parentData.height-r;if(q){s.size.width=s.size.height*s.aspectRatio}}},stop:function(e,m){var p=c(this).data("resizable"),f=p.options,k=p.position,l=p.containerOffset,d=p.containerPosition,g=p.containerElement;var i=c(p.helper),q=i.offset(),n=i.outerWidth()-p.sizeDiff.width,j=i.outerHeight()-p.sizeDiff.height;if(p._helper&&!f.animate&&(/relative/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}if(p._helper&&!f.animate&&(/static/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}}});c.ui.plugin.add("resizable","ghost",{start:function(f,g){var d=c(this).data("resizable"),h=d.options,e=d.size;d.ghost=d.originalElement.clone();d.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");d.ghost.appendTo(d.helper)},resize:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost){d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})}},stop:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost&&d.helper){d.helper.get(0).removeChild(d.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(d,l){var n=c(this).data("resizable"),g=n.options,j=n.size,h=n.originalSize,i=n.originalPosition,m=n.axis,k=g._aspectRatio||d.shiftKey;g.grid=typeof g.grid=="number"?[g.grid,g.grid]:g.grid;var f=Math.round((j.width-h.width)/(g.grid[0]||1))*(g.grid[0]||1),e=Math.round((j.height-h.height)/(g.grid[1]||1))*(g.grid[1]||1);if(/^(se|s|e)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e}else{if(/^(ne)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e}else{if(/^(sw)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.left=i.left-f}else{n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e;n.position.left=i.left-f}}}}});var b=function(d){return parseInt(d,10)||0};var a=function(d){return !isNaN(parseInt(d,10))}})(jQuery);;/*
+ * jQuery UI Selectable 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Selectables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function(a){a.widget("ui.selectable",a.extend({},a.ui.mouse,{_init:function(){var b=this;this.element.addClass("ui-selectable");this.dragged=false;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]);c.each(function(){var d=a(this);var e=d.offset();a.data(this,"selectable-item",{element:this,$element:d,left:e.left,top:e.top,right:e.left+d.outerWidth(),bottom:e.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"),selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=a(document.createElement("div")).css({border:"1px dotted black"}).addClass("ui-selectable-helper")},destroy:function(){this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy()},_mouseStart:function(d){var b=this;this.opos=[d.pageX,d.pageY];if(this.options.disabled){return}var c=this.options;this.selectees=a(c.filter,this.element[0]);this._trigger("start",d);a(c.appendTo).append(this.helper);this.helper.css({"z-index":100,position:"absolute",left:d.clientX,top:d.clientY,width:0,height:0});if(c.autoRefresh){this.refresh()}this.selectees.filter(".ui-selected").each(function(){var e=a.data(this,"selectable-item");e.startselected=true;if(!d.metaKey){e.$element.removeClass("ui-selected");e.selected=false;e.$element.addClass("ui-unselecting");e.unselecting=true;b._trigger("unselecting",d,{unselecting:e.element})}});a(d.target).parents().andSelf().each(function(){var e=a.data(this,"selectable-item");if(e){e.$element.removeClass("ui-unselecting").addClass("ui-selecting");e.unselecting=false;e.selecting=true;e.selected=true;b._trigger("selecting",d,{selecting:e.element});return false}})},_mouseDrag:function(i){var c=this;this.dragged=true;if(this.options.disabled){return}var e=this.options;var d=this.opos[0],h=this.opos[1],b=i.pageX,g=i.pageY;if(d>b){var f=b;b=d;d=f}if(h>g){var f=g;g=h;h=f}this.helper.css({left:d,top:h,width:b-d,height:g-h});this.selectees.each(function(){var j=a.data(this,"selectable-item");if(!j||j.element==c.element[0]){return}var k=false;if(e.tolerance=="touch"){k=(!(j.left>b||j.right<d||j.top>g||j.bottom<h))}else{if(e.tolerance=="fit"){k=(j.left>d&&j.right<b&&j.top>h&&j.bottom<g)}}if(k){if(j.selected){j.$element.removeClass("ui-selected");j.selected=false}if(j.unselecting){j.$element.removeClass("ui-unselecting");j.unselecting=false}if(!j.selecting){j.$element.addClass("ui-selecting");j.selecting=true;c._trigger("selecting",i,{selecting:j.element})}}else{if(j.selecting){if(i.metaKey&&j.startselected){j.$element.removeClass("ui-selecting");j.selecting=false;j.$element.addClass("ui-selected");j.selected=true}else{j.$element.removeClass("ui-selecting");j.selecting=false;if(j.startselected){j.$element.addClass("ui-unselecting");j.unselecting=true}c._trigger("unselecting",i,{unselecting:j.element})}}if(j.selected){if(!i.metaKey&&!j.startselected){j.$element.removeClass("ui-selected");j.selected=false;j.$element.addClass("ui-unselecting");j.unselecting=true;c._trigger("unselecting",i,{unselecting:j.element})}}}});return false},_mouseStop:function(d){var b=this;this.dragged=false;var c=this.options;a(".ui-unselecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-unselecting");e.unselecting=false;e.startselected=false;b._trigger("unselected",d,{unselected:e.element})});a(".ui-selecting",this.element[0]).each(function(){var e=a.data(this,"selectable-item");e.$element.removeClass("ui-selecting").addClass("ui-selected");e.selecting=false;e.selected=true;e.startselected=true;b._trigger("selected",d,{selected:e.element})});this._trigger("stop",d);this.helper.remove();return false}}));a.extend(a.ui.selectable,{version:"1.7.2",defaults:{appendTo:"body",autoRefresh:true,cancel:":input,option",delay:0,distance:0,filter:"*",tolerance:"touch"}})})(jQuery);;/*
+ * jQuery UI Sortable 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Sortables
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function(a){a.widget("ui.sortable",a.extend({},a.ui.mouse,{_init:function(){var b=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?(/left|right/).test(this.items[0].item.css("float")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--){this.items[b].item.removeData("sortable-item")}},_mouseCapture:function(e,f){if(this.reverting){return false}if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems(e);var d=null,c=this,b=a(e.target).parents().each(function(){if(a.data(this,"sortable-item")==c){d=a(this);return false}});if(a.data(e.target,"sortable-item")==c){d=a(e.target)}if(!d){return false}if(this.options.handle&&!f){var g=false;a(this.options.handle,d).find("*").andSelf().each(function(){if(this==e.target){g=true}});if(!g){return false}}this.currentItem=d;this._removeCurrentsFromItems();return true},_mouseStart:function(e,f,b){var g=this.options,c=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(e);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(e);this.originalPageX=e.pageX;this.originalPageY=e.pageY;if(g.cursorAt){this._adjustOffsetFromHelper(g.cursorAt)}this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide()}this._createPlaceholder();if(g.containment){this._setContainment()}if(g.cursor){if(a("body").css("cursor")){this._storedCursor=a("body").css("cursor")}a("body").css("cursor",g.cursor)}if(g.opacity){if(this.helper.css("opacity")){this._storedOpacity=this.helper.css("opacity")}this.helper.css("opacity",g.opacity)}if(g.zIndex){if(this.helper.css("zIndex")){this._storedZIndex=this.helper.css("zIndex")}this.helper.css("zIndex",g.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){this.overflowOffset=this.scrollParent.offset()}this._trigger("start",e,this._uiHash());if(!this._preserveHelperProportions){this._cacheHelperProportions()}if(!b){for(var d=this.containers.length-1;d>=0;d--){this.containers[d]._trigger("activate",e,c._uiHash(this))}}if(a.ui.ddmanager){a.ui.ddmanager.current=this}if(a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,e)}this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(e);return true},_mouseDrag:function(f){this.position=this._generatePosition(f);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs}if(this.options.scroll){var g=this.options,b=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if((this.overflowOffset.top+this.scrollParent[0].offsetHeight)-f.pageY<g.scrollSensitivity){this.scrollParent[0].scrollTop=b=this.scrollParent[0].scrollTop+g.scrollSpeed}else{if(f.pageY-this.overflowOffset.top<g.scrollSensitivity){this.scrollParent[0].scrollTop=b=this.scrollParent[0].scrollTop-g.scrollSpeed}}if((this.overflowOffset.left+this.scrollParent[0].offsetWidth)-f.pageX<g.scrollSensitivity){this.scrollParent[0].scrollLeft=b=this.scrollParent[0].scrollLeft+g.scrollSpeed}else{if(f.pageX-this.overflowOffset.left<g.scrollSensitivity){this.scrollParent[0].scrollLeft=b=this.scrollParent[0].scrollLeft-g.scrollSpeed}}}else{if(f.pageY-a(document).scrollTop()<g.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()-g.scrollSpeed)}else{if(a(window).height()-(f.pageY-a(document).scrollTop())<g.scrollSensitivity){b=a(document).scrollTop(a(document).scrollTop()+g.scrollSpeed)}}if(f.pageX-a(document).scrollLeft()<g.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()-g.scrollSpeed)}else{if(a(window).width()-(f.pageX-a(document).scrollLeft())<g.scrollSensitivity){b=a(document).scrollLeft(a(document).scrollLeft()+g.scrollSpeed)}}}if(b!==false&&a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,f)}}this.positionAbs=this._convertPositionTo("absolute");if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}for(var d=this.items.length-1;d>=0;d--){var e=this.items[d],c=e.item[0],h=this._intersectsWithPointer(e);if(!h){continue}if(c!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=c&&!a.ui.contains(this.placeholder[0],c)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],c):true)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e)){this._rearrange(f,e)}else{break}this._trigger("change",f,this._uiHash());break}}this._contactContainers(f);if(a.ui.ddmanager){a.ui.ddmanager.drag(this,f)}this._trigger("sort",f,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(c,d){if(!c){return}if(a.ui.ddmanager&&!this.options.dropBehaviour){a.ui.ddmanager.drop(this,c)}if(this.options.revert){var b=this;var e=b.placeholder.offset();b.reverting=true;a(this.helper).animate({left:e.left-this.offset.parent.left-b.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-b.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){b._clear(c)})}else{this._clear(c,d)}return false},cancel:function(){var b=this;if(this.dragging){this._mouseUp();if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,b._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,b._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder[0].parentNode){this.placeholder[0].parentNode.removeChild(this.placeholder[0])}if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode){this.helper.remove()}a.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){a(this.domPosition.prev).after(this.currentItem)}else{a(this.domPosition.parent).prepend(this.currentItem)}return true},serialize:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};a(b).each(function(){var e=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||(/(.+)[-=_](.+)/));if(e){c.push((d.key||e[1]+"[]")+"="+(d.key&&d.expression?e[1]:e[2]))}});return c.join("&")},toArray:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};b.each(function(){c.push(a(d.item||this).attr(d.attribute||"id")||"")});return c},_intersectsWith:function(m){var e=this.positionAbs.left,d=e+this.helperProportions.width,k=this.positionAbs.top,j=k+this.helperProportions.height;var f=m.left,c=f+m.width,n=m.top,i=n+m.height;var o=this.offset.click.top,h=this.offset.click.left;var g=(k+o)>n&&(k+o)<i&&(e+h)>f&&(e+h)<c;if(this.options.tolerance=="pointer"||this.options.forcePointerForContainers||(this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>m[this.floating?"width":"height"])){return g}else{return(f<e+(this.helperProportions.width/2)&&d-(this.helperProportions.width/2)<c&&n<k+(this.helperProportions.height/2)&&j-(this.helperProportions.height/2)<i)}},_intersectsWithPointer:function(d){var e=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,d.top,d.height),c=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,d.left,d.width),g=e&&c,b=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();if(!g){return false}return this.floating?(((f&&f=="right")||b=="down")?2:1):(b&&(b=="down"?2:1))},_intersectsWithSides:function(e){var c=a.ui.isOverAxis(this.positionAbs.top+this.offset.click.top,e.top+(e.height/2),e.height),d=a.ui.isOverAxis(this.positionAbs.left+this.offset.click.left,e.left+(e.width/2),e.width),b=this._getDragVerticalDirection(),f=this._getDragHorizontalDirection();if(this.floating&&f){return((f=="right"&&d)||(f=="left"&&!d))}else{return b&&((b=="down"&&c)||(b=="up"&&!c))}},_getDragVerticalDirection:function(){var b=this.positionAbs.top-this.lastPositionAbs.top;return b!=0&&(b>0?"down":"up")},_getDragHorizontalDirection:function(){var b=this.positionAbs.left-this.lastPositionAbs.left;return b!=0&&(b>0?"right":"left")},refresh:function(b){this._refreshItems(b);this.refreshPositions()},_connectWith:function(){var b=this.options;return b.connectWith.constructor==String?[b.connectWith]:b.connectWith},_getItemsAsjQuery:function(b){var l=this;var g=[];var e=[];var h=this._connectWith();if(h&&b){for(var d=h.length-1;d>=0;d--){var k=a(h[d]);for(var c=k.length-1;c>=0;c--){var f=a.data(k[c],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element):a(f.options.items,f.element).not(".ui-sortable-helper"),f])}}}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper"),this]);for(var d=e.length-1;d>=0;d--){e[d][0].each(function(){g.push(this)})}return a(g)},_removeCurrentsFromItems:function(){var d=this.currentItem.find(":data(sortable-item)");for(var c=0;c<this.items.length;c++){for(var b=0;b<d.length;b++){if(d[b]==this.items[c].item[0]){this.items.splice(c,1)}}}},_refreshItems:function(b){this.items=[];this.containers=[this];var h=this.items;var p=this;var f=[[a.isFunction(this.options.items)?this.options.items.call(this.element[0],b,{item:this.currentItem}):a(this.options.items,this.element),this]];var l=this._connectWith();if(l){for(var e=l.length-1;e>=0;e--){var m=a(l[e]);for(var d=m.length-1;d>=0;d--){var g=a.data(m[d],"sortable");if(g&&g!=this&&!g.options.disabled){f.push([a.isFunction(g.options.items)?g.options.items.call(g.element[0],b,{item:this.currentItem}):a(g.options.items,g.element),g]);this.containers.push(g)}}}}for(var e=f.length-1;e>=0;e--){var k=f[e][1];var c=f[e][0];for(var d=0,n=c.length;d<n;d++){var o=a(c[d]);o.data("sortable-item",k);h.push({item:o,instance:k,width:0,height:0,left:0,top:0})}}},refreshPositions:function(b){if(this.offsetParent&&this.helper){this.offset.parent=this._getParentOffset()}for(var d=this.items.length-1;d>=0;d--){var e=this.items[d];if(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0]){continue}var c=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!b){e.width=c.outerWidth();e.height=c.outerHeight()}var f=c.offset();e.left=f.left;e.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var d=this.containers.length-1;d>=0;d--){var f=this.containers[d].element.offset();this.containers[d].containerCache.left=f.left;this.containers[d].containerCache.top=f.top;this.containers[d].containerCache.width=this.containers[d].element.outerWidth();this.containers[d].containerCache.height=this.containers[d].element.outerHeight()}}},_createPlaceholder:function(d){var b=d||this,e=b.options;if(!e.placeholder||e.placeholder.constructor==String){var c=e.placeholder;e.placeholder={element:function(){var f=a(document.createElement(b.currentItem[0].nodeName)).addClass(c||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!c){f.style.visibility="hidden"}return f},update:function(f,g){if(c&&!e.forcePlaceholderSize){return}if(!g.height()){g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10))}if(!g.width()){g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=a(e.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);e.placeholder.update(b,b.placeholder)},_contactContainers:function(d){for(var c=this.containers.length-1;c>=0;c--){if(this._intersectsWith(this.containers[c].containerCache)){if(!this.containers[c].containerCache.over){if(this.currentContainer!=this.containers[c]){var h=10000;var g=null;var e=this.positionAbs[this.containers[c].floating?"left":"top"];for(var b=this.items.length-1;b>=0;b--){if(!a.ui.contains(this.containers[c].element[0],this.items[b].item[0])){continue}var f=this.items[b][this.containers[c].floating?"left":"top"];if(Math.abs(f-e)<h){h=Math.abs(f-e);g=this.items[b]}}if(!g&&!this.options.dropOnEmpty){continue}this.currentContainer=this.containers[c];g?this._rearrange(d,g,null,true):this._rearrange(d,null,this.containers[c].element,true);this._trigger("change",d,this._uiHash());this.containers[c]._trigger("change",d,this._uiHash(this));this.options.placeholder.update(this.currentContainer,this.placeholder)}this.containers[c]._trigger("over",d,this._uiHash(this));this.containers[c].containerCache.over=1}}else{if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",d,this._uiHash(this));this.containers[c].containerCache.over=0}}}},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c,this.currentItem])):(d.helper=="clone"?this.currentItem.clone():this.currentItem);if(!b.parents("body").length){a(d.appendTo!="parent"?d.appendTo:this.currentItem[0].parentNode)[0].appendChild(b[0])}if(b[0]==this.currentItem[0]){this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}}if(b[0].style.width==""||d.forceHelperSize){b.width(this.currentItem.width())}if(b[0].style.height==""||d.forceHelperSize){b.height(this.currentItem.height())}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.currentItem.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.currentItem.css("marginLeft"),10)||0),top:(parseInt(this.currentItem.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)){var c=a(e.containment)[0];var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.left<this.containment[0]){d=this.containment[0]+this.offset.click.left}if(e.pageY-this.offset.click.top<this.containment[1]){c=this.containment[1]+this.offset.click.top}if(e.pageX-this.offset.click.left>this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.top<this.containment[1]||g-this.offset.click.top>this.containment[3])?g:(!(g-this.offset.click.top<this.containment[1])?g-h.grid[1]:g+h.grid[1])):g;var f=this.originalPageX+Math.round((d-this.originalPageX)/h.grid[0])*h.grid[0];d=this.containment?(!(f-this.offset.click.left<this.containment[0]||f-this.offset.click.left>this.containment[2])?f:(!(f-this.offset.click.left<this.containment[0])?f-h.grid[0]:f+h.grid[0])):f}}return{top:(c-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(i?0:b.scrollTop())))),left:(d-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():i?0:b.scrollLeft())))}},_rearrange:function(g,f,c,e){c?c[0].appendChild(this.placeholder[0]):f.item[0].parentNode.insertBefore(this.placeholder[0],(this.direction=="down"?f.item[0]:f.item[0].nextSibling));this.counter=this.counter?++this.counter:1;var d=this,b=this.counter;window.setTimeout(function(){if(b==d.counter){d.refreshPositions(!e)}},0)},_clear:function(d,e){this.reverting=false;var f=[],b=this;if(!this._noFinalSort&&this.currentItem[0].parentNode){this.placeholder.before(this.currentItem)}this._noFinalSort=null;if(this.helper[0]==this.currentItem[0]){for(var c in this._storedCSS){if(this._storedCSS[c]=="auto"||this._storedCSS[c]=="static"){this._storedCSS[c]=""}}this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}if(this.fromOutside&&!e){f.push(function(g){this._trigger("receive",g,this._uiHash(this.fromOutside))})}if((this.fromOutside||this.domPosition.prev!=this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!=this.currentItem.parent()[0])&&!e){f.push(function(g){this._trigger("update",g,this._uiHash())})}if(!a.ui.contains(this.element[0],this.currentItem[0])){if(!e){f.push(function(g){this._trigger("remove",g,this._uiHash())})}for(var c=this.containers.length-1;c>=0;c--){if(a.ui.contains(this.containers[c].element[0],this.currentItem[0])&&!e){f.push((function(g){return function(h){g._trigger("receive",h,this._uiHash(this))}}).call(this,this.containers[c]));f.push((function(g){return function(h){g._trigger("update",h,this._uiHash(this))}}).call(this,this.containers[c]))}}}for(var c=this.containers.length-1;c>=0;c--){if(!e){f.push((function(g){return function(h){g._trigger("deactivate",h,this._uiHash(this))}}).call(this,this.containers[c]))}if(this.containers[c].containerCache.over){f.push((function(g){return function(h){g._trigger("out",h,this._uiHash(this))}}).call(this,this.containers[c]));this.containers[c].containerCache.over=0}}if(this._storedCursor){a("body").css("cursor",this._storedCursor)}if(this._storedOpacity){this.helper.css("opacity",this._storedOpacity)}if(this._storedZIndex){this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex)}this.dragging=false;if(this.cancelHelperRemoval){if(!e){this._trigger("beforeStop",d,this._uiHash());for(var c=0;c<f.length;c++){f[c].call(this,d)}this._trigger("stop",d,this._uiHash())}return false}if(!e){this._trigger("beforeStop",d,this._uiHash())}this.placeholder[0].parentNode.removeChild(this.placeholder[0]);if(this.helper[0]!=this.currentItem[0]){this.helper.remove()}this.helper=null;if(!e){for(var c=0;c<f.length;c++){f[c].call(this,d)}this._trigger("stop",d,this._uiHash())}this.fromOutside=false;return true},_trigger:function(){if(a.widget.prototype._trigger.apply(this,arguments)===false){this.cancel()}},_uiHash:function(c){var b=c||this;return{helper:b.helper,placeholder:b.placeholder||a([]),position:b.position,absolutePosition:b.positionAbs,offset:b.positionAbs,item:b.currentItem,sender:c?c.element:null}}}));a.extend(a.ui.sortable,{getter:"serialize toArray",version:"1.7.2",eventPrefix:"sort",defaults:{appendTo:"parent",axis:false,cancel:":input,option",connectWith:false,containment:false,cursor:"auto",cursorAt:false,delay:0,distance:1,dropOnEmpty:true,forcePlaceholderSize:false,forceHelperSize:false,grid:false,handle:false,helper:"original",items:"> *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1000}})})(jQuery);;/*
+ * jQuery UI Accordion 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Accordion
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function(a){a.widget("ui.accordion",{_init:function(){var d=this.options,b=this;this.running=0;if(d.collapsible==a.ui.accordion.defaults.collapsible&&d.alwaysOpen!=a.ui.accordion.defaults.alwaysOpen){d.collapsible=!d.alwaysOpen}if(d.navigation){var c=this.element.find("a").filter(d.navigationFilter);if(c.length){if(c.filter(d.header).length){this.active=c}else{this.active=c.parent().parent().prev();c.addClass("ui-accordion-content-active")}}}this.element.addClass("ui-accordion ui-widget ui-helper-reset");if(this.element[0].nodeName=="UL"){this.element.children("li").addClass("ui-accordion-li-fix")}this.headers=this.element.find(d.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){a(this).removeClass("ui-state-focus")});this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");this.active=this._findActive(this.active||d.active).toggleClass("ui-state-default").toggleClass("ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");this.active.next().addClass("ui-accordion-content-active");a("<span/>").addClass("ui-icon "+d.icons.header).prependTo(this.headers);this.active.find(".ui-icon").toggleClass(d.icons.header).toggleClass(d.icons.headerSelected);if(a.browser.msie){this.element.find("a").css("zoom","1")}this.resize();this.element.attr("role","tablist");this.headers.attr("role","tab").bind("keydown",function(e){return b._keydown(e)}).next().attr("role","tabpanel");this.headers.not(this.active||"").attr("aria-expanded","false").attr("tabIndex","-1").next().hide();if(!this.active.length){this.headers.eq(0).attr("tabIndex","0")}else{this.active.attr("aria-expanded","true").attr("tabIndex","0")}if(!a.browser.safari){this.headers.find("a").attr("tabIndex","-1")}if(d.event){this.headers.bind((d.event)+".accordion",function(e){return b._clickHandler.call(b,e,this)})}},destroy:function(){var c=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role").unbind(".accordion").removeData("accordion");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("tabindex");this.headers.find("a").removeAttr("tabindex");this.headers.children(".ui-icon").remove();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active");if(c.autoHeight||c.fillHeight){b.css("height","")}},_setData:function(b,c){if(b=="alwaysOpen"){b="collapsible";c=!c}a.widget.prototype._setData.apply(this,arguments)},_keydown:function(e){var g=this.options,f=a.ui.keyCode;if(g.disabled||e.altKey||e.ctrlKey){return}var d=this.headers.length;var b=this.headers.index(e.target);var c=false;switch(e.keyCode){case f.RIGHT:case f.DOWN:c=this.headers[(b+1)%d];break;case f.LEFT:case f.UP:c=this.headers[(b-1+d)%d];break;case f.SPACE:case f.ENTER:return this._clickHandler({target:e.target},e.target)}if(c){a(e.target).attr("tabIndex","-1");a(c).attr("tabIndex","0");c.focus();return false}return true},resize:function(){var e=this.options,d;if(e.fillSpace){if(a.browser.msie){var b=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}d=this.element.parent().height();if(a.browser.msie){this.element.parent().css("overflow",b)}this.headers.each(function(){d-=a(this).outerHeight()});var c=0;this.headers.next().each(function(){c=Math.max(c,a(this).innerHeight()-a(this).height())}).height(Math.max(0,d-c)).css("overflow","auto")}else{if(e.autoHeight){d=0;this.headers.next().each(function(){d=Math.max(d,a(this).outerHeight())}).height(d)}}},activate:function(b){var c=this._findActive(b)[0];this._clickHandler({target:c},c)},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===false?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,f){var d=this.options;if(d.disabled){return false}if(!b.target&&d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").find(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var h=this.active.next(),e={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:h},c=(this.active=a([]));this._toggle(c,h,e);return false}var g=a(b.currentTarget||f);var i=g[0]==this.active[0];if(this.running||(!d.collapsible&&i)){return false}this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").find(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");if(!i){g.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").find(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);g.next().addClass("ui-accordion-content-active")}var c=g.next(),h=this.active.next(),e={options:d,newHeader:i&&d.collapsible?a([]):g,oldHeader:this.active,newContent:i&&d.collapsible?a([]):c.find("> *"),oldContent:h.find("> *")},j=this.headers.index(this.active[0])>this.headers.index(g[0]);this.active=i?a([]):g;this._toggle(c,h,e,i,j);return false},_toggle:function(b,i,g,j,k){var d=this.options,m=this;this.toShow=b;this.toHide=i;this.data=g;var c=function(){if(!m){return}return m._completed.apply(m,arguments)};this._trigger("changestart",null,this.data);this.running=i.size()===0?b.size():i.size();if(d.animated){var f={};if(d.collapsible&&j){f={toShow:a([]),toHide:i,complete:c,down:k,autoHeight:d.autoHeight||d.fillSpace}}else{f={toShow:b,toHide:i,complete:c,down:k,autoHeight:d.autoHeight||d.fillSpace}}if(!d.proxied){d.proxied=d.animated}if(!d.proxiedDuration){d.proxiedDuration=d.duration}d.animated=a.isFunction(d.proxied)?d.proxied(f):d.proxied;d.duration=a.isFunction(d.proxiedDuration)?d.proxiedDuration(f):d.proxiedDuration;var l=a.ui.accordion.animations,e=d.duration,h=d.animated;if(!l[h]){l[h]=function(n){this.slide(n,{easing:h,duration:e||700})}}l[h](f)}else{if(d.collapsible&&j){b.toggle()}else{i.hide();b.show()}c(true)}i.prev().attr("aria-expanded","false").attr("tabIndex","-1").blur();b.prev().attr("aria-expanded","true").attr("tabIndex","0").focus()},_completed:function(b){var c=this.options;this.running=b?0:--this.running;if(this.running){return}if(c.clearStyle){this.toShow.add(this.toHide).css({height:"",overflow:""})}this._trigger("change",null,this.data)}});a.extend(a.ui.accordion,{version:"1.7.2",defaults:{active:null,alwaysOpen:true,animated:"slide",autoHeight:true,clearStyle:false,collapsible:false,event:"click",fillSpace:false,header:"> li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()==location.href.toLowerCase()}},animations:{slide:function(j,h){j=a.extend({easing:"swing",duration:300},j,h);if(!j.toHide.size()){j.toShow.animate({height:"show"},j);return}if(!j.toShow.size()){j.toHide.animate({height:"hide"},j);return}var c=j.toShow.css("overflow"),g,d={},f={},e=["height","paddingTop","paddingBottom"],b;var i=j.toShow;b=i[0].style.width;i.width(parseInt(i.parent().width(),10)-parseInt(i.css("paddingLeft"),10)-parseInt(i.css("paddingRight"),10)-(parseInt(i.css("borderLeftWidth"),10)||0)-(parseInt(i.css("borderRightWidth"),10)||0));a.each(e,function(k,m){f[m]="hide";var l=(""+a.css(j.toShow[0],m)).match(/^([\d+-.]+)(.*)$/);d[m]={value:l[1],unit:l[2]||"px"}});j.toShow.css({height:0,overflow:"hidden"}).show();j.toHide.filter(":hidden").each(j.complete).end().filter(":visible").animate(f,{step:function(k,l){if(l.prop=="height"){g=(l.now-l.start)/(l.end-l.start)}j.toShow[0].style[l.prop]=(g*d[l.prop].value)+d[l.prop].unit},duration:j.duration,easing:j.easing,complete:function(){if(!j.autoHeight){j.toShow.css("height","")}j.toShow.css("width",b);j.toShow.css({overflow:c});j.complete()}})},bounceslide:function(b){this.slide(b,{easing:b.down?"easeOutBounce":"swing",duration:b.down?1000:200})},easeslide:function(b){this.slide(b,{easing:"easeinout",duration:700})}}})})(jQuery);;/*
+ * jQuery UI Dialog 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Dialog
+ *
+ * Depends:
+ * ui.core.js
+ * ui.draggable.js
+ * ui.resizable.js
+ */
+(function(c){var b={dragStart:"start.draggable",drag:"drag.draggable",dragStop:"stop.draggable",maxHeight:"maxHeight.resizable",minHeight:"minHeight.resizable",maxWidth:"maxWidth.resizable",minWidth:"minWidth.resizable",resizeStart:"start.resizable",resize:"drag.resizable",resizeStop:"stop.resizable"},a="ui-dialog ui-widget ui-widget-content ui-corner-all ";c.widget("ui.dialog",{_init:function(){this.originalTitle=this.element.attr("title");var l=this,m=this.options,j=m.title||this.originalTitle||"&nbsp;",e=c.ui.dialog.getTitleId(this.element),k=(this.uiDialog=c("<div/>")).appendTo(document.body).hide().addClass(a+m.dialogClass).css({position:"absolute",overflow:"hidden",zIndex:m.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(n){(m.closeOnEscape&&n.keyCode&&n.keyCode==c.ui.keyCode.ESCAPE&&l.close(n))}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(n){l.moveToTop(false,n)}),g=this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(k),f=(this.uiDialogTitlebar=c("<div></div>")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(k),i=c('<a href="#"/>').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){i.addClass("ui-state-hover")},function(){i.removeClass("ui-state-hover")}).focus(function(){i.addClass("ui-state-focus")}).blur(function(){i.removeClass("ui-state-focus")}).mousedown(function(n){n.stopPropagation()}).click(function(n){l.close(n);return false}).appendTo(f),h=(this.uiDialogTitlebarCloseText=c("<span/>")).addClass("ui-icon ui-icon-closethick").text(m.closeText).appendTo(i),d=c("<span/>").addClass("ui-dialog-title").attr("id",e).html(j).prependTo(f);f.find("*").add(f).disableSelection();(m.draggable&&c.fn.draggable&&this._makeDraggable());(m.resizable&&c.fn.resizable&&this._makeResizable());this._createButtons(m.buttons);this._isOpen=false;(m.bgiframe&&c.fn.bgiframe&&k.bgiframe());(m.autoOpen&&this.open())},destroy:function(){(this.overlay&&this.overlay.destroy());this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");this.uiDialog.remove();(this.originalTitle&&this.element.attr("title",this.originalTitle))},close:function(f){var d=this;if(false===d._trigger("beforeclose",f)){return}(d.overlay&&d.overlay.destroy());d.uiDialog.unbind("keypress.ui-dialog");(d.options.hide?d.uiDialog.hide(d.options.hide,function(){d._trigger("close",f)}):d.uiDialog.hide()&&d._trigger("close",f));c.ui.dialog.overlay.resize();d._isOpen=false;if(d.options.modal){var e=0;c(".ui-dialog").each(function(){if(this!=d.uiDialog[0]){e=Math.max(e,c(this).css("z-index"))}});c.ui.dialog.maxZ=e}},isOpen:function(){return this._isOpen},moveToTop:function(f,e){if((this.options.modal&&!f)||(!this.options.stack&&!this.options.modal)){return this._trigger("focus",e)}if(this.options.zIndex>c.ui.dialog.maxZ){c.ui.dialog.maxZ=this.options.zIndex}(this.overlay&&this.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=++c.ui.dialog.maxZ));var d={scrollTop:this.element.attr("scrollTop"),scrollLeft:this.element.attr("scrollLeft")};this.uiDialog.css("z-index",++c.ui.dialog.maxZ);this.element.attr(d);this._trigger("focus",e)},open:function(){if(this._isOpen){return}var e=this.options,d=this.uiDialog;this.overlay=e.modal?new c.ui.dialog.overlay(this):null;(d.next().length&&d.appendTo("body"));this._size();this._position(e.position);d.show(e.show);this.moveToTop(true);(e.modal&&d.bind("keypress.ui-dialog",function(h){if(h.keyCode!=c.ui.keyCode.TAB){return}var g=c(":tabbable",this),i=g.filter(":first")[0],f=g.filter(":last")[0];if(h.target==f&&!h.shiftKey){setTimeout(function(){i.focus()},1)}else{if(h.target==i&&h.shiftKey){setTimeout(function(){f.focus()},1)}}}));c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();this._trigger("open");this._isOpen=true},_createButtons:function(g){var f=this,d=false,e=c("<div></div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");this.uiDialog.find(".ui-dialog-buttonpane").remove();(typeof g=="object"&&g!==null&&c.each(g,function(){return !(d=true)}));if(d){c.each(g,function(h,i){c('<button type="button"></button>').addClass("ui-state-default ui-corner-all").text(h).click(function(){i.apply(f.element[0],arguments)}).hover(function(){c(this).addClass("ui-state-hover")},function(){c(this).removeClass("ui-state-hover")}).focus(function(){c(this).addClass("ui-state-focus")}).blur(function(){c(this).removeClass("ui-state-focus")}).appendTo(e)});e.appendTo(this.uiDialog)}},_makeDraggable:function(){var d=this,f=this.options,e;this.uiDialog.draggable({cancel:".ui-dialog-content",handle:".ui-dialog-titlebar",containment:"document",start:function(){e=f.height;c(this).height(c(this).height()).addClass("ui-dialog-dragging");(f.dragStart&&f.dragStart.apply(d.element[0],arguments))},drag:function(){(f.drag&&f.drag.apply(d.element[0],arguments))},stop:function(){c(this).removeClass("ui-dialog-dragging").height(e);(f.dragStop&&f.dragStop.apply(d.element[0],arguments));c.ui.dialog.overlay.resize()}})},_makeResizable:function(g){g=(g===undefined?this.options.resizable:g);var d=this,f=this.options,e=typeof g=="string"?g:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",alsoResize:this.element,maxWidth:f.maxWidth,maxHeight:f.maxHeight,minWidth:f.minWidth,minHeight:f.minHeight,start:function(){c(this).addClass("ui-dialog-resizing");(f.resizeStart&&f.resizeStart.apply(d.element[0],arguments))},resize:function(){(f.resize&&f.resize.apply(d.element[0],arguments))},handles:e,stop:function(){c(this).removeClass("ui-dialog-resizing");f.height=c(this).height();f.width=c(this).width();(f.resizeStop&&f.resizeStop.apply(d.element[0],arguments));c.ui.dialog.overlay.resize()}}).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_position:function(i){var e=c(window),f=c(document),g=f.scrollTop(),d=f.scrollLeft(),h=g;if(c.inArray(i,["center","top","right","bottom","left"])>=0){i=[i=="right"||i=="left"?i:"center",i=="top"||i=="bottom"?i:"middle"]}if(i.constructor!=Array){i=["center","middle"]}if(i[0].constructor==Number){d+=i[0]}else{switch(i[0]){case"left":d+=0;break;case"right":d+=e.width()-this.uiDialog.outerWidth();break;default:case"center":d+=(e.width()-this.uiDialog.outerWidth())/2}}if(i[1].constructor==Number){g+=i[1]}else{switch(i[1]){case"top":g+=0;break;case"bottom":g+=e.height()-this.uiDialog.outerHeight();break;default:case"middle":g+=(e.height()-this.uiDialog.outerHeight())/2}}g=Math.max(g,h);this.uiDialog.css({top:g,left:d})},_setData:function(e,f){(b[e]&&this.uiDialog.data(b[e],f));switch(e){case"buttons":this._createButtons(f);break;case"closeText":this.uiDialogTitlebarCloseText.text(f);break;case"dialogClass":this.uiDialog.removeClass(this.options.dialogClass).addClass(a+f);break;case"draggable":(f?this._makeDraggable():this.uiDialog.draggable("destroy"));break;case"height":this.uiDialog.height(f);break;case"position":this._position(f);break;case"resizable":var d=this.uiDialog,g=this.uiDialog.is(":data(resizable)");(g&&!f&&d.resizable("destroy"));(g&&typeof f=="string"&&d.resizable("option","handles",f));(g||this._makeResizable(f));break;case"title":c(".ui-dialog-title",this.uiDialogTitlebar).html(f||"&nbsp;");break;case"width":this.uiDialog.width(f);break}c.widget.prototype._setData.apply(this,arguments)},_size:function(){var e=this.options;this.element.css({height:0,minHeight:0,width:"auto"});var d=this.uiDialog.css({height:"auto",width:e.width}).height();this.element.css({minHeight:Math.max(e.minHeight-d,0),height:e.height=="auto"?"auto":Math.max(e.height-d,0)})}});c.extend(c.ui.dialog,{version:"1.7.2",defaults:{autoOpen:true,bgiframe:false,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,show:null,stack:true,title:"",width:300,zIndex:1000},getter:"isOpen",uuid:0,maxZ:0,getTitleId:function(d){return"ui-dialog-title-"+(d.attr("id")||++this.uuid)},overlay:function(d){this.$el=c.ui.dialog.overlay.create(d)}});c.extend(c.ui.dialog.overlay,{instances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(d){return d+".dialog-overlay"}).join(" "),create:function(e){if(this.instances.length===0){setTimeout(function(){if(c.ui.dialog.overlay.instances.length){c(document).bind(c.ui.dialog.overlay.events,function(f){var g=c(f.target).parents(".ui-dialog").css("zIndex")||0;return(g>c.ui.dialog.overlay.maxZ)})}},1);c(document).bind("keydown.dialog-overlay",function(f){(e.options.closeOnEscape&&f.keyCode&&f.keyCode==c.ui.keyCode.ESCAPE&&e.close(f))});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var d=c("<div></div>").appendTo(document.body).addClass("ui-widget-overlay").css({width:this.width(),height:this.height()});(e.options.bgiframe&&c.fn.bgiframe&&d.bgiframe());this.instances.push(d);return d},destroy:function(d){this.instances.splice(c.inArray(this.instances,d),1);if(this.instances.length===0){c([document,window]).unbind(".dialog-overlay")}d.remove();var e=0;c.each(this.instances,function(){e=Math.max(e,this.css("z-index"))});this.maxZ=e},height:function(){if(c.browser.msie&&c.browser.version<7){var e=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);var d=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);if(e<d){return c(window).height()+"px"}else{return e+"px"}}else{return c(document).height()+"px"}},width:function(){if(c.browser.msie&&c.browser.version<7){var d=Math.max(document.documentElement.scrollWidth,document.body.scrollWidth);var e=Math.max(document.documentElement.offsetWidth,document.body.offsetWidth);if(d<e){return c(window).width()+"px"}else{return d+"px"}}else{return c(document).width()+"px"}},resize:function(){var d=c([]);c.each(c.ui.dialog.overlay.instances,function(){d=d.add(this)});d.css({width:0,height:0}).css({width:c.ui.dialog.overlay.width(),height:c.ui.dialog.overlay.height()})}});c.extend(c.ui.dialog.overlay.prototype,{destroy:function(){c.ui.dialog.overlay.destroy(this.$el)}})})(jQuery);;/*
+ * jQuery UI Slider 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Slider
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function(a){a.widget("ui.slider",a.extend({},a.ui.mouse,{_init:function(){var b=this,c=this.options;this._keySliding=false;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget ui-widget-content ui-corner-all");this.range=a([]);if(c.range){if(c.range===true){this.range=a("<div></div>");if(!c.values){c.values=[this._valueMin(),this._valueMin()]}if(c.values.length&&c.values.length!=2){c.values=[c.values[0],c.values[0]]}}else{this.range=a("<div></div>")}this.range.appendTo(this.element).addClass("ui-slider-range");if(c.range=="min"||c.range=="max"){this.range.addClass("ui-slider-range-"+c.range)}this.range.addClass("ui-widget-header")}if(a(".ui-slider-handle",this.element).length==0){a('<a href="#"></a>').appendTo(this.element).addClass("ui-slider-handle")}if(c.values&&c.values.length){while(a(".ui-slider-handle",this.element).length<c.values.length){a('<a href="#"></a>').appendTo(this.element).addClass("ui-slider-handle")}}this.handles=a(".ui-slider-handle",this.element).addClass("ui-state-default ui-corner-all");this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(d){d.preventDefault()}).hover(function(){if(!c.disabled){a(this).addClass("ui-state-hover")}},function(){a(this).removeClass("ui-state-hover")}).focus(function(){if(!c.disabled){a(".ui-slider .ui-state-focus").removeClass("ui-state-focus");a(this).addClass("ui-state-focus")}else{a(this).blur()}}).blur(function(){a(this).removeClass("ui-state-focus")});this.handles.each(function(d){a(this).data("index.ui-slider-handle",d)});this.handles.keydown(function(i){var f=true;var e=a(this).data("index.ui-slider-handle");if(b.options.disabled){return}switch(i.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:f=false;if(!b._keySliding){b._keySliding=true;a(this).addClass("ui-state-active");b._start(i,e)}break}var g,d,h=b._step();if(b.options.values&&b.options.values.length){g=d=b.values(e)}else{g=d=b.value()}switch(i.keyCode){case a.ui.keyCode.HOME:d=b._valueMin();break;case a.ui.keyCode.END:d=b._valueMax();break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(g==b._valueMax()){return}d=g+h;break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(g==b._valueMin()){return}d=g-h;break}b._slide(i,e,d);return f}).keyup(function(e){var d=a(this).data("index.ui-slider-handle");if(b._keySliding){b._stop(e,d);b._change(e,d);b._keySliding=false;a(this).removeClass("ui-state-active")}});this._refreshValue()},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy()},_mouseCapture:function(d){var e=this.options;if(e.disabled){return false}this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();var h={x:d.pageX,y:d.pageY};var j=this._normValueFromMouse(h);var c=this._valueMax()-this._valueMin()+1,f;var k=this,i;this.handles.each(function(l){var m=Math.abs(j-k.values(l));if(c>m){c=m;f=a(this);i=l}});if(e.range==true&&this.values(1)==e.min){f=a(this.handles[++i])}this._start(d,i);k._handleIndex=i;f.addClass("ui-state-active").focus();var g=f.offset();var b=!a(d.target).parents().andSelf().is(".ui-slider-handle");this._clickOffset=b?{left:0,top:0}:{left:d.pageX-g.left-(f.width()/2),top:d.pageY-g.top-(f.height()/2)-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};j=this._normValueFromMouse(h);this._slide(d,i,j);return true},_mouseStart:function(b){return true},_mouseDrag:function(d){var b={x:d.pageX,y:d.pageY};var c=this._normValueFromMouse(b);this._slide(d,this._handleIndex,c);return false},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._handleIndex=null;this._clickOffset=null;return false},_detectOrientation:function(){this.orientation=this.options.orientation=="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(d){var c,h;if("horizontal"==this.orientation){c=this.elementSize.width;h=d.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{c=this.elementSize.height;h=d.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}var f=(h/c);if(f>1){f=1}if(f<0){f=0}if("vertical"==this.orientation){f=1-f}var e=this._valueMax()-this._valueMin(),i=f*e,b=i%this.options.step,g=this._valueMin()+i-b;if(b>(this.options.step/2)){g+=this.options.step}return parseFloat(g.toFixed(5))},_start:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("start",d,b)},_slide:function(f,e,d){var g=this.handles[e];if(this.options.values&&this.options.values.length){var b=this.values(e?0:1);if((this.options.values.length==2&&this.options.range===true)&&((e==0&&d>b)||(e==1&&d<b))){d=b}if(d!=this.values(e)){var c=this.values();c[e]=d;var h=this._trigger("slide",f,{handle:this.handles[e],value:d,values:c});var b=this.values(e?0:1);if(h!==false){this.values(e,d,(f.type=="mousedown"&&this.options.animate),true)}}}else{if(d!=this.value()){var h=this._trigger("slide",f,{handle:this.handles[e],value:d});if(h!==false){this._setData("value",d,(f.type=="mousedown"&&this.options.animate))}}}},_stop:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("stop",d,b)},_change:function(d,c){var b={handle:this.handles[c],value:this.value()};if(this.options.values&&this.options.values.length){b.value=this.values(c);b.values=this.values()}this._trigger("change",d,b)},value:function(b){if(arguments.length){this._setData("value",b);this._change(null,0)}return this._value()},values:function(b,e,c,d){if(arguments.length>1){this.options.values[b]=e;this._refreshValue(c);if(!d){this._change(null,b)}}if(arguments.length){if(this.options.values&&this.options.values.length){return this._values(b)}else{return this.value()}}else{return this._values()}},_setData:function(b,d,c){a.widget.prototype._setData.apply(this,arguments);switch(b){case"disabled":if(d){this.handles.filter(".ui-state-focus").blur();this.handles.removeClass("ui-state-hover");this.handles.attr("disabled","disabled")}else{this.handles.removeAttr("disabled")}case"orientation":this._detectOrientation();this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation);this._refreshValue(c);break;case"value":this._refreshValue(c);break}},_step:function(){var b=this.options.step;return b},_value:function(){var b=this.options.value;if(b<this._valueMin()){b=this._valueMin()}if(b>this._valueMax()){b=this._valueMax()}return b},_values:function(b){if(arguments.length){var c=this.options.values[b];if(c<this._valueMin()){c=this._valueMin()}if(c>this._valueMax()){c=this._valueMax()}return c}else{return this.options.values}},_valueMin:function(){var b=this.options.min;return b},_valueMax:function(){var b=this.options.max;return b},_refreshValue:function(c){var f=this.options.range,d=this.options,l=this;if(this.options.values&&this.options.values.length){var i,h;this.handles.each(function(p,n){var o=(l.values(p)-l._valueMin())/(l._valueMax()-l._valueMin())*100;var m={};m[l.orientation=="horizontal"?"left":"bottom"]=o+"%";a(this).stop(1,1)[c?"animate":"css"](m,d.animate);if(l.options.range===true){if(l.orientation=="horizontal"){(p==0)&&l.range.stop(1,1)[c?"animate":"css"]({left:o+"%"},d.animate);(p==1)&&l.range[c?"animate":"css"]({width:(o-lastValPercent)+"%"},{queue:false,duration:d.animate})}else{(p==0)&&l.range.stop(1,1)[c?"animate":"css"]({bottom:(o)+"%"},d.animate);(p==1)&&l.range[c?"animate":"css"]({height:(o-lastValPercent)+"%"},{queue:false,duration:d.animate})}}lastValPercent=o})}else{var j=this.value(),g=this._valueMin(),k=this._valueMax(),e=k!=g?(j-g)/(k-g)*100:0;var b={};b[l.orientation=="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[c?"animate":"css"](b,d.animate);(f=="min")&&(this.orientation=="horizontal")&&this.range.stop(1,1)[c?"animate":"css"]({width:e+"%"},d.animate);(f=="max")&&(this.orientation=="horizontal")&&this.range[c?"animate":"css"]({width:(100-e)+"%"},{queue:false,duration:d.animate});(f=="min")&&(this.orientation=="vertical")&&this.range.stop(1,1)[c?"animate":"css"]({height:e+"%"},d.animate);(f=="max")&&(this.orientation=="vertical")&&this.range[c?"animate":"css"]({height:(100-e)+"%"},{queue:false,duration:d.animate})}}}));a.extend(a.ui.slider,{getter:"value values",version:"1.7.2",eventPrefix:"slide",defaults:{animate:false,delay:0,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null}})})(jQuery);;/*
+ * jQuery UI Tabs 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Tabs
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function(a){a.widget("ui.tabs",{_init:function(){if(this.options.deselectable!==undefined){this.options.collapsible=this.options.deselectable}this._tabify(true)},_setData:function(b,c){if(b=="selected"){if(this.options.collapsible&&c==this.options.selected){return}this.select(c)}else{this.options[b]=c;if(b=="deselectable"){this.options.collapsible=c}this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+a.data(b)},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+a.data(this.list[0]));return a.cookie.apply(null,[b].concat(a.makeArray(arguments)))},_ui:function(c,b){return{tab:c,panel:b,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b=a(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(n){this.list=this.element.children("ul:first");this.lis=a("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);var p=this,d=this.options;var c=/^#.+/;this.anchors.each(function(r,o){var q=a(o).attr("href");var s=q.split("#")[0],u;if(s&&(s===location.toString().split("#")[0]||(u=a("base")[0])&&s===u.href)){q=o.hash;o.href=q}if(c.test(q)){p.panels=p.panels.add(p._sanitizeSelector(q))}else{if(q!="#"){a.data(o,"href.tabs",q);a.data(o,"load.tabs",q.replace(/#.*$/,""));var w=p._tabId(o);o.href="#"+w;var v=a("#"+w);if(!v.length){v=a(d.panelTemplate).attr("id",w).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(p.panels[r-1]||p.list);v.data("destroy.tabs",true)}p.panels=p.panels.add(v)}else{d.disabled.push(r)}}});if(n){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(d.selected===undefined){if(location.hash){this.anchors.each(function(q,o){if(o.hash==location.hash){d.selected=q;return false}})}if(typeof d.selected!="number"&&d.cookie){d.selected=parseInt(p._cookie(),10)}if(typeof d.selected!="number"&&this.lis.filter(".ui-tabs-selected").length){d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}d.selected=d.selected||0}else{if(d.selected===null){d.selected=-1}}d.selected=((d.selected>=0&&this.anchors[d.selected])||d.selected<0)?d.selected:0;d.disabled=a.unique(d.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(q,o){return p.lis.index(q)}))).sort();if(a.inArray(d.selected,d.disabled)!=-1){d.disabled.splice(a.inArray(d.selected,d.disabled),1)}this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active");if(d.selected>=0&&this.anchors.length){this.panels.eq(d.selected).removeClass("ui-tabs-hide");this.lis.eq(d.selected).addClass("ui-tabs-selected ui-state-active");p.element.queue("tabs",function(){p._trigger("show",null,p._ui(p.anchors[d.selected],p.panels[d.selected]))});this.load(d.selected)}a(window).bind("unload",function(){p.lis.add(p.anchors).unbind(".tabs");p.lis=p.anchors=p.panels=null})}else{d.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"))}this.element[d.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");if(d.cookie){this._cookie(d.selected,d.cookie)}for(var g=0,m;(m=this.lis[g]);g++){a(m)[a.inArray(g,d.disabled)!=-1&&!a(m).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled")}if(d.cache===false){this.anchors.removeData("cache.tabs")}this.lis.add(this.anchors).unbind(".tabs");if(d.event!="mouseover"){var f=function(o,i){if(i.is(":not(.ui-state-disabled)")){i.addClass("ui-state-"+o)}};var j=function(o,i){i.removeClass("ui-state-"+o)};this.lis.bind("mouseover.tabs",function(){f("hover",a(this))});this.lis.bind("mouseout.tabs",function(){j("hover",a(this))});this.anchors.bind("focus.tabs",function(){f("focus",a(this).closest("li"))});this.anchors.bind("blur.tabs",function(){j("focus",a(this).closest("li"))})}var b,h;if(d.fx){if(a.isArray(d.fx)){b=d.fx[0];h=d.fx[1]}else{b=h=d.fx}}function e(i,o){i.css({display:""});if(a.browser.msie&&o.opacity){i[0].style.removeAttribute("filter")}}var k=h?function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.hide().removeClass("ui-tabs-hide").animate(h,h.duration||"normal",function(){e(o,h);p._trigger("show",null,p._ui(i,o[0]))})}:function(i,o){a(i).closest("li").removeClass("ui-state-default").addClass("ui-tabs-selected ui-state-active");o.removeClass("ui-tabs-hide");p._trigger("show",null,p._ui(i,o[0]))};var l=b?function(o,i){i.animate(b,b.duration||"normal",function(){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");e(i,b);p.element.dequeue("tabs")})}:function(o,i,q){p.lis.removeClass("ui-tabs-selected ui-state-active").addClass("ui-state-default");i.addClass("ui-tabs-hide");p.element.dequeue("tabs")};this.anchors.bind(d.event+".tabs",function(){var o=this,r=a(this).closest("li"),i=p.panels.filter(":not(.ui-tabs-hide)"),q=a(p._sanitizeSelector(this.hash));if((r.hasClass("ui-tabs-selected")&&!d.collapsible)||r.hasClass("ui-state-disabled")||r.hasClass("ui-state-processing")||p._trigger("select",null,p._ui(this,q[0]))===false){this.blur();return false}d.selected=p.anchors.index(this);p.abort();if(d.collapsible){if(r.hasClass("ui-tabs-selected")){d.selected=-1;if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){l(o,i)}).dequeue("tabs");this.blur();return false}else{if(!i.length){if(d.cookie){p._cookie(d.selected,d.cookie)}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this));this.blur();return false}}}if(d.cookie){p._cookie(d.selected,d.cookie)}if(q.length){if(i.length){p.element.queue("tabs",function(){l(o,i)})}p.element.queue("tabs",function(){k(o,q)});p.load(p.anchors.index(this))}else{throw"jQuery UI Tabs: Mismatching fragment identifier."}if(a.browser.msie){this.blur()}});this.anchors.bind("click.tabs",function(){return false})},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var c=a.data(this,"href.tabs");if(c){this.href=c}var d=a(this).unbind(".tabs");a.each(["href","load","cache"],function(e,f){d.removeData(f+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){if(a.data(this,"destroy.tabs")){a(this).remove()}else{a(this).removeClass(["ui-state-default","ui-corner-top","ui-tabs-selected","ui-state-active","ui-state-hover","ui-state-focus","ui-state-disabled","ui-tabs-panel","ui-widget-content","ui-corner-bottom","ui-tabs-hide"].join(" "))}});if(b.cookie){this._cookie(null,b.cookie)}},add:function(e,d,c){if(c===undefined){c=this.anchors.length}var b=this,g=this.options,i=a(g.tabTemplate.replace(/#\{href\}/g,e).replace(/#\{label\}/g,d)),h=!e.indexOf("#")?e.replace("#",""):this._tabId(a("a",i)[0]);i.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var f=a("#"+h);if(!f.length){f=a(g.panelTemplate).attr("id",h).data("destroy.tabs",true)}f.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(c>=this.lis.length){i.appendTo(this.list);f.appendTo(this.list[0].parentNode)}else{i.insertBefore(this.lis[c]);f.insertBefore(this.panels[c])}g.disabled=a.map(g.disabled,function(k,j){return k>=c?++k:k});this._tabify();if(this.anchors.length==1){i.addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[0],b.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[c],this.panels[c]))},remove:function(b){var d=this.options,e=this.lis.eq(b).remove(),c=this.panels.eq(b).remove();if(e.hasClass("ui-tabs-selected")&&this.anchors.length>1){this.select(b+(b+1<this.anchors.length?1:-1))}d.disabled=a.map(a.grep(d.disabled,function(g,f){return g!=b}),function(g,f){return g>=b?--g:g});this._tabify();this._trigger("remove",null,this._ui(e.find("a")[0],c[0]))},enable:function(b){var c=this.options;if(a.inArray(b,c.disabled)==-1){return}this.lis.eq(b).removeClass("ui-state-disabled");c.disabled=a.grep(c.disabled,function(e,d){return e!=b});this._trigger("enable",null,this._ui(this.anchors[b],this.panels[b]))},disable:function(c){var b=this,d=this.options;if(c!=d.selected){this.lis.eq(c).addClass("ui-state-disabled");d.disabled.push(c);d.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[c],this.panels[c]))}},select:function(b){if(typeof b=="string"){b=this.anchors.index(this.anchors.filter("[href$="+b+"]"))}else{if(b===null){b=-1}}if(b==-1&&this.options.collapsible){b=this.options.selected}this.anchors.eq(b).trigger(this.options.event+".tabs")},load:function(e){var c=this,g=this.options,b=this.anchors.eq(e)[0],d=a.data(b,"load.tabs");this.abort();if(!d||this.element.queue("tabs").length!==0&&a.data(b,"cache.tabs")){this.element.dequeue("tabs");return}this.lis.eq(e).addClass("ui-state-processing");if(g.spinner){var f=a("span",b);f.data("label.tabs",f.html()).html(g.spinner)}this.xhr=a.ajax(a.extend({},g.ajaxOptions,{url:d,success:function(i,h){a(c._sanitizeSelector(b.hash)).html(i);c._cleanup();if(g.cache){a.data(b,"cache.tabs",true)}c._trigger("load",null,c._ui(c.anchors[e],c.panels[e]));try{g.ajaxOptions.success(i,h)}catch(j){}c.element.dequeue("tabs")}}))},abort:function(){this.element.queue([]);this.panels.stop(false,true);if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup()},url:function(c,b){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",b)},length:function(){return this.anchors.length}});a.extend(a.ui.tabs,{version:"1.7.2",getter:"length",defaults:{ajaxOptions:null,cache:false,cookie:null,collapsible:false,disabled:[],event:"click",fx:null,idPrefix:"ui-tabs-",panelTemplate:"<div></div>",spinner:"<em>Loading&#8230;</em>",tabTemplate:'<li><a href="#{href}"><span>#{label}</span></a></li>'}});a.extend(a.ui.tabs.prototype,{rotation:null,rotate:function(d,f){var b=this,g=this.options;var c=b._rotate||(b._rotate=function(h){clearTimeout(b.rotation);b.rotation=setTimeout(function(){var i=g.selected;b.select(++i<b.anchors.length?i:0)},d);if(h){h.stopPropagation()}});var e=b._unrotate||(b._unrotate=!f?function(h){if(h.clientX){b.rotate(null)}}:function(h){t=g.selected;c()});if(d){this.element.bind("tabsshow",c);this.anchors.bind(g.event+".tabs",e);c()}else{clearTimeout(b.rotation);this.element.unbind("tabsshow",c);this.anchors.unbind(g.event+".tabs",e);delete this._rotate;delete this._unrotate}}})})(jQuery);;/*
+ * jQuery UI Datepicker 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Datepicker
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function($){$.extend($.ui,{datepicker:{version:"1.7.2"}});var PROP_NAME="datepicker";function Datepicker(){this.debug=false;this._curInst=null;this._keyEvent=false;this._disabledInputs=[];this._datepickerShowing=false;this._inDialog=false;this._mainDivId="ui-datepicker-div";this._inlineClass="ui-datepicker-inline";this._appendClass="ui-datepicker-append";this._triggerClass="ui-datepicker-trigger";this._dialogClass="ui-datepicker-dialog";this._disableClass="ui-datepicker-disabled";this._unselectableClass="ui-datepicker-unselectable";this._currentClass="ui-datepicker-current-day";this._dayOverClass="ui-datepicker-days-cell-over";this.regional=[];this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],dateFormat:"mm/dd/yy",firstDay:0,isRTL:false};this._defaults={showOn:"focus",showAnim:"show",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:false,hideIfNoPrevNext:false,navigationAsDateFormat:false,gotoCurrent:false,changeMonth:false,changeYear:false,showMonthAfterYear:false,yearRange:"-10:+10",showOtherMonths:false,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"normal",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:true,showButtonPanel:false};$.extend(this._defaults,this.regional[""]);this.dpDiv=$('<div id="'+this._mainDivId+'" class="ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all ui-helper-hidden-accessible"></div>')}$.extend(Datepicker.prototype,{markerClassName:"hasDatepicker",log:function(){if(this.debug){console.log.apply("",arguments)}},setDefaults:function(settings){extendRemove(this._defaults,settings||{});return this},_attachDatepicker:function(target,settings){var inlineSettings=null;for(var attrName in this._defaults){var attrValue=target.getAttribute("date:"+attrName);if(attrValue){inlineSettings=inlineSettings||{};try{inlineSettings[attrName]=eval(attrValue)}catch(err){inlineSettings[attrName]=attrValue}}}var nodeName=target.nodeName.toLowerCase();var inline=(nodeName=="div"||nodeName=="span");if(!target.id){target.id="dp"+(++this.uuid)}var inst=this._newInst($(target),inline);inst.settings=$.extend({},settings||{},inlineSettings||{});if(nodeName=="input"){this._connectDatepicker(target,inst)}else{if(inline){this._inlineDatepicker(target,inst)}}},_newInst:function(target,inline){var id=target[0].id.replace(/([:\[\]\.])/g,"\\\\$1");return{id:id,input:target,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:inline,dpDiv:(!inline?this.dpDiv:$('<div class="'+this._inlineClass+' ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all"></div>'))}},_connectDatepicker:function(target,inst){var input=$(target);inst.append=$([]);inst.trigger=$([]);if(input.hasClass(this.markerClassName)){return}var appendText=this._get(inst,"appendText");var isRTL=this._get(inst,"isRTL");if(appendText){inst.append=$('<span class="'+this._appendClass+'">'+appendText+"</span>");input[isRTL?"before":"after"](inst.append)}var showOn=this._get(inst,"showOn");if(showOn=="focus"||showOn=="both"){input.focus(this._showDatepicker)}if(showOn=="button"||showOn=="both"){var buttonText=this._get(inst,"buttonText");var buttonImage=this._get(inst,"buttonImage");inst.trigger=$(this._get(inst,"buttonImageOnly")?$("<img/>").addClass(this._triggerClass).attr({src:buttonImage,alt:buttonText,title:buttonText}):$('<button type="button"></button>').addClass(this._triggerClass).html(buttonImage==""?buttonText:$("<img/>").attr({src:buttonImage,alt:buttonText,title:buttonText})));input[isRTL?"before":"after"](inst.trigger);inst.trigger.click(function(){if($.datepicker._datepickerShowing&&$.datepicker._lastInput==target){$.datepicker._hideDatepicker()}else{$.datepicker._showDatepicker(target)}return false})}input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst)},_inlineDatepicker:function(target,inst){var divSpan=$(target);if(divSpan.hasClass(this.markerClassName)){return}divSpan.addClass(this.markerClassName).append(inst.dpDiv).bind("setData.datepicker",function(event,key,value){inst.settings[key]=value}).bind("getData.datepicker",function(event,key){return this._get(inst,key)});$.data(target,PROP_NAME,inst);this._setDate(inst,this._getDefaultDate(inst));this._updateDatepicker(inst);this._updateAlternate(inst)},_dialogDatepicker:function(input,dateText,onSelect,settings,pos){var inst=this._dialogInst;if(!inst){var id="dp"+(++this.uuid);this._dialogInput=$('<input type="text" id="'+id+'" size="1" style="position: absolute; top: -100px;"/>');this._dialogInput.keydown(this._doKeyDown);$("body").append(this._dialogInput);inst=this._dialogInst=this._newInst(this._dialogInput,false);inst.settings={};$.data(this._dialogInput[0],PROP_NAME,inst)}extendRemove(inst.settings,settings||{});this._dialogInput.val(dateText);this._pos=(pos?(pos.length?pos:[pos.pageX,pos.pageY]):null);if(!this._pos){var browserWidth=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;var browserHeight=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;var scrollX=document.documentElement.scrollLeft||document.body.scrollLeft;var scrollY=document.documentElement.scrollTop||document.body.scrollTop;this._pos=[(browserWidth/2)-100+scrollX,(browserHeight/2)-150+scrollY]}this._dialogInput.css("left",this._pos[0]+"px").css("top",this._pos[1]+"px");inst.settings.onSelect=onSelect;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);if($.blockUI){$.blockUI(this.dpDiv)}$.data(this._dialogInput[0],PROP_NAME,inst);return this},_destroyDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();$.removeData(target,PROP_NAME);if(nodeName=="input"){inst.append.remove();inst.trigger.remove();$target.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress)}else{if(nodeName=="div"||nodeName=="span"){$target.removeClass(this.markerClassName).empty()}}},_enableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=false;inst.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().removeClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)})},_disableDatepicker:function(target){var $target=$(target);var inst=$.data(target,PROP_NAME);if(!$target.hasClass(this.markerClassName)){return}var nodeName=target.nodeName.toLowerCase();if(nodeName=="input"){target.disabled=true;inst.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else{if(nodeName=="div"||nodeName=="span"){var inline=$target.children("."+this._inlineClass);inline.children().addClass("ui-state-disabled")}}this._disabledInputs=$.map(this._disabledInputs,function(value){return(value==target?null:value)});this._disabledInputs[this._disabledInputs.length]=target},_isDisabledDatepicker:function(target){if(!target){return false}for(var i=0;i<this._disabledInputs.length;i++){if(this._disabledInputs[i]==target){return true}}return false},_getInst:function(target){try{return $.data(target,PROP_NAME)}catch(err){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(target,name,value){var inst=this._getInst(target);if(arguments.length==2&&typeof name=="string"){return(name=="defaults"?$.extend({},$.datepicker._defaults):(inst?(name=="all"?$.extend({},inst.settings):this._get(inst,name)):null))}var settings=name||{};if(typeof name=="string"){settings={};settings[name]=value}if(inst){if(this._curInst==inst){this._hideDatepicker(null)}var date=this._getDateDatepicker(target);extendRemove(inst.settings,settings);this._setDateDatepicker(target,date);this._updateDatepicker(inst)}},_changeDatepicker:function(target,name,value){this._optionDatepicker(target,name,value)},_refreshDatepicker:function(target){var inst=this._getInst(target);if(inst){this._updateDatepicker(inst)}},_setDateDatepicker:function(target,date,endDate){var inst=this._getInst(target);if(inst){this._setDate(inst,date,endDate);this._updateDatepicker(inst);this._updateAlternate(inst)}},_getDateDatepicker:function(target){var inst=this._getInst(target);if(inst&&!inst.inline){this._setDateFromField(inst)}return(inst?this._getDate(inst):null)},_doKeyDown:function(event){var inst=$.datepicker._getInst(event.target);var handled=true;var isRTL=inst.dpDiv.is(".ui-datepicker-rtl");inst._keyEvent=true;if($.datepicker._datepickerShowing){switch(event.keyCode){case 9:$.datepicker._hideDatepicker(null,"");break;case 13:var sel=$("td."+$.datepicker._dayOverClass+", td."+$.datepicker._currentClass,inst.dpDiv);if(sel[0]){$.datepicker._selectDay(event.target,inst.selectedMonth,inst.selectedYear,sel[0])}else{$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"))}return false;break;case 27:$.datepicker._hideDatepicker(null,$.datepicker._get(inst,"duration"));break;case 33:$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M");break;case 34:$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M");break;case 35:if(event.ctrlKey||event.metaKey){$.datepicker._clearDate(event.target)}handled=event.ctrlKey||event.metaKey;break;case 36:if(event.ctrlKey||event.metaKey){$.datepicker._gotoToday(event.target)}handled=event.ctrlKey||event.metaKey;break;case 37:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?+1:-1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?-$.datepicker._get(inst,"stepBigMonths"):-$.datepicker._get(inst,"stepMonths")),"M")}break;case 38:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,-7,"D")}handled=event.ctrlKey||event.metaKey;break;case 39:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,(isRTL?-1:+1),"D")}handled=event.ctrlKey||event.metaKey;if(event.originalEvent.altKey){$.datepicker._adjustDate(event.target,(event.ctrlKey?+$.datepicker._get(inst,"stepBigMonths"):+$.datepicker._get(inst,"stepMonths")),"M")}break;case 40:if(event.ctrlKey||event.metaKey){$.datepicker._adjustDate(event.target,+7,"D")}handled=event.ctrlKey||event.metaKey;break;default:handled=false}}else{if(event.keyCode==36&&event.ctrlKey){$.datepicker._showDatepicker(this)}else{handled=false}}if(handled){event.preventDefault();event.stopPropagation()}},_doKeyPress:function(event){var inst=$.datepicker._getInst(event.target);if($.datepicker._get(inst,"constrainInput")){var chars=$.datepicker._possibleChars($.datepicker._get(inst,"dateFormat"));var chr=String.fromCharCode(event.charCode==undefined?event.keyCode:event.charCode);return event.ctrlKey||(chr<" "||!chars||chars.indexOf(chr)>-1)}},_showDatepicker:function(input){input=input.target||input;if(input.nodeName.toLowerCase()!="input"){input=$("input",input.parentNode)[0]}if($.datepicker._isDisabledDatepicker(input)||$.datepicker._lastInput==input){return}var inst=$.datepicker._getInst(input);var beforeShow=$.datepicker._get(inst,"beforeShow");extendRemove(inst.settings,(beforeShow?beforeShow.apply(input,[input,inst]):{}));$.datepicker._hideDatepicker(null,"");$.datepicker._lastInput=input;$.datepicker._setDateFromField(inst);if($.datepicker._inDialog){input.value=""}if(!$.datepicker._pos){$.datepicker._pos=$.datepicker._findPos(input);$.datepicker._pos[1]+=input.offsetHeight}var isFixed=false;$(input).parents().each(function(){isFixed|=$(this).css("position")=="fixed";return !isFixed});if(isFixed&&$.browser.opera){$.datepicker._pos[0]-=document.documentElement.scrollLeft;$.datepicker._pos[1]-=document.documentElement.scrollTop}var offset={left:$.datepicker._pos[0],top:$.datepicker._pos[1]};$.datepicker._pos=null;inst.rangeStart=null;inst.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});$.datepicker._updateDatepicker(inst);offset=$.datepicker._checkOffset(inst,offset,isFixed);inst.dpDiv.css({position:($.datepicker._inDialog&&$.blockUI?"static":(isFixed?"fixed":"absolute")),display:"none",left:offset.left+"px",top:offset.top+"px"});if(!inst.inline){var showAnim=$.datepicker._get(inst,"showAnim")||"show";var duration=$.datepicker._get(inst,"duration");var postProcess=function(){$.datepicker._datepickerShowing=true;if($.browser.msie&&parseInt($.browser.version,10)<7){$("iframe.ui-datepicker-cover").css({width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4})}};if($.effects&&$.effects[showAnim]){inst.dpDiv.show(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[showAnim](duration,postProcess)}if(duration==""){postProcess()}if(inst.input[0].type!="hidden"){inst.input[0].focus()}$.datepicker._curInst=inst}},_updateDatepicker:function(inst){var dims={width:inst.dpDiv.width()+4,height:inst.dpDiv.height()+4};var self=this;inst.dpDiv.empty().append(this._generateHTML(inst)).find("iframe.ui-datepicker-cover").css({width:dims.width,height:dims.height}).end().find("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a").bind("mouseout",function(){$(this).removeClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).removeClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).removeClass("ui-datepicker-next-hover")}}).bind("mouseover",function(){if(!self._isDisabledDatepicker(inst.inline?inst.dpDiv.parent()[0]:inst.input[0])){$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");$(this).addClass("ui-state-hover");if(this.className.indexOf("ui-datepicker-prev")!=-1){$(this).addClass("ui-datepicker-prev-hover")}if(this.className.indexOf("ui-datepicker-next")!=-1){$(this).addClass("ui-datepicker-next-hover")}}}).end().find("."+this._dayOverClass+" a").trigger("mouseover").end();var numMonths=this._getNumberOfMonths(inst);var cols=numMonths[1];var width=17;if(cols>1){inst.dpDiv.addClass("ui-datepicker-multi-"+cols).css("width",(width*cols)+"em")}else{inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("")}inst.dpDiv[(numMonths[0]!=1||numMonths[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");inst.dpDiv[(this._get(inst,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");if(inst.input&&inst.input[0].type!="hidden"&&inst==$.datepicker._curInst){$(inst.input[0]).focus()}},_checkOffset:function(inst,offset,isFixed){var dpWidth=inst.dpDiv.outerWidth();var dpHeight=inst.dpDiv.outerHeight();var inputWidth=inst.input?inst.input.outerWidth():0;var inputHeight=inst.input?inst.input.outerHeight():0;var viewWidth=(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)+$(document).scrollLeft();var viewHeight=(window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight)+$(document).scrollTop();offset.left-=(this._get(inst,"isRTL")?(dpWidth-inputWidth):0);offset.left-=(isFixed&&offset.left==inst.input.offset().left)?$(document).scrollLeft():0;offset.top-=(isFixed&&offset.top==(inst.input.offset().top+inputHeight))?$(document).scrollTop():0;offset.left-=(offset.left+dpWidth>viewWidth&&viewWidth>dpWidth)?Math.abs(offset.left+dpWidth-viewWidth):0;offset.top-=(offset.top+dpHeight>viewHeight&&viewHeight>dpHeight)?Math.abs(offset.top+dpHeight+inputHeight*2-viewHeight):0;return offset},_findPos:function(obj){while(obj&&(obj.type=="hidden"||obj.nodeType!=1)){obj=obj.nextSibling}var position=$(obj).offset();return[position.left,position.top]},_hideDatepicker:function(input,duration){var inst=this._curInst;if(!inst||(input&&inst!=$.data(input,PROP_NAME))){return}if(inst.stayOpen){this._selectDate("#"+inst.id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear))}inst.stayOpen=false;if(this._datepickerShowing){duration=(duration!=null?duration:this._get(inst,"duration"));var showAnim=this._get(inst,"showAnim");var postProcess=function(){$.datepicker._tidyDialog(inst)};if(duration!=""&&$.effects&&$.effects[showAnim]){inst.dpDiv.hide(showAnim,$.datepicker._get(inst,"showOptions"),duration,postProcess)}else{inst.dpDiv[(duration==""?"hide":(showAnim=="slideDown"?"slideUp":(showAnim=="fadeIn"?"fadeOut":"hide")))](duration,postProcess)}if(duration==""){this._tidyDialog(inst)}var onClose=this._get(inst,"onClose");if(onClose){onClose.apply((inst.input?inst.input[0]:null),[(inst.input?inst.input.val():""),inst])}this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if($.blockUI){$.unblockUI();$("body").append(this.dpDiv)}}this._inDialog=false}this._curInst=null},_tidyDialog:function(inst){inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(event){if(!$.datepicker._curInst){return}var $target=$(event.target);if(($target.parents("#"+$.datepicker._mainDivId).length==0)&&!$target.hasClass($.datepicker.markerClassName)&&!$target.hasClass($.datepicker._triggerClass)&&$.datepicker._datepickerShowing&&!($.datepicker._inDialog&&$.blockUI)){$.datepicker._hideDatepicker(null,"")}},_adjustDate:function(id,offset,period){var target=$(id);var inst=this._getInst(target[0]);if(this._isDisabledDatepicker(target[0])){return}this._adjustInstDate(inst,offset+(period=="M"?this._get(inst,"showCurrentAtPos"):0),period);this._updateDatepicker(inst)},_gotoToday:function(id){var target=$(id);var inst=this._getInst(target[0]);if(this._get(inst,"gotoCurrent")&&inst.currentDay){inst.selectedDay=inst.currentDay;inst.drawMonth=inst.selectedMonth=inst.currentMonth;inst.drawYear=inst.selectedYear=inst.currentYear}else{var date=new Date();inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear()}this._notifyChange(inst);this._adjustDate(target)},_selectMonthYear:function(id,select,period){var target=$(id);var inst=this._getInst(target[0]);inst._selectingMonthYear=false;inst["selected"+(period=="M"?"Month":"Year")]=inst["draw"+(period=="M"?"Month":"Year")]=parseInt(select.options[select.selectedIndex].value,10);this._notifyChange(inst);this._adjustDate(target)},_clickMonthYear:function(id){var target=$(id);var inst=this._getInst(target[0]);if(inst.input&&inst._selectingMonthYear&&!$.browser.msie){inst.input[0].focus()}inst._selectingMonthYear=!inst._selectingMonthYear},_selectDay:function(id,month,year,td){var target=$(id);if($(td).hasClass(this._unselectableClass)||this._isDisabledDatepicker(target[0])){return}var inst=this._getInst(target[0]);inst.selectedDay=inst.currentDay=$("a",td).html();inst.selectedMonth=inst.currentMonth=month;inst.selectedYear=inst.currentYear=year;if(inst.stayOpen){inst.endDay=inst.endMonth=inst.endYear=null}this._selectDate(id,this._formatDate(inst,inst.currentDay,inst.currentMonth,inst.currentYear));if(inst.stayOpen){inst.rangeStart=this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay));this._updateDatepicker(inst)}},_clearDate:function(id){var target=$(id);var inst=this._getInst(target[0]);inst.stayOpen=false;inst.endDay=inst.endMonth=inst.endYear=inst.rangeStart=null;this._selectDate(target,"")},_selectDate:function(id,dateStr){var target=$(id);var inst=this._getInst(target[0]);dateStr=(dateStr!=null?dateStr:this._formatDate(inst));if(inst.input){inst.input.val(dateStr)}this._updateAlternate(inst);var onSelect=this._get(inst,"onSelect");if(onSelect){onSelect.apply((inst.input?inst.input[0]:null),[dateStr,inst])}else{if(inst.input){inst.input.trigger("change")}}if(inst.inline){this._updateDatepicker(inst)}else{if(!inst.stayOpen){this._hideDatepicker(null,this._get(inst,"duration"));this._lastInput=inst.input[0];if(typeof(inst.input[0])!="object"){inst.input[0].focus()}this._lastInput=null}}},_updateAlternate:function(inst){var altField=this._get(inst,"altField");if(altField){var altFormat=this._get(inst,"altFormat")||this._get(inst,"dateFormat");var date=this._getDate(inst);dateStr=this.formatDate(altFormat,date,this._getFormatConfig(inst));$(altField).each(function(){$(this).val(dateStr)})}},noWeekends:function(date){var day=date.getDay();return[(day>0&&day<6),""]},iso8601Week:function(date){var checkDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var firstMon=new Date(checkDate.getFullYear(),1-1,4);var firstDay=firstMon.getDay()||7;firstMon.setDate(firstMon.getDate()+1-firstDay);if(firstDay<4&&checkDate<firstMon){checkDate.setDate(checkDate.getDate()-3);return $.datepicker.iso8601Week(checkDate)}else{if(checkDate>new Date(checkDate.getFullYear(),12-1,28)){firstDay=new Date(checkDate.getFullYear()+1,1-1,4).getDay()||7;if(firstDay>4&&(checkDate.getDay()||7)<firstDay-3){return 1}}}return Math.floor(((checkDate-firstMon)/86400000)/7)+1},parseDate:function(format,value,settings){if(format==null||value==null){throw"Invalid arguments"}value=(typeof value=="object"?value.toString():value+"");if(value==""){return null}var shortYearCutoff=(settings?settings.shortYearCutoff:null)||this._defaults.shortYearCutoff;var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var year=-1;var month=-1;var day=-1;var doy=-1;var literal=false;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var getNumber=function(match){lookAhead(match);var origSize=(match=="@"?14:(match=="y"?4:(match=="o"?3:2)));var size=origSize;var num=0;while(size>0&&iValue<value.length&&value.charAt(iValue)>="0"&&value.charAt(iValue)<="9"){num=num*10+parseInt(value.charAt(iValue++),10);size--}if(size==origSize){throw"Missing number at position "+iValue}return num};var getName=function(match,shortNames,longNames){var names=(lookAhead(match)?longNames:shortNames);var size=0;for(var j=0;j<names.length;j++){size=Math.max(size,names[j].length)}var name="";var iInit=iValue;while(size>0&&iValue<value.length){name+=value.charAt(iValue++);for(var i=0;i<names.length;i++){if(name==names[i]){return i+1}}size--}throw"Unknown name at position "+iInit};var checkLiteral=function(){if(value.charAt(iValue)!=format.charAt(iFormat)){throw"Unexpected literal at position "+iValue}iValue++};var iValue=0;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{checkLiteral()}}else{switch(format.charAt(iFormat)){case"d":day=getNumber("d");break;case"D":getName("D",dayNamesShort,dayNames);break;case"o":doy=getNumber("o");break;case"m":month=getNumber("m");break;case"M":month=getName("M",monthNamesShort,monthNames);break;case"y":year=getNumber("y");break;case"@":var date=new Date(getNumber("@"));year=date.getFullYear();month=date.getMonth()+1;day=date.getDate();break;case"'":if(lookAhead("'")){checkLiteral()}else{literal=true}break;default:checkLiteral()}}}if(year==-1){year=new Date().getFullYear()}else{if(year<100){year+=new Date().getFullYear()-new Date().getFullYear()%100+(year<=shortYearCutoff?0:-100)}}if(doy>-1){month=1;day=doy;do{var dim=this._getDaysInMonth(year,month-1);if(day<=dim){break}month++;day-=dim}while(true)}var date=this._daylightSavingAdjust(new Date(year,month-1,day));if(date.getFullYear()!=year||date.getMonth()+1!=month||date.getDate()!=day){throw"Invalid date"}return date},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TIMESTAMP:"@",W3C:"yy-mm-dd",formatDate:function(format,date,settings){if(!date){return""}var dayNamesShort=(settings?settings.dayNamesShort:null)||this._defaults.dayNamesShort;var dayNames=(settings?settings.dayNames:null)||this._defaults.dayNames;var monthNamesShort=(settings?settings.monthNamesShort:null)||this._defaults.monthNamesShort;var monthNames=(settings?settings.monthNames:null)||this._defaults.monthNames;var lookAhead=function(match){var matches=(iFormat+1<format.length&&format.charAt(iFormat+1)==match);if(matches){iFormat++}return matches};var formatNumber=function(match,value,len){var num=""+value;if(lookAhead(match)){while(num.length<len){num="0"+num}}return num};var formatName=function(match,value,shortNames,longNames){return(lookAhead(match)?longNames[value]:shortNames[value])};var output="";var literal=false;if(date){for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{output+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":output+=formatNumber("d",date.getDate(),2);break;case"D":output+=formatName("D",date.getDay(),dayNamesShort,dayNames);break;case"o":var doy=date.getDate();for(var m=date.getMonth()-1;m>=0;m--){doy+=this._getDaysInMonth(date.getFullYear(),m)}output+=formatNumber("o",doy,3);break;case"m":output+=formatNumber("m",date.getMonth()+1,2);break;case"M":output+=formatName("M",date.getMonth(),monthNamesShort,monthNames);break;case"y":output+=(lookAhead("y")?date.getFullYear():(date.getYear()%100<10?"0":"")+date.getYear()%100);break;case"@":output+=date.getTime();break;case"'":if(lookAhead("'")){output+="'"}else{literal=true}break;default:output+=format.charAt(iFormat)}}}}return output},_possibleChars:function(format){var chars="";var literal=false;for(var iFormat=0;iFormat<format.length;iFormat++){if(literal){if(format.charAt(iFormat)=="'"&&!lookAhead("'")){literal=false}else{chars+=format.charAt(iFormat)}}else{switch(format.charAt(iFormat)){case"d":case"m":case"y":case"@":chars+="0123456789";break;case"D":case"M":return null;case"'":if(lookAhead("'")){chars+="'"}else{literal=true}break;default:chars+=format.charAt(iFormat)}}}return chars},_get:function(inst,name){return inst.settings[name]!==undefined?inst.settings[name]:this._defaults[name]},_setDateFromField:function(inst){var dateFormat=this._get(inst,"dateFormat");var dates=inst.input?inst.input.val():null;inst.endDay=inst.endMonth=inst.endYear=null;var date=defaultDate=this._getDefaultDate(inst);var settings=this._getFormatConfig(inst);try{date=this.parseDate(dateFormat,dates,settings)||defaultDate}catch(event){this.log(event);date=defaultDate}inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();inst.currentDay=(dates?date.getDate():0);inst.currentMonth=(dates?date.getMonth():0);inst.currentYear=(dates?date.getFullYear():0);this._adjustInstDate(inst)},_getDefaultDate:function(inst){var date=this._determineDate(this._get(inst,"defaultDate"),new Date());var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);return date},_determineDate:function(date,defaultDate){var offsetNumeric=function(offset){var date=new Date();date.setDate(date.getDate()+offset);return date};var offsetString=function(offset,getDaysInMonth){var date=new Date();var year=date.getFullYear();var month=date.getMonth();var day=date.getDate();var pattern=/([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g;var matches=pattern.exec(offset);while(matches){switch(matches[2]||"d"){case"d":case"D":day+=parseInt(matches[1],10);break;case"w":case"W":day+=parseInt(matches[1],10)*7;break;case"m":case"M":month+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break;case"y":case"Y":year+=parseInt(matches[1],10);day=Math.min(day,getDaysInMonth(year,month));break}matches=pattern.exec(offset)}return new Date(year,month,day)};date=(date==null?defaultDate:(typeof date=="string"?offsetString(date,this._getDaysInMonth):(typeof date=="number"?(isNaN(date)?defaultDate:offsetNumeric(date)):date)));date=(date&&date.toString()=="Invalid Date"?defaultDate:date);if(date){date.setHours(0);date.setMinutes(0);date.setSeconds(0);date.setMilliseconds(0)}return this._daylightSavingAdjust(date)},_daylightSavingAdjust:function(date){if(!date){return null}date.setHours(date.getHours()>12?date.getHours()+2:0);return date},_setDate:function(inst,date,endDate){var clear=!(date);var origMonth=inst.selectedMonth;var origYear=inst.selectedYear;date=this._determineDate(date,new Date());inst.selectedDay=inst.currentDay=date.getDate();inst.drawMonth=inst.selectedMonth=inst.currentMonth=date.getMonth();inst.drawYear=inst.selectedYear=inst.currentYear=date.getFullYear();if(origMonth!=inst.selectedMonth||origYear!=inst.selectedYear){this._notifyChange(inst)}this._adjustInstDate(inst);if(inst.input){inst.input.val(clear?"":this._formatDate(inst))}},_getDate:function(inst){var startDate=(!inst.currentYear||(inst.input&&inst.input.val()=="")?null:this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return startDate},_generateHTML:function(inst){var today=new Date();today=this._daylightSavingAdjust(new Date(today.getFullYear(),today.getMonth(),today.getDate()));var isRTL=this._get(inst,"isRTL");var showButtonPanel=this._get(inst,"showButtonPanel");var hideIfNoPrevNext=this._get(inst,"hideIfNoPrevNext");var navigationAsDateFormat=this._get(inst,"navigationAsDateFormat");var numMonths=this._getNumberOfMonths(inst);var showCurrentAtPos=this._get(inst,"showCurrentAtPos");var stepMonths=this._get(inst,"stepMonths");var stepBigMonths=this._get(inst,"stepBigMonths");var isMultiMonth=(numMonths[0]!=1||numMonths[1]!=1);var currentDate=this._daylightSavingAdjust((!inst.currentDay?new Date(9999,9,9):new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");var drawMonth=inst.drawMonth-showCurrentAtPos;var drawYear=inst.drawYear;if(drawMonth<0){drawMonth+=12;drawYear--}if(maxDate){var maxDraw=this._daylightSavingAdjust(new Date(maxDate.getFullYear(),maxDate.getMonth()-numMonths[1]+1,maxDate.getDate()));maxDraw=(minDate&&maxDraw<minDate?minDate:maxDraw);while(this._daylightSavingAdjust(new Date(drawYear,drawMonth,1))>maxDraw){drawMonth--;if(drawMonth<0){drawMonth=11;drawYear--}}}inst.drawMonth=drawMonth;inst.drawYear=drawYear;var prevText=this._get(inst,"prevText");prevText=(!navigationAsDateFormat?prevText:this.formatDate(prevText,this._daylightSavingAdjust(new Date(drawYear,drawMonth-stepMonths,1)),this._getFormatConfig(inst)));var prev=(this._canAdjustMonth(inst,-1,drawYear,drawMonth)?'<a class="ui-datepicker-prev ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', -"+stepMonths+", 'M');\" title=\""+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-prev ui-corner-all ui-state-disabled" title="'+prevText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"e":"w")+'">'+prevText+"</span></a>"));var nextText=this._get(inst,"nextText");nextText=(!navigationAsDateFormat?nextText:this.formatDate(nextText,this._daylightSavingAdjust(new Date(drawYear,drawMonth+stepMonths,1)),this._getFormatConfig(inst)));var next=(this._canAdjustMonth(inst,+1,drawYear,drawMonth)?'<a class="ui-datepicker-next ui-corner-all" onclick="DP_jQuery.datepicker._adjustDate(\'#'+inst.id+"', +"+stepMonths+", 'M');\" title=\""+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>":(hideIfNoPrevNext?"":'<a class="ui-datepicker-next ui-corner-all ui-state-disabled" title="'+nextText+'"><span class="ui-icon ui-icon-circle-triangle-'+(isRTL?"w":"e")+'">'+nextText+"</span></a>"));var currentText=this._get(inst,"currentText");var gotoDate=(this._get(inst,"gotoCurrent")&&inst.currentDay?currentDate:today);currentText=(!navigationAsDateFormat?currentText:this.formatDate(currentText,gotoDate,this._getFormatConfig(inst)));var controls=(!inst.inline?'<button type="button" class="ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all" onclick="DP_jQuery.datepicker._hideDatepicker();">'+this._get(inst,"closeText")+"</button>":"");var buttonPanel=(showButtonPanel)?'<div class="ui-datepicker-buttonpane ui-widget-content">'+(isRTL?controls:"")+(this._isInRange(inst,gotoDate)?'<button type="button" class="ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all" onclick="DP_jQuery.datepicker._gotoToday(\'#'+inst.id+"');\">"+currentText+"</button>":"")+(isRTL?"":controls)+"</div>":"";var firstDay=parseInt(this._get(inst,"firstDay"),10);firstDay=(isNaN(firstDay)?0:firstDay);var dayNames=this._get(inst,"dayNames");var dayNamesShort=this._get(inst,"dayNamesShort");var dayNamesMin=this._get(inst,"dayNamesMin");var monthNames=this._get(inst,"monthNames");var monthNamesShort=this._get(inst,"monthNamesShort");var beforeShowDay=this._get(inst,"beforeShowDay");var showOtherMonths=this._get(inst,"showOtherMonths");var calculateWeek=this._get(inst,"calculateWeek")||this.iso8601Week;var endDate=inst.endDay?this._daylightSavingAdjust(new Date(inst.endYear,inst.endMonth,inst.endDay)):currentDate;var defaultDate=this._getDefaultDate(inst);var html="";for(var row=0;row<numMonths[0];row++){var group="";for(var col=0;col<numMonths[1];col++){var selectedDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,inst.selectedDay));var cornerClass=" ui-corner-all";var calender="";if(isMultiMonth){calender+='<div class="ui-datepicker-group ui-datepicker-group-';switch(col){case 0:calender+="first";cornerClass=" ui-corner-"+(isRTL?"right":"left");break;case numMonths[1]-1:calender+="last";cornerClass=" ui-corner-"+(isRTL?"left":"right");break;default:calender+="middle";cornerClass="";break}calender+='">'}calender+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+cornerClass+'">'+(/all|left/.test(cornerClass)&&row==0?(isRTL?next:prev):"")+(/all|right/.test(cornerClass)&&row==0?(isRTL?prev:next):"")+this._generateMonthYearHeader(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,row>0||col>0,monthNames,monthNamesShort)+'</div><table class="ui-datepicker-calendar"><thead><tr>';var thead="";for(var dow=0;dow<7;dow++){var day=(dow+firstDay)%7;thead+="<th"+((dow+firstDay+6)%7>=5?' class="ui-datepicker-week-end"':"")+'><span title="'+dayNames[day]+'">'+dayNamesMin[day]+"</span></th>"}calender+=thead+"</tr></thead><tbody>";var daysInMonth=this._getDaysInMonth(drawYear,drawMonth);if(drawYear==inst.selectedYear&&drawMonth==inst.selectedMonth){inst.selectedDay=Math.min(inst.selectedDay,daysInMonth)}var leadDays=(this._getFirstDayOfMonth(drawYear,drawMonth)-firstDay+7)%7;var numRows=(isMultiMonth?6:Math.ceil((leadDays+daysInMonth)/7));var printDate=this._daylightSavingAdjust(new Date(drawYear,drawMonth,1-leadDays));for(var dRow=0;dRow<numRows;dRow++){calender+="<tr>";var tbody="";for(var dow=0;dow<7;dow++){var daySettings=(beforeShowDay?beforeShowDay.apply((inst.input?inst.input[0]:null),[printDate]):[true,""]);var otherMonth=(printDate.getMonth()!=drawMonth);var unselectable=otherMonth||!daySettings[0]||(minDate&&printDate<minDate)||(maxDate&&printDate>maxDate);tbody+='<td class="'+((dow+firstDay+6)%7>=5?" ui-datepicker-week-end":"")+(otherMonth?" ui-datepicker-other-month":"")+((printDate.getTime()==selectedDate.getTime()&&drawMonth==inst.selectedMonth&&inst._keyEvent)||(defaultDate.getTime()==printDate.getTime()&&defaultDate.getTime()==selectedDate.getTime())?" "+this._dayOverClass:"")+(unselectable?" "+this._unselectableClass+" ui-state-disabled":"")+(otherMonth&&!showOtherMonths?"":" "+daySettings[1]+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" "+this._currentClass:"")+(printDate.getTime()==today.getTime()?" ui-datepicker-today":""))+'"'+((!otherMonth||showOtherMonths)&&daySettings[2]?' title="'+daySettings[2]+'"':"")+(unselectable?"":" onclick=\"DP_jQuery.datepicker._selectDay('#"+inst.id+"',"+drawMonth+","+drawYear+', this);return false;"')+">"+(otherMonth?(showOtherMonths?printDate.getDate():"&#xa0;"):(unselectable?'<span class="ui-state-default">'+printDate.getDate()+"</span>":'<a class="ui-state-default'+(printDate.getTime()==today.getTime()?" ui-state-highlight":"")+(printDate.getTime()>=currentDate.getTime()&&printDate.getTime()<=endDate.getTime()?" ui-state-active":"")+'" href="#">'+printDate.getDate()+"</a>"))+"</td>";printDate.setDate(printDate.getDate()+1);printDate=this._daylightSavingAdjust(printDate)}calender+=tbody+"</tr>"}drawMonth++;if(drawMonth>11){drawMonth=0;drawYear++}calender+="</tbody></table>"+(isMultiMonth?"</div>"+((numMonths[0]>0&&col==numMonths[1]-1)?'<div class="ui-datepicker-row-break"></div>':""):"");group+=calender}html+=group}html+=buttonPanel+($.browser.msie&&parseInt($.browser.version,10)<7&&!inst.inline?'<iframe src="javascript:false;" class="ui-datepicker-cover" frameborder="0"></iframe>':"");inst._keyEvent=false;return html},_generateMonthYearHeader:function(inst,drawMonth,drawYear,minDate,maxDate,selectedDate,secondary,monthNames,monthNamesShort){minDate=(inst.rangeStart&&minDate&&selectedDate<minDate?selectedDate:minDate);var changeMonth=this._get(inst,"changeMonth");var changeYear=this._get(inst,"changeYear");var showMonthAfterYear=this._get(inst,"showMonthAfterYear");var html='<div class="ui-datepicker-title">';var monthHtml="";if(secondary||!changeMonth){monthHtml+='<span class="ui-datepicker-month">'+monthNames[drawMonth]+"</span> "}else{var inMinYear=(minDate&&minDate.getFullYear()==drawYear);var inMaxYear=(maxDate&&maxDate.getFullYear()==drawYear);monthHtml+='<select class="ui-datepicker-month" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'M');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(var month=0;month<12;month++){if((!inMinYear||month>=minDate.getMonth())&&(!inMaxYear||month<=maxDate.getMonth())){monthHtml+='<option value="'+month+'"'+(month==drawMonth?' selected="selected"':"")+">"+monthNamesShort[month]+"</option>"}}monthHtml+="</select>"}if(!showMonthAfterYear){html+=monthHtml+((secondary||changeMonth||changeYear)&&(!(changeMonth&&changeYear))?"&#xa0;":"")}if(secondary||!changeYear){html+='<span class="ui-datepicker-year">'+drawYear+"</span>"}else{var years=this._get(inst,"yearRange").split(":");var year=0;var endYear=0;if(years.length!=2){year=drawYear-10;endYear=drawYear+10}else{if(years[0].charAt(0)=="+"||years[0].charAt(0)=="-"){year=drawYear+parseInt(years[0],10);endYear=drawYear+parseInt(years[1],10)}else{year=parseInt(years[0],10);endYear=parseInt(years[1],10)}}year=(minDate?Math.max(year,minDate.getFullYear()):year);endYear=(maxDate?Math.min(endYear,maxDate.getFullYear()):endYear);html+='<select class="ui-datepicker-year" onchange="DP_jQuery.datepicker._selectMonthYear(\'#'+inst.id+"', this, 'Y');\" onclick=\"DP_jQuery.datepicker._clickMonthYear('#"+inst.id+"');\">";for(;year<=endYear;year++){html+='<option value="'+year+'"'+(year==drawYear?' selected="selected"':"")+">"+year+"</option>"}html+="</select>"}if(showMonthAfterYear){html+=(secondary||changeMonth||changeYear?"&#xa0;":"")+monthHtml}html+="</div>";return html},_adjustInstDate:function(inst,offset,period){var year=inst.drawYear+(period=="Y"?offset:0);var month=inst.drawMonth+(period=="M"?offset:0);var day=Math.min(inst.selectedDay,this._getDaysInMonth(year,month))+(period=="D"?offset:0);var date=this._daylightSavingAdjust(new Date(year,month,day));var minDate=this._getMinMaxDate(inst,"min",true);var maxDate=this._getMinMaxDate(inst,"max");date=(minDate&&date<minDate?minDate:date);date=(maxDate&&date>maxDate?maxDate:date);inst.selectedDay=date.getDate();inst.drawMonth=inst.selectedMonth=date.getMonth();inst.drawYear=inst.selectedYear=date.getFullYear();if(period=="M"||period=="Y"){this._notifyChange(inst)}},_notifyChange:function(inst){var onChange=this._get(inst,"onChangeMonthYear");if(onChange){onChange.apply((inst.input?inst.input[0]:null),[inst.selectedYear,inst.selectedMonth+1,inst])}},_getNumberOfMonths:function(inst){var numMonths=this._get(inst,"numberOfMonths");return(numMonths==null?[1,1]:(typeof numMonths=="number"?[1,numMonths]:numMonths))},_getMinMaxDate:function(inst,minMax,checkRange){var date=this._determineDate(this._get(inst,minMax+"Date"),null);return(!checkRange||!inst.rangeStart?date:(!date||inst.rangeStart>date?inst.rangeStart:date))},_getDaysInMonth:function(year,month){return 32-new Date(year,month,32).getDate()},_getFirstDayOfMonth:function(year,month){return new Date(year,month,1).getDay()},_canAdjustMonth:function(inst,offset,curYear,curMonth){var numMonths=this._getNumberOfMonths(inst);var date=this._daylightSavingAdjust(new Date(curYear,curMonth+(offset<0?offset:numMonths[1]),1));if(offset<0){date.setDate(this._getDaysInMonth(date.getFullYear(),date.getMonth()))}return this._isInRange(inst,date)},_isInRange:function(inst,date){var newMinDate=(!inst.rangeStart?null:this._daylightSavingAdjust(new Date(inst.selectedYear,inst.selectedMonth,inst.selectedDay)));newMinDate=(newMinDate&&inst.rangeStart<newMinDate?inst.rangeStart:newMinDate);var minDate=newMinDate||this._getMinMaxDate(inst,"min");var maxDate=this._getMinMaxDate(inst,"max");return((!minDate||date>=minDate)&&(!maxDate||date<=maxDate))},_getFormatConfig:function(inst){var shortYearCutoff=this._get(inst,"shortYearCutoff");shortYearCutoff=(typeof shortYearCutoff!="string"?shortYearCutoff:new Date().getFullYear()%100+parseInt(shortYearCutoff,10));return{shortYearCutoff:shortYearCutoff,dayNamesShort:this._get(inst,"dayNamesShort"),dayNames:this._get(inst,"dayNames"),monthNamesShort:this._get(inst,"monthNamesShort"),monthNames:this._get(inst,"monthNames")}},_formatDate:function(inst,day,month,year){if(!day){inst.currentDay=inst.selectedDay;inst.currentMonth=inst.selectedMonth;inst.currentYear=inst.selectedYear}var date=(day?(typeof day=="object"?day:this._daylightSavingAdjust(new Date(year,month,day))):this._daylightSavingAdjust(new Date(inst.currentYear,inst.currentMonth,inst.currentDay)));return this.formatDate(this._get(inst,"dateFormat"),date,this._getFormatConfig(inst))}});function extendRemove(target,props){$.extend(target,props);for(var name in props){if(props[name]==null||props[name]==undefined){target[name]=props[name]}}return target}function isArray(a){return(a&&(($.browser.safari&&typeof a=="object"&&a.length)||(a.constructor&&a.constructor.toString().match(/\Array\(\)/))))}$.fn.datepicker=function(options){if(!$.datepicker.initialized){$(document).mousedown($.datepicker._checkExternalClick).find("body").append($.datepicker.dpDiv);$.datepicker.initialized=true}var otherArgs=Array.prototype.slice.call(arguments,1);if(typeof options=="string"&&(options=="isDisabled"||options=="getDate")){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}if(options=="option"&&arguments.length==2&&typeof arguments[1]=="string"){return $.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this[0]].concat(otherArgs))}return this.each(function(){typeof options=="string"?$.datepicker["_"+options+"Datepicker"].apply($.datepicker,[this].concat(otherArgs)):$.datepicker._attachDatepicker(this,options)})};$.datepicker=new Datepicker();$.datepicker.initialized=false;$.datepicker.uuid=new Date().getTime();$.datepicker.version="1.7.2";window.DP_jQuery=$})(jQuery);;/*
+ * jQuery UI Progressbar 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Progressbar
+ *
+ * Depends:
+ * ui.core.js
+ */
+(function(a){a.widget("ui.progressbar",{_init:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=a('<div class="ui-progressbar-value ui-widget-header ui-corner-left"></div>').appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow").removeData("progressbar").unbind(".progressbar");this.valueDiv.remove();a.widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===undefined){return this._value()}this._setData("value",b);return this},_setData:function(b,c){switch(b){case"value":this.options.value=c;this._refreshValue();this._trigger("change",null,{});break}a.widget.prototype._setData.apply(this,arguments)},_value:function(){var b=this.options.value;if(b<this._valueMin()){b=this._valueMin()}if(b>this._valueMax()){b=this._valueMax()}return b},_valueMin:function(){var b=0;return b},_valueMax:function(){var b=100;return b},_refreshValue:function(){var b=this.value();this.valueDiv[b==this._valueMax()?"addClass":"removeClass"]("ui-corner-right");this.valueDiv.width(b+"%");this.element.attr("aria-valuenow",b)}});a.extend(a.ui.progressbar,{version:"1.7.2",defaults:{value:0}})})(jQuery);;/*
+ * jQuery UI Effects 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/
+ */
+jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.data("ec.storage."+h[f],g[0].style[h[f]])}}},restore:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.css(h[f],g.data("ec.storage."+h[f]))}}},setMode:function(f,g){if(g=="toggle"){g=f.is(":hidden")?"show":"hide"}return g},getBaseline:function(g,h){var i,f;switch(g[0]){case"top":i=0;break;case"middle":i=0.5;break;case"bottom":i=1;break;default:i=g[0]/h.height}switch(g[1]){case"left":f=0;break;case"center":f=0.5;break;case"right":f=1;break;default:f=g[1]/h.width}return{x:f,y:i}},createWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent()}var g={width:f.outerWidth(true),height:f.outerHeight(true),"float":f.css("float")};f.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}};function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:(i.duration?i.duration:g[2]);h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[1])&&g[1])||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(d.isFunction(arguments[0])||typeof arguments[0]=="boolean")){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return -(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f},easeOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return h*Math.pow(2,-10*i)*Math.sin((i*l-j)*(2*Math.PI)/k)+m+f},easeInOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l/2)==2){return f+m}if(!k){k=l*(0.3*1.5)}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}if(i<1){return -0.5*(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f}return h*Math.pow(2,-10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k)*0.5+m+f},easeInBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*(h/=j)*h*((i+1)*h-i)+f},easeOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*((h=h/j-1)*h*((i+1)*h+i)+1)+f},easeInOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}if((h/=j/2)<1){return k/2*(h*h*(((i*=(1.525))+1)*h-i))+f}return k/2*((h-=2)*h*(((i*=(1.525))+1)*h+i)+2)+f},easeInBounce:function(g,h,f,j,i){return j-d.easing.easeOutBounce(g,i-h,0,j,i)+f},easeOutBounce:function(g,h,f,j,i){if((h/=i)<(1/2.75)){return j*(7.5625*h*h)+f}else{if(h<(2/2.75)){return j*(7.5625*(h-=(1.5/2.75))*h+0.75)+f}else{if(h<(2.5/2.75)){return j*(7.5625*(h-=(2.25/2.75))*h+0.9375)+f}else{return j*(7.5625*(h-=(2.625/2.75))*h+0.984375)+f}}}},easeInOutBounce:function(g,h,f,j,i){if(h<i/2){return d.easing.easeInBounce(g,h*2,0,j,i)*0.5+f}return d.easing.easeOutBounce(g,h*2-i,0,j,i)*0.5+j*0.5+f}})})(jQuery);;/*
+ * jQuery UI Effects Blind 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Blind
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.blind=function(b){return this.queue(function(){var d=a(this),c=["position","top","left"];var h=a.effects.setMode(d,b.options.mode||"hide");var g=b.options.direction||"vertical";a.effects.save(d,c);d.show();var j=a.effects.createWrapper(d).css({overflow:"hidden"});var e=(g=="vertical")?"height":"width";var i=(g=="vertical")?j.height():j.width();if(h=="show"){j.css(e,0)}var f={};f[e]=h=="show"?i:0;j.animate(f,b.duration,b.options.easing,function(){if(h=="hide"){d.hide()}a.effects.restore(d,c);a.effects.removeWrapper(d);if(b.callback){b.callback.apply(d[0],arguments)}d.dequeue()})})}})(jQuery);;/*
+ * jQuery UI Effects Bounce 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Bounce
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.bounce=function(b){return this.queue(function(){var e=a(this),l=["position","top","left"];var k=a.effects.setMode(e,b.options.mode||"effect");var n=b.options.direction||"up";var c=b.options.distance||20;var d=b.options.times||5;var g=b.duration||250;if(/show|hide/.test(k)){l.push("opacity")}a.effects.save(e,l);e.show();a.effects.createWrapper(e);var f=(n=="up"||n=="down")?"top":"left";var p=(n=="up"||n=="left")?"pos":"neg";var c=b.options.distance||(f=="top"?e.outerHeight({margin:true})/3:e.outerWidth({margin:true})/3);if(k=="show"){e.css("opacity",0).css(f,p=="pos"?-c:c)}if(k=="hide"){c=c/(d*2)}if(k!="hide"){d--}if(k=="show"){var h={opacity:1};h[f]=(p=="pos"?"+=":"-=")+c;e.animate(h,g/2,b.options.easing);c=c/2;d--}for(var j=0;j<d;j++){var o={},m={};o[f]=(p=="pos"?"-=":"+=")+c;m[f]=(p=="pos"?"+=":"-=")+c;e.animate(o,g/2,b.options.easing).animate(m,g/2,b.options.easing);c=(k=="hide")?c*2:c/2}if(k=="hide"){var h={opacity:0};h[f]=(p=="pos"?"-=":"+=")+c;e.animate(h,g/2,b.options.easing,function(){e.hide();a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}})}else{var o={},m={};o[f]=(p=="pos"?"-=":"+=")+c;m[f]=(p=="pos"?"+=":"-=")+c;e.animate(o,g/2,b.options.easing).animate(m,g/2,b.options.easing,function(){a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}})}e.queue("fx",function(){e.dequeue()});e.dequeue()})}})(jQuery);;/*
+ * jQuery UI Effects Clip 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Clip
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.clip=function(b){return this.queue(function(){var f=a(this),j=["position","top","left","height","width"];var i=a.effects.setMode(f,b.options.mode||"hide");var k=b.options.direction||"vertical";a.effects.save(f,j);f.show();var c=a.effects.createWrapper(f).css({overflow:"hidden"});var e=f[0].tagName=="IMG"?c:f;var g={size:(k=="vertical")?"height":"width",position:(k=="vertical")?"top":"left"};var d=(k=="vertical")?e.height():e.width();if(i=="show"){e.css(g.size,0);e.css(g.position,d/2)}var h={};h[g.size]=i=="show"?d:0;h[g.position]=i=="show"?0:d/2;e.animate(h,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){f.hide()}a.effects.restore(f,j);a.effects.removeWrapper(f);if(b.callback){b.callback.apply(f[0],arguments)}f.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Drop 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Drop
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.drop=function(b){return this.queue(function(){var e=a(this),d=["position","top","left","opacity"];var i=a.effects.setMode(e,b.options.mode||"hide");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e);var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true})/2:e.outerWidth({margin:true})/2);if(i=="show"){e.css("opacity",0).css(f,c=="pos"?-j:j)}var g={opacity:i=="show"?1:0};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Explode 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Explode
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.explode=function(b){return this.queue(function(){var k=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;var e=b.options.pieces?Math.round(Math.sqrt(b.options.pieces)):3;b.options.mode=b.options.mode=="toggle"?(a(this).is(":visible")?"hide":"show"):b.options.mode;var h=a(this).show().css("visibility","hidden");var l=h.offset();l.top-=parseInt(h.css("marginTop"),10)||0;l.left-=parseInt(h.css("marginLeft"),10)||0;var g=h.outerWidth(true);var c=h.outerHeight(true);for(var f=0;f<k;f++){for(var d=0;d<e;d++){h.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-d*(g/e),top:-f*(c/k)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:g/e,height:c/k,left:l.left+d*(g/e)+(b.options.mode=="show"?(d-Math.floor(e/2))*(g/e):0),top:l.top+f*(c/k)+(b.options.mode=="show"?(f-Math.floor(k/2))*(c/k):0),opacity:b.options.mode=="show"?0:1}).animate({left:l.left+d*(g/e)+(b.options.mode=="show"?0:(d-Math.floor(e/2))*(g/e)),top:l.top+f*(c/k)+(b.options.mode=="show"?0:(f-Math.floor(k/2))*(c/k)),opacity:b.options.mode=="show"?1:0},b.duration||500)}}setTimeout(function(){b.options.mode=="show"?h.css({visibility:"visible"}):h.css({visibility:"visible"}).hide();if(b.callback){b.callback.apply(h[0])}h.dequeue();a("div.ui-effects-explode").remove()},b.duration||500)})}})(jQuery);;/*
+ * jQuery UI Effects Fold 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Fold
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.fold=function(b){return this.queue(function(){var e=a(this),k=["position","top","left"];var h=a.effects.setMode(e,b.options.mode||"hide");var o=b.options.size||15;var n=!(!b.options.horizFirst);var g=b.duration?b.duration/2:a.fx.speeds._default/2;a.effects.save(e,k);e.show();var d=a.effects.createWrapper(e).css({overflow:"hidden"});var i=((h=="show")!=n);var f=i?["width","height"]:["height","width"];var c=i?[d.width(),d.height()]:[d.height(),d.width()];var j=/([0-9]+)%/.exec(o);if(j){o=parseInt(j[1],10)/100*c[h=="hide"?0:1]}if(h=="show"){d.css(n?{height:0,width:o}:{height:o,width:0})}var m={},l={};m[f[0]]=h=="show"?c[0]:o;l[f[1]]=h=="show"?c[1]:0;d.animate(m,g,b.options.easing).animate(l,g,b.options.easing,function(){if(h=="hide"){e.hide()}a.effects.restore(e,k);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(e[0],arguments)}e.dequeue()})})}})(jQuery);;/*
+ * jQuery UI Effects Highlight 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Highlight
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.highlight=function(b){return this.queue(function(){var e=a(this),d=["backgroundImage","backgroundColor","opacity"];var h=a.effects.setMode(e,b.options.mode||"show");var c=b.options.color||"#ffff99";var g=e.css("backgroundColor");a.effects.save(e,d);e.show();e.css({backgroundImage:"none",backgroundColor:c});var f={backgroundColor:g};if(h=="hide"){f.opacity=0}e.animate(f,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(h=="hide"){e.hide()}a.effects.restore(e,d);if(h=="show"&&a.browser.msie){this.style.removeAttribute("filter")}if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Pulsate 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Pulsate
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.pulsate=function(b){return this.queue(function(){var d=a(this);var g=a.effects.setMode(d,b.options.mode||"show");var f=b.options.times||5;var e=b.duration?b.duration/2:a.fx.speeds._default/2;if(g=="hide"){f--}if(d.is(":hidden")){d.css("opacity",0);d.show();d.animate({opacity:1},e,b.options.easing);f=f-2}for(var c=0;c<f;c++){d.animate({opacity:0},e,b.options.easing).animate({opacity:1},e,b.options.easing)}if(g=="hide"){d.animate({opacity:0},e,b.options.easing,function(){d.hide();if(b.callback){b.callback.apply(this,arguments)}})}else{d.animate({opacity:0},e,b.options.easing).animate({opacity:1},e,b.options.easing,function(){if(b.callback){b.callback.apply(this,arguments)}})}d.queue("fx",function(){d.dequeue()});d.dequeue()})}})(jQuery);;/*
+ * jQuery UI Effects Scale 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Scale
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.puff=function(b){return this.queue(function(){var f=a(this);var c=a.extend(true,{},b.options);var h=a.effects.setMode(f,b.options.mode||"hide");var g=parseInt(b.options.percent,10)||150;c.fade=true;var e={height:f.height(),width:f.width()};var d=g/100;f.from=(h=="hide")?e:{height:e.height*d,width:e.width*d};c.from=f.from;c.percent=(h=="hide")?g:100;c.mode=h;f.effect("scale",c,b.duration,b.callback);f.dequeue()})};a.effects.scale=function(b){return this.queue(function(){var g=a(this);var d=a.extend(true,{},b.options);var j=a.effects.setMode(g,b.options.mode||"effect");var h=parseInt(b.options.percent,10)||(parseInt(b.options.percent,10)==0?0:(j=="hide"?0:100));var i=b.options.direction||"both";var c=b.options.origin;if(j!="effect"){d.origin=c||["middle","center"];d.restore=true}var f={height:g.height(),width:g.width()};g.from=b.options.from||(j=="show"?{height:0,width:0}:f);var e={y:i!="horizontal"?(h/100):1,x:i!="vertical"?(h/100):1};g.to={height:f.height*e.y,width:f.width*e.x};if(b.options.fade){if(j=="show"){g.from.opacity=0;g.to.opacity=1}if(j=="hide"){g.from.opacity=1;g.to.opacity=0}}d.from=g.from;d.to=g.to;d.mode=j;g.effect("size",d,b.duration,b.callback);g.dequeue()})};a.effects.size=function(b){return this.queue(function(){var c=a(this),n=["position","top","left","width","height","overflow","opacity"];var m=["position","top","left","overflow","opacity"];var j=["width","height","overflow"];var p=["fontSize"];var k=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"];var f=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"];var g=a.effects.setMode(c,b.options.mode||"effect");var i=b.options.restore||false;var e=b.options.scale||"both";var o=b.options.origin;var d={height:c.height(),width:c.width()};c.from=b.options.from||d;c.to=b.options.to||d;if(o){var h=a.effects.getBaseline(o,d);c.from.top=(d.height-c.from.height)*h.y;c.from.left=(d.width-c.from.width)*h.x;c.to.top=(d.height-c.to.height)*h.y;c.to.left=(d.width-c.to.width)*h.x}var l={from:{y:c.from.height/d.height,x:c.from.width/d.width},to:{y:c.to.height/d.height,x:c.to.width/d.width}};if(e=="box"||e=="both"){if(l.from.y!=l.to.y){n=n.concat(k);c.from=a.effects.setTransition(c,k,l.from.y,c.from);c.to=a.effects.setTransition(c,k,l.to.y,c.to)}if(l.from.x!=l.to.x){n=n.concat(f);c.from=a.effects.setTransition(c,f,l.from.x,c.from);c.to=a.effects.setTransition(c,f,l.to.x,c.to)}}if(e=="content"||e=="both"){if(l.from.y!=l.to.y){n=n.concat(p);c.from=a.effects.setTransition(c,p,l.from.y,c.from);c.to=a.effects.setTransition(c,p,l.to.y,c.to)}}a.effects.save(c,i?n:m);c.show();a.effects.createWrapper(c);c.css("overflow","hidden").css(c.from);if(e=="content"||e=="both"){k=k.concat(["marginTop","marginBottom"]).concat(p);f=f.concat(["marginLeft","marginRight"]);j=n.concat(k).concat(f);c.find("*[width]").each(function(){child=a(this);if(i){a.effects.save(child,j)}var q={height:child.height(),width:child.width()};child.from={height:q.height*l.from.y,width:q.width*l.from.x};child.to={height:q.height*l.to.y,width:q.width*l.to.x};if(l.from.y!=l.to.y){child.from=a.effects.setTransition(child,k,l.from.y,child.from);child.to=a.effects.setTransition(child,k,l.to.y,child.to)}if(l.from.x!=l.to.x){child.from=a.effects.setTransition(child,f,l.from.x,child.from);child.to=a.effects.setTransition(child,f,l.to.x,child.to)}child.css(child.from);child.animate(child.to,b.duration,b.options.easing,function(){if(i){a.effects.restore(child,j)}})})}c.animate(c.to,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(g=="hide"){c.hide()}a.effects.restore(c,i?n:m);a.effects.removeWrapper(c);if(b.callback){b.callback.apply(this,arguments)}c.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Shake 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Shake
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.shake=function(b){return this.queue(function(){var e=a(this),l=["position","top","left"];var k=a.effects.setMode(e,b.options.mode||"effect");var n=b.options.direction||"left";var c=b.options.distance||20;var d=b.options.times||3;var g=b.duration||b.options.duration||140;a.effects.save(e,l);e.show();a.effects.createWrapper(e);var f=(n=="up"||n=="down")?"top":"left";var p=(n=="up"||n=="left")?"pos":"neg";var h={},o={},m={};h[f]=(p=="pos"?"-=":"+=")+c;o[f]=(p=="pos"?"+=":"-=")+c*2;m[f]=(p=="pos"?"-=":"+=")+c*2;e.animate(h,g,b.options.easing);for(var j=1;j<d;j++){e.animate(o,g,b.options.easing).animate(m,g,b.options.easing)}e.animate(o,g,b.options.easing).animate(h,g/2,b.options.easing,function(){a.effects.restore(e,l);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}});e.queue("fx",function(){e.dequeue()});e.dequeue()})}})(jQuery);;/*
+ * jQuery UI Effects Slide 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Slide
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.slide=function(b){return this.queue(function(){var e=a(this),d=["position","top","left"];var i=a.effects.setMode(e,b.options.mode||"show");var h=b.options.direction||"left";a.effects.save(e,d);e.show();a.effects.createWrapper(e).css({overflow:"hidden"});var f=(h=="up"||h=="down")?"top":"left";var c=(h=="up"||h=="left")?"pos":"neg";var j=b.options.distance||(f=="top"?e.outerHeight({margin:true}):e.outerWidth({margin:true}));if(i=="show"){e.css(f,c=="pos"?-j:j)}var g={};g[f]=(i=="show"?(c=="pos"?"+=":"-="):(c=="pos"?"-=":"+="))+j;e.animate(g,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){e.hide()}a.effects.restore(e,d);a.effects.removeWrapper(e);if(b.callback){b.callback.apply(this,arguments)}e.dequeue()}})})}})(jQuery);;/*
+ * jQuery UI Effects Transfer 1.7.2
+ *
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * http://docs.jquery.com/UI/Effects/Transfer
+ *
+ * Depends:
+ * effects.core.js
+ */
+(function(a){a.effects.transfer=function(b){return this.queue(function(){var f=a(this),h=a(b.options.to),e=h.offset(),g={top:e.top,left:e.left,height:h.innerHeight(),width:h.innerWidth()},d=f.offset(),c=a('<div class="ui-effects-transfer"></div>').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);; \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/lesson.js b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/lesson.js
new file mode 100755
index 0000000..2a7e4ca
--- /dev/null
+++ b/bundles/XO/karma/lessons/Math_Numeric_Puzzle_Solving/js/lesson.js
@@ -0,0 +1,217 @@
+$(document).ready(function() {
+ var k = Karma({audio: [{'name':'correct','file':'correct.ogg'}]});
+
+ k.ready(function(){
+
+
+ //initialize the variables used and display initial value
+ var drag_no = 0; //store the current dragged no
+ var drop_no = 0; //store the current dropped on no
+ var imgrand = []; //stores the random variables generated
+ var imgPosition = []; //stores the position of the random variable
+ var drag_position = 0; //position of dragged object
+ var drop_position = 0; //position of dropped object
+ var flag, i ,j;
+ var moves_count = 0;
+ var imgPath;
+
+
+ for(i=0; i<16; i++){
+ $('#feedback_image').append("<img class='dragme' id='imgdrag" +
+ i + "' draggable='true' src='' alt='' />");
+ }
+
+ game("img1");
+
+
+ $('a#anchorImg1').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img1");
+
+
+ });
+
+ $('a#anchorImg2').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img2");
+
+ });
+
+ $('a#anchorImg3').click(function(){
+ $("#"+imgPath+"").hide();
+ $(".dragme").show();
+ game("img3");
+
+ });
+
+ function generate_random_no() { //generate random number
+ var rand_no = Math.ceil(16*Math.random());
+ return rand_no;
+ }
+
+ //update the Random variable number according to the position
+ //update number according to the position and the value
+ function update_Numbers_position(){
+ imgrand[drag_position] = drop_no;
+ imgrand[drop_position] = drag_no;
+ }
+
+ //Check the game over
+ function check_game_over(){
+ var x = 0;
+ for(i=0;i<16;i++){
+ if(imgrand[i] == i+1){
+ x++;
+ }
+ }
+ if(x == 16){ //puzzle solved . Hurray
+ k.audio.correct.play();
+ $(".dragme").hide();
+ $("#"+imgPath+"").fadeIn(5000);
+
+
+ }
+ }
+
+ function game(imgPuzzle){ //draws the necessary random numbers for the game
+ imgPath = imgPuzzle;
+ imgrand[0]=generate_random_no(); //1 number generated, 3 different numbers to be generated
+ for(i=1; i<16; i++){
+ do{
+ flag = 0;
+ imgrand[i] = generate_random_no();
+ for(j=0; j<i; j++){
+ if(imgrand[i]===imgrand[j]){
+ flag++;
+ }
+ }
+ }while(flag != 0 ); //end of do while loop
+ }
+
+ for(i=0; i<16; i++){
+ imgPosition[i] = i;
+ document.getElementById("imgdrag"+i+"").src = "assets/image/"+imgPath+"/"+imgrand[i]+".jpg";
+ }
+
+ } //end of game()
+ $('#feedback_image').bind('dragstart', function(ev) {
+ if (!$(ev.target).hasClass('dragme'))
+ return true;
+ switch (ev.target.id) {
+ case 'imgdrag0':
+ drag_no = imgrand[0]; drag_position = 0; break;
+ case 'imgdrag1':
+ drag_no = imgrand[1]; drag_position = 1; break;
+ case 'imgdrag2':
+ drag_no = imgrand[2]; drag_position = 2; break;
+ case 'imgdrag3':
+ drag_no = imgrand[3]; drag_position = 3; break;
+ case 'imgdrag4':
+ drag_no = imgrand[4]; drag_position = 4; break;
+ case 'imgdrag5':
+ drag_no = imgrand[5]; drag_position = 5; break;
+ case 'imgdrag6':
+ drag_no = imgrand[6]; drag_position = 6; break;
+ case 'imgdrag7':
+ drag_no = imgrand[7]; drag_position = 7; break;
+ case 'imgdrag8':
+ drag_no = imgrand[8]; drag_position = 8; break;
+ case 'imgdrag9':
+ drag_no = imgrand[9]; drag_position = 9; break;
+ case 'imgdrag10':
+ drag_no = imgrand[10]; drag_position = 10; break;
+ case 'imgdrag11':
+ drag_no = imgrand[11]; drag_position = 11; break;
+ case 'imgdrag12':
+ drag_no = imgrand[12]; drag_position = 12; break;
+ case 'imgdrag13':
+ drag_no = imgrand[13]; drag_position = 13; break;
+ case 'imgdrag14':
+ drag_no = imgrand[14]; drag_position = 14; break;
+ case 'imgdrag15':
+ drag_no = imgrand[15]; drag_position = 15; break;
+ }
+
+ //document.display.dragBox.value = drag_no;
+ //document.display.dragPos.value = drag_position;
+
+ return true;
+ });
+
+ // Set up the drop zone.
+ $('#feedback_image').bind('dragenter', function(ev) { // Update the drop zone class on drag enter/leave
+ if (!$(ev.target).hasClass('dragme')) return true;
+ $(ev.target).addClass('dragover'); return false;
+ })
+
+ .bind('dragleave', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ $(ev.target).removeClass('dragover'); return false;
+ })
+
+ // Allow drops of any kind into the zone.
+ .bind('dragover', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ return false;
+ })
+
+ // Handle the final drop...
+ .bind('drop', function(ev) {
+ if (!$(ev.target).hasClass('dragme')) return true;
+ switch (ev.target.id) {
+ case 'imgdrag0':
+ drop_no = imgrand[0]; drop_position = 0; break;
+ case 'imgdrag1':
+ drop_no = imgrand[1]; drop_position = 1; break;
+ case 'imgdrag2':
+ drop_no = imgrand[2]; drop_position = 2; break;
+ case 'imgdrag3':
+ drop_no = imgrand[3]; drop_position = 3; break;
+ case 'imgdrag4':
+ drop_no = imgrand[4]; drop_position = 4; break;
+ case 'imgdrag5':
+ drop_no = imgrand[5]; drop_position = 5; break;
+ case 'imgdrag6':
+ drop_no = imgrand[6]; drop_position = 6; break;
+ case 'imgdrag7':
+ drop_no = imgrand[7]; drop_position = 7; break;
+ case 'imgdrag8':
+ drop_no = imgrand[8]; drop_position = 8; break;
+ case 'imgdrag9':
+ drop_no = imgrand[9]; drop_position = 9; break;
+ case 'imgdrag10':
+ drop_no = imgrand[10]; drop_position = 10; break;
+ case 'imgdrag11':
+ drop_no = imgrand[11]; drop_position = 11; break;
+ case 'imgdrag12':
+ drop_no = imgrand[12]; drop_position = 12; break;
+ case 'imgdrag13':
+ drop_no = imgrand[13]; drop_position = 13; break;
+ case 'imgdrag14':
+ drop_no = imgrand[14]; drop_position = 14; break;
+ case 'imgdrag15':
+ drop_no = imgrand[15]; drop_position = 15; break;
+ }
+
+ moves_count++;
+ //document.display.dropBox.value = drop_no;
+ //document.display.dropPos.value = drop_position;
+ //document.display.moves.value = moves_count;
+
+ document.getElementById("imgdrag"+imgPosition[drag_position]+"").src = "assets/image/"+imgPath+"/"+drop_no+".jpg";
+ document.getElementById("imgdrag"+imgPosition[drop_position]+"").src = "assets/image/"+imgPath+"/"+drag_no+".jpg";
+
+ update_Numbers_position();
+
+
+ //Game over condition
+ check_game_over();
+
+ ev.stopPropagation();
+ return false;
+ });
+
+ });
+}); //end of document.ready
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/trigger.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/trigger.ogg
new file mode 100755
index 0000000..f22512a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/audio/trigger.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/en/sounds/en_correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/en/sounds/en_correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/en/sounds/en_correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/en/sounds/en_incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/en/sounds/en_incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/en/sounds/en_incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/es-MX/sounds/es-MX_correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/es-MX/sounds/es-MX_correct.ogg
new file mode 100755
index 0000000..a54f738
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/es-MX/sounds/es-MX_correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/es-MX/sounds/es-MX_incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/es-MX/sounds/es-MX_incorrect.ogg
new file mode 100755
index 0000000..0474b93
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/es-MX/sounds/es-MX_incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/he/sounds/he_correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/he/sounds/he_correct.ogg
new file mode 100755
index 0000000..4e12c65
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/he/sounds/he_correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/he/sounds/he_incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/he/sounds/he_incorrect.ogg
new file mode 100755
index 0000000..9e314bb
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/he/sounds/he_incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/ball37px.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/ball37px.png
new file mode 100755
index 0000000..4388283
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/ball37px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/balloon37px.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/balloon37px.png
new file mode 100755
index 0000000..8f47d6a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/balloon37px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/banana37px.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/banana37px.png
new file mode 100755
index 0000000..90728e6
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/banana37px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/chilli.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/chilli.png
new file mode 100755
index 0000000..5f8b64d
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/chilli.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/fish64px.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/fish64px.png
new file mode 100755
index 0000000..a29f12c
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/fish64px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/flower37px.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/flower37px.png
new file mode 100755
index 0000000..224e707
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/flower37px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/happyChimp_120x125.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/happyChimp_120x125.png
new file mode 100755
index 0000000..5e721c9
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/happyChimp_120x125.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/happyMonkey.jpg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/happyMonkey.jpg
new file mode 100755
index 0000000..bfe0d38
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/happyMonkey.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/normalChimp_120x125.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/normalChimp_120x125.png
new file mode 100755
index 0000000..a731df4
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/normalChimp_120x125.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/plussign.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/plussign.png
new file mode 100755
index 0000000..915c5aa
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/plussign.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/sadChimp_120x125.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/sadChimp_120x125.png
new file mode 100755
index 0000000..1dec5f0
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/sadChimp_120x125.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/scorebox.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/scorebox.png
new file mode 100755
index 0000000..424b60b
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/scorebox.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/sidebar.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/sidebar.png
new file mode 100755
index 0000000..9632788
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/sidebar.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/yellowBox.png b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/yellowBox.png
new file mode 100755
index 0000000..f7a72ca
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/image/yellowBox.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/ne/sounds/ne_correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/ne/sounds/ne_correct.ogg
new file mode 100755
index 0000000..8ced3cd
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/ne/sounds/ne_correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/ne/sounds/ne_incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/ne/sounds/ne_incorrect.ogg
new file mode 100755
index 0000000..106fe0f
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/assets/ne/sounds/ne_incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/css/knavbar.css b/bundles/XO/karma/lessons/adding_up_to_10_canvas/css/knavbar.css
new file mode 100755
index 0000000..26e3896
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/css/knavbar.css
@@ -0,0 +1,134 @@
+body
+{
+background: #D8D8D8;
+margin:0;
+padding:0;
+}
+
+nav
+{
+list-style: none;
+padding: 0;
+margin: 0;
+float:left;
+width:100%;
+background: #FFFFFF;
+}
+
+nav li
+{
+float: left;
+}
+
+nav li a
+{
+height: 63px;
+text-align: center;
+font-weight: bold;
+font-size: 110%;
+display: block;
+color:#000000;
+padding-left: 0.2em;
+padding-right: 0.2em;
+text-decoration: none;
+}
+
+nav img
+{
+border: none;
+width: 58px;
+}
+
+#welcome
+{
+padding-left: 1em;
+padding-right: 1em;
+line-height: 3em;
+}
+
+#subject
+{
+text-align: center;
+font-weight: bold;
+font-size: 130%;
+}
+
+#lesson_name
+{
+text-align: center;
+font-weight: bold;
+font-size: 150%;
+padding: 0.8em;
+}
+
+#welcome_refs
+{
+text-align: center;
+font-weight: bold;
+font-size: 150%;
+width: 50%;
+float: left;
+}
+
+#tutorial_link
+{
+width: 50%;
+float: left;
+}
+
+#tutorial_link img
+{
+padding: 2em;
+
+}
+
+#exercise_link
+{
+width: 50%;
+float: left;
+}
+
+#exercise_link img
+{
+padding: 2em;
+}
+
+#lesson
+{
+width:800px;
+background: #BDBDBD;
+}
+
+#welcome_logo img
+{
+padding: 2em;
+}
+
+img
+{
+border: none;
+}
+
+nav a:hover {
+text-decoration: underline;
+outline-width:1px;
+outline-style:solid;
+}
+
+nav a.selected {
+text-decoration: underline;
+background: #BDBDBD;
+}
+
+.centeredImage
+{
+text-align:center;
+margin-top:0px;
+margin-bottom:0px;
+padding:0px;
+}
+
+.icon_right
+{
+float: right;
+} \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/css/lesson.css b/bundles/XO/karma/lessons/adding_up_to_10_canvas/css/lesson.css
new file mode 100755
index 0000000..5147cfa
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/css/lesson.css
@@ -0,0 +1,173 @@
+
+#main {
+width:800px;
+height:600px;
+position:absolute;
+}
+#action {
+float:left;
+position:relative;
+width: 650px;
+height: 600px;
+
+}
+#sidebar {
+background-image: url(../assets/generic/images/sidebar.png);
+-moz-background-clip:border;
+-moz-background-inline-policy:continuous;
+-moz-background-origin:padding;
+background:none none repeat scroll 0 0;
+float:left;
+height:600px;
+position:relative;
+width:150px;
+}
+#actionTop {
+width: 650px;
+height: 300px;
+position:relative;
+}
+#bottom {
+clear:both;
+float:left;
+width: 650px;
+height: 300px;
+position:relative;
+}
+#topLtSide {
+float:left;
+width: 300px;
+height: 300px;
+position:relative;
+}
+#topMd {
+-moz-background-clip:border;
+-moz-background-inline-policy:continuous;
+-moz-background-origin:padding;
+background:none none repeat scroll 0 0;
+float:left;
+width: 50px;
+height: 300px;
+position:relative;
+}
+#topRtSide {
+float:left;
+width: 300px;
+height:300px;
+position:relative;
+}
+#topLtBox {
+-moz-background-clip:border;
+-moz-background-inline-policy:continuous;
+-moz-background-origin:padding;
+background:none none repeat scroll 0 0;
+width: 200px;
+height: 200px;
+left: 75px;
+position:absolute;
+top:50px;
+}
+
+#topLtCanvas {
+-moz-background-clip:border;
+-moz-background-inline-policy:continuous;
+-moz-background-origin:padding;
+background:none none repeat scroll 0 0;
+position:absolute;
+top: 50px;
+left: 75px;
+}
+#plussign {
+display: block;
+margin-left: auto;
+margin-right: auto;
+margin-top: 150px;
+}
+#topRtBox {
+background: none none repeat scroll 0 0;
+width: 200px;
+height: 200px;
+position:absolute;
+right: 50px;
+top: 50px;
+}
+#topRtCanvas {
+background:none none repeat scroll 0 0;
+position:absolute;
+left: 50px;
+right:50px;
+top:50px;
+}
+
+.bottom {
+-moz-background-clip:border;
+-moz-background-inline-policy:continuous;
+-moz-background-origin:padding;
+background:none none repeat scroll 0 0;
+float:left;
+width: 216.5px;
+height: 300px;
+position:relative;
+}
+
+.bottomBox {
+ left:25px;
+ position:absolute;
+ width: 200px;
+ height: 200px;
+ top: 20px;
+}
+
+.sidebarItem {
+ clear:both;
+ float:left;
+ width:150px;
+ height: 200px;
+ position: relative;
+}
+
+#timer {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+}
+
+#timerCanvas {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+}
+
+#scorebox {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+}
+
+#scoreboxCanvas {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+}
+
+
+#chimpCanvas {
+position:absolute;
+top:10px;
+left:25px;
+
+}
+
+#buttons {
+position:absolute;
+top:80%;
+}
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/exercise.html b/bundles/XO/karma/lessons/adding_up_to_10_canvas/exercise.html
new file mode 100755
index 0000000..eaf3d63
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/exercise.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Adding up to 10 - Exercise (Alpha)</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <link type="image/ico" rel="icon" href="../../assets/default/images/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="../../css/karma.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.Gettext.js"></script>
+ <script type="text/javascript" src="../../js/jquery.karma.js"></script>
+
+ <link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+</head>
+
+<body>
+
+<div id="lesson">
+<nav>
+<li><a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back"></a></li>
+<li><a id="welcome" href="index_knavbar.html">Adding up to 10</a></li>
+<li><img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial"></li>
+<li><a href="exercise.html" class="selected"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise"></a></li>
+<li><a href="#tab_help"><img src="../../assets/default/images/help.png" alt="Help" title="Help"></a></li>
+<li><a href="http://olenepal.org/" target="_blank"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal Web site"></a></li>
+</nav>
+
+
+ <div id="karma-main">
+ <div id="action">
+ <div id="actionTop">
+
+ <div id="topLtSide">
+ <img id="topLtBox" src="assets/generic/images/yellowBox.png" alt="" />
+ <canvas id="topLtCanvas" width="200px" height="200px"></canvas>
+
+ </div>
+ <div id="topMd">
+ <img id="plussign" src="assets/generic/images/plussign.png" alt=""/>
+ </div>
+ <div id="topRtSide">
+ <img id="topRtBox" src="assets/generic/images/yellowBox.png" alt=""/>
+ <canvas id="topRtCanvas" width="200px" height="200px"></canvas>
+ </div>
+
+ </div>
+
+ <div id="bottom">
+ <!-- <canvas id="bottomCanvas"></canvas> -->
+ <div id="bottomLt" class="bottom">
+ <img class="bottomBox" src="assets/generic/images/yellowBox.png" alt=""/>
+ <canvas id="bottomLtCanvas" class="bottomBox" width="200px" height="200px"> </canvas>
+ </div>
+ <div id="bottomMd" class="bottom">
+ <img class="bottomBox" src="assets/generic/images/yellowBox.png" alt=""/>
+ <canvas id="bottomMdCanvas" class="bottomBox" width="200px" height="200px"> </canvas>
+ </div>
+ <div id="bottomRt" class="bottom">
+ <img class="bottomBox" src="assets/generic/images/yellowBox.png" alt=""/>
+ <canvas id="bottomRtCanvas" class="bottomBox" width="200px" height="200px"> </canvas>
+ </div>
+
+ </div>
+
+ </div>
+ <div id="sidebar">
+ <div class="sidebarItem">
+ <img id="timer" src="assets/generic/images/scorebox.png" alt=""/>
+ <canvas id="timerCanvas" width="100" height="140" > </canvas>
+ </div>
+ <div class="sidebarItem">
+ <img id="scorebox" src="assets/generic/images/scorebox.png" alt=""/>
+ <canvas id="scoreboxCanvas" width="100" height="140" />
+ </div>
+ <div class="sidebarItem">
+ <canvas id="chimpCanvas" width="120px" height="125px"> </canvas>
+ <button id="reset">Start Over</button>
+ </div>
+
+
+ </div>
+
+
+ </div>
+</div>
+
+</body>
+
+</html>
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/index.html b/bundles/XO/karma/lessons/adding_up_to_10_canvas/index.html
new file mode 100755
index 0000000..a87db80
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/index.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Karma - Adding Up to 10</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="../../css/karma.css" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+
+
+
+</head>
+
+<body>
+ <div>
+ <div id="action">
+ <div id="actionTop">
+
+ <div id="topLtSide">
+ <img id="topLtBox" src="assets/image/yellowBox.png" alt="" />
+ <canvas id="topLtCanvas" width="200px" height="200px"></canvas>
+
+ </div>
+ <div id="topMd">
+ <img id="plussign" src="assets/image/plussign.png" alt=""/>
+ </div>
+ <div id="topRtSide">
+ <img id="topRtBox" src="assets/image/yellowBox.png" alt=""/>
+ <canvas id="topRtCanvas" width="200px" height="200px"></canvas>
+ </div>
+
+ </div>
+
+ <div id="bottom">
+ <!-- <canvas id="bottomCanvas"></canvas> -->
+ <div id="bottomLt" class="bottom">
+ <img class="bottomBox" src="assets/image/yellowBox.png" alt=""/>
+ <canvas id="bottomLtCanvas" class="bottomBox" width="200px" height="200px"> </canvas>
+ </div>
+ <div id="bottomMd" class="bottom">
+ <img class="bottomBox" src="assets/image/yellowBox.png" alt=""/>
+ <canvas id="bottomMdCanvas" class="bottomBox" width="200px" height="200px"> </canvas>
+ </div>
+ <div id="bottomRt" class="bottom">
+ <img class="bottomBox" src="assets/image/yellowBox.png" alt=""/>
+ <canvas id="bottomRtCanvas" class="bottomBox" width="200px" height="200px"> </canvas>
+ </div>
+
+ </div>
+
+ </div>
+ <div id="sidebar">
+ <div class="sidebarItem">
+ <img id="timer" src="assets//image/scorebox.png" alt=""/>
+ <canvas id="timerCanvas" width="100px" height="140px" > </canvas>
+ </div>
+ <div class="sidebarItem">
+ <img id="scorebox" src="assets/image/scorebox.png" alt=""/>
+ <canvas id="scoreboxCanvas" width="100px" height="140px"></canvas>
+ </div>
+ <div class="sidebarItem">
+ <canvas id="chimpCanvas" width="120px" height="125px"> </canvas>
+ <div id="buttons">
+ <button id="start">Start</button>
+ <button id="stop">Stop</button>
+ <button id="reset">Restart</button>
+ </div>
+ </div>
+
+
+ </div>
+
+
+ </div>
+
+
+</body>
+
+</html>
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/index_knavbar.html b/bundles/XO/karma/lessons/adding_up_to_10_canvas/index_knavbar.html
new file mode 100755
index 0000000..e1e2fca
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/index_knavbar.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html lang="en">
+
+<head>
+<title>Adding up to 10 - Index (Alpha)</title>
+<meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta charset="utf-8">
+
+<link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
+<script type="text/javascript" src="js/jquery.ui.all.js"></script>
+
+</head>
+
+<body>
+
+<div id="lesson">
+
+<nav>
+<li><a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back"></a></li>
+<li><a id="welcome" href="index_knavbar.html" class="selected">Adding up to 10</a></li>
+</nav>
+
+<div id="subject">Mathematics</div>
+<div id="lesson_name">Adding up to 10</div>
+
+<div id="tutorial_link" class="centeredImage"><img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial"></div>
+<div id="exercise_link" class="centeredImage"><a href="exercise.html"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise"></a></div>
+
+<div id="welcome_refs"><a href="assets/en/docs/teachernotes.swf" target="_blank">Teacher's note</a></div>
+<div id="welcome_refs"><a href="assets/en/docs/lessonplan.swf" target="_blank">Lesson plan</a></div>
+
+<div id="welcome_logo" class="centeredImage"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal"></div>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/js/lesson.js b/bundles/XO/karma/lessons/adding_up_to_10_canvas/js/lesson.js
new file mode 100755
index 0000000..6581bdf
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/js/lesson.js
@@ -0,0 +1,300 @@
+$(document).ready(
+ function(){
+
+ var k = Karma({
+ image: [
+ {name: "ball", file: "ball37px.png"},
+ {name: "balloon", file: "balloon37px.png"},
+ {name: "banana", file: "banana37px.png"},
+ {name: "chilli", file: "chilli.png"},
+ {name: "fish" , file: "fish64px.png"},
+ {name: "flower", file: "flower37px.png"},
+ {name: "normalChimp", file: "normalChimp_120x125.png"},
+ {name: "happyChimp", file: "happyChimp_120x125.png"},
+ {name: "sadChimp", file: "sadChimp_120x125.png"}
+ ]
+ ,
+ audio: [
+ {name: "correct", file: "correct.ogg"},
+ {name: "incorrect", file: "incorrect.ogg"},
+ {name: "trigger", file: "trigger.ogg"}
+ ],
+ canvas: [
+ {name:"topLt", domId:"topLtCanvas"},
+ {name:"topRt", domId:"topRtCanvas"},
+ {name:"bottomLt", domId:"bottomLtCanvas"},
+ {name:"bottomMd", domId:"bottomMdCanvas"},
+ {name:"bottomRt", domId:"bottomRtCanvas"},
+ {name:"timer", domId:"timerCanvas"},
+ {name:"scorebox", domId:"scoreboxCanvas"},
+ {name:"chimp", domId:"chimpCanvas"}
+ ]
+ });
+
+
+ k.ready(function() {
+ var imgNames = ["ball", "banana", "balloon","chilli", "fish", "flower"];
+ //game logic
+ var total, level=0, time, n0, n1, correct;
+ var maskd=200;
+ var d=160;
+ var choices=[];
+ var score = 0;
+ var speed = 2000;
+ var playerCorrect = 0;
+ var endTimerX = 80;
+ var startTimerY = 10;
+ var endTimerY = 100;
+ var offsetTimerY = 5;
+ var timerId;
+ var isGameRunning = false;
+
+ var timerFn = function () {
+ k.canvas['timer'].clear();
+
+ if ( startTimerY >= endTimerY ){
+ //you didn't answer in time
+ k.audio["trigger"].play();
+ answer(false, true);
+ game();
+ }
+ else {
+ k.canvas['timer'].clear();
+ startTimerY = startTimerY + offsetTimerY;
+ k.canvas['timer'].fillStyle("#ffffff").
+ fillRect(10, startTimerY, endTimerX, 20);
+ }
+ };
+
+ function game () {
+ $.each(k.canvas, function () {
+ if (this.name != "chimp"){
+ this.clear();
+ }
+ });
+
+
+ writeScore();
+ total = k.rand( 2, 10 ); //the total
+ n0 = total - k.rand(1, total - 1 ); //first number
+ n1 = total - n0; //second number
+
+ //chose one option (the correct option)
+ //and then put the correct value into it
+ correct = k.rand( 0, 2 );
+ choices[ correct ] = total;
+
+ for (var i=0; i<3; i++) {
+ //generate the two other options
+ if ( choices[i] === total) {
+ continue;
+ } else {
+ // generate the other options
+ choices[ i ] = k.rand( 2, 10 );
+ for (var j = 0; j < i; j++){
+ if (choices[i] === choices[j]) {
+ choices[ i ] = k.rand( 2, 10 );
+ }
+ }
+ }
+ }
+
+ var imgId = imgNames[ level ] ;
+
+
+ var card = function (canvas, n, minx, miny, d ) {
+ canvas.save();
+ var pos = [];
+ var x, y, flag;
+
+
+ for (var i=0; i<n; i++) {
+ do {
+ flag = false;
+ x = k.rand( 0, d );
+ y = k.rand( 0, d );
+ for ( var j=0; j<pos.length; j++) {
+ if ( k.distance2( pos[j],
+ {"x": x, "y": y} ) < 120 ) {
+ flag = true;
+ break;
+ }
+ }
+
+ }while ( flag === true );
+ pos.push( { "x":x, "y": y } );
+ //k.image[ imgId ].draw(canvas, x, y )
+ canvas.drawImage(k.image[imgId].media, x, y);
+ }
+
+
+
+ canvas.restore();
+ };
+
+
+ //put the cards
+ card(k.canvas["topLt"], n0 , 0, 0, d);
+ card(k.canvas["topRt"], n1 , 0, 0, d);
+ card(k.canvas["bottomLt"], choices[ 0 ] , 0, 0, d);
+ card(k.canvas["bottomMd"], choices[ 1 ] , 0, 0, d);
+ card(k.canvas["bottomRt"], choices[ 2 ] , 0, 0, d);
+
+ }
+
+ var writeScore = function (){
+ k.canvas["scorebox"].save().
+ clear().
+ font("bold 50px sans-serif white").
+ fillStyle("#fff").
+ textBaseline("middle").
+ fillText("" + score, 30, 100).
+ restore();
+ };
+
+ var answer = function (correct, tooSlow) {
+
+ if ( correct === false) {
+ //answer was incorrect or took too long
+ score = score - 1;
+ playerCorrect = playerCorrect - 1;
+ writeScore();
+ if (tooSlow === true) {
+ k.audio[ "trigger" ].play();
+ } else {
+ k.audio[ "incorrect" ].play();
+ }
+ animateChimp(false);
+
+ } else {
+ score = score + 1;
+ playerCorrect = playerCorrect + 1;
+ writeScore();
+ k.audio[ "correct" ].play();
+ animateChimp(true);
+ if (playerCorrect === 5){
+ level = (level+1)% imgNames.length;
+ speed = speed - 300;
+ playerCorrect = 0;
+ }
+ }
+
+ changeTimer('start');
+
+ };
+
+ var animateChimp = function (answer) {
+ var timerChimp;
+ k.canvas["chimp"].clear();
+ if( answer === true){
+ k.canvas["chimp"].drawImage(
+ k.image["happyChimp"].media, 0, 0);
+ } else {
+ k.canvas["chimp"].drawImage(
+ k.image["sadChimp"].media, 0, 0);
+ }
+
+ var restoreChimp = function () {
+ k.canvas["chimp"].clear();
+ k.canvas["chimp"].drawImage(
+ k.image["normalChimp"].media, 0, 0);
+ };
+
+ timerChimp = setTimeout(restoreChimp, 800);
+
+
+ };
+
+ var changeTimer = function (status){
+ startTimerY = 10;
+ k.canvas["timer"].clear();
+ clearInterval(timerId);
+
+ if (status === 'start'){
+ timerId = setInterval(timerFn, speed);
+ }
+
+ };
+
+ var startStop = function (start) {
+ score = level = 0;
+ startTimerY = 10;
+ isGameRunning = true;
+
+ $.each(k.canvas, function () {
+ if (this.name != "chimp"){
+ this.clear();
+ }
+ });
+
+ changeTimer('start');
+ game();
+
+
+ };
+
+ var start = function () {
+ startStop(true);
+ };
+
+
+ var stop = function () {
+ isGameRunning = false;
+
+ changeTimer('stop');
+ $.each(k.canvas, function () {
+ if (this.name != "chimp"){
+ this.clear();
+ }
+ });
+ };
+
+ var reset = function () {
+ startStop(true);
+ };
+
+
+
+
+
+ //put the buttons
+ var buttons=[];
+ buttons[ 0 ] = { "canvas": k.canvas["bottomLt"], "id": 0};
+ buttons[ 1 ] = { "canvas": k.canvas["bottomMd"], "id": 1};
+ buttons[ 2 ] = { "canvas": k.canvas["bottomRt"], "id": 2};
+
+
+
+ $.each(buttons, function( key, item ) {
+ item.canvas.node
+ .addEventListener('click',
+ function ( ev ) {
+ if(isGameRunning === true){
+ if ( choices[ item.id ] === total){
+ answer(true);
+ game();
+ }else {
+ answer(false);
+ game();
+ }
+ }
+ }, false);
+ });
+
+ document.getElementById('start').
+ addEventListener('click', start, false);
+
+
+ document.getElementById('stop').
+ addEventListener('click', stop, false);
+
+ document.getElementById('reset').
+ addEventListener('click', reset, false);
+
+ k.canvas["chimp"].drawImage(
+ k.image["normalChimp"].media, 0, 0);
+
+ });
+
+
+ }); \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/js/lesson1.js b/bundles/XO/karma/lessons/adding_up_to_10_canvas/js/lesson1.js
new file mode 100755
index 0000000..bce243f
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/js/lesson1.js
@@ -0,0 +1,326 @@
+$(document).ready(
+ function(){
+
+ var k = Karma({
+ images: [
+ {name: "ball", file: "ball37px.png"},
+ {name: "balloon", file: "balloon37px.png"},
+ {name: "banana", file: "banana37px.png"},
+ {name: "chilli", file: "chilli.png"},
+ {name: "fish" , file: "fish64px.png"},
+ {name: "flower", file: "flower37px.png"},
+ {name: "normalChimp", file: "normalChimp_120x125.png"},
+ {name: "happyChimp", file: "happyChimp_120x125.png"},
+ {name: "sadChimp", file: "sadChimp_120x125.png"}
+ ]
+ ,
+ sounds: [
+ {name: "correct", file: "correct.ogg"},
+ {name: "incorrect", file: "incorrect.ogg"},
+ {name: "trigger", file: "trigger.ogg"}
+ ],
+ canvases: [
+ {name:"topLt", domId:"topLtCanvas"},
+ {name:"topRt", domId:"topRtCanvas"},
+ {name:"bottomLt", domId:"bottomLtCanvas"},
+ {name:"bottomMd", domId:"bottomMdCanvas"},
+ {name:"bottomRt", domId:"bottomRtCanvas"},
+ {name:"timer", domId:"timerCanvas"},
+ {name:"scorebox", domId:"scoreboxCanvas"},
+ {name:"chimp", domId:"chimpCanvas"}
+ ]
+ });
+
+
+ k.ready(function() {
+
+ k.canvases['timer'].clear();
+
+ k.canvases["scorebox"].save().
+ //clear().
+ font("bold 50px sans-serif white").
+ fillStyle("#fff").
+ textBaseline("middle").
+ fillText("foo", 30, 100).
+ restore();
+ k.canvases["topLt"].ctx.drawImage(k.images["ball"].media, 5, 10);
+
+ /* k.canvases["topLt"].ctx.drawImage(k.images["ball"].media, 5, 10);
+ k.canvases['timer'].ctx.fillRect(10, 30, 40, 20);
+
+ k.canvases['timer'].ctx.fillStyle = "#fff";
+ k.canvases['timer'].ctx.fillRect(10, startTimerY, endTimerX, 20);
+ k.canvases['timer'].clear();
+ k.rand( 2, 10 );
+
+ k.canvases["scorebox"].save().
+ clear().
+ font("bold 50px sans-serif white").
+ fillStyle("#fff").
+ textBaseline("middle").
+ fillText("" + score, 30, 100).
+ restore();
+ */
+
+/*
+ var imgNames = ["ball", "banana", "balloon","chilli", "fish", "flower"];
+ //game logic
+ var total, level=0, time, n0, n1, correct;
+ var maskd=200;
+ var d=160;
+ var choices=[];
+ var score = 0;
+ var correct;
+ var speed = 2000;
+ var playerCorrect = 0;
+ var endTimerX = 80;
+ var startTimerY = 10;
+ var endTimerY = 100;
+ var offsetTimerY = 5;
+ var timerId;
+
+ var timerFn = function () {
+ k.canvases['timer'].clear();
+
+ if ( startTimerY >= endTimerY ){
+ //you didn't answer in time
+ k.sounds["trigger"].play();
+ answer(false, true);
+ game();
+ }
+ else {
+ k.canvases['timer'].clear();
+ startTimerY = startTimerY + offsetTimerY;
+ k.canvases['timer'].ctx.fillStyle = "#fff";
+ k.canvases['timer'].ctx.fillRect(10, startTimerY, endTimerX, 20);
+ }
+ };
+
+
+ function game () {
+ $.each(k.canvases, function () {
+ if (this.name != "chimp"){
+ this.clear();
+ }
+ });
+
+
+ writeScore();
+ total = k.rand( 2, 10 ); //the total
+ n0 = total - k.rand(1, total - 1 ); //first number
+ n1 = total - n0; //second number
+
+ //chose one option (the correct option)
+ //and then put the correct value into it
+ correct = k.rand( 0, 2 );
+ choices[ correct ] = total;
+
+ for (var i=0; i<3; i++) {
+ //generate the two other options
+ if ( choices[i] === total) {
+ continue;
+ } else {
+ // generate the other options
+ choices[ i ] = k.rand( 2, 10 );
+ for (var j = 0; j < i; j++){
+ if (choices[i] === choices[j]) {
+ choices[ i ] = k.rand( 2, 10 );
+ }
+ }
+ }
+ }
+
+ var imgId = imgNames[ level ] ;
+
+
+ var card = function (surface, n, minx, miny, d ) {
+ surface.save();
+ //var r = k.rectangle({x:minx, y:miny, width:maskd, height:maskd,
+ // stroke:false,fill:false}).draw(surface);
+
+ // var r = surface.rectangle({x:minx, y:miny, width:maskd, height:maskd,
+ // stroke:false,fill:false} );
+
+ //do the clip
+ //surface.clip();
+ var pos = [];
+ var x, y, flag;
+
+
+ for (var i=0; i<n; i++) {
+ do {
+ flag = false;
+ x = k.rand( 0, d );
+ y = k.rand( 0, d );
+ for ( var j=0; j<pos.length; j++) {
+ if ( k.distance2( pos[j],
+ {"x": x, "y": y} ) < 120 ) {
+ flag = true;
+ break;
+ }
+ }
+
+ }while ( flag === true );
+ pos.push( { "x":x, "y": y } );
+ //k.images[ imgId ].draw(surface, x, y )
+ surface.drawImage(k.images[imgId], x, y);
+ }
+
+
+
+ surface.restore();
+ }
+
+
+ //put the cards
+ card(k.canvases["topLt"], n0 , 0, 0, d);
+ card(k.canvases["topRt"], n1 , 0, 0, d);
+ card(k.canvases["bottomLt"], choices[ 0 ] , 0, 0, d);
+ card(k.canvases["bottomMd"], choices[ 1 ] , 0, 0, d);
+ card(k.canvases["bottomRt"], choices[ 2 ] , 0, 0, d);
+
+ }
+
+ var writeScore = function (){
+ k.canvases["scorebox"].save().
+ clear().
+ font("bold 50px sans-serif white").
+ fillStyle("#fff").
+ textBaseline("middle").
+ fillText("" + score, 30, 100).
+ restore();
+ };
+
+ var answer = function (correct, tooSlow) {
+
+ if ( correct === false) {
+ //answer was incorrect or took too long
+ score = score - 1;
+ playerCorrect = playerCorrect - 1;
+ writeScore();
+ if (tooSlow === true) {
+ k.sounds[ "trigger" ].play();
+ } else {
+ k.sounds[ "incorrect" ].play();
+ }
+ //animate sad monkey
+ animateChimp(false);
+
+ } else {
+ score = score + 1;
+ playerCorrect = playerCorrect + 1;
+ writeScore();
+ k.sounds[ "correct" ].play();
+ animateChimp(true);
+ if (playerCorrect === 5){
+ level = (level+1)% imgNames.length;
+ speed = speed - 300;
+ playerCorrect = 0;
+ }
+ }
+
+ changeTimer('start');
+
+ };
+
+ var animateChimp = function (answer) {
+ var timerChimp;
+ k.canvases["chimp"].clear();
+ if( answer === true){
+ //k.images["happyChimp"].draw(k.canvases["chimp"], 0, 0);
+ k.canvases["chimp"].drawImage(k.images["happyChimp"], 0, 0);
+ } else {
+ k.canvases["chimp"].drawImage(k.images["sadChimp"], 0, 0);
+ }
+
+ var restoreChimp = function () {
+ k.canvases["chimp"].clear();
+ k.canvases["chimp"].drawImage(k.images["normalChimp"], 0, 0);
+ };
+
+ timerChimp = setTimeout(restoreChimp, 800);
+
+
+ };
+
+ var changeTimer = function (status){
+ startTimerY = 10;
+ k.canvases["timer"].clear();
+ clearInterval(timerId);
+
+ if (status === 'start'){
+ timerId = setInterval(timerFn, speed);
+ }
+
+ };
+
+ var startStop = function (start) {
+ score = level = 0;
+ startTimerY = 10;
+ $.each(k.canvases, function () {
+ if (this.name != "chimp"){
+ this.clear();
+ }
+ });
+
+ changeTimer('start');
+ game();
+
+
+ };
+
+ var start = function () {
+ startStop(true);
+ };
+
+
+ var stop = function () {
+ changeTimer('stop');
+ };
+
+ var reset = function () {
+ startStop(true);
+ };
+
+
+
+
+
+ //put the buttons
+ var buttons=[];
+ buttons[ 0 ] = { "surface": k.canvases["bottomLt"], "id": 0};
+ buttons[ 1 ] = { "surface": k.canvases["bottomMd"], "id": 1};
+ buttons[ 2 ] = { "surface": k.canvases["bottomRt"], "id": 2};
+
+ $.each(buttons, function( key, item ) {
+ item.surface.node.addEventListener('click', function( ev ) {
+ if ( choices[ item.id ] === total){
+ answer(true);
+ game();
+ }else {
+ answer(false);
+ game();
+ }
+
+ }, false);
+ });
+
+ document.getElementById('start').
+ addEventListener('click', start, false);
+
+
+ document.getElementById('stop').
+ addEventListener('click', stop, false);
+
+ document.getElementById('reset').
+ addEventListener('click', reset, false);
+
+ k.canvases["chimp"].drawImage(k.images["normalChimp"], 0, 0);
+
+ //end of Karma.main
+ });
+*/
+
+ //end of ready
+ });
+ }); \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/en.po b/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/en.po
new file mode 100755
index 0000000..4d1444f
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/en.po
@@ -0,0 +1,28 @@
+# English translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe LĂłpez Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: English\n"
+"X-Poedit-Country: United States\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "choose an optionxxxxxxx"
+
+msgid "Time"
+msgstr "Time1"
+
+msgid "Level"
+msgstr "Level1"
+
+msgid "Restart"
+msgstr "Restart1"
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/es-MX.po b/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/es-MX.po
new file mode 100755
index 0000000..ca1e61c
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/es-MX.po
@@ -0,0 +1,29 @@
+# Spanish translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe LĂłpez Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+"X-Poedit-Country: MEXICO\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "escoge una opciĂłn"
+
+msgid "Time"
+msgstr "Tiempo"
+
+msgid "Level"
+msgstr "Nivel"
+
+msgid "Restart"
+msgstr "Reinicia"
+
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/es.po b/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/es.po
new file mode 100755
index 0000000..b665366
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/es.po
@@ -0,0 +1,29 @@
+# Spanish translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe LĂłpez Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+"X-Poedit-Country: MEXICO\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "escoge una opciĂłnXXX"
+
+msgid "Time"
+msgstr "Tiempo"
+
+msgid "Level"
+msgstr "Nivel"
+
+msgid "Restart"
+msgstr "Reinicia"
+
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/he-IL.po b/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/he-IL.po
new file mode 100755
index 0000000..f681aca
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/po/he-IL.po
@@ -0,0 +1,28 @@
+# Hebrew translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe LĂłpez Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Hebrew\n"
+"X-Poedit-Country: Israel\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "בחר ב×פשרות"
+
+msgid "Time"
+msgstr "שעה"
+
+msgid "Level"
+msgstr "רמת"
+
+msgid "Restart"
+msgstr "הפעל מחדש"
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_canvas/resources.html b/bundles/XO/karma/lessons/adding_up_to_10_canvas/resources.html
new file mode 100755
index 0000000..0e93455
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_canvas/resources.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Karma - Adding Up to 10</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <link type="image/ico" rel="icon" href="../../assets/default/images/favicon.ico" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.Gettext.js"></script>
+ <script type="text/javascript" src="../../js/jquery.karma.js"></script>
+ <link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+</head>
+
+<body>
+
+<div id="lesson">
+<nav>
+<li><a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back"></a></li>
+<li><a href="../../index.html"><img src="../../assets/default/images/chakra_logo.png" alt="Chakra" title="Chakra"></a></li>
+<li><a id="welcome" href="index_knavbar.html">Adding up to 10</a></li>
+<li><img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial"></li>
+<li><a href="exercise.html"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise"></a></li>
+<li><a href="resources.html" class="selected"><img src="../../assets/default/images/resources.png" alt="Resources" title="Resources"></a></li>
+<li><a href="#tab_help"><img src="../../assets/default/images/help.png" alt="Help" title="Help"></a></li>
+<li><a href="http://olenepal.org/" target="_blank"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal Web site"></a></li>
+</nav>
+
+<li><a href="assets/en/docs/teachernotes.swf" target="_blank">Teacher's notes</a></li>
+<li><a href="assets/en/docs/lessonplan.swf" target="_blank">Lesson plan</a></li>
+<li><a href="quadrilaterals.zip">Download</a></li>
+</div>
+
+</body>
+
+</html>
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/trigger.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/trigger.ogg
new file mode 100755
index 0000000..f22512a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/audio/trigger.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/en/sounds/en_correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/en/sounds/en_correct.ogg
new file mode 100755
index 0000000..a0d9e3a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/en/sounds/en_correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/en/sounds/en_incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/en/sounds/en_incorrect.ogg
new file mode 100755
index 0000000..4805e55
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/en/sounds/en_incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/es-MX/sounds/es-MX_correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/es-MX/sounds/es-MX_correct.ogg
new file mode 100755
index 0000000..a54f738
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/es-MX/sounds/es-MX_correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/es-MX/sounds/es-MX_incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/es-MX/sounds/es-MX_incorrect.ogg
new file mode 100755
index 0000000..0474b93
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/es-MX/sounds/es-MX_incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/he/sounds/he_correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/he/sounds/he_correct.ogg
new file mode 100755
index 0000000..4e12c65
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/he/sounds/he_correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/he/sounds/he_incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/he/sounds/he_incorrect.ogg
new file mode 100755
index 0000000..9e314bb
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/he/sounds/he_incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/ball37px.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/ball37px.png
new file mode 100755
index 0000000..4388283
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/ball37px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/balloon37px.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/balloon37px.png
new file mode 100755
index 0000000..8f47d6a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/balloon37px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/banana37px.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/banana37px.png
new file mode 100755
index 0000000..90728e6
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/banana37px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/chilli.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/chilli.png
new file mode 100755
index 0000000..5f8b64d
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/chilli.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/fish64px.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/fish64px.png
new file mode 100755
index 0000000..a29f12c
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/fish64px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/flower37px.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/flower37px.png
new file mode 100755
index 0000000..224e707
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/flower37px.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/happyChimp_120x125.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/happyChimp_120x125.png
new file mode 100755
index 0000000..5e721c9
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/happyChimp_120x125.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/happyMonkey.jpg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/happyMonkey.jpg
new file mode 100755
index 0000000..bfe0d38
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/happyMonkey.jpg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/normalChimp_120x125.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/normalChimp_120x125.png
new file mode 100755
index 0000000..a731df4
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/normalChimp_120x125.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/plussign.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/plussign.png
new file mode 100755
index 0000000..915c5aa
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/plussign.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/sadChimp_120x125.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/sadChimp_120x125.png
new file mode 100755
index 0000000..1dec5f0
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/sadChimp_120x125.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/scorebox.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/scorebox.png
new file mode 100755
index 0000000..424b60b
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/scorebox.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/sidebar.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/sidebar.png
new file mode 100755
index 0000000..9632788
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/sidebar.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/yellowBox.png b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/yellowBox.png
new file mode 100755
index 0000000..f7a72ca
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/image/yellowBox.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/ne/sounds/ne_correct.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/ne/sounds/ne_correct.ogg
new file mode 100755
index 0000000..8ced3cd
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/ne/sounds/ne_correct.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/ne/sounds/ne_incorrect.ogg b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/ne/sounds/ne_incorrect.ogg
new file mode 100755
index 0000000..106fe0f
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/assets/ne/sounds/ne_incorrect.ogg
Binary files differ
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/css/knavbar.css b/bundles/XO/karma/lessons/adding_up_to_10_svg/css/knavbar.css
new file mode 100755
index 0000000..b39f205
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/css/knavbar.css
@@ -0,0 +1,139 @@
+body
+{
+background: #D8D8D8;
+margin:0;
+padding:0;
+}
+
+#knavbar {
+display: table;
+width: 800px;
+margin: 0 auto;
+}
+
+nav
+{
+list-style: none;
+padding: 0;
+margin: 0;
+float:left;
+width:100%;
+background: #FFFFFF;
+}
+
+nav img
+{
+border: none;
+width: 58px;
+}
+
+#welcome
+{
+padding-left: 1em;
+padding-right: 1em;
+line-height: 3em;
+}
+
+#subject
+{
+text-align: center;
+font-weight: bold;
+font-size: 130%;
+}
+
+#lesson_name
+{
+text-align: center;
+font-weight: bold;
+font-size: 150%;
+padding: 0.8em;
+}
+
+#welcome_refs
+{
+text-align: center;
+font-weight: bold;
+font-size: 150%;
+width: 50%;
+float: left;
+}
+
+#tutorial_link
+{
+width: 50%;
+float: left;
+}
+
+#tutorial_link img
+{
+padding: 2em;
+
+}
+
+#exercise_link
+{
+width: 50%;
+float: left;
+}
+
+#exercise_link img
+{
+padding: 2em;
+}
+
+#lesson
+{
+width:800px;
+background: #BDBDBD;
+}
+
+#welcome_logo img
+{
+padding: 2em;
+}
+
+img
+{
+border: none;
+}
+
+#lessonTitle
+{
+display: block;
+}
+
+nav a:hover {
+text-decoration: underline;
+outline-width:1px;
+outline-style:solid;
+}
+
+nav a.selected {
+text-decoration: underline;
+background: #BDBDBD;
+}
+
+.centeredImage
+{
+text-align:center;
+margin-top:0px;
+margin-bottom:0px;
+padding:0px;
+}
+
+.icon_right
+{
+float: right;
+}
+
+.floatLeft {
+ float: left;
+ margin-left: 5px;
+ margin-bottom: 5px;
+}
+
+.floatRight {
+ float: right;
+ margin-right: 5px;
+ margin-bottom: 5px;
+} \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/css/lesson.css b/bundles/XO/karma/lessons/adding_up_to_10_svg/css/lesson.css
new file mode 100755
index 0000000..e368b14
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/css/lesson.css
@@ -0,0 +1,171 @@
+@charset "UTF-8";
+
+#karma-main {
+width:800px;
+height:600px;
+position:absolute;
+}
+
+#main {
+float:left;
+position:relative;
+width: 650px;
+height: 600px;
+
+}
+#side {
+background-image: url(../assets/generic/images/sidebar.png);
+background:none none repeat scroll 0 0;
+float:left;
+height:600px;
+position:relative;
+width:150px;
+}
+
+#top {
+width: 650px;
+height: 300px;
+position:relative;
+}
+
+#bottom {
+clear:both;
+float:left;
+width: 650px;
+height: 300px;
+position:relative;
+}
+#topLeftArea {
+float:left;
+width: 300px;
+height: 300px;
+position:relative;
+}
+#topMiddleArea {
+background:none none repeat scroll 0 0;
+float:left;
+width: 50px;
+height: 300px;
+position:relative;
+}
+#topRightArea {
+float:left;
+width: 300px;
+height:300px;
+position:relative;
+}
+#topLeftCard {
+background:none none repeat scroll 0 0;
+width: 200px;
+height: 200px;
+left: 75px;
+position:absolute;
+top:50px;
+}
+
+#topLeftPaper {
+background:none none repeat scroll 0 0;
+position:absolute;
+top: 50px;
+left: 75px;
+width:200px;
+height:200px;
+}
+
+#plusSign {
+display: block;
+margin-left: auto;
+margin-right: auto;
+margin-top: 150px;
+}
+#topRightCard {
+background: none none repeat scroll 0 0;
+width: 200px;
+height: 200px;
+position:absolute;
+right: 50px;
+top: 50px;
+}
+#topRightPaper {
+background:none none repeat scroll 0 0;
+position:absolute;
+left: 50px;
+right:50px;
+top:50px;
+width:200px;
+height:200px;
+}
+
+.bottom {
+background:none none repeat scroll 0 0;
+float:left;
+width: 216.5px;
+height: 300px;
+position:relative;
+}
+
+.bottomCard {
+ left:25px;
+ position:absolute;
+ width: 200px;
+ height: 200px;
+ top: 20px;
+}
+
+
+.sideItem {
+ clear:both;
+ float:left;
+ width:150px;
+ height: 200px;
+ position: relative;
+}
+
+#timer {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+}
+
+#timerPaper {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+}
+
+#scoreBox {
+position:absolute;
+width:100px;
+height:150px;
+top:10px;
+left:25px;
+z-index: 10;
+}
+
+#scoreBoxText {
+position:relative;
+top:60px;
+font: 70px Arial;
+color: #fff;
+text-align: center;
+z-index: 100;
+}
+
+
+#chimpPaper {
+position:absolute;
+top:10px;
+left:25px;
+width:120px;
+height:125px;
+}
+
+#buttons {
+position:absolute;
+top:80%;
+}
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/exercise.html b/bundles/XO/karma/lessons/adding_up_to_10_svg/exercise.html
new file mode 100755
index 0000000..97d0855
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/exercise.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Adding up to 10 - Exercise (Alpha)</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/images/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="../../css/karma.css" />
+ <script type="text/javascript" src="../../js/raphael-min.js"></script>
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.Gettext.js"></script>
+ <script type="text/javascript" src="../../js/jquery.karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+ <link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+</head>
+
+<body>
+
+<section id="navigation">
+ <nav id="knavbar">
+ <a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back" class="floatLeft"></a>
+ <div id="lessonTitle" class="floatLeft"><a id="welcome" href="index_knavbar.html">Adding up to 10</a></div>
+ <a href="http://olenepal.org/" target="_blank"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal Web site" class="floatRight"></a>
+ <a href="#tab_help"><img src="../../assets/default/images/help.png" alt="Help" title="Help" class="floatRight"></a>
+ <img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial" class="floatRight">
+ <a href="exercise.html" class="selected"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise" class="floatRight"></a>
+ </nav>
+</section>
+
+ <div id="karma-main">
+ <div id="main">
+ <div id="top">
+
+ <div id="topLeftArea">
+ <img id="topLeftCard" src="assets/generic/images/yellowBox.png" alt="" />
+ <div id="topLeftPaper" ></div>
+
+ </div>
+ <div id="topMiddleArea">
+ <img id="plusSign" src="assets/generic/images/plussign.png" alt=""/>
+ </div>
+ <div id="topRightArea">
+ <img id="topRightCard" src="assets/generic/images/yellowBox.png" alt=""/>
+ <div id="topRightPaper"></div>
+ </div>
+
+ </div>
+
+ <div id="bottom">
+ <div id="bottomLeft" class="bottom">
+ <img class="bottomCard" src="assets/generic/images/yellowBox.png" alt=""/>
+ <div id="bottomLeftPaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomMiddle" class="bottom">
+ <img class="bottomCard" src="assets/generic/images/yellowBox.png" alt=""/>
+ <div id="bottomMiddlePaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomRight" class="bottom">
+ <img class="bottomCard" src="assets/generic/images/yellowBox.png" alt=""/>
+ <div id="bottomRightPaper" class="bottomCard"> </div>
+ </div>
+
+ </div>
+
+ </div>
+ <div id="side">
+ <div class="sideItem">
+ <img id="timer" src="assets/generic/images/scorebox.png" alt=""/>
+ <div id="timerPaper"> </div>
+ </div>
+ <div class="sideItem">
+ <img id="scoreBox" src="assets/generic/images/scorebox.png" alt=""/>
+ <div id="scoreBoxText"></div>
+ </div>
+ <div class="sideItem">
+ <div id="chimpPaper"> </div>
+ <div id="buttons">
+ <button id="start">Start</button>
+ <button id="stop">Stop</button>
+ <button id="reset">Restart</button>
+ </div>
+ </div>
+
+
+ </div>
+ <div id="overlay"></div>
+ <div id="overlayPaper"></div>
+ </div>
+</div>
+
+</body>
+
+</html>
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/index.html b/bundles/XO/karma/lessons/adding_up_to_10_svg/index.html
new file mode 100755
index 0000000..7ecbfa3
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/index.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Karma - Adding Up to 10</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <link type="image/ico" rel="icon" href="../../assets/default/image/favicon.ico" />
+ <link type="text/css" rel="stylesheet" href="../../css/karma.css" />
+ <script type="text/javascript" src="../../js/raphael-min.js"></script>
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+
+
+
+</head>
+
+<body>
+ <div>
+ <div id="main">
+ <div id="top">
+
+ <div id="topLeftArea">
+ <img id="topLeftCard" src="assets/image/yellowBox.png" alt="" />
+ <div id="topLeftPaper" ></div>
+
+ </div>
+ <div id="topMiddleArea">
+ <img id="plusSign" src="assets/image/plussign.png" alt=""/>
+ </div>
+ <div id="topRightArea">
+ <img id="topRightCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="topRightPaper"></div>
+ </div>
+
+ </div>
+
+ <div id="bottom">
+ <div id="bottomLeft" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomLeftPaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomMiddle" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomMiddlePaper" class="bottomCard"> </div>
+ </div>
+ <div id="bottomRight" class="bottom">
+ <img class="bottomCard" src="assets/image/yellowBox.png" alt=""/>
+ <div id="bottomRightPaper" class="bottomCard"> </div>
+ </div>
+
+ </div>
+
+ </div>
+ <div id="side">
+ <div class="sideItem">
+ <img id="timer" src="assets/image/scorebox.png" alt=""/>
+ <div id="timerPaper"> </div>
+ </div>
+ <div class="sideItem">
+ <img id="scoreBox" src="assets/image/scorebox.png" alt=""/>
+ <div id="scoreBoxText"></div>
+ </div>
+ <div class="sideItem">
+ <div id="chimpPaper"> </div>
+ <div id="buttons">
+ <button id="start">Start</button>
+ <button id="stop">Stop</button>
+ <button id="reset">Restart</button>
+ </div>
+ </div>
+
+
+ </div>
+ <div id="overlay"></div>
+ <div id="overlayPaper"></div>
+ </div>
+
+
+</body>
+
+</html>
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/index_knavbar.html b/bundles/XO/karma/lessons/adding_up_to_10_svg/index_knavbar.html
new file mode 100755
index 0000000..6bd5e7a
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/index_knavbar.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html lang="en">
+
+<head>
+<title>Adding up to 10 - Index (Alpha)</title>
+<meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal">
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta charset="utf-8">
+
+<link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+<script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
+<script type="text/javascript" src="js/jquery.ui.all.js"></script>
+
+</head>
+
+<body>
+
+<div id="lesson">
+
+<nav>
+<a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back" class="floatLeft"></a>
+<div id="lessonTitle" class="floatLeft"><a id="welcome" href="index_knavbar.html" class="selected">Adding up to 10</a></div>
+</nav>
+
+<div id="subject">Mathematics</div>
+<div id="lesson_name">Adding up to 10</div>
+
+<div id="tutorial_link" class="centeredImage"><img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial"></div>
+<div id="exercise_link" class="centeredImage"><a href="exercise.html"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise"></a></div>
+
+<div id="welcome_refs"><a href="assets/en/docs/teachernotes.swf" target="_blank">Teacher's note</a></div>
+<div id="welcome_refs"><a href="assets/en/docs/lessonplan.swf" target="_blank">Lesson plan</a></div>
+
+<div id="welcome_logo" class="centeredImage"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal"></div>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/js/lesson.js b/bundles/XO/karma/lessons/adding_up_to_10_svg/js/lesson.js
new file mode 100755
index 0000000..b591973
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/js/lesson.js
@@ -0,0 +1,363 @@
+/* jslint browser: true
+*/
+$(document).ready(function(){
+
+
+ var k = Karma({
+ image: [
+ {name: "ball", file: "ball37px.png"},
+ {name: "balloon", file: "balloon37px.png"},
+ {name: "banana", file: "banana37px.png"},
+ {name: "chilli", file: "chilli.png"},
+ {name: "fish" , file: "fish64px.png"},
+ {name: "flower", file: "flower37px.png"},
+ {name: "normalChimp", file: "normalChimp_120x125.png"},
+ {name: "happyChimp", file: "happyChimp_120x125.png"},
+ {name: "sadChimp", file: "sadChimp_120x125.png"}],
+ audio: [
+ {name: "correct", file: "correct.ogg"},
+ {name: "incorrect", file: "incorrect.ogg"},
+ {name: "trigger", file: "trigger.ogg"}
+ ]
+
+ });
+
+
+k.ready(function() {
+
+ var imageNames = ["ball", "banana", "balloon","chilli", "fish", "flower"];
+ //game logic
+ var cards;
+ var totalCorrect = 0, n0 = 0, n1 = 0, correctCard = 0,
+ level = 0, score = 0, numCorrectAnswers = 0;
+ var DRAW_MAX_X = 170, DRAW_MAX_Y = 170;
+ var choices=[0, 0, 0];
+ var timerSpeed = 12000;
+ var START_TIMER_Y = 25, END_TIMER_Y = 125;
+ var timerPaper, chimpPaper;
+ var timerRect;
+ var normalChimpImage, sadChimpImage, happyChimpImage;
+ var overlayCard, topLeftCard, topRightCard, bottomLeftCard,
+ bottomMiddleCard, bottomRightCard;
+
+ var buttons=[];
+ var isTimerRunning = false;
+ var isGameRunning = false;
+
+
+ var createCard = function (paperName, width, height) {
+ var set;
+ var paper;
+
+ if(!width || !height){
+ paper = Raphael(paperName+"Paper", 200, 200);
+ }
+ else {
+ paper = Raphael(paperName+"Paper", width, height);
+ }
+ set = paper.set();
+ return { "paper": paper, "prefix": paperName, "set": set};
+ };
+
+
+ overlayCard = createCard("overlay", 800, 600);
+ topLeftCard = createCard("topLeft");
+ topRightCard = createCard("topRight");
+ bottomLeftCard = createCard("bottomLeft");
+ bottomMiddleCard = createCard("bottomMiddle");
+ bottomRightCard = createCard("bottomRight");
+
+
+ cards = [ topLeftCard, topRightCard, bottomLeftCard,
+ bottomMiddleCard, bottomRightCard];
+
+ sets = [topLeftCard.set, topRightCard.set, bottomLeftCard.set,
+ bottomMiddleCard.set, bottomRightCard.set];
+
+
+ function drawCards () {
+ var imageId = imageNames[ level ];
+ //reinitialize choices to zero
+ choices = [0, 0, 0];
+
+ cards.forEach(function (box) {
+ box.set.remove();
+ });
+
+ totalCorrect = k.rand( 2, 5 + level ); //the totalCorrect
+ n0 = totalCorrect - k.rand(1, totalCorrect - 1 ); //first number
+ n1 = totalCorrect - n0; //second number
+
+ //chose one option (the correct option)
+ //and then put the correct value into it
+ correctCard = k.rand( 0, 2 );
+ choices[ correctCard ] = totalCorrect;
+
+ var computeUniqueChoice = function(choice){
+ var newChoice = 0;
+ if (choice === totalCorrect) {
+ return choice;
+ } else {
+ newChoice = k.rand( 1, 10 );
+ if (newChoice === totalCorrect){
+ return computeUniqueChoice(choice);
+ } else {
+ return newChoice;
+ }
+ }
+ };
+
+ choices = choices.map(computeUniqueChoice);
+
+ var drawCard = function (card, n) {
+ var positions = [];
+ var x = 0, y = 0;
+ var isOverlapping = false;
+ var imageVarNames = {};
+ var varPrefix = card.prefix;
+ imageVarNames[varPrefix] = [];
+ card.set = card.paper.set();
+
+ for (var i=0; i<n; i++) {
+ do {
+ isOverlapping = false;
+ x = k.rand( 0, DRAW_MAX_X);
+ y = k.rand( 0, DRAW_MAX_Y );
+ for ( var j=0; j<positions.length; j++) {
+ if ( k.distance2( positions[j],
+ {"x": x, "y": y} ) < 137 ) {
+ isOverlapping = true;
+ break;
+ }
+ }
+
+ }while ( isOverlapping === true );
+ positions.push( { "x":x, "y": y } );
+ imageVarNames[varPrefix][i] = card.paper.
+ image(k.image[imageId].src, x , y, 35, 35);
+ card.set.push(imageVarNames[varPrefix][i]);
+ }
+
+ };
+
+ //put the cards
+ drawCard(topLeftCard, n0);
+ drawCard(topRightCard, n1);
+ drawCard(bottomLeftCard, choices[ 0 ]);
+ drawCard(bottomMiddleCard, choices[ 1 ]);
+ drawCard(bottomRightCard, choices[ 2 ]);
+
+ }
+
+ //put the buttons on the cards
+ buttons[ 0 ] = { node: $('#bottomLeftPaper')[0], num: 0};
+ buttons[ 1 ] = { node: $('#bottomMiddlePaper')[0], num: 1};
+ buttons[ 2 ] = { node: $('#bottomRightPaper')[0], num: 2};
+
+ buttons.forEach(
+ function(button) {
+ var numButton = button.num;
+ button.node
+ .addEventListener('click', function (){
+ if(isGameRunning === true){
+ var myButton = numButton;
+ chooseCard(myButton);
+ }
+ }, false);
+ });
+
+
+
+
+
+ var chooseCard = function(numButton) {
+ if ( choices[numButton] === totalCorrect){
+ //If the player has completed all the levels
+ if (numCorrectAnswers === 4 && level === 5) {
+ congrats();
+ } else {
+ computeScore(true, false);
+ resetTimer();
+ animateTimer();
+ drawCards();
+ }
+ }else {
+ computeScore(false, false);
+ resetTimer();
+ animateTimer();
+ drawCards();
+ }
+ };
+
+
+
+ var writeScore = function (newScore){
+ $('#scoreBoxText')[0].innerHTML = newScore;
+ };
+
+
+ var computeScore = function (correct, tooSlow) {
+
+ if ( correct === false) {
+ //answer was incorrect or took too long
+ score = score - 1;
+ numCorrectAnswers = numCorrectAnswers - 1;
+ writeScore(score);
+ if (tooSlow === true) {
+ k.audio.trigger.play();
+ } else {
+ k.audio.incorrect.play();
+ }
+ //animate sad monkey
+ animateChimp(false);
+
+ } else {
+ score = score + 1;
+ numCorrectAnswers = numCorrectAnswers + 1;
+ writeScore(score);
+ k.audio.correct.play();
+ animateChimp(true);
+ if (numCorrectAnswers == 5){
+ level = level + 1;
+ timerSpeed = timerSpeed - 1000;
+ numCorrectAnswers = 0;
+ }
+
+ }
+
+
+ };
+
+
+ var startGame = function () {
+ score = 0;
+ writeScore(score);
+ isTimerRunning = true;
+ isGameRunning = true;
+
+ //move timer back to start in case it is
+ //already running
+ resetTimer();
+
+ //start timer
+ animateTimer();
+
+ drawCards();
+ };
+
+ var stopGame = function () {
+ writeScore(' ');
+ isGameRunning = false;
+ //stop timer
+ isTimerRunning = false;
+ resetTimer();
+
+ //clear the cards
+ cards.forEach(function (card) {
+ card.set.remove();
+ card.set = card.paper.set();
+ });
+
+ };
+
+ var resetGame = function () {
+ score = 0;
+ writeScore(score);
+ isTimerRunning = true;
+ resetTimer();
+ animateTimer();
+ drawCards();
+
+ };
+
+ var resetTimer = function () {
+ timerRect.animate({y: START_TIMER_Y}, 0);
+ };
+
+ var animateTimer = function () {
+ timerRect.animate({y : END_TIMER_Y}, timerSpeed, function(){
+ timerRect.attr("y", START_TIMER_Y);
+ if (isTimerRunning === true){
+ computeScore(false, true);
+ animateTimer();
+ drawCards();
+ }
+ });
+ };
+
+
+ var animateChimp = function (answer) {
+ var timerChimp;
+ normalChimpImage.hide();
+ if( answer === true){
+ happyChimpImage.show();
+ } else {
+ sadChimpImage.show();
+ }
+
+
+ timerChip = setTimeout(function() {
+ happyChimpImage.hide();
+ sadChimpImage.hide();
+ normalChimpImage.show();}, 800);
+
+ };
+
+ var congrats = function () {
+ var congratsText;
+ stopGame();
+
+ $('#overlay').css({"position": "absolute", "background": "white", "opacity": "0.7",
+ "width": 800, "height": 600, "z-index": 10});
+ $('#overlayPaper').css({"position": "absolute", "z-index": "100", "opacity": 1});
+ congratsChimp = overlayCard.paper.image(
+ k.image.happyChimp.src, 200, 100, 300, 400);
+ congratsChimp.attr({"fill-opacity": "1", "opacity": "1"});
+ congratsText = overlayCard.paper.text(400, 550, "Great Job!");
+ congratsText.attr({"font-size": 80});
+ overlayCard.set.push(congratsChimp, congratsText);
+
+ congratsChimp.node.addEventListener('click', function(){
+ $('#overlay').css({"opacity": 0});
+ overlayCard.set.remove();
+ }, false);
+
+ };
+
+ document.getElementById('start').
+ addEventListener('click', startGame, false);
+
+
+ document.getElementById('stop').
+ addEventListener('click', stopGame, true);
+
+ document.getElementById('reset').
+ addEventListener('click', resetGame, false);
+
+
+ //set up the timer
+ timerPaper = Raphael('timerPaper', 100, 150);
+ timerRect = timerPaper.rect(7, START_TIMER_Y, 85, 20, 3);
+ timerRect.attr('fill', "#fff");
+
+ //Set up the monkeys
+ chimpPaper = Raphael('chimpPaper', 120, 125);
+ normalChimpImage = chimpPaper.image(k.image.normalChimp.src,
+ 0, 20, 100, 100);
+ sadChimpImage = chimpPaper.image(k.image.sadChimp.src,
+ 0, 20, 100, 100);
+ happyChimpImage = chimpPaper.image(k.image.happyChimp.src,
+ 0, 20, 100, 100);
+ happyChimpImage.hide();
+ sadChimpImage.hide();
+
+
+
+
+});
+
+
+
+
+//end of ready
+}); \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/po/en.po b/bundles/XO/karma/lessons/adding_up_to_10_svg/po/en.po
new file mode 100755
index 0000000..4d1444f
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/po/en.po
@@ -0,0 +1,28 @@
+# English translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe LĂłpez Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: English\n"
+"X-Poedit-Country: United States\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "choose an optionxxxxxxx"
+
+msgid "Time"
+msgstr "Time1"
+
+msgid "Level"
+msgstr "Level1"
+
+msgid "Restart"
+msgstr "Restart1"
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/po/es-MX.po b/bundles/XO/karma/lessons/adding_up_to_10_svg/po/es-MX.po
new file mode 100755
index 0000000..ca1e61c
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/po/es-MX.po
@@ -0,0 +1,29 @@
+# Spanish translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe LĂłpez Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+"X-Poedit-Country: MEXICO\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "escoge una opciĂłn"
+
+msgid "Time"
+msgstr "Tiempo"
+
+msgid "Level"
+msgstr "Nivel"
+
+msgid "Restart"
+msgstr "Reinicia"
+
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/po/es.po b/bundles/XO/karma/lessons/adding_up_to_10_svg/po/es.po
new file mode 100755
index 0000000..b665366
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/po/es.po
@@ -0,0 +1,29 @@
+# Spanish translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe LĂłpez Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Spanish\n"
+"X-Poedit-Country: MEXICO\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "escoge una opciĂłnXXX"
+
+msgid "Time"
+msgstr "Tiempo"
+
+msgid "Level"
+msgstr "Nivel"
+
+msgid "Restart"
+msgstr "Reinicia"
+
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/po/he-IL.po b/bundles/XO/karma/lessons/adding_up_to_10_svg/po/he-IL.po
new file mode 100755
index 0000000..f681aca
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/po/he-IL.po
@@ -0,0 +1,28 @@
+# Hebrew translations for PACKAGE package.
+msgid ""
+msgstr ""
+"Project-Id-Version: adding up to 10 v1\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: 2009-07-07 04:46-0600\n"
+"Last-Translator: Felipe LĂłpez Toledo <zer.subzero@gmail.com>\n"
+"Language-Team: karma <zer.subzero@gmail.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Hebrew\n"
+"X-Poedit-Country: Israel\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+
+msgid "choose an option"
+msgstr "בחר ב×פשרות"
+
+msgid "Time"
+msgstr "שעה"
+
+msgid "Level"
+msgstr "רמת"
+
+msgid "Restart"
+msgstr "הפעל מחדש"
+
diff --git a/bundles/XO/karma/lessons/adding_up_to_10_svg/resources.html b/bundles/XO/karma/lessons/adding_up_to_10_svg/resources.html
new file mode 100755
index 0000000..0e93455
--- /dev/null
+++ b/bundles/XO/karma/lessons/adding_up_to_10_svg/resources.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Karma - Adding Up to 10</title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal" />
+ <link type="text/css" rel="stylesheet" href="css/lesson.css" />
+ <meta http-equiv="content-type" content="text/html; charset=utf-8">
+ <link type="image/ico" rel="icon" href="../../assets/default/images/favicon.ico" />
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.Gettext.js"></script>
+ <script type="text/javascript" src="../../js/jquery.karma.js"></script>
+ <link rel="stylesheet" href="css/knavbar.css" type="text/css"/>
+
+</head>
+
+<body>
+
+<div id="lesson">
+<nav>
+<li><a href="../../chakra/grade1mathematics.html"><img src="../../assets/default/images/back.png" alt="Back" title="Back"></a></li>
+<li><a href="../../index.html"><img src="../../assets/default/images/chakra_logo.png" alt="Chakra" title="Chakra"></a></li>
+<li><a id="welcome" href="index_knavbar.html">Adding up to 10</a></li>
+<li><img src="../../assets/default/images/tutorial_bw.png" alt="Tutorial" title="Tutorial"></li>
+<li><a href="exercise.html"><img src="../../assets/default/images/exercise.png" alt="Exercise" title="Exercise"></a></li>
+<li><a href="resources.html" class="selected"><img src="../../assets/default/images/resources.png" alt="Resources" title="Resources"></a></li>
+<li><a href="#tab_help"><img src="../../assets/default/images/help.png" alt="Help" title="Help"></a></li>
+<li><a href="http://olenepal.org/" target="_blank"><img src="../../assets/default/images/olenepal_logo.gif" alt="OLE Nepal logo" title="OLE Nepal Web site"></a></li>
+</nav>
+
+<li><a href="assets/en/docs/teachernotes.swf" target="_blank">Teacher's notes</a></li>
+<li><a href="assets/en/docs/lessonplan.swf" target="_blank">Lesson plan</a></li>
+<li><a href="quadrilaterals.zip">Download</a></li>
+</div>
+
+</body>
+
+</html>
diff --git a/bundles/XO/karma/lessons/quadrilaterals/css/activity.css b/bundles/XO/karma/lessons/quadrilaterals/css/activity.css
new file mode 100755
index 0000000..a2ae7e9
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/css/activity.css
@@ -0,0 +1,4 @@
+#Karma { position: relative; }
+#canvasDrawing { position: absolute; top: 0px; left: 0px; }
+#canvasTmp { position: absolute; top: 0px; left: 0px; }
+.button { position: absolute; top: 0px; left: 0px; } \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/quadrilaterals/css/jquery.jgrowl.css b/bundles/XO/karma/lessons/quadrilaterals/css/jquery.jgrowl.css
new file mode 100755
index 0000000..96af78e
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/css/jquery.jgrowl.css
@@ -0,0 +1,119 @@
+
+div.jGrowl {
+ padding: 10px;
+ z-index: 9999;
+}
+
+/** Special IE6 Style Positioning **/
+div.ie6 {
+ position: absolute;
+}
+
+div.ie6.top-right {
+ right: auto;
+ bottom: auto;
+ left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
+ top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
+}
+
+div.ie6.top-left {
+ left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
+ top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
+}
+
+div.ie6.bottom-right {
+ left: expression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
+ top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
+}
+
+div.ie6.bottom-left {
+ left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
+ top: expression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
+}
+
+div.ie6.center {
+ left: expression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );
+ top: expression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );
+ width: 100%;
+}
+
+/** Normal Style Positions **/
+body > div.jGrowl {
+ position: fixed;
+}
+
+body > div.jGrowl.top-left {
+ left: 0px;
+ top: 0px;
+}
+
+body > div.jGrowl.top-right {
+ left: 150 px;
+ top: 100px;
+}
+
+body > div.jGrowl.bottom-left {
+ left: 0px;
+ bottom: 0px;
+}
+
+body > div.jGrowl.bottom-right {
+ right: 0px;
+ bottom: 0px;
+}
+
+body > div.jGrowl.center {
+ top: 0px;
+ width: 50%;
+ left: 25%;
+}
+
+/** Cross Browser Styling **/
+div.center div.jGrowl-notification, div.center div.jGrowl-closer {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+div.jGrowl div.jGrowl-notification, div.jGrowl div.jGrowl-closer {
+ background-color: #000;
+ color: #fff;
+ opacity: .85;
+ filter: alpha(opacity = 85);
+ zoom: 1;
+ width: 235px;
+ padding: 10px;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ font-family: Tahoma, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ text-align: left;
+ display: none;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+}
+
+div.jGrowl div.jGrowl-notification {
+ min-height: 40px;
+}
+
+div.jGrowl div.jGrowl-notification div.header {
+ font-weight: bold;
+ font-size: 10px;
+}
+
+div.jGrowl div.jGrowl-notification div.close {
+ float: right;
+ font-weight: bold;
+ font-size: 12px;
+ cursor: pointer;
+}
+
+div.jGrowl div.jGrowl-closer {
+ height: 15px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ cursor: pointer;
+ font-size: 11px;
+ font-weight: bold;
+ text-align: center;
+}
diff --git a/bundles/XO/karma/lessons/quadrilaterals/css/lesson.css b/bundles/XO/karma/lessons/quadrilaterals/css/lesson.css
new file mode 100755
index 0000000..3ed4696
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/css/lesson.css
@@ -0,0 +1,79 @@
+#main
+{
+ background-image: url('../images/bg.png');
+ width: 550px;
+ height: 400px;
+}
+
+#leftArea {
+ width: 60%;
+ display: inline;
+ float: left;
+ height: 100%;
+}
+
+#rightArea {
+ width: 40%;
+ display: inline;
+ float: left;
+ height: 100%;
+}
+
+#leftTop {
+ height: 20%;
+ position: relative;
+}
+
+#leftMiddle {
+ height: 60%;
+}
+
+#leftBottom {
+ height: 20%;
+ float: left;
+}
+
+
+#rightTop {
+ height: 30%;
+}
+
+#rightMiddle {
+ height: 40%;
+}
+
+#rightBottom {
+ height: 30%;
+}
+
+
+
+
+
+
+#Karma
+{
+ position: relative;
+}
+
+.canvas
+{
+ position: absolute;
+ top: 0px;
+ left: 0px;
+}
+
+#left
+{
+ float: left;
+ width: 350px;
+}
+
+.left {
+ float:left;
+}
+
+#instruction{
+ position: absolute;
+ top: 60px;
+} \ No newline at end of file
diff --git a/bundles/XO/karma/lessons/quadrilaterals/images/bg.png b/bundles/XO/karma/lessons/quadrilaterals/images/bg.png
new file mode 100755
index 0000000..1a4249f
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/images/bg.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/quadrilaterals/images/bg_small.png b/bundles/XO/karma/lessons/quadrilaterals/images/bg_small.png
new file mode 100755
index 0000000..2dedab6
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/images/bg_small.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/quadrilaterals/images/erase.png b/bundles/XO/karma/lessons/quadrilaterals/images/erase.png
new file mode 100755
index 0000000..f2ea68f
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/images/erase.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/quadrilaterals/images/eraseOver.png b/bundles/XO/karma/lessons/quadrilaterals/images/eraseOver.png
new file mode 100755
index 0000000..bea6dbf
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/images/eraseOver.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/quadrilaterals/images/next.png b/bundles/XO/karma/lessons/quadrilaterals/images/next.png
new file mode 100755
index 0000000..81cc3c0
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/images/next.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/quadrilaterals/images/previous.png b/bundles/XO/karma/lessons/quadrilaterals/images/previous.png
new file mode 100755
index 0000000..ef3b168
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/images/previous.png
Binary files differ
diff --git a/bundles/XO/karma/lessons/quadrilaterals/index.html b/bundles/XO/karma/lessons/quadrilaterals/index.html
new file mode 100755
index 0000000..3325887
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/index.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Quadrilaterals - Karma </title>
+ <meta name="keywords" content="karma,javascript,html5,sugar,sugarlabs,gsoc,ole,nepal"/>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <meta charset="utf-8"/>
+ <link rel="shortcut icon" href="http://karma.sugarlabs.org/favicon.ico"/>
+ <link rel="stylesheet" href="css/jquery.jgrowl.css" type="text/css"/>
+ <link rel="stylesheet" href="css/lesson.css" type="text/css"/>
+ <script type="text/javascript" src="../../js/jquery-1.3.2.min.js"></script>
+ <script type="text/javascript" src="../../js/karma.js"></script>
+ <script type="text/javascript" src="../../js/jquery.jgrowl_minimized.js"></script>
+ <script type="text/javascript" src="js/lesson.js"></script>
+ </head>
+<body>
+ <noscript>
+ Man, you need to enable JavaScript.
+ </noscript>
+
+ <div id="main">
+ <div id="leftArea">
+ <div id="leftTop">
+ <div id="instruction"> Construct a quadrilateral by moving
+ the given straight lines to appropriate places </div>
+ </div>
+ <div id="leftMiddle">
+ <div id="Karma">
+ <canvas id="canvas" class="canvas" width="550" height="400"></canvas>
+ <canvas id="canvasDrawing" class="canvas" width="550" height="400"></canvas>
+ <canvas id="canvasTmp" class="canvas" width="550" height="400"></canvas>
+ </div>
+ </div>
+ <div id="leftBottom">
+ <img id="btnErase" src="images/erase.png" />
+ </div>
+ </div>
+ <div id="rightArea" class="left">
+ <div id="rightTop">
+ </div>
+ <div id="rightMiddle">
+ <div id="textExample">Make quadrilaterals on geo-board</div>
+ </div>
+ <div id="rightBottom">
+ <div id="btn">
+ <img id="imgPrev" src="images/previous.png" />
+ <img id="imgNext" src="images/next.png" />
+ </div>
+ </div>
+ </div>
+ </div>
+
+</body>
+
+</html>
+
+
+
+
+
diff --git a/bundles/XO/karma/lessons/quadrilaterals/js/lesson.js b/bundles/XO/karma/lessons/quadrilaterals/js/lesson.js
new file mode 100755
index 0000000..03cbace
--- /dev/null
+++ b/bundles/XO/karma/lessons/quadrilaterals/js/lesson.js
@@ -0,0 +1,289 @@
+$(document).ready(function(){
+
+ var canvasDrawing = $("#canvasDrawing")[0];
+ var ctxDrawing = canvasDrawing.getContext("2d");
+
+ var canvas =$("#canvas")[0];
+ var ctx = canvas.getContext("2d");
+
+ var canvasTmp = $("#canvasTmp")[0];
+ var ctxTmp = canvasTmp.getContext("2d");
+ ctxTmp.lineWidth = 3;
+ ctxTmp.lineCap = 'round';
+
+ var points=[]; //points of the quadrilateral
+
+ function reset() {
+ ctxDrawing.clearRect(0, 0, canvas.width, canvas.height);
+ ctxTmp.clearRect(0, 0, canvas.width, canvas.height);
+ started=false;
+ points=[];
+ }
+
+ var buttons= {
+ next:{ x:510, y:135, width:30, height:30},
+ prev:{ x:330, y:135, width:30, height:30}
+ };
+
+ //f of functions, a "place" to put functions ;)
+ var f={
+ drawCircle: function ( context, x, y, size){
+ context.save();
+ //context.translate(x,y);
+ context.beginPath();
+ context.fillStyle = "#cccccc"
+ context.strokeStyle = "#000000"
+ context.lineWidth = 1;
+ context.arc( x ,y, size, 0, Math.PI*2, true);
+ context.closePath();
+ context.fill();
+ context.stroke();
+ context.restore();
+ },
+ equals: function (x, y) {
+ if ( x.lenght != y.length ) return false;
+ for(var propertyName in x) {
+ if(x[propertyName] !== y[propertyName]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ };
+ var geometry = {
+ // 2D cross product.
+ // return a positive value, if OAB makes a counter-clockwise turn,
+ // negative for clockwise turn, and zero if the points are collinear.
+ cross: function ( o, a, b ) {
+ return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
+ }
+ };
+
+ //var imgBg = document.getElementById("bg"); //creates the image element for background
+ var imgErase = document.getElementById("btnErase");; //creates the image element for erase button
+ var imgPrev = document.getElementById("imgPrev");//creates the image element for previous button
+ var imgNext = document.getElementById("imgNext");//creates the image element for next button
+
+ imgNext.onmouseup = function()
+ {
+ $.jGrowl("next pressed");
+ };
+
+ imgPrev.onmouseup = function()
+ {
+ $.jGrowl("previous pressed");
+ };
+
+ imgErase.onmouseup = function()
+ {
+ reset();
+ }
+ //necessary stuff to do test the figure
+ var match = false;
+ function sortPoint( a, b) {
+ if (a.x == b.x) return (a.y < b.y);
+ return (a.x < b.x);
+ }
+ function checkQuadrilateral( points ) {
+ started = false;
+ if ( f.equals (points[0], points[4]) === false ) {
+ return false;
+ }
+ points.push(points[ 1 ]); //add the second point (pos 1) to create a loop 0-1, 1-2, 2-3, 3-4, 4-1
+ //slope
+ var m, m0 = undefined;
+ for ( var i=0; i<5; i++ ) {
+ m = (points[ (i+1)%6 ].y - points[ i ].y) / (points[ (i+1)%6 ].x - points[ i ].x);
+ if ( m === m0) {
+ return false;
+ }
+ m0 = m;
+ }
+ //clockwise or anti-clockwise ?? choose it
+ var dir = geometry.cross( points[0], points[1], points[2])<=0 ? 0: 1; // get the direction
+ for ( var i=2; i<5; i++ ) {
+ if ( (geometry.cross( points[i-2], points[i-1], points[i]) <= 0 ?0:1) != dir) {
+ return false;
+ }
+ }
+ return true;
+
+ }
+
+
+ //drawing area
+ ctx.fillStyle = "rgba( 111, 226, 245, 0.7)";
+ ctx.strokeStyle = "#B74000"
+ ctx.lineWidth = 3;
+ ctx.fillRect( 10, 70, 310, 150 );
+ ctx.strokeRect( 10, 70, 310, 150 );
+
+ //settings for the grid
+ ctx.strokeStyle = "rgba( 111, 226, 245, 1)"
+ ctx.lineWidth = 1;
+ //draw the row lines
+ for (var i=0; i<5; i ++) {
+ ctx.beginPath();
+ ctx.moveTo( 330, 70 + i*15 );
+ ctx.lineTo( 540, 70 + i*15 );
+ ctx.closePath();
+ ctx.stroke()
+ }
+ //draw the column lines
+ for (var i=0; i<8; i ++) {
+ ctx.beginPath();
+ ctx.moveTo( 330 + i*30, 70 );
+ ctx.lineTo( 330 + i*30, 130 );
+ ctx.closePath();
+ ctx.stroke()
+ }
+
+
+ //the dotButton definition
+ var dotButton = function( valx, valy, size){
+ var obj={
+ x:valx, y:valy, width:size, height:size,
+ mouseup:function( ev ) {
+ var p = { x:valx, y:valy };
+ if ( points.length > 0 && f.equals( points[ points.length -1 ], p ) ) return;
+
+ points.push( p );
+
+ //clear the current line in order to adjust it
+ ctxTmp.clearRect(0, 0, canvas.width, canvas.height);
+ ctxTmp.beginPath();
+ if ( points.length === 1) {
+ ctxTmp.moveTo( valx + 7, valy + 7 );
+ } else {
+ ctxTmp.moveTo(mouse.x0, mouse.y0 );
+ }
+ ctxTmp.lineTo(valx + 7, valy + 7);
+ ctxTmp.stroke();
+ ctxTmp.closePath();
+
+
+ //do updating
+ ctxDrawing.drawImage(canvasTmp, 0, 0);
+
+ //+7 hack, start point for the next line if any
+ mouse.x0 = valx + 7;
+ mouse.y0 = valy + 7;
+
+ if (points.length === 5) {
+ if (checkQuadrilateral( points ) === true) {
+ $.jGrowl("good! ");
+ }else {
+ $.jGrowl("that is not a quadrilateral ");
+ }
+ reset();
+ }
+
+ },
+ mousedown:function( ev ) {
+ ctxTmp.moveTo( mouse.x0, mouse.y0 );
+ //set the default beahavior
+ if (started !== true) {
+ mouse.x0 = mouse.x;
+ mouse.y0 = mouse.y;
+ started = true;
+ }
+ },
+ mouseover:function( ev ) { }
+ }
+ return obj;
+ };
+
+ //draw the circles
+ //buttons["dot"]=dotButton(100-25, 100-25, 50);
+ //f.drawCircle( ctx, 100, 100, 25);
+ for (var i=0; i<5; i++) {
+ for (var j=0; j<8; j++) {
+ //tricky way..
+ buttons["dot"+i+""+j]=dotButton(10 + j*40 +15 -7, 70 + i*30 +15 -7, 14);
+ f.drawCircle( ctx, 10 + j*40 +15, 70 + i*30 +15, 7);
+ }
+ }
+
+
+
+ //clipping path, this is the drawing region
+ ctxTmp.beginPath();
+ ctxTmp.moveTo(10, 70);
+ ctxTmp.lineTo(320, 70);
+ ctxTmp.lineTo(320, 220);
+ ctxTmp.lineTo(10, 220);
+ ctxTmp.lineTo(10, 70);
+ ctx.closePath();
+ ctxTmp.clip();
+
+
+
+ function distance2 ( x1, x2, y1, y2){
+ return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) ;
+ }
+ var mouse= {x:0, y:0, x0:0, y0:0, listeners:[] };
+ var started=false,counter=0;
+
+ //drawing object
+
+ var drawing={};
+ drawing.mouseup =function ( ev ) {
+ //see dotButton.mouseup
+ }
+ drawing.mousedown = function (ev) {
+ //see dotButton.mousedown
+ }
+ drawing.mousemove = function (ev) {
+ if (started) {
+
+ ctxTmp.clearRect(0, 0, canvas.width, canvas.height);
+ ctxTmp.beginPath();
+
+ ctxTmp.moveTo(mouse.x0, mouse.y0);
+ ctxTmp.lineTo(mouse.x, mouse.y );
+ ctxTmp.stroke();
+ ctxTmp.closePath();
+ }
+ }
+
+ function mouseHandler( ev ){
+
+ mouse.x = ev.layerX ;
+ mouse.y = ev.layerY;
+
+ //calls the listeners if any
+ $.each( mouse.listeners, function( i, val ){
+ mouse.listeners[i][ev.type]( ev );
+ });
+
+
+ //debug="";
+ $.each(buttons, function( i, val ){
+ d = distance2(mouse.x, buttons[i].x + buttons[i].width/2, mouse.y, buttons[i].y + buttons[i].height/2);
+ mouse.minDist=(buttons[i].width/2) * (buttons[i].height/2);
+
+ if ( d <= mouse.minDist ){
+ if ( ev.type==="mousemove"){
+ buttons[i]["mouseover"]( ev );
+ }
+ else {
+ buttons[i][ev.type]( ev );
+ }
+
+ //debug+= ev.type + " fire!";
+ }
+
+ });
+ //$("#debug").html( debug );
+ }
+
+ //Karma handler (need to work around mouse out)
+ canvasTmp.addEventListener('mouseup', mouseHandler, false);
+ canvasTmp.addEventListener('mousedown', mouseHandler, false);
+ canvasTmp.addEventListener('mousemove', mouseHandler, false);
+
+ //wiring (Karma stuff)
+ //mouseHandler will call this listener :)
+ mouse.listeners.push( drawing );
+
+});
diff --git a/bundles/XO/libfreebl3.chk b/bundles/XO/libfreebl3.chk
new file mode 100755
index 0000000..9f40adb
--- /dev/null
+++ b/bundles/XO/libfreebl3.chk
Binary files differ
diff --git a/bundles/XO/libfreebl3.so b/bundles/XO/libfreebl3.so
new file mode 100755
index 0000000..243648e
--- /dev/null
+++ b/bundles/XO/libfreebl3.so
Binary files differ
diff --git a/bundles/XO/libmozjs.so b/bundles/XO/libmozjs.so
new file mode 100755
index 0000000..c4da441
--- /dev/null
+++ b/bundles/XO/libmozjs.so
Binary files differ
diff --git a/bundles/XO/libnspr4.so b/bundles/XO/libnspr4.so
new file mode 100755
index 0000000..19064bc
--- /dev/null
+++ b/bundles/XO/libnspr4.so
Binary files differ
diff --git a/bundles/XO/libnss3.so b/bundles/XO/libnss3.so
new file mode 100755
index 0000000..164bdd4
--- /dev/null
+++ b/bundles/XO/libnss3.so
Binary files differ
diff --git a/bundles/XO/libnssckbi.so b/bundles/XO/libnssckbi.so
new file mode 100755
index 0000000..321857e
--- /dev/null
+++ b/bundles/XO/libnssckbi.so
Binary files differ
diff --git a/bundles/XO/libnssdbm3.so b/bundles/XO/libnssdbm3.so
new file mode 100755
index 0000000..a7cabd8
--- /dev/null
+++ b/bundles/XO/libnssdbm3.so
Binary files differ
diff --git a/bundles/XO/libnssutil3.so b/bundles/XO/libnssutil3.so
new file mode 100755
index 0000000..9352a79
--- /dev/null
+++ b/bundles/XO/libnssutil3.so
Binary files differ
diff --git a/bundles/XO/libplc4.so b/bundles/XO/libplc4.so
new file mode 100755
index 0000000..f805028
--- /dev/null
+++ b/bundles/XO/libplc4.so
Binary files differ
diff --git a/bundles/XO/libplds4.so b/bundles/XO/libplds4.so
new file mode 100755
index 0000000..a833e67
--- /dev/null
+++ b/bundles/XO/libplds4.so
Binary files differ
diff --git a/bundles/XO/libsmime3.so b/bundles/XO/libsmime3.so
new file mode 100755
index 0000000..f211048
--- /dev/null
+++ b/bundles/XO/libsmime3.so
Binary files differ
diff --git a/bundles/XO/libsoftokn3.chk b/bundles/XO/libsoftokn3.chk
new file mode 100755
index 0000000..da6a98c
--- /dev/null
+++ b/bundles/XO/libsoftokn3.chk
Binary files differ
diff --git a/bundles/XO/libsoftokn3.so b/bundles/XO/libsoftokn3.so
new file mode 100755
index 0000000..b48b8dd
--- /dev/null
+++ b/bundles/XO/libsoftokn3.so
Binary files differ
diff --git a/bundles/XO/libsqlite3.so b/bundles/XO/libsqlite3.so
new file mode 100755
index 0000000..294bffd
--- /dev/null
+++ b/bundles/XO/libsqlite3.so
Binary files differ
diff --git a/bundles/XO/libssl3.so b/bundles/XO/libssl3.so
new file mode 100755
index 0000000..09a30bf
--- /dev/null
+++ b/bundles/XO/libssl3.so
Binary files differ
diff --git a/bundles/XO/libxpcom.so b/bundles/XO/libxpcom.so
new file mode 100755
index 0000000..a94ee6d
--- /dev/null
+++ b/bundles/XO/libxpcom.so
Binary files differ
diff --git a/bundles/XO/libxul.so b/bundles/XO/libxul.so
new file mode 100755
index 0000000..cab8b59
--- /dev/null
+++ b/bundles/XO/libxul.so
Binary files differ
diff --git a/bundles/XO/modules/DownloadLastDir.jsm b/bundles/XO/modules/DownloadLastDir.jsm
new file mode 100755
index 0000000..9236391
--- /dev/null
+++ b/bundles/XO/modules/DownloadLastDir.jsm
@@ -0,0 +1,70 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Download Manager Utility Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Ehsan Akhgari <ehsan.akhgari@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var EXPORTED_SYMBOLS = [ "gDownloadLastDir" ];
+
+let observer = {
+ QueryInterface: function (aIID) {
+ if (aIID.equals(Components.interfaces.nsIObserver) ||
+ aIID.equals(Components.interfaces.nsISupports) ||
+ aIID.equals(Components.interfaces.nsISupportsWeakReference))
+ return this;
+ throw Components.results.NS_NOINTERFACE;
+ },
+ observe: function (aSubject, aTopic, aData) {
+ gDownloadLastDirFile = null;
+ }
+};
+
+Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService)
+ .addObserver(observer, "private-browsing", true);
+
+let gDownloadLastDirFile = null;
+let gDownloadLastDir = {
+ get file() {
+ if (gDownloadLastDirFile && !gDownloadLastDirFile.exists())
+ gDownloadLastDirFile = null;
+
+ return gDownloadLastDirFile;
+ },
+ set file(val) {
+ if (val instanceof Components.interfaces.nsIFile)
+ gDownloadLastDirFile = val.clone();
+ else
+ gDownloadLastDirFile = null;
+ }
+};
diff --git a/bundles/XO/modules/DownloadUtils.jsm b/bundles/XO/modules/DownloadUtils.jsm
new file mode 100755
index 0000000..d2c0fb2
--- /dev/null
+++ b/bundles/XO/modules/DownloadUtils.jsm
@@ -0,0 +1,502 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Download Manager Utility Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Edward Lee <edward.lee@engineering.uiuc.edu>.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var EXPORTED_SYMBOLS = [ "DownloadUtils" ];
+
+/**
+ * This module provides the DownloadUtils object which contains useful methods
+ * for downloads such as displaying file sizes, transfer times, and download
+ * locations.
+ *
+ * List of methods:
+ *
+ * [string status, double newLast]
+ * getDownloadStatus(int aCurrBytes, [optional] int aMaxBytes,
+ * [optional] double aSpeed, [optional] double aLastSec)
+ *
+ * string progress
+ * getTransferTotal(int aCurrBytes, [optional] int aMaxBytes)
+ *
+ * [string timeLeft, double newLast]
+ * getTimeLeft(double aSeconds, [optional] double aLastSec)
+ *
+ * [string displayHost, string fullHost]
+ * getURIHost(string aURIString)
+ *
+ * [double convertedBytes, string units]
+ * convertByteUnits(int aBytes)
+ *
+ * [int time, string units, int subTime, string subUnits]
+ * convertTimeUnits(double aSecs)
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+Cu.import("resource://gre/modules/PluralForm.jsm");
+
+const kDownloadProperties =
+ "chrome://mozapps/locale/downloads/downloads.properties";
+
+// These strings will be converted to the corresponding ones from the string
+// bundle on use
+let kStrings = {
+ statusFormat: "statusFormat2",
+ transferSameUnits: "transferSameUnits",
+ transferDiffUnits: "transferDiffUnits",
+ transferNoTotal: "transferNoTotal",
+ timePair: "timePair",
+ timeLeftSingle: "timeLeftSingle",
+ timeLeftDouble: "timeLeftDouble",
+ timeFewSeconds: "timeFewSeconds",
+ timeUnknown: "timeUnknown",
+ doneScheme: "doneScheme",
+ doneFileScheme: "doneFileScheme",
+ units: ["bytes", "kilobyte", "megabyte", "gigabyte"],
+ // Update timeSize in convertTimeUnits if changing the length of this array
+ timeUnits: ["seconds", "minutes", "hours", "days"],
+};
+
+// This object will lazily load the strings defined in kStrings
+let gStr = {
+ /**
+ * Initialize lazy string getters
+ */
+ _init: function()
+ {
+ // Make each "name" a lazy-loading string that knows how to load itself. We
+ // need to locally scope name and value to keep them around for the getter.
+ for (let [name, value] in Iterator(kStrings))
+ let ([n, v] = [name, value])
+ gStr.__defineGetter__(n, function() gStr._getStr(n, v));
+ },
+
+ /**
+ * Convert strings to those in the string bundle. This lazily loads the
+ * string bundle *once* only when used the first time.
+ */
+ get _getStr()
+ {
+ // Delete the getter to be overwritten
+ delete gStr._getStr;
+
+ // Lazily load the bundle into the closure on first call to _getStr
+ let getStr = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).
+ createBundle(kDownloadProperties).
+ GetStringFromName;
+
+ // _getStr is a function that sets string "name" to stringbundle's "value"
+ return gStr._getStr = function(name, value) {
+ // Delete the getter to be overwritten
+ delete gStr[name];
+
+ try {
+ // "name" is a string or array of the stringbundle-loaded "value"
+ return gStr[name] = typeof value == "string" ?
+ getStr(value) :
+ value.map(getStr);
+ } catch (e) {
+ log(["Couldn't get string '", name, "' from property '", value, "'"]);
+ // Don't return anything (undefined), and because we deleted ourselves,
+ // future accesses will also be undefined
+ }
+ };
+ },
+};
+// Initialize the lazy string getters!
+gStr._init();
+
+// Keep track of at most this many second/lastSec pairs so that multiple calls
+// to getTimeLeft produce the same time left
+const kCachedLastMaxSize = 10;
+let gCachedLast = [];
+
+let DownloadUtils = {
+ /**
+ * Generate a full status string for a download given its current progress,
+ * total size, speed, last time remaining
+ *
+ * @param aCurrBytes
+ * Number of bytes transferred so far
+ * @param [optional] aMaxBytes
+ * Total number of bytes or -1 for unknown
+ * @param [optional] aSpeed
+ * Current transfer rate in bytes/sec or -1 for unknown
+ * @param [optional] aLastSec
+ * Last time remaining in seconds or Infinity for unknown
+ * @return A pair: [download status text, new value of "last seconds"]
+ */
+ getDownloadStatus: function DU_getDownloadStatus(aCurrBytes, aMaxBytes,
+ aSpeed, aLastSec)
+ {
+ if (aMaxBytes == null)
+ aMaxBytes = -1;
+ if (aSpeed == null)
+ aSpeed = -1;
+ if (aLastSec == null)
+ aLastSec = Infinity;
+
+ // Calculate the time remaining if we have valid values
+ let seconds = (aSpeed > 0) && (aMaxBytes > 0) ?
+ (aMaxBytes - aCurrBytes) / aSpeed : -1;
+
+ // Update the bytes transferred and bytes total
+ let status;
+ let (transfer = DownloadUtils.getTransferTotal(aCurrBytes, aMaxBytes)) {
+ // Insert 1 is the download progress
+ status = replaceInsert(gStr.statusFormat, 1, transfer);
+ }
+
+ // Update the download rate
+ let ([rate, unit] = DownloadUtils.convertByteUnits(aSpeed)) {
+ // Insert 2 is the download rate
+ status = replaceInsert(status, 2, rate);
+ // Insert 3 is the |unit|/sec
+ status = replaceInsert(status, 3, unit);
+ }
+
+ // Update time remaining
+ let ([timeLeft, newLast] = DownloadUtils.getTimeLeft(seconds, aLastSec)) {
+ // Insert 4 is the time remaining
+ status = replaceInsert(status, 4, timeLeft);
+
+ return [status, newLast];
+ }
+ },
+
+ /**
+ * Generate the transfer progress string to show the current and total byte
+ * size. Byte units will be as large as possible and the same units for
+ * current and max will be supressed for the former.
+ *
+ * @param aCurrBytes
+ * Number of bytes transferred so far
+ * @param [optional] aMaxBytes
+ * Total number of bytes or -1 for unknown
+ * @return The transfer progress text
+ */
+ getTransferTotal: function DU_getTransferTotal(aCurrBytes, aMaxBytes)
+ {
+ if (aMaxBytes == null)
+ aMaxBytes = -1;
+
+ let [progress, progressUnits] = DownloadUtils.convertByteUnits(aCurrBytes);
+ let [total, totalUnits] = DownloadUtils.convertByteUnits(aMaxBytes);
+
+ // Figure out which byte progress string to display
+ let transfer;
+ if (total < 0)
+ transfer = gStr.transferNoTotal;
+ else if (progressUnits == totalUnits)
+ transfer = gStr.transferSameUnits;
+ else
+ transfer = gStr.transferDiffUnits;
+
+ transfer = replaceInsert(transfer, 1, progress);
+ transfer = replaceInsert(transfer, 2, progressUnits);
+ transfer = replaceInsert(transfer, 3, total);
+ transfer = replaceInsert(transfer, 4, totalUnits);
+
+ return transfer;
+ },
+
+ /**
+ * Generate a "time left" string given an estimate on the time left and the
+ * last time. The extra time is used to give a better estimate on the time to
+ * show. Both the time values are doubles instead of integers to help get
+ * sub-second accuracy for current and future estimates.
+ *
+ * @param aSeconds
+ * Current estimate on number of seconds left for the download
+ * @param [optional] aLastSec
+ * Last time remaining in seconds or Infinity for unknown
+ * @return A pair: [time left text, new value of "last seconds"]
+ */
+ getTimeLeft: function DU_getTimeLeft(aSeconds, aLastSec)
+ {
+ if (aLastSec == null)
+ aLastSec = Infinity;
+
+ if (aSeconds < 0)
+ return [gStr.timeUnknown, aLastSec];
+
+ // Try to find a cached lastSec for the given second
+ aLastSec = gCachedLast.reduce(function(aResult, aItem)
+ aItem[0] == aSeconds ? aItem[1] : aResult, aLastSec);
+
+ // Add the current second/lastSec pair unless we have too many
+ gCachedLast.push([aSeconds, aLastSec]);
+ if (gCachedLast.length > kCachedLastMaxSize)
+ gCachedLast.shift();
+
+ // Apply smoothing only if the new time isn't a huge change -- e.g., if the
+ // new time is more than half the previous time; this is useful for
+ // downloads that start/resume slowly
+ if (aSeconds > aLastSec / 2) {
+ // Apply hysteresis to favor downward over upward swings
+ // 30% of down and 10% of up (exponential smoothing)
+ let (diff = aSeconds - aLastSec) {
+ aSeconds = aLastSec + (diff < 0 ? .3 : .1) * diff;
+ }
+
+ // If the new time is similar, reuse something close to the last seconds,
+ // but subtract a little to provide forward progress
+ let diff = aSeconds - aLastSec;
+ let diffPct = diff / aLastSec * 100;
+ if (Math.abs(diff) < 5 || Math.abs(diffPct) < 5)
+ aSeconds = aLastSec - (diff < 0 ? .4 : .2);
+ }
+
+ // Decide what text to show for the time
+ let timeLeft;
+ if (aSeconds < 4) {
+ // Be friendly in the last few seconds
+ timeLeft = gStr.timeFewSeconds;
+ } else {
+ // Convert the seconds into its two largest units to display
+ let [time1, unit1, time2, unit2] =
+ DownloadUtils.convertTimeUnits(aSeconds);
+
+ let pair1 = replaceInsert(gStr.timePair, 1, time1);
+ pair1 = replaceInsert(pair1, 2, unit1);
+ let pair2 = replaceInsert(gStr.timePair, 1, time2);
+ pair2 = replaceInsert(pair2, 2, unit2);
+
+ // Only show minutes for under 1 hour or the second pair is 0
+ if (aSeconds < 3600 || time2 == 0) {
+ timeLeft = replaceInsert(gStr.timeLeftSingle, 1, pair1);
+ } else {
+ // We've got 2 pairs of times to display
+ timeLeft = replaceInsert(gStr.timeLeftDouble, 1, pair1);
+ timeLeft = replaceInsert(timeLeft, 2, pair2);
+ }
+ }
+
+ return [timeLeft, aSeconds];
+ },
+
+ /**
+ * Get the appropriate display host string for a URI string depending on if
+ * the URI has an eTLD + 1, is an IP address, a local file, or other protocol
+ *
+ * @param aURIString
+ * The URI string to try getting an eTLD + 1, etc.
+ * @return A pair: [display host for the URI string, full host name]
+ */
+ getURIHost: function DU_getURIHost(aURIString)
+ {
+ let ioService = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ let eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"].
+ getService(Ci.nsIEffectiveTLDService);
+ let idnService = Cc["@mozilla.org/network/idn-service;1"].
+ getService(Ci.nsIIDNService);
+
+ // Get a URI that knows about its components
+ let uri = ioService.newURI(aURIString, null, null);
+
+ // Get the inner-most uri for schemes like jar:
+ if (uri instanceof Ci.nsINestedURI)
+ uri = uri.innermostURI;
+
+ let fullHost;
+ try {
+ // Get the full host name; some special URIs fail (data: jar:)
+ fullHost = uri.host;
+ } catch (e) {
+ fullHost = "";
+ }
+
+ let displayHost;
+ try {
+ // This might fail if it's an IP address or doesn't have more than 1 part
+ let baseDomain = eTLDService.getBaseDomain(uri);
+
+ // Convert base domain for display; ignore the isAscii out param
+ displayHost = idnService.convertToDisplayIDN(baseDomain, {});
+ } catch (e) {
+ // Default to the host name
+ displayHost = fullHost;
+ }
+
+ // Check if we need to show something else for the host
+ if (uri.scheme == "file") {
+ // Display special text for file protocol
+ displayHost = gStr.doneFileScheme;
+ fullHost = displayHost;
+ } else if (displayHost.length == 0) {
+ // Got nothing; show the scheme (data: about: moz-icon:)
+ displayHost = replaceInsert(gStr.doneScheme, 1, uri.scheme);
+ fullHost = displayHost;
+ } else if (uri.port != -1) {
+ // Tack on the port if it's not the default port
+ let port = ":" + uri.port;
+ displayHost += port;
+ fullHost += port;
+ }
+
+ return [displayHost, fullHost];
+ },
+
+ /**
+ * Converts a number of bytes to the appropriate unit that results in a
+ * number that needs fewer than 4 digits
+ *
+ * @param aBytes
+ * Number of bytes to convert
+ * @return A pair: [new value with 3 sig. figs., its unit]
+ */
+ convertByteUnits: function DU_convertByteUnits(aBytes)
+ {
+ let unitIndex = 0;
+
+ // Convert to next unit if it needs 4 digits (after rounding), but only if
+ // we know the name of the next unit
+ while ((aBytes >= 999.5) && (unitIndex < gStr.units.length - 1)) {
+ aBytes /= 1024;
+ unitIndex++;
+ }
+
+ // Get rid of insignificant bits by truncating to 1 or 0 decimal points
+ // 0 -> 0; 1.2 -> 1.2; 12.3 -> 12.3; 123.4 -> 123; 234.5 -> 235
+ aBytes = aBytes.toFixed((aBytes > 0) && (aBytes < 100) ? 1 : 0);
+
+ return [aBytes, gStr.units[unitIndex]];
+ },
+
+ /**
+ * Converts a number of seconds to the two largest units. Time values are
+ * whole numbers, and units have the correct plural/singular form.
+ *
+ * @param aSecs
+ * Seconds to convert into the appropriate 2 units
+ * @return 4-item array [first value, its unit, second value, its unit]
+ */
+ convertTimeUnits: function DU_convertTimeUnits(aSecs)
+ {
+ // These are the maximum values for seconds, minutes, hours corresponding
+ // with gStr.timeUnits without the last item
+ let timeSize = [60, 60, 24];
+
+ let time = aSecs;
+ let scale = 1;
+ let unitIndex = 0;
+
+ // Keep converting to the next unit while we have units left and the
+ // current one isn't the largest unit possible
+ while ((unitIndex < timeSize.length) && (time >= timeSize[unitIndex])) {
+ time /= timeSize[unitIndex];
+ scale *= timeSize[unitIndex];
+ unitIndex++;
+ }
+
+ let value = convertTimeUnitsValue(time);
+ let units = convertTimeUnitsUnits(value, unitIndex);
+
+ let extra = aSecs - value * scale;
+ let nextIndex = unitIndex - 1;
+
+ // Convert the extra time to the next largest unit
+ for (let index = 0; index < nextIndex; index++)
+ extra /= timeSize[index];
+
+ let value2 = convertTimeUnitsValue(extra);
+ let units2 = convertTimeUnitsUnits(value2, nextIndex);
+
+ return [value, units, value2, units2];
+ },
+};
+
+/**
+ * Private helper for convertTimeUnits that gets the display value of a time
+ *
+ * @param aTime
+ * Time value for display
+ * @return An integer value for the time rounded down
+ */
+function convertTimeUnitsValue(aTime)
+{
+ return Math.floor(aTime);
+}
+
+/**
+ * Private helper for convertTimeUnits that gets the display units of a time
+ *
+ * @param aTime
+ * Time value for display
+ * @param aIndex
+ * Index into gStr.timeUnits for the appropriate unit
+ * @return The appropriate plural form of the unit for the time
+ */
+function convertTimeUnitsUnits(aTime, aIndex)
+{
+ // Negative index would be an invalid unit, so just give empty
+ if (aIndex < 0)
+ return "";
+
+ return PluralForm.get(aTime, gStr.timeUnits[aIndex]);
+}
+
+/**
+ * Private helper function to replace a placeholder string with a real string
+ *
+ * @param aText
+ * Source text containing placeholder (e.g., #1)
+ * @param aIndex
+ * Index number of placeholder to replace
+ * @param aValue
+ * New string to put in place of placeholder
+ * @return The string with placeholder replaced with the new string
+ */
+function replaceInsert(aText, aIndex, aValue)
+{
+ return aText.replace("#" + aIndex, aValue);
+}
+
+/**
+ * Private helper function to log errors to the error console and command line
+ *
+ * @param aMsg
+ * Error message to log or an array of strings to concat
+ */
+function log(aMsg)
+{
+ let msg = "DownloadUtils.jsm: " + (aMsg.join ? aMsg.join("") : aMsg);
+ Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).
+ logStringMessage(msg);
+ dump(msg + "\n");
+}
diff --git a/bundles/XO/modules/ISO8601DateUtils.jsm b/bundles/XO/modules/ISO8601DateUtils.jsm
new file mode 100755
index 0000000..f53dfd7
--- /dev/null
+++ b/bundles/XO/modules/ISO8601DateUtils.jsm
@@ -0,0 +1,176 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Robert Sayre.
+ * Portions created by the Initial Developer are Copyright (C) 2006
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Flock Inc. <erwan@flock.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const HOURS_TO_MINUTES = 60;
+const MINUTES_TO_SECONDS = 60;
+const SECONDS_TO_MILLISECONDS = 1000;
+const MINUTES_TO_MILLISECONDS = MINUTES_TO_SECONDS * SECONDS_TO_MILLISECONDS;
+const HOURS_TO_MILLISECONDS = HOURS_TO_MINUTES * MINUTES_TO_MILLISECONDS;
+
+var EXPORTED_SYMBOLS = ["ISO8601DateUtils"];
+
+debug("*** loading ISO8601DateUtils\n");
+
+var ISO8601DateUtils = {
+
+ /**
+ * XXX Thunderbird's W3C-DTF function
+ *
+ * Converts a W3C-DTF (subset of ISO 8601) date string to a Javascript
+ * date object. W3C-DTF is described in this note:
+ * http://www.w3.org/TR/NOTE-datetime IETF is obtained via the Date
+ * object's toUTCString() method. The object's toString() method is
+ * insufficient because it spells out timezones on Win32
+ * (f.e. "Pacific Standard Time" instead of "PST"), which Mail doesn't
+ * grok. For info, see
+ * http://lxr.mozilla.org/mozilla/source/js/src/jsdate.c#1526.
+ */
+ parse: function ISO8601_parse(aDateString) {
+ var dateString = aDateString;
+ if (!dateString.match('-')) {
+ // Workaround for server sending
+ // dates such as: 20030530T11:18:50-08:00
+ // instead of: 2003-05-30T11:18:50-08:00
+ var year = dateString.slice(0, 4);
+ var month = dateString.slice(4, 6);
+ var rest = dateString.slice(6, dateString.length);
+ dateString = year + "-" + month + "-" + rest;
+ }
+
+ var parts = dateString.match(/(\d{4})(-(\d{2,3}))?(-(\d{2}))?(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|([+-])(\d{2}):(\d{2}))?)?/);
+
+ // Here's an example of a W3C-DTF date string and what .match returns for it.
+ //
+ // date: 2003-05-30T11:18:50.345-08:00
+ // date.match returns array values:
+ //
+ // 0: 2003-05-30T11:18:50-08:00,
+ // 1: 2003,
+ // 2: -05,
+ // 3: 05,
+ // 4: -30,
+ // 5: 30,
+ // 6: T11:18:50-08:00,
+ // 7: 11,
+ // 8: 18,
+ // 9: :50,
+ // 10: 50,
+ // 11: .345,
+ // 12: 345,
+ // 13: -08:00,
+ // 14: -,
+ // 15: 08,
+ // 16: 00
+
+ // Create a Date object from the date parts. Note that the Date
+ // object apparently can't deal with empty string parameters in lieu
+ // of numbers, so optional values (like hours, minutes, seconds, and
+ // milliseconds) must be forced to be numbers.
+ var date = new Date(parts[1], parts[3] - 1, parts[5], parts[7] || 0,
+ parts[8] || 0, parts[10] || 0, parts[12] || 0);
+
+ // We now have a value that the Date object thinks is in the local
+ // timezone but which actually represents the date/time in the
+ // remote timezone (f.e. the value was "10:00 EST", and we have
+ // converted it to "10:00 PST" instead of "07:00 PST"). We need to
+ // correct that. To do so, we're going to add the offset between
+ // the remote timezone and UTC (to convert the value to UTC), then
+ // add the offset between UTC and the local timezone //(to convert
+ // the value to the local timezone).
+
+ // Ironically, W3C-DTF gives us the offset between UTC and the
+ // remote timezone rather than the other way around, while the
+ // getTimezoneOffset() method of a Date object gives us the offset
+ // between the local timezone and UTC rather than the other way
+ // around. Both of these are the additive inverse (i.e. -x for x)
+ // of what we want, so we have to invert them to use them by
+ // multipying by -1 (f.e. if "the offset between UTC and the remote
+ // timezone" is -5 hours, then "the offset between the remote
+ // timezone and UTC" is -5*-1 = 5 hours).
+
+ // Note that if the timezone portion of the date/time string is
+ // absent (which violates W3C-DTF, although ISO 8601 allows it), we
+ // assume the value to be in UTC.
+
+ // The offset between the remote timezone and UTC in milliseconds.
+ var remoteToUTCOffset = 0;
+ if (parts[13] && parts[13] != "Z") {
+ var direction = (parts[14] == "+" ? 1 : -1);
+ if (parts[15])
+ remoteToUTCOffset += direction * parts[15] * HOURS_TO_MILLISECONDS;
+ if (parts[16])
+ remoteToUTCOffset += direction * parts[16] * MINUTES_TO_MILLISECONDS;
+ }
+ remoteToUTCOffset = remoteToUTCOffset * -1; // invert it
+
+ // The offset between UTC and the local timezone in milliseconds.
+ var UTCToLocalOffset = date.getTimezoneOffset() * MINUTES_TO_MILLISECONDS;
+ UTCToLocalOffset = UTCToLocalOffset * -1; // invert it
+ date.setTime(date.getTime() + remoteToUTCOffset + UTCToLocalOffset);
+
+ return date;
+ },
+
+ create: function ISO8601_create(aDate) {
+ function zeropad (s, l) {
+ s = s.toString(); // force it to a string
+ while (s.length < l) {
+ s = '0' + s;
+ }
+ return s;
+ }
+
+ var myDate;
+ // if d is a number, turn it into a date
+ if (typeof aDate == 'number') {
+ myDate = new Date()
+ myDate.setTime(aDate);
+ } else {
+ myDate = aDate;
+ }
+
+ // YYYY-MM-DDThh:mm:ssZ
+ var result = zeropad(myDate.getUTCFullYear (), 4) +
+ zeropad(myDate.getUTCMonth () + 1, 2) +
+ zeropad(myDate.getUTCDate (), 2) + 'T' +
+ zeropad(myDate.getUTCHours (), 2) + ':' +
+ zeropad(myDate.getUTCMinutes (), 2) + ':' +
+ zeropad(myDate.getUTCSeconds (), 2) + 'Z';
+
+ return result;
+ }
+}
diff --git a/bundles/XO/modules/Microformats.js b/bundles/XO/modules/Microformats.js
new file mode 100755
index 0000000..65ce79b
--- /dev/null
+++ b/bundles/XO/modules/Microformats.js
@@ -0,0 +1,1837 @@
+var EXPORTED_SYMBOLS = ["Microformats", "adr", "tag", "hCard", "hCalendar", "geo"];
+
+var Microformats = {
+ /* When a microformat is added, the name is placed in this list */
+ list: [],
+ /* Custom iterator so that microformats can be enumerated as */
+ /* for (i in Microformats) */
+ __iterator__: function () {
+ for (let i=0; i < this.list.length; i++) {
+ yield this.list[i];
+ }
+ },
+ /**
+ * Retrieves microformats objects of the given type from a document
+ *
+ * @param name The name of the microformat (required)
+ * @param rootElement The DOM element at which to start searching (required)
+ * @param options Literal object with the following options:
+ * recurseExternalFrames - Whether or not to search child frames
+ * that reference external pages (with a src attribute)
+ * for microformats (optional - defaults to true)
+ * showHidden - Whether or not to add hidden microformat
+ * (optional - defaults to false)
+ * debug - Whether or not we are in debug mode (optional
+ * - defaults to false)
+ * @param targetArray An array of microformat objects to which is added the results (optional)
+ * @return A new array of microformat objects or the passed in microformat
+ * object array with the new objects added
+ */
+ get: function(name, rootElement, options, targetArray) {
+ function isAncestor(haystack, needle) {
+ var parent = needle;
+ while (parent = parent.parentNode) {
+ /* We need to check parentNode because defaultView.frames[i].frameElement */
+ /* isn't a real DOM node */
+ if (parent == needle.parentNode) {
+ return true;
+ }
+ }
+ return false;
+ }
+ if (!Microformats[name] || !rootElement) {
+ return;
+ }
+ targetArray = targetArray || [];
+
+ /* Root element might not be the document - we need the document's default view */
+ /* to get frames and to check their ancestry */
+ var defaultView = rootElement.defaultView || rootElement.ownerDocument.defaultView;
+ var rootDocument = rootElement.ownerDocument || rootElement;
+
+ /* If recurseExternalFrames is undefined or true, look through all child frames for microformats */
+ if (!options || !options.hasOwnProperty("recurseExternalFrames") || options.recurseExternalFrames) {
+ if (defaultView && defaultView.frames.length > 0) {
+ for (let i=0; i < defaultView.frames.length; i++) {
+ if (isAncestor(rootDocument, defaultView.frames[i].frameElement)) {
+ Microformats.get(name, defaultView.frames[i].document, options, targetArray);
+ }
+ }
+ }
+ }
+
+ /* Get the microformat nodes for the document */
+ var microformatNodes = [];
+ if (Microformats[name].className) {
+ microformatNodes = Microformats.getElementsByClassName(rootElement,
+ Microformats[name].className);
+ /* alternateClassName is for cases where a parent microformat is inferred by the children */
+ /* If we find alternateClassName, the entire document becomes the microformat */
+ if ((microformatNodes.length == 0) && Microformats[name].alternateClassName) {
+ var altClass = Microformats.getElementsByClassName(rootElement, Microformats[name].alternateClassName);
+ if (altClass.length > 0) {
+ microformatNodes.push(rootElement);
+ }
+ }
+ } else if (Microformats[name].attributeValues) {
+ microformatNodes =
+ Microformats.getElementsByAttribute(rootElement,
+ Microformats[name].attributeName,
+ Microformats[name].attributeValues);
+
+ }
+
+
+ function isVisible(node, checkChildren) {
+ if (node.getBoundingClientRect) {
+ var box = node.getBoundingClientRect();
+ } else {
+ var box = node.ownerDocument.getBoxObjectFor(node);
+ }
+ /* If the parent has is an empty box, double check the children */
+ if ((box.height == 0) || (box.width == 0)) {
+ if (checkChildren && node.childNodes.length > 0) {
+ for(let i=0; i < node.childNodes.length; i++) {
+ if (node.childNodes[i].nodeType == Components.interfaces.nsIDOMNode.ELEMENT_NODE) {
+ /* For performance reasons, we only go down one level */
+ /* of children */
+ if (isVisible(node.childNodes[i], false)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false
+ }
+ return true;
+ }
+
+ /* Create objects for the microformat nodes and put them into the microformats */
+ /* array */
+ for (let i = 0; i < microformatNodes.length; i++) {
+ /* If showHidden undefined or false, don't add microformats to the list that aren't visible */
+ if (!options || !options.hasOwnProperty("showHidden") || !options.showHidden) {
+ if (microformatNodes[i].ownerDocument) {
+ if (!isVisible(microformatNodes[i], true)) {
+ continue;
+ }
+ }
+ }
+ try {
+ if (options && options.debug) {
+ /* Don't validate in the debug case so that we don't get errors thrown */
+ /* in the debug case, we want all microformats, even if they are invalid */
+ targetArray.push(new Microformats[name].mfObject(microformatNodes[i], false));
+ } else {
+ targetArray.push(new Microformats[name].mfObject(microformatNodes[i], true));
+ }
+ } catch (ex) {
+ /* Creation of individual object probably failed because it is invalid. */
+ /* This isn't a problem, because the page might have invalid microformats */
+ }
+ }
+ return targetArray;
+ },
+ /**
+ * Counts microformats objects of the given type from a document
+ *
+ * @param name The name of the microformat (required)
+ * @param rootElement The DOM element at which to start searching (required)
+ * @param options Literal object with the following options:
+ * recurseExternalFrames - Whether or not to search child frames
+ * that reference external pages (with a src attribute)
+ * for microformats (optional - defaults to true)
+ * showHidden - Whether or not to add hidden microformat
+ * (optional - defaults to false)
+ * debug - Whether or not we are in debug mode (optional
+ * - defaults to false)
+ * @return The new count
+ */
+ count: function(name, rootElement, options) {
+ var mfArray = Microformats.get(name, rootElement, options);
+ if (mfArray) {
+ return mfArray.length;
+ }
+ return 0;
+ },
+ /**
+ * Returns true if the passed in node is a microformat. Does NOT return true
+ * if the passed in node is a child of a microformat.
+ *
+ * @param node DOM node to check
+ * @return true if the node is a microformat, false if it is not
+ */
+ isMicroformat: function(node) {
+ for (let i in Microformats)
+ {
+ if (Microformats[i].className) {
+ if (Microformats.matchClass(node, Microformats[i].className)) {
+ return true;
+ }
+ } else {
+ var attribute;
+ if (attribute = node.getAttribute(Microformats[i].attributeName)) {
+ var attributeList = Microformats[i].attributeValues.split(" ");
+ for (let j=0; j < attributeList.length; j++) {
+ if (attribute.match("(^|\\s)" + attributeList[j] + "(\\s|$)")) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+ },
+ /**
+ * This function searches a given nodes ancestors looking for a microformat
+ * and if it finds it, returns it. It does NOT include self, so if the passed
+ * in node is a microformat, it will still search ancestors for a microformat.
+ *
+ * @param node DOM node to check
+ * @return If the node is contained in a microformat, it returns the parent
+ * DOM node, otherwise returns null
+ */
+ getParent: function(node) {
+ var xpathExpression;
+ var xpathResult;
+
+ xpathExpression = "ancestor::*[";
+ for (let i=0; i < Microformats.list.length; i++) {
+ var mfname = Microformats.list[i];
+ if (i != 0) {
+ xpathExpression += " or ";
+ }
+ if (Microformats[mfname].className) {
+ xpathExpression += "contains(concat(' ', @class, ' '), ' " + Microformats[mfname].className + " ')";
+ } else {
+ var attributeList = Microformats[mfname].attributeValues.split(" ");
+ for (let j=0; j < attributeList.length; j++) {
+ if (j != 0) {
+ xpathExpression += " or ";
+ }
+ xpathExpression += "contains(concat(' ', @" + Microformats[mfname].attributeName + ", ' '), ' " + attributeList[j] + " ')";
+ }
+ }
+ }
+ xpathExpression += "][1]";
+ xpathResult = (node.ownerDocument || node).evaluate(xpathExpression, node, null, Components.interfaces.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE, null);
+ if (xpathResult.singleNodeValue) {
+ xpathResult.singleNodeValue.microformat = mfname;
+ return xpathResult.singleNodeValue;
+ }
+ return null;
+ },
+ /**
+ * If the passed in node is a microformat, this function returns a space
+ * separated list of the microformat names that correspond to this node
+ *
+ * @param node DOM node to check
+ * @return If the node is a microformat, a space separated list of microformat
+ * names, otherwise returns nothing
+ */
+ getNamesFromNode: function(node) {
+ var microformatNames = [];
+ var xpathExpression;
+ var xpathResult;
+ for (let i in Microformats)
+ {
+ if (Microformats[i]) {
+ if (Microformats[i].className) {
+ if (Microformats.matchClass(node, Microformats[i].className)) {
+ microformatNames.push(i);
+ continue;
+ }
+ } else if (Microformats[i].attributeValues) {
+ var attribute;
+ if (attribute = node.getAttribute(Microformats[i].attributeName)) {
+ var attributeList = Microformats[i].attributeValues.split(" ");
+ for (let j=0; j < attributeList.length; j++) {
+ /* If we match any attribute, we've got a microformat */
+ if (attribute.match("(^|\\s)" + attributeList[j] + "(\\s|$)")) {
+ microformatNames.push(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ return microformatNames.join(" ");
+ },
+ /**
+ * Outputs the contents of a microformat object for debug purposes.
+ *
+ * @param microformatObject JavaScript object that represents a microformat
+ * @return string containing a visual representation of the contents of the microformat
+ */
+ debug: function debug(microformatObject) {
+ function dumpObject(item, indent)
+ {
+ if (!indent) {
+ indent = "";
+ }
+ var toreturn = "";
+ var testArray = [];
+
+ for (let i in item)
+ {
+ if (testArray[i]) {
+ continue;
+ }
+ if (typeof item[i] == "object") {
+ if ((i != "node") && (i != "resolvedNode")) {
+ if (item[i] && item[i].semanticType) {
+ toreturn += indent + item[i].semanticType + " [" + i + "] { \n";
+ } else {
+ toreturn += indent + "object " + i + " { \n";
+ }
+ toreturn += dumpObject(item[i], indent + "\t");
+ toreturn += indent + "}\n";
+ }
+ } else if ((typeof item[i] != "function") && (i != "semanticType")) {
+ if (item[i]) {
+ toreturn += indent + i + "=" + item[i] + "\n";
+ }
+ }
+ }
+ if (!toreturn && item) {
+ toreturn = item.toString();
+ }
+ return toreturn;
+ }
+ return dumpObject(microformatObject);
+ },
+ add: function add(microformat, microformatDefinition) {
+ /* We always replace an existing definition with the new one */
+ if (!Microformats[microformat]) {
+ Microformats.list.push(microformat);
+ }
+ Microformats[microformat] = microformatDefinition;
+ microformatDefinition.mfObject.prototype.debug =
+ function(microformatObject) {
+ return Microformats.debug(microformatObject)
+ };
+ },
+ /* All parser specific functions are contained in this object */
+ parser: {
+ /**
+ * Uses the microformat patterns to decide what the correct text for a
+ * given microformat property is. This includes looking at things like
+ * abbr, img/alt, area/alt and value excerpting.
+ *
+ * @param propnode The DOMNode to check
+ * @param parentnode The parent node of the property. If it is a subproperty,
+ * this is the parent property node. If it is not, this is the
+ * microformat node.
+ & @param datatype HTML/text - whether to use innerHTML or innerText - defaults to text
+ * @return A string with the value of the property
+ */
+ defaultGetter: function(propnode, parentnode, datatype) {
+ function collapseWhitespace(instring) {
+ /* Remove new lines, carriage returns and tabs */
+ outstring = instring.replace(/[\n\r\t]/gi, ' ');
+ /* Replace any double spaces with single spaces */
+ outstring = outstring.replace(/\s{2,}/gi, ' ');
+ /* Remove any double spaces that are left */
+ outstring = outstring.replace(/\s{2,}/gi, '');
+ /* Remove any spaces at the beginning */
+ outstring = outstring.replace(/^\s+/, '');
+ /* Remove any spaces at the end */
+ outstring = outstring.replace(/\s+$/, '');
+ return outstring;
+ }
+
+
+ if (((((propnode.localName.toLowerCase() == "abbr") || (propnode.localName.toLowerCase() == "html:abbr")) && !propnode.namespaceURI) ||
+ ((propnode.localName.toLowerCase() == "abbr") && (propnode.namespaceURI == "http://www.w3.org/1999/xhtml"))) && (propnode.getAttribute("title"))) {
+ return propnode.getAttribute("title");
+ } else if ((propnode.nodeName.toLowerCase() == "img") && (propnode.getAttribute("alt"))) {
+ return propnode.getAttribute("alt");
+ } else if ((propnode.nodeName.toLowerCase() == "area") && (propnode.getAttribute("alt"))) {
+ return propnode.getAttribute("alt");
+ } else if ((propnode.nodeName.toLowerCase() == "textarea") ||
+ (propnode.nodeName.toLowerCase() == "select") ||
+ (propnode.nodeName.toLowerCase() == "input")) {
+ return propnode.value;
+ } else {
+ var values = Microformats.getElementsByClassName(propnode, "value");
+ /* Verify that values are children of the propnode */
+ for (let i = values.length-1; i >= 0; i--) {
+ if (values[i].parentNode != propnode) {
+ values.splice(i,1);
+ }
+ }
+ if (values.length > 0) {
+ var value = "";
+ for (let j=0;j<values.length;j++) {
+ value += Microformats.parser.defaultGetter(values[j], propnode, datatype);
+ }
+ return collapseWhitespace(value);
+ }
+ var s;
+ if (datatype == "HTML") {
+ s = propnode.innerHTML;
+ } else {
+ if (propnode.innerText) {
+ s = propnode.innerText;
+ } else {
+ s = propnode.textContent;
+ }
+ }
+ /* If we are processing a value node, don't remove whitespace now */
+ /* (we'll do it later) */
+ if (!Microformats.matchClass(propnode, "value")) {
+ s = collapseWhitespace(s);
+ }
+ if (s.length > 0) {
+ return s;
+ }
+ }
+ },
+ /**
+ * Used to specifically retrieve a date in a microformat node.
+ * After getting the default text, it normalizes it to an ISO8601 date.
+ *
+ * @param propnode The DOMNode to check
+ * @param parentnode The parent node of the property. If it is a subproperty,
+ * this is the parent property node. If it is not, this is the
+ * microformat node.
+ * @return A string with the normalized date.
+ */
+ dateTimeGetter: function(propnode, parentnode) {
+ var date = Microformats.parser.textGetter(propnode, parentnode);
+ if (date) {
+ return Microformats.parser.normalizeISO8601(date);
+ }
+ },
+ /**
+ * Used to specifically retrieve a URI in a microformat node. This includes
+ * looking at an href/img/object/area to get the fully qualified URI.
+ *
+ * @param propnode The DOMNode to check
+ * @param parentnode The parent node of the property. If it is a subproperty,
+ * this is the parent property node. If it is not, this is the
+ * microformat node.
+ * @return A string with the fully qualified URI.
+ */
+ uriGetter: function(propnode, parentnode) {
+ var pairs = {"a":"href", "img":"src", "object":"data", "area":"href"};
+ var name = propnode.nodeName.toLowerCase();
+ if (pairs.hasOwnProperty(name)) {
+ return propnode[pairs[name]];
+ }
+ return Microformats.parser.textGetter(propnode, parentnode);
+ },
+ /**
+ * Used to specifically retrieve a telephone number in a microformat node.
+ * Basically this is to handle the face that telephone numbers use value
+ * as the name as one of their subproperties, but value is also used for
+ * value excerpting (http://microformats.org/wiki/hcard#Value_excerpting)
+
+ * @param propnode The DOMNode to check
+ * @param parentnode The parent node of the property. If it is a subproperty,
+ * this is the parent property node. If it is not, this is the
+ * microformat node.
+ * @return A string with the telephone number
+ */
+ telGetter: function(propnode, parentnode) {
+ var pairs = {"a":"href", "object":"data", "area":"href"};
+ var name = propnode.nodeName.toLowerCase();
+ if (pairs.hasOwnProperty(name)) {
+ var protocol;
+ if (propnode[pairs[name]].indexOf("tel:") == 0) {
+ protocol = "tel:";
+ }
+ if (propnode[pairs[name]].indexOf("fax:") == 0) {
+ protocol = "fax:";
+ }
+ if (propnode[pairs[name]].indexOf("modem:") == 0) {
+ protocol = "modem:";
+ }
+ if (protocol) {
+ if (propnode[pairs[name]].indexOf('?') > 0) {
+ return unescape(propnode[pairs[name]].substring(protocol.length, propnode[pairs[name]].indexOf('?')));
+ } else {
+ return unescape(propnode[pairs[name]].substring(protocol.length));
+ }
+ }
+ }
+ /* Special case - if this node is a value, use the parent node to get all the values */
+ if (Microformats.matchClass(propnode, "value")) {
+ return Microformats.parser.textGetter(parentnode, parentnode);
+ } else {
+ /* Virtual case */
+ if (!parentnode && (Microformats.getElementsByClassName(propnode, "type").length > 0)) {
+ var tempNode = propnode.cloneNode(true);
+ var typeNodes = Microformats.getElementsByClassName(tempNode, "type");
+ for (let i=0; i < typeNodes.length; i++) {
+ typeNodes[i].parentNode.removeChild(typeNodes[i]);
+ }
+ return Microformats.parser.textGetter(tempNode);
+ }
+ return Microformats.parser.textGetter(propnode, parentnode);
+ }
+ },
+ /**
+ * Used to specifically retrieve an email address in a microformat node.
+ * This includes at an href, as well as removing subject if specified and
+ * the mailto prefix.
+ *
+ * @param propnode The DOMNode to check
+ * @param parentnode The parent node of the property. If it is a subproperty,
+ * this is the parent property node. If it is not, this is the
+ * microformat node.
+ * @return A string with the email address.
+ */
+ emailGetter: function(propnode, parentnode) {
+ if ((propnode.nodeName.toLowerCase() == "a") || (propnode.nodeName.toLowerCase() == "area")) {
+ var mailto = propnode.href;
+ /* IO Service won't fully parse mailto, so we do it manually */
+ if (mailto.indexOf('?') > 0) {
+ return unescape(mailto.substring("mailto:".length, mailto.indexOf('?')));
+ } else {
+ return unescape(mailto.substring("mailto:".length));
+ }
+ } else {
+ /* Special case - if this node is a value, use the parent node to get all the values */
+ /* If this case gets executed, per the value design pattern, the result */
+ /* will be the EXACT email address with no extra parsing required */
+ if (Microformats.matchClass(propnode, "value")) {
+ return Microformats.parser.textGetter(parentnode, parentnode);
+ } else {
+ /* Virtual case */
+ if (!parentnode && (Microformats.getElementsByClassName(propnode, "type").length > 0)) {
+ var tempNode = propnode.cloneNode(true);
+ var typeNodes = Microformats.getElementsByClassName(tempNode, "type");
+ for (let i=0; i < typeNodes.length; i++) {
+ typeNodes[i].parentNode.removeChild(typeNodes[i]);
+ }
+ return Microformats.parser.textGetter(tempNode);
+ }
+ return Microformats.parser.textGetter(propnode, parentnode);
+ }
+ }
+ },
+ /**
+ * Used when a caller needs the text inside a particular DOM node.
+ * It calls defaultGetter to handle all the subtleties of getting
+ * text from a microformat.
+ *
+ * @param propnode The DOMNode to check
+ * @param parentnode The parent node of the property. If it is a subproperty,
+ * this is the parent property node. If it is not, this is the
+ * microformat node.
+ * @return A string with just the text including all tags.
+ */
+ textGetter: function(propnode, parentnode) {
+ return Microformats.parser.defaultGetter(propnode, parentnode, "text");
+ },
+ /**
+ * Used when a caller needs the HTML inside a particular DOM node.
+ *
+ * @param propnode The DOMNode to check
+ * @param parentnode The parent node of the property. If it is a subproperty,
+ * this is the parent property node. If it is not, this is the
+ * microformat node.
+ * @return An emulated string object that also has a new function called toHTML
+ */
+ HTMLGetter: function(propnode, parentnode) {
+ /* This is so we can have a string that behaves like a string */
+ /* but also has a new function that can return the HTML that corresponds */
+ /* to the string. */
+ function mfHTML(value) {
+ this.valueOf = function() {return value ? value.valueOf() : "";}
+ this.toString = function() {return value ? value.toString() : "";}
+ }
+ mfHTML.prototype = new String;
+ mfHTML.prototype.toHTML = function() {
+ return Microformats.parser.defaultGetter(propnode, parentnode, "HTML");
+ }
+ return new mfHTML(Microformats.parser.defaultGetter(propnode, parentnode, "text"));
+ },
+ /**
+ * Internal parser API used to determine which getter to call based on the
+ * datatype specified in the microformat definition.
+ *
+ * @param prop The microformat property in the definition
+ * @param propnode The DOMNode to check
+ * @param parentnode The parent node of the property. If it is a subproperty,
+ * this is the parent property node. If it is not, this is the
+ * microformat node.
+ * @return A string with the property value.
+ */
+ datatypeHelper: function(prop, node, parentnode) {
+ var result;
+ var datatype = prop.datatype;
+ switch (datatype) {
+ case "dateTime":
+ result = Microformats.parser.dateTimeGetter(node, parentnode);
+ break;
+ case "anyURI":
+ result = Microformats.parser.uriGetter(node, parentnode);
+ break;
+ case "email":
+ result = Microformats.parser.emailGetter(node, parentnode);
+ break;
+ case "tel":
+ result = Microformats.parser.telGetter(node, parentnode);
+ break;
+ case "HTML":
+ result = Microformats.parser.HTMLGetter(node, parentnode);
+ break;
+ case "float":
+ var asText = Microformats.parser.textGetter(node, parentnode);
+ if (!isNaN(asText)) {
+ result = parseFloat(asText);
+ }
+ break;
+ case "custom":
+ result = prop.customGetter(node, parentnode);
+ break;
+ case "microformat":
+ try {
+ result = new Microformats[prop.microformat].mfObject(node, true);
+ } catch (ex) {
+ /* There are two reasons we get here, one because the node is not */
+ /* a microformat and two because the node is a microformat and */
+ /* creation failed. If the node is not a microformat, we just fall */
+ /* through and use the default getter since there are some cases */
+ /* (location in hCalendar) where a property can be either a microformat */
+ /* or a string. If creation failed, we break and simply don't add the */
+ /* microformat property to the parent microformat */
+ if (ex != "Node is not a microformat (" + prop.microformat + ")") {
+ break;
+ }
+ }
+ if (result != undefined) {
+ if (prop.microformat_property) {
+ result = result[prop.microformat_property];
+ }
+ break;
+ }
+ default:
+ result = Microformats.parser.textGetter(node, parentnode);
+ break;
+ }
+ /* This handles the case where one property implies another property */
+ /* For instance, org by itself is actually org.organization-name */
+ if (prop.values && (result != undefined)) {
+ var validType = false;
+ for (let value in prop.values) {
+ if (result.toLowerCase() == prop.values[value]) {
+ result = result.toLowerCase();
+ validType = true;
+ break;
+ }
+ }
+ if (!validType) {
+ return;
+ }
+ }
+ return result;
+ },
+ newMicroformat: function(object, in_node, microformat, validate) {
+ /* check to see if we are even valid */
+ if (!Microformats[microformat]) {
+ throw("Invalid microformat - " + microformat);
+ }
+ if (in_node.ownerDocument) {
+ if (Microformats[microformat].attributeName) {
+ if (!(in_node.getAttribute(Microformats[microformat].attributeName))) {
+ throw("Node is not a microformat (" + microformat + ")");
+ }
+ } else {
+ if (!Microformats.matchClass(in_node, Microformats[microformat].className)) {
+ throw("Node is not a microformat (" + microformat + ")");
+ }
+ }
+ }
+ var node = in_node;
+ if ((Microformats[microformat].className) && in_node.ownerDocument) {
+ node = Microformats.parser.preProcessMicroformat(in_node);
+ }
+
+ for (let i in Microformats[microformat].properties) {
+ object.__defineGetter__(i, Microformats.parser.getMicroformatPropertyGenerator(node, microformat, i, object));
+ }
+
+ /* The node in the object should be the original node */
+ object.node = in_node;
+ /* we also store the node that has been "resolved" */
+ object.resolvedNode = node;
+ object.semanticType = microformat;
+ if (validate) {
+ Microformats.parser.validate(node, microformat);
+ }
+ },
+ getMicroformatPropertyGenerator: function getMicroformatPropertyGenerator(node, name, property, microformat)
+ {
+ return function() {
+ var result = Microformats.parser.getMicroformatProperty(node, name, property);
+// delete microformat[property];
+// microformat[property] = result;
+ return result;
+ };
+ },
+ getPropertyInternal: function getPropertyInternal(propnode, parentnode, propobj, propname, mfnode) {
+ var result;
+ if (propobj.subproperties) {
+ for (let subpropname in propobj.subproperties) {
+ var subpropnodes;
+ var subpropobj = propobj.subproperties[subpropname];
+ if (subpropobj.rel == true) {
+ subpropnodes = Microformats.getElementsByAttribute(propnode, "rel", subpropname);
+ } else {
+ subpropnodes = Microformats.getElementsByClassName(propnode, subpropname);
+ }
+ var resultArray = [];
+ var subresult;
+ for (let i = 0; i < subpropnodes.length; i++) {
+ subresult = Microformats.parser.getPropertyInternal(subpropnodes[i], propnode,
+ subpropobj,
+ subpropname, mfnode);
+ if (subresult != undefined) {
+ resultArray.push(subresult);
+ /* If we're not a plural property, don't bother getting more */
+ if (!subpropobj.plural) {
+ break;
+ }
+ }
+ }
+ if (resultArray.length == 0) {
+ subresult = Microformats.parser.getPropertyInternal(propnode, null,
+ subpropobj,
+ subpropname, mfnode);
+ if (subresult != undefined) {
+ resultArray.push(subresult);
+ }
+ }
+ if (resultArray.length > 0) {
+ result = result || {};
+ if (subpropobj.plural) {
+ result[subpropname] = resultArray;
+ } else {
+ result[subpropname] = resultArray[0];
+ }
+ }
+ }
+ }
+ if (!parentnode || (!result && propobj.subproperties)) {
+ if (propobj.virtual) {
+ if (propobj.virtualGetter) {
+ result = propobj.virtualGetter(mfnode || propnode);
+ } else {
+ result = Microformats.parser.datatypeHelper(propobj, propnode);
+ }
+ }
+ } else if (!result) {
+ result = Microformats.parser.datatypeHelper(propobj, propnode, parentnode);
+ }
+ return result;
+ },
+ getMicroformatProperty: function getMicroformatProperty(in_mfnode, mfname, propname) {
+ var mfnode = in_mfnode;
+ /* If the node has not been preprocessed, the requested microformat */
+ /* is a class based microformat and the passed in node is not the */
+ /* entire document, preprocess it. Preprocessing the node involves */
+ /* creating a duplicate of the node and taking care of things like */
+ /* the include and header design patterns */
+ if (!in_mfnode.origNode && Microformats[mfname].className && in_mfnode.ownerDocument) {
+ mfnode = Microformats.parser.preProcessMicroformat(in_mfnode);
+ }
+ /* propobj is the corresponding property object in the microformat */
+ var propobj;
+ /* If there is a corresponding property in the microformat, use it */
+ if (Microformats[mfname].properties[propname]) {
+ propobj = Microformats[mfname].properties[propname];
+ } else {
+ /* If we didn't get a property, bail */
+ return;
+ }
+ /* Query the correct set of nodes (rel or class) based on the setting */
+ /* in the property */
+ var propnodes;
+ if (propobj.rel == true) {
+ propnodes = Microformats.getElementsByAttribute(mfnode, "rel", propname);
+ } else {
+ propnodes = Microformats.getElementsByClassName(mfnode, propname);
+ }
+ for (let i=propnodes.length-1; i >= 0; i--) {
+ /* The reason getParent is not used here is because this code does */
+ /* not apply to attribute based microformats, plus adr and geo */
+ /* when contained in hCard are a special case */
+ var parentnode;
+ var node = propnodes[i];
+ var xpathExpression = "";
+ for (let j=0; j < Microformats.list.length; j++) {
+ /* Don't treat adr or geo in an hCard as a microformat in this case */
+ if ((mfname == "hCard") && ((Microformats.list[j] == "adr") || (Microformats.list[j] == "geo"))) {
+ continue;
+ }
+ if (Microformats[Microformats.list[j]].className) {
+ if (xpathExpression.length == 0) {
+ xpathExpression = "ancestor::*[";
+ } else {
+ xpathExpression += " or ";
+ }
+ xpathExpression += "contains(concat(' ', @class, ' '), ' " + Microformats[Microformats.list[j]].className + " ')";
+ }
+ }
+ xpathExpression += "][1]";
+ var xpathResult = (node.ownerDocument || node).evaluate(xpathExpression, node, null, Components.interfaces.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE, null);
+ if (xpathResult.singleNodeValue) {
+ xpathResult.singleNodeValue.microformat = mfname;
+ parentnode = xpathResult.singleNodeValue;
+ }
+ /* If the propnode is not a child of the microformat, and */
+ /* the property belongs to the parent microformat as well, */
+ /* remove it. */
+ if (parentnode != mfnode) {
+ var mfNameString = Microformats.getNamesFromNode(parentnode);
+ var mfNames = mfNameString.split(" ");
+ var j;
+ for (j=0; j < mfNames.length; j++) {
+ /* If this property is in the parent microformat, remove the node */
+ if (Microformats[mfNames[j]].properties[propname]) {
+ propnodes.splice(i,1);
+ break;
+ }
+ }
+ }
+ }
+ if (propnodes.length > 0) {
+ var resultArray = [];
+ for (let i = 0; i < propnodes.length; i++) {
+ var subresult = Microformats.parser.getPropertyInternal(propnodes[i],
+ mfnode,
+ propobj,
+ propname);
+ if (subresult != undefined) {
+ resultArray.push(subresult);
+ /* If we're not a plural property, don't bother getting more */
+ if (!propobj.plural) {
+ return resultArray[0];
+ }
+ }
+ }
+ if (resultArray.length > 0) {
+ return resultArray;
+ }
+ } else {
+ /* If we didn't find any class nodes, check to see if this property */
+ /* is virtual and if so, call getPropertyInternal again */
+ if (propobj.virtual) {
+ return Microformats.parser.getPropertyInternal(mfnode, null,
+ propobj, propname);
+ }
+ }
+ return;
+ },
+ /**
+ * Internal parser API used to resolve includes and headers. Includes are
+ * resolved by simply cloning the node and replacing it in a clone of the
+ * original DOM node. Headers are resolved by creating a span and then copying
+ * the innerHTML and the class name.
+ *
+ * @param in_mfnode The node to preProcess.
+ * @return If the node had includes or headers, a cloned node otherwise
+ * the original node. You can check to see if the node was cloned
+ * by looking for .origNode in the new node.
+ */
+ preProcessMicroformat: function preProcessMicroformat(in_mfnode) {
+ var mfnode;
+ if ((in_mfnode.nodeName.toLowerCase() == "td") && (in_mfnode.getAttribute("headers"))) {
+ mfnode = in_mfnode.cloneNode(true);
+ mfnode.origNode = in_mfnode;
+ var headers = in_mfnode.getAttribute("headers").split(" ");
+ for (let i = 0; i < headers.length; i++) {
+ var tempNode = in_mfnode.ownerDocument.createElement("span");
+ var headerNode = in_mfnode.ownerDocument.getElementById(headers[i]);
+ if (headerNode) {
+ tempNode.innerHTML = headerNode.innerHTML;
+ tempNode.className = headerNode.className;
+ mfnode.appendChild(tempNode);
+ }
+ }
+ } else {
+ mfnode = in_mfnode;
+ }
+ var includes = Microformats.getElementsByClassName(mfnode, "include");
+ if (includes.length > 0) {
+ /* If we didn't clone, clone now */
+ if (!mfnode.origNode) {
+ mfnode = in_mfnode.cloneNode(true);
+ mfnode.origNode = in_mfnode;
+ }
+ includes = Microformats.getElementsByClassName(mfnode, "include");
+ var includeId;
+ var include_length = includes.length;
+ for (let i = include_length -1; i >= 0; i--) {
+ if (includes[i].nodeName.toLowerCase() == "a") {
+ includeId = includes[i].getAttribute("href").substr(1);
+ }
+ if (includes[i].nodeName.toLowerCase() == "object") {
+ includeId = includes[i].getAttribute("data").substr(1);
+ }
+ if (in_mfnode.ownerDocument.getElementById(includeId)) {
+ includes[i].parentNode.replaceChild(in_mfnode.ownerDocument.getElementById(includeId).cloneNode(true), includes[i]);
+ }
+ }
+ }
+ return mfnode;
+ },
+ validate: function validate(mfnode, mfname) {
+ var error = "";
+ if (Microformats[mfname].validate) {
+ return Microformats[mfname].validate(mfnode);
+ } else if (Microformats[mfname].required) {
+ for (let i=0;i<Microformats[mfname].required.length;i++) {
+ if (!Microformats.parser.getMicroformatProperty(mfnode, mfname, Microformats[mfname].required[i])) {
+ error += "Required property " + Microformats[mfname].required[i] + " not specified\n";
+ }
+ }
+ if (error.length > 0) {
+ throw(error);
+ }
+ return true;
+ }
+ },
+ /* This function normalizes an ISO8601 date by adding punctuation and */
+ /* ensuring that hours and seconds have values */
+ normalizeISO8601: function normalizeISO8601(string)
+ {
+ var dateArray = string.match(/(\d\d\d\d)(?:-?(\d\d)(?:-?(\d\d)(?:[T ](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(?:([-+Z])(?:(\d\d)(?::?(\d\d))?)?)?)?)?)?/);
+
+ var dateString;
+ var tzOffset = 0;
+ if (!dateArray) {
+ return;
+ }
+ if (dateArray[1]) {
+ dateString = dateArray[1];
+ if (dateArray[2]) {
+ dateString += "-" + dateArray[2];
+ if (dateArray[3]) {
+ dateString += "-" + dateArray[3];
+ if (dateArray[4]) {
+ dateString += "T" + dateArray[4];
+ if (dateArray[5]) {
+ dateString += ":" + dateArray[5];
+ } else {
+ dateString += ":" + "00";
+ }
+ if (dateArray[6]) {
+ dateString += ":" + dateArray[6];
+ } else {
+ dateString += ":" + "00";
+ }
+ if (dateArray[7]) {
+ dateString += "." + dateArray[7];
+ }
+ if (dateArray[8]) {
+ dateString += dateArray[8];
+ if ((dateArray[8] == "+") || (dateArray[8] == "-")) {
+ if (dateArray[9]) {
+ dateString += dateArray[9];
+ if (dateArray[10]) {
+ dateString += dateArray[10];
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return dateString;
+ }
+ },
+ /**
+ * Converts an ISO8601 date into a JavaScript date object, honoring the TZ
+ * offset and Z if present to convert the date to local time
+ * NOTE: I'm using an extra parameter on the date object for this function.
+ * I set date.time to true if there is a date, otherwise date.time is false.
+ *
+ * @param string ISO8601 formatted date
+ * @return JavaScript date object that represents the ISO date.
+ */
+ dateFromISO8601: function dateFromISO8601(string) {
+ var dateArray = string.match(/(\d\d\d\d)(?:-?(\d\d)(?:-?(\d\d)(?:[T ](\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(?:([-+Z])(?:(\d\d)(?::?(\d\d))?)?)?)?)?)?/);
+
+ var date = new Date(dateArray[1], 0, 1);
+ date.time = false;
+
+ if (dateArray[2]) {
+ date.setMonth(dateArray[2] - 1);
+ }
+ if (dateArray[3]) {
+ date.setDate(dateArray[3]);
+ }
+ if (dateArray[4]) {
+ date.setHours(dateArray[4]);
+ date.time = true;
+ if (dateArray[5]) {
+ date.setMinutes(dateArray[5]);
+ if (dateArray[6]) {
+ date.setSeconds(dateArray[6]);
+ if (dateArray[7]) {
+ date.setMilliseconds(Number("0." + dateArray[7]) * 1000);
+ }
+ }
+ }
+ }
+ if (dateArray[8]) {
+ if (dateArray[8] == "-") {
+ if (dateArray[9] && dateArray[10]) {
+ date.setHours(date.getHours() + parseInt(dateArray[9], 10));
+ date.setMinutes(date.getMinutes() + parseInt(dateArray[10], 10));
+ }
+ } else if (dateArray[8] == "+") {
+ if (dateArray[9] && dateArray[10]) {
+ date.setHours(date.getHours() - parseInt(dateArray[9], 10));
+ date.setMinutes(date.getMinutes() - parseInt(dateArray[10], 10));
+ }
+ }
+ /* at this point we have the time in gmt */
+ /* convert to local if we had a Z - or + */
+ if (dateArray[8]) {
+ var tzOffset = date.getTimezoneOffset();
+ if (tzOffset < 0) {
+ date.setMinutes(date.getMinutes() + tzOffset);
+ } else if (tzOffset > 0) {
+ date.setMinutes(date.getMinutes() - tzOffset);
+ }
+ }
+ }
+ return date;
+ },
+ /**
+ * Converts a Javascript date object into an ISO 8601 formatted date
+ * NOTE: I'm using an extra parameter on the date object for this function.
+ * If date.time is NOT true, this function only outputs the date.
+ *
+ * @param date Javascript Date object
+ * @param punctuation true if the date should have -/:
+ * @return string with the ISO date.
+ */
+ iso8601FromDate: function iso8601FromDate(date, punctuation) {
+ var string = date.getFullYear().toString();
+ if (punctuation) {
+ string += "-";
+ }
+ string += (date.getMonth() + 1).toString().replace(/\b(\d)\b/g, '0$1');
+ if (punctuation) {
+ string += "-";
+ }
+ string += date.getDate().toString().replace(/\b(\d)\b/g, '0$1');
+ if (date.time) {
+ string += "T";
+ string += date.getHours().toString().replace(/\b(\d)\b/g, '0$1');
+ if (punctuation) {
+ string += ":";
+ }
+ string += date.getMinutes().toString().replace(/\b(\d)\b/g, '0$1');
+ if (punctuation) {
+ string += ":";
+ }
+ string += date.getSeconds().toString().replace(/\b(\d)\b/g, '0$1');
+ if (date.getMilliseconds() > 0) {
+ if (punctuation) {
+ string += ".";
+ }
+ string += date.getMilliseconds().toString();
+ }
+ }
+ return string;
+ },
+ simpleEscape: function simpleEscape(s)
+ {
+ s = s.replace(/\&/g, '%26');
+ s = s.replace(/\#/g, '%23');
+ s = s.replace(/\+/g, '%2B');
+ s = s.replace(/\-/g, '%2D');
+ s = s.replace(/\=/g, '%3D');
+ s = s.replace(/\'/g, '%27');
+ s = s.replace(/\,/g, '%2C');
+// s = s.replace(/\r/g, '%0D');
+// s = s.replace(/\n/g, '%0A');
+ s = s.replace(/ /g, '+');
+ return s;
+ },
+ /**
+ * Not intended for external consumption. Microformat implementations might use it.
+ *
+ * Retrieve elements matching all classes listed in a space-separated string.
+ * I had to implement my own because I need an Array, not an nsIDomNodeList
+ *
+ * @param rootElement The DOM element at which to start searching (optional)
+ * @param className A space separated list of classenames
+ * @return microformatNodes An array of DOM Nodes, each representing a
+ microformat in the document.
+ */
+ getElementsByClassName: function getElementsByClassName(rootNode, className)
+ {
+ var returnElements = [];
+
+ if ((rootNode.ownerDocument || rootNode).getElementsByClassName) {
+ /* Firefox 3 - native getElementsByClassName */
+ var col = rootNode.getElementsByClassName(className);
+ for (let i = 0; i < col.length; i++) {
+ returnElements[i] = col[i];
+ }
+ } else if ((rootNode.ownerDocument || rootNode).evaluate) {
+ /* Firefox 2 and below - XPath */
+ var xpathExpression;
+ xpathExpression = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
+ var xpathResult = (rootNode.ownerDocument || rootNode).evaluate(xpathExpression, rootNode, null, 0, null);
+
+ var node;
+ while (node = xpathResult.iterateNext()) {
+ returnElements.push(node);
+ }
+ } else {
+ /* Slow fallback for testing */
+ className = className.replace(/\-/g, "\\-");
+ var elements = rootNode.getElementsByTagName("*");
+ for (let i=0;i<elements.length;i++) {
+ if (elements[i].className.match("(^|\\s)" + className + "(\\s|$)")) {
+ returnElements.push(elements[i]);
+ }
+ }
+ }
+ return returnElements;
+ },
+ /**
+ * Not intended for external consumption. Microformat implementations might use it.
+ *
+ * Retrieve elements matching an attribute and an attribute list in a space-separated string.
+ *
+ * @param rootElement The DOM element at which to start searching (optional)
+ * @param atributeName The attribute name to match against
+ * @param attributeValues A space separated list of attribute values
+ * @return microformatNodes An array of DOM Nodes, each representing a
+ microformat in the document.
+ */
+ getElementsByAttribute: function getElementsByAttribute(rootNode, attributeName, attributeValues)
+ {
+ var attributeList = attributeValues.split(" ");
+
+ var returnElements = [];
+
+ if ((rootNode.ownerDocument || rootNode).evaluate) {
+ /* Firefox 3 and below - XPath */
+ /* Create an XPath expression based on the attribute list */
+ var xpathExpression = ".//*[";
+ for (let i = 0; i < attributeList.length; i++) {
+ if (i != 0) {
+ xpathExpression += " or ";
+ }
+ xpathExpression += "contains(concat(' ', @" + attributeName + ", ' '), ' " + attributeList[i] + " ')";
+ }
+ xpathExpression += "]";
+
+ var xpathResult = (rootNode.ownerDocument || rootNode).evaluate(xpathExpression, rootNode, null, 0, null);
+
+ var node;
+ while (node = xpathResult.iterateNext()) {
+ returnElements.push(node);
+ }
+ } else {
+ /* Need Slow fallback for testing */
+ }
+ return returnElements;
+ },
+ matchClass: function matchClass(node, className) {
+ var classValue = node.getAttribute("class");
+ return (classValue && classValue.match("(^|\\s)" + className + "(\\s|$)"));
+ }
+};
+
+/* MICROFORMAT DEFINITIONS BEGIN HERE */
+
+function adr(node, validate) {
+ if (node) {
+ Microformats.parser.newMicroformat(this, node, "adr", validate);
+ }
+}
+
+adr.prototype.toString = function() {
+ var address_text = "";
+ var start_parens = false;
+ if (this["street-address"]) {
+ address_text += this["street-address"][0];
+ } else if (this["extended-address"]) {
+ address_text += this["extended-address"];
+ }
+ if (this["locality"]) {
+ if (this["street-address"] || this["extended-address"]) {
+ address_text += " (";
+ start_parens = true;
+ }
+ address_text += this["locality"];
+ }
+ if (this["region"]) {
+ if ((this["street-address"] || this["extended-address"]) && (!start_parens)) {
+ address_text += " (";
+ start_parens = true;
+ } else if (this["locality"]) {
+ address_text += ", ";
+ }
+ address_text += this["region"];
+ }
+ if (this["country-name"]) {
+ if ((this["street-address"] || this["extended-address"]) && (!start_parens)) {
+ address_text += " (";
+ start_parens = true;
+ address_text += this["country-name"];
+ } else if ((!this["locality"]) && (!this["region"])) {
+ address_text += this["country-name"];
+ } else if (((!this["locality"]) && (this["region"])) || ((this["locality"]) && (!this["region"]))) {
+ address_text += ", ";
+ address_text += this["country-name"];
+ }
+ }
+ if (start_parens) {
+ address_text += ")";
+ }
+ return address_text;
+}
+
+var adr_definition = {
+ mfObject: adr,
+ className: "adr",
+ properties: {
+ "type" : {
+ plural: true,
+ values: ["work", "home", "pref", "postal", "dom", "intl", "parcel"]
+ },
+ "post-office-box" : {
+ },
+ "street-address" : {
+ plural: true
+ },
+ "extended-address" : {
+ },
+ "locality" : {
+ },
+ "region" : {
+ },
+ "postal-code" : {
+ },
+ "country-name" : {
+ }
+ },
+ validate: function(node) {
+ var xpathExpression = "count(descendant::*[" +
+ "contains(concat(' ', @class, ' '), ' post-office-box ')" +
+ " or contains(concat(' ', @class, ' '), ' street-address ')" +
+ " or contains(concat(' ', @class, ' '), ' extended-address ')" +
+ " or contains(concat(' ', @class, ' '), ' locality ')" +
+ " or contains(concat(' ', @class, ' '), ' region ')" +
+ " or contains(concat(' ', @class, ' '), ' postal-code ')" +
+ " or contains(concat(' ', @class, ' '), ' country-name')" +
+ "])";
+ var xpathResult = (node.ownerDocument || node).evaluate(xpathExpression, node, null, Components.interfaces.nsIDOMXPathResult.ANY_TYPE, null).numberValue;
+ if (xpathResult == 0) {
+ throw("Unable to create microformat");
+ }
+ return true;
+ }
+};
+
+Microformats.add("adr", adr_definition);
+
+function hCard(node, validate) {
+ if (node) {
+ Microformats.parser.newMicroformat(this, node, "hCard", validate);
+ }
+}
+hCard.prototype.toString = function() {
+ if (this.resolvedNode) {
+ /* If this microformat has an include pattern, put the */
+ /* organization-name in parenthesis after the fn to differentiate */
+ /* them. */
+ var fns = Microformats.getElementsByClassName(this.node, "fn");
+ if (fns.length === 0) {
+ if (this.fn) {
+ if (this.org && this.org[0]["organization-name"] && (this.fn != this.org[0]["organization-name"])) {
+ return this.fn + " (" + this.org[0]["organization-name"] + ")";
+ }
+ }
+ }
+ }
+ return this.fn;
+}
+
+var hCard_definition = {
+ mfObject: hCard,
+ className: "vcard",
+ required: ["fn"],
+ properties: {
+ "adr" : {
+ plural: true,
+ datatype: "microformat",
+ microformat: "adr"
+ },
+ "agent" : {
+ plural: true,
+ datatype: "microformat",
+ microformat: "hCard"
+ },
+ "bday" : {
+ datatype: "dateTime"
+ },
+ "class" : {
+ },
+ "category" : {
+ plural: true,
+ datatype: "microformat",
+ microformat: "tag",
+ microformat_property: "tag"
+ },
+ "email" : {
+ subproperties: {
+ "type" : {
+ plural: true,
+ values: ["internet", "x400", "pref"]
+ },
+ "value" : {
+ datatype: "email",
+ virtual: true
+ }
+ },
+ plural: true
+ },
+ "fn" : {
+ required: true
+ },
+ "geo" : {
+ datatype: "microformat",
+ microformat: "geo"
+ },
+ "key" : {
+ plural: true
+ },
+ "label" : {
+ plural: true
+ },
+ "logo" : {
+ plural: true,
+ datatype: "anyURI"
+ },
+ "mailer" : {
+ plural: true
+ },
+ "n" : {
+ subproperties: {
+ "honorific-prefix" : {
+ plural: true
+ },
+ "given-name" : {
+ plural: true
+ },
+ "additional-name" : {
+ plural: true
+ },
+ "family-name" : {
+ plural: true
+ },
+ "honorific-suffix" : {
+ plural: true
+ }
+ },
+ virtual: true,
+ /* Implied "n" Optimization */
+ /* http://microformats.org/wiki/hcard#Implied_.22n.22_Optimization */
+ virtualGetter: function(mfnode) {
+ var fn = Microformats.parser.getMicroformatProperty(mfnode, "hCard", "fn");
+ var orgs = Microformats.parser.getMicroformatProperty(mfnode, "hCard", "org");
+ var given_name = [];
+ var family_name = [];
+ if (fn && (!orgs || (orgs.length > 1) || (fn != orgs[0]["organization-name"]))) {
+ var fns = fn.split(" ");
+ if (fns.length === 2) {
+ if (fns[0].charAt(fns[0].length-1) == ',') {
+ given_name[0] = fns[1];
+ family_name[0] = fns[0].substr(0, fns[0].length-1);
+ } else if (fns[1].length == 1) {
+ given_name[0] = fns[1];
+ family_name[0] = fns[0];
+ } else if ((fns[1].length == 2) && (fns[1].charAt(fns[1].length-1) == '.')) {
+ given_name[0] = fns[1];
+ family_name[0] = fns[0];
+ } else {
+ given_name[0] = fns[0];
+ family_name[0] = fns[1];
+ }
+ return {"given-name" : given_name, "family-name" : family_name};
+ }
+ }
+ }
+ },
+ "nickname" : {
+ plural: true,
+ virtual: true,
+ /* Implied "nickname" Optimization */
+ /* http://microformats.org/wiki/hcard#Implied_.22nickname.22_Optimization */
+ virtualGetter: function(mfnode) {
+ var fn = Microformats.parser.getMicroformatProperty(mfnode, "hCard", "fn");
+ var orgs = Microformats.parser.getMicroformatProperty(mfnode, "hCard", "org");
+ var given_name;
+ var family_name;
+ if (fn && (!orgs || (orgs.length) > 1 || (fn != orgs[0]["organization-name"]))) {
+ var fns = fn.split(" ");
+ if (fns.length === 1) {
+ return [fns[0]];
+ }
+ }
+ return;
+ }
+ },
+ "note" : {
+ plural: true,
+ datatype: "HTML"
+ },
+ "org" : {
+ subproperties: {
+ "organization-name" : {
+ virtual: true
+ },
+ "organization-unit" : {
+ plural: true
+ }
+ },
+ plural: true
+ },
+ "photo" : {
+ plural: true,
+ datatype: "anyURI"
+ },
+ "rev" : {
+ datatype: "dateTime"
+ },
+ "role" : {
+ plural: true
+ },
+ "sequence" : {
+ },
+ "sort-string" : {
+ },
+ "sound" : {
+ plural: true
+ },
+ "title" : {
+ plural: true
+ },
+ "tel" : {
+ subproperties: {
+ "type" : {
+ plural: true,
+ values: ["msg", "home", "work", "pref", "voice", "fax", "cell", "video", "pager", "bbs", "car", "isdn", "pcs"]
+ },
+ "value" : {
+ datatype: "tel",
+ virtual: true
+ }
+ },
+ plural: true
+ },
+ "tz" : {
+ },
+ "uid" : {
+ datatype: "anyURI"
+ },
+ "url" : {
+ plural: true,
+ datatype: "anyURI"
+ }
+ }
+};
+
+Microformats.add("hCard", hCard_definition);
+
+function hCalendar(node, validate) {
+ if (node) {
+ Microformats.parser.newMicroformat(this, node, "hCalendar", validate);
+ }
+}
+hCalendar.prototype.toString = function() {
+ if (this.resolvedNode) {
+ /* If this microformat has an include pattern, put the */
+ /* dtstart in parenthesis after the summary to differentiate */
+ /* them. */
+ var summaries = Microformats.getElementsByClassName(this.node, "summary");
+ if (summaries.length === 0) {
+ if (this.summary) {
+ if (this.dtstart) {
+ return this.summary + " (" + Microformats.dateFromISO8601(this.dtstart).toLocaleString() + ")";
+ }
+ }
+ }
+ }
+ if (this.dtstart) {
+ return this.summary;
+ }
+ return;
+}
+
+var hCalendar_definition = {
+ mfObject: hCalendar,
+ className: "vevent",
+ required: ["summary", "dtstart"],
+ properties: {
+ "category" : {
+ plural: true,
+ datatype: "microformat",
+ microformat: "tag",
+ microformat_property: "tag"
+ },
+ "class" : {
+ values: ["public", "private", "confidential"]
+ },
+ "description" : {
+ datatype: "HTML"
+ },
+ "dtstart" : {
+ datatype: "dateTime"
+ },
+ "dtend" : {
+ datatype: "dateTime"
+ },
+ "dtstamp" : {
+ datatype: "dateTime"
+ },
+ "duration" : {
+ },
+ "geo" : {
+ datatype: "microformat",
+ microformat: "geo"
+ },
+ "location" : {
+ datatype: "microformat",
+ microformat: "hCard"
+ },
+ "status" : {
+ values: ["tentative", "confirmed", "cancelled"]
+ },
+ "summary" : {},
+ "transp" : {
+ values: ["opaque", "transparent"]
+ },
+ "uid" : {
+ datatype: "anyURI"
+ },
+ "url" : {
+ datatype: "anyURI"
+ },
+ "last-modified" : {
+ datatype: "dateTime"
+ },
+ "rrule" : {
+ subproperties: {
+ "interval" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "interval");
+ }
+ },
+ "freq" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "freq");
+ }
+ },
+ "bysecond" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "bysecond");
+ }
+ },
+ "byminute" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "byminute");
+ }
+ },
+ "byhour" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "byhour");
+ }
+ },
+ "bymonthday" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "bymonthday");
+ }
+ },
+ "byyearday" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "byyearday");
+ }
+ },
+ "byweekno" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "byweekno");
+ }
+ },
+ "bymonth" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "bymonth");
+ }
+ },
+ "byday" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "byday");
+ }
+ },
+ "until" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "until");
+ }
+ },
+ "count" : {
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ return Microformats.hCalendar.properties.rrule.retrieve(mfnode, "count");
+ }
+ }
+ },
+ retrieve: function(mfnode, property) {
+ var value = Microformats.parser.textGetter(mfnode);
+ var rrule;
+ rrule = value.split(';');
+ for (let i=0; i < rrule.length; i++) {
+ if (rrule[i].match(property)) {
+ return rrule[i].split('=')[1];
+ }
+ }
+ }
+ }
+ }
+};
+
+Microformats.add("hCalendar", hCalendar_definition);
+
+function geo(node, validate) {
+ if (node) {
+ Microformats.parser.newMicroformat(this, node, "geo", validate);
+ }
+}
+geo.prototype.toString = function() {
+ if (this.latitude != undefined) {
+ if (!isFinite(this.latitude) || (this.latitude > 360) || (this.latitude < -360)) {
+ return;
+ }
+ }
+ if (this.longitude != undefined) {
+ if (!isFinite(this.longitude) || (this.longitude > 360) || (this.longitude < -360)) {
+ return;
+ }
+ }
+
+ if ((this.latitude != undefined) && (this.longitude != undefined)) {
+ var s;
+ if ((this.node.localName.toLowerCase() == "abbr") || (this.node.localName.toLowerCase() == "html:abbr")) {
+ s = this.node.textContent;
+ }
+
+ if (s) {
+ return s;
+ }
+
+ /* check if geo is contained in a vcard */
+ var xpathExpression = "ancestor::*[contains(concat(' ', @class, ' '), ' vcard ')]";
+ var xpathResult = this.node.ownerDocument.evaluate(xpathExpression, this.node, null, Components.interfaces.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE, null);
+ if (xpathResult.singleNodeValue) {
+ var hcard = new hCard(xpathResult.singleNodeValue);
+ if (hcard.fn) {
+ return hcard.fn;
+ }
+ }
+ /* check if geo is contained in a vevent */
+ xpathExpression = "ancestor::*[contains(concat(' ', @class, ' '), ' vevent ')]";
+ xpathResult = this.node.ownerDocument.evaluate(xpathExpression, this.node, null, Components.interfaces.nsIDOMXPathResult.FIRST_ORDERED_NODE_TYPE, xpathResult);
+ if (xpathResult.singleNodeValue) {
+ var hcal = new hCalendar(xpathResult.singleNodeValue);
+ if (hcal.summary) {
+ return hcal.summary;
+ }
+ }
+ if (s) {
+ return s;
+ } else {
+ return this.latitude + ", " + this.longitude;
+ }
+ }
+}
+
+var geo_definition = {
+ mfObject: geo,
+ className: "geo",
+ required: ["latitude","longitude"],
+ properties: {
+ "latitude" : {
+ datatype: "float",
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ var value = Microformats.parser.textGetter(mfnode);
+ var latlong;
+ if (value.match(';')) {
+ latlong = value.split(';');
+ if (latlong[0]) {
+ if (!isNaN(latlong[0])) {
+ return parseFloat(latlong[0]);
+ }
+ }
+ }
+ }
+ },
+ "longitude" : {
+ datatype: "float",
+ virtual: true,
+ /* This will only be called in the virtual case */
+ virtualGetter: function(mfnode) {
+ var value = Microformats.parser.textGetter(mfnode);
+ var latlong;
+ if (value.match(';')) {
+ latlong = value.split(';');
+ if (latlong[1]) {
+ if (!isNaN(latlong[1])) {
+ return parseFloat(latlong[1]);
+ }
+ }
+ }
+ }
+ }
+ },
+ validate: function(node) {
+ var latitude = Microformats.parser.getMicroformatProperty(node, "geo", "latitude");
+ var longitude = Microformats.parser.getMicroformatProperty(node, "geo", "longitude");
+ if (latitude != undefined) {
+ if (!isFinite(latitude) || (latitude > 360) || (latitude < -360)) {
+ throw("Invalid latitude");
+ }
+ } else {
+ throw("No latitude specified");
+ }
+ if (longitude != undefined) {
+ if (!isFinite(longitude) || (longitude > 360) || (longitude < -360)) {
+ throw("Invalid longitude");
+ }
+ } else {
+ throw("No longitude specified");
+ }
+ return true;
+ }
+};
+
+Microformats.add("geo", geo_definition);
+
+function tag(node, validate) {
+ if (node) {
+ Microformats.parser.newMicroformat(this, node, "tag", validate);
+ }
+}
+tag.prototype.toString = function() {
+ return this.tag;
+}
+
+var tag_definition = {
+ mfObject: tag,
+ attributeName: "rel",
+ attributeValues: "tag",
+ properties: {
+ "tag" : {
+ virtual: true,
+ virtualGetter: function(mfnode) {
+ if (mfnode.href) {
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"].
+ getService(Components.interfaces.nsIIOService);
+ var uri = ioService.newURI(mfnode.href, null, null);
+ var url_array = uri.path.split("/");
+ for(let i=url_array.length-1; i > 0; i--) {
+ if (url_array[i] !== "") {
+ var tag
+ if (tag = Microformats.tag.validTagName(url_array[i].replace(/\+/g, ' '))) {
+ try {
+ return decodeURIComponent(tag);
+ } catch (ex) {
+ return unescape(tag);
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+ },
+ "link" : {
+ virtual: true,
+ datatype: "anyURI"
+ },
+ "text" : {
+ virtual: true
+ }
+ },
+ validTagName: function(tag)
+ {
+ var returnTag = tag;
+ if (tag.indexOf('?') != -1) {
+ if (tag.indexOf('?') === 0) {
+ return false;
+ } else {
+ returnTag = tag.substr(0, tag.indexOf('?'));
+ }
+ }
+ if (tag.indexOf('#') != -1) {
+ if (tag.indexOf('#') === 0) {
+ return false;
+ } else {
+ returnTag = tag.substr(0, tag.indexOf('#'));
+ }
+ }
+ if (tag.indexOf('.html') != -1) {
+ if (tag.indexOf('.html') == tag.length - 5) {
+ return false;
+ }
+ }
+ return returnTag;
+ },
+ validate: function(node) {
+ var tag = Microformats.parser.getMicroformatProperty(node, "tag", "tag");
+ if (!tag) {
+ if (node.href) {
+ var url_array = node.getAttribute("href").split("/");
+ for(let i=url_array.length-1; i > 0; i--) {
+ if (url_array[i] !== "") {
+ throw("Invalid tag name (" + url_array[i] + ")");
+ }
+ }
+ } else {
+ throw("No href specified on tag");
+ }
+ }
+ return true;
+ }
+};
+
+Microformats.add("tag", tag_definition);
diff --git a/bundles/XO/modules/PlacesDBUtils.jsm b/bundles/XO/modules/PlacesDBUtils.jsm
new file mode 100755
index 0000000..b60e597
--- /dev/null
+++ b/bundles/XO/modules/PlacesDBUtils.jsm
@@ -0,0 +1,589 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=2 sts=2 expandtab filetype=javascript
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Places Database Utils code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Marco Bonardo <mak77@bonardo.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+let EXPORTED_SYMBOLS = [ "PlacesDBUtils" ];
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+const IS_CONTRACTID = "@mozilla.org/widget/idleservice;1";
+const OS_CONTRACTID = "@mozilla.org/observer-service;1";
+const HS_CONTRACTID = "@mozilla.org/browser/nav-history-service;1";
+const BS_CONTRACTID = "@mozilla.org/browser/nav-bookmarks-service;1";
+const TS_CONTRACTID = "@mozilla.org/timer;1";
+const SB_CONTRACTID = "@mozilla.org/intl/stringbundle;1";
+const TIM_CONTRACTID = "@mozilla.org/updates/timer-manager;1";
+
+const PLACES_STRING_BUNDLE_URI = "chrome://places/locale/places.properties";
+
+const FINISHED_MAINTENANCE_NOTIFICATION_TOPIC = "places-maintenance-finished";
+
+// Do maintenance after 10 minutes of idle.
+// We choose a small idle time because we must not prevent laptops from going
+// to standby, also we don't want to hit cpu/disk while the user is doing other
+// activities on the computer, like watching a movie.
+// So, we suppose that after 10 idle minutes the user is moving to another task
+// and we can hit without big troubles.
+const IDLE_TIMEOUT = 10 * 60 * 1000;
+
+// Check for idle every 10 minutes and do maintenance if the user has been idle
+// for more than IDLE_TIMEOUT.
+const IDLE_LOOKUP_REPEAT = 10 * 60 * 1000;
+
+// These are the seconds between each maintenance (24h).
+const MAINTENANCE_REPEAT = 24 * 60 * 60;
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsPlacesDBUtils class
+
+function nsPlacesDBUtils() {
+ //////////////////////////////////////////////////////////////////////////////
+ //// Smart getters
+
+ this.__defineGetter__("_bms", function() {
+ delete this._bms;
+ return this._bms = Cc[BS_CONTRACTID].getService(Ci.nsINavBookmarksService);
+ });
+
+ this.__defineGetter__("_hs", function() {
+ delete this._hs;
+ return this._hs = Cc[HS_CONTRACTID].getService(Ci.nsINavHistoryService);
+ });
+
+ this.__defineGetter__("_os", function() {
+ delete this._os;
+ return this._os = Cc[OS_CONTRACTID].getService(Ci.nsIObserverService);
+ });
+
+ this.__defineGetter__("_idlesvc", function() {
+ delete this._idlesvc;
+ return this._idlesvc = Cc[IS_CONTRACTID].getService(Ci.nsIIdleService);
+ });
+
+ this.__defineGetter__("_dbConn", function() {
+ delete this._dbConn;
+ return this._dbConn = Cc[HS_CONTRACTID].
+ getService(Ci.nsPIPlacesDatabase).DBConnection;
+ });
+
+ this.__defineGetter__("_bundle", function() {
+ delete this._bundle;
+ return this._bundle = Cc[SB_CONTRACTID].
+ getService(Ci.nsIStringBundleService).
+ createBundle(PLACES_STRING_BUNDLE_URI);
+ });
+
+ // register the maintenance timer
+ try {
+ let tim = Cc[TIM_CONTRACTID].getService(Ci.nsIUpdateTimerManager);
+ tim.registerTimer("places-maintenance-timer", this, MAINTENANCE_REPEAT);
+ } catch (ex) {
+ // The timer manager is not available in xpc shell tests
+ }
+}
+
+nsPlacesDBUtils.prototype = {
+ _idleLookupTimer: null,
+ _statementsRunningCount: 0,
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsISupports
+
+ QueryInterface: XPCOMUtils.generateQI([
+ Ci.nsITimerCallback,
+ Ci.nsIObserver,
+ ]),
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsITimerCallback
+
+ notify: function PDBU_notify(aTimer) {
+ switch (aTimer) {
+ case this._idleLookUpTimer:
+ let idleTime = 0;
+ try {
+ idleTime = this._idlesvc.idleTime;
+ } catch (ex) {}
+
+ // do maintenance on idle
+ if (idleTime > IDLE_TIMEOUT) {
+ // Stop the timer, we do maintenance once per day
+ this._idleLookUpTimer.cancel();
+ this._idleLookUpTimer = null;
+
+ // start the cleanup
+ this.maintenanceOnIdle();
+ }
+ break;
+ default:
+ // Start the idle lookup timer
+ this._idleLookUpTimer = Cc[TS_CONTRACTID].createInstance(Ci.nsITimer);
+ this._idleLookUpTimer.initWithCallback(this, IDLE_LOOKUP_REPEAT,
+ Ci.nsITimer.TYPE_REPEATING_SLACK);
+ break;
+ }
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// mozIStorageStatementCallback
+
+ handleError: function PDBU_handleError(aError) {
+ Cu.reportError("Async statement execution returned with '" +
+ aError.result + "', '" + aError.message + "'");
+ },
+
+ handleCompletion: function PDBU_handleCompletion(aReason) {
+ // We serve only the last statement completion
+ if (--this._statementsRunningCount > 0)
+ return;
+
+ // We finished executing all statements.
+ // Sending Begin/EndUpdateBatch notification will ensure that the UI
+ // is correctly refreshed.
+ this._hs.runInBatchMode({runBatched: function(aUserData){}}, null);
+ this._bms.runInBatchMode({runBatched: function(aUserData){}}, null);
+ // Notify observers that maintenance tasks are complete
+ this._os.notifyObservers(null, FINISHED_MAINTENANCE_NOTIFICATION_TOPIC, null);
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// Tasks
+
+ maintenanceOnIdle: function PDBU_maintenanceOnIdle() {
+ // bug 431558: preventive maintenance for Places database
+ let cleanupStatements = [];
+
+ // MOZ_ANNO_ATTRIBUTES
+ // A.1 remove unused attributes
+ let deleteUnusedAnnoAttributes = this._dbConn.createStatement(
+ "DELETE FROM moz_anno_attributes WHERE id IN ( " +
+ "SELECT id FROM moz_anno_attributes n " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_annos WHERE anno_attribute_id = n.id LIMIT 1) " +
+ "AND NOT EXISTS " +
+ "(SELECT id FROM moz_items_annos WHERE anno_attribute_id = n.id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteUnusedAnnoAttributes);
+
+ // MOZ_ANNOS
+ // B.1 remove annos with an invalid attribute
+ let deleteInvalidAttributeAnnos = this._dbConn.createStatement(
+ "DELETE FROM moz_annos WHERE id IN ( " +
+ "SELECT id FROM moz_annos a " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_anno_attributes " +
+ "WHERE id = a.anno_attribute_id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteInvalidAttributeAnnos);
+
+ // B.2 remove orphan annos
+ let deleteOrphanAnnos = this._dbConn.createStatement(
+ "DELETE FROM moz_annos WHERE id IN ( " +
+ "SELECT id FROM moz_annos a " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_places_temp WHERE id = a.place_id LIMIT 1) " +
+ "AND NOT EXISTS " +
+ "(SELECT id FROM moz_places WHERE id = a.place_id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteOrphanAnnos);
+
+ // MOZ_BOOKMARKS_ROOTS
+ // C.1 fix missing Places root
+ // Bug 477739 shows a case where the root could be wrongly removed
+ // due to an endianness issue. We try to fix broken roots here.
+ let selectPlacesRoot = this._dbConn.createStatement(
+ "SELECT id FROM moz_bookmarks WHERE id = :places_root");
+ selectPlacesRoot.params["places_root"] = this._bms.placesRoot;
+ if (!selectPlacesRoot.executeStep()) {
+ // We are missing the root, try to recreate it.
+ let createPlacesRoot = this._dbConn.createStatement(
+ "INSERT INTO moz_bookmarks (id, type, fk, parent, position, title) " +
+ "VALUES (:places_root, 2, NULL, 0, 0, :title)");
+ createPlacesRoot.params["places_root"] = this._bms.placesRoot;
+ createPlacesRoot.params["title"] = "";
+ cleanupStatements.push(createPlacesRoot);
+
+ // Now ensure that other roots are children of Places root.
+ let fixPlacesRootChildren = this._dbConn.createStatement(
+ "UPDATE moz_bookmarks SET parent = :places_root WHERE id IN " +
+ "(SELECT folder_id FROM moz_bookmarks_roots " +
+ "WHERE folder_id <> :places_root)");
+ fixPlacesRootChildren.params["places_root"] = this._bms.placesRoot;
+ cleanupStatements.push(fixPlacesRootChildren);
+ }
+ selectPlacesRoot.finalize();
+
+ // C.2 fix roots titles
+ // some alpha version has wrong roots title, and this also fixes them if
+ // locale has changed.
+ let updateRootTitleSql = "UPDATE moz_bookmarks SET title = :title " +
+ "WHERE id = :root_id AND title <> :title";
+ // root
+ let fixPlacesRootTitle = this._dbConn.createStatement(updateRootTitleSql);
+ fixPlacesRootTitle.params["root_id"] = this._bms.placesRoot;
+ fixPlacesRootTitle.params["title"] = "";
+ cleanupStatements.push(fixPlacesRootTitle);
+ // bookmarks menu
+ let fixBookmarksMenuTitle = this._dbConn.createStatement(updateRootTitleSql);
+ fixBookmarksMenuTitle.params["root_id"] = this._bms.bookmarksMenuFolder;
+ fixBookmarksMenuTitle.params["title"] =
+ this._bundle.GetStringFromName("BookmarksMenuFolderTitle");
+ cleanupStatements.push(fixBookmarksMenuTitle);
+ // bookmarks toolbar
+ let fixBookmarksToolbarTitle = this._dbConn.createStatement(updateRootTitleSql);
+ fixBookmarksToolbarTitle.params["root_id"] = this._bms.toolbarFolder;
+ fixBookmarksToolbarTitle.params["title"] =
+ this._bundle.GetStringFromName("BookmarksToolbarFolderTitle");
+ cleanupStatements.push(fixBookmarksToolbarTitle);
+ // unsorted bookmarks
+ let fixUnsortedBookmarksTitle = this._dbConn.createStatement(updateRootTitleSql);
+ fixUnsortedBookmarksTitle.params["root_id"] = this._bms.unfiledBookmarksFolder;
+ fixUnsortedBookmarksTitle.params["title"] =
+ this._bundle.GetStringFromName("UnsortedBookmarksFolderTitle");
+ cleanupStatements.push(fixUnsortedBookmarksTitle);
+ // tags
+ let fixTagsRootTitle = this._dbConn.createStatement(updateRootTitleSql);
+ fixTagsRootTitle.params["root_id"] = this._bms.tagsFolder;
+ fixTagsRootTitle.params["title"] =
+ this._bundle.GetStringFromName("TagsFolderTitle");
+ cleanupStatements.push(fixTagsRootTitle);
+
+ // MOZ_BOOKMARKS
+ // D.1 remove items without a valid place
+ // if fk IS NULL we fix them in D.7
+ let deleteNoPlaceItems = this._dbConn.createStatement(
+ "DELETE FROM moz_bookmarks WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN (" +
+ "SELECT b.id FROM moz_bookmarks b " +
+ "WHERE fk NOT NULL AND b.type = :bookmark_type " +
+ "AND NOT EXISTS (SELECT url FROM moz_places_temp WHERE id = b.fk LIMIT 1) " +
+ "AND NOT EXISTS (SELECT url FROM moz_places WHERE id = b.fk LIMIT 1) " +
+ ")");
+ deleteNoPlaceItems.params["bookmark_type"] = this._bms.TYPE_BOOKMARK;
+ cleanupStatements.push(deleteNoPlaceItems);
+
+ // D.2 remove items that are not uri bookmarks from tag containers
+ let deleteBogusTagChildren = this._dbConn.createStatement(
+ "DELETE FROM moz_bookmarks WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN (" +
+ "SELECT b.id FROM moz_bookmarks b " +
+ "WHERE b.parent IN " +
+ "(SELECT id FROM moz_bookmarks WHERE parent = :tags_folder) " +
+ "AND b.type <> :bookmark_type " +
+ ")");
+ deleteBogusTagChildren.params["tags_folder"] = this._bms.tagsFolder;
+ deleteBogusTagChildren.params["bookmark_type"] = this._bms.TYPE_BOOKMARK;
+ cleanupStatements.push(deleteBogusTagChildren);
+
+ // D.3 remove empty tags
+ let deleteEmptyTags = this._dbConn.createStatement(
+ "DELETE FROM moz_bookmarks WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN (" +
+ "SELECT b.id FROM moz_bookmarks b " +
+ "WHERE b.id IN " +
+ "(SELECT id FROM moz_bookmarks WHERE parent = :tags_folder) " +
+ "AND NOT EXISTS " +
+ "(SELECT id from moz_bookmarks WHERE parent = b.id LIMIT 1) " +
+ ")");
+ deleteEmptyTags.params["tags_folder"] = this._bms.tagsFolder;
+ cleanupStatements.push(deleteEmptyTags);
+
+ // D.4 move orphan items to unsorted folder
+ let fixOrphanItems = this._dbConn.createStatement(
+ "UPDATE moz_bookmarks SET parent = :unsorted_folder WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN (" +
+ "SELECT b.id FROM moz_bookmarks b " +
+ "WHERE b.parent <> 0 " + // exclude Places root
+ "AND NOT EXISTS " +
+ "(SELECT id FROM moz_bookmarks WHERE id = b.parent LIMIT 1) " +
+ ")");
+ fixOrphanItems.params["unsorted_folder"] = this._bms.unfiledBookmarksFolder;
+ cleanupStatements.push(fixOrphanItems);
+
+ // D.5 fix wrong keywords
+ let fixInvalidKeywords = this._dbConn.createStatement(
+ "UPDATE moz_bookmarks SET keyword_id = NULL WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN ( " +
+ "SELECT id FROM moz_bookmarks b " +
+ "WHERE keyword_id NOT NULL " +
+ "AND NOT EXISTS " +
+ "(SELECT id FROM moz_keywords WHERE id = b.keyword_id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(fixInvalidKeywords);
+
+ // D.6 fix wrong item types
+ // Folders, separators and dynamic containers should not have an fk.
+ // If they have a valid fk convert them to bookmarks. Later in D.9 we
+ // will move eventual children to unsorted bookmarks.
+ let fixBookmarksAsFolders = this._dbConn.createStatement(
+ "UPDATE moz_bookmarks SET type = :bookmark_type WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN ( " +
+ "SELECT id FROM moz_bookmarks b " +
+ "WHERE type IN (:folder_type, :separator_type, :dynamic_type) " +
+ "AND fk NOTNULL " +
+ ")");
+ fixBookmarksAsFolders.params["bookmark_type"] = this._bms.TYPE_BOOKMARK;
+ fixBookmarksAsFolders.params["folder_type"] = this._bms.TYPE_FOLDER;
+ fixBookmarksAsFolders.params["separator_type"] = this._bms.TYPE_SEPARATOR;
+ fixBookmarksAsFolders.params["dynamic_type"] = this._bms.TYPE_DYNAMIC_CONTAINER;
+ cleanupStatements.push(fixBookmarksAsFolders);
+
+ // D.7 fix wrong item types
+ // Bookmarks should have an fk, if they don't have any, convert them to
+ // folders.
+ let fixFoldersAsBookmarks = this._dbConn.createStatement(
+ "UPDATE moz_bookmarks SET type = :folder_type WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN ( " +
+ "SELECT id FROM moz_bookmarks b " +
+ "WHERE type = :bookmark_type " +
+ "AND fk IS NULL " +
+ ")");
+ fixFoldersAsBookmarks.params["bookmark_type"] = this._bms.TYPE_BOOKMARK;
+ fixFoldersAsBookmarks.params["folder_type"] = this._bms.TYPE_FOLDER;
+ cleanupStatements.push(fixFoldersAsBookmarks);
+
+ // D.8 fix wrong item types
+ // Dynamic containers should have a folder_type, if they don't have any
+ // convert them to folders.
+ let fixFoldersAsDynamic = this._dbConn.createStatement(
+ "UPDATE moz_bookmarks SET type = :folder_type WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN ( " +
+ "SELECT id FROM moz_bookmarks b " +
+ "WHERE type = :dynamic_type " +
+ "AND folder_type IS NULL " +
+ ")");
+ fixFoldersAsDynamic.params["dynamic_type"] = this._bms.TYPE_DYNAMIC_CONTAINER;
+ fixFoldersAsDynamic.params["folder_type"] = this._bms.TYPE_FOLDER;
+ cleanupStatements.push(fixFoldersAsDynamic);
+
+ // D.9 fix wrong parents
+ // Items cannot have dynamic containers, separators or other bookmarks
+ // as parent, if they have bad parent move them to unsorted bookmarks.
+ let fixInvalidParents = this._dbConn.createStatement(
+ "UPDATE moz_bookmarks SET parent = :unsorted_folder WHERE id NOT IN ( " +
+ "SELECT folder_id FROM moz_bookmarks_roots " + // skip roots
+ ") AND id IN ( " +
+ "SELECT id FROM moz_bookmarks b " +
+ "WHERE EXISTS " +
+ "(SELECT id FROM moz_bookmarks WHERE id = b.parent " +
+ "AND type IN (:bookmark_type, :separator_type, :dynamic_type) " +
+ "LIMIT 1) " +
+ ")");
+ fixInvalidParents.params["unsorted_folder"] = this._bms.unfiledBookmarksFolder;
+ fixInvalidParents.params["bookmark_type"] = this._bms.TYPE_BOOKMARK;
+ fixInvalidParents.params["separator_type"] = this._bms.TYPE_SEPARATOR;
+ fixInvalidParents.params["dynamic_type"] = this._bms.TYPE_DYNAMIC_CONTAINER;
+ cleanupStatements.push(fixInvalidParents);
+
+/* XXX needs test
+ // D.10 recalculate positions
+ // This requires multiple related statements.
+ // We can detect a folder with bad position values comparing the sum of
+ // all position values with the triangular numbers obtained by the number
+ // of children: (n * (n + 1) / 2). Starting from 0 is (n * (n - 1) / 2).
+ let detectWrongPositionsParents = this._dbConn.createStatement(
+ "SELECT parent FROM " +
+ "(SELECT parent, " +
+ "(SUM(position) - (count(*) * (count(*) - 1) / 2)) AS diff " +
+ "FROM moz_bookmarks " +
+ "GROUP BY parent) " +
+ "WHERE diff <> 0");
+ while (detectWrongPositionsParents.executeStep()) {
+ let parent = detectWrongPositionsParents.getInt64(0);
+ // We will lose the previous position values and reposition items based
+ // on the ROWID value. Not perfect, but we can't rely on position values.
+ let fixPositionsForParent = this._dbConn.createStatement(
+ "UPDATE moz_bookmarks SET position = ( " +
+ "SELECT " +
+ "((SELECT count(*) FROM moz_bookmarks WHERE parent = :parent) - " +
+ "(SELECT count(*) FROM moz_bookmarks " +
+ "WHERE parent = :parent AND ROWID >= b.ROWID)) " +
+ "FROM moz_bookmarks b WHERE parent = :parent AND id = moz_bookmarks.id " +
+ ") WHERE parent = :parent");
+ fixPositionsForParent.params["parent"] = parent;
+ cleanupStatements.push(fixPositionsForParent);
+ }
+*/
+
+ // D.11 remove old livemarks status items
+ // Livemark status items are now static but some livemark has still old
+ // status items bookmarks inside it. We should remove them.
+ // Note: This does not need to query the temp table.
+ let removeLivemarkStaticItems = this._dbConn.createStatement(
+ "DELETE FROM moz_bookmarks WHERE type = :bookmark_type AND fk IN ( " +
+ "SELECT id FROM moz_places WHERE url = :lmloading OR url = :lmfailed " +
+ ")");
+ removeLivemarkStaticItems.params["bookmark_type"] = this._bms.TYPE_BOOKMARK;
+ removeLivemarkStaticItems.params["lmloading"] = "about:livemark-loading";
+ removeLivemarkStaticItems.params["lmfailed"] = "about:livemark-failed";
+ cleanupStatements.push(removeLivemarkStaticItems);
+
+ // MOZ_FAVICONS
+ // E.1 remove orphan icons
+ let deleteOrphanIcons = this._dbConn.createStatement(
+ "DELETE FROM moz_favicons WHERE id IN (" +
+ "SELECT id FROM moz_favicons f " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_places_temp WHERE favicon_id = f.id LIMIT 1) " +
+ "AND NOT EXISTS" +
+ "(SELECT id FROM moz_places WHERE favicon_id = f.id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteOrphanIcons);
+
+ // MOZ_HISTORYVISITS
+ // F.1 remove orphan visits
+ let deleteOrphanVisits = this._dbConn.createStatement(
+ "DELETE FROM moz_historyvisits WHERE id IN (" +
+ "SELECT id FROM moz_historyvisits v " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_places_temp WHERE id = v.place_id LIMIT 1) " +
+ "AND NOT EXISTS " +
+ "(SELECT id FROM moz_places WHERE id = v.place_id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteOrphanVisits);
+
+ // MOZ_INPUTHISTORY
+ // G.1 remove orphan input history
+ let deleteOrphanInputHistory = this._dbConn.createStatement(
+ "DELETE FROM moz_inputhistory WHERE place_id IN (" +
+ "SELECT place_id FROM moz_inputhistory i " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_places_temp WHERE id = i.place_id LIMIT 1) " +
+ "AND NOT EXISTS " +
+ "(SELECT id FROM moz_places WHERE id = i.place_id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteOrphanInputHistory);
+
+ // MOZ_ITEMS_ANNOS
+ // H.1 remove item annos with an invalid attribute
+ let deleteInvalidAttributeItemsAnnos = this._dbConn.createStatement(
+ "DELETE FROM moz_items_annos WHERE id IN ( " +
+ "SELECT id FROM moz_items_annos t " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_anno_attributes " +
+ "WHERE id = t.anno_attribute_id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteInvalidAttributeItemsAnnos);
+
+ // H.2 remove orphan item annos
+ let deleteOrphanItemsAnnos = this._dbConn.createStatement(
+ "DELETE FROM moz_items_annos WHERE id IN ( " +
+ "SELECT id FROM moz_items_annos t " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_bookmarks WHERE id = t.item_id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteOrphanItemsAnnos);
+
+ // MOZ_KEYWORDS
+ // I.1 remove unused keywords
+ let deleteUnusedKeywords = this._dbConn.createStatement(
+ "DELETE FROM moz_keywords WHERE id IN ( " +
+ "SELECT id FROM moz_keywords k " +
+ "WHERE NOT EXISTS " +
+ "(SELECT id FROM moz_bookmarks WHERE keyword_id = k.id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(deleteUnusedKeywords);
+
+ // MOZ_PLACES
+ // L.1 fix wrong favicon ids
+ let fixInvalidFaviconIds = this._dbConn.createStatement(
+ "UPDATE moz_places SET favicon_id = NULL WHERE id IN ( " +
+ "SELECT id FROM moz_places h " +
+ "WHERE favicon_id NOT NULL " +
+ "AND NOT EXISTS " +
+ "(SELECT id FROM moz_favicons WHERE id = h.favicon_id LIMIT 1) " +
+ ")");
+ cleanupStatements.push(fixInvalidFaviconIds);
+
+/* XXX needs test
+ // L.2 recalculate visit_count
+ // We're detecting errors only in disk table since temp tables could have
+ // different values based on the number of visits not yet synced to disk.
+ let detectWrongCountPlaces = this._dbConn.createStatement(
+ "SELECT id FROM moz_places h " +
+ "WHERE id NOT IN (SELECT id FROM moz_places_temp) " +
+ "AND h.visit_count <> " +
+ "(SELECT count(*) FROM moz_historyvisits " +
+ "WHERE place_id = h.id AND visit_type NOT IN (0,4,7))");
+ while (detectWrongCountPlaces.executeStep()) {
+ let placeId = detectWrongCountPlaces.getInt64(0);
+
+ let fixCountForPlace = this._dbConn.createStatement(
+ "UPDATE moz_places_view SET visit_count = ( " +
+ "(SELECT count(*) FROM moz_historyvisits " +
+ "WHERE place_id = :place_id AND visit_type NOT IN (0,4,7)) + " +
+ "(SELECT count(*) FROM moz_historyvisits_temp " +
+ "WHERE place_id = :place_id AND visit_type NOT IN (0,4,7)) + " +
+ ") WHERE id = :place_id");
+ fixCountForPlace.params["place_id"] = placeId;
+ cleanupStatements.push(fixCountForPlace);
+ }
+*/
+
+ // MAINTENANCE STATEMENTS SHOULD GO ABOVE THIS POINT!
+
+ // Used to keep track of last call to handleCompletion
+ this._statementsRunningCount = cleanupStatements.length;
+ // Statements are automatically queued-up by mozStorage
+ cleanupStatements.forEach(function (aStatement) {
+ aStatement.executeAsync(this);
+ aStatement.finalize();
+ }, this);
+ },
+};
+
+__defineGetter__("PlacesDBUtils", function() {
+ delete this.PlacesDBUtils;
+ return this.PlacesDBUtils = new nsPlacesDBUtils;
+});
diff --git a/bundles/XO/modules/PluralForm.jsm b/bundles/XO/modules/PluralForm.jsm
new file mode 100755
index 0000000..63b058d
--- /dev/null
+++ b/bundles/XO/modules/PluralForm.jsm
@@ -0,0 +1,207 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Plural Form l10n Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Edward Lee <edward.lee@engineering.uiuc.edu>.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var EXPORTED_SYMBOLS = [ "PluralForm" ];
+
+/**
+ * This module provides the PluralForm object which contains a method to figure
+ * out which plural form of a word to use for a given number based on the
+ * current localization. There is also a makeGetter method that creates a get
+ * function for the desired plural rule. This is useful for extensions that
+ * specify their own plural rule instead of relying on the browser default.
+ * (I.e., the extension hasn't been localized to the browser's locale.)
+ *
+ * See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+ *
+ * List of methods:
+ *
+ * string pluralForm
+ * get(int aNum, string aWords)
+ *
+ * int numForms
+ * numForms()
+ *
+ * [string pluralForm get(int aNum, string aWords), int numForms numForms()]
+ * makeGetter(int aRuleNum)
+ * Note: Basically, makeGetter returns 2 functions that do "get" and "numForm"
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const kIntlProperties = "chrome://global/locale/intl.properties";
+
+// These are the available plural functions that give the appropriate index
+// based on the plural rule number specified. The first element is the number
+// of plural forms and the second is the function to figure out the index.
+let gFunctions = [
+ // 0: Chinese
+ [1, function(n) 0],
+ // 1: English
+ [2, function(n) n!=1?1:0],
+ // 2: French
+ [2, function(n) n>1?1:0],
+ // 3: Latvian
+ [3, function(n) n%10==1&&n%100!=11?1:n!=0?2:0],
+ // 4: Scottish Gaelic
+ [3, function(n) n==1?0:n==2?1:2],
+ // 5: Romanian
+ [3, function(n) n==1?0:n==0||n%100>0&&n%100<20?1:2],
+ // 6: Lithuanian
+ [3, function(n) n%10==1&&n%100!=11?0:n%10>=2&&(n%100<10||n%100>=20)?2:1],
+ // 7: Russian
+ [3, function(n) n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2],
+ // 8: Slovak
+ [3, function(n) n==1?0:n>=2&&n<=4?1:2],
+ // 9: Polish
+ [3, function(n) n==1?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2],
+ // 10: Slovenian
+ [4, function(n) n%100==1?0:n%100==2?1:n%100==3||n%100==4?2:3],
+ // 11: Irish Gaeilge
+ [5, function(n) n==1?0:n==2?1:n>=3&&n<=6?2:n>=7&&n<=10?3:4],
+ // 12: Arabic
+ [6, function(n) n==0?5:n==1?0:n==2?1:n%100>=3&&n%100<=10?2:n%100>=11&&n%100<=99?3:4],
+ // 13: Maltese
+ [4, function(n) n==1?0:n==0||n%100>0&&n%100<=10?1:n%100>10&&n%100<20?2:3],
+ // 14: Macedonian
+ [3, function(n) n%10==1?0:n%10==2?1:2],
+ // 15: Icelandic
+ [2, function(n) n%10==1&&n%100!=11?0:1],
+];
+
+let PluralForm = {
+ /**
+ * Get the correct plural form of a word based on the number
+ *
+ * @param aNum
+ * The number to decide which plural form to use
+ * @param aWords
+ * A semi-colon (;) separated string of words to pick the plural form
+ * @return The appropriate plural form of the word
+ */
+ get get()
+ {
+ // This method will lazily load to avoid perf when it is first needed and
+ // creates getPluralForm function. The function it creates is based on the
+ // value of pluralRule specified in the intl stringbundle.
+ // See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+
+ // Delete the getters to be overwritten
+ delete PluralForm.numForms;
+ delete PluralForm.get;
+
+ // Get the plural rule number from the intl stringbundle
+ let ruleNum = Number(Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).createBundle(kIntlProperties).
+ GetStringFromName("pluralRule"));
+
+ // Make the plural form get function and set it as the default get
+ [PluralForm.get, PluralForm.numForms] = PluralForm.makeGetter(ruleNum);
+ return PluralForm.get;
+ },
+
+ /**
+ * Create a pair of plural form functions for the given plural rule number.
+ *
+ * @param aRuleNum
+ * The plural rule number to create functions
+ * @return A pair: [function that gets the right plural form,
+ * function that returns the number of plural forms]
+ */
+ makeGetter: function(aRuleNum)
+ {
+ // Default to "all plural" if the value is out of bounds or invalid
+ if (aRuleNum < 0 || aRuleNum >= gFunctions.length || isNaN(aRuleNum)) {
+ log(["Invalid rule number: ", aRuleNum, " -- defaulting to 0"]);
+ aRuleNum = 0;
+ }
+
+ // Get the desired pluralRule function
+ let [numForms, pluralFunc] = gFunctions[aRuleNum];
+
+ // Return functions that give 1) the number of forms and 2) gets the right
+ // plural form
+ return [function(aNum, aWords) {
+ // Figure out which index to use for the semi-colon separated words
+ let index = pluralFunc(aNum ? Number(aNum) : 0);
+ let words = aWords ? aWords.split(/;/) : [""];
+
+ // Explicitly check bounds to avoid strict warnings
+ let ret = index < words.length ? words[index] : undefined;
+
+ // Check for array out of bounds or empty strings
+ if ((ret == undefined) || (ret == "")) {
+ // Report the caller to help figure out who is causing badness
+ let caller = PluralForm.get.caller ? PluralForm.get.caller.name : "top";
+
+ // Display a message in the error console
+ log(["Index #", index, " of '", aWords, "' for value ", aNum,
+ " is invalid -- plural rule #", aRuleNum, "; called by ", caller]);
+
+ // Default to the first entry (which might be empty, but not undefined)
+ ret = words[0];
+ }
+
+ return ret;
+ }, function() numForms];
+ },
+
+ /**
+ * Get the number of forms for the current plural rule
+ *
+ * @return The number of forms
+ */
+ get numForms()
+ {
+ // We lazily load numForms, so trigger the init logic with get()
+ PluralForm.get();
+ return PluralForm.numForms;
+ },
+};
+
+/**
+ * Private helper function to log errors to the error console and command line
+ *
+ * @param aMsg
+ * Error message to log or an array of strings to concat
+ */
+function log(aMsg)
+{
+ let msg = "PluralForm.jsm: " + (aMsg.join ? aMsg.join("") : aMsg);
+ Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).
+ logStringMessage(msg);
+ dump(msg + "\n");
+}
diff --git a/bundles/XO/modules/SpatialNavigation.js b/bundles/XO/modules/SpatialNavigation.js
new file mode 100755
index 0000000..682a0e1
--- /dev/null
+++ b/bundles/XO/modules/SpatialNavigation.js
@@ -0,0 +1,558 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Spatial Navigation.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Doug Turner <dougt@meer.net> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ *
+ * Import this module through
+ *
+ * Components.utils.import("resource://gre/modules/SpatialNavigation.js");
+ *
+ * Usage: (Literal class)
+ *
+ * SpatialNavigation(browser_element, optional_callback);
+ *
+ * optional_callback will be called when a new element is focused.
+ *
+ * function optional_callback(element) {}
+ *
+ */
+
+
+var EXPORTED_SYMBOLS = ["SpatialNavigation"];
+
+var SpatialNavigation = {
+
+ init: function(browser, callback) {
+ browser.addEventListener("keypress", function (event) { _onInputKeyPress(event, callback) }, true);
+ },
+
+ uninit: function() {
+ }
+};
+
+
+// Private stuff
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+function dump(msg)
+{
+ var console = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
+ console.logStringMessage("*** SNAV: " + msg);
+}
+
+var gDirectionalBias = 10;
+var gRectFudge = 1;
+
+// modifier values
+const kAlt = "alt";
+const kShift = "shift";
+const kCtrl = "ctrl";
+const kNone = "none";
+
+function _onInputKeyPress (event, callback) {
+
+ // Use whatever key value is available (either keyCode or charCode).
+ // It might be useful for addons or whoever wants to set different
+ // key to be used here (e.g. "a", "F1", "arrowUp", ...).
+ var key = event.which || event.keyCode;
+
+ // If it isn't enabled, bail.
+ if (!PrefObserver['enabled'])
+ return;
+
+ if (key != PrefObserver['keyCodeDown'] &&
+ key != PrefObserver['keyCodeRight'] &&
+ key != PrefObserver['keyCodeUp'] &&
+ key != PrefObserver['keyCodeLeft'])
+ return;
+
+ // If it is not using the modifiers it should, bail.
+ if (!event.altKey && PrefObserver['modifierAlt'])
+ return;
+
+ if (!event.shiftKey && PrefObserver['modifierShift'])
+ return;
+
+ if (!event.crtlKey && PrefObserver['modifierCtrl'])
+ return;
+
+ var target = event.target;
+
+ var doc = target.ownerDocument;
+
+ // If it is XUL content (e.g. about:config), bail.
+ if (!PrefObserver['xulContentEnabled'] && doc instanceof Ci.nsIDOMXULDocument)
+ return ;
+
+ // check to see if we are in a textarea or text input element, and if so,
+ // ensure that we let the arrow keys work properly.
+ if (target instanceof Ci.nsIDOMHTMLHtmlElement) {
+ _focusNextUsingCmdDispatcher(key, callback);
+ return;
+ }
+
+ if ((target instanceof Ci.nsIDOMHTMLInputElement && (target.type == "text" || target.type == "password")) ||
+ target instanceof Ci.nsIDOMHTMLTextAreaElement ) {
+
+ // if there is any selection at all, just ignore
+ if (target.selectionEnd - target.selectionStart > 0)
+ return;
+
+ // if there is no text, there is nothing special to do.
+ if (target.textLength > 0) {
+ if (key == PrefObserver['keyCodeRight'] ||
+ key == PrefObserver['keyCodeDown'] ) {
+ // we are moving forward into the document
+ if (target.textLength != target.selectionEnd)
+ return;
+ }
+ else
+ {
+ // we are at the start of the text, okay to move
+ if (target.selectionStart != 0)
+ return;
+ }
+ }
+ }
+
+ // Check to see if we are in a select
+ if (target instanceof Ci.nsIDOMHTMLSelectElement)
+ {
+ if (key == PrefObserver['keyCodeDown']) {
+ if (target.selectedIndex + 1 < target.length)
+ return;
+ }
+
+ if (key == PrefObserver['keyCodeUp']) {
+ if (target.selectedIndex > 0)
+ return;
+ }
+ }
+
+ function snavfilter(node) {
+
+ if (node instanceof Ci.nsIDOMHTMLLinkElement ||
+ node instanceof Ci.nsIDOMHTMLAnchorElement) {
+ // if a anchor doesn't have a href, don't target it.
+ if (node.href == "")
+ return Ci.nsIDOMNodeFilter.FILTER_SKIP;
+ return Ci.nsIDOMNodeFilter.FILTER_ACCEPT;
+ }
+
+ if ((node instanceof Ci.nsIDOMHTMLButtonElement ||
+ node instanceof Ci.nsIDOMHTMLInputElement ||
+ node instanceof Ci.nsIDOMHTMLLinkElement ||
+ node instanceof Ci.nsIDOMHTMLOptGroupElement ||
+ node instanceof Ci.nsIDOMHTMLSelectElement ||
+ node instanceof Ci.nsIDOMHTMLTextAreaElement) &&
+ node.disabled == false)
+ return Ci.nsIDOMNodeFilter.FILTER_ACCEPT;
+
+ return Ci.nsIDOMNodeFilter.FILTER_SKIP;
+ }
+
+ var bestElementToFocus = null;
+ var distanceToBestElement = Infinity;
+ var focusedRect = _inflateRect(target.getBoundingClientRect(),
+ - gRectFudge);
+
+ var treeWalker = doc.createTreeWalker(doc, Ci.nsIDOMNodeFilter.SHOW_ELEMENT, snavfilter, false);
+ var nextNode;
+
+ while ((nextNode = treeWalker.nextNode())) {
+
+ if (nextNode == target)
+ continue;
+
+ var nextRect = _inflateRect(nextNode.getBoundingClientRect(),
+ - gRectFudge);
+
+ if (! _isRectInDirection(key, focusedRect, nextRect))
+ continue;
+
+ var distance = _spatialDistance(key, focusedRect, nextRect);
+
+ //dump("looking at: " + nextNode + " " + distance);
+
+ if (distance <= distanceToBestElement && distance > 0) {
+ distanceToBestElement = distance;
+ bestElementToFocus = nextNode;
+ }
+ }
+
+ if (bestElementToFocus != null) {
+ //dump("focusing element " + bestElementToFocus.nodeName + " " + bestElementToFocus) + "id=" + bestElementToFocus.getAttribute("id");
+
+ // Wishing we could do element.focus()
+ doc.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).focus(bestElementToFocus);
+
+ // if it is a text element, select all.
+ if((bestElementToFocus instanceof Ci.nsIDOMHTMLInputElement && (bestElementToFocus.type == "text" || bestElementToFocus.type == "password")) ||
+ bestElementToFocus instanceof Ci.nsIDOMHTMLTextAreaElement ) {
+ bestElementToFocus.selectionStart = 0;
+ bestElementToFocus.selectionEnd = bestElementToFocus.textLength;
+ }
+
+ if (callback != undefined)
+ callback(bestElementToFocus);
+
+ } else {
+ // couldn't find anything. just advance and hope.
+ _focusNextUsingCmdDispatcher(key, callback);
+ }
+
+ event.preventDefault();
+ event.stopPropagation();
+}
+
+function _focusNextUsingCmdDispatcher(key, callback) {
+
+ var windowMediator = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
+ var window = windowMediator.getMostRecentWindow("navigator:browser");
+
+ if (key == PrefObserver['keyCodeRight'] || key == PrefObserver['keyCodeDown']) {
+ window.document.commandDispatcher.advanceFocus();
+ } else {
+ window.document.commandDispatcher.rewindFocus();
+ }
+
+ if (callback != undefined)
+ callback(null);
+}
+
+function _isRectInDirection(key, focusedRect, anotherRect)
+{
+ if (key == PrefObserver['keyCodeLeft']) {
+ return (anotherRect.left < focusedRect.left);
+ }
+
+ if (key == PrefObserver['keyCodeRight']) {
+ return (anotherRect.right > focusedRect.right);
+ }
+
+ if (key == PrefObserver['keyCodeUp']) {
+ return (anotherRect.top < focusedRect.top);
+ }
+
+ if (key == PrefObserver['keyCodeDown']) {
+ return (anotherRect.bottom > focusedRect.bottom);
+ }
+ return false;
+}
+
+function _inflateRect(rect, value)
+{
+ var newRect = new Object();
+
+ newRect.left = rect.left - value;
+ newRect.top = rect.top - value;
+ newRect.right = rect.right + value;
+ newRect.bottom = rect.bottom + value;
+ return newRect;
+}
+
+function _containsRect(a, b)
+{
+ return ( (b.left <= a.right) &&
+ (b.right >= a.left) &&
+ (b.top <= a.bottom) &&
+ (b.bottom >= a.top) );
+}
+
+function _spatialDistance(key, a, b)
+{
+ var inlineNavigation = false;
+ var mx, my, nx, ny;
+
+ if (key == PrefObserver['keyCodeLeft']) {
+
+ // |---|
+ // |---|
+ //
+ // |---| |---|
+ // |---| |---|
+ //
+ // |---|
+ // |---|
+ //
+
+ if (a.top > b.bottom) {
+ // the b rect is above a.
+ mx = a.left;
+ my = a.top;
+ nx = b.right;
+ ny = b.bottom;
+ }
+ else if (a.bottom < b.top) {
+ // the b rect is below a.
+ mx = a.left;
+ my = a.bottom;
+ nx = b.right;
+ ny = b.top;
+ }
+ else {
+ mx = a.left;
+ my = 0;
+ nx = b.right;
+ ny = 0;
+ }
+ } else if (key == PrefObserver['keyCodeRight']) {
+
+ // |---|
+ // |---|
+ //
+ // |---| |---|
+ // |---| |---|
+ //
+ // |---|
+ // |---|
+ //
+
+ if (a.top > b.bottom) {
+ // the b rect is above a.
+ mx = a.right;
+ my = a.top;
+ nx = b.left;
+ ny = b.bottom;
+ }
+ else if (a.bottom < b.top) {
+ // the b rect is below a.
+ mx = a.right;
+ my = a.bottom;
+ nx = b.left;
+ ny = b.top;
+ } else {
+ mx = a.right;
+ my = 0;
+ nx = b.left;
+ ny = 0;
+ }
+ } else if (key == PrefObserver['keyCodeUp']) {
+
+ // |---| |---| |---|
+ // |---| |---| |---|
+ //
+ // |---|
+ // |---|
+ //
+
+ if (a.left > b.right) {
+ // the b rect is to the left of a.
+ mx = a.left;
+ my = a.top;
+ nx = b.right;
+ ny = b.bottom;
+ } else if (a.right < b.left) {
+ // the b rect is to the right of a
+ mx = a.right;
+ my = a.top;
+ nx = b.left;
+ ny = b.bottom;
+ } else {
+ // both b and a share some common x's.
+ mx = 0;
+ my = a.top;
+ nx = 0;
+ ny = b.bottom;
+ }
+ } else if (key == PrefObserver['keyCodeDown']) {
+
+ // |---|
+ // |---|
+ //
+ // |---| |---| |---|
+ // |---| |---| |---|
+ //
+
+ if (a.left > b.right) {
+ // the b rect is to the left of a.
+ mx = a.left;
+ my = a.bottom;
+ nx = b.right;
+ ny = b.top;
+ } else if (a.right < b.left) {
+ // the b rect is to the right of a
+ mx = a.right;
+ my = a.bottom;
+ nx = b.left;
+ ny = b.top;
+ } else {
+ // both b and a share some common x's.
+ mx = 0;
+ my = a.bottom;
+ nx = 0;
+ ny = b.top;
+ }
+ }
+
+ var scopedRect = _inflateRect(a, gRectFudge);
+
+ if (key == PrefObserver['keyCodeLeft'] ||
+ key == PrefObserver['keyCodeRight']) {
+ scopedRect.left = 0;
+ scopedRect.right = Infinity;
+ inlineNavigation = _containsRect(scopedRect, b);
+ }
+ else if (key == PrefObserver['keyCodeUp'] ||
+ key == PrefObserver['keyCodeDown']) {
+ scopedRect.top = 0;
+ scopedRect.bottom = Infinity;
+ inlineNavigation = _containsRect(scopedRect, b);
+ }
+
+ var d = Math.pow((mx-nx), 2) + Math.pow((my-ny), 2);
+
+ // prefer elements directly aligned with the focused element
+ if (inlineNavigation)
+ d /= gDirectionalBias;
+
+ return d;
+}
+
+// Snav preference observer
+
+PrefObserver = {
+
+ register: function()
+ {
+ this.prefService = Cc["@mozilla.org/preferences-service;1"]
+ .getService(Ci.nsIPrefService);
+
+ this._branch = this.prefService.getBranch("snav.");
+ this._branch.QueryInterface(Ci.nsIPrefBranch2);
+ this._branch.addObserver("", this, false);
+
+ // set current or default pref values
+ this.observe(null, "nsPref:changed", "enabled");
+ this.observe(null, "nsPref:changed", "xulContentEnabled");
+ this.observe(null, "nsPref:changed", "keyCode.modifier");
+ this.observe(null, "nsPref:changed", "keyCode.right");
+ this.observe(null, "nsPref:changed", "keyCode.up");
+ this.observe(null, "nsPref:changed", "keyCode.down");
+ this.observe(null, "nsPref:changed", "keyCode.left");
+ },
+
+ observe: function(aSubject, aTopic, aData)
+ {
+ if(aTopic != "nsPref:changed")
+ return;
+
+ // aSubject is the nsIPrefBranch we're observing (after appropriate QI)
+ // aData is the name of the pref that's been changed (relative to aSubject)
+ switch (aData) {
+ case "enabled":
+ try {
+ this.enabled = this._branch.getBoolPref("enabled");
+ } catch(e) {
+ this.enabled = false;
+ }
+ break;
+ case "xulContentEnabled":
+ try {
+ this.xulContentEnabled = this._branch.getBoolPref("xulContentEnabled");
+ } catch(e) {
+ this.xulContentEnabled = false;
+ }
+ break;
+
+ case "keyCode.modifier":
+ try {
+ this.keyCodeModifier = this._branch.getCharPref("keyCode.modifier");
+
+ // resetting modifiers
+ this.modifierAlt = false;
+ this.modifierShift = false;
+ this.modifierCtrl = false;
+
+ if (this.keyCodeModifier != this.kNone)
+ {
+ // use are using '+' as a separator in about:config.
+ var mods = this.keyCodeModifier.split(/\++/);
+ for (var i = 0; i < mods.length; i++) {
+ var mod = mods[i].toLowerCase();
+ if (mod == "")
+ continue;
+ else if (mod == kAlt)
+ this.modifierAlt = true;
+ else if (mod == kShift)
+ this.modifierShift = true;
+ else if (mod == kCtrl)
+ this.modifierCtrl = true;
+ else {
+ this.keyCodeModifier = kNone;
+ break;
+ }
+ }
+ }
+ } catch(e) {
+ this.keyCodeModifier = kNone;
+ }
+ break;
+ case "keyCode.up":
+ try {
+ this.keyCodeUp = this._branch.getIntPref("keyCode.up");
+ } catch(e) {
+ this.keyCodeUp = Ci.nsIDOMKeyEvent.DOM_VK_UP;
+ }
+ break;
+ case "keyCode.down":
+ try {
+ this.keyCodeDown = this._branch.getIntPref("keyCode.down");
+ } catch(e) {
+ this.keyCodeDown = Ci.nsIDOMKeyEvent.DOM_VK_DOWN;
+ }
+ break;
+ case "keyCode.left":
+ try {
+ this.keyCodeLeft = this._branch.getIntPref("keyCode.left");
+ } catch(e) {
+ this.keyCodeLeft = Ci.nsIDOMKeyEvent.DOM_VK_LEFT;
+ }
+ break;
+ case "keyCode.right":
+ try {
+ this.keyCodeRight = this._branch.getIntPref("keyCode.right");
+ } catch(e) {
+ this.keyCodeRight = Ci.nsIDOMKeyEvent.DOM_VK_RIGHT;
+ }
+ break;
+ }
+ },
+}
+
+PrefObserver.register();
diff --git a/bundles/XO/modules/WindowDraggingUtils.jsm b/bundles/XO/modules/WindowDraggingUtils.jsm
new file mode 100755
index 0000000..0fadb1c
--- /dev/null
+++ b/bundles/XO/modules/WindowDraggingUtils.jsm
@@ -0,0 +1,87 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Markus Stange <mstange@themasta.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let EXPORTED_SYMBOLS = [ "WindowDraggingElement" ];
+
+function WindowDraggingElement(elem, window) {
+ this._elem = elem;
+ this._window = window;
+ this._elem.addEventListener("mousedown", this, false);
+}
+
+WindowDraggingElement.prototype = {
+ mouseDownCheck: function(e) { return true; },
+ dragTags: ["box", "hbox", "vbox", "spacer", "label", "statusbarpanel", "stack",
+ "toolbaritem", "toolbarseparator", "toolbarspring", "toolbarspacer",
+ "radiogroup"],
+ handleEvent: function(aEvent) {
+ switch (aEvent.type) {
+ case "mousedown":
+ if (aEvent.button != 0 || !this.mouseDownCheck.call(this._elem, aEvent))
+ return;
+
+ let target = aEvent.originalTarget, parent = aEvent.originalTarget;
+ while (parent != this._elem) {
+ let mousethrough = parent.getAttribute("mousethrough");
+ if (mousethrough == "always")
+ target = parent.parentNode;
+ else if (mousethrough == "never")
+ break;
+ parent = parent.parentNode;
+ }
+ while (target != this._elem) {
+ if (this.dragTags.indexOf(target.localName) == -1)
+ return;
+ target = target.parentNode;
+ }
+ this._deltaX = aEvent.screenX - this._window.screenX;
+ this._deltaY = aEvent.screenY - this._window.screenY;
+ this._draggingWindow = true;
+ this._window.addEventListener("mousemove", this, false);
+ this._window.addEventListener("mouseup", this, false);
+ break;
+ case "mousemove":
+ if (this._draggingWindow)
+ this._window.moveTo(aEvent.screenX - this._deltaX, aEvent.screenY - this._deltaY);
+ break;
+ case "mouseup":
+ this._draggingWindow = false;
+ this._window.removeEventListener("mousemove", this, false);
+ this._window.removeEventListener("mouseup", this, false);
+ break;
+ }
+ }
+}
diff --git a/bundles/XO/modules/XPCOMUtils.jsm b/bundles/XO/modules/XPCOMUtils.jsm
new file mode 100755
index 0000000..311c24a
--- /dev/null
+++ b/bundles/XO/modules/XPCOMUtils.jsm
@@ -0,0 +1,267 @@
+/*
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Alex Fritze <alex@croczilla.com> (original author)
+ * Nickolay Ponomarev <asqueella@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Utilities for JavaScript components loaded by the JS component
+ * loader.
+ *
+ * Import into a JS component using
+ * 'Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");'
+ *
+ * Exposing a JS 'class' as a component using these utility methods consists
+ * of several steps:
+ * 0. Import XPCOMUtils, as described above.
+ * 1. Declare the 'class' (or multiple classes) implementing the component(s):
+ * function MyComponent() {
+ * // constructor
+ * }
+ * MyComponent.prototype = {
+ * // properties required for XPCOM registration:
+ * classDescription: "unique text description",
+ * classID: Components.ID("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"),
+ * contractID: "@example.com/xxx;1",
+ *
+ * // [optional] custom factory (an object implementing nsIFactory). If not
+ * // provided, the default factory is used, which returns
+ * // |(new MyComponent()).QueryInterface(iid)| in its createInstance().
+ * _xpcom_factory: { ... },
+ *
+ * // [optional] an array of categories to register this component in.
+ * _xpcom_categories: [{
+ * // Each object in the array specifies the parameters to pass to
+ * // nsICategoryManager.addCategoryEntry(). 'true' is passed for
+ * // both aPersist and aReplace params.
+ * category: "some-category",
+ * // optional, defaults to the object's classDescription
+ * entry: "entry name",
+ * // optional, defaults to the object's contractID (unless
+ * // 'service' is specified)
+ * value: "...",
+ * // optional, defaults to false. When set to true, and only if 'value'
+ * // is not specified, the concatenation of the string "service," and the
+ * // object's contractID is passed as aValue parameter of addCategoryEntry.
+ * service: true
+ * }],
+ *
+ * // QueryInterface implementation, e.g. using the generateQI helper
+ * QueryInterface: XPCOMUtils.generateQI(
+ * [Components.interfaces.nsIObserver,
+ * Components.interfaces.nsIMyInterface]),
+ *
+ * // ...component implementation...
+ * };
+ *
+ * 2. Create an array of component constructors (like the one
+ * created in step 1):
+ * var components = [MyComponent];
+ *
+ * 3. Define the NSGetModule entry point:
+ * function NSGetModule(compMgr, fileSpec) {
+ * // components is the array created in step 2.
+ * return XPCOMUtils.generateModule(components);
+ * }
+ */
+
+
+var EXPORTED_SYMBOLS = [ "XPCOMUtils" ];
+
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+var XPCOMUtils = {
+ /**
+ * Generate a QueryInterface implementation. The returned function must be
+ * assigned to the 'QueryInterface' property of a JS object. When invoked on
+ * that object, it checks if the given iid is listed in the |interfaces|
+ * param, and if it is, returns |this| (the object it was called on).
+ */
+ generateQI: function(interfaces) {
+ return makeQI([i.name for each (i in interfaces) if (i)]);
+ },
+
+ /**
+ * Generate the NSGetModule function (along with the module definition).
+ * See the parameters to generateModule.
+ */
+ generateNSGetModule: function(componentsArray, postRegister, preUnregister) {
+ return function NSGetModule(compMgr, fileSpec) {
+ return XPCOMUtils.generateModule(componentsArray,
+ postRegister,
+ preUnregister);
+ }
+ },
+
+ /**
+ * Generate a module implementation.
+ *
+ * @param componentsArray Array of component constructors. See the comment
+ * at the top of this file for details.
+ * @param postRegister optional post-registration function with
+ * signature 'postRegister(nsIComponentManager,
+ * nsIFile, componentsArray)'
+ * @param preUnregister optional pre-unregistration function with
+ * signature 'preUnregister(nsIComponentManager,
+ * nsIFile, componentsArray)'
+ */
+ generateModule: function(componentsArray, postRegister, preUnregister) {
+ let classes = [];
+ for each (let component in componentsArray) {
+ classes.push({
+ cid: component.prototype.classID,
+ className: component.prototype.classDescription,
+ contractID: component.prototype.contractID,
+ factory: this._getFactory(component),
+ categories: component.prototype._xpcom_categories
+ });
+ }
+
+ return { // nsIModule impl.
+ getClassObject: function(compMgr, cid, iid) {
+ // We only support nsIFactory queries, not nsIClassInfo
+ if (!iid.equals(Ci.nsIFactory))
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+
+ for each (let classDesc in classes) {
+ if (classDesc.cid.equals(cid))
+ return classDesc.factory;
+ }
+
+ throw Cr.NS_ERROR_FACTORY_NOT_REGISTERED;
+ },
+
+ registerSelf: function(compMgr, fileSpec, location, type) {
+ var componentCount = 0;
+ debug("*** registering " + fileSpec.leafName + ": [ ");
+ compMgr.QueryInterface(Ci.nsIComponentRegistrar);
+
+ for each (let classDesc in classes) {
+ debug((componentCount++ ? ", " : "") + classDesc.className);
+ compMgr.registerFactoryLocation(classDesc.cid,
+ classDesc.className,
+ classDesc.contractID,
+ fileSpec,
+ location,
+ type);
+ if (classDesc.categories) {
+ let catMan = XPCOMUtils.categoryManager;
+ for each (let cat in classDesc.categories) {
+ let defaultValue = (cat.service ? "service," : "") +
+ classDesc.contractID;
+ catMan.addCategoryEntry(cat.category,
+ cat.entry || classDesc.className,
+ cat.value || defaultValue,
+ true, true);
+ }
+ }
+ }
+
+ if (postRegister)
+ postRegister(compMgr, fileSpec, componentsArray);
+ debug(" ]\n");
+ },
+
+ unregisterSelf: function(compMgr, fileSpec, location) {
+ var componentCount = 0;
+ debug("*** unregistering " + fileSpec.leafName + ": [ ");
+ compMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ if (preUnregister)
+ preUnregister(compMgr, fileSpec, componentsArray);
+
+ for each (let classDesc in classes) {
+ debug((componentCount++ ? ", " : "") + classDesc.className);
+ if (classDesc.categories) {
+ let catMan = XPCOMUtils.categoryManager;
+ for each (let cat in classDesc.categories) {
+ catMan.deleteCategoryEntry(cat.category,
+ cat.entry || classDesc.className,
+ true);
+ }
+ }
+ compMgr.unregisterFactoryLocation(classDesc.cid, fileSpec);
+ }
+ debug(" ]\n");
+ },
+
+ canUnload: function(compMgr) {
+ return true;
+ }
+ };
+ },
+
+ /**
+ * Convenience access to category manager
+ */
+ get categoryManager() {
+ return Components.classes["@mozilla.org/categorymanager;1"]
+ .getService(Ci.nsICategoryManager);
+ },
+
+ /**
+ * Returns an nsIFactory for |component|.
+ */
+ _getFactory: function(component) {
+ var factory = component.prototype._xpcom_factory;
+ if (!factory) {
+ factory = {
+ createInstance: function(outer, iid) {
+ if (outer)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return (new component()).QueryInterface(iid);
+ }
+ }
+ }
+ return factory;
+ }
+};
+
+/**
+ * Helper for XPCOMUtils.generateQI to avoid leaks - see bug 381651#c1
+ */
+function makeQI(interfaceNames) {
+ return function XPCOMUtils_QueryInterface(iid) {
+ if (iid.equals(Ci.nsISupports))
+ return this;
+ for each(let interfaceName in interfaceNames) {
+ if (Ci[interfaceName].equals(iid))
+ return this;
+ }
+
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ };
+}
diff --git a/bundles/XO/modules/debug.js b/bundles/XO/modules/debug.js
new file mode 100755
index 0000000..42b22d1
--- /dev/null
+++ b/bundles/XO/modules/debug.js
@@ -0,0 +1,82 @@
+//@line 44 "/builds/moz2_slave/linux_build/build/toolkit/content/debug.js"
+
+var EXPORTED_SYMBOLS = ["NS_ASSERT"];
+
+var gTraceOnAssert = true;
+
+/**
+ * This function provides a simple assertion function for JavaScript.
+ * If the condition is true, this function will do nothing. If the
+ * condition is false, then the message will be printed to the console
+ * and an alert will appear showing a stack trace, so that the (alpha
+ * or nightly) user can file a bug containing it. For future enhancements,
+ * see bugs 330077 and 330078.
+ *
+ * To suppress the dialogs, you can run with the environment variable
+ * XUL_ASSERT_PROMPT set to 0 (if unset, this defaults to 1).
+ *
+ * @param condition represents the condition that we're asserting to be
+ * true when we call this function--should be
+ * something that can be evaluated as a boolean.
+ * @param message a string to be displayed upon failure of the assertion
+ */
+
+function NS_ASSERT(condition, message) {
+ if (condition)
+ return;
+
+ var releaseBuild = true;
+ var defB = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService)
+ .getDefaultBranch(null);
+ try {
+ switch (defB.getCharPref("app.update.channel")) {
+ case "nightly":
+ case "beta":
+ case "default":
+ releaseBuild = false;
+ }
+ } catch(ex) {}
+
+ var caller = arguments.callee.caller;
+ var assertionText = "ASSERT: " + message + "\n";
+
+ if (releaseBuild) {
+ // Just report the error to the console
+ Components.utils.reportError(assertionText);
+ return;
+ }
+
+ // Otherwise, dump to stdout and launch an assertion failure dialog
+ dump(assertionText);
+
+ var stackText = "";
+ if (gTraceOnAssert) {
+ stackText = "Stack Trace: \n";
+ var count = 0;
+ while (caller) {
+ stackText += count++ + ":" + caller.name + "(";
+ for (var i = 0; i < caller.arguments.length; ++i) {
+ var arg = caller.arguments[i];
+ stackText += arg;
+ if (i < caller.arguments.length - 1)
+ stackText += ",";
+ }
+ stackText += ")\n";
+ caller = caller.arguments.callee.caller;
+ }
+ }
+
+ var environment = Components.classes["@mozilla.org/process/environment;1"].
+ getService(Components.interfaces.nsIEnvironment);
+ if (environment.exists("XUL_ASSERT_PROMPT") &&
+ !parseInt(environment.get("XUL_ASSERT_PROMPT")))
+ return;
+
+ var source = null;
+ if (this.window)
+ source = this.window;
+ var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
+ getService(Components.interfaces.nsIPromptService);
+ ps.alert(source, "Assertion Failed", assertionText + stackText);
+}
diff --git a/bundles/XO/modules/distribution.js b/bundles/XO/modules/distribution.js
new file mode 100755
index 0000000..722abe2
--- /dev/null
+++ b/bundles/XO/modules/distribution.js
@@ -0,0 +1,359 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Firefox Distribution Customizations.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dan Mills <thunder@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+EXPORTED_SYMBOLS = [ "DistributionCustomizer" ];
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+function DistributionCustomizer() {
+ this._distroDir = this._dirSvc.get("XCurProcD", Ci.nsIFile);
+ this._distroDir.append("distribution");
+
+ let iniFile = this._distroDir.clone();
+ iniFile.append("distribution.ini");
+ this._iniExists = iniFile.exists();
+
+ if (!this._iniExists)
+ return;
+
+ this._ini = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].
+ getService(Ci.nsIINIParserFactory).createINIParser(iniFile);
+
+ this._prefs = this._prefSvc.getBranch(null);
+ this._locale = this._prefs.getCharPref("general.useragent.locale");
+
+}
+DistributionCustomizer.prototype = {
+ __bmSvc: null,
+ get _bmSvc() {
+ if (!this.__bmSvc)
+ this.__bmSvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+ getService(Ci.nsINavBookmarksService);
+ return this.__bmSvc;
+ },
+
+ __annoSvc: null,
+ get _annoSvc() {
+ if (!this.__annoSvc)
+ this.__annoSvc = Cc["@mozilla.org/browser/annotation-service;1"].
+ getService(Ci.nsIAnnotationService);
+ return this.__annoSvc;
+ },
+
+ __livemarkSvc: null,
+ get _livemarkSvc() {
+ if (!this.__livemarkSvc)
+ this.__livemarkSvc = Cc["@mozilla.org/browser/livemark-service;2"].
+ getService(Ci.nsILivemarkService);
+ return this.__livemarkSvc;
+ },
+
+ __dirSvc: null,
+ get _dirSvc() {
+ if (!this.__dirSvc)
+ this.__dirSvc = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ return this.__dirSvc;
+ },
+
+ __prefSvc: null,
+ get _prefSvc() {
+ if (!this.__prefSvc)
+ this.__prefSvc = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefService);
+ return this.__prefSvc;
+ },
+
+ __iosvc: null,
+ get _iosvc() {
+ if (!this.__iosvc)
+ this.__iosvc = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return this.__iosvc;
+ },
+
+ _locale: "en-US",
+ _distroDir: null,
+ _iniExists: false,
+ _ini: null,
+
+
+ _makeURI: function DIST__makeURI(spec) {
+ return this._iosvc.newURI(spec, null, null);
+ },
+ _parseBookmarksSection: function DIST_parseBookmarksSection(parentId, section) {
+ let keys = [];
+ for (let i in enumerate(this._ini.getKeys(section)))
+ keys.push(i);
+ keys.sort();
+ let items = {};
+ let defaultItemId = -1;
+ let maxItemId = -1;
+
+ for (let i = 0; i < keys.length; i++) {
+ let m = /^item\.(\d+)\.(\w+)\.?(\w*)/.exec(keys[i]);
+ if (m) {
+ let [foo, iid, iprop, ilocale] = m;
+
+ if (ilocale)
+ continue;
+
+ if (!items[iid])
+ items[iid] = {};
+ if (keys.indexOf(keys[i] + "." + this._locale) >= 0) {
+ items[iid][iprop] = this._ini.getString(section, keys[i] + "." +
+ this._locale);
+ } else {
+ items[iid][iprop] = this._ini.getString(section, keys[i]);
+ }
+
+ if (iprop == "type" && items[iid]["type"] == "default")
+ defaultItemId = iid;
+
+ if (maxItemId < iid)
+ maxItemId = iid;
+ } else {
+ dump("Key did not match: " + keys[i] + "\n");
+ }
+ }
+
+ let prependIndex = 0;
+ for (let iid = 0; iid <= maxItemId; iid++) {
+ if (!items[iid])
+ continue;
+
+ let index = -1;
+ let newId;
+
+ switch (items[iid]["type"]) {
+ case "default":
+ break;
+
+ case "folder":
+ if (iid < defaultItemId)
+ index = prependIndex++;
+
+ newId = this._bmSvc.createFolder(parentId, items[iid]["title"], index);
+
+ this._parseBookmarksSection(newId, "BookmarksFolder-" +
+ items[iid]["folderId"]);
+
+ if (items[iid]["description"])
+ this._annoSvc.setItemAnnotation(newId, "bookmarkProperties/description",
+ items[iid]["description"], 0,
+ this._annoSvc.EXPIRE_NEVER);
+
+ break;
+
+ case "separator":
+ if (iid < defaultItemId)
+ index = prependIndex++;
+ this._bmSvc.insertSeparator(parentId, index);
+ break;
+
+ case "livemark":
+ if (iid < defaultItemId)
+ index = prependIndex++;
+
+ newId = this._livemarkSvc.
+ createLivemark(parentId,
+ items[iid]["title"],
+ this._makeURI(items[iid]["siteLink"]),
+ this._makeURI(items[iid]["feedLink"]),
+ index);
+ break;
+
+ case "bookmark":
+ default:
+ if (iid < defaultItemId)
+ index = prependIndex++;
+
+ newId = this._bmSvc.insertBookmark(parentId,
+ this._makeURI(items[iid]["link"]),
+ index, items[iid]["title"]);
+
+ if (items[iid]["description"])
+ this._annoSvc.setItemAnnotation(newId, "bookmarkProperties/description",
+ items[iid]["description"], 0,
+ this._annoSvc.EXPIRE_NEVER);
+
+ break;
+ }
+ }
+ },
+ applyCustomizations: function DIST_applyCustomizations() {
+ if (!this._iniExists)
+ return;
+
+ // nsPrefService loads very early. Reload prefs so we can set
+ // distribution defaults during the prefservice:after-app-defaults
+ // notification (see applyPrefDefaults below)
+ this._prefSvc.QueryInterface(Ci.nsIObserver);
+ this._prefSvc.observe(null, "reload-default-prefs", null);
+
+ let sections = enumToObject(this._ini.getSections());
+
+ // The global section, and several of its fields, is required
+ // (we also check here to be consistent with applyPrefDefaults below)
+ if (!sections["Global"])
+ return;
+ let globalPrefs = enumToObject(this._ini.getKeys("Global"));
+ if (!(globalPrefs["id"] && globalPrefs["version"] && globalPrefs["about"]))
+ return;
+
+ let bmProcessed = false;
+ let bmProcessedPref;
+
+ try {
+ bmProcessedPref = this._ini.getString("Global",
+ "bookmarks.initialized.pref");
+ } catch (e) {
+ bmProcessedPref = "distribution." +
+ this._ini.getString("Global", "id") + ".bookmarksProcessed";
+ }
+
+ try {
+ bmProcessed = this._prefs.getBoolPref(bmProcessedPref);
+ } catch (e) {}
+
+ if (!bmProcessed) {
+ if (sections["BookmarksMenu"])
+ this._parseBookmarksSection(this._bmSvc.bookmarksMenuFolder,
+ "BookmarksMenu");
+ if (sections["BookmarksToolbar"])
+ this._parseBookmarksSection(this._bmSvc.toolbarFolder,
+ "BookmarksToolbar");
+ this._prefs.setBoolPref(bmProcessedPref, true);
+ }
+ },
+ applyPrefDefaults: function DIST_applyPrefDefaults() {
+ if (!this._iniExists)
+ return;
+
+ let sections = enumToObject(this._ini.getSections());
+
+ // The global section, and several of its fields, is required
+ if (!sections["Global"])
+ return;
+ let globalPrefs = enumToObject(this._ini.getKeys("Global"));
+ if (!(globalPrefs["id"] && globalPrefs["version"] && globalPrefs["about"]))
+ return;
+
+ let defaults = this._prefSvc.getDefaultBranch(null);
+
+ // Global really contains info we set as prefs. They're only
+ // separate because they are "special" (read: required)
+
+ defaults.setCharPref("distribution.id", this._ini.getString("Global", "id"));
+ defaults.setCharPref("distribution.version",
+ this._ini.getString("Global", "version"));
+
+ let partnerAbout = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ if (globalPrefs["about." + this._locale]) {
+ partnerAbout.data = this._ini.getString("Global", "about." + this._locale);
+ } else {
+ partnerAbout.data = this._ini.getString("Global", "about");
+ }
+ defaults.setComplexValue("distribution.about",
+ Ci.nsISupportsString, partnerAbout);
+
+ if (sections["Preferences"]) {
+ for (let key in enumerate(this._ini.getKeys("Preferences"))) {
+ try {
+ let value = eval(this._ini.getString("Preferences", key));
+ switch (typeof value) {
+ case "boolean":
+ defaults.setBoolPref(key, value);
+ break;
+ case "number":
+ defaults.setIntPref(key, value);
+ break;
+ case "string":
+ defaults.setCharPref(key, value);
+ break;
+ case "undefined":
+ defaults.setCharPref(key, value);
+ break;
+ }
+ } catch (e) { /* ignore bad prefs and move on */ }
+ }
+ }
+
+ // We eval() the localizable prefs as well (even though they'll
+ // always get set as a string) to keep the INI format consistent:
+ // string prefs always need to be in quotes
+
+ let localizedStr = Cc["@mozilla.org/pref-localizedstring;1"].
+ createInstance(Ci.nsIPrefLocalizedString);
+
+ if (sections["LocalizablePreferences"]) {
+ for (let key in enumerate(this._ini.getKeys("LocalizablePreferences"))) {
+ try {
+ let value = eval(this._ini.getString("LocalizablePreferences", key));
+ value = value.replace("%LOCALE%", this._locale, "g");
+ localizedStr.data = "data:text/plain," + key + "=" + value;
+ defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
+ } catch (e) { /* ignore bad prefs and move on */ }
+ }
+ }
+
+ if (sections["LocalizablePreferences-" + this._locale]) {
+ for (let key in enumerate(this._ini.getKeys("LocalizablePreferences-" + this._locale))) {
+ try {
+ let value = eval(this._ini.getString("LocalizablePreferences-" + this._locale, key));
+ localizedStr.data = "data:text/plain," + key + "=" + value;
+ defaults.setComplexValue(key, Ci.nsIPrefLocalizedString, localizedStr);
+ } catch (e) { /* ignore bad prefs and move on */ }
+ }
+ }
+ }
+};
+
+function enumerate(UTF8Enumerator) {
+ while (UTF8Enumerator.hasMore())
+ yield UTF8Enumerator.getNext();
+}
+
+function enumToObject(UTF8Enumerator) {
+ let ret = {};
+ for (let i in enumerate(UTF8Enumerator))
+ ret[i] = 1;
+ return ret;
+}
diff --git a/bundles/XO/modules/utils.js b/bundles/XO/modules/utils.js
new file mode 100755
index 0000000..f982934
--- /dev/null
+++ b/bundles/XO/modules/utils.js
@@ -0,0 +1,1804 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Places Command Controller.
+ *
+ * The Initial Developer of the Original Code is Google Inc.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Ben Goodger <beng@google.com>
+ * Myk Melez <myk@mozilla.org>
+ * Asaf Romano <mano@mozilla.com>
+ * Sungjoon Steve Won <stevewon@gmail.com>
+ * Dietrich Ayala <dietrich@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+function LOG(str) {
+ dump("*** " + str + "\n");
+}
+
+var EXPORTED_SYMBOLS = ["PlacesUtils"];
+
+var Ci = Components.interfaces;
+var Cc = Components.classes;
+var Cr = Components.results;
+
+const EXCLUDE_FROM_BACKUP_ANNO = "places/excludeFromBackup";
+const POST_DATA_ANNO = "bookmarkProperties/POSTData";
+const READ_ONLY_ANNO = "placesInternal/READ_ONLY";
+const LMANNO_FEEDURI = "livemark/feedURI";
+const LMANNO_SITEURI = "livemark/siteURI";
+const LMANNO_EXPIRATION = "livemark/expiration";
+const LMANNO_LOADFAILED = "livemark/loadfailed";
+const LMANNO_LOADING = "livemark/loading";
+
+// The RESTORE_*_NSIOBSERVER_TOPIC constants should match the #defines of the
+// same names in browser/components/places/src/nsPlacesImportExportService.cpp
+const RESTORE_BEGIN_NSIOBSERVER_TOPIC = "bookmarks-restore-begin";
+const RESTORE_SUCCESS_NSIOBSERVER_TOPIC = "bookmarks-restore-success";
+const RESTORE_FAILED_NSIOBSERVER_TOPIC = "bookmarks-restore-failed";
+const RESTORE_NSIOBSERVER_DATA = "json";
+
+//@line 73 "/builds/moz2_slave/linux_build/build/toolkit/components/places/src/utils.js"
+// On other platforms, the transferable system converts "\r\n" to "\n".
+const NEWLINE = "\r\n";
+//@line 76 "/builds/moz2_slave/linux_build/build/toolkit/components/places/src/utils.js"
+
+function QI_node(aNode, aIID) {
+ var result = null;
+ try {
+ result = aNode.QueryInterface(aIID);
+ }
+ catch (e) {
+ }
+ return result;
+}
+function asVisit(aNode) { return QI_node(aNode, Ci.nsINavHistoryVisitResultNode); }
+function asFullVisit(aNode){ return QI_node(aNode, Ci.nsINavHistoryFullVisitResultNode);}
+function asContainer(aNode){ return QI_node(aNode, Ci.nsINavHistoryContainerResultNode);}
+function asQuery(aNode) { return QI_node(aNode, Ci.nsINavHistoryQueryResultNode); }
+
+var PlacesUtils = {
+ // Place entries that are containers, e.g. bookmark folders or queries.
+ TYPE_X_MOZ_PLACE_CONTAINER: "text/x-moz-place-container",
+ // Place entries that are bookmark separators.
+ TYPE_X_MOZ_PLACE_SEPARATOR: "text/x-moz-place-separator",
+ // Place entries that are not containers or separators
+ TYPE_X_MOZ_PLACE: "text/x-moz-place",
+ // Place entries in shortcut url format (url\ntitle)
+ TYPE_X_MOZ_URL: "text/x-moz-url",
+ // Place entries formatted as HTML anchors
+ TYPE_HTML: "text/html",
+ // Place entries as raw URL text
+ TYPE_UNICODE: "text/unicode",
+
+ /**
+ * The Bookmarks Service.
+ */
+ get bookmarks() {
+ delete this.bookmarks;
+ return this.bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+ getService(Ci.nsINavBookmarksService);
+ },
+
+ /**
+ * The Nav History Service.
+ */
+ get history() {
+ delete this.history;
+ return this.history = Cc["@mozilla.org/browser/nav-history-service;1"].
+ getService(Ci.nsINavHistoryService);
+ },
+
+ /**
+ * The Live Bookmark Service.
+ */
+ get livemarks() {
+ delete this.livemarks;
+ return this.livemarks = Cc["@mozilla.org/browser/livemark-service;2"].
+ getService(Ci.nsILivemarkService);
+ },
+
+ /**
+ * The Annotations Service.
+ */
+ get annotations() {
+ delete this.annotations;
+ return this.annotations = Cc["@mozilla.org/browser/annotation-service;1"].
+ getService(Ci.nsIAnnotationService);
+ },
+
+ /**
+ * The Favicons Service
+ */
+ get favicons() {
+ delete this.favicons;
+ return this.favicons = Cc["@mozilla.org/browser/favicon-service;1"].
+ getService(Ci.nsIFaviconService);
+ },
+
+ /**
+ * The Places Tagging Service
+ */
+ get tagging() {
+ delete this.tagging;
+ return this.tagging = Cc["@mozilla.org/browser/tagging-service;1"].
+ getService(Ci.nsITaggingService);
+ },
+
+ /**
+ * Makes a URI from a spec.
+ * @param aSpec
+ * The string spec of the URI
+ * @returns A URI object for the spec.
+ */
+ _uri: function PU__uri(aSpec) {
+ return Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService).
+ newURI(aSpec, null, null);
+ },
+
+ /**
+ * String bundle helpers
+ */
+ get _bundle() {
+ const PLACES_STRING_BUNDLE_URI =
+ "chrome://places/locale/places.properties";
+ delete this._bundle;
+ return this._bundle = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService).
+ createBundle(PLACES_STRING_BUNDLE_URI);
+ },
+
+ getFormattedString: function PU_getFormattedString(key, params) {
+ return this._bundle.formatStringFromName(key, params, params.length);
+ },
+
+ getString: function PU_getString(key) {
+ return this._bundle.GetStringFromName(key);
+ },
+
+ /**
+ * Determines whether or not a ResultNode is a Bookmark folder.
+ * @param aNode
+ * A result node
+ * @returns true if the node is a Bookmark folder, false otherwise
+ */
+ nodeIsFolder: function PU_nodeIsFolder(aNode) {
+ return (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
+ aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT);
+ },
+
+ /**
+ * Determines whether or not a ResultNode represents a bookmarked URI.
+ * @param aNode
+ * A result node
+ * @returns true if the node represents a bookmarked URI, false otherwise
+ */
+ nodeIsBookmark: function PU_nodeIsBookmark(aNode) {
+ return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_URI &&
+ aNode.itemId != -1;
+ },
+
+ /**
+ * Determines whether or not a ResultNode is a Bookmark separator.
+ * @param aNode
+ * A result node
+ * @returns true if the node is a Bookmark separator, false otherwise
+ */
+ nodeIsSeparator: function PU_nodeIsSeparator(aNode) {
+
+ return (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR);
+ },
+
+ /**
+ * Determines whether or not a ResultNode is a visit item.
+ * @param aNode
+ * A result node
+ * @returns true if the node is a visit item, false otherwise
+ */
+ nodeIsVisit: function PU_nodeIsVisit(aNode) {
+ var type = aNode.type;
+ return type == Ci.nsINavHistoryResultNode.RESULT_TYPE_VISIT ||
+ type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FULL_VISIT;
+ },
+
+ /**
+ * Determines whether or not a ResultNode is a URL item.
+ * @param aNode
+ * A result node
+ * @returns true if the node is a URL item, false otherwise
+ */
+ uriTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_URI,
+ Ci.nsINavHistoryResultNode.RESULT_TYPE_VISIT,
+ Ci.nsINavHistoryResultNode.RESULT_TYPE_FULL_VISIT],
+ nodeIsURI: function PU_nodeIsURI(aNode) {
+ return this.uriTypes.indexOf(aNode.type) != -1;
+ },
+
+ /**
+ * Determines whether or not a ResultNode is a Query item.
+ * @param aNode
+ * A result node
+ * @returns true if the node is a Query item, false otherwise
+ */
+ nodeIsQuery: function PU_nodeIsQuery(aNode) {
+ return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY;
+ },
+
+ /**
+ * Determines if a node is read only (children cannot be inserted, sometimes
+ * they cannot be removed depending on the circumstance)
+ * @param aNode
+ * A result node
+ * @returns true if the node is readonly, false otherwise
+ */
+ nodeIsReadOnly: function PU_nodeIsReadOnly(aNode) {
+ if (this.nodeIsFolder(aNode) || this.nodeIsDynamicContainer(aNode))
+ return this.bookmarks.getFolderReadonly(this.getConcreteItemId(aNode));
+ if (this.nodeIsQuery(aNode) &&
+ asQuery(aNode).queryOptions.resultType !=
+ Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_CONTENTS)
+ return aNode.childrenReadOnly;
+ return false;
+ },
+
+ /**
+ * Determines whether or not a ResultNode is a host container.
+ * @param aNode
+ * A result node
+ * @returns true if the node is a host container, false otherwise
+ */
+ nodeIsHost: function PU_nodeIsHost(aNode) {
+ return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
+ aNode.parent &&
+ asQuery(aNode.parent).queryOptions.resultType ==
+ Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY;
+ },
+
+ /**
+ * Determines whether or not a ResultNode is a day container.
+ * @param node
+ * A NavHistoryResultNode
+ * @returns true if the node is a day container, false otherwise
+ */
+ nodeIsDay: function PU_nodeIsDay(aNode) {
+ var resultType;
+ return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
+ aNode.parent &&
+ ((resultType = asQuery(aNode.parent).queryOptions.resultType) ==
+ Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY ||
+ resultType == Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY);
+ },
+
+ /**
+ * Determines whether or not a result-node is a tag container.
+ * @param aNode
+ * A result-node
+ * @returns true if the node is a tag container, false otherwise
+ */
+ nodeIsTagQuery: function PU_nodeIsTagQuery(aNode) {
+ return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
+ asQuery(aNode).queryOptions.resultType ==
+ Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_CONTENTS;
+ },
+
+ /**
+ * Determines whether or not a ResultNode is a container.
+ * @param aNode
+ * A result node
+ * @returns true if the node is a container item, false otherwise
+ */
+ containerTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER,
+ Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT,
+ Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY,
+ Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER],
+ nodeIsContainer: function PU_nodeIsContainer(aNode) {
+ return this.containerTypes.indexOf(aNode.type) != -1;
+ },
+
+ /**
+ * Determines whether or not a ResultNode is an history related container.
+ * @param node
+ * A result node
+ * @returns true if the node is an history related container, false otherwise
+ */
+ nodeIsHistoryContainer: function PU_nodeIsHistoryContainer(aNode) {
+ var resultType;
+ return this.nodeIsQuery(aNode) &&
+ ((resultType = asQuery(aNode).queryOptions.resultType) ==
+ Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY ||
+ resultType == Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY ||
+ resultType == Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY ||
+ this.nodeIsDay(aNode) ||
+ this.nodeIsHost(aNode));
+ },
+
+ /**
+ * Determines whether or not a result-node is a dynamic-container item.
+ * The dynamic container result node type is for dynamically created
+ * containers (e.g. for the file browser service where you get your folders
+ * in bookmark menus).
+ * @param aNode
+ * A result node
+ * @returns true if the node is a dynamic container item, false otherwise
+ */
+ nodeIsDynamicContainer: function PU_nodeIsDynamicContainer(aNode) {
+ if (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER)
+ return true;
+ return false;
+ },
+
+ /**
+ * Determines whether a result node is a remote container registered by the
+ * livemark service.
+ * @param aNode
+ * A result Node
+ * @returns true if the node is a livemark container item
+ */
+ nodeIsLivemarkContainer: function PU_nodeIsLivemarkContainer(aNode) {
+ // Use the annotations service directly to avoid instantiating
+ // the Livemark service on startup. (bug 398300)
+ return this.nodeIsFolder(aNode) &&
+ this.annotations.itemHasAnnotation(aNode.itemId, LMANNO_FEEDURI);
+ },
+
+ /**
+ * Determines whether a result node is a live-bookmark item
+ * @param aNode
+ * A result node
+ * @returns true if the node is a livemark container item
+ */
+ nodeIsLivemarkItem: function PU_nodeIsLivemarkItem(aNode) {
+ return aNode.parent && this.nodeIsLivemarkContainer(aNode.parent);
+ },
+
+ /**
+ * Determines whether or not a node is a readonly folder.
+ * @param aNode
+ * The node to test.
+ * @returns true if the node is a readonly folder.
+ */
+ isReadonlyFolder: function(aNode) {
+ return this.nodeIsFolder(aNode) &&
+ this.bookmarks.getFolderReadonly(asQuery(aNode).folderItemId);
+ },
+
+ /**
+ * Gets the concrete item-id for the given node. Generally, this is just
+ * node.itemId, but for folder-shortcuts that's node.folderItemId.
+ */
+ getConcreteItemId: function PU_getConcreteItemId(aNode) {
+ if (aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT)
+ return asQuery(aNode).folderItemId;
+ else if (PlacesUtils.nodeIsTagQuery(aNode)) {
+ // RESULTS_AS_TAG_CONTENTS queries are similar to folder shortcuts
+ // so we can still get the concrete itemId for them.
+ var queries = aNode.getQueries({});
+ var folders = queries[0].getFolders({});
+ return folders[0];
+ }
+ return aNode.itemId;
+ },
+
+ /**
+ * Gets the index of a node within its parent container
+ * @param aNode
+ * The node to look up
+ * @returns The index of the node within its parent container, or -1 if the
+ * node was not found or the node specified has no parent.
+ */
+ getIndexOfNode: function PU_getIndexOfNode(aNode) {
+ var parent = aNode.parent;
+ if (!parent)
+ return -1;
+ var wasOpen = parent.containerOpen;
+ var result, oldViewer;
+ if (!wasOpen) {
+ result = parent.parentResult;
+ oldViewer = result.viewer;
+ result.viewer = null;
+ parent.containerOpen = true;
+ }
+ var cc = parent.childCount;
+ for (var i = 0; i < cc && parent.getChild(i) != aNode; ++i);
+ if (!wasOpen) {
+ parent.containerOpen = false;
+ result.viewer = oldViewer;
+ }
+ return i < cc ? i : -1;
+ },
+
+ /**
+ * String-wraps a result node according to the rules of the specified
+ * content type.
+ * @param aNode
+ * The Result node to wrap (serialize)
+ * @param aType
+ * The content type to serialize as
+ * @param [optional] aOverrideURI
+ * Used instead of the node's URI if provided.
+ * This is useful for wrapping a container as TYPE_X_MOZ_URL,
+ * TYPE_HTML or TYPE_UNICODE.
+ * @param aForceCopy
+ * Does a full copy, resolving folder shortcuts.
+ * @returns A string serialization of the node
+ */
+ wrapNode: function PU_wrapNode(aNode, aType, aOverrideURI, aForceCopy) {
+ var self = this;
+
+ // when wrapping a node, we want all the items, even if the original
+ // query options are excluding them.
+ // this can happen when copying from the left hand pane of the bookmarks
+ // organizer
+ function convertNode(cNode) {
+ if (self.nodeIsFolder(cNode) && asQuery(cNode).queryOptions.excludeItems) {
+ var concreteId = self.getConcreteItemId(cNode);
+ return self.getFolderContents(concreteId, false, true).root;
+ }
+ return cNode;
+ }
+
+ switch (aType) {
+ case this.TYPE_X_MOZ_PLACE:
+ case this.TYPE_X_MOZ_PLACE_SEPARATOR:
+ case this.TYPE_X_MOZ_PLACE_CONTAINER:
+ var writer = {
+ value: "",
+ write: function PU_wrapNode__write(aStr, aLen) {
+ this.value += aStr;
+ }
+ };
+ self.serializeNodeAsJSONToOutputStream(convertNode(aNode), writer, true, aForceCopy);
+ return writer.value;
+ case this.TYPE_X_MOZ_URL:
+ function gatherDataUrl(bNode) {
+ if (self.nodeIsLivemarkContainer(bNode)) {
+ var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
+ return siteURI + NEWLINE + bNode.title;
+ }
+ if (self.nodeIsURI(bNode))
+ return (aOverrideURI || bNode.uri) + NEWLINE + bNode.title;
+ // ignore containers and separators - items without valid URIs
+ return "";
+ }
+ return gatherDataUrl(convertNode(aNode));
+
+ case this.TYPE_HTML:
+ function gatherDataHtml(bNode) {
+ function htmlEscape(s) {
+ s = s.replace(/&/g, "&amp;");
+ s = s.replace(/>/g, "&gt;");
+ s = s.replace(/</g, "&lt;");
+ s = s.replace(/"/g, "&quot;");
+ s = s.replace(/'/g, "&apos;");
+ return s;
+ }
+ // escape out potential HTML in the title
+ var escapedTitle = bNode.title ? htmlEscape(bNode.title) : "";
+ if (self.nodeIsLivemarkContainer(bNode)) {
+ var siteURI = self.livemarks.getSiteURI(bNode.itemId).spec;
+ return "<A HREF=\"" + siteURI + "\">" + escapedTitle + "</A>" + NEWLINE;
+ }
+ if (self.nodeIsContainer(bNode)) {
+ asContainer(bNode);
+ var wasOpen = bNode.containerOpen;
+ if (!wasOpen)
+ bNode.containerOpen = true;
+
+ var childString = "<DL><DT>" + escapedTitle + "</DT>" + NEWLINE;
+ var cc = bNode.childCount;
+ for (var i = 0; i < cc; ++i)
+ childString += "<DD>"
+ + NEWLINE
+ + gatherDataHtml(bNode.getChild(i))
+ + "</DD>"
+ + NEWLINE;
+ bNode.containerOpen = wasOpen;
+ return childString + "</DL>" + NEWLINE;
+ }
+ if (self.nodeIsURI(bNode))
+ return "<A HREF=\"" + bNode.uri + "\">" + escapedTitle + "</A>" + NEWLINE;
+ if (self.nodeIsSeparator(bNode))
+ return "<HR>" + NEWLINE;
+ return "";
+ }
+ return gatherDataHtml(convertNode(aNode));
+ }
+ // case this.TYPE_UNICODE:
+ function gatherDataText(bNode) {
+ if (self.nodeIsLivemarkContainer(bNode))
+ return self.livemarks.getSiteURI(bNode.itemId).spec;
+ if (self.nodeIsContainer(bNode)) {
+ asContainer(bNode);
+ var wasOpen = bNode.containerOpen;
+ if (!wasOpen)
+ bNode.containerOpen = true;
+
+ var childString = bNode.title + NEWLINE;
+ var cc = bNode.childCount;
+ for (var i = 0; i < cc; ++i) {
+ var child = bNode.getChild(i);
+ var suffix = i < (cc - 1) ? NEWLINE : "";
+ childString += gatherDataText(child) + suffix;
+ }
+ bNode.containerOpen = wasOpen;
+ return childString;
+ }
+ if (self.nodeIsURI(bNode))
+ return (aOverrideURI || bNode.uri);
+ if (self.nodeIsSeparator(bNode))
+ return "--------------------";
+ return "";
+ }
+
+ return gatherDataText(convertNode(aNode));
+ },
+
+ /**
+ * Unwraps data from the Clipboard or the current Drag Session.
+ * @param blob
+ * A blob (string) of data, in some format we potentially know how
+ * to parse.
+ * @param type
+ * The content type of the blob.
+ * @returns An array of objects representing each item contained by the source.
+ */
+ unwrapNodes: function PU_unwrapNodes(blob, type) {
+ // We split on "\n" because the transferable system converts "\r\n" to "\n"
+ var nodes = [];
+ switch(type) {
+ case this.TYPE_X_MOZ_PLACE:
+ case this.TYPE_X_MOZ_PLACE_SEPARATOR:
+ case this.TYPE_X_MOZ_PLACE_CONTAINER:
+ var JSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
+ nodes = JSON.decode("[" + blob + "]");
+ break;
+ case this.TYPE_X_MOZ_URL:
+ var parts = blob.split("\n");
+ // data in this type has 2 parts per entry, so if there are fewer
+ // than 2 parts left, the blob is malformed and we should stop
+ // but drag and drop of files from the shell has parts.length = 1
+ if (parts.length != 1 && parts.length % 2)
+ break;
+ for (var i = 0; i < parts.length; i=i+2) {
+ var uriString = parts[i];
+ var titleString = "";
+ if (parts.length > i+1)
+ titleString = parts[i+1];
+ else {
+ // for drag and drop of files, try to use the leafName as title
+ try {
+ titleString = this._uri(uriString).QueryInterface(Ci.nsIURL)
+ .fileName;
+ }
+ catch (e) {}
+ }
+ // note: this._uri() will throw if uriString is not a valid URI
+ if (this._uri(uriString)) {
+ nodes.push({ uri: uriString,
+ title: titleString ? titleString : uriString ,
+ type: this.TYPE_X_MOZ_URL });
+ }
+ }
+ break;
+ case this.TYPE_UNICODE:
+ var parts = blob.split("\n");
+ for (var i = 0; i < parts.length; i++) {
+ var uriString = parts[i];
+ // text/uri-list is converted to TYPE_UNICODE but it could contain
+ // comments line prepended by #, we should skip them
+ if (uriString.substr(0, 1) == '\x23')
+ continue;
+ // note: this._uri() will throw if uriString is not a valid URI
+ if (uriString != "" && this._uri(uriString))
+ nodes.push({ uri: uriString,
+ title: uriString,
+ type: this.TYPE_X_MOZ_URL });
+ }
+ break;
+ default:
+ LOG("Cannot unwrap data of type " + type);
+ throw Cr.NS_ERROR_INVALID_ARG;
+ }
+ return nodes;
+ },
+
+ /**
+ * Generates a nsINavHistoryResult for the contents of a folder.
+ * @param folderId
+ * The folder to open
+ * @param [optional] excludeItems
+ * True to hide all items (individual bookmarks). This is used on
+ * the left places pane so you just get a folder hierarchy.
+ * @param [optional] expandQueries
+ * True to make query items expand as new containers. For managing,
+ * you want this to be false, for menus and such, you want this to
+ * be true.
+ * @returns A nsINavHistoryResult containing the contents of the
+ * folder. The result.root is guaranteed to be open.
+ */
+ getFolderContents:
+ function PU_getFolderContents(aFolderId, aExcludeItems, aExpandQueries) {
+ var query = this.history.getNewQuery();
+ query.setFolders([aFolderId], 1);
+ var options = this.history.getNewQueryOptions();
+ options.excludeItems = aExcludeItems;
+ options.expandQueries = aExpandQueries;
+
+ var result = this.history.executeQuery(query, options);
+ result.root.containerOpen = true;
+ return result;
+ },
+
+ /**
+ * Fetch all annotations for a URI, including all properties of each
+ * annotation which would be required to recreate it.
+ * @param aURI
+ * The URI for which annotations are to be retrieved.
+ * @return Array of objects, each containing the following properties:
+ * name, flags, expires, mimeType, type, value
+ */
+ getAnnotationsForURI: function PU_getAnnotationsForURI(aURI) {
+ var annosvc = this.annotations;
+ var annos = [], val = null;
+ var annoNames = annosvc.getPageAnnotationNames(aURI, {});
+ for (var i = 0; i < annoNames.length; i++) {
+ var flags = {}, exp = {}, mimeType = {}, storageType = {};
+ annosvc.getPageAnnotationInfo(aURI, annoNames[i], flags, exp, mimeType, storageType);
+ if (storageType.value == annosvc.TYPE_BINARY) {
+ var data = {}, length = {}, mimeType = {};
+ annosvc.getPageAnnotationBinary(aURI, annoNames[i], data, length, mimeType);
+ val = data.value;
+ }
+ else
+ val = annosvc.getPageAnnotation(aURI, annoNames[i]);
+
+ annos.push({name: annoNames[i],
+ flags: flags.value,
+ expires: exp.value,
+ mimeType: mimeType.value,
+ type: storageType.value,
+ value: val});
+ }
+ return annos;
+ },
+
+ /**
+ * Fetch all annotations for an item, including all properties of each
+ * annotation which would be required to recreate it.
+ * @param aItemId
+ * The identifier of the itme for which annotations are to be
+ * retrieved.
+ * @return Array of objects, each containing the following properties:
+ * name, flags, expires, mimeType, type, value
+ */
+ getAnnotationsForItem: function PU_getAnnotationsForItem(aItemId) {
+ var annosvc = this.annotations;
+ var annos = [], val = null;
+ var annoNames = annosvc.getItemAnnotationNames(aItemId, {});
+ for (var i = 0; i < annoNames.length; i++) {
+ var flags = {}, exp = {}, mimeType = {}, storageType = {};
+ annosvc.getItemAnnotationInfo(aItemId, annoNames[i], flags, exp, mimeType, storageType);
+ if (storageType.value == annosvc.TYPE_BINARY) {
+ var data = {}, length = {}, mimeType = {};
+ annosvc.geItemAnnotationBinary(aItemId, annoNames[i], data, length, mimeType);
+ val = data.value;
+ }
+ else
+ val = annosvc.getItemAnnotation(aItemId, annoNames[i]);
+
+ annos.push({name: annoNames[i],
+ flags: flags.value,
+ expires: exp.value,
+ mimeType: mimeType.value,
+ type: storageType.value,
+ value: val});
+ }
+ return annos;
+ },
+
+ /**
+ * Annotate a URI with a batch of annotations.
+ * @param aURI
+ * The URI for which annotations are to be set.
+ * @param aAnnotations
+ * Array of objects, each containing the following properties:
+ * name, flags, expires, type, mimeType (only used for binary
+ * annotations) value.
+ * If the value for an annotation is not set it will be removed.
+ */
+ setAnnotationsForURI: function PU_setAnnotationsForURI(aURI, aAnnos) {
+ var annosvc = this.annotations;
+ aAnnos.forEach(function(anno) {
+ if (!anno.value) {
+ annosvc.removePageAnnotation(aURI, anno.name);
+ return;
+ }
+ var flags = ("flags" in anno) ? anno.flags : 0;
+ var expires = ("expires" in anno) ?
+ anno.expires : Ci.nsIAnnotationService.EXPIRE_NEVER;
+ if (anno.type == annosvc.TYPE_BINARY) {
+ annosvc.setPageAnnotationBinary(aURI, anno.name, anno.value,
+ anno.value.length, anno.mimeType,
+ flags, expires);
+ }
+ else
+ annosvc.setPageAnnotation(aURI, anno.name, anno.value, flags, expires);
+ });
+ },
+
+ /**
+ * Annotate an item with a batch of annotations.
+ * @param aItemId
+ * The identifier of the item for which annotations are to be set
+ * @param aAnnotations
+ * Array of objects, each containing the following properties:
+ * name, flags, expires, type, mimeType (only used for binary
+ * annotations) value.
+ * If the value for an annotation is not set it will be removed.
+ */
+ setAnnotationsForItem: function PU_setAnnotationsForItem(aItemId, aAnnos) {
+ var annosvc = this.annotations;
+
+ aAnnos.forEach(function(anno) {
+ if (!anno.value) {
+ annosvc.removeItemAnnotation(aItemId, anno.name);
+ return;
+ }
+ var flags = ("flags" in anno) ? anno.flags : 0;
+ var expires = ("expires" in anno) ?
+ anno.expires : Ci.nsIAnnotationService.EXPIRE_NEVER;
+ if (anno.type == annosvc.TYPE_BINARY) {
+ annosvc.setItemAnnotationBinary(aItemId, anno.name, anno.value,
+ anno.value.length, anno.mimeType,
+ flags, expires);
+ }
+ else {
+ annosvc.setItemAnnotation(aItemId, anno.name, anno.value, flags,
+ expires);
+ }
+ });
+ },
+
+ // identifier getters for special folders
+ get placesRootId() {
+ delete this.placesRootId;
+ return this.placesRootId = this.bookmarks.placesRoot;
+ },
+
+ get bookmarksMenuFolderId() {
+ delete this.bookmarksMenuFolderId;
+ return this.bookmarksMenuFolderId = this.bookmarks.bookmarksMenuFolder;
+ },
+
+ get toolbarFolderId() {
+ delete this.toolbarFolderId;
+ return this.toolbarFolderId = this.bookmarks.toolbarFolder;
+ },
+
+ get tagsFolderId() {
+ delete this.tagsFolderId;
+ return this.tagsFolderId = this.bookmarks.tagsFolder;
+ },
+
+ get unfiledBookmarksFolderId() {
+ delete this.unfiledBookmarksFolderId;
+ return this.unfiledBookmarksFolderId = this.bookmarks.unfiledBookmarksFolder;
+ },
+
+ /**
+ * Checks if aItemId is a root.
+ *
+ * @param aItemId
+ * item id to look for.
+ * @returns true if aItemId is a root, false otherwise.
+ */
+ isRootItem: function PU_isRootItem(aItemId) {
+ return aItemId == PlacesUtils.bookmarksMenuFolderId ||
+ aItemId == PlacesUtils.toolbarFolderId ||
+ aItemId == PlacesUtils.unfiledBookmarksFolderId ||
+ aItemId == PlacesUtils.tagsFolderId ||
+ aItemId == PlacesUtils.placesRootId;
+ },
+
+ /**
+ * Set the POST data associated with a bookmark, if any.
+ * Used by POST keywords.
+ * @param aBookmarkId
+ * @returns string of POST data
+ */
+ setPostDataForBookmark: function PU_setPostDataForBookmark(aBookmarkId, aPostData) {
+ const annos = this.annotations;
+ if (aPostData)
+ annos.setItemAnnotation(aBookmarkId, POST_DATA_ANNO, aPostData,
+ 0, Ci.nsIAnnotationService.EXPIRE_NEVER);
+ else if (annos.itemHasAnnotation(aBookmarkId, POST_DATA_ANNO))
+ annos.removeItemAnnotation(aBookmarkId, POST_DATA_ANNO);
+ },
+
+ /**
+ * Get the POST data associated with a bookmark, if any.
+ * @param aBookmarkId
+ * @returns string of POST data if set for aBookmarkId. null otherwise.
+ */
+ getPostDataForBookmark: function PU_getPostDataForBookmark(aBookmarkId) {
+ const annos = this.annotations;
+ if (annos.itemHasAnnotation(aBookmarkId, POST_DATA_ANNO))
+ return annos.getItemAnnotation(aBookmarkId, POST_DATA_ANNO);
+
+ return null;
+ },
+
+ /**
+ * Get the URI (and any associated POST data) for a given keyword.
+ * @param aKeyword string keyword
+ * @returns an array containing a string URL and a string of POST data
+ */
+ getURLAndPostDataForKeyword: function PU_getURLAndPostDataForKeyword(aKeyword) {
+ var url = null, postdata = null;
+ try {
+ var uri = this.bookmarks.getURIForKeyword(aKeyword);
+ if (uri) {
+ url = uri.spec;
+ var bookmarks = this.bookmarks.getBookmarkIdsForURI(uri, {});
+ for (let i = 0; i < bookmarks.length; i++) {
+ var bookmark = bookmarks[i];
+ var kw = this.bookmarks.getKeywordForBookmark(bookmark);
+ if (kw == aKeyword) {
+ postdata = this.getPostDataForBookmark(bookmark);
+ break;
+ }
+ }
+ }
+ } catch(ex) {}
+ return [url, postdata];
+ },
+
+ /**
+ * Get all bookmarks for a URL, excluding items under tag or livemark
+ * containers.
+ */
+ getBookmarksForURI:
+ function PU_getBookmarksForURI(aURI) {
+ var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {});
+
+ // filter the ids list
+ return bmkIds.filter(function(aID) {
+ var parent = this.bookmarks.getFolderIdForItem(aID);
+ // Livemark child
+ if (this.annotations.itemHasAnnotation(parent, LMANNO_FEEDURI))
+ return false;
+ var grandparent = this.bookmarks.getFolderIdForItem(parent);
+ // item under a tag container
+ if (grandparent == this.tagsFolderId)
+ return false;
+ return true;
+ }, this);
+ },
+
+ /**
+ * Get the most recently added/modified bookmark for a URL, excluding items
+ * under tag or livemark containers. -1 is returned if no item is found.
+ */
+ getMostRecentBookmarkForURI:
+ function PU_getMostRecentBookmarkForURI(aURI) {
+ var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {});
+ for (var i = 0; i < bmkIds.length; i++) {
+ // Find the first folder which isn't a tag container
+ var bk = bmkIds[i];
+ var parent = this.bookmarks.getFolderIdForItem(bk);
+ if (parent == this.unfiledBookmarksFolderId)
+ return bk;
+
+ var grandparent = this.bookmarks.getFolderIdForItem(parent);
+ if (grandparent != this.tagsFolderId &&
+ !this.annotations.itemHasAnnotation(parent, LMANNO_FEEDURI))
+ return bk;
+ }
+ return -1;
+ },
+
+ getMostRecentFolderForFeedURI:
+ function PU_getMostRecentFolderForFeedURI(aURI) {
+ var feedSpec = aURI.spec
+ var annosvc = this.annotations;
+ var livemarks = annosvc.getItemsWithAnnotation(LMANNO_FEEDURI, {});
+ for (var i = 0; i < livemarks.length; i++) {
+ if (annosvc.getItemAnnotation(livemarks[i], LMANNO_FEEDURI) == feedSpec)
+ return livemarks[i];
+ }
+ return -1;
+ },
+
+ /**
+ * Returns a nsNavHistoryContainerResultNode with forced excludeItems and
+ * expandQueries.
+ * @param aNode
+ * The node to convert
+ * @param [optional] excludeItems
+ * True to hide all items (individual bookmarks). This is used on
+ * the left places pane so you just get a folder hierarchy.
+ * @param [optional] expandQueries
+ * True to make query items expand as new containers. For managing,
+ * you want this to be false, for menus and such, you want this to
+ * be true.
+ * @returns A nsINavHistoryContainerResultNode containing the unfiltered
+ * contents of the container.
+ * @note The returned container node could be open or closed, we don't
+ * guarantee its status.
+ */
+ getContainerNodeWithOptions:
+ function PU_getContainerNodeWithOptions(aNode, aExcludeItems, aExpandQueries) {
+ if (!this.nodeIsContainer(aNode))
+ throw Cr.NS_ERROR_INVALID_ARG;
+
+ // excludeItems is inherited by child containers in an excludeItems view.
+ var excludeItems = asQuery(aNode).queryOptions.excludeItems ||
+ asQuery(aNode.parentResult.root).queryOptions.excludeItems;
+ // expandQueries is inherited by child containers in an expandQueries view.
+ var expandQueries = asQuery(aNode).queryOptions.expandQueries &&
+ asQuery(aNode.parentResult.root).queryOptions.expandQueries;
+
+ // If our options are exactly what we expect, directly return the node.
+ if (excludeItems == aExcludeItems && expandQueries == aExpandQueries)
+ return aNode;
+
+ // Otherwise, get contents manually.
+ var queries = {}, options = {};
+ this.history.queryStringToQueries(aNode.uri, queries, {}, options);
+ options.value.excludeItems = aExcludeItems;
+ options.value.expandQueries = aExpandQueries;
+ return this.history.executeQueries(queries.value,
+ queries.value.length,
+ options.value).root;
+ },
+
+ /**
+ * Returns true if a container has uri nodes in its first level.
+ * Has better performance than (getURLsForContainerNode(node).length > 0).
+ * @param aNode
+ * The container node to search through.
+ * @returns true if the node contains uri nodes, false otherwise.
+ */
+ hasChildURIs: function PU_hasChildURIs(aNode) {
+ if (!this.nodeIsContainer(aNode))
+ return false;
+
+ var root = this.getContainerNodeWithOptions(aNode, false, true);
+ var oldViewer = root.parentResult.viewer;
+ var wasOpen = root.containerOpen;
+ if (!wasOpen) {
+ root.parentResult.viewer = null;
+ root.containerOpen = true;
+ }
+
+ var found = false;
+ for (var i = 0; i < root.childCount && !found; i++) {
+ var child = root.getChild(i);
+ if (this.nodeIsURI(child))
+ found = true;
+ }
+
+ if (!wasOpen) {
+ root.containerOpen = false;
+ root.parentResult.viewer = oldViewer;
+ }
+ return found;
+ },
+
+ /**
+ * Returns an array containing all the uris in the first level of the
+ * passed in container.
+ * If you only need to know if the node contains uris, use hasChildURIs.
+ * @param aNode
+ * The container node to search through
+ * @returns array of uris in the first level of the container.
+ */
+ getURLsForContainerNode: function PU_getURLsForContainerNode(aNode) {
+ var urls = [];
+ if (!this.nodeIsContainer(aNode))
+ return urls;
+
+ var root = this.getContainerNodeWithOptions(aNode, false, true);
+ var oldViewer = root.parentResult.viewer;
+ var wasOpen = root.containerOpen;
+ if (!wasOpen) {
+ root.parentResult.viewer = null;
+ root.containerOpen = true;
+ }
+
+ for (var i = 0; i < root.childCount; ++i) {
+ var child = root.getChild(i);
+ if (this.nodeIsURI(child))
+ urls.push({uri: child.uri, isBookmark: this.nodeIsBookmark(child)});
+ }
+
+ if (!wasOpen) {
+ root.containerOpen = false;
+ root.parentResult.viewer = oldViewer;
+ }
+ return urls;
+ },
+
+ /**
+ * Restores bookmarks/tags from a JSON file.
+ * WARNING: This method *removes* any bookmarks in the collection before
+ * restoring from the file.
+ *
+ * @param aFile
+ * nsIFile of bookmarks in JSON format to be restored.
+ */
+ restoreBookmarksFromJSONFile:
+ function PU_restoreBookmarksFromJSONFile(aFile) {
+ var failed = false;
+ var obsServ = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ obsServ.notifyObservers(null,
+ RESTORE_BEGIN_NSIOBSERVER_TOPIC,
+ RESTORE_NSIOBSERVER_DATA);
+
+ try {
+ // open file stream
+ var stream = Cc["@mozilla.org/network/file-input-stream;1"].
+ createInstance(Ci.nsIFileInputStream);
+ stream.init(aFile, 0x01, 0, 0);
+ var converted = Cc["@mozilla.org/intl/converter-input-stream;1"].
+ createInstance(Ci.nsIConverterInputStream);
+ converted.init(stream, "UTF-8", 8192,
+ Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ // read in contents
+ var str = {};
+ var jsonStr = "";
+ while (converted.readString(8192, str) != 0)
+ jsonStr += str.value;
+ converted.close();
+
+ if (jsonStr.length == 0)
+ return; // empty file
+
+ this.restoreBookmarksFromJSONString(jsonStr, true);
+ }
+ catch (exc) {
+ failed = true;
+ obsServ.notifyObservers(null,
+ RESTORE_FAILED_NSIOBSERVER_TOPIC,
+ RESTORE_NSIOBSERVER_DATA);
+ Components.utils.reportError("Bookmarks JSON restore failed: " + exc);
+ throw exc;
+ }
+ finally {
+ if (!failed) {
+ obsServ.notifyObservers(null,
+ RESTORE_SUCCESS_NSIOBSERVER_TOPIC,
+ RESTORE_NSIOBSERVER_DATA);
+ }
+ }
+ },
+
+ /**
+ * Import bookmarks from a JSON string.
+ * Note: any item annotated with "places/excludeFromBackup" won't be removed
+ * before executing the restore.
+ *
+ * @param aString
+ * JSON string of serialized bookmark data.
+ * @param aReplace
+ * Boolean if true, replace existing bookmarks, else merge.
+ */
+ restoreBookmarksFromJSONString:
+ function PU_restoreBookmarksFromJSONString(aString, aReplace) {
+ // convert string to JSON
+ var nodes = this.unwrapNodes(aString, this.TYPE_X_MOZ_PLACE_CONTAINER);
+
+ if (nodes.length == 0 || !nodes[0].children ||
+ nodes[0].children.length == 0)
+ return; // nothing to restore
+
+ // ensure tag folder gets processed last
+ nodes[0].children.sort(function sortRoots(aNode, bNode) {
+ return (aNode.root && aNode.root == "tagsFolder") ? 1 :
+ (bNode.root && bNode.root == "tagsFolder") ? -1 : 0;
+ });
+
+ var batch = {
+ _utils: this,
+ nodes: nodes[0].children,
+ runBatched: function restore_runBatched() {
+ if (aReplace) {
+ // Get roots excluded from the backup, we will not remove them
+ // before restoring.
+ var excludeItems = this._utils.annotations
+ .getItemsWithAnnotation(EXCLUDE_FROM_BACKUP_ANNO, {});
+ // delete existing children of the root node, excepting:
+ // 1. special folders: delete the child nodes
+ // 2. tags folder: untag via the tagging api
+ var query = this._utils.history.getNewQuery();
+ query.setFolders([this._utils.placesRootId], 1);
+ var options = this._utils.history.getNewQueryOptions();
+ options.expandQueries = false;
+ var root = this._utils.history.executeQuery(query, options).root;
+ root.containerOpen = true;
+ var childIds = [];
+ for (var i = 0; i < root.childCount; i++) {
+ var childId = root.getChild(i).itemId;
+ if (excludeItems.indexOf(childId) == -1)
+ childIds.push(childId);
+ }
+ root.containerOpen = false;
+
+ for (var i = 0; i < childIds.length; i++) {
+ var rootItemId = childIds[i];
+ if (rootItemId == this._utils.tagsFolderId) {
+ // remove tags via the tagging service
+ var tags = this._utils.tagging.allTags;
+ var uris = [];
+ var bogusTagContainer = false;
+ for (let i in tags) {
+ var tagURIs = [];
+ // skip empty tags since getURIsForTag would throw
+ if (tags[i])
+ tagURIs = this._utils.tagging.getURIsForTag(tags[i]);
+
+ if (!tagURIs.length) {
+ // This is a bogus tag container, empty tags should be removed
+ // automatically, but this does not work if they contain some
+ // not-uri node, so we remove them manually.
+ // XXX this is a temporary workaround until we implement
+ // preventive database maintenance in bug 431558.
+ bogusTagContainer = true;
+ }
+ for (let j in tagURIs)
+ this._utils.tagging.untagURI(tagURIs[j], [tags[i]]);
+ }
+ if (bogusTagContainer)
+ this._utils.bookmarks.removeFolderChildren(rootItemId);
+ }
+ else if ([this._utils.toolbarFolderId,
+ this._utils.unfiledBookmarksFolderId,
+ this._utils.bookmarksMenuFolderId].indexOf(rootItemId) != -1)
+ this._utils.bookmarks.removeFolderChildren(rootItemId);
+ else
+ this._utils.bookmarks.removeItem(rootItemId);
+ }
+ }
+
+ var searchIds = [];
+ var folderIdMap = [];
+
+ this.nodes.forEach(function(node) {
+ if (!node.children || node.children.length == 0)
+ return; // nothing to restore for this root
+
+ if (node.root) {
+ var container = this.placesRootId; // default to places root
+ switch (node.root) {
+ case "bookmarksMenuFolder":
+ container = this.bookmarksMenuFolderId;
+ break;
+ case "tagsFolder":
+ container = this.tagsFolderId;
+ break;
+ case "unfiledBookmarksFolder":
+ container = this.unfiledBookmarksFolderId;
+ break;
+ case "toolbarFolder":
+ container = this.toolbarFolderId;
+ break;
+ }
+
+ // insert the data into the db
+ node.children.forEach(function(child) {
+ var index = child.index;
+ var [folders, searches] = this.importJSONNode(child, container, index);
+ for (var i = 0; i < folders.length; i++) {
+ if (folders[i])
+ folderIdMap[i] = folders[i];
+ }
+ searchIds = searchIds.concat(searches);
+ }, this);
+ }
+ else
+ this.importJSONNode(node, this.placesRootId, node.index);
+
+ }, this._utils);
+
+ // fixup imported place: uris that contain folders
+ searchIds.forEach(function(aId) {
+ var oldURI = this.bookmarks.getBookmarkURI(aId);
+ var uri = this._fixupQuery(this.bookmarks.getBookmarkURI(aId),
+ folderIdMap);
+ if (!uri.equals(oldURI))
+ this.bookmarks.changeBookmarkURI(aId, uri);
+ }, this._utils);
+ }
+ };
+
+ this.bookmarks.runInBatchMode(batch, null);
+ },
+
+ /**
+ * Takes a JSON-serialized node and inserts it into the db.
+ *
+ * @param aData
+ * The unwrapped data blob of dropped or pasted data.
+ * @param aContainer
+ * The container the data was dropped or pasted into
+ * @param aIndex
+ * The index within the container the item was dropped or pasted at
+ * @returns an array containing of maps of old folder ids to new folder ids,
+ * and an array of saved search ids that need to be fixed up.
+ * eg: [[[oldFolder1, newFolder1]], [search1]]
+ */
+ importJSONNode: function PU_importJSONNode(aData, aContainer, aIndex) {
+ var folderIdMap = [];
+ var searchIds = [];
+ var id = -1;
+ switch (aData.type) {
+ case this.TYPE_X_MOZ_PLACE_CONTAINER:
+ if (aContainer == PlacesUtils.bookmarks.tagsFolder) {
+ // node is a tag
+ if (aData.children) {
+ aData.children.forEach(function(aChild) {
+ try {
+ this.tagging.tagURI(this._uri(aChild.uri), [aData.title]);
+ } catch (ex) {
+ // invalid tag child, skip it
+ }
+ }, this);
+ return [folderIdMap, searchIds];
+ }
+ }
+ else if (aData.livemark && aData.annos) {
+ // node is a livemark
+ var feedURI = null;
+ var siteURI = null;
+ aData.annos = aData.annos.filter(function(aAnno) {
+ switch (aAnno.name) {
+ case LMANNO_FEEDURI:
+ feedURI = this._uri(aAnno.value);
+ return false;
+ case LMANNO_SITEURI:
+ siteURI = this._uri(aAnno.value);
+ return false;
+ case LMANNO_EXPIRATION:
+ case LMANNO_LOADING:
+ case LMANNO_LOADFAILED:
+ return false;
+ default:
+ return true;
+ }
+ }, this);
+
+ if (feedURI) {
+ id = this.livemarks.createLivemarkFolderOnly(aContainer,
+ aData.title,
+ siteURI, feedURI,
+ aIndex);
+ }
+ }
+ else {
+ id = this.bookmarks.createFolder(aContainer, aData.title, aIndex);
+ folderIdMap[aData.id] = id;
+ // process children
+ if (aData.children) {
+ aData.children.forEach(function(aChild, aIndex) {
+ var [folders, searches] = this.importJSONNode(aChild, id, aIndex);
+ for (var i = 0; i < folders.length; i++) {
+ if (folders[i])
+ folderIdMap[i] = folders[i];
+ }
+ searchIds = searchIds.concat(searches);
+ }, this);
+ }
+ }
+ break;
+ case this.TYPE_X_MOZ_PLACE:
+ id = this.bookmarks.insertBookmark(aContainer, this._uri(aData.uri), aIndex, aData.title);
+ if (aData.keyword)
+ this.bookmarks.setKeywordForBookmark(id, aData.keyword);
+ if (aData.tags) {
+ var tags = aData.tags.split(", ");
+ if (tags.length)
+ this.tagging.tagURI(this._uri(aData.uri), tags);
+ }
+ if (aData.charset)
+ this.history.setCharsetForURI(this._uri(aData.uri), aData.charset);
+ if (aData.uri.substr(0, 6) == "place:")
+ searchIds.push(id);
+ break;
+ case this.TYPE_X_MOZ_PLACE_SEPARATOR:
+ id = this.bookmarks.insertSeparator(aContainer, aIndex);
+ break;
+ default:
+ // Unknown node type
+ }
+
+ // set generic properties, valid for all nodes
+ if (id != -1) {
+ if (aData.dateAdded)
+ this.bookmarks.setItemDateAdded(id, aData.dateAdded);
+ if (aData.lastModified)
+ this.bookmarks.setItemLastModified(id, aData.lastModified);
+ if (aData.annos && aData.annos.length)
+ this.setAnnotationsForItem(id, aData.annos);
+ }
+
+ return [folderIdMap, searchIds];
+ },
+
+ /**
+ * Replaces imported folder ids with their local counterparts in a place: URI.
+ *
+ * @param aURI
+ * A place: URI with folder ids.
+ * @param aFolderIdMap
+ * An array mapping old folder id to new folder ids.
+ * @returns the fixed up URI if all matched. If some matched, it returns
+ * the URI with only the matching folders included. If none matched it
+ * returns the input URI unchanged.
+ */
+ _fixupQuery: function PU__fixupQuery(aQueryURI, aFolderIdMap) {
+ function convert(str, p1, offset, s) {
+ return "folder=" + aFolderIdMap[p1];
+ }
+ var stringURI = aQueryURI.spec.replace(/folder=([0-9]+)/g, convert);
+ return this._uri(stringURI);
+ },
+
+ /**
+ * Serializes the given node (and all its descendents) as JSON
+ * and writes the serialization to the given output stream.
+ *
+ * @param aNode
+ * An nsINavHistoryResultNode
+ * @param aStream
+ * An nsIOutputStream. NOTE: it only uses the write(str, len)
+ * method of nsIOutputStream. The caller is responsible for
+ * closing the stream.
+ * @param aIsUICommand
+ * Boolean - If true, modifies serialization so that each node self-contained.
+ * For Example, tags are serialized inline with each bookmark.
+ * @param aResolveShortcuts
+ * Converts folder shortcuts into actual folders.
+ * @param aExcludeItems
+ * An array of item ids that should not be written to the backup.
+ */
+ serializeNodeAsJSONToOutputStream:
+ function PU_serializeNodeAsJSONToOutputStream(aNode, aStream, aIsUICommand,
+ aResolveShortcuts,
+ aExcludeItems) {
+ var self = this;
+
+ function addGenericProperties(aPlacesNode, aJSNode) {
+ aJSNode.title = aPlacesNode.title;
+ var id = aPlacesNode.itemId;
+ if (id != -1) {
+ aJSNode.id = id;
+
+ var parent = aPlacesNode.parent;
+ if (parent)
+ aJSNode.parent = parent.itemId;
+ var dateAdded = aPlacesNode.dateAdded;
+ if (dateAdded)
+ aJSNode.dateAdded = dateAdded;
+ var lastModified = aPlacesNode.lastModified;
+ if (lastModified)
+ aJSNode.lastModified = lastModified;
+
+ // XXX need a hasAnnos api
+ var annos = [];
+ try {
+ annos = self.getAnnotationsForItem(id).filter(function(anno) {
+ // XXX should whitelist this instead, w/ a pref for
+ // backup/restore of non-whitelisted annos
+ // XXX causes JSON encoding errors, so utf-8 encode
+ //anno.value = unescape(encodeURIComponent(anno.value));
+ if (anno.name == LMANNO_FEEDURI)
+ aJSNode.livemark = 1;
+ if (anno.name == READ_ONLY_ANNO && aResolveShortcuts) {
+ // When copying a read-only node, remove the read-only annotation.
+ return false;
+ }
+ return true;
+ });
+ } catch(ex) {
+ LOG(ex);
+ }
+ if (annos.length != 0)
+ aJSNode.annos = annos;
+ }
+ // XXXdietrich - store annos for non-bookmark items
+ }
+
+ function addURIProperties(aPlacesNode, aJSNode) {
+ aJSNode.type = self.TYPE_X_MOZ_PLACE;
+ aJSNode.uri = aPlacesNode.uri;
+ if (aJSNode.id && aJSNode.id != -1) {
+ // harvest bookmark-specific properties
+ var keyword = self.bookmarks.getKeywordForBookmark(aJSNode.id);
+ if (keyword)
+ aJSNode.keyword = keyword;
+ }
+
+ var tags = aIsUICommand ? aPlacesNode.tags : null;
+ if (tags)
+ aJSNode.tags = tags;
+
+ // last character-set
+ var uri = self._uri(aPlacesNode.uri);
+ var lastCharset = self.history.getCharsetForURI(uri);
+ if (lastCharset)
+ aJSNode.charset = lastCharset;
+ }
+
+ function addSeparatorProperties(aPlacesNode, aJSNode) {
+ aJSNode.type = self.TYPE_X_MOZ_PLACE_SEPARATOR;
+ }
+
+ function addContainerProperties(aPlacesNode, aJSNode) {
+ // saved queries
+ var concreteId = PlacesUtils.getConcreteItemId(aPlacesNode);
+ if (aJSNode.id != -1 && (PlacesUtils.nodeIsQuery(aPlacesNode) ||
+ (concreteId != aPlacesNode.itemId && !aResolveShortcuts))) {
+ aJSNode.type = self.TYPE_X_MOZ_PLACE;
+ aJSNode.uri = aPlacesNode.uri;
+ // folder shortcut
+ if (aIsUICommand)
+ aJSNode.concreteId = concreteId;
+ return;
+ }
+ else if (aJSNode.id != -1) { // bookmark folder
+ if (concreteId != aPlacesNode.itemId)
+ aJSNode.type = self.TYPE_X_MOZ_PLACE;
+ aJSNode.type = self.TYPE_X_MOZ_PLACE_CONTAINER;
+ // mark special folders
+ if (aJSNode.id == self.bookmarks.placesRoot)
+ aJSNode.root = "placesRoot";
+ else if (aJSNode.id == self.bookmarks.bookmarksMenuFolder)
+ aJSNode.root = "bookmarksMenuFolder";
+ else if (aJSNode.id == self.bookmarks.tagsFolder)
+ aJSNode.root = "tagsFolder";
+ else if (aJSNode.id == self.bookmarks.unfiledBookmarksFolder)
+ aJSNode.root = "unfiledBookmarksFolder";
+ else if (aJSNode.id == self.bookmarks.toolbarFolder)
+ aJSNode.root = "toolbarFolder";
+ }
+ }
+
+ function writeScalarNode(aStream, aNode) {
+ // serialize to json
+ var jstr = self.toJSONString(aNode);
+ // write to stream
+ aStream.write(jstr, jstr.length);
+ }
+
+ function writeComplexNode(aStream, aNode, aSourceNode) {
+ var escJSONStringRegExp = /(["\\])/g;
+ // write prefix
+ var properties = [];
+ for (let [name, value] in Iterator(aNode)) {
+ if (name == "annos")
+ value = self.toJSONString(value);
+ else if (typeof value == "string")
+ value = "\"" + value.replace(escJSONStringRegExp, '\\$1') + "\"";
+ properties.push("\"" + name.replace(escJSONStringRegExp, '\\$1') + "\":" + value);
+ }
+ var jStr = "{" + properties.join(",") + ",\"children\":[";
+ aStream.write(jStr, jStr.length);
+
+ // write child nodes
+ if (!aNode.livemark) {
+ asContainer(aSourceNode);
+ var wasOpen = aSourceNode.containerOpen;
+ if (!wasOpen)
+ aSourceNode.containerOpen = true;
+ var cc = aSourceNode.childCount;
+ for (var i = 0; i < cc; ++i) {
+ var childNode = aSourceNode.getChild(i);
+ if (aExcludeItems && aExcludeItems.indexOf(childNode.itemId) != -1)
+ continue;
+ var written = serializeNodeToJSONStream(aSourceNode.getChild(i), i);
+ if (written && i < cc - 1)
+ aStream.write(",", 1);
+ }
+ if (!wasOpen)
+ aSourceNode.containerOpen = false;
+ }
+
+ // write suffix
+ aStream.write("]}", 2);
+ }
+
+ function serializeNodeToJSONStream(bNode, aIndex) {
+ var node = {};
+
+ // set index in order received
+ // XXX handy shortcut, but are there cases where we don't want
+ // to export using the sorting provided by the query?
+ if (aIndex)
+ node.index = aIndex;
+
+ addGenericProperties(bNode, node);
+
+ var parent = bNode.parent;
+ var grandParent = parent ? parent.parent : null;
+
+ if (self.nodeIsURI(bNode)) {
+ // Tag root accept only folder nodes
+ if (parent && parent.itemId == self.tagsFolderId)
+ return false;
+ // Check for url validity, since we can't halt while writing a backup.
+ // This will throw if we try to serialize an invalid url and it does
+ // not make sense saving a wrong or corrupt uri node.
+ try {
+ self._uri(bNode.uri);
+ } catch (ex) {
+ return false;
+ }
+ addURIProperties(bNode, node);
+ }
+ else if (self.nodeIsContainer(bNode)) {
+ // Tag containers accept only uri nodes
+ if (grandParent && grandParent.itemId == self.tagsFolderId)
+ return false;
+ addContainerProperties(bNode, node);
+ }
+ else if (self.nodeIsSeparator(bNode)) {
+ // Tag root accept only folder nodes
+ // Tag containers accept only uri nodes
+ if ((parent && parent.itemId == self.tagsFolderId) ||
+ (grandParent && grandParent.itemId == self.tagsFolderId))
+ return false;
+
+ addSeparatorProperties(bNode, node);
+ }
+
+ if (!node.feedURI && node.type == self.TYPE_X_MOZ_PLACE_CONTAINER)
+ writeComplexNode(aStream, node, bNode);
+ else
+ writeScalarNode(aStream, node);
+ return true;
+ }
+
+ // serialize to stream
+ serializeNodeToJSONStream(aNode, null);
+ },
+
+ /**
+ * Serialize a JS object to JSON
+ */
+ toJSONString: function PU_toJSONString(aObj) {
+ var JSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
+ return JSON.encode(aObj);
+ },
+
+ /**
+ * backupBookmarksToFile()
+ *
+ * Serializes bookmarks using JSON, and writes to the supplied file.
+ * Note: any item that should not be backed up must be annotated with
+ * "places/excludeFromBackup".
+ *
+ * @param aFile
+ * nsIFile where to save JSON backup.
+ */
+ backupBookmarksToFile: function PU_backupBookmarksToFile(aFile) {
+ if (aFile.exists() && !aFile.isWritable())
+ return; // XXX
+
+ // init stream
+ var stream = Cc["@mozilla.org/network/file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ stream.init(aFile, 0x02 | 0x08 | 0x20, 0600, 0);
+
+ // utf-8 converter stream
+ var converter = Cc["@mozilla.org/intl/converter-output-stream;1"].
+ createInstance(Ci.nsIConverterOutputStream);
+ converter.init(stream, "UTF-8", 0, 0x0000);
+
+ // weep over stream interface variance
+ var streamProxy = {
+ converter: converter,
+ write: function(aData, aLen) {
+ this.converter.writeString(aData);
+ }
+ };
+
+ // Get itemIds to be exluded from the backup
+ var excludeItems = this.annotations
+ .getItemsWithAnnotation(EXCLUDE_FROM_BACKUP_ANNO, {});
+
+ // query places root
+ var options = this.history.getNewQueryOptions();
+ options.expandQueries = false;
+ var query = this.history.getNewQuery();
+ query.setFolders([this.bookmarks.placesRoot], 1);
+ var result = this.history.executeQuery(query, options);
+ result.root.containerOpen = true;
+ // serialize as JSON, write to stream
+ this.serializeNodeAsJSONToOutputStream(result.root, streamProxy,
+ false, false, excludeItems);
+ result.root.containerOpen = false;
+
+ // close converter and stream
+ converter.close();
+ stream.close();
+ },
+
+ /**
+ * Creates a filename for bookmarks backup files.
+ *
+ * @param [optional] aDateObj Date object used to build the filename.
+ * Will use current date if empty.
+ * @return A bookmarks backup filename.
+ */
+ getBackupFilename:
+ function PU_getBackupFilename(aDateObj) {
+ if (!aDateObj)
+ aDateObj = new Date();
+ // Use YYYY-MM-DD (ISO 8601) as it doesn't contain illegal characters
+ // and makes the alphabetical order of multiple backup files more useful.
+ var date = aDateObj.toLocaleFormat("%Y-%m-%d");
+ return "bookmarks-" + date + ".json";
+ },
+
+ /**
+ * ArchiveBookmarksFile()
+ *
+ * Creates a dated backup once a day in <profile>/bookmarkbackups.
+ * Stores the bookmarks using JSON.
+ * Note: any item that should not be backed up must be annotated with
+ * "places/excludeFromBackup".
+ *
+ * @param int aNumberOfBackups - the maximum number of backups to keep
+ *
+ * @param bool aForceArchive - forces creating an archive even if one was
+ * already created that day (overwrites)
+ */
+ archiveBookmarksFile:
+ function PU_archiveBookmarksFile(aNumberOfBackups, aForceArchive) {
+ // get/create backups directory
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ var bookmarksBackupDir = dirService.get("ProfD", Ci.nsILocalFile);
+ bookmarksBackupDir.append("bookmarkbackups");
+ if (!bookmarksBackupDir.exists()) {
+ bookmarksBackupDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0700);
+ if (!bookmarksBackupDir.exists())
+ return; // unable to create directory!
+ }
+
+ // Construct the new leafname.
+ var date = new Date();
+ var backupFilename = this.getBackupFilename(date);
+ var backupFile = null;
+ if (!aForceArchive) {
+ var backupFileNames = [];
+ var backupFilenamePrefix = backupFilename.substr(0, backupFilename.indexOf("-"));
+
+ // Get the localized backup filename, to clear out
+ // old backups with a localized name (bug 445704).
+ var localizedFilename = this.getFormattedString("bookmarksArchiveFilename", [date]);
+ var localizedFilenamePrefix = localizedFilename.substr(0, localizedFilename.indexOf("-"));
+ var rx = new RegExp("^(bookmarks|" + localizedFilenamePrefix + ")-([0-9-]+)\.(json|html)");
+
+ var entries = bookmarksBackupDir.directoryEntries;
+ while (entries.hasMoreElements()) {
+ var entry = entries.getNext().QueryInterface(Ci.nsIFile);
+ var backupName = entry.leafName;
+ // A valid backup is any file that matches either the localized or
+ // not-localized filename (bug 445704).
+ var matches = backupName.match(rx);
+ if (matches) {
+ if (backupName == backupFilename)
+ backupFile = entry;
+ backupFileNames.push({ filename: backupName, date: matches[2] });
+ }
+ }
+
+ var numberOfBackupsToDelete = 0;
+ if (aNumberOfBackups > -1)
+ numberOfBackupsToDelete = backupFileNames.length - aNumberOfBackups;
+
+ if (numberOfBackupsToDelete > 0) {
+ // If we don't have today's backup, remove one more so that
+ // the total backups after this operation does not exceed the
+ // number specified in the pref.
+ if (!backupFile)
+ numberOfBackupsToDelete++;
+ backupFileNames.sort(function compare(a, b) {
+ return a.date < b.date ? -1 : a.date > b.date ? 1 : 0;
+ });
+ while (numberOfBackupsToDelete--) {
+ let backupFile = bookmarksBackupDir.clone();
+ backupFile.append(backupFileNames[0].filename);
+ backupFile.remove(false);
+ backupFileNames.shift();
+ }
+ }
+
+ // do nothing if we either have today's backup already
+ // or the user has set the pref to zero.
+ if (backupFile || aNumberOfBackups == 0)
+ return;
+ }
+
+ backupFile = bookmarksBackupDir.clone();
+ backupFile.append(backupFilename);
+
+ if (aForceArchive && backupFile.exists())
+ backupFile.remove(false);
+
+ if (!backupFile.exists())
+ backupFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
+
+ this.backupBookmarksToFile(backupFile);
+ },
+
+ /**
+ * Get the most recent backup file.
+ * @returns nsIFile backup file
+ */
+ getMostRecentBackup: function PU_getMostRecentBackup() {
+ var dirService = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ var bookmarksBackupDir = dirService.get("ProfD", Ci.nsILocalFile);
+ bookmarksBackupDir.append("bookmarkbackups");
+ if (!bookmarksBackupDir.exists())
+ return null;
+
+ var backups = [];
+ var entries = bookmarksBackupDir.directoryEntries;
+ while (entries.hasMoreElements()) {
+ var entry = entries.getNext().QueryInterface(Ci.nsIFile);
+ if (!entry.isHidden() && entry.leafName.match(/^bookmarks-.+(html|json)?$/))
+ backups.push(entry.leafName);
+ }
+
+ if (backups.length == 0)
+ return null;
+
+ backups.sort();
+ var filename = backups.pop();
+
+ var backupFile = bookmarksBackupDir.clone();
+ backupFile.append(filename);
+ return backupFile;
+ },
+
+ /**
+ * Starts the database coherence check and executes update tasks on a timer,
+ * this method is called by browser.js in delayed startup.
+ */
+ startPlacesDBUtils: function PU_startPlacesDBUtils() {
+ Components.utils.import("resource://gre/modules/PlacesDBUtils.jsm");
+ }
+};
diff --git a/bundles/XO/mozilla-xremote-client b/bundles/XO/mozilla-xremote-client
new file mode 100755
index 0000000..b6f8c0b
--- /dev/null
+++ b/bundles/XO/mozilla-xremote-client
Binary files differ
diff --git a/bundles/XO/old-homepage-default.properties b/bundles/XO/old-homepage-default.properties
new file mode 100755
index 0000000..6bfa4c9
--- /dev/null
+++ b/bundles/XO/old-homepage-default.properties
@@ -0,0 +1 @@
+browser.startup.homepage=http://en-US.start.mozilla.com/firefox?client=firefox-a&rls=org.mozilla:en-US:official
diff --git a/bundles/XO/platform.ini b/bundles/XO/platform.ini
new file mode 100755
index 0000000..fabf597
--- /dev/null
+++ b/bundles/XO/platform.ini
@@ -0,0 +1,5 @@
+[Build]
+BuildID=20090824085743
+Milestone=1.9.1.3
+SourceStamp=0da982f65d37
+SourceRepository=http://hg.mozilla.org/releases/mozilla-1.9.1
diff --git a/bundles/XO/plugins/libnullplugin.so b/bundles/XO/plugins/libnullplugin.so
new file mode 100755
index 0000000..34b4350
--- /dev/null
+++ b/bundles/XO/plugins/libnullplugin.so
Binary files differ
diff --git a/bundles/XO/removed-files b/bundles/XO/removed-files
new file mode 100755
index 0000000..90ad051
--- /dev/null
+++ b/bundles/XO/removed-files
@@ -0,0 +1,531 @@
+chrome/US.jar
+chrome/en-win.jar
+chrome/help.jar
+chrome/chrome.rdf
+chrome/installed-chrome.txt
+chrome/app-chrome.manifest
+chrome/overlayinfo/
+chrome/m3ffxtbr.manifest
+chrome/m3ffxtbr.jar
+defaults/pref/all.js
+defaults/pref/security-prefs.js
+defaults/pref/winpref.js
+defaults/pref/xpinstall.js
+defaults/pref/bug307259.js
+defaults/pref/bug259708.js
+defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
+defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/
+defaults/profile/extensions/Extensions.rdf
+defaults/profile/extensions/installed-extensions.txt
+defaults/profile/extensions/
+defaults/profile/search.rdf
+defaults/profile/US/
+extensions/{641d8d09-7dda-4850-8228-ac0ab65e2ac9}/install.rdf
+extensions/{641d8d09-7dda-4850-8228-ac0ab65e2ac9}/
+searchplugins/dictionary.src
+searchplugins/dictionary.png
+searchplugins/amazondotcom.src
+searchplugins/amazondotcom.png
+searchplugins/creativecommons.src
+searchplugins/creativecommons.png
+searchplugins/answers.src
+searchplugins/answers.png
+searchplugins/eBay.src
+searchplugins/eBay.gif
+searchplugins/google.src
+searchplugins/google.gif
+searchplugins/yahoo.src
+searchplugins/yahoo.gif
+searchplugins/
+libxpcom_core.so
+components/libjar50.so
+components/libjsd.so
+components/libxpinstall.so
+libxpistub.so
+component.reg
+components/compreg.dat
+components/libmyspell.so
+components/libspellchecker.so
+components/libspellchk.so
+components/xpti.dat
+components/xptitemp.dat
+components/nsBackgroundUpdateService.js
+components/nsCloseAllWindows.js
+components/autocomplete.xpt
+libzlib.so
+components/BrandRes.dll
+components/fullsoft.dll
+components/master.ini
+components/qfaservices.dll
+components/qfaservices.xpt
+components/talkback-l10n.ini
+components/talkback.cnt
+components/talkback.exe
+components/talkback.hlp
+components/libqfaservices.so
+components/talkback/master.ini
+components/talkback/talkback
+components/talkback/talkback.so
+components/talkback/XTalkback.ad
+extensions/reporter@mozilla.org/install.rdf
+extensions/reporter@mozilla.org/chrome.manifest
+extensions/reporter@mozilla.org/chrome/reporter.jar
+extensions/reporter@mozilla.org/defaults/preferences/reporter.js
+extensions/inspector@mozilla.org/install.rdf
+extensions/inspector@mozilla.org/components/inspector-cmdline.js
+extensions/inspector@mozilla.org/chrome.manifest
+extensions/inspector@mozilla.org/chrome/inspector.jar
+extensions/inspector@mozilla.org/defaults/preferences/inspector.js
+extensions/inspector@mozilla.org/platform/WINNT/chrome/icons/default/winInspectorMain.ico
+extensions/inspector@mozilla.org/components/inspector.xpt
+extensions/inspector@mozilla.org/components/libinspector.so
+extensions/inspector@mozilla.org/chrome/icons/default/winInspectorMain.ico
+uninstall/UninstallFirefox.exe
+uninstall/UninstallDeerPark.exe
+uninstall/uninst.exe
+uninstall/uninstall.exe
+components/myspell/en-US.dic
+components/myspell/en-US.aff
+searchplugins/centrum-cz.xml
+searchplugins/eBay-fy-NL.xml
+searchplugins/eBay-nl.xml
+searchplugins/eBay-zh-CN.xml
+searchplugins/eBay-zh-TW.xml
+searchplugins/filesearchru.xml
+searchplugins/goo.xml
+searchplugins/google-ar.xml
+searchplugins/grandiccionari.xml
+searchplugins/lingvo.yandex.ru.xml
+searchplugins/nana.xml
+searchplugins/netex.xml
+searchplugins/nosaltres.xml
+searchplugins/pbi-pl.xml
+searchplugins/taobao.xml
+searchplugins/wikipedia-en-CN.xml
+searchplugins/wikipedia-zh.xml
+searchplugins/yahoo-jp-shopping.xml
+searchplugins/yahoo-ru.xml
+searchplugins/yahoo-zh-CN.xml
+searchplugins/DRAE.src
+searchplugins/DRAE.png
+searchplugins/DRAE.gif
+searchplugins/MediaDICO-fr.src
+searchplugins/MediaDICO-fr.png
+searchplugins/MediaDICO-fr.gif
+searchplugins/allegro-pl.src
+searchplugins/allegro-pl.png
+searchplugins/allegro-pl.gif
+searchplugins/amazon-de.src
+searchplugins/amazon-de.png
+searchplugins/amazon-de.gif
+searchplugins/amazon-en-GB.src
+searchplugins/amazon-en-GB.png
+searchplugins/amazon-en-GB.gif
+searchplugins/amazon-france.src
+searchplugins/amazon-france.png
+searchplugins/amazon-france.gif
+searchplugins/amazon-jp.src
+searchplugins/amazon-jp.png
+searchplugins/amazon-jp.gif
+searchplugins/amazondotcom.src
+searchplugins/amazondotcom.png
+searchplugins/amazondotcom.gif
+searchplugins/amazondotcom-zh-TW.src
+searchplugins/amazondotcom-zh-TW.png
+searchplugins/amazondotcom-zh-TW.gif
+searchplugins/answers.src
+searchplugins/answers.png
+searchplugins/answers.gif
+searchplugins/google-es-ES.src
+searchplugins/google-es-ES.png
+searchplugins/google-es-ES.gif
+searchplugins/atlas-sk.src
+searchplugins/atlas-sk.png
+searchplugins/atlas-sk.gif
+searchplugins/baidu.src
+searchplugins/baidu.png
+searchplugins/baidu.gif
+searchplugins/bok-NO.src
+searchplugins/bok-NO.png
+searchplugins/bok-NO.gif
+searchplugins/bolcom-nl.src
+searchplugins/bolcom-nl.png
+searchplugins/bolcom-nl.gif
+searchplugins/bookplus-fi.src
+searchplugins/bookplus-fi.png
+searchplugins/bookplus-fi.gif
+searchplugins/caplex-NO.src
+searchplugins/caplex-NO.png
+searchplugins/caplex-NO.gif
+searchplugins/centrum-cz.src
+searchplugins/centrum-cz.png
+searchplugins/centrum-cz.gif
+searchplugins/creativecommons.src
+searchplugins/creativecommons.png
+searchplugins/creativecommons.gif
+searchplugins/creativecommons-fi.src
+searchplugins/creativecommons-fi.png
+searchplugins/creativecommons-fi.gif
+searchplugins/creativecommons-it.src
+searchplugins/creativecommons-it.png
+searchplugins/creativecommons-it.gif
+searchplugins/creativecommons-zh-TW.src
+searchplugins/creativecommons-zh-TW.png
+searchplugins/creativecommons-zh-TW.gif
+searchplugins/daum-ko.src
+searchplugins/daum-ko.png
+searchplugins/daum-ko.gif
+searchplugins/demauro-it.src
+searchplugins/demauro-it.png
+searchplugins/demauro-it.gif
+searchplugins/dictionary-en-GB.src
+searchplugins/dictionary-en-GB.png
+searchplugins/dictionary-en-GB.gif
+searchplugins/dunaj-sk.src
+searchplugins/dunaj-sk.png
+searchplugins/dunaj-sk.gif
+searchplugins/eBay.src
+searchplugins/eBay.png
+searchplugins/eBay.gif
+searchplugins/eBay-de.src
+searchplugins/eBay-de.png
+searchplugins/eBay-de.gif
+searchplugins/eBay-en-GB.src
+searchplugins/eBay-en-GB.png
+searchplugins/eBay-en-GB.gif
+searchplugins/eBay-france.src
+searchplugins/eBay-france.png
+searchplugins/eBay-france.gif
+searchplugins/eBay-gu.src
+searchplugins/eBay-gu.png
+searchplugins/eBay-gu.gif
+searchplugins/eBay-nl.src
+searchplugins/eBay-nl.png
+searchplugins/eBay-nl.gif
+searchplugins/eBay-zh-CN.src
+searchplugins/eBay-zh-CN.png
+searchplugins/eBay-zh-CN.gif
+searchplugins/eBay-zh-TW.src
+searchplugins/eBay-zh-TW.png
+searchplugins/eBay-zh-TW.gif
+searchplugins/ebay-it.src
+searchplugins/ebay-it.png
+searchplugins/ebay-it.gif
+searchplugins/filesearchru.src
+searchplugins/filesearchru.png
+searchplugins/filesearchru.gif
+searchplugins/goo.src
+searchplugins/goo.png
+searchplugins/goo.gif
+searchplugins/google.src
+searchplugins/google.png
+searchplugins/google.gif
+searchplugins/google-NO.src
+searchplugins/google-NO.png
+searchplugins/google-NO.gif
+searchplugins/google-ar.src
+searchplugins/google-ar.png
+searchplugins/google-ar.gif
+searchplugins/google-bg.src
+searchplugins/google-bg.png
+searchplugins/google-bg.gif
+searchplugins/google-ca.src
+searchplugins/google-ca.png
+searchplugins/google-ca.gif
+searchplugins/google-de.src
+searchplugins/google-de.png
+searchplugins/google-de.gif
+searchplugins/google-dk.src
+searchplugins/google-dk.png
+searchplugins/google-dk.gif
+searchplugins/google-en-GB.src
+searchplugins/google-en-GB.png
+searchplugins/google-en-GB.gif
+searchplugins/google-eu.src
+searchplugins/google-eu.png
+searchplugins/google-eu.gif
+searchplugins/google-fi.src
+searchplugins/google-fi.png
+searchplugins/google-fi.gif
+searchplugins/google-gu.src
+searchplugins/google-gu.png
+searchplugins/google-gu.gif
+searchplugins/google-it.src
+searchplugins/google-it.png
+searchplugins/google-it.gif
+searchplugins/google-jp.src
+searchplugins/google-jp.png
+searchplugins/google-jp.gif
+searchplugins/google-ko.src
+searchplugins/google-ko.png
+searchplugins/google-ko.gif
+searchplugins/google-lt.src
+searchplugins/google-lt.png
+searchplugins/google-lt.gif
+searchplugins/google-nl.src
+searchplugins/google-nl.png
+searchplugins/google-nl.gif
+searchplugins/google-pl.src
+searchplugins/google-pl.png
+searchplugins/google-pl.gif
+searchplugins/google-ro.src
+searchplugins/google-ro.png
+searchplugins/google-ro.gif
+searchplugins/google-ru.src
+searchplugins/google-ru.png
+searchplugins/google-ru.gif
+searchplugins/google-sl.src
+searchplugins/google-sl.png
+searchplugins/google-sl.gif
+searchplugins/google-zh-TW.src
+searchplugins/google-zh-TW.png
+searchplugins/google-zh-TW.gif
+searchplugins/grandiccionari.src
+searchplugins/grandiccionari.png
+searchplugins/grandiccionari.gif
+searchplugins/huuto-fi.src
+searchplugins/huuto-fi.png
+searchplugins/huuto-fi.gif
+searchplugins/jyxo-cz.src
+searchplugins/jyxo-cz.png
+searchplugins/jyxo-cz.gif
+searchplugins/lingvo.yandex.ru.src
+searchplugins/lingvo.yandex.ru.png
+searchplugins/lingvo.yandex.ru.gif
+searchplugins/llibres.src
+searchplugins/llibres.png
+searchplugins/llibres.gif
+searchplugins/mall-cz.src
+searchplugins/mall-cz.png
+searchplugins/mall-cz.gif
+searchplugins/mercadolivre-com-br.src
+searchplugins/mercadolivre-com-br.png
+searchplugins/mercadolivre-com-br.gif
+searchplugins/merlin-pl.src
+searchplugins/merlin-pl.png
+searchplugins/merlin-pl.gif
+searchplugins/najdi-si.src
+searchplugins/najdi-si.png
+searchplugins/najdi-si.gif
+searchplugins/naver-ko.src
+searchplugins/naver-ko.png
+searchplugins/naver-ko.gif
+searchplugins/nosaltres.src
+searchplugins/nosaltres.png
+searchplugins/nosaltres.gif
+searchplugins/pbi-pl.src
+searchplugins/pbi-pl.png
+searchplugins/pbi-pl.gif
+searchplugins/google-pt-BR.src
+searchplugins/google-pt-BR.png
+searchplugins/google-pt-BR.gif
+searchplugins/priceru.src
+searchplugins/priceru.png
+searchplugins/priceru.gif
+searchplugins/pwn-pl.src
+searchplugins/pwn-pl.png
+searchplugins/pwn-pl.gif
+searchplugins/qxl-NO.src
+searchplugins/qxl-NO.png
+searchplugins/qxl-NO.gif
+searchplugins/rakuten.src
+searchplugins/rakuten.png
+searchplugins/rakuten.gif
+searchplugins/seznam-cz.src
+searchplugins/seznam-cz.png
+searchplugins/seznam-cz.gif
+searchplugins/sigov-gov-si.src
+searchplugins/sigov-gov-si.png
+searchplugins/sigov-gov-si.gif
+searchplugins/slunecnice-cz.src
+searchplugins/slunecnice-cz.png
+searchplugins/slunecnice-cz.gif
+searchplugins/submarino-com-br.src
+searchplugins/submarino-com-br.png
+searchplugins/submarino-com-br.gif
+searchplugins/taobao.src
+searchplugins/taobao.png
+searchplugins/taobao.gif
+searchplugins/telefonkatalogen-NO.src
+searchplugins/telefonkatalogen-NO.png
+searchplugins/telefonkatalogen-NO.gif
+searchplugins/universal-pt.src
+searchplugins/universal-pt.png
+searchplugins/universal-pt.gif
+searchplugins/vandale-nl.src
+searchplugins/vandale-nl.png
+searchplugins/vandale-nl.gif
+searchplugins/walla_sites.src
+searchplugins/walla_sites.png
+searchplugins/walla_sites.gif
+searchplugins/wikipedia-bg.src
+searchplugins/wikipedia-bg.png
+searchplugins/wikipedia-bg.gif
+searchplugins/wikipedia-ca.src
+searchplugins/wikipedia-ca.png
+searchplugins/wikipedia-ca.gif
+searchplugins/wikipedia-de.src
+searchplugins/wikipedia-de.png
+searchplugins/wikipedia-de.gif
+searchplugins/wikipedia-es-ES.src
+searchplugins/wikipedia-es-ES.png
+searchplugins/wikipedia-es-ES.gif
+searchplugins/wikipedia-eu.src
+searchplugins/wikipedia-eu.png
+searchplugins/wikipedia-eu.gif
+searchplugins/wikipedia-fi.src
+searchplugins/wikipedia-fi.png
+searchplugins/wikipedia-fi.gif
+searchplugins/wikipedia-fr.src
+searchplugins/wikipedia-fr.png
+searchplugins/wikipedia-fr.gif
+searchplugins/wikipedia-fy.src
+searchplugins/wikipedia-fy.png
+searchplugins/wikipedia-fy.gif
+searchplugins/wikipedia-he.src
+searchplugins/wikipedia-he.png
+searchplugins/wikipedia-he.gif
+searchplugins/wikipedia-it.src
+searchplugins/wikipedia-it.png
+searchplugins/wikipedia-it.gif
+searchplugins/wikipedia-lt.src
+searchplugins/wikipedia-lt.png
+searchplugins/wikipedia-lt.gif
+searchplugins/wikipedia-nl.src
+searchplugins/wikipedia-nl.png
+searchplugins/wikipedia-nl.gif
+searchplugins/wikipedia-pl.src
+searchplugins/wikipedia-pl.png
+searchplugins/wikipedia-pl.gif
+searchplugins/wikipedia-ru.src
+searchplugins/wikipedia-ru.png
+searchplugins/wikipedia-ru.gif
+searchplugins/wikipedia-sk.src
+searchplugins/wikipedia-sk.png
+searchplugins/wikipedia-sk.gif
+searchplugins/wp-pl.src
+searchplugins/wp-pl.png
+searchplugins/wp-pl.gif
+searchplugins/yahoo.src
+searchplugins/yahoo.png
+searchplugins/yahoo.gif
+searchplugins/yahoo-NO.src
+searchplugins/yahoo-NO.png
+searchplugins/yahoo-NO.gif
+searchplugins/yahoo-ar.src
+searchplugins/yahoo-ar.png
+searchplugins/yahoo-ar.gif
+searchplugins/yahoo-ca.src
+searchplugins/yahoo-ca.png
+searchplugins/yahoo-ca.gif
+searchplugins/yahoo-cn.src
+searchplugins/yahoo-cn.png
+searchplugins/yahoo-cn.gif
+searchplugins/yahoo-de.src
+searchplugins/yahoo-de.png
+searchplugins/yahoo-de.gif
+searchplugins/yahoo-dk.src
+searchplugins/yahoo-dk.png
+searchplugins/yahoo-dk.gif
+searchplugins/yahoo-en-GB.src
+searchplugins/yahoo-en-GB.png
+searchplugins/yahoo-en-GB.gif
+searchplugins/yahoo-es-ES.src
+searchplugins/yahoo-es-ES.png
+searchplugins/yahoo-es-ES.gif
+searchplugins/yahoo-fi.src
+searchplugins/yahoo-fi.png
+searchplugins/yahoo-fi.gif
+searchplugins/yahoo-france.src
+searchplugins/yahoo-france.png
+searchplugins/yahoo-france.gif
+searchplugins/yahoo-gu.src
+searchplugins/yahoo-gu.png
+searchplugins/yahoo-gu.gif
+searchplugins/yahoo-it.src
+searchplugins/yahoo-it.png
+searchplugins/yahoo-it.gif
+searchplugins/yahoo-jp.src
+searchplugins/yahoo-jp.png
+searchplugins/yahoo-jp.gif
+searchplugins/yahoo-jp-auctions.src
+searchplugins/yahoo-jp-auctions.png
+searchplugins/yahoo-jp-auctions.gif
+searchplugins/yahoo-jp-shopping.src
+searchplugins/yahoo-jp-shopping.png
+searchplugins/yahoo-jp-shopping.gif
+searchplugins/yahoo-kr.src
+searchplugins/yahoo-kr.png
+searchplugins/yahoo-kr.gif
+searchplugins/yahoo-nl.src
+searchplugins/yahoo-nl.png
+searchplugins/yahoo-nl.gif
+searchplugins/google-ga-IE.src
+searchplugins/google-ga-IE.png
+searchplugins/google-ga-IE.gif
+searchplugins/yahoo-pt-BR.src
+searchplugins/yahoo-pt-BR.png
+searchplugins/yahoo-pt-BR.gif
+searchplugins/yahoo-tw.src
+searchplugins/yahoo-tw.png
+searchplugins/yahoo-tw.gif
+searchplugins/yandex.src
+searchplugins/yandex.png
+searchplugins/yandex.gif
+searchplugins/zoznam-sk.src
+searchplugins/zoznam-sk.png
+searchplugins/zoznam-sk.gif
+components/sidebar.xpt
+components/xmlextras.xpt
+components/xpcom.xpt
+components/bookmarks.xpt
+components/history.xpt
+components/nsBookmarkTransactionManager.js
+extensions/talkback@mozilla.org/
+extensions/talkback@mozilla.org/install.rdf
+extensions/talkback@mozilla.org/chrome.manifest
+extensions/talkback@mozilla.org/components/qfaservices.xpt
+extensions/talkback@mozilla.org/components/libqfaservices.so
+extensions/talkback@mozilla.org/components/talkback/talkback
+extensions/talkback@mozilla.org/components/talkback/XTalkback.ad
+extensions/talkback@mozilla.org/components/talkback/master.ini
+extensions/talkback@mozilla.org/components/talkback/talkback.so
+components/airbag.xpt
+components/nsUrlClassifierTable.js
+res/cmessage.txt
+res/html/gopher-audio.gif
+res/html/gopher-binary.gif
+res/html/gopher-find.gif
+res/html/gopher-image.gif
+res/html/gopher-menu.gif
+res/html/gopher-movie.gif
+res/html/gopher-sound.gif
+res/html/gopher-telnet.gif
+res/html/gopher-text.gif
+res/html/gopher-unknown.gif
+res/fonts/mathfontCMEX10.properties
+res/fonts/mathfontCMSY10.properties
+res/fonts/mathfontMath1.properties
+res/fonts/mathfontMath2.properties
+res/fonts/mathfontMath4.properties
+res/fonts/mathfontMTExtra.properties
+res/fonts/mathfontPUA.properties
+res/fonts/mathfontSymbol.properties
+res/fonts/fontEncoding.properties
+res/fonts/pangoFontEncoding.properties
+res/fonts/fontNameMap.properties
+libxpcom_compat.so
+components/nsDictionary.js
+components/nsXmlRpcClient.js
+components/nsInterfaceInfoToIDL.js
+components/nsScriptableIO.js
+chrome/chromelist.txt
+modules/JSON.jsm
+readme.txt
+chrome/icons/default/default.xpm
+dictionaries/PL.dic
+dictionaries/PL.aff
+libjemalloc.so
+xpicleanup
+chrome.manifest
+install.rdf
diff --git a/bundles/XO/res/EditorOverride.css b/bundles/XO/res/EditorOverride.css
new file mode 100755
index 0000000..1af76bc
--- /dev/null
+++ b/bundles/XO/res/EditorOverride.css
@@ -0,0 +1,363 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+*|* {
+ -moz-user-modify: read-write;
+}
+
+/* Styles to alter look of things in the Editor content window
+ * that should NOT be removed when we display in completely WYSIWYG
+ * "Browser Preview" mode.
+ * Anything that should change, like appearance of table borders
+ * and Named Anchors, should be placed in EditorContent.css instead of here.
+*/
+
+/* Primary cursor is text I-beam */
+
+::-moz-canvas, a:link {
+ cursor: text;
+}
+
+/* Use default arrow over objects with size that
+ are selected when clicked on.
+ Override the browser's pointer cursor over links
+*/
+
+img, img[usemap], area,
+object, object[usemap],
+applet, hr, button, input, isindex, textarea, select,
+a:link img, a:visited img, a:active img,
+a[name]:-moz-only-whitespace {
+ cursor: default;
+}
+
+a:visited, a:active {
+ cursor: text;
+}
+
+/* Prevent clicking on links from going to link */
+a:link img, a:visited img {
+ -moz-user-input: none;
+}
+
+/* We suppress user/author's prefs for link underline,
+ so we must set explicitly. This isn't good!
+*/
+a:link {
+ text-decoration: underline -moz-anchor-decoration;
+ color: -moz-hyperlinktext;
+}
+
+/* Allow double-clicks on these widgets to open properties dialogs
+ XXX except when the widget has disabled attribute */
+input, button, textarea {
+ -moz-user-select: all !important;
+ -moz-user-input: auto !important;
+ -moz-user-focus: none !important;
+}
+
+/* XXX Still need a better way of blocking other events to these widgets */
+select, input[disabled], input[type="checkbox"], input[type="radio"], input[type="file"] {
+ -moz-user-select: all !important;
+ -moz-user-input: none !important;
+ -moz-user-focus: none !important;
+}
+
+isindex[prompt]
+{
+ -moz-user-select: none !important;
+ -moz-user-input: none !important;
+ -moz-user-focus: none !important;
+}
+
+input[type="hidden"] {
+ border: 1px solid black !important;
+ visibility: visible !important;
+}
+
+label {
+ -moz-user-select: all !important;
+}
+
+::-moz-display-comboboxcontrol-frame {
+ -moz-user-select: text !important;
+}
+
+option {
+ -moz-user-select: text !important;
+}
+
+#mozToc.readonly {
+ -moz-user-select: all !important;
+ -moz-user-input: none !important;
+}
+
+/* the following rules are for Image Resizing */
+
+span[\_moz_anonclass="mozResizer"] {
+ width: 5px;
+ height: 5px;
+ position: absolute;
+ border: 1px black solid;
+ background-color: white;
+ -moz-user-select: none;
+ z-index: 2147483646; /* max value -1 for this property */
+}
+
+/* we can't use :active below */
+span[\_moz_anonclass="mozResizer"][\_moz_activated],
+span[\_moz_anonclass="mozResizer"]:hover {
+ background-color: black;
+}
+
+span[\_moz_anonclass="mozResizer"].hidden,
+span[\_moz_anonclass="mozResizingShadow"].hidden,
+img[\_moz_anonclass="mozResizingShadow"].hidden,
+span[\_moz_anonclass="mozGrabber"].hidden,
+span[\_moz_anonclass="mozResizingInfo"].hidden,
+a[\_moz_anonclass="mozTableRemoveRow"].hidden,
+a[\_moz_anonclass="mozTableRemoveColumn"].hidden {
+ display: none !important;
+}
+
+span[\_moz_anonclass="mozResizer"][anonlocation="nw"] {
+ cursor: nw-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="n"] {
+ cursor: n-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="ne"] {
+ cursor: ne-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="w"] {
+ cursor: w-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="e"] {
+ cursor: e-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="sw"] {
+ cursor: sw-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="s"] {
+ cursor: s-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="se"] {
+ cursor: se-resize;
+}
+
+span[\_moz_anonclass="mozResizingShadow"],
+img[\_moz_anonclass="mozResizingShadow"] {
+ outline: thin dashed black;
+ -moz-user-select: none;
+ opacity: 0.5;
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+}
+
+span[\_moz_anonclass="mozResizingInfo"] {
+ font-family: sans-serif;
+ font-size: x-small;
+ color: black;
+ background-color: #d0d0d0;
+ border: ridge 2px #d0d0d0;
+ padding: 2px;
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+}
+
+img[\_moz_resizing] {
+ outline: thin solid black;
+}
+
+*[\_moz_abspos] {
+ outline: silver ridge 2px;
+ z-index: 2147483645 !important; /* max value -2 for this property */
+}
+*[\_moz_abspos="white"] {
+ background-color: white !important;
+}
+*[\_moz_abspos="black"] {
+ background-color: black !important;
+}
+
+span[\_moz_anonclass="mozGrabber"] {
+ outline: ridge 2px silver;
+ padding: 2px;
+ position: absolute;
+ width: 12px;
+ height: 12px;
+ background-image: url("resource://gre/res/grabber.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none;
+ cursor: move;
+ z-index: 2147483647; /* max value for this property */
+}
+
+/* INLINE TABLE EDITING */
+
+a[\_moz_anonclass="mozTableAddColumnBefore"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 4px;
+ height: 8px;
+ background-image: url("resource://gre/res/table-add-column-before.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableAddColumnBefore"]:hover {
+ background-image: url("resource://gre/res/table-add-column-before-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableAddColumnBefore"]:active {
+ background-image: url("resource://gre/res/table-add-column-before-active.gif");
+}
+
+a[\_moz_anonclass="mozTableAddColumnAfter"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 4px;
+ height: 8px;
+ background-image: url("resource://gre/res/table-add-column-after.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableAddColumnAfter"]:hover {
+ background-image: url("resource://gre/res/table-add-column-after-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableAddColumnAfter"]:active {
+ background-image: url("resource://gre/res/table-add-column-after-active.gif");
+}
+
+a[\_moz_anonclass="mozTableRemoveColumn"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 8px;
+ height: 8px;
+ background-image: url("resource://gre/res/table-remove-column.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableRemoveColumn"]:hover {
+ background-image: url("resource://gre/res/table-remove-column-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableRemoveColumn"]:active {
+ background-image: url("resource://gre/res/table-remove-column-active.gif");
+}
+
+a[\_moz_anonclass="mozTableAddRowBefore"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 8px;
+ height: 4px;
+ background-image: url("resource://gre/res/table-add-row-before.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableAddRowBefore"]:hover {
+ background-image: url("resource://gre/res/table-add-row-before-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableAddRowBefore"]:active {
+ background-image: url("resource://gre/res/table-add-row-before-active.gif");
+}
+
+a[\_moz_anonclass="mozTableAddRowAfter"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 8px;
+ height: 4px;
+ background-image: url("resource://gre/res/table-add-row-after.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableAddRowAfter"]:hover {
+ background-image: url("resource://gre/res/table-add-row-after-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableAddRowAfter"]:active {
+ background-image: url("resource://gre/res/table-add-row-after-active.gif");
+}
+
+a[\_moz_anonclass="mozTableRemoveRow"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 8px;
+ height: 8px;
+ background-image: url("resource://gre/res/table-remove-row.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableRemoveRow"]:hover {
+ background-image: url("resource://gre/res/table-remove-row-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableRemoveRow"]:active {
+ background-image: url("resource://gre/res/table-remove-row-active.gif");
+}
diff --git a/bundles/XO/res/arrow.gif b/bundles/XO/res/arrow.gif
new file mode 100755
index 0000000..afb4641
--- /dev/null
+++ b/bundles/XO/res/arrow.gif
Binary files differ
diff --git a/bundles/XO/res/arrowd.gif b/bundles/XO/res/arrowd.gif
new file mode 100755
index 0000000..02173c7
--- /dev/null
+++ b/bundles/XO/res/arrowd.gif
Binary files differ
diff --git a/bundles/XO/res/broken-image.gif b/bundles/XO/res/broken-image.gif
new file mode 100755
index 0000000..a070cec
--- /dev/null
+++ b/bundles/XO/res/broken-image.gif
Binary files differ
diff --git a/bundles/XO/res/charsetData.properties b/bundles/XO/res/charsetData.properties
new file mode 100755
index 0000000..853b3fa
--- /dev/null
+++ b/bundles/XO/res/charsetData.properties
@@ -0,0 +1,223 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1999 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+# IBM Corporation
+# Jungshik Shin <jshin@mailaps.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+## Rule of this file:
+## 1. key should always be in lower case ascii so we can do case insensitive
+## comparison in the code faster.
+
+## Format of this file:
+##
+## charset_name.notForBrowser = anything - specifies that this charset is
+## not to be used in the browser
+## charset_name.notForOutgoing = anything - specifies that this charset is
+## not to be used for exporting files ('SaveAsCharset' in composer)
+##
+## charset_name.LangGroup =
+##
+## charset_name.isMultibyte = multi byte charsets
+
+t.61-8bit.notForBrowser = true
+x-imap4-modified-utf7.notForBrowser = true
+windows-936.notForBrowser = true
+us-ascii.notForBrowser = true
+x-obsoleted-euc-jp.notForBrowser = true
+x-obsoleted-iso-2022-jp.notForBrowser = true
+x-obsoleted-shift_jis.notForBrowser = true
+iso-8859-6-e.notForBrowser = true
+iso-8859-6-i.notForBrowser = true
+ibm864i.notForBrowser = true
+ibm869.notForBrowser = true
+ibm1125.notForBrowser = true
+ibm1131.notForBrowser = true
+x-ibm1046.notForBrowser = true
+iso-8859-8-e.notForBrowser = true
+utf-7.notForBrowser = true
+
+t.61-8bit.notForOutgoing = true
+utf-7.notForOutgoing = true
+x-imap4-modified-utf7.notForOutgoing = true
+windows-936.notForOutgoing = true
+us-ascii.notForOutgoing = true
+x-obsoleted-euc-jp.notForOutgoing = true
+x-obsoleted-iso-2022-jp.notForOutgoing = true
+x-obsoleted-shift_jis.notForOutgoing = true
+iso-8859-6-e.notForOutgoing = true
+iso-8859-6-i.notForOutgoing = true
+ibm864i.notForOutgoing = true
+ibm869.notForOutgoing = true
+ibm1125.notForOutgoing = true
+ibm1131.notForOutgoing = true
+x-ibm1046.notForOutgoing = true
+iso-8859-8-e.notForOutgoing = true
+iso-8859-8.notForOutgoing = true
+iso-2022-kr.notForOutgoing = true
+x-windows-949.notForOutgoing = true
+x-johab.notForOutgoing = true
+
+
+// XXX : there are some entries only necessary for Gtk/Xlib builds
+// to map XLFD registry-encoding pairs to langGroups. they can be
+// removed once bug 215537 is fixed.
+adobe-symbol-encoding.LangGroup = el
+armscii-8.LangGroup = x-armn
+big5.LangGroup = zh-TW
+x-x-big5.LangGroup = zh-TW
+big5-hkscs.LangGroup = zh-HK
+euc-jp.LangGroup = ja
+euc-kr.LangGroup = ko
+gb2312.LangGroup = zh-CN
+gb18030.LangGroup = zh-CN
+gb18030.2000-0.LangGroup = zh-CN
+gb18030.2000-1.LangGroup = zh-CN
+geostd8.LangGroup = x-geor
+hkscs-1.LangGroup = zh-HK
+hz-gb-2312.LangGroup = zh-CN
+ibm850.LangGroup = x-western
+ibm852.LangGroup = x-central-euro
+ibm855.LangGroup = x-cyrillic
+ibm857.LangGroup = tr
+ibm862.LangGroup = he
+ibm864.LangGroup = ar
+ibm864i.LangGroup = ar
+ibm866.LangGroup = x-cyrillic
+ibm869.LangGroup = el
+ibm1125.LangGroup = x-cyrillic
+ibm1131.LangGroup = x-cyrillic
+x-ibm1046.LangGroup = ar
+iso-2022-cn.LangGroup = zh-CN
+iso-2022-jp.LangGroup = ja
+iso-2022-kr.LangGroup = ko
+iso-8859-1.LangGroup = x-western
+iso-8859-10.LangGroup = x-western
+iso-8859-14.LangGroup = x-western
+iso-8859-15.LangGroup = x-western
+iso-8859-2.LangGroup = x-central-euro
+iso-8859-16.LangGroup = x-central-euro
+iso-8859-3.LangGroup = x-western
+iso-8859-4.LangGroup = x-baltic
+iso-8859-13.LangGroup = x-baltic
+iso-8859-5.LangGroup = x-cyrillic
+iso-8859-6.LangGroup = ar
+iso-8859-6-e.LangGroup = ar
+iso-8859-6-i.LangGroup = ar
+iso-8859-7.LangGroup = el
+iso-8859-8.LangGroup = he
+iso-8859-8-e.LangGroup = he
+iso-8859-8-i.LangGroup = he
+iso-8859-9.LangGroup = tr
+jis_0208-1983.LangGroup = ja
+koi8-r.LangGroup = x-cyrillic
+koi8-u.LangGroup = x-cyrillic
+iso-ir-111.LangGroup = x-cyrillic
+shift_jis.LangGroup = ja
+tis-620.LangGroup = th
+tis620-2.LangGroup = th
+windows-874.LangGroup = th
+iso-8859-11.LangGroup = th
+x-thaittf-0.LangGroup = th
+us-ascii.LangGroup = x-western
+t.61-8bit.LangGroup = x-western
+utf-8.LangGroup = x-unicode
+utf-16.LangGroup = x-unicode
+utf-16be.LangGroup = x-unicode
+utf-16le.LangGroup = x-unicode
+utf-32.LangGroup = x-unicode
+utf-32be.LangGroup = x-unicode
+utf-32le.LangGroup = x-unicode
+utf-7.LangGroup = x-unicode
+x-imap4-modified-utf7.LangGroup = x-unicode
+viscii.LangGroup = x-western
+x-viet-tcvn5712.LangGroup = x-western
+x-viet-vps.LangGroup = x-western
+windows-1250.LangGroup = x-central-euro
+windows-1251.LangGroup = x-cyrillic
+windows-1252.LangGroup = x-western
+windows-1253.LangGroup = el
+windows-1254.LangGroup = tr
+windows-1255.LangGroup = he
+windows-1256.LangGroup = ar
+windows-1257.LangGroup = x-baltic
+windows-1258.LangGroup = x-western
+windows-936.LangGroup = zh-CN
+x-cns-11643-1.LangGroup = zh-TW
+x-euc-tw.LangGroup = zh-TW
+x-gbk.LangGroup = zh-CN
+gb_2312-80.LangGroup = zh-CN
+x-gbk-noascii.LangGroup = zh-CN
+x-mac-ce.LangGroup = x-central-euro
+x-mac-croatian.LangGroup = x-central-euro
+x-mac-cyrillic.LangGroup = x-cyrillic
+x-mac-devanagari.LangGroup = x-devanagari
+x-mac-farsi.LangGroup = ar
+x-mac-greek.LangGroup = el
+x-mac-gujarati.LangGroup = x-gujr
+x-mac-gurmukhi.LangGroup = x-guru
+x-mac-icelandic.LangGroup = x-western
+x-mac-roman.LangGroup = x-western
+x-mac-turkish.LangGroup = tr
+x-mac-ukrainian.LangGroup = x-cyrillic
+x-mac-romanian.LangGroup = x-central-euro
+x-user-defined.LangGroup = x-user-def
+ks_c_5601-1987.LangGroup = ko
+x-x11johab.LangGroup = ko
+x-johab.LangGroup = ko
+x-johab-noascii.LangGroup = ko
+x-windows-949.LangGroup = ko
+x-koreanjamo-0.LangGroup = ko
+x-mac-hebrew.LangGroup = he
+x-mac-arabic.LangGroup = ar
+x-iso-8859-6-8-x.LangGroup = ar
+x-iso-8859-6-16.LangGroup = ar
+x-sun-unicode-india-0.LangGroup = x-devanagari
+x-tscii.LangGroup = x-tamil
+x-tamilttf-0.LangGroup = x-tamil
+
+iso-2022-jp.isMultibyte = true
+shift_jis.isMultibyte = true
+euc-jp.isMultibyte = true
+big5.isMultibyte = true
+big5-hkscs.isMultibyte = true
+x-euc-tw.isMultibyte = true
+gb2312.isMultibyte = true
+hz-gb-2312.isMultibyte = true
+iso-2022-kr.isMultibyte = true
+euc-kr.isMultibyte = true
+x-johab.isMultibyte = true
+x-windows-949.isMultibyte = true
+utf-7.isMultibyte = true
+utf-8.isMultibyte = true
diff --git a/bundles/XO/res/charsetalias.properties b/bundles/XO/res/charsetalias.properties
new file mode 100755
index 0000000..ff4efd3
--- /dev/null
+++ b/bundles/XO/res/charsetalias.properties
@@ -0,0 +1,522 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# IBM Corporation
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+# This Original Code has been modified by IBM Corporation.
+# Modifications made by IBM described herein are
+# Copyright (c) International Business Machines
+# Corporation, 1999
+#
+# Modifications to Mozilla code or documentation
+# identified per MPL Section 3.3
+#
+# Date Modified by Description of modification
+# 12/09/1999 IBM Corp. Support for IBM codepages - 850,852,855,857,862,864
+#
+# Rule of this file:
+# 1. key should always be in lower case ascii so we can do case insensitive
+# comparison in the code faster.
+# 2. value should be the one used in unicode converter
+#
+# 3. If the charset is not used for document charset, but font charset
+# (e.g. XLFD charset- such as JIS x0201, JIS x0208), don't put here
+#
+
+ascii=us-ascii
+us-ascii=us-ascii
+ansi_x3.4-1968=us-ascii
+646=us-ascii
+iso-8859-1=ISO-8859-1
+iso-8859-2=ISO-8859-2
+iso-8859-3=ISO-8859-3
+iso-8859-4=ISO-8859-4
+iso-8859-5=ISO-8859-5
+iso-8859-6=ISO-8859-6
+iso-8859-6-i=ISO-8859-6-I
+iso-8859-6-e=ISO-8859-6-E
+iso-8859-7=ISO-8859-7
+iso-8859-8=ISO-8859-8
+iso-8859-8-i=ISO-8859-8-I
+iso-8859-8-e=ISO-8859-8-E
+iso-8859-9=ISO-8859-9
+iso-8859-10=ISO-8859-10
+iso-8859-11=ISO-8859-11
+iso-8859-13=ISO-8859-13
+iso-8859-14=ISO-8859-14
+iso-8859-15=ISO-8859-15
+iso-8859-16=ISO-8859-16
+iso-ir-111=ISO-IR-111
+iso-2022-cn=ISO-2022-CN
+iso-2022-cn-ext=ISO-2022-CN
+iso-2022-kr=ISO-2022-KR
+iso-2022-jp=ISO-2022-JP
+utf-32be=UTF-32BE
+utf-32le=UTF-32LE
+utf-32=UTF-32
+utf-16be=UTF-16BE
+utf-16le=UTF-16LE
+utf-16=UTF-16
+windows-1250=windows-1250
+windows-1251=windows-1251
+windows-1252=windows-1252
+windows-1253=windows-1253
+windows-1254=windows-1254
+windows-1255=windows-1255
+windows-1256=windows-1256
+windows-1257=windows-1257
+windows-1258=windows-1258
+ibm866=IBM866
+ibm850=IBM850
+ibm852=IBM852
+ibm855=IBM855
+ibm857=IBM857
+ibm862=IBM862
+ibm864=IBM864
+ibm864i=IBM864i
+utf-8=UTF-8
+utf-7=UTF-7
+shift_jis=Shift_JIS
+big5=Big5
+euc-jp=EUC-JP
+euc-kr=EUC-KR
+gb2312=GB2312
+gb18030=gb18030
+viscii=VISCII
+koi8-r=KOI8-R
+koi8-u=KOI8-U
+tis-620=TIS-620
+t.61-8bit=T.61-8bit
+hz-gb-2312=HZ-GB-2312
+big5-hkscs=Big5-HKSCS
+gbk=x-gbk
+cns11643=x-euc-tw
+#
+# Netscape private ...
+#
+x-imap4-modified-utf7=x-imap4-modified-utf7
+x-euc-tw=x-euc-tw
+x-mac-roman=x-mac-roman
+x-mac-ce=x-mac-ce
+x-mac-turkish=x-mac-turkish
+x-mac-greek=x-mac-greek
+x-mac-icelandic=x-mac-icelandic
+x-mac-croatian=x-mac-croatian
+x-mac-romanian=x-mac-romanian
+x-mac-cyrillic=x-mac-cyrillic
+x-mac-ukrainian=x-mac-ukrainian
+x-mac-hebrew=x-mac-hebrew
+x-mac-arabic=x-mac-arabic
+x-mac-farsi=x-mac-farsi
+x-mac-devanagari=x-mac-devanagari
+x-mac-gujarati=x-mac-gujarati
+x-mac-gurmukhi=x-mac-gurmukhi
+geostd8=GEOSTD8
+armscii-8=armscii-8
+x-viet-tcvn5712=x-viet-tcvn5712
+x-viet-vps=x-viet-vps
+x-viet-vni=x-viet-vni
+iso-10646-ucs-2=UTF-16BE
+x-iso-10646-ucs-2-be=UTF-16BE
+x-iso-10646-ucs-2-le=UTF-16LE
+iso-10646-ucs-4=UTF-32BE
+x-iso-10646-ucs-4-be=UTF-32BE
+x-iso-10646-ucs-4-le=UTF-32LE
+x-user-defined=x-user-defined
+x-johab=x-johab
+x-windows-949=x-windows-949
+#
+# Aliases for ISO-8859-1
+#
+latin1=ISO-8859-1
+iso_8859-1=ISO-8859-1
+iso8859-1=ISO-8859-1
+iso8859-2=ISO-8859-2
+iso8859-3=ISO-8859-3
+iso8859-4=ISO-8859-4
+iso8859-5=ISO-8859-5
+iso8859-6=ISO-8859-6
+iso8859-7=ISO-8859-7
+iso8859-8=ISO-8859-8
+iso8859-9=ISO-8859-9
+iso8859-10=ISO-8859-10
+iso8859-11=ISO-8859-11
+iso8859-13=ISO-8859-13
+iso8859-14=ISO-8859-14
+iso8859-15=ISO-8859-15
+# Currently .properties cannot handle : in key
+# iso_8859-1:1987=ISO-8859-1
+iso-ir-100=ISO-8859-1
+l1=ISO-8859-1
+ibm819=ISO-8859-1
+cp819=ISO-8859-1
+csisolatin1=ISO-8859-1
+#
+# Aliases for ISO-8859-2
+#
+latin2=ISO-8859-2
+iso_8859-2=ISO-8859-2
+# Currently .properties cannot handle : in key
+# iso_8859-2:1987=ISO-8859-2
+iso-ir-101=ISO-8859-2
+l2=ISO-8859-2
+csisolatin2=ISO-8859-2
+#
+# Aliases for ISO-8859-3
+#
+latin3=ISO-8859-3
+iso_8859-3=ISO-8859-3
+# Currently .properties cannot handle : in key
+#iso_8859-3:1988=ISO-8859-3
+iso-ir-109=ISO-8859-3
+l3=ISO-8859-3
+csisolatin3=ISO-8859-3
+#
+# Aliases for ISO-8859-4
+#
+latin4=ISO-8859-4
+iso_8859-4=ISO-8859-4
+# Currently .properties cannot handle : in key
+#iso_8859-4:1988=ISO-8859-4
+iso-ir-110=ISO-8859-4
+l4=ISO-8859-4
+csisolatin4=ISO-8859-4
+#
+# Aliases for ISO-8859-5
+#
+cyrillic=ISO-8859-5
+iso_8859-5=ISO-8859-5
+# Currently .properties cannot handle : in key
+#iso_8859-5:1988=ISO-8859-5
+iso-ir-144=ISO-8859-5
+csisolatincyrillic=ISO-8859-5
+#
+# Aliases for ISO-8859-6
+#
+arabic=ISO-8859-6
+iso_8859-6=ISO-8859-6
+# Currently .properties cannot handle : in key
+#iso_8859-6:1987=ISO-8859-6
+iso-ir-127=ISO-8859-6
+ecma-114=ISO-8859-6
+asmo-708=ISO-8859-6
+csisolatinarabic=ISO-8859-6
+#
+# Aliases for ISO-8859-6-I
+#
+csiso88596i=ISO-8859-6-I
+#
+# Aliases for ISO-8859-6-E
+#
+csiso88596e=ISO-8859-6-E
+#
+# Aliases for ISO-8859-7
+#
+greek=ISO-8859-7
+greek8=ISO-8859-7
+sun_eu_greek=ISO-8859-7
+iso_8859-7=ISO-8859-7
+# Currently .properties cannot handle : in key
+#iso_8859-7:1987=ISO-8859-7
+iso-ir-126=ISO-8859-7
+elot_928=ISO-8859-7
+ecma-118=ISO-8859-7
+csisolatingreek=ISO-8859-7
+#
+# Aliases for ISO-8859-8
+#
+hebrew=ISO-8859-8
+iso_8859-8=ISO-8859-8
+visual=ISO-8859-8
+# Currently .properties cannot handle : in key
+#iso_8859-8:1988=ISO-8859-8
+iso-ir-138=ISO-8859-8
+csisolatinhebrew=ISO-8859-8
+#
+# Aliases for ISO-8859-8-I
+#
+csiso88598i=ISO-8859-8-I
+iso-8859-8i=ISO-8859-8-I
+#
+# Aliases for ISO-8859-8-E
+#
+csiso88598e=ISO-8859-8-E
+#
+# Aliases for ISO-8859-9
+#
+latin5=ISO-8859-9
+iso_8859-9=ISO-8859-9
+# Currently .properties cannot handle : in key
+#iso_8859-9:1989=ISO-8859-9
+iso-ir-148=ISO-8859-9
+l5=ISO-8859-9
+csisolatin5=ISO-8859-9
+#
+# Aliases for UTF-8
+#
+unicode-1-1-utf-8=UTF-8
+# nl_langinfo(CODESET) in HP/UX returns 'utf8' under UTF-8 locales
+utf8=UTF-8
+#
+# Aliases for Shift_JIS
+#
+x-sjis=Shift_JIS
+shift-jis=Shift_JIS
+ms_kanji=Shift_JIS
+csshiftjis=Shift_JIS
+windows-31j=Shift_JIS
+#
+# Aliases for EUC_JP
+#
+cseucjpkdfmtjapanese=EUC-JP
+x-euc-jp=EUC-JP
+#
+# Aliases for ISO-2022-JP
+#
+csiso2022jp=ISO-2022-JP
+# The following are really not aliases ISO-2022-JP, but sharing the same decoder
+iso-2022-jp-2=ISO-2022-JP
+csiso2022jp2=ISO-2022-JP
+#
+# Aliases for Big5
+#
+csbig5=Big5
+# x-x-big5 is not really a alias for Big5, add it only for MS FrontPage
+x-x-big5=Big5
+# Sun Solaris
+zh_tw-big5=Big5
+#
+# Aliases for EUC-KR
+#
+csueckr=EUC-KR
+# The following are really not aliases EUC-KR, add them only for MS FrontPage
+#ks_c_5601-1987=EUC-KR
+iso-ir-149=EUC-KR
+ks_c_5601-1989=EUC-KR
+ksc_5601=EUC-KR
+ksc5601=EUC-KR
+korean=EUC-KR
+csksc56011987=EUC-KR
+5601=EUC-KR
+#
+# Aliases for X-Windows-949, CP949, Unified Hangul Code (UHC)
+#
+# Microsoft uses ks_c_5601-1987 to mean Windows-949 or its subset EUC-KR.
+ks_c_5601-1987=x-windows-949
+#
+# Aliases for GB2312
+#
+# The following are really not aliases GB2312, add them only for MS FrontPage
+gb_2312-80=GB2312
+iso-ir-58=GB2312
+chinese=GB2312
+csiso58gb231280=GB2312
+csgb2312=GB2312
+zh_cn.euc=GB2312
+# Sun Solaris
+gb_2312=GB2312
+#
+# Aliases for windows-125x
+#
+x-cp1250=windows-1250
+x-cp1251=windows-1251
+x-cp1252=windows-1252
+x-cp1253=windows-1253
+x-cp1254=windows-1254
+x-cp1255=windows-1255
+x-cp1256=windows-1256
+x-cp1257=windows-1257
+x-cp1258=windows-1258
+#
+# Aliases for windows-874
+#
+windows-874=windows-874
+ibm874=windows-874
+#
+# Aliases for x-mac-roman
+# XXX: should make macintosh the canonical name later
+#
+macintosh=x-mac-roman
+mac=x-mac-roman
+csMacintosh=x-mac-roman
+#
+# Aliases for IBM866
+#
+cp866=IBM866
+cp-866=IBM866
+866=IBM866
+csIBM866=IBM866
+#
+# Aliases for IBM850
+#
+cp850=IBM850
+850=IBM850
+csIBM850=IBM850
+#
+# Aliases for IBM852
+#
+cp852=IBM852
+852=IBM852
+csIBM852=IBM852
+#
+# Aliases for IBM855
+#
+cp855=IBM855
+855=IBM855
+csIBM855=IBM855
+#
+# Aliases for IBM857
+#
+cp857=IBM857
+857=IBM857
+csIBM857=IBM857
+#
+# Aliases for IBM862
+#
+cp862=IBM862
+862=IBM862
+csIBM862=IBM862
+#
+# Aliases for IBM864
+#
+cp864=IBM864
+864=IBM864
+csIBM864=IBM864
+ibm-864=IBM864
+#
+# Aliases for IBM864i
+#
+cp864i=IBM864i
+864i=IBM864i
+csibm864i=IBM864i
+ibm-864i=IBM864i
+#
+# Aliases for T.61-8bit
+#
+t.61=T.61-8bit
+iso-ir-103=T.61-8bit
+csiso103t618bit=T.61-8bit
+#
+# Aliases for UTF-7
+#
+x-unicode-2-0-utf-7=UTF-7
+unicode-2-0-utf-7=UTF-7
+unicode-1-1-utf-7=UTF-7
+csunicode11utf7=UTF-7
+#
+# Aliases for ISO-10646-UCS-2
+#
+csunicode=UTF-16BE
+csunicode11=UTF-16BE
+iso-10646-ucs-basic=UTF-16BE
+csunicodeascii=UTF-16BE
+iso-10646-unicode-latin1=UTF-16BE
+csunicodelatin1=UTF-16BE
+iso-10646=UTF-16BE
+iso-10646-j-1=UTF-16BE
+#
+# Aliases for ISO-8859-10
+#
+latin6=ISO-8859-10
+iso-ir-157=ISO-8859-10
+l6=ISO-8859-10
+# Currently .properties cannot handle : in key
+#iso_8859-10:1992=ISO-8859-10
+csisolatin6=ISO-8859-10
+#
+# Aliases for ISO-8859-15
+#
+iso_8859-15=ISO-8859-15
+#
+# Aliases for ISO-IR-111
+#
+ecma-cyrillic=ISO-IR-111
+csiso111ecmacyrillic=ISO-IR-111
+#
+# Aliases for ISO-2022-KR
+#
+csiso2022kr=ISO-2022-KR
+#
+# Aliases for VISCII
+#
+csviscii=VISCII
+#
+# Aliases for VIQR
+#
+csviqr=VIQR
+#
+# Aliases for x-euc-tw
+#
+zh_tw-euc=x-euc-tw
+#
+# Following names appears in unix nl_langinfo(CODESET)
+# They can be compiled as platform specific if necessary
+# DONT put things here if it does not look generic enough (like hp15CN)
+#
+iso88591=ISO-8859-1
+iso88592=ISO-8859-2
+iso88593=ISO-8859-3
+iso88594=ISO-8859-4
+iso88595=ISO-8859-5
+iso88596=ISO-8859-6
+iso88597=ISO-8859-7
+iso88598=ISO-8859-8
+iso88599=ISO-8859-9
+iso885910=ISO-8859-10
+iso885911=ISO-8859-11
+iso885912=ISO-8859-12
+iso885913=ISO-8859-13
+iso885914=ISO-8859-14
+iso885915=ISO-8859-15
+#
+tis620=TIS-620
+#
+cp1250=windows-1250
+cp1251=windows-1251
+cp1252=windows-1252
+cp1253=windows-1253
+cp1254=windows-1254
+cp1255=windows-1255
+cp1256=windows-1256
+cp1257=windows-1257
+cp1258=windows-1258
+
+# Tempory charset for testing purpose. Should be remove before Beta
+x-obsoleted-shift_jis=x-obsoleted-Shift_JIS
+x-obsoleted-iso-2022-jp=x-obsoleted-ISO-2022-JP
+x-obsoleted-euc-jp=x-obsoleted-EUC-JP
+x-gbk=x-gbk
+windows-936=windows-936
+ansi-1251=windows-1251
diff --git a/bundles/XO/res/contenteditable.css b/bundles/XO/res/contenteditable.css
new file mode 100755
index 0000000..3adda8d
--- /dev/null
+++ b/bundles/XO/res/contenteditable.css
@@ -0,0 +1,376 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Disruptive Innovations.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Peter Van der Beken <peterv@propagandism.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+::-moz-canvas {
+ cursor: text;
+}
+
+:focus:-moz-read-write :-moz-read-only {
+ -moz-user-select: all !important;
+}
+
+input:-moz-read-write > .anonymous-div:-moz-read-only,
+textarea:-moz-read-write > .anonymous-div:-moz-read-only {
+ -moz-user-select: text !important;
+}
+
+/* Use default arrow over objects with size that
+ are selected when clicked on.
+ Override the browser's pointer cursor over links
+*/
+
+img:-moz-read-write, img:-moz-read-write[usemap], area:-moz-read-write,
+object:-moz-read-write, object:-moz-read-write[usemap],
+applet:-moz-read-write, hr:-moz-read-write, button:-moz-read-write,
+isindex:-moz-read-write, select:-moz-read-write,
+a:-moz-read-write:link img, a:-moz-read-write:visited img,
+a:-moz-read-write:active img, a:-moz-read-write:-moz-only-whitespace[name] {
+ cursor: default;
+}
+
+:-moz-any-link:-moz-read-write {
+ cursor: text;
+}
+
+/* Prevent clicking on links from going to link */
+a:link:-moz-read-write img, a:visited:-moz-read-write img,
+a:active:-moz-read-write img {
+ -moz-user-input: none;
+}
+
+/* We suppress user/author's prefs for link underline,
+ so we must set explicitly. This isn't good!
+*/
+a:link:-moz-read-write {
+ text-decoration: underline -moz-anchor-decoration;
+ color: -moz-hyperlinktext;
+}
+
+/* Allow double-clicks on these widgets to open properties dialogs
+ XXX except when the widget has disabled attribute */
+:-moz-read-write > input:-moz-read-only,
+:-moz-read-write > button:-moz-read-only,
+:-moz-read-write > textarea:-moz-read-only {
+ -moz-user-select: all !important;
+ -moz-user-input: auto !important;
+ -moz-user-focus: none !important;
+}
+
+/* XXX Still need a better way of blocking other events to these widgets */
+select:-moz-read-write,
+:-moz-read-write > input[disabled],
+:-moz-read-write > input[type="checkbox"],
+:-moz-read-write > input[type="radio"],
+:-moz-read-write > input[type="file"],
+input[contenteditable="true"][disabled],
+input[contenteditable="true"][type="checkbox"],
+input[contenteditable="true"][type="radio"],
+input[contenteditable="true"][type="file"] {
+ -moz-user-select: all !important;
+ -moz-user-input: none !important;
+ -moz-user-focus: none !important;
+}
+
+isindex:-moz-read-write[prompt]
+{
+ -moz-user-select: none !important;
+ -moz-user-input: none !important;
+ -moz-user-focus: none !important;
+}
+
+/* emulation of non-standard HTML <marquee> tag */
+marquee:-moz-read-write {
+ -moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-horizontal-editable');
+}
+
+marquee[direction="up"]:-moz-read-write, marquee[direction="down"]:-moz-read-write {
+ -moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-vertical-editable');
+}
+
+:-moz-read-write > input[type="hidden"],
+input[contenteditable="true"][type="hidden"] {
+ border: 1px solid black !important;
+ visibility: visible !important;
+}
+
+label:-moz-read-write {
+ -moz-user-select: all !important;
+}
+
+::-moz-display-comboboxcontrol-frame {
+ -moz-user-select: text !important;
+}
+
+option:-moz-read-write {
+ -moz-user-select: text !important;
+}
+
+/* the following rules are for Image Resizing */
+
+span[\_moz_anonclass="mozResizer"] {
+ width: 5px;
+ height: 5px;
+ position: absolute;
+ border: 1px black solid;
+ background-color: white;
+ -moz-user-select: none;
+ z-index: 2147483646; /* max value -1 for this property */
+}
+
+/* we can't use :active below */
+span[\_moz_anonclass="mozResizer"][\_moz_activated],
+span[\_moz_anonclass="mozResizer"]:hover {
+ background-color: black;
+}
+
+span[\_moz_anonclass="mozResizer"].hidden,
+span[\_moz_anonclass="mozResizingShadow"].hidden,
+img[\_moz_anonclass="mozResizingShadow"].hidden,
+span[\_moz_anonclass="mozGrabber"].hidden,
+span[\_moz_anonclass="mozResizingInfo"].hidden,
+a[\_moz_anonclass="mozTableRemoveRow"].hidden,
+a[\_moz_anonclass="mozTableRemoveColumn"].hidden {
+ display: none !important;
+}
+
+span[\_moz_anonclass="mozResizer"][anonlocation="nw"] {
+ cursor: nw-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="n"] {
+ cursor: n-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="ne"] {
+ cursor: ne-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="w"] {
+ cursor: w-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="e"] {
+ cursor: e-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="sw"] {
+ cursor: sw-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="s"] {
+ cursor: s-resize;
+}
+span[\_moz_anonclass="mozResizer"][anonlocation="se"] {
+ cursor: se-resize;
+}
+
+span[\_moz_anonclass="mozResizingShadow"],
+img[\_moz_anonclass="mozResizingShadow"] {
+ outline: thin dashed black;
+ -moz-user-select: none;
+ opacity: 0.5;
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+}
+
+span[\_moz_anonclass="mozResizingInfo"] {
+ font-family: sans-serif;
+ font-size: x-small;
+ color: black;
+ background-color: #d0d0d0;
+ border: ridge 2px #d0d0d0;
+ padding: 2px;
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+}
+
+img[\_moz_resizing] {
+ outline: thin solid black;
+}
+
+*[\_moz_abspos] {
+ outline: silver ridge 2px;
+ z-index: 2147483645 !important; /* max value -2 for this property */
+}
+*[\_moz_abspos="white"] {
+ background-color: white !important;
+}
+*[\_moz_abspos="black"] {
+ background-color: black !important;
+}
+
+span[\_moz_anonclass="mozGrabber"] {
+ outline: ridge 2px silver;
+ padding: 2px;
+ position: absolute;
+ width: 12px;
+ height: 12px;
+ background-image: url("resource://gre/res/grabber.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none;
+ cursor: move;
+}
+
+/* INLINE TABLE EDITING */
+
+a[\_moz_anonclass="mozTableAddColumnBefore"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 4px;
+ height: 8px;
+ background-image: url("resource://gre/res/table-add-column-before.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableAddColumnBefore"]:hover {
+ background-image: url("resource://gre/res/table-add-column-before-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableAddColumnBefore"]:active {
+ background-image: url("resource://gre/res/table-add-column-before-active.gif");
+}
+
+a[\_moz_anonclass="mozTableAddColumnAfter"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 4px;
+ height: 8px;
+ background-image: url("resource://gre/res/table-add-column-after.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableAddColumnAfter"]:hover {
+ background-image: url("resource://gre/res/table-add-column-after-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableAddColumnAfter"]:active {
+ background-image: url("resource://gre/res/table-add-column-after-active.gif");
+}
+
+a[\_moz_anonclass="mozTableRemoveColumn"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 8px;
+ height: 8px;
+ background-image: url("resource://gre/res/table-remove-column.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableRemoveColumn"]:hover {
+ background-image: url("resource://gre/res/table-remove-column-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableRemoveColumn"]:active {
+ background-image: url("resource://gre/res/table-remove-column-active.gif");
+}
+
+a[\_moz_anonclass="mozTableAddRowBefore"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 8px;
+ height: 4px;
+ background-image: url("resource://gre/res/table-add-row-before.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableAddRowBefore"]:hover {
+ background-image: url("resource://gre/res/table-add-row-before-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableAddRowBefore"]:active {
+ background-image: url("resource://gre/res/table-add-row-before-active.gif");
+}
+
+a[\_moz_anonclass="mozTableAddRowAfter"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 8px;
+ height: 4px;
+ background-image: url("resource://gre/res/table-add-row-after.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableAddRowAfter"]:hover {
+ background-image: url("resource://gre/res/table-add-row-after-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableAddRowAfter"]:active {
+ background-image: url("resource://gre/res/table-add-row-after-active.gif");
+}
+
+a[\_moz_anonclass="mozTableRemoveRow"] {
+ position: absolute;
+ z-index: 2147483647; /* max value for this property */
+ text-decoration: none !important;
+ border: none 0px !important;
+ width: 8px;
+ height: 8px;
+ background-image: url("resource://gre/res/table-remove-row.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ -moz-user-select: none !important;
+ -moz-user-focus: none !important;
+}
+
+a[\_moz_anonclass="mozTableRemoveRow"]:hover {
+ background-image: url("resource://gre/res/table-remove-row-hover.gif");
+}
+
+a[\_moz_anonclass="mozTableRemoveRow"]:active {
+ background-image: url("resource://gre/res/table-remove-row-active.gif");
+}
diff --git a/bundles/XO/res/designmode.css b/bundles/XO/res/designmode.css
new file mode 100755
index 0000000..6e2598c
--- /dev/null
+++ b/bundles/XO/res/designmode.css
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Disruptive Innovations.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Peter Van der Beken <peterv@propagandism.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+*|* {
+ -moz-user-modify: read-write;
+}
diff --git a/bundles/XO/res/dtd/mathml.dtd b/bundles/XO/res/dtd/mathml.dtd
new file mode 100755
index 0000000..fb911c8
--- /dev/null
+++ b/bundles/XO/res/dtd/mathml.dtd
@@ -0,0 +1,1592 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Mozilla MathML Project.
+ -
+ - The Initial Developer of the Original Code is
+ - The University of Queensland.
+ - Portions created by the Initial Developer are Copyright (C) 2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ - Roger B. Sidje <rbs@maths.uq.edu.au>
+ - Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the LGPL or the GPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- Entities defined in MathML 2.0 but with Unicode code points updated in
+ line with http://www.unicode.org/reports/tr25/tr25-9.html
+ -->
+<!ENTITY phi "&#x3D5;">
+<!ENTITY ShortLeftArrow "&#x2190;&#x200B;"><!ENTITY slarr "&#x2190;&#x200B;">
+<!ENTITY ShortUpArrow "&#x2191;&#x200B;">
+<!ENTITY ShortRightArrow "&#x2192;&#x200B;"><!ENTITY srarr "&#x2192;&#x200B;">
+<!ENTITY ShortDownArrow "&#x2193;&#x200B;">
+<!ENTITY OverParenthesis "&#x23DC;">
+<!ENTITY UnderParenthesis "&#x23DD;">
+<!ENTITY OverBrace "&#x23DE;">
+<!ENTITY UnderBrace "&#x23DF;">
+<!ENTITY trpezium "&#x23E2;">
+<!ENTITY elinters "&#x23E7;">
+<!ENTITY lbbrk "&#x2772;">
+<!ENTITY rbbrk "&#x2773;">
+<!ENTITY lobrk "&#x27E6;"><!ENTITY LeftDoubleBracket "&#x27E6;">
+<!ENTITY robrk "&#x27E7;"><!ENTITY RightDoubleBracket "&#x27E7;">
+<!ENTITY lang "&#x27E8;"><!ENTITY LeftAngleBracket "&#x27E8;"><!ENTITY langle "&#x27E8;">
+<!ENTITY rang "&#x27E9;"><!ENTITY RightAngleBracket "&#x27E9;"><!ENTITY rangle "&#x27E9;">
+<!ENTITY Lang "&#x27EA;">
+<!ENTITY Rang "&#x27EB;">
+<!ENTITY loang "&#x27EC;">
+<!ENTITY roang "&#x27ED;">
+<!ENTITY imath "&#x1D6A4;"><!ENTITY inodot "&#x1D6A4;">
+<!ENTITY jmath "&#x1D6A5;">
+
+<!-- MathML 2.0 entities - Auto-generated from the
+ "XHTML 1.1 plus MathML 2.0 plus SVG 1.1 DTD"
+ http://www.w3.org/Math/DTD/mathml2.tgz
+ as of Revision: xhtml-math11-f.dtd,v 1.16 2003/11/04 13:14:35
+
+ *** *** ***
+
+ The "XHTML 1.1 plus MathML 2.0 plus SVG 1.1 DTD" file from which the
+ entities were retrieved had the following copyright notice:
+
+ Copyright 2002 World Wide Web Consortium
+ (Massachusetts Institute of Technology, Institut National de
+ Recherche en Informatique et en Automatique, Keio University).
+ All Rights Reserved.
+
+ Permission to use, copy, modify and distribute this DTD and its
+ accompanying documentation for any purpose and without fee is hereby
+ granted in perpetuity, provided that the above copyright notice and
+ this paragraph appear in all copies. The copyright holders make no
+ representation about the suitability of the DTD for any purpose.
+
+ *** *** ***
+
+ The section listing entity declarations had the following notices:
+
+ Portions (C) International Organization for Standardization 1986:
+ Permission to copy in any form is granted for use with conforming
+ SGML systems and applications as defined in ISO 8879, provided
+ this notice is included in all copies.
+
+ (C) International Organization for Standardization 1991
+ Permission to copy in any form is granted for use with
+ conforming SGML systems and applications as defined in
+ ISO 8879, provided this notice is included in all copies.
+ -->
+<!ENTITY Tab "&#x9;">
+<!ENTITY NewLine "&#xA;">
+<!ENTITY excl "&#x21;">
+<!ENTITY quot "&#x22;">
+<!ENTITY num "&#x23;">
+<!ENTITY dollar "&#x24;">
+<!ENTITY percnt "&#x25;">
+<!ENTITY nvlt "&#x26;#x3C;&#x20D2;">
+<!ENTITY apos "&#x27;">
+<!ENTITY lpar "&#x28;">
+<!ENTITY rpar "&#x29;">
+<!ENTITY midast "&#x2A;"><!ENTITY ast "&#x2A;">
+<!ENTITY plus "&#x2B;">
+<!ENTITY comma "&#x2C;">
+<!ENTITY period "&#x2E;">
+<!ENTITY sol "&#x2F;">
+<!ENTITY colon "&#x3A;">
+<!ENTITY semi "&#x3B;">
+<!ENTITY equals "&#x3D;">
+<!ENTITY bne "&#x3D;&#x20E5;">
+<!ENTITY nvgt "&#x3E;&#x20D2;">
+<!ENTITY quest "&#x3F;">
+<!ENTITY commat "&#x40;">
+<!ENTITY lsqb "&#x5B;"><!ENTITY lbrack "&#x5B;">
+<!ENTITY bsol "&#x5C;">
+<!ENTITY bsolhsub "&#x5C;&#x2282;">
+<!ENTITY rsqb "&#x5D;"><!ENTITY rbrack "&#x5D;">
+<!ENTITY Hat "&#x5E;">
+<!ENTITY lowbar "&#x5F;">
+<!ENTITY grave "&#x60;"><!ENTITY DiacriticalGrave "&#x60;">
+<!ENTITY lcub "&#x7B;"><!ENTITY lbrace "&#x7B;">
+<!ENTITY verbar "&#x7C;"><!ENTITY VerticalLine "&#x7C;"><!ENTITY vert "&#x7C;">
+<!ENTITY rcub "&#x7D;"><!ENTITY rbrace "&#x7D;">
+<!ENTITY nbsp "&#xA0;"><!ENTITY NonBreakingSpace "&#xA0;">
+<!ENTITY iexcl "&#xA1;">
+<!ENTITY cent "&#xA2;">
+<!ENTITY pound "&#xA3;">
+<!ENTITY curren "&#xA4;">
+<!ENTITY yen "&#xA5;">
+<!ENTITY brvbar "&#xA6;">
+<!ENTITY sect "&#xA7;">
+<!ENTITY uml "&#xA8;"><!ENTITY Dot "&#xA8;"><!ENTITY die "&#xA8;"><!ENTITY DoubleDot "&#xA8;">
+<!ENTITY copy "&#xA9;">
+<!ENTITY ordf "&#xAA;">
+<!ENTITY laquo "&#xAB;">
+<!ENTITY not "&#xAC;">
+<!ENTITY shy "&#xAD;">
+<!ENTITY reg "&#xAE;"><!ENTITY circledR "&#xAE;">
+<!ENTITY macr "&#xAF;"><!ENTITY strns "&#xAF;"><!ENTITY OverBar "&#xAF;">
+<!ENTITY deg "&#xB0;">
+<!ENTITY plusmn "&#xB1;"><!ENTITY PlusMinus "&#xB1;"><!ENTITY pm "&#xB1;">
+<!ENTITY sup2 "&#xB2;">
+<!ENTITY sup3 "&#xB3;">
+<!ENTITY acute "&#xB4;"><!ENTITY DiacriticalAcute "&#xB4;">
+<!ENTITY micro "&#xB5;">
+<!ENTITY para "&#xB6;">
+<!ENTITY middot "&#xB7;"><!ENTITY CenterDot "&#xB7;"><!ENTITY centerdot "&#xB7;">
+<!ENTITY cedil "&#xB8;"><!ENTITY Cedilla "&#xB8;">
+<!ENTITY sup1 "&#xB9;">
+<!ENTITY ordm "&#xBA;">
+<!ENTITY raquo "&#xBB;">
+<!ENTITY frac14 "&#xBC;">
+<!ENTITY frac12 "&#xBD;"><!ENTITY half "&#xBD;">
+<!ENTITY frac34 "&#xBE;">
+<!ENTITY iquest "&#xBF;">
+<!ENTITY Agrave "&#xC0;">
+<!ENTITY Aacute "&#xC1;">
+<!ENTITY Acirc "&#xC2;">
+<!ENTITY Atilde "&#xC3;">
+<!ENTITY Auml "&#xC4;">
+<!ENTITY Aring "&#xC5;">
+<!ENTITY AElig "&#xC6;">
+<!ENTITY Ccedil "&#xC7;">
+<!ENTITY Egrave "&#xC8;">
+<!ENTITY Eacute "&#xC9;">
+<!ENTITY Ecirc "&#xCA;">
+<!ENTITY Euml "&#xCB;">
+<!ENTITY Igrave "&#xCC;">
+<!ENTITY Iacute "&#xCD;">
+<!ENTITY Icirc "&#xCE;">
+<!ENTITY Iuml "&#xCF;">
+<!ENTITY ETH "&#xD0;">
+<!ENTITY Ntilde "&#xD1;">
+<!ENTITY Ograve "&#xD2;">
+<!ENTITY Oacute "&#xD3;">
+<!ENTITY Ocirc "&#xD4;">
+<!ENTITY Otilde "&#xD5;">
+<!ENTITY Ouml "&#xD6;">
+<!ENTITY times "&#xD7;">
+<!ENTITY Oslash "&#xD8;">
+<!ENTITY Ugrave "&#xD9;">
+<!ENTITY Uacute "&#xDA;">
+<!ENTITY Ucirc "&#xDB;">
+<!ENTITY Uuml "&#xDC;">
+<!ENTITY Yacute "&#xDD;">
+<!ENTITY THORN "&#xDE;">
+<!ENTITY szlig "&#xDF;">
+<!ENTITY agrave "&#xE0;">
+<!ENTITY aacute "&#xE1;">
+<!ENTITY acirc "&#xE2;">
+<!ENTITY atilde "&#xE3;">
+<!ENTITY auml "&#xE4;">
+<!ENTITY aring "&#xE5;">
+<!ENTITY aelig "&#xE6;">
+<!ENTITY ccedil "&#xE7;">
+<!ENTITY egrave "&#xE8;">
+<!ENTITY eacute "&#xE9;">
+<!ENTITY ecirc "&#xEA;">
+<!ENTITY euml "&#xEB;">
+<!ENTITY igrave "&#xEC;">
+<!ENTITY iacute "&#xED;">
+<!ENTITY icirc "&#xEE;">
+<!ENTITY iuml "&#xEF;">
+<!ENTITY eth "&#xF0;">
+<!ENTITY ntilde "&#xF1;">
+<!ENTITY ograve "&#xF2;">
+<!ENTITY oacute "&#xF3;">
+<!ENTITY ocirc "&#xF4;">
+<!ENTITY otilde "&#xF5;">
+<!ENTITY ouml "&#xF6;">
+<!ENTITY divide "&#xF7;"><!ENTITY div "&#xF7;">
+<!ENTITY oslash "&#xF8;">
+<!ENTITY ugrave "&#xF9;">
+<!ENTITY uacute "&#xFA;">
+<!ENTITY ucirc "&#xFB;">
+<!ENTITY uuml "&#xFC;">
+<!ENTITY yacute "&#xFD;">
+<!ENTITY thorn "&#xFE;">
+<!ENTITY yuml "&#xFF;">
+<!ENTITY Amacr "&#x100;">
+<!ENTITY amacr "&#x101;">
+<!ENTITY Abreve "&#x102;">
+<!ENTITY abreve "&#x103;">
+<!ENTITY Aogon "&#x104;">
+<!ENTITY aogon "&#x105;">
+<!ENTITY Cacute "&#x106;">
+<!ENTITY cacute "&#x107;">
+<!ENTITY Ccirc "&#x108;">
+<!ENTITY ccirc "&#x109;">
+<!ENTITY Cdot "&#x10A;">
+<!ENTITY cdot "&#x10B;">
+<!ENTITY Ccaron "&#x10C;">
+<!ENTITY ccaron "&#x10D;">
+<!ENTITY Dcaron "&#x10E;">
+<!ENTITY dcaron "&#x10F;">
+<!ENTITY Dstrok "&#x110;">
+<!ENTITY dstrok "&#x111;">
+<!ENTITY Emacr "&#x112;">
+<!ENTITY emacr "&#x113;">
+<!ENTITY Edot "&#x116;">
+<!ENTITY edot "&#x117;">
+<!ENTITY Eogon "&#x118;">
+<!ENTITY eogon "&#x119;">
+<!ENTITY Ecaron "&#x11A;">
+<!ENTITY ecaron "&#x11B;">
+<!ENTITY Gcirc "&#x11C;">
+<!ENTITY gcirc "&#x11D;">
+<!ENTITY Gbreve "&#x11E;">
+<!ENTITY gbreve "&#x11F;">
+<!ENTITY Gdot "&#x120;">
+<!ENTITY gdot "&#x121;">
+<!ENTITY Gcedil "&#x122;">
+<!ENTITY Hcirc "&#x124;">
+<!ENTITY hcirc "&#x125;">
+<!ENTITY Hstrok "&#x126;">
+<!ENTITY hstrok "&#x127;">
+<!ENTITY Itilde "&#x128;">
+<!ENTITY itilde "&#x129;">
+<!ENTITY Imacr "&#x12A;">
+<!ENTITY imacr "&#x12B;">
+<!ENTITY Iogon "&#x12E;">
+<!ENTITY iogon "&#x12F;">
+<!ENTITY Idot "&#x130;">
+<!ENTITY IJlig "&#x132;">
+<!ENTITY ijlig "&#x133;">
+<!ENTITY Jcirc "&#x134;">
+<!ENTITY jcirc "&#x135;">
+<!ENTITY Kcedil "&#x136;">
+<!ENTITY kcedil "&#x137;">
+<!ENTITY kgreen "&#x138;">
+<!ENTITY Lacute "&#x139;">
+<!ENTITY lacute "&#x13A;">
+<!ENTITY Lcedil "&#x13B;">
+<!ENTITY lcedil "&#x13C;">
+<!ENTITY Lcaron "&#x13D;">
+<!ENTITY lcaron "&#x13E;">
+<!ENTITY Lmidot "&#x13F;">
+<!ENTITY lmidot "&#x140;">
+<!ENTITY Lstrok "&#x141;">
+<!ENTITY lstrok "&#x142;">
+<!ENTITY Nacute "&#x143;">
+<!ENTITY nacute "&#x144;">
+<!ENTITY Ncedil "&#x145;">
+<!ENTITY ncedil "&#x146;">
+<!ENTITY Ncaron "&#x147;">
+<!ENTITY ncaron "&#x148;">
+<!ENTITY napos "&#x149;">
+<!ENTITY ENG "&#x14A;">
+<!ENTITY eng "&#x14B;">
+<!ENTITY Omacr "&#x14C;">
+<!ENTITY omacr "&#x14D;">
+<!ENTITY Odblac "&#x150;">
+<!ENTITY odblac "&#x151;">
+<!ENTITY OElig "&#x152;">
+<!ENTITY oelig "&#x153;">
+<!ENTITY Racute "&#x154;">
+<!ENTITY racute "&#x155;">
+<!ENTITY Rcedil "&#x156;">
+<!ENTITY rcedil "&#x157;">
+<!ENTITY Rcaron "&#x158;">
+<!ENTITY rcaron "&#x159;">
+<!ENTITY Sacute "&#x15A;">
+<!ENTITY sacute "&#x15B;">
+<!ENTITY Scirc "&#x15C;">
+<!ENTITY scirc "&#x15D;">
+<!ENTITY Scedil "&#x15E;">
+<!ENTITY scedil "&#x15F;">
+<!ENTITY Scaron "&#x160;">
+<!ENTITY scaron "&#x161;">
+<!ENTITY Tcedil "&#x162;">
+<!ENTITY tcedil "&#x163;">
+<!ENTITY Tcaron "&#x164;">
+<!ENTITY tcaron "&#x165;">
+<!ENTITY Tstrok "&#x166;">
+<!ENTITY tstrok "&#x167;">
+<!ENTITY Utilde "&#x168;">
+<!ENTITY utilde "&#x169;">
+<!ENTITY Umacr "&#x16A;">
+<!ENTITY umacr "&#x16B;">
+<!ENTITY Ubreve "&#x16C;">
+<!ENTITY ubreve "&#x16D;">
+<!ENTITY Uring "&#x16E;">
+<!ENTITY uring "&#x16F;">
+<!ENTITY Udblac "&#x170;">
+<!ENTITY udblac "&#x171;">
+<!ENTITY Uogon "&#x172;">
+<!ENTITY uogon "&#x173;">
+<!ENTITY Wcirc "&#x174;">
+<!ENTITY wcirc "&#x175;">
+<!ENTITY Ycirc "&#x176;">
+<!ENTITY ycirc "&#x177;">
+<!ENTITY Yuml "&#x178;">
+<!ENTITY Zacute "&#x179;">
+<!ENTITY zacute "&#x17A;">
+<!ENTITY Zdot "&#x17B;">
+<!ENTITY zdot "&#x17C;">
+<!ENTITY Zcaron "&#x17D;">
+<!ENTITY zcaron "&#x17E;">
+<!ENTITY fnof "&#x192;">
+<!ENTITY imped "&#x1B5;">
+<!ENTITY gacute "&#x1F5;">
+<!ENTITY circ "&#x2C6;">
+<!ENTITY caron "&#x2C7;"><!ENTITY Hacek "&#x2C7;">
+<!ENTITY breve "&#x2D8;"><!ENTITY Breve "&#x2D8;">
+<!ENTITY dot "&#x2D9;"><!ENTITY DiacriticalDot "&#x2D9;">
+<!ENTITY ring "&#x2DA;">
+<!ENTITY ogon "&#x2DB;">
+<!ENTITY tilde "&#x2DC;"><!ENTITY DiacriticalTilde "&#x2DC;">
+<!ENTITY dblac "&#x2DD;"><!ENTITY DiacriticalDoubleAcute "&#x2DD;">
+<!ENTITY DownBreve " &#x311;">
+<!ENTITY UnderBar " &#x332;">
+<!ENTITY Alpha "&#x391;">
+<!ENTITY Beta "&#x392;">
+<!ENTITY Gamma "&#x393;">
+<!ENTITY Delta "&#x394;">
+<!ENTITY Epsilon "&#x395;">
+<!ENTITY Zeta "&#x396;">
+<!ENTITY Eta "&#x397;">
+<!ENTITY Theta "&#x398;">
+<!ENTITY Iota "&#x399;">
+<!ENTITY Kappa "&#x39A;">
+<!ENTITY Lambda "&#x39B;">
+<!ENTITY Mu "&#x39C;">
+<!ENTITY Nu "&#x39D;">
+<!ENTITY Xi "&#x39E;">
+<!ENTITY Omicron "&#x39F;">
+<!ENTITY Pi "&#x3A0;">
+<!ENTITY Rho "&#x3A1;">
+<!ENTITY Sigma "&#x3A3;">
+<!ENTITY Tau "&#x3A4;">
+<!ENTITY Upsilon "&#x3A5;">
+<!ENTITY Phi "&#x3A6;">
+<!ENTITY Chi "&#x3A7;">
+<!ENTITY Psi "&#x3A8;">
+<!ENTITY Omega "&#x3A9;">
+<!ENTITY alpha "&#x3B1;">
+<!ENTITY beta "&#x3B2;">
+<!ENTITY gamma "&#x3B3;">
+<!ENTITY delta "&#x3B4;">
+<!ENTITY epsilon "&#x3B5;"><!ENTITY epsiv "&#x3B5;"><!ENTITY varepsilon "&#x3B5;">
+<!ENTITY zeta "&#x3B6;">
+<!ENTITY eta "&#x3B7;">
+<!ENTITY theta "&#x3B8;">
+<!ENTITY iota "&#x3B9;">
+<!ENTITY kappa "&#x3BA;">
+<!ENTITY lambda "&#x3BB;">
+<!ENTITY mu "&#x3BC;">
+<!ENTITY nu "&#x3BD;">
+<!ENTITY xi "&#x3BE;">
+<!ENTITY omicron "&#x3BF;">
+<!ENTITY pi "&#x3C0;">
+<!ENTITY rho "&#x3C1;">
+<!ENTITY sigmaf "&#x3C2;"><!ENTITY sigmav "&#x3C2;"><!ENTITY varsigma "&#x3C2;">
+<!ENTITY sigma "&#x3C3;">
+<!ENTITY tau "&#x3C4;">
+<!ENTITY upsilon "&#x3C5;"><!ENTITY upsi "&#x3C5;">
+<!ENTITY phiv "&#x3C6;"><!ENTITY varphi "&#x3C6;">
+<!ENTITY chi "&#x3C7;">
+<!ENTITY psi "&#x3C8;">
+<!ENTITY omega "&#x3C9;">
+<!ENTITY thetasym "&#x3D1;"><!ENTITY thetav "&#x3D1;"><!ENTITY vartheta "&#x3D1;">
+<!ENTITY upsih "&#x3D2;"><!ENTITY Upsi "&#x3D2;">
+<!ENTITY straightphi "&#x3D5;">
+<!ENTITY piv "&#x3D6;"><!ENTITY varpi "&#x3D6;">
+<!ENTITY Gammad "&#x3DC;">
+<!ENTITY gammad "&#x3DD;"><!ENTITY digamma "&#x3DD;">
+<!ENTITY kappav "&#x3F0;"><!ENTITY varkappa "&#x3F0;">
+<!ENTITY rhov "&#x3F1;"><!ENTITY varrho "&#x3F1;">
+<!ENTITY epsi "&#x3F5;"><!ENTITY straightepsilon "&#x3F5;">
+<!ENTITY bepsi "&#x3F6;"><!ENTITY backepsilon "&#x3F6;">
+<!ENTITY IOcy "&#x401;">
+<!ENTITY DJcy "&#x402;">
+<!ENTITY GJcy "&#x403;">
+<!ENTITY Jukcy "&#x404;">
+<!ENTITY DScy "&#x405;">
+<!ENTITY Iukcy "&#x406;">
+<!ENTITY YIcy "&#x407;">
+<!ENTITY Jsercy "&#x408;">
+<!ENTITY LJcy "&#x409;">
+<!ENTITY NJcy "&#x40A;">
+<!ENTITY TSHcy "&#x40B;">
+<!ENTITY KJcy "&#x40C;">
+<!ENTITY Ubrcy "&#x40E;">
+<!ENTITY DZcy "&#x40F;">
+<!ENTITY Acy "&#x410;">
+<!ENTITY Bcy "&#x411;">
+<!ENTITY Vcy "&#x412;">
+<!ENTITY Gcy "&#x413;">
+<!ENTITY Dcy "&#x414;">
+<!ENTITY IEcy "&#x415;">
+<!ENTITY ZHcy "&#x416;">
+<!ENTITY Zcy "&#x417;">
+<!ENTITY Icy "&#x418;">
+<!ENTITY Jcy "&#x419;">
+<!ENTITY Kcy "&#x41A;">
+<!ENTITY Lcy "&#x41B;">
+<!ENTITY Mcy "&#x41C;">
+<!ENTITY Ncy "&#x41D;">
+<!ENTITY Ocy "&#x41E;">
+<!ENTITY Pcy "&#x41F;">
+<!ENTITY Rcy "&#x420;">
+<!ENTITY Scy "&#x421;">
+<!ENTITY Tcy "&#x422;">
+<!ENTITY Ucy "&#x423;">
+<!ENTITY Fcy "&#x424;">
+<!ENTITY KHcy "&#x425;">
+<!ENTITY TScy "&#x426;">
+<!ENTITY CHcy "&#x427;">
+<!ENTITY SHcy "&#x428;">
+<!ENTITY SHCHcy "&#x429;">
+<!ENTITY HARDcy "&#x42A;">
+<!ENTITY Ycy "&#x42B;">
+<!ENTITY SOFTcy "&#x42C;">
+<!ENTITY Ecy "&#x42D;">
+<!ENTITY YUcy "&#x42E;">
+<!ENTITY YAcy "&#x42F;">
+<!ENTITY acy "&#x430;">
+<!ENTITY bcy "&#x431;">
+<!ENTITY vcy "&#x432;">
+<!ENTITY gcy "&#x433;">
+<!ENTITY dcy "&#x434;">
+<!ENTITY iecy "&#x435;">
+<!ENTITY zhcy "&#x436;">
+<!ENTITY zcy "&#x437;">
+<!ENTITY icy "&#x438;">
+<!ENTITY jcy "&#x439;">
+<!ENTITY kcy "&#x43A;">
+<!ENTITY lcy "&#x43B;">
+<!ENTITY mcy "&#x43C;">
+<!ENTITY ncy "&#x43D;">
+<!ENTITY ocy "&#x43E;">
+<!ENTITY pcy "&#x43F;">
+<!ENTITY rcy "&#x440;">
+<!ENTITY scy "&#x441;">
+<!ENTITY tcy "&#x442;">
+<!ENTITY ucy "&#x443;">
+<!ENTITY fcy "&#x444;">
+<!ENTITY khcy "&#x445;">
+<!ENTITY tscy "&#x446;">
+<!ENTITY chcy "&#x447;">
+<!ENTITY shcy "&#x448;">
+<!ENTITY shchcy "&#x449;">
+<!ENTITY hardcy "&#x44A;">
+<!ENTITY ycy "&#x44B;">
+<!ENTITY softcy "&#x44C;">
+<!ENTITY ecy "&#x44D;">
+<!ENTITY yucy "&#x44E;">
+<!ENTITY yacy "&#x44F;">
+<!ENTITY iocy "&#x451;">
+<!ENTITY djcy "&#x452;">
+<!ENTITY gjcy "&#x453;">
+<!ENTITY jukcy "&#x454;">
+<!ENTITY dscy "&#x455;">
+<!ENTITY iukcy "&#x456;">
+<!ENTITY yicy "&#x457;">
+<!ENTITY jsercy "&#x458;">
+<!ENTITY ljcy "&#x459;">
+<!ENTITY njcy "&#x45A;">
+<!ENTITY tshcy "&#x45B;">
+<!ENTITY kjcy "&#x45C;">
+<!ENTITY ubrcy "&#x45E;">
+<!ENTITY dzcy "&#x45F;">
+<!ENTITY ensp "&#x2002;">
+<!ENTITY emsp "&#x2003;">
+<!ENTITY emsp13 "&#x2004;">
+<!ENTITY emsp14 "&#x2005;">
+<!ENTITY numsp "&#x2007;">
+<!ENTITY puncsp "&#x2008;">
+<!ENTITY thinsp "&#x2009;"><!ENTITY ThinSpace "&#x2009;">
+<!ENTITY ThickSpace "&#x2009;&#x200A;&#x200A;">
+<!ENTITY hairsp "&#x200A;"><!ENTITY VeryThinSpace "&#x200A;">
+<!ENTITY ZeroWidthSpace "&#x200B;"><!ENTITY NegativeMediumSpace "&#x200B;"><!ENTITY NegativeThickSpace "&#x200B;"><!ENTITY NegativeThinSpace "&#x200B;"><!ENTITY NegativeVeryThinSpace "&#x200B;">
+<!ENTITY zwnj "&#x200C;">
+<!ENTITY zwj "&#x200D;">
+<!ENTITY lrm "&#x200E;">
+<!ENTITY rlm "&#x200F;">
+<!ENTITY hyphen "&#x2010;"><!ENTITY dash "&#x2010;">
+<!ENTITY ndash "&#x2013;">
+<!ENTITY mdash "&#x2014;">
+<!ENTITY horbar "&#x2015;">
+<!ENTITY Verbar "&#x2016;"><!ENTITY Vert "&#x2016;">
+<!ENTITY lsquo "&#x2018;"><!ENTITY OpenCurlyQuote "&#x2018;">
+<!ENTITY rsquo "&#x2019;"><!ENTITY rsquor "&#x2019;"><!ENTITY CloseCurlyQuote "&#x2019;">
+<!ENTITY sbquo "&#x201A;"><!ENTITY lsquor "&#x201A;">
+<!ENTITY ldquo "&#x201C;"><!ENTITY OpenCurlyDoubleQuote "&#x201C;">
+<!ENTITY rdquo "&#x201D;"><!ENTITY rdquor "&#x201D;"><!ENTITY CloseCurlyDoubleQuote "&#x201D;">
+<!ENTITY bdquo "&#x201E;"><!ENTITY ldquor "&#x201E;">
+<!ENTITY dagger "&#x2020;">
+<!ENTITY Dagger "&#x2021;"><!ENTITY ddagger "&#x2021;">
+<!ENTITY bull "&#x2022;"><!ENTITY bullet "&#x2022;">
+<!ENTITY nldr "&#x2025;">
+<!ENTITY hellip "&#x2026;"><!ENTITY mldr "&#x2026;">
+<!ENTITY permil "&#x2030;">
+<!ENTITY pertenk "&#x2031;">
+<!ENTITY prime "&#x2032;">
+<!ENTITY Prime "&#x2033;">
+<!ENTITY tprime "&#x2034;">
+<!ENTITY bprime "&#x2035;"><!ENTITY backprime "&#x2035;">
+<!ENTITY lsaquo "&#x2039;">
+<!ENTITY rsaquo "&#x203A;">
+<!ENTITY oline "&#x203E;">
+<!ENTITY caret "&#x2041;">
+<!ENTITY hybull "&#x2043;">
+<!ENTITY frasl "&#x2044;">
+<!ENTITY bsemi "&#x204F;">
+<!ENTITY qprime "&#x2057;">
+<!ENTITY MediumSpace "&#x205F;">
+<!ENTITY NoBreak "&#x2060;">
+<!ENTITY af "&#x2061;"><!ENTITY ApplyFunction "&#x2061;">
+<!ENTITY it "&#x2062;"><!ENTITY InvisibleTimes "&#x2062;">
+<!ENTITY ic "&#x2063;"><!ENTITY InvisibleComma "&#x2063;">
+<!ENTITY euro "&#x20AC;">
+<!ENTITY tdot " &#x20DB;"><!ENTITY TripleDot " &#x20DB;">
+<!ENTITY DotDot " &#x20DC;">
+<!ENTITY Copf "&#x2102;"><!ENTITY complexes "&#x2102;">
+<!ENTITY incare "&#x2105;">
+<!ENTITY gscr "&#x210A;">
+<!ENTITY Hscr "&#x210B;"><!ENTITY hamilt "&#x210B;"><!ENTITY HilbertSpace "&#x210B;">
+<!ENTITY Hfr "&#x210C;"><!ENTITY Poincareplane "&#x210C;">
+<!ENTITY Hopf "&#x210D;"><!ENTITY quaternions "&#x210D;">
+<!ENTITY planckh "&#x210E;">
+<!ENTITY planck "&#x210F;"><!ENTITY plankv "&#x210F;"><!ENTITY hbar "&#x210F;"><!ENTITY hslash "&#x210F;">
+<!ENTITY Iscr "&#x2110;"><!ENTITY imagline "&#x2110;">
+<!ENTITY image "&#x2111;"><!ENTITY Ifr "&#x2111;"><!ENTITY Im "&#x2111;"><!ENTITY imagpart "&#x2111;">
+<!ENTITY Lscr "&#x2112;"><!ENTITY lagran "&#x2112;"><!ENTITY Laplacetrf "&#x2112;">
+<!ENTITY ell "&#x2113;">
+<!ENTITY Nopf "&#x2115;"><!ENTITY naturals "&#x2115;">
+<!ENTITY numero "&#x2116;">
+<!ENTITY copysr "&#x2117;">
+<!ENTITY weierp "&#x2118;"><!ENTITY wp "&#x2118;">
+<!ENTITY Popf "&#x2119;"><!ENTITY primes "&#x2119;">
+<!ENTITY Qopf "&#x211A;"><!ENTITY rationals "&#x211A;">
+<!ENTITY Rscr "&#x211B;"><!ENTITY realine "&#x211B;">
+<!ENTITY real "&#x211C;"><!ENTITY Rfr "&#x211C;"><!ENTITY Re "&#x211C;"><!ENTITY realpart "&#x211C;">
+<!ENTITY Ropf "&#x211D;"><!ENTITY reals "&#x211D;">
+<!ENTITY rx "&#x211E;">
+<!ENTITY trade "&#x2122;">
+<!ENTITY Zopf "&#x2124;"><!ENTITY integers "&#x2124;">
+<!ENTITY ohm "&#x2126;">
+<!ENTITY mho "&#x2127;">
+<!ENTITY Zfr "&#x2128;"><!ENTITY zeetrf "&#x2128;">
+<!ENTITY iiota "&#x2129;">
+<!ENTITY angst "&#x212B;">
+<!ENTITY Bscr "&#x212C;"><!ENTITY bernou "&#x212C;"><!ENTITY Bernoullis "&#x212C;">
+<!ENTITY Cfr "&#x212D;"><!ENTITY Cayleys "&#x212D;">
+<!ENTITY escr "&#x212F;">
+<!ENTITY Escr "&#x2130;"><!ENTITY expectation "&#x2130;">
+<!ENTITY Fscr "&#x2131;"><!ENTITY Fouriertrf "&#x2131;">
+<!ENTITY Mscr "&#x2133;"><!ENTITY phmmat "&#x2133;"><!ENTITY Mellintrf "&#x2133;">
+<!ENTITY oscr "&#x2134;"><!ENTITY order "&#x2134;"><!ENTITY orderof "&#x2134;">
+<!ENTITY alefsym "&#x2135;"><!ENTITY aleph "&#x2135;">
+<!ENTITY beth "&#x2136;">
+<!ENTITY gimel "&#x2137;">
+<!ENTITY daleth "&#x2138;">
+<!ENTITY DD "&#x2145;"><!ENTITY CapitalDifferentialD "&#x2145;">
+<!ENTITY dd "&#x2146;"><!ENTITY DifferentialD "&#x2146;">
+<!ENTITY ee "&#x2147;"><!ENTITY ExponentialE "&#x2147;"><!ENTITY exponentiale "&#x2147;">
+<!ENTITY ii "&#x2148;"><!ENTITY ImaginaryI "&#x2148;">
+<!ENTITY frac13 "&#x2153;">
+<!ENTITY frac23 "&#x2154;">
+<!ENTITY frac15 "&#x2155;">
+<!ENTITY frac25 "&#x2156;">
+<!ENTITY frac35 "&#x2157;">
+<!ENTITY frac45 "&#x2158;">
+<!ENTITY frac16 "&#x2159;">
+<!ENTITY frac56 "&#x215A;">
+<!ENTITY frac18 "&#x215B;">
+<!ENTITY frac38 "&#x215C;">
+<!ENTITY frac58 "&#x215D;">
+<!ENTITY frac78 "&#x215E;">
+<!ENTITY larr "&#x2190;"><!ENTITY LeftArrow "&#x2190;"><!ENTITY leftarrow "&#x2190;">
+<!ENTITY uarr "&#x2191;"><!ENTITY UpArrow "&#x2191;"><!ENTITY uparrow "&#x2191;">
+<!ENTITY rarr "&#x2192;"><!ENTITY RightArrow "&#x2192;"><!ENTITY rightarrow "&#x2192;">
+<!ENTITY darr "&#x2193;"><!ENTITY DownArrow "&#x2193;"><!ENTITY downarrow "&#x2193;">
+<!ENTITY harr "&#x2194;"><!ENTITY LeftRightArrow "&#x2194;"><!ENTITY leftrightarrow "&#x2194;">
+<!ENTITY varr "&#x2195;"><!ENTITY UpDownArrow "&#x2195;"><!ENTITY updownarrow "&#x2195;">
+<!ENTITY nwarr "&#x2196;"><!ENTITY nwarrow "&#x2196;"><!ENTITY UpperLeftArrow "&#x2196;">
+<!ENTITY nearr "&#x2197;"><!ENTITY nearrow "&#x2197;"><!ENTITY UpperRightArrow "&#x2197;">
+<!ENTITY searr "&#x2198;"><!ENTITY LowerRightArrow "&#x2198;"><!ENTITY searrow "&#x2198;">
+<!ENTITY swarr "&#x2199;"><!ENTITY LowerLeftArrow "&#x2199;"><!ENTITY swarrow "&#x2199;">
+<!ENTITY nlarr "&#x219A;"><!ENTITY nleftarrow "&#x219A;">
+<!ENTITY nrarr "&#x219B;"><!ENTITY nrightarrow "&#x219B;">
+<!ENTITY rarrw "&#x219D;"><!ENTITY rightsquigarrow "&#x219D;">
+<!ENTITY nrarrw "&#x219D;&#x338;">
+<!ENTITY Larr "&#x219E;"><!ENTITY twoheadleftarrow "&#x219E;">
+<!ENTITY Uarr "&#x219F;">
+<!ENTITY Rarr "&#x21A0;"><!ENTITY twoheadrightarrow "&#x21A0;">
+<!ENTITY Darr "&#x21A1;">
+<!ENTITY larrtl "&#x21A2;"><!ENTITY leftarrowtail "&#x21A2;">
+<!ENTITY rarrtl "&#x21A3;"><!ENTITY rightarrowtail "&#x21A3;">
+<!ENTITY mapstoleft "&#x21A4;"><!ENTITY LeftTeeArrow "&#x21A4;">
+<!ENTITY mapstoup "&#x21A5;"><!ENTITY UpTeeArrow "&#x21A5;">
+<!ENTITY map "&#x21A6;"><!ENTITY mapsto "&#x21A6;"><!ENTITY RightTeeArrow "&#x21A6;">
+<!ENTITY mapstodown "&#x21A7;"><!ENTITY DownTeeArrow "&#x21A7;">
+<!ENTITY larrhk "&#x21A9;"><!ENTITY hookleftarrow "&#x21A9;">
+<!ENTITY rarrhk "&#x21AA;"><!ENTITY hookrightarrow "&#x21AA;">
+<!ENTITY larrlp "&#x21AB;"><!ENTITY looparrowleft "&#x21AB;">
+<!ENTITY rarrlp "&#x21AC;"><!ENTITY looparrowright "&#x21AC;">
+<!ENTITY harrw "&#x21AD;"><!ENTITY leftrightsquigarrow "&#x21AD;">
+<!ENTITY nharr "&#x21AE;"><!ENTITY nleftrightarrow "&#x21AE;">
+<!ENTITY lsh "&#x21B0;"><!ENTITY Lsh "&#x21B0;">
+<!ENTITY rsh "&#x21B1;"><!ENTITY Rsh "&#x21B1;">
+<!ENTITY ldsh "&#x21B2;">
+<!ENTITY rdsh "&#x21B3;">
+<!ENTITY crarr "&#x21B5;">
+<!ENTITY cularr "&#x21B6;"><!ENTITY curvearrowleft "&#x21B6;">
+<!ENTITY curarr "&#x21B7;"><!ENTITY curvearrowright "&#x21B7;">
+<!ENTITY olarr "&#x21BA;"><!ENTITY circlearrowleft "&#x21BA;">
+<!ENTITY orarr "&#x21BB;"><!ENTITY circlearrowright "&#x21BB;">
+<!ENTITY lharu "&#x21BC;"><!ENTITY leftharpoonup "&#x21BC;"><!ENTITY LeftVector "&#x21BC;">
+<!ENTITY lhard "&#x21BD;"><!ENTITY DownLeftVector "&#x21BD;"><!ENTITY leftharpoondown "&#x21BD;">
+<!ENTITY uharr "&#x21BE;"><!ENTITY RightUpVector "&#x21BE;"><!ENTITY upharpoonright "&#x21BE;">
+<!ENTITY uharl "&#x21BF;"><!ENTITY LeftUpVector "&#x21BF;"><!ENTITY upharpoonleft "&#x21BF;">
+<!ENTITY rharu "&#x21C0;"><!ENTITY rightharpoonup "&#x21C0;"><!ENTITY RightVector "&#x21C0;">
+<!ENTITY rhard "&#x21C1;"><!ENTITY DownRightVector "&#x21C1;"><!ENTITY rightharpoondown "&#x21C1;">
+<!ENTITY dharr "&#x21C2;"><!ENTITY downharpoonright "&#x21C2;"><!ENTITY RightDownVector "&#x21C2;">
+<!ENTITY dharl "&#x21C3;"><!ENTITY downharpoonleft "&#x21C3;"><!ENTITY LeftDownVector "&#x21C3;">
+<!ENTITY rlarr "&#x21C4;"><!ENTITY RightArrowLeftArrow "&#x21C4;"><!ENTITY rightleftarrows "&#x21C4;">
+<!ENTITY udarr "&#x21C5;"><!ENTITY UpArrowDownArrow "&#x21C5;">
+<!ENTITY lrarr "&#x21C6;"><!ENTITY LeftArrowRightArrow "&#x21C6;"><!ENTITY leftrightarrows "&#x21C6;">
+<!ENTITY llarr "&#x21C7;"><!ENTITY leftleftarrows "&#x21C7;">
+<!ENTITY uuarr "&#x21C8;"><!ENTITY upuparrows "&#x21C8;">
+<!ENTITY rrarr "&#x21C9;"><!ENTITY rightrightarrows "&#x21C9;">
+<!ENTITY ddarr "&#x21CA;"><!ENTITY downdownarrows "&#x21CA;">
+<!ENTITY lrhar "&#x21CB;"><!ENTITY leftrightharpoons "&#x21CB;"><!ENTITY ReverseEquilibrium "&#x21CB;">
+<!ENTITY rlhar "&#x21CC;"><!ENTITY Equilibrium "&#x21CC;"><!ENTITY rightleftharpoons "&#x21CC;">
+<!ENTITY nlArr "&#x21CD;"><!ENTITY nLeftarrow "&#x21CD;">
+<!ENTITY nhArr "&#x21CE;"><!ENTITY nLeftrightarrow "&#x21CE;">
+<!ENTITY nrArr "&#x21CF;"><!ENTITY nRightarrow "&#x21CF;">
+<!ENTITY lArr "&#x21D0;"><!ENTITY DoubleLeftArrow "&#x21D0;"><!ENTITY Leftarrow "&#x21D0;">
+<!ENTITY uArr "&#x21D1;"><!ENTITY DoubleUpArrow "&#x21D1;"><!ENTITY Uparrow "&#x21D1;">
+<!ENTITY rArr "&#x21D2;"><!ENTITY DoubleRightArrow "&#x21D2;"><!ENTITY Implies "&#x21D2;"><!ENTITY Rightarrow "&#x21D2;">
+<!ENTITY dArr "&#x21D3;"><!ENTITY DoubleDownArrow "&#x21D3;"><!ENTITY Downarrow "&#x21D3;">
+<!ENTITY hArr "&#x21D4;"><!ENTITY iff "&#x21D4;"><!ENTITY DoubleLeftRightArrow "&#x21D4;"><!ENTITY Leftrightarrow "&#x21D4;">
+<!ENTITY vArr "&#x21D5;"><!ENTITY DoubleUpDownArrow "&#x21D5;"><!ENTITY Updownarrow "&#x21D5;">
+<!ENTITY nwArr "&#x21D6;">
+<!ENTITY neArr "&#x21D7;">
+<!ENTITY seArr "&#x21D8;">
+<!ENTITY swArr "&#x21D9;">
+<!ENTITY lAarr "&#x21DA;"><!ENTITY Lleftarrow "&#x21DA;">
+<!ENTITY rAarr "&#x21DB;"><!ENTITY Rrightarrow "&#x21DB;">
+<!ENTITY zigrarr "&#x21DD;">
+<!ENTITY larrb "&#x21E4;"><!ENTITY LeftArrowBar "&#x21E4;">
+<!ENTITY rarrb "&#x21E5;"><!ENTITY RightArrowBar "&#x21E5;">
+<!ENTITY duarr "&#x21F5;"><!ENTITY DownArrowUpArrow "&#x21F5;">
+<!ENTITY loarr "&#x21FD;">
+<!ENTITY roarr "&#x21FE;">
+<!ENTITY hoarr "&#x21FF;">
+<!ENTITY forall "&#x2200;"><!ENTITY ForAll "&#x2200;">
+<!ENTITY comp "&#x2201;"><!ENTITY complement "&#x2201;">
+<!ENTITY part "&#x2202;"><!ENTITY PartialD "&#x2202;">
+<!ENTITY npart "&#x2202;&#x338;">
+<!ENTITY exist "&#x2203;"><!ENTITY Exists "&#x2203;">
+<!ENTITY nexist "&#x2204;"><!ENTITY nexists "&#x2204;"><!ENTITY NotExists "&#x2204;">
+<!ENTITY empty "&#x2205;"><!ENTITY emptyv "&#x2205;"><!ENTITY emptyset "&#x2205;"><!ENTITY varnothing "&#x2205;">
+<!ENTITY nabla "&#x2207;"><!ENTITY Del "&#x2207;">
+<!ENTITY isin "&#x2208;"><!ENTITY isinv "&#x2208;"><!ENTITY Element "&#x2208;"><!ENTITY in "&#x2208;">
+<!ENTITY notin "&#x2209;"><!ENTITY notinva "&#x2209;"><!ENTITY NotElement "&#x2209;">
+<!ENTITY ni "&#x220B;"><!ENTITY niv "&#x220B;"><!ENTITY ReverseElement "&#x220B;"><!ENTITY SuchThat "&#x220B;">
+<!ENTITY notni "&#x220C;"><!ENTITY notniva "&#x220C;"><!ENTITY NotReverseElement "&#x220C;">
+<!ENTITY prod "&#x220F;"><!ENTITY Product "&#x220F;">
+<!ENTITY coprod "&#x2210;"><!ENTITY Coproduct "&#x2210;">
+<!ENTITY sum "&#x2211;"><!ENTITY Sum "&#x2211;">
+<!ENTITY minus "&#x2212;">
+<!ENTITY mnplus "&#x2213;"><!ENTITY MinusPlus "&#x2213;"><!ENTITY mp "&#x2213;">
+<!ENTITY plusdo "&#x2214;"><!ENTITY dotplus "&#x2214;">
+<!ENTITY setmn "&#x2216;"><!ENTITY ssetmn "&#x2216;"><!ENTITY Backslash "&#x2216;"><!ENTITY setminus "&#x2216;"><!ENTITY smallsetminus "&#x2216;">
+<!ENTITY lowast "&#x2217;">
+<!ENTITY compfn "&#x2218;"><!ENTITY SmallCircle "&#x2218;">
+<!ENTITY radic "&#x221A;"><!ENTITY Sqrt "&#x221A;">
+<!ENTITY prop "&#x221D;"><!ENTITY vprop "&#x221D;"><!ENTITY Proportional "&#x221D;"><!ENTITY propto "&#x221D;"><!ENTITY varpropto "&#x221D;">
+<!ENTITY infin "&#x221E;">
+<!ENTITY angrt "&#x221F;">
+<!ENTITY ang "&#x2220;"><!ENTITY angle "&#x2220;">
+<!ENTITY nang "&#x2220;&#x20D2;">
+<!ENTITY angmsd "&#x2221;"><!ENTITY measuredangle "&#x2221;">
+<!ENTITY angsph "&#x2222;">
+<!ENTITY mid "&#x2223;"><!ENTITY smid "&#x2223;"><!ENTITY shortmid "&#x2223;"><!ENTITY VerticalBar "&#x2223;">
+<!ENTITY nmid "&#x2224;"><!ENTITY nsmid "&#x2224;"><!ENTITY NotVerticalBar "&#x2224;"><!ENTITY nshortmid "&#x2224;">
+<!ENTITY spar "&#x2225;"><!ENTITY par "&#x2225;"><!ENTITY DoubleVerticalBar "&#x2225;"><!ENTITY parallel "&#x2225;"><!ENTITY shortparallel "&#x2225;">
+<!ENTITY npar "&#x2226;"><!ENTITY nspar "&#x2226;"><!ENTITY NotDoubleVerticalBar "&#x2226;"><!ENTITY nparallel "&#x2226;"><!ENTITY nshortparallel "&#x2226;">
+<!ENTITY and "&#x2227;"><!ENTITY wedge "&#x2227;">
+<!ENTITY or "&#x2228;"><!ENTITY vee "&#x2228;">
+<!ENTITY cap "&#x2229;">
+<!ENTITY caps "&#x2229;&#xFE00;">
+<!ENTITY cup "&#x222A;">
+<!ENTITY cups "&#x222A;&#xFE00;">
+<!ENTITY int "&#x222B;"><!ENTITY Integral "&#x222B;">
+<!ENTITY Int "&#x222C;">
+<!ENTITY tint "&#x222D;"><!ENTITY iiint "&#x222D;">
+<!ENTITY conint "&#x222E;"><!ENTITY ContourIntegral "&#x222E;"><!ENTITY oint "&#x222E;">
+<!ENTITY Conint "&#x222F;"><!ENTITY DoubleContourIntegral "&#x222F;">
+<!ENTITY Cconint "&#x2230;">
+<!ENTITY cwint "&#x2231;">
+<!ENTITY cwconint "&#x2232;"><!ENTITY ClockwiseContourIntegral "&#x2232;">
+<!ENTITY awconint "&#x2233;"><!ENTITY CounterClockwiseContourIntegral "&#x2233;">
+<!ENTITY there4 "&#x2234;"><!ENTITY Therefore "&#x2234;"><!ENTITY therefore "&#x2234;">
+<!ENTITY becaus "&#x2235;"><!ENTITY Because "&#x2235;"><!ENTITY because "&#x2235;">
+<!ENTITY ratio "&#x2236;">
+<!ENTITY Colon "&#x2237;"><!ENTITY Proportion "&#x2237;">
+<!ENTITY minusd "&#x2238;"><!ENTITY dotminus "&#x2238;">
+<!ENTITY mDDot "&#x223A;">
+<!ENTITY homtht "&#x223B;">
+<!ENTITY sim "&#x223C;"><!ENTITY thksim "&#x223C;"><!ENTITY thicksim "&#x223C;"><!ENTITY Tilde "&#x223C;">
+<!ENTITY nvsim "&#x223C;&#x20D2;">
+<!ENTITY bsim "&#x223D;"><!ENTITY backsim "&#x223D;">
+<!ENTITY ac "&#x223E;"><!ENTITY mstpos "&#x223E;">
+<!ENTITY acE "&#x223E;&#x333;">
+<!ENTITY acd "&#x223F;">
+<!ENTITY wreath "&#x2240;"><!ENTITY VerticalTilde "&#x2240;"><!ENTITY wr "&#x2240;">
+<!ENTITY nsim "&#x2241;"><!ENTITY NotTilde "&#x2241;">
+<!ENTITY esim "&#x2242;"><!ENTITY eqsim "&#x2242;"><!ENTITY EqualTilde "&#x2242;">
+<!ENTITY nesim "&#x2242;&#x338;"><!ENTITY NotEqualTilde "&#x2242;&#x338;">
+<!ENTITY sime "&#x2243;"><!ENTITY simeq "&#x2243;"><!ENTITY TildeEqual "&#x2243;">
+<!ENTITY nsime "&#x2244;"><!ENTITY NotTildeEqual "&#x2244;"><!ENTITY nsimeq "&#x2244;">
+<!ENTITY cong "&#x2245;"><!ENTITY TildeFullEqual "&#x2245;">
+<!ENTITY simne "&#x2246;">
+<!ENTITY ncong "&#x2247;"><!ENTITY NotTildeFullEqual "&#x2247;">
+<!ENTITY asymp "&#x2248;"><!ENTITY thkap "&#x2248;"><!ENTITY ap "&#x2248;"><!ENTITY approx "&#x2248;"><!ENTITY thickapprox "&#x2248;"><!ENTITY TildeTilde "&#x2248;">
+<!ENTITY nap "&#x2249;"><!ENTITY napprox "&#x2249;"><!ENTITY NotTildeTilde "&#x2249;">
+<!ENTITY ape "&#x224A;"><!ENTITY approxeq "&#x224A;">
+<!ENTITY apid "&#x224B;">
+<!ENTITY napid "&#x224B;&#x338;">
+<!ENTITY bcong "&#x224C;"><!ENTITY backcong "&#x224C;">
+<!ENTITY asympeq "&#x224D;"><!ENTITY CupCap "&#x224D;">
+<!ENTITY nvap "&#x224D;&#x20D2;">
+<!ENTITY bump "&#x224E;"><!ENTITY Bumpeq "&#x224E;"><!ENTITY HumpDownHump "&#x224E;">
+<!ENTITY nbump "&#x224E;&#x338;"><!ENTITY NotHumpDownHump "&#x224E;&#x338;">
+<!ENTITY bumpe "&#x224F;"><!ENTITY bumpeq "&#x224F;"><!ENTITY HumpEqual "&#x224F;">
+<!ENTITY nbumpe "&#x224F;&#x338;"><!ENTITY NotHumpEqual "&#x224F;&#x338;">
+<!ENTITY esdot "&#x2250;"><!ENTITY doteq "&#x2250;"><!ENTITY DotEqual "&#x2250;">
+<!ENTITY nedot "&#x2250;&#x338;">
+<!ENTITY eDot "&#x2251;"><!ENTITY doteqdot "&#x2251;">
+<!ENTITY efDot "&#x2252;"><!ENTITY fallingdotseq "&#x2252;">
+<!ENTITY erDot "&#x2253;"><!ENTITY risingdotseq "&#x2253;">
+<!ENTITY colone "&#x2254;"><!ENTITY Assign "&#x2254;"><!ENTITY coloneq "&#x2254;">
+<!ENTITY ecolon "&#x2255;"><!ENTITY eqcolon "&#x2255;">
+<!ENTITY ecir "&#x2256;"><!ENTITY eqcirc "&#x2256;">
+<!ENTITY cire "&#x2257;"><!ENTITY circeq "&#x2257;">
+<!ENTITY wedgeq "&#x2259;">
+<!ENTITY veeeq "&#x225A;">
+<!ENTITY trie "&#x225C;"><!ENTITY triangleq "&#x225C;">
+<!ENTITY equest "&#x225F;"><!ENTITY questeq "&#x225F;">
+<!ENTITY ne "&#x2260;"><!ENTITY NotEqual "&#x2260;">
+<!ENTITY equiv "&#x2261;"><!ENTITY Congruent "&#x2261;">
+<!ENTITY bnequiv "&#x2261;&#x20E5;">
+<!ENTITY nequiv "&#x2262;"><!ENTITY NotCongruent "&#x2262;">
+<!ENTITY le "&#x2264;"><!ENTITY leq "&#x2264;">
+<!ENTITY nvle "&#x2264;&#x20D2;">
+<!ENTITY ge "&#x2265;"><!ENTITY geq "&#x2265;"><!ENTITY GreaterEqual "&#x2265;">
+<!ENTITY nvge "&#x2265;&#x20D2;">
+<!ENTITY lE "&#x2266;"><!ENTITY leqq "&#x2266;"><!ENTITY LessFullEqual "&#x2266;">
+<!ENTITY nlE "&#x2266;&#x338;"><!ENTITY nleqq "&#x2266;&#x338;"><!ENTITY NotGreaterFullEqual "&#x2266;&#x338;">
+<!ENTITY gE "&#x2267;"><!ENTITY geqq "&#x2267;"><!ENTITY GreaterFullEqual "&#x2267;">
+<!ENTITY ngE "&#x2267;&#x338;"><!ENTITY ngeqq "&#x2267;&#x338;">
+<!ENTITY lnE "&#x2268;"><!ENTITY lneqq "&#x2268;">
+<!ENTITY lvnE "&#x2268;&#xFE00;"><!ENTITY lvertneqq "&#x2268;&#xFE00;">
+<!ENTITY gnE "&#x2269;"><!ENTITY gneqq "&#x2269;">
+<!ENTITY gvnE "&#x2269;&#xFE00;"><!ENTITY gvertneqq "&#x2269;&#xFE00;">
+<!ENTITY Lt "&#x226A;"><!ENTITY ll "&#x226A;"><!ENTITY NestedLessLess "&#x226A;">
+<!ENTITY nLt "&#x226A;&#x20D2;">
+<!ENTITY nLtv "&#x226A;&#x338;"><!ENTITY NotLessLess "&#x226A;&#x338;">
+<!ENTITY Gt "&#x226B;"><!ENTITY gg "&#x226B;"><!ENTITY NestedGreaterGreater "&#x226B;">
+<!ENTITY nGt "&#x226B;&#x20D2;">
+<!ENTITY nGtv "&#x226B;&#x338;"><!ENTITY NotGreaterGreater "&#x226B;&#x338;">
+<!ENTITY twixt "&#x226C;"><!ENTITY between "&#x226C;">
+<!ENTITY NotCupCap "&#x226D;">
+<!ENTITY nlt "&#x226E;"><!ENTITY nless "&#x226E;"><!ENTITY NotLess "&#x226E;">
+<!ENTITY ngt "&#x226F;"><!ENTITY ngtr "&#x226F;"><!ENTITY NotGreater "&#x226F;">
+<!ENTITY nle "&#x2270;"><!ENTITY nleq "&#x2270;"><!ENTITY NotLessEqual "&#x2270;">
+<!ENTITY nge "&#x2271;"><!ENTITY ngeq "&#x2271;"><!ENTITY NotGreaterEqual "&#x2271;">
+<!ENTITY lsim "&#x2272;"><!ENTITY lesssim "&#x2272;"><!ENTITY LessTilde "&#x2272;">
+<!ENTITY gsim "&#x2273;"><!ENTITY GreaterTilde "&#x2273;"><!ENTITY gtrsim "&#x2273;">
+<!ENTITY nlsim "&#x2274;"><!ENTITY NotLessTilde "&#x2274;">
+<!ENTITY ngsim "&#x2275;"><!ENTITY NotGreaterTilde "&#x2275;">
+<!ENTITY lg "&#x2276;"><!ENTITY LessGreater "&#x2276;"><!ENTITY lessgtr "&#x2276;">
+<!ENTITY gl "&#x2277;"><!ENTITY GreaterLess "&#x2277;"><!ENTITY gtrless "&#x2277;">
+<!ENTITY ntlg "&#x2278;"><!ENTITY NotLessGreater "&#x2278;">
+<!ENTITY ntgl "&#x2279;"><!ENTITY NotGreaterLess "&#x2279;">
+<!ENTITY pr "&#x227A;"><!ENTITY prec "&#x227A;"><!ENTITY Precedes "&#x227A;">
+<!ENTITY sc "&#x227B;"><!ENTITY succ "&#x227B;"><!ENTITY Succeeds "&#x227B;">
+<!ENTITY prcue "&#x227C;"><!ENTITY preccurlyeq "&#x227C;"><!ENTITY PrecedesSlantEqual "&#x227C;">
+<!ENTITY sccue "&#x227D;"><!ENTITY succcurlyeq "&#x227D;"><!ENTITY SucceedsSlantEqual "&#x227D;">
+<!ENTITY prsim "&#x227E;"><!ENTITY PrecedesTilde "&#x227E;"><!ENTITY precsim "&#x227E;">
+<!ENTITY scsim "&#x227F;"><!ENTITY SucceedsTilde "&#x227F;"><!ENTITY succsim "&#x227F;">
+<!ENTITY NotSucceedsTilde "&#x227F;&#x338;">
+<!ENTITY npr "&#x2280;"><!ENTITY NotPrecedes "&#x2280;"><!ENTITY nprec "&#x2280;">
+<!ENTITY nsc "&#x2281;"><!ENTITY NotSucceeds "&#x2281;"><!ENTITY nsucc "&#x2281;">
+<!ENTITY sub "&#x2282;"><!ENTITY subset "&#x2282;">
+<!ENTITY vnsub "&#x2282;&#x20D2;"><!ENTITY NotSubset "&#x2282;&#x20D2;"><!ENTITY nsubset "&#x2282;&#x20D2;">
+<!ENTITY sup "&#x2283;"><!ENTITY Superset "&#x2283;"><!ENTITY supset "&#x2283;">
+<!ENTITY vnsup "&#x2283;&#x20D2;"><!ENTITY NotSuperset "&#x2283;&#x20D2;"><!ENTITY nsupset "&#x2283;&#x20D2;">
+<!ENTITY suphsol "&#x2283;&#x2F;">
+<!ENTITY nsub "&#x2284;">
+<!ENTITY nsup "&#x2285;">
+<!ENTITY sube "&#x2286;"><!ENTITY subseteq "&#x2286;"><!ENTITY SubsetEqual "&#x2286;">
+<!ENTITY supe "&#x2287;"><!ENTITY SupersetEqual "&#x2287;"><!ENTITY supseteq "&#x2287;">
+<!ENTITY nsube "&#x2288;"><!ENTITY NotSubsetEqual "&#x2288;"><!ENTITY nsubseteq "&#x2288;">
+<!ENTITY nsupe "&#x2289;"><!ENTITY NotSupersetEqual "&#x2289;"><!ENTITY nsupseteq "&#x2289;">
+<!ENTITY subne "&#x228A;"><!ENTITY subsetneq "&#x228A;">
+<!ENTITY vsubne "&#x228A;&#xFE00;"><!ENTITY varsubsetneq "&#x228A;&#xFE00;">
+<!ENTITY supne "&#x228B;"><!ENTITY supsetneq "&#x228B;">
+<!ENTITY vsupne "&#x228B;&#xFE00;"><!ENTITY varsupsetneq "&#x228B;&#xFE00;">
+<!ENTITY cupdot "&#x228D;">
+<!ENTITY uplus "&#x228E;"><!ENTITY UnionPlus "&#x228E;">
+<!ENTITY sqsub "&#x228F;"><!ENTITY sqsubset "&#x228F;"><!ENTITY SquareSubset "&#x228F;">
+<!ENTITY NotSquareSubset "&#x228F;&#x338;">
+<!ENTITY sqsup "&#x2290;"><!ENTITY sqsupset "&#x2290;"><!ENTITY SquareSuperset "&#x2290;">
+<!ENTITY NotSquareSuperset "&#x2290;&#x338;">
+<!ENTITY sqsube "&#x2291;"><!ENTITY sqsubseteq "&#x2291;"><!ENTITY SquareSubsetEqual "&#x2291;">
+<!ENTITY sqsupe "&#x2292;"><!ENTITY sqsupseteq "&#x2292;"><!ENTITY SquareSupersetEqual "&#x2292;">
+<!ENTITY sqcap "&#x2293;"><!ENTITY SquareIntersection "&#x2293;">
+<!ENTITY sqcaps "&#x2293;&#xFE00;">
+<!ENTITY sqcup "&#x2294;"><!ENTITY SquareUnion "&#x2294;">
+<!ENTITY sqcups "&#x2294;&#xFE00;">
+<!ENTITY oplus "&#x2295;"><!ENTITY CirclePlus "&#x2295;">
+<!ENTITY ominus "&#x2296;"><!ENTITY CircleMinus "&#x2296;">
+<!ENTITY otimes "&#x2297;"><!ENTITY CircleTimes "&#x2297;">
+<!ENTITY osol "&#x2298;">
+<!ENTITY odot "&#x2299;"><!ENTITY CircleDot "&#x2299;">
+<!ENTITY ocir "&#x229A;"><!ENTITY circledcirc "&#x229A;">
+<!ENTITY oast "&#x229B;"><!ENTITY circledast "&#x229B;">
+<!ENTITY odash "&#x229D;"><!ENTITY circleddash "&#x229D;">
+<!ENTITY plusb "&#x229E;"><!ENTITY boxplus "&#x229E;">
+<!ENTITY minusb "&#x229F;"><!ENTITY boxminus "&#x229F;">
+<!ENTITY timesb "&#x22A0;"><!ENTITY boxtimes "&#x22A0;">
+<!ENTITY sdotb "&#x22A1;"><!ENTITY dotsquare "&#x22A1;">
+<!ENTITY vdash "&#x22A2;"><!ENTITY RightTee "&#x22A2;">
+<!ENTITY dashv "&#x22A3;"><!ENTITY LeftTee "&#x22A3;">
+<!ENTITY top "&#x22A4;"><!ENTITY DownTee "&#x22A4;">
+<!ENTITY perp "&#x22A5;"><!ENTITY bottom "&#x22A5;"><!ENTITY bot "&#x22A5;"><!ENTITY UpTee "&#x22A5;">
+<!ENTITY models "&#x22A7;">
+<!ENTITY vDash "&#x22A8;"><!ENTITY DoubleRightTee "&#x22A8;">
+<!ENTITY Vdash "&#x22A9;">
+<!ENTITY Vvdash "&#x22AA;">
+<!ENTITY VDash "&#x22AB;">
+<!ENTITY nvdash "&#x22AC;">
+<!ENTITY nvDash "&#x22AD;">
+<!ENTITY nVdash "&#x22AE;">
+<!ENTITY nVDash "&#x22AF;">
+<!ENTITY prurel "&#x22B0;">
+<!ENTITY vltri "&#x22B2;"><!ENTITY LeftTriangle "&#x22B2;"><!ENTITY vartriangleleft "&#x22B2;">
+<!ENTITY vrtri "&#x22B3;"><!ENTITY RightTriangle "&#x22B3;"><!ENTITY vartriangleright "&#x22B3;">
+<!ENTITY ltrie "&#x22B4;"><!ENTITY LeftTriangleEqual "&#x22B4;"><!ENTITY trianglelefteq "&#x22B4;">
+<!ENTITY nvltrie "&#x22B4;&#x20D2;">
+<!ENTITY rtrie "&#x22B5;"><!ENTITY RightTriangleEqual "&#x22B5;"><!ENTITY trianglerighteq "&#x22B5;">
+<!ENTITY nvrtrie "&#x22B5;&#x20D2;">
+<!ENTITY origof "&#x22B6;">
+<!ENTITY imof "&#x22B7;">
+<!ENTITY mumap "&#x22B8;"><!ENTITY multimap "&#x22B8;">
+<!ENTITY hercon "&#x22B9;">
+<!ENTITY intcal "&#x22BA;"><!ENTITY intercal "&#x22BA;">
+<!ENTITY veebar "&#x22BB;">
+<!ENTITY barvee "&#x22BD;">
+<!ENTITY angrtvb "&#x22BE;">
+<!ENTITY lrtri "&#x22BF;">
+<!ENTITY xwedge "&#x22C0;"><!ENTITY bigwedge "&#x22C0;"><!ENTITY Wedge "&#x22C0;">
+<!ENTITY xvee "&#x22C1;"><!ENTITY bigvee "&#x22C1;"><!ENTITY Vee "&#x22C1;">
+<!ENTITY xcap "&#x22C2;"><!ENTITY bigcap "&#x22C2;"><!ENTITY Intersection "&#x22C2;">
+<!ENTITY xcup "&#x22C3;"><!ENTITY bigcup "&#x22C3;"><!ENTITY Union "&#x22C3;">
+<!ENTITY diam "&#x22C4;"><!ENTITY Diamond "&#x22C4;"><!ENTITY diamond "&#x22C4;">
+<!ENTITY sdot "&#x22C5;">
+<!ENTITY sstarf "&#x22C6;"><!ENTITY Star "&#x22C6;">
+<!ENTITY divonx "&#x22C7;"><!ENTITY divideontimes "&#x22C7;">
+<!ENTITY bowtie "&#x22C8;">
+<!ENTITY ltimes "&#x22C9;">
+<!ENTITY rtimes "&#x22CA;">
+<!ENTITY lthree "&#x22CB;"><!ENTITY leftthreetimes "&#x22CB;">
+<!ENTITY rthree "&#x22CC;"><!ENTITY rightthreetimes "&#x22CC;">
+<!ENTITY bsime "&#x22CD;"><!ENTITY backsimeq "&#x22CD;">
+<!ENTITY cuvee "&#x22CE;"><!ENTITY curlyvee "&#x22CE;">
+<!ENTITY cuwed "&#x22CF;"><!ENTITY curlywedge "&#x22CF;">
+<!ENTITY Sub "&#x22D0;"><!ENTITY Subset "&#x22D0;">
+<!ENTITY Sup "&#x22D1;"><!ENTITY Supset "&#x22D1;">
+<!ENTITY Cap "&#x22D2;">
+<!ENTITY Cup "&#x22D3;">
+<!ENTITY fork "&#x22D4;"><!ENTITY pitchfork "&#x22D4;">
+<!ENTITY epar "&#x22D5;">
+<!ENTITY ltdot "&#x22D6;"><!ENTITY lessdot "&#x22D6;">
+<!ENTITY gtdot "&#x22D7;"><!ENTITY gtrdot "&#x22D7;">
+<!ENTITY Ll "&#x22D8;">
+<!ENTITY nLl "&#x22D8;&#x338;">
+<!ENTITY Gg "&#x22D9;"><!ENTITY ggg "&#x22D9;">
+<!ENTITY nGg "&#x22D9;&#x338;">
+<!ENTITY leg "&#x22DA;"><!ENTITY lesseqgtr "&#x22DA;"><!ENTITY LessEqualGreater "&#x22DA;">
+<!ENTITY lesg "&#x22DA;&#xFE00;">
+<!ENTITY gel "&#x22DB;"><!ENTITY GreaterEqualLess "&#x22DB;"><!ENTITY gtreqless "&#x22DB;">
+<!ENTITY gesl "&#x22DB;&#xFE00;">
+<!ENTITY cuepr "&#x22DE;"><!ENTITY curlyeqprec "&#x22DE;">
+<!ENTITY cuesc "&#x22DF;"><!ENTITY curlyeqsucc "&#x22DF;">
+<!ENTITY nprcue "&#x22E0;"><!ENTITY NotPrecedesSlantEqual "&#x22E0;">
+<!ENTITY nsccue "&#x22E1;"><!ENTITY NotSucceedsSlantEqual "&#x22E1;">
+<!ENTITY nsqsube "&#x22E2;"><!ENTITY NotSquareSubsetEqual "&#x22E2;">
+<!ENTITY nsqsupe "&#x22E3;"><!ENTITY NotSquareSupersetEqual "&#x22E3;">
+<!ENTITY lnsim "&#x22E6;">
+<!ENTITY gnsim "&#x22E7;">
+<!ENTITY prnsim "&#x22E8;"><!ENTITY precnsim "&#x22E8;">
+<!ENTITY scnsim "&#x22E9;"><!ENTITY succnsim "&#x22E9;">
+<!ENTITY nltri "&#x22EA;"><!ENTITY NotLeftTriangle "&#x22EA;"><!ENTITY ntriangleleft "&#x22EA;">
+<!ENTITY nrtri "&#x22EB;"><!ENTITY NotRightTriangle "&#x22EB;"><!ENTITY ntriangleright "&#x22EB;">
+<!ENTITY nltrie "&#x22EC;"><!ENTITY NotLeftTriangleEqual "&#x22EC;"><!ENTITY ntrianglelefteq "&#x22EC;">
+<!ENTITY nrtrie "&#x22ED;"><!ENTITY NotRightTriangleEqual "&#x22ED;"><!ENTITY ntrianglerighteq "&#x22ED;">
+<!ENTITY vellip "&#x22EE;">
+<!ENTITY ctdot "&#x22EF;">
+<!ENTITY utdot "&#x22F0;">
+<!ENTITY dtdot "&#x22F1;">
+<!ENTITY disin "&#x22F2;">
+<!ENTITY isinsv "&#x22F3;">
+<!ENTITY isins "&#x22F4;">
+<!ENTITY isindot "&#x22F5;">
+<!ENTITY notindot "&#x22F5;&#x338;">
+<!ENTITY notinvc "&#x22F6;">
+<!ENTITY notinvb "&#x22F7;">
+<!ENTITY isinE "&#x22F9;">
+<!ENTITY notinE "&#x22F9;&#x338;">
+<!ENTITY nisd "&#x22FA;">
+<!ENTITY xnis "&#x22FB;">
+<!ENTITY nis "&#x22FC;">
+<!ENTITY notnivc "&#x22FD;">
+<!ENTITY notnivb "&#x22FE;">
+<!ENTITY barwed "&#x2305;"><!ENTITY barwedge "&#x2305;">
+<!ENTITY Barwed "&#x2306;"><!ENTITY doublebarwedge "&#x2306;">
+<!ENTITY lceil "&#x2308;"><!ENTITY LeftCeiling "&#x2308;">
+<!ENTITY rceil "&#x2309;"><!ENTITY RightCeiling "&#x2309;">
+<!ENTITY lfloor "&#x230A;"><!ENTITY LeftFloor "&#x230A;">
+<!ENTITY rfloor "&#x230B;"><!ENTITY RightFloor "&#x230B;">
+<!ENTITY drcrop "&#x230C;">
+<!ENTITY dlcrop "&#x230D;">
+<!ENTITY urcrop "&#x230E;">
+<!ENTITY ulcrop "&#x230F;">
+<!ENTITY bnot "&#x2310;">
+<!ENTITY profline "&#x2312;">
+<!ENTITY profsurf "&#x2313;">
+<!ENTITY telrec "&#x2315;">
+<!ENTITY target "&#x2316;">
+<!ENTITY ulcorn "&#x231C;"><!ENTITY ulcorner "&#x231C;">
+<!ENTITY urcorn "&#x231D;"><!ENTITY urcorner "&#x231D;">
+<!ENTITY dlcorn "&#x231E;"><!ENTITY llcorner "&#x231E;">
+<!ENTITY drcorn "&#x231F;"><!ENTITY lrcorner "&#x231F;">
+<!ENTITY frown "&#x2322;"><!ENTITY sfrown "&#x2322;">
+<!ENTITY smile "&#x2323;"><!ENTITY ssmile "&#x2323;">
+<!ENTITY cylcty "&#x232D;">
+<!ENTITY profalar "&#x232E;">
+<!ENTITY topbot "&#x2336;">
+<!ENTITY ovbar "&#x233D;">
+<!ENTITY solbar "&#x233F;">
+<!ENTITY angzarr "&#x237C;">
+<!ENTITY lmoust "&#x23B0;"><!ENTITY lmoustache "&#x23B0;">
+<!ENTITY rmoust "&#x23B1;"><!ENTITY rmoustache "&#x23B1;">
+<!ENTITY tbrk "&#x23B4;"><!ENTITY OverBracket "&#x23B4;">
+<!ENTITY bbrk "&#x23B5;"><!ENTITY UnderBracket "&#x23B5;">
+<!ENTITY bbrktbrk "&#x23B6;">
+<!ENTITY blank "&#x2423;">
+<!ENTITY oS "&#x24C8;"><!ENTITY circledS "&#x24C8;">
+<!ENTITY boxh "&#x2500;"><!ENTITY HorizontalLine "&#x2500;">
+<!ENTITY boxv "&#x2502;">
+<!ENTITY boxdr "&#x250C;">
+<!ENTITY boxdl "&#x2510;">
+<!ENTITY boxur "&#x2514;">
+<!ENTITY boxul "&#x2518;">
+<!ENTITY boxvr "&#x251C;">
+<!ENTITY boxvl "&#x2524;">
+<!ENTITY boxhd "&#x252C;">
+<!ENTITY boxhu "&#x2534;">
+<!ENTITY boxvh "&#x253C;">
+<!ENTITY boxH "&#x2550;">
+<!ENTITY boxV "&#x2551;">
+<!ENTITY boxdR "&#x2552;">
+<!ENTITY boxDr "&#x2553;">
+<!ENTITY boxDR "&#x2554;">
+<!ENTITY boxdL "&#x2555;">
+<!ENTITY boxDl "&#x2556;">
+<!ENTITY boxDL "&#x2557;">
+<!ENTITY boxuR "&#x2558;">
+<!ENTITY boxUr "&#x2559;">
+<!ENTITY boxUR "&#x255A;">
+<!ENTITY boxuL "&#x255B;">
+<!ENTITY boxUl "&#x255C;">
+<!ENTITY boxUL "&#x255D;">
+<!ENTITY boxvR "&#x255E;">
+<!ENTITY boxVr "&#x255F;">
+<!ENTITY boxVR "&#x2560;">
+<!ENTITY boxvL "&#x2561;">
+<!ENTITY boxVl "&#x2562;">
+<!ENTITY boxVL "&#x2563;">
+<!ENTITY boxHd "&#x2564;">
+<!ENTITY boxhD "&#x2565;">
+<!ENTITY boxHD "&#x2566;">
+<!ENTITY boxHu "&#x2567;">
+<!ENTITY boxhU "&#x2568;">
+<!ENTITY boxHU "&#x2569;">
+<!ENTITY boxvH "&#x256A;">
+<!ENTITY boxVh "&#x256B;">
+<!ENTITY boxVH "&#x256C;">
+<!ENTITY uhblk "&#x2580;">
+<!ENTITY lhblk "&#x2584;">
+<!ENTITY block "&#x2588;">
+<!ENTITY blk14 "&#x2591;">
+<!ENTITY blk12 "&#x2592;">
+<!ENTITY blk34 "&#x2593;">
+<!ENTITY square "&#x25A1;"><!ENTITY squ "&#x25A1;"><!ENTITY Square "&#x25A1;">
+<!ENTITY squarf "&#x25AA;"><!ENTITY squf "&#x25AA;"><!ENTITY FilledVerySmallSquare "&#x25AA;"><!ENTITY blacksquare "&#x25AA;">
+<!ENTITY EmptyVerySmallSquare "&#x25AB;">
+<!ENTITY rect "&#x25AD;">
+<!ENTITY marker "&#x25AE;">
+<!ENTITY fltns "&#x25B1;">
+<!ENTITY xutri "&#x25B3;"><!ENTITY bigtriangleup "&#x25B3;">
+<!ENTITY utrif "&#x25B4;"><!ENTITY blacktriangle "&#x25B4;">
+<!ENTITY utri "&#x25B5;"><!ENTITY triangle "&#x25B5;">
+<!ENTITY rtrif "&#x25B8;"><!ENTITY blacktriangleright "&#x25B8;">
+<!ENTITY rtri "&#x25B9;"><!ENTITY triangleright "&#x25B9;">
+<!ENTITY xdtri "&#x25BD;"><!ENTITY bigtriangledown "&#x25BD;">
+<!ENTITY dtrif "&#x25BE;"><!ENTITY blacktriangledown "&#x25BE;">
+<!ENTITY dtri "&#x25BF;"><!ENTITY triangledown "&#x25BF;">
+<!ENTITY ltrif "&#x25C2;"><!ENTITY blacktriangleleft "&#x25C2;">
+<!ENTITY ltri "&#x25C3;"><!ENTITY triangleleft "&#x25C3;">
+<!ENTITY loz "&#x25CA;"><!ENTITY lozenge "&#x25CA;">
+<!ENTITY cir "&#x25CB;">
+<!ENTITY tridot "&#x25EC;">
+<!ENTITY xcirc "&#x25EF;"><!ENTITY bigcirc "&#x25EF;">
+<!ENTITY ultri "&#x25F8;">
+<!ENTITY urtri "&#x25F9;">
+<!ENTITY lltri "&#x25FA;">
+<!ENTITY EmptySmallSquare "&#x25FB;">
+<!ENTITY FilledSmallSquare "&#x25FC;">
+<!ENTITY starf "&#x2605;"><!ENTITY bigstar "&#x2605;">
+<!ENTITY star "&#x2606;">
+<!ENTITY phone "&#x260E;">
+<!ENTITY female "&#x2640;">
+<!ENTITY male "&#x2642;">
+<!ENTITY spades "&#x2660;"><!ENTITY spadesuit "&#x2660;">
+<!ENTITY clubs "&#x2663;"><!ENTITY clubsuit "&#x2663;">
+<!ENTITY hearts "&#x2665;"><!ENTITY heartsuit "&#x2665;">
+<!ENTITY diams "&#x2666;"><!ENTITY diamondsuit "&#x2666;">
+<!ENTITY sung "&#x266A;">
+<!ENTITY flat "&#x266D;">
+<!ENTITY natur "&#x266E;"><!ENTITY natural "&#x266E;">
+<!ENTITY sharp "&#x266F;">
+<!ENTITY check "&#x2713;"><!ENTITY checkmark "&#x2713;">
+<!ENTITY cross "&#x2717;">
+<!ENTITY malt "&#x2720;"><!ENTITY maltese "&#x2720;">
+<!ENTITY sext "&#x2736;">
+<!ENTITY VerticalSeparator "&#x2758;">
+<!ENTITY xlarr "&#x27F5;"><!ENTITY LongLeftArrow "&#x27F5;"><!ENTITY longleftarrow "&#x27F5;">
+<!ENTITY xrarr "&#x27F6;"><!ENTITY LongRightArrow "&#x27F6;"><!ENTITY longrightarrow "&#x27F6;">
+<!ENTITY xharr "&#x27F7;"><!ENTITY LongLeftRightArrow "&#x27F7;"><!ENTITY longleftrightarrow "&#x27F7;">
+<!ENTITY xlArr "&#x27F8;"><!ENTITY DoubleLongLeftArrow "&#x27F8;"><!ENTITY Longleftarrow "&#x27F8;">
+<!ENTITY xrArr "&#x27F9;"><!ENTITY DoubleLongRightArrow "&#x27F9;"><!ENTITY Longrightarrow "&#x27F9;">
+<!ENTITY xhArr "&#x27FA;"><!ENTITY DoubleLongLeftRightArrow "&#x27FA;"><!ENTITY Longleftrightarrow "&#x27FA;">
+<!ENTITY xmap "&#x27FC;"><!ENTITY longmapsto "&#x27FC;">
+<!ENTITY dzigrarr "&#x27FF;">
+<!ENTITY nvlArr "&#x2902;">
+<!ENTITY nvrArr "&#x2903;">
+<!ENTITY nvHarr "&#x2904;">
+<!ENTITY Map "&#x2905;">
+<!ENTITY lbarr "&#x290C;">
+<!ENTITY rbarr "&#x290D;"><!ENTITY bkarow "&#x290D;">
+<!ENTITY lBarr "&#x290E;">
+<!ENTITY rBarr "&#x290F;"><!ENTITY dbkarow "&#x290F;">
+<!ENTITY RBarr "&#x2910;"><!ENTITY drbkarow "&#x2910;">
+<!ENTITY DDotrahd "&#x2911;">
+<!ENTITY UpArrowBar "&#x2912;">
+<!ENTITY DownArrowBar "&#x2913;">
+<!ENTITY Rarrtl "&#x2916;">
+<!ENTITY latail "&#x2919;">
+<!ENTITY ratail "&#x291A;">
+<!ENTITY lAtail "&#x291B;">
+<!ENTITY rAtail "&#x291C;">
+<!ENTITY larrfs "&#x291D;">
+<!ENTITY rarrfs "&#x291E;">
+<!ENTITY larrbfs "&#x291F;">
+<!ENTITY rarrbfs "&#x2920;">
+<!ENTITY nwarhk "&#x2923;">
+<!ENTITY nearhk "&#x2924;">
+<!ENTITY searhk "&#x2925;"><!ENTITY hksearow "&#x2925;">
+<!ENTITY swarhk "&#x2926;"><!ENTITY hkswarow "&#x2926;">
+<!ENTITY nwnear "&#x2927;">
+<!ENTITY nesear "&#x2928;"><!ENTITY toea "&#x2928;">
+<!ENTITY seswar "&#x2929;"><!ENTITY tosa "&#x2929;">
+<!ENTITY swnwar "&#x292A;">
+<!ENTITY rarrc "&#x2933;">
+<!ENTITY nrarrc "&#x2933;&#x338;">
+<!ENTITY cudarrr "&#x2935;">
+<!ENTITY ldca "&#x2936;">
+<!ENTITY rdca "&#x2937;">
+<!ENTITY cudarrl "&#x2938;">
+<!ENTITY larrpl "&#x2939;">
+<!ENTITY curarrm "&#x293C;">
+<!ENTITY cularrp "&#x293D;">
+<!ENTITY rarrpl "&#x2945;">
+<!ENTITY harrcir "&#x2948;">
+<!ENTITY Uarrocir "&#x2949;">
+<!ENTITY lurdshar "&#x294A;">
+<!ENTITY ldrushar "&#x294B;">
+<!ENTITY LeftRightVector "&#x294E;">
+<!ENTITY RightUpDownVector "&#x294F;">
+<!ENTITY DownLeftRightVector "&#x2950;">
+<!ENTITY LeftUpDownVector "&#x2951;">
+<!ENTITY LeftVectorBar "&#x2952;">
+<!ENTITY RightVectorBar "&#x2953;">
+<!ENTITY RightUpVectorBar "&#x2954;">
+<!ENTITY RightDownVectorBar "&#x2955;">
+<!ENTITY DownLeftVectorBar "&#x2956;">
+<!ENTITY DownRightVectorBar "&#x2957;">
+<!ENTITY LeftUpVectorBar "&#x2958;">
+<!ENTITY LeftDownVectorBar "&#x2959;">
+<!ENTITY LeftTeeVector "&#x295A;">
+<!ENTITY RightTeeVector "&#x295B;">
+<!ENTITY RightUpTeeVector "&#x295C;">
+<!ENTITY RightDownTeeVector "&#x295D;">
+<!ENTITY DownLeftTeeVector "&#x295E;">
+<!ENTITY DownRightTeeVector "&#x295F;">
+<!ENTITY LeftUpTeeVector "&#x2960;">
+<!ENTITY LeftDownTeeVector "&#x2961;">
+<!ENTITY lHar "&#x2962;">
+<!ENTITY uHar "&#x2963;">
+<!ENTITY rHar "&#x2964;">
+<!ENTITY dHar "&#x2965;">
+<!ENTITY luruhar "&#x2966;">
+<!ENTITY ldrdhar "&#x2967;">
+<!ENTITY ruluhar "&#x2968;">
+<!ENTITY rdldhar "&#x2969;">
+<!ENTITY lharul "&#x296A;">
+<!ENTITY llhard "&#x296B;">
+<!ENTITY rharul "&#x296C;">
+<!ENTITY lrhard "&#x296D;">
+<!ENTITY udhar "&#x296E;"><!ENTITY UpEquilibrium "&#x296E;">
+<!ENTITY duhar "&#x296F;"><!ENTITY ReverseUpEquilibrium "&#x296F;">
+<!ENTITY RoundImplies "&#x2970;">
+<!ENTITY erarr "&#x2971;">
+<!ENTITY simrarr "&#x2972;">
+<!ENTITY larrsim "&#x2973;">
+<!ENTITY rarrsim "&#x2974;">
+<!ENTITY rarrap "&#x2975;">
+<!ENTITY ltlarr "&#x2976;">
+<!ENTITY gtrarr "&#x2978;">
+<!ENTITY subrarr "&#x2979;">
+<!ENTITY suplarr "&#x297B;">
+<!ENTITY lfisht "&#x297C;">
+<!ENTITY rfisht "&#x297D;">
+<!ENTITY ufisht "&#x297E;">
+<!ENTITY dfisht "&#x297F;">
+<!ENTITY lopar "&#x2985;">
+<!ENTITY ropar "&#x2986;">
+<!ENTITY lbrke "&#x298B;">
+<!ENTITY rbrke "&#x298C;">
+<!ENTITY lbrkslu "&#x298D;">
+<!ENTITY rbrksld "&#x298E;">
+<!ENTITY lbrksld "&#x298F;">
+<!ENTITY rbrkslu "&#x2990;">
+<!ENTITY langd "&#x2991;">
+<!ENTITY rangd "&#x2992;">
+<!ENTITY lparlt "&#x2993;">
+<!ENTITY rpargt "&#x2994;">
+<!ENTITY gtlPar "&#x2995;">
+<!ENTITY ltrPar "&#x2996;">
+<!ENTITY vzigzag "&#x299A;">
+<!ENTITY vangrt "&#x299C;">
+<!ENTITY angrtvbd "&#x299D;">
+<!ENTITY ange "&#x29A4;">
+<!ENTITY range "&#x29A5;">
+<!ENTITY dwangle "&#x29A6;">
+<!ENTITY uwangle "&#x29A7;">
+<!ENTITY angmsdaa "&#x29A8;">
+<!ENTITY angmsdab "&#x29A9;">
+<!ENTITY angmsdac "&#x29AA;">
+<!ENTITY angmsdad "&#x29AB;">
+<!ENTITY angmsdae "&#x29AC;">
+<!ENTITY angmsdaf "&#x29AD;">
+<!ENTITY angmsdag "&#x29AE;">
+<!ENTITY angmsdah "&#x29AF;">
+<!ENTITY bemptyv "&#x29B0;">
+<!ENTITY demptyv "&#x29B1;">
+<!ENTITY cemptyv "&#x29B2;">
+<!ENTITY raemptyv "&#x29B3;">
+<!ENTITY laemptyv "&#x29B4;">
+<!ENTITY ohbar "&#x29B5;">
+<!ENTITY omid "&#x29B6;">
+<!ENTITY opar "&#x29B7;">
+<!ENTITY operp "&#x29B9;">
+<!ENTITY olcross "&#x29BB;">
+<!ENTITY odsold "&#x29BC;">
+<!ENTITY olcir "&#x29BE;">
+<!ENTITY ofcir "&#x29BF;">
+<!ENTITY olt "&#x29C0;">
+<!ENTITY ogt "&#x29C1;">
+<!ENTITY cirscir "&#x29C2;">
+<!ENTITY cirE "&#x29C3;">
+<!ENTITY solb "&#x29C4;">
+<!ENTITY bsolb "&#x29C5;">
+<!ENTITY boxbox "&#x29C9;">
+<!ENTITY trisb "&#x29CD;">
+<!ENTITY rtriltri "&#x29CE;">
+<!ENTITY LeftTriangleBar "&#x29CF;">
+<!ENTITY NotLeftTriangleBar "&#x29CF;&#x338;">
+<!ENTITY RightTriangleBar "&#x29D0;">
+<!ENTITY NotRightTriangleBar "&#x29D0;&#x338;">
+<!ENTITY race "&#x29DA;">
+<!ENTITY iinfin "&#x29DC;">
+<!ENTITY infintie "&#x29DD;">
+<!ENTITY nvinfin "&#x29DE;">
+<!ENTITY eparsl "&#x29E3;">
+<!ENTITY smeparsl "&#x29E4;">
+<!ENTITY eqvparsl "&#x29E5;">
+<!ENTITY lozf "&#x29EB;"><!ENTITY blacklozenge "&#x29EB;">
+<!ENTITY RuleDelayed "&#x29F4;">
+<!ENTITY dsol "&#x29F6;">
+<!ENTITY xodot "&#x2A00;"><!ENTITY bigodot "&#x2A00;">
+<!ENTITY xoplus "&#x2A01;"><!ENTITY bigoplus "&#x2A01;">
+<!ENTITY xotime "&#x2A02;"><!ENTITY bigotimes "&#x2A02;">
+<!ENTITY xuplus "&#x2A04;"><!ENTITY biguplus "&#x2A04;">
+<!ENTITY xsqcup "&#x2A06;"><!ENTITY bigsqcup "&#x2A06;">
+<!ENTITY qint "&#x2A0C;"><!ENTITY iiiint "&#x2A0C;">
+<!ENTITY fpartint "&#x2A0D;">
+<!ENTITY cirfnint "&#x2A10;">
+<!ENTITY awint "&#x2A11;">
+<!ENTITY rppolint "&#x2A12;">
+<!ENTITY scpolint "&#x2A13;">
+<!ENTITY npolint "&#x2A14;">
+<!ENTITY pointint "&#x2A15;">
+<!ENTITY quatint "&#x2A16;">
+<!ENTITY intlarhk "&#x2A17;">
+<!ENTITY pluscir "&#x2A22;">
+<!ENTITY plusacir "&#x2A23;">
+<!ENTITY simplus "&#x2A24;">
+<!ENTITY plusdu "&#x2A25;">
+<!ENTITY plussim "&#x2A26;">
+<!ENTITY plustwo "&#x2A27;">
+<!ENTITY mcomma "&#x2A29;">
+<!ENTITY minusdu "&#x2A2A;">
+<!ENTITY loplus "&#x2A2D;">
+<!ENTITY roplus "&#x2A2E;">
+<!ENTITY Cross "&#x2A2F;">
+<!ENTITY timesd "&#x2A30;">
+<!ENTITY timesbar "&#x2A31;">
+<!ENTITY smashp "&#x2A33;">
+<!ENTITY lotimes "&#x2A34;">
+<!ENTITY rotimes "&#x2A35;">
+<!ENTITY otimesas "&#x2A36;">
+<!ENTITY Otimes "&#x2A37;">
+<!ENTITY odiv "&#x2A38;">
+<!ENTITY triplus "&#x2A39;">
+<!ENTITY triminus "&#x2A3A;">
+<!ENTITY tritime "&#x2A3B;">
+<!ENTITY iprod "&#x2A3C;"><!ENTITY intprod "&#x2A3C;">
+<!ENTITY amalg "&#x2A3F;">
+<!ENTITY capdot "&#x2A40;">
+<!ENTITY ncup "&#x2A42;">
+<!ENTITY ncap "&#x2A43;">
+<!ENTITY capand "&#x2A44;">
+<!ENTITY cupor "&#x2A45;">
+<!ENTITY cupcap "&#x2A46;">
+<!ENTITY capcup "&#x2A47;">
+<!ENTITY cupbrcap "&#x2A48;">
+<!ENTITY capbrcup "&#x2A49;">
+<!ENTITY cupcup "&#x2A4A;">
+<!ENTITY capcap "&#x2A4B;">
+<!ENTITY ccups "&#x2A4C;">
+<!ENTITY ccaps "&#x2A4D;">
+<!ENTITY ccupssm "&#x2A50;">
+<!ENTITY And "&#x2A53;">
+<!ENTITY Or "&#x2A54;">
+<!ENTITY andand "&#x2A55;">
+<!ENTITY oror "&#x2A56;">
+<!ENTITY orslope "&#x2A57;">
+<!ENTITY andslope "&#x2A58;">
+<!ENTITY andv "&#x2A5A;">
+<!ENTITY orv "&#x2A5B;">
+<!ENTITY andd "&#x2A5C;">
+<!ENTITY ord "&#x2A5D;">
+<!ENTITY wedbar "&#x2A5F;">
+<!ENTITY sdote "&#x2A66;">
+<!ENTITY simdot "&#x2A6A;">
+<!ENTITY congdot "&#x2A6D;">
+<!ENTITY ncongdot "&#x2A6D;&#x338;">
+<!ENTITY easter "&#x2A6E;">
+<!ENTITY apacir "&#x2A6F;">
+<!ENTITY apE "&#x2A70;">
+<!ENTITY napE "&#x2A70;&#x338;">
+<!ENTITY eplus "&#x2A71;">
+<!ENTITY pluse "&#x2A72;">
+<!ENTITY Esim "&#x2A73;">
+<!ENTITY Colone "&#x2A74;">
+<!ENTITY Equal "&#x2A75;">
+<!ENTITY eDDot "&#x2A77;"><!ENTITY ddotseq "&#x2A77;">
+<!ENTITY equivDD "&#x2A78;">
+<!ENTITY ltcir "&#x2A79;">
+<!ENTITY gtcir "&#x2A7A;">
+<!ENTITY ltquest "&#x2A7B;">
+<!ENTITY gtquest "&#x2A7C;">
+<!ENTITY les "&#x2A7D;"><!ENTITY leqslant "&#x2A7D;"><!ENTITY LessSlantEqual "&#x2A7D;">
+<!ENTITY nles "&#x2A7D;&#x338;"><!ENTITY nleqslant "&#x2A7D;&#x338;"><!ENTITY NotLessSlantEqual "&#x2A7D;&#x338;">
+<!ENTITY ges "&#x2A7E;"><!ENTITY geqslant "&#x2A7E;"><!ENTITY GreaterSlantEqual "&#x2A7E;">
+<!ENTITY nges "&#x2A7E;&#x338;"><!ENTITY ngeqslant "&#x2A7E;&#x338;"><!ENTITY NotGreaterSlantEqual "&#x2A7E;&#x338;">
+<!ENTITY lesdot "&#x2A7F;">
+<!ENTITY gesdot "&#x2A80;">
+<!ENTITY lesdoto "&#x2A81;">
+<!ENTITY gesdoto "&#x2A82;">
+<!ENTITY lesdotor "&#x2A83;">
+<!ENTITY gesdotol "&#x2A84;">
+<!ENTITY lap "&#x2A85;"><!ENTITY lessapprox "&#x2A85;">
+<!ENTITY gap "&#x2A86;"><!ENTITY gtrapprox "&#x2A86;">
+<!ENTITY lne "&#x2A87;"><!ENTITY lneq "&#x2A87;">
+<!ENTITY gne "&#x2A88;"><!ENTITY gneq "&#x2A88;">
+<!ENTITY lnap "&#x2A89;"><!ENTITY lnapprox "&#x2A89;">
+<!ENTITY gnap "&#x2A8A;"><!ENTITY gnapprox "&#x2A8A;">
+<!ENTITY lEg "&#x2A8B;"><!ENTITY lesseqqgtr "&#x2A8B;">
+<!ENTITY gEl "&#x2A8C;"><!ENTITY gtreqqless "&#x2A8C;">
+<!ENTITY lsime "&#x2A8D;">
+<!ENTITY gsime "&#x2A8E;">
+<!ENTITY lsimg "&#x2A8F;">
+<!ENTITY gsiml "&#x2A90;">
+<!ENTITY lgE "&#x2A91;">
+<!ENTITY glE "&#x2A92;">
+<!ENTITY lesges "&#x2A93;">
+<!ENTITY gesles "&#x2A94;">
+<!ENTITY els "&#x2A95;"><!ENTITY eqslantless "&#x2A95;">
+<!ENTITY egs "&#x2A96;"><!ENTITY eqslantgtr "&#x2A96;">
+<!ENTITY elsdot "&#x2A97;">
+<!ENTITY egsdot "&#x2A98;">
+<!ENTITY el "&#x2A99;">
+<!ENTITY eg "&#x2A9A;">
+<!ENTITY siml "&#x2A9D;">
+<!ENTITY simg "&#x2A9E;">
+<!ENTITY simlE "&#x2A9F;">
+<!ENTITY simgE "&#x2AA0;">
+<!ENTITY LessLess "&#x2AA1;">
+<!ENTITY NotNestedLessLess "&#x2AA1;&#x338;">
+<!ENTITY GreaterGreater "&#x2AA2;">
+<!ENTITY NotNestedGreaterGreater "&#x2AA2;&#x338;">
+<!ENTITY glj "&#x2AA4;">
+<!ENTITY gla "&#x2AA5;">
+<!ENTITY ltcc "&#x2AA6;">
+<!ENTITY gtcc "&#x2AA7;">
+<!ENTITY lescc "&#x2AA8;">
+<!ENTITY gescc "&#x2AA9;">
+<!ENTITY smt "&#x2AAA;">
+<!ENTITY lat "&#x2AAB;">
+<!ENTITY smte "&#x2AAC;">
+<!ENTITY smtes "&#x2AAC;&#xFE00;">
+<!ENTITY late "&#x2AAD;">
+<!ENTITY lates "&#x2AAD;&#xFE00;">
+<!ENTITY bumpE "&#x2AAE;">
+<!ENTITY pre "&#x2AAF;"><!ENTITY PrecedesEqual "&#x2AAF;"><!ENTITY preceq "&#x2AAF;">
+<!ENTITY npre "&#x2AAF;&#x338;"><!ENTITY NotPrecedesEqual "&#x2AAF;&#x338;"><!ENTITY npreceq "&#x2AAF;&#x338;">
+<!ENTITY sce "&#x2AB0;"><!ENTITY SucceedsEqual "&#x2AB0;"><!ENTITY succeq "&#x2AB0;">
+<!ENTITY nsce "&#x2AB0;&#x338;"><!ENTITY NotSucceedsEqual "&#x2AB0;&#x338;"><!ENTITY nsucceq "&#x2AB0;&#x338;">
+<!ENTITY prE "&#x2AB3;">
+<!ENTITY scE "&#x2AB4;">
+<!ENTITY prnE "&#x2AB5;"><!ENTITY precneqq "&#x2AB5;">
+<!ENTITY scnE "&#x2AB6;"><!ENTITY succneqq "&#x2AB6;">
+<!ENTITY prap "&#x2AB7;"><!ENTITY precapprox "&#x2AB7;">
+<!ENTITY scap "&#x2AB8;"><!ENTITY succapprox "&#x2AB8;">
+<!ENTITY prnap "&#x2AB9;"><!ENTITY precnapprox "&#x2AB9;">
+<!ENTITY scnap "&#x2ABA;"><!ENTITY succnapprox "&#x2ABA;">
+<!ENTITY Pr "&#x2ABB;">
+<!ENTITY Sc "&#x2ABC;">
+<!ENTITY subdot "&#x2ABD;">
+<!ENTITY supdot "&#x2ABE;">
+<!ENTITY subplus "&#x2ABF;">
+<!ENTITY supplus "&#x2AC0;">
+<!ENTITY submult "&#x2AC1;">
+<!ENTITY supmult "&#x2AC2;">
+<!ENTITY subedot "&#x2AC3;">
+<!ENTITY supedot "&#x2AC4;">
+<!ENTITY subE "&#x2AC5;"><!ENTITY subseteqq "&#x2AC5;">
+<!ENTITY nsubE "&#x2AC5;&#x338;"><!ENTITY nsubseteqq "&#x2AC5;&#x338;">
+<!ENTITY supE "&#x2AC6;"><!ENTITY supseteqq "&#x2AC6;">
+<!ENTITY nsupE "&#x2AC6;&#x338;"><!ENTITY nsupseteqq "&#x2AC6;&#x338;">
+<!ENTITY subsim "&#x2AC7;">
+<!ENTITY supsim "&#x2AC8;">
+<!ENTITY subnE "&#x2ACB;"><!ENTITY subsetneqq "&#x2ACB;">
+<!ENTITY vsubnE "&#x2ACB;&#xFE00;"><!ENTITY varsubsetneqq "&#x2ACB;&#xFE00;">
+<!ENTITY supnE "&#x2ACC;"><!ENTITY supsetneqq "&#x2ACC;">
+<!ENTITY vsupnE "&#x2ACC;&#xFE00;"><!ENTITY varsupsetneqq "&#x2ACC;&#xFE00;">
+<!ENTITY csub "&#x2ACF;">
+<!ENTITY csup "&#x2AD0;">
+<!ENTITY csube "&#x2AD1;">
+<!ENTITY csupe "&#x2AD2;">
+<!ENTITY subsup "&#x2AD3;">
+<!ENTITY supsub "&#x2AD4;">
+<!ENTITY subsub "&#x2AD5;">
+<!ENTITY supsup "&#x2AD6;">
+<!ENTITY suphsub "&#x2AD7;">
+<!ENTITY supdsub "&#x2AD8;">
+<!ENTITY forkv "&#x2AD9;">
+<!ENTITY topfork "&#x2ADA;">
+<!ENTITY mlcp "&#x2ADB;">
+<!ENTITY Dashv "&#x2AE4;"><!ENTITY DoubleLeftTee "&#x2AE4;">
+<!ENTITY Vdashl "&#x2AE6;">
+<!ENTITY Barv "&#x2AE7;">
+<!ENTITY vBar "&#x2AE8;">
+<!ENTITY vBarv "&#x2AE9;">
+<!ENTITY Vbar "&#x2AEB;">
+<!ENTITY Not "&#x2AEC;">
+<!ENTITY bNot "&#x2AED;">
+<!ENTITY rnmid "&#x2AEE;">
+<!ENTITY cirmid "&#x2AEF;">
+<!ENTITY midcir "&#x2AF0;">
+<!ENTITY topcir "&#x2AF1;">
+<!ENTITY nhpar "&#x2AF2;">
+<!ENTITY parsim "&#x2AF3;">
+<!ENTITY parsl "&#x2AFD;">
+<!ENTITY nparsl "&#x2AFD;&#x20E5;">
+<!ENTITY fflig "&#xFB00;">
+<!ENTITY filig "&#xFB01;">
+<!ENTITY fllig "&#xFB02;">
+<!ENTITY ffilig "&#xFB03;">
+<!ENTITY ffllig "&#xFB04;">
+<!ENTITY Ascr "&#x1D49C;">
+<!ENTITY Cscr "&#x1D49E;">
+<!ENTITY Dscr "&#x1D49F;">
+<!ENTITY Gscr "&#x1D4A2;">
+<!ENTITY Jscr "&#x1D4A5;">
+<!ENTITY Kscr "&#x1D4A6;">
+<!ENTITY Nscr "&#x1D4A9;">
+<!ENTITY Oscr "&#x1D4AA;">
+<!ENTITY Pscr "&#x1D4AB;">
+<!ENTITY Qscr "&#x1D4AC;">
+<!ENTITY Sscr "&#x1D4AE;">
+<!ENTITY Tscr "&#x1D4AF;">
+<!ENTITY Uscr "&#x1D4B0;">
+<!ENTITY Vscr "&#x1D4B1;">
+<!ENTITY Wscr "&#x1D4B2;">
+<!ENTITY Xscr "&#x1D4B3;">
+<!ENTITY Yscr "&#x1D4B4;">
+<!ENTITY Zscr "&#x1D4B5;">
+<!ENTITY ascr "&#x1D4B6;">
+<!ENTITY bscr "&#x1D4B7;">
+<!ENTITY cscr "&#x1D4B8;">
+<!ENTITY dscr "&#x1D4B9;">
+<!ENTITY fscr "&#x1D4BB;">
+<!ENTITY hscr "&#x1D4BD;">
+<!ENTITY iscr "&#x1D4BE;">
+<!ENTITY jscr "&#x1D4BF;">
+<!ENTITY kscr "&#x1D4C0;">
+<!ENTITY lscr "&#x1D4C1;">
+<!ENTITY mscr "&#x1D4C2;">
+<!ENTITY nscr "&#x1D4C3;">
+<!ENTITY pscr "&#x1D4C5;">
+<!ENTITY qscr "&#x1D4C6;">
+<!ENTITY rscr "&#x1D4C7;">
+<!ENTITY sscr "&#x1D4C8;">
+<!ENTITY tscr "&#x1D4C9;">
+<!ENTITY uscr "&#x1D4CA;">
+<!ENTITY vscr "&#x1D4CB;">
+<!ENTITY wscr "&#x1D4CC;">
+<!ENTITY xscr "&#x1D4CD;">
+<!ENTITY yscr "&#x1D4CE;">
+<!ENTITY zscr "&#x1D4CF;">
+<!ENTITY Afr "&#x1D504;">
+<!ENTITY Bfr "&#x1D505;">
+<!ENTITY Dfr "&#x1D507;">
+<!ENTITY Efr "&#x1D508;">
+<!ENTITY Ffr "&#x1D509;">
+<!ENTITY Gfr "&#x1D50A;">
+<!ENTITY Jfr "&#x1D50D;">
+<!ENTITY Kfr "&#x1D50E;">
+<!ENTITY Lfr "&#x1D50F;">
+<!ENTITY Mfr "&#x1D510;">
+<!ENTITY Nfr "&#x1D511;">
+<!ENTITY Ofr "&#x1D512;">
+<!ENTITY Pfr "&#x1D513;">
+<!ENTITY Qfr "&#x1D514;">
+<!ENTITY Sfr "&#x1D516;">
+<!ENTITY Tfr "&#x1D517;">
+<!ENTITY Ufr "&#x1D518;">
+<!ENTITY Vfr "&#x1D519;">
+<!ENTITY Wfr "&#x1D51A;">
+<!ENTITY Xfr "&#x1D51B;">
+<!ENTITY Yfr "&#x1D51C;">
+<!ENTITY afr "&#x1D51E;">
+<!ENTITY bfr "&#x1D51F;">
+<!ENTITY cfr "&#x1D520;">
+<!ENTITY dfr "&#x1D521;">
+<!ENTITY efr "&#x1D522;">
+<!ENTITY ffr "&#x1D523;">
+<!ENTITY gfr "&#x1D524;">
+<!ENTITY hfr "&#x1D525;">
+<!ENTITY ifr "&#x1D526;">
+<!ENTITY jfr "&#x1D527;">
+<!ENTITY kfr "&#x1D528;">
+<!ENTITY lfr "&#x1D529;">
+<!ENTITY mfr "&#x1D52A;">
+<!ENTITY nfr "&#x1D52B;">
+<!ENTITY ofr "&#x1D52C;">
+<!ENTITY pfr "&#x1D52D;">
+<!ENTITY qfr "&#x1D52E;">
+<!ENTITY rfr "&#x1D52F;">
+<!ENTITY sfr "&#x1D530;">
+<!ENTITY tfr "&#x1D531;">
+<!ENTITY ufr "&#x1D532;">
+<!ENTITY vfr "&#x1D533;">
+<!ENTITY wfr "&#x1D534;">
+<!ENTITY xfr "&#x1D535;">
+<!ENTITY yfr "&#x1D536;">
+<!ENTITY zfr "&#x1D537;">
+<!ENTITY Aopf "&#x1D538;">
+<!ENTITY Bopf "&#x1D539;">
+<!ENTITY Dopf "&#x1D53B;">
+<!ENTITY Eopf "&#x1D53C;">
+<!ENTITY Fopf "&#x1D53D;">
+<!ENTITY Gopf "&#x1D53E;">
+<!ENTITY Iopf "&#x1D540;">
+<!ENTITY Jopf "&#x1D541;">
+<!ENTITY Kopf "&#x1D542;">
+<!ENTITY Lopf "&#x1D543;">
+<!ENTITY Mopf "&#x1D544;">
+<!ENTITY Oopf "&#x1D546;">
+<!ENTITY Sopf "&#x1D54A;">
+<!ENTITY Topf "&#x1D54B;">
+<!ENTITY Uopf "&#x1D54C;">
+<!ENTITY Vopf "&#x1D54D;">
+<!ENTITY Wopf "&#x1D54E;">
+<!ENTITY Xopf "&#x1D54F;">
+<!ENTITY Yopf "&#x1D550;">
+<!ENTITY aopf "&#x1D552;">
+<!ENTITY bopf "&#x1D553;">
+<!ENTITY copf "&#x1D554;">
+<!ENTITY dopf "&#x1D555;">
+<!ENTITY eopf "&#x1D556;">
+<!ENTITY fopf "&#x1D557;">
+<!ENTITY gopf "&#x1D558;">
+<!ENTITY hopf "&#x1D559;">
+<!ENTITY iopf "&#x1D55A;">
+<!ENTITY jopf "&#x1D55B;">
+<!ENTITY kopf "&#x1D55C;">
+<!ENTITY lopf "&#x1D55D;">
+<!ENTITY mopf "&#x1D55E;">
+<!ENTITY nopf "&#x1D55F;">
+<!ENTITY oopf "&#x1D560;">
+<!ENTITY popf "&#x1D561;">
+<!ENTITY qopf "&#x1D562;">
+<!ENTITY ropf "&#x1D563;">
+<!ENTITY sopf "&#x1D564;">
+<!ENTITY topf "&#x1D565;">
+<!ENTITY uopf "&#x1D566;">
+<!ENTITY vopf "&#x1D567;">
+<!ENTITY wopf "&#x1D568;">
+<!ENTITY xopf "&#x1D569;">
+<!ENTITY yopf "&#x1D56A;">
+<!ENTITY zopf "&#x1D56B;">
diff --git a/bundles/XO/res/dtd/xhtml11.dtd b/bundles/XO/res/dtd/xhtml11.dtd
new file mode 100755
index 0000000..b3e360c
--- /dev/null
+++ b/bundles/XO/res/dtd/xhtml11.dtd
@@ -0,0 +1,300 @@
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is mozilla.org code.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the LGPL or the GPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+
+<!--
+ * Predefined HTML entities to be loaded when parsing XHTML documents.
+ * The contents match mozilla/parser/htmlparser/src/nsHTMLEntityList.h,
+ * except that Navigator entity extensions are not included.
+ -->
+
+<!-- ISO 8859-1 entities -->
+<!ENTITY nbsp "&#160;">
+<!ENTITY iexcl "&#161;">
+<!ENTITY cent "&#162;">
+<!ENTITY pound "&#163;">
+<!ENTITY curren "&#164;">
+<!ENTITY yen "&#165;">
+<!ENTITY brvbar "&#166;">
+<!ENTITY sect "&#167;">
+<!ENTITY uml "&#168;">
+<!ENTITY copy "&#169;">
+<!ENTITY ordf "&#170;">
+<!ENTITY laquo "&#171;">
+<!ENTITY not "&#172;">
+<!ENTITY shy "&#173;">
+<!ENTITY reg "&#174;">
+<!ENTITY macr "&#175;">
+<!ENTITY deg "&#176;">
+<!ENTITY plusmn "&#177;">
+<!ENTITY sup2 "&#178;">
+<!ENTITY sup3 "&#179;">
+<!ENTITY acute "&#180;">
+<!ENTITY micro "&#181;">
+<!ENTITY para "&#182;">
+<!ENTITY middot "&#183;">
+<!ENTITY cedil "&#184;">
+<!ENTITY sup1 "&#185;">
+<!ENTITY ordm "&#186;">
+<!ENTITY raquo "&#187;">
+<!ENTITY frac14 "&#188;">
+<!ENTITY frac12 "&#189;">
+<!ENTITY frac34 "&#190;">
+<!ENTITY iquest "&#191;">
+<!ENTITY Agrave "&#192;">
+<!ENTITY Aacute "&#193;">
+<!ENTITY Acirc "&#194;">
+<!ENTITY Atilde "&#195;">
+<!ENTITY Auml "&#196;">
+<!ENTITY Aring "&#197;">
+<!ENTITY AElig "&#198;">
+<!ENTITY Ccedil "&#199;">
+<!ENTITY Egrave "&#200;">
+<!ENTITY Eacute "&#201;">
+<!ENTITY Ecirc "&#202;">
+<!ENTITY Euml "&#203;">
+<!ENTITY Igrave "&#204;">
+<!ENTITY Iacute "&#205;">
+<!ENTITY Icirc "&#206;">
+<!ENTITY Iuml "&#207;">
+<!ENTITY ETH "&#208;">
+<!ENTITY Ntilde "&#209;">
+<!ENTITY Ograve "&#210;">
+<!ENTITY Oacute "&#211;">
+<!ENTITY Ocirc "&#212;">
+<!ENTITY Otilde "&#213;">
+<!ENTITY Ouml "&#214;">
+<!ENTITY times "&#215;">
+<!ENTITY Oslash "&#216;">
+<!ENTITY Ugrave "&#217;">
+<!ENTITY Uacute "&#218;">
+<!ENTITY Ucirc "&#219;">
+<!ENTITY Uuml "&#220;">
+<!ENTITY Yacute "&#221;">
+<!ENTITY THORN "&#222;">
+<!ENTITY szlig "&#223;">
+<!ENTITY agrave "&#224;">
+<!ENTITY aacute "&#225;">
+<!ENTITY acirc "&#226;">
+<!ENTITY atilde "&#227;">
+<!ENTITY auml "&#228;">
+<!ENTITY aring "&#229;">
+<!ENTITY aelig "&#230;">
+<!ENTITY ccedil "&#231;">
+<!ENTITY egrave "&#232;">
+<!ENTITY eacute "&#233;">
+<!ENTITY ecirc "&#234;">
+<!ENTITY euml "&#235;">
+<!ENTITY igrave "&#236;">
+<!ENTITY iacute "&#237;">
+<!ENTITY icirc "&#238;">
+<!ENTITY iuml "&#239;">
+<!ENTITY eth "&#240;">
+<!ENTITY ntilde "&#241;">
+<!ENTITY ograve "&#242;">
+<!ENTITY oacute "&#243;">
+<!ENTITY ocirc "&#244;">
+<!ENTITY otilde "&#245;">
+<!ENTITY ouml "&#246;">
+<!ENTITY divide "&#247;">
+<!ENTITY oslash "&#248;">
+<!ENTITY ugrave "&#249;">
+<!ENTITY uacute "&#250;">
+<!ENTITY ucirc "&#251;">
+<!ENTITY uuml "&#252;">
+<!ENTITY yacute "&#253;">
+<!ENTITY thorn "&#254;">
+<!ENTITY yuml "&#255;">
+
+<!-- Mathematical symbols and Greek letters -->
+<!ENTITY fnof "&#402;">
+<!ENTITY Alpha "&#913;">
+<!ENTITY Beta "&#914;">
+<!ENTITY Gamma "&#915;">
+<!ENTITY Delta "&#916;">
+<!ENTITY Epsilon "&#917;">
+<!ENTITY Zeta "&#918;">
+<!ENTITY Eta "&#919;">
+<!ENTITY Theta "&#920;">
+<!ENTITY Iota "&#921;">
+<!ENTITY Kappa "&#922;">
+<!ENTITY Lambda "&#923;">
+<!ENTITY Mu "&#924;">
+<!ENTITY Nu "&#925;">
+<!ENTITY Xi "&#926;">
+<!ENTITY Omicron "&#927;">
+<!ENTITY Pi "&#928;">
+<!ENTITY Rho "&#929;">
+<!ENTITY Sigma "&#931;">
+<!ENTITY Tau "&#932;">
+<!ENTITY Upsilon "&#933;">
+<!ENTITY Phi "&#934;">
+<!ENTITY Chi "&#935;">
+<!ENTITY Psi "&#936;">
+<!ENTITY Omega "&#937;">
+<!ENTITY alpha "&#x03B1;">
+<!ENTITY beta "&#946;">
+<!ENTITY gamma "&#947;">
+<!ENTITY delta "&#948;">
+<!ENTITY epsilon "&#949;">
+<!ENTITY zeta "&#950;">
+<!ENTITY eta "&#951;">
+<!ENTITY theta "&#952;">
+<!ENTITY iota "&#953;">
+<!ENTITY kappa "&#954;">
+<!ENTITY lambda "&#955;">
+<!ENTITY mu "&#956;">
+<!ENTITY nu "&#957;">
+<!ENTITY xi "&#958;">
+<!ENTITY omicron "&#959;">
+<!ENTITY pi "&#960;">
+<!ENTITY rho "&#961;">
+<!ENTITY sigmaf "&#962;">
+<!ENTITY sigma "&#963;">
+<!ENTITY tau "&#964;">
+<!ENTITY upsilon "&#965;">
+<!ENTITY phi "&#966;">
+<!ENTITY chi "&#967;">
+<!ENTITY psi "&#968;">
+<!ENTITY omega "&#969;">
+<!ENTITY thetasym "&#977;">
+<!ENTITY upsih "&#978;">
+<!ENTITY piv "&#982;">
+<!ENTITY bull "&#8226;">
+<!ENTITY hellip "&#8230;">
+<!ENTITY prime "&#8242;">
+<!ENTITY Prime "&#8243;">
+<!ENTITY oline "&#8254;">
+<!ENTITY frasl "&#8260;">
+<!ENTITY weierp "&#8472;">
+<!ENTITY image "&#8465;">
+<!ENTITY real "&#8476;">
+<!ENTITY trade "&#8482;">
+<!ENTITY alefsym "&#8501;">
+<!ENTITY larr "&#8592;">
+<!ENTITY uarr "&#8593;">
+<!ENTITY rarr "&#8594;">
+<!ENTITY darr "&#8595;">
+<!ENTITY harr "&#8596;">
+<!ENTITY crarr "&#8629;">
+<!ENTITY lArr "&#8656;">
+<!ENTITY uArr "&#8657;">
+<!ENTITY rArr "&#8658;">
+<!ENTITY dArr "&#8659;">
+<!ENTITY hArr "&#8660;">
+<!ENTITY forall "&#8704;">
+<!ENTITY part "&#8706;">
+<!ENTITY exist "&#8707;">
+<!ENTITY empty "&#8709;">
+<!ENTITY nabla "&#8711;">
+<!ENTITY isin "&#8712;">
+<!ENTITY notin "&#8713;">
+<!ENTITY ni "&#8715;">
+<!ENTITY prod "&#8719;">
+<!ENTITY sum "&#8721;">
+<!ENTITY minus "&#8722;">
+<!ENTITY lowast "&#8727;">
+<!ENTITY radic "&#8730;">
+<!ENTITY prop "&#8733;">
+<!ENTITY infin "&#8734;">
+<!ENTITY ang "&#8736;">
+<!ENTITY and "&#8743;">
+<!ENTITY or "&#8744;">
+<!ENTITY cap "&#8745;">
+<!ENTITY cup "&#8746;">
+<!ENTITY int "&#8747;">
+<!ENTITY there4 "&#8756;">
+<!ENTITY sim "&#8764;">
+<!ENTITY cong "&#8773;">
+<!ENTITY asymp "&#8776;">
+<!ENTITY ne "&#8800;">
+<!ENTITY equiv "&#8801;">
+<!ENTITY le "&#8804;">
+<!ENTITY ge "&#8805;">
+<!ENTITY sub "&#8834;">
+<!ENTITY sup "&#8835;">
+<!ENTITY nsub "&#8836;">
+<!ENTITY sube "&#8838;">
+<!ENTITY supe "&#8839;">
+<!ENTITY oplus "&#8853;">
+<!ENTITY otimes "&#8855;">
+<!ENTITY perp "&#8869;">
+<!ENTITY sdot "&#8901;">
+<!ENTITY lceil "&#8968;">
+<!ENTITY rceil "&#8969;">
+<!ENTITY lfloor "&#8970;">
+<!ENTITY rfloor "&#8971;">
+<!ENTITY lang "&#9001;">
+<!ENTITY rang "&#9002;">
+<!ENTITY loz "&#9674;">
+<!ENTITY spades "&#9824;">
+<!ENTITY clubs "&#9827;">
+<!ENTITY hearts "&#9829;">
+<!ENTITY diams "&#9830;">
+
+<!-- Markup-significant and internationalization characters -->
+<!ENTITY quot "&#34;">
+<!ENTITY amp "&#38;">
+<!ENTITY lt "&#60;">
+<!ENTITY gt "&#62;">
+<!ENTITY OElig "&#338;">
+<!ENTITY oelig "&#339;">
+<!ENTITY Scaron "&#352;">
+<!ENTITY scaron "&#353;">
+<!ENTITY Yuml "&#376;">
+<!ENTITY circ "&#710;">
+<!ENTITY tilde "&#732;">
+<!ENTITY ensp "&#8194;">
+<!ENTITY emsp "&#8195;">
+<!ENTITY thinsp "&#8201;">
+<!ENTITY zwnj "&#8204;">
+<!ENTITY zwj "&#8205;">
+<!ENTITY lrm "&#8206;">
+<!ENTITY rlm "&#8207;">
+<!ENTITY ndash "&#8211;">
+<!ENTITY mdash "&#8212;">
+<!ENTITY lsquo "&#8216;">
+<!ENTITY rsquo "&#8217;">
+<!ENTITY sbquo "&#8218;">
+<!ENTITY ldquo "&#8220;">
+<!ENTITY rdquo "&#8221;">
+<!ENTITY bdquo "&#8222;">
+<!ENTITY dagger "&#8224;">
+<!ENTITY Dagger "&#8225;">
+<!ENTITY permil "&#8240;">
+<!ENTITY lsaquo "&#8249;">
+<!ENTITY rsaquo "&#8250;">
+<!ENTITY euro "&#8364;">
diff --git a/bundles/XO/res/entityTables/html40Latin1.properties b/bundles/XO/res/entityTables/html40Latin1.properties
new file mode 100755
index 0000000..7d8e1d3
--- /dev/null
+++ b/bundles/XO/res/entityTables/html40Latin1.properties
@@ -0,0 +1,146 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1999 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# LOCALIZATION NOTE FILE
+# This file contains names that assign html elements to
+# ascii codepoints. Do not translate any of the "entities" in
+# this file.
+
+entity.list.name=html40Latin1
+entity.160=&nbsp;
+entity.161=&iexcl;
+entity.162=&cent;
+entity.163=&pound;
+entity.164=&curren;
+entity.165=&yen;
+entity.166=&brvbar;
+entity.167=&sect;
+entity.168=&uml;
+entity.169=&copy;
+entity.170=&ordf;
+entity.171=&laquo;
+entity.172=&not;
+entity.173=&shy;
+entity.174=&reg;
+entity.175=&macr;
+entity.176=&deg;
+entity.177=&plusmn;
+entity.178=&sup2;
+entity.179=&sup3;
+entity.180=&acute;
+entity.181=&micro;
+entity.182=&para;
+entity.183=&middot;
+entity.184=&cedil;
+entity.185=&sup1;
+entity.186=&ordm;
+entity.187=&raquo;
+entity.188=&frac14;
+entity.189=&frac12;
+entity.190=&frac34;
+entity.191=&iquest;
+entity.192=&Agrave;
+entity.193=&Aacute;
+entity.194=&Acirc;
+entity.195=&Atilde;
+entity.196=&Auml;
+entity.197=&Aring;
+entity.198=&AElig;
+entity.199=&Ccedil;
+entity.200=&Egrave;
+entity.201=&Eacute;
+entity.202=&Ecirc;
+entity.203=&Euml;
+entity.204=&Igrave;
+entity.205=&Iacute;
+entity.206=&Icirc;
+entity.207=&Iuml;
+entity.208=&ETH;
+entity.209=&Ntilde;
+entity.210=&Ograve;
+entity.211=&Oacute;
+entity.212=&Ocirc;
+entity.213=&Otilde;
+entity.214=&Ouml;
+entity.215=&times;
+entity.216=&Oslash;
+entity.217=&Ugrave;
+entity.218=&Uacute;
+entity.219=&Ucirc;
+entity.220=&Uuml;
+entity.221=&Yacute;
+entity.222=&THORN;
+entity.223=&szlig;
+entity.224=&agrave;
+entity.225=&aacute;
+entity.226=&acirc;
+entity.227=&atilde;
+entity.228=&auml;
+entity.229=&aring;
+entity.230=&aelig;
+entity.231=&ccedil;
+entity.232=&egrave;
+entity.233=&eacute;
+entity.234=&ecirc;
+entity.235=&euml;
+entity.236=&igrave;
+entity.237=&iacute;
+entity.238=&icirc;
+entity.239=&iuml;
+entity.240=&eth;
+entity.241=&ntilde;
+entity.242=&ograve;
+entity.243=&oacute;
+entity.244=&ocirc;
+entity.245=&otilde;
+entity.246=&ouml;
+entity.247=&divide;
+entity.248=&oslash;
+entity.249=&ugrave;
+entity.250=&uacute;
+entity.251=&ucirc;
+entity.252=&uuml;
+entity.253=&yacute;
+entity.254=&thorn;
+entity.255=&yuml;
+
+
+
+
+
+
+
+
diff --git a/bundles/XO/res/entityTables/html40Special.properties b/bundles/XO/res/entityTables/html40Special.properties
new file mode 100755
index 0000000..6f951fe
--- /dev/null
+++ b/bundles/XO/res/entityTables/html40Special.properties
@@ -0,0 +1,69 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# LOCALIZATION NOTE: FILE
+# This file contains names that assign entity references to
+# numbers in an entity.list object. Do not translate this file.
+
+entity.list.name=html40Special
+entity.338=&OElig;
+entity.339=&oelig;
+entity.352=&Scaron;
+entity.353=&scaron;
+entity.376=&Yuml;
+entity.710=&circ;
+entity.732=&tilde;
+entity.8194=&ensp;
+entity.8195=&emsp;
+entity.8201=&thinsp;
+entity.8204=&zwnj;
+entity.8205=&zwj;
+entity.8206=&lrm;
+entity.8207=&rlm;
+entity.8211=&ndash;
+entity.8212=&mdash;
+entity.8216=&lsquo;
+entity.8217=&rsquo;
+entity.8218=&sbquo;
+entity.8220=&ldquo;
+entity.8221=&rdquo;
+entity.8222=&bdquo;
+entity.8224=&dagger;
+entity.8225=&Dagger;
+entity.8240=&permil;
+entity.8249=&lsaquo;
+entity.8250=&rsaquo;
+entity.8364=&euro;
diff --git a/bundles/XO/res/entityTables/html40Symbols.properties b/bundles/XO/res/entityTables/html40Symbols.properties
new file mode 100755
index 0000000..c81a2ed
--- /dev/null
+++ b/bundles/XO/res/entityTables/html40Symbols.properties
@@ -0,0 +1,164 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# LOCALIZATION NOTE FILE
+# Do not translate this file.
+
+entity.list.name=html40Symbols
+entity.402=&fnof;
+entity.913=&Alpha;
+entity.914=&Beta;
+entity.915=&Gamma;
+entity.916=&Delta;
+entity.917=&Epsilon;
+entity.918=&Zeta;
+entity.919=&Eta;
+entity.920=&Theta;
+entity.921=&Iota;
+entity.922=&Kappa;
+entity.923=&Lambda;
+entity.924=&Mu;
+entity.925=&Nu;
+entity.926=&Xi;
+entity.927=&Omicron;
+entity.928=&Pi;
+entity.929=&Rho;
+entity.931=&Sigma;
+entity.932=&Tau;
+entity.933=&Upsilon;
+entity.934=&Phi;
+entity.935=&Chi;
+entity.936=&Psi;
+entity.937=&Omega;
+entity.945=&alpha;
+entity.946=&beta;
+entity.947=&gamma;
+entity.948=&delta;
+entity.949=&epsilon;
+entity.950=&zeta;
+entity.951=&eta;
+entity.952=&theta;
+entity.953=&iota;
+entity.954=&kappa;
+entity.955=&lambda;
+entity.956=&mu;
+entity.957=&nu;
+entity.958=&xi;
+entity.959=&omicron;
+entity.960=&pi;
+entity.961=&rho;
+entity.962=&sigmaf;
+entity.963=&sigma;
+entity.964=&tau;
+entity.965=&upsilon;
+entity.966=&phi;
+entity.967=&chi;
+entity.968=&psi;
+entity.969=&omega;
+entity.977=&thetasym;
+entity.978=&upsih;
+entity.982=&piv;
+entity.8226=&bull;
+entity.8230=&hellip;
+entity.8242=&prime;
+entity.8243=&Prime;
+entity.8254=&oline;
+entity.8260=&frasl;
+entity.8472=&weierp;
+entity.8465=&image;
+entity.8476=&real;
+entity.8482=&trade;
+entity.8501=&alefsym;
+entity.8592=&larr;
+entity.8593=&uarr;
+entity.8594=&rarr;
+entity.8595=&darr;
+entity.8596=&harr;
+entity.8629=&crarr;
+entity.8656=&lArr;
+entity.8657=&uArr;
+entity.8658=&rArr;
+entity.8659=&dArr;
+entity.8660=&hArr;
+entity.8704=&forall;
+entity.8706=&part;
+entity.8707=&exist;
+entity.8709=&empty;
+entity.8711=&nabla;
+entity.8712=&isin;
+entity.8713=&notin;
+entity.8715=&ni;
+entity.8719=&prod;
+entity.8721=&sum;
+entity.8722=&minus;
+entity.8727=&lowast;
+entity.8730=&radic;
+entity.8733=&prop;
+entity.8734=&infin;
+entity.8736=&ang;
+entity.8743=&and;
+entity.8744=&or;
+entity.8745=&cap;
+entity.8746=&cup;
+entity.8747=&int;
+entity.8756=&there4;
+entity.8764=&sim;
+entity.8773=&cong;
+entity.8776=&asymp;
+entity.8800=&ne;
+entity.8801=&equiv;
+entity.8804=&le;
+entity.8805=&ge;
+entity.8834=&sub;
+entity.8835=&sup;
+entity.8836=&nsub;
+entity.8838=&sube;
+entity.8839=&supe;
+entity.8853=&oplus;
+entity.8855=&otimes;
+entity.8869=&perp;
+entity.8901=&sdot;
+entity.8968=&lceil;
+entity.8969=&rceil;
+entity.8970=&lfloor;
+entity.8971=&rfloor;
+entity.9001=&lang;
+entity.9002=&rang;
+entity.9674=&loz;
+entity.9824=&spades;
+entity.9827=&clubs;
+entity.9829=&hearts;
+entity.9830=&diams;
diff --git a/bundles/XO/res/entityTables/htmlEntityVersions.properties b/bundles/XO/res/entityTables/htmlEntityVersions.properties
new file mode 100755
index 0000000..2ffc2d0
--- /dev/null
+++ b/bundles/XO/res/entityTables/htmlEntityVersions.properties
@@ -0,0 +1,50 @@
+
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+
+# LOCALIZATION NOTE: FILE
+# This file associates internal names of entity lists to integers.
+# Do not translate anything in this file
+
+# list supported versions number/name pair
+# length should not be greater than 32
+length=5
+1=html40Latin1
+2=html40Symbols
+3=html40Special
+4=transliterate
+5=mathml20
diff --git a/bundles/XO/res/entityTables/mathml20.properties b/bundles/XO/res/entityTables/mathml20.properties
new file mode 100755
index 0000000..5f44854
--- /dev/null
+++ b/bundles/XO/res/entityTables/mathml20.properties
@@ -0,0 +1,1286 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla MathML Project.
+#
+# The Initial Developer of the Original Code is
+# The University Of Queensland.
+# Portions created by the Initial Developer are Copyright (C) 2002
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Roger B. Sidje <rbs@maths.uq.edu.au>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+## LOCALIZATION NOTE: FILE
+# Do not translate this file.
+# The file contains a mapping of Unicode values to MathML entity names.
+# Entities already listed in html40 were deliberately excluded. So you must use
+# nsIEntityConverter.html40 + nsIEntityConverter.mathml20 to access everything.
+
+entity.list.name=mathml20
+entity.168=&DoubleDot;
+entity.175=&OverBar;
+entity.177=&PlusMinus;
+entity.184=&Cedilla;
+entity.256=&Amacr;
+entity.257=&amacr;
+entity.258=&Abreve;
+entity.259=&abreve;
+entity.260=&Aogon;
+entity.261=&aogon;
+entity.262=&Cacute;
+entity.263=&cacute;
+entity.264=&Ccirc;
+entity.265=&ccirc;
+entity.266=&Cdot;
+entity.267=&cdot;
+entity.268=&Ccaron;
+entity.269=&ccaron;
+entity.270=&Dcaron;
+entity.271=&dcaron;
+entity.272=&Dstrok;
+entity.273=&dstrok;
+entity.274=&Emacr;
+entity.275=&emacr;
+entity.278=&Edot;
+entity.279=&edot;
+entity.280=&Eogon;
+entity.281=&eogon;
+entity.282=&Ecaron;
+entity.283=&ecaron;
+entity.284=&Gcirc;
+entity.285=&gcirc;
+entity.286=&Gbreve;
+entity.287=&gbreve;
+entity.288=&Gdot;
+entity.289=&gdot;
+entity.290=&Gcedil;
+entity.292=&Hcirc;
+entity.293=&hcirc;
+entity.294=&Hstrok;
+entity.295=&hstrok;
+entity.296=&Itilde;
+entity.297=&itilde;
+entity.298=&Imacr;
+entity.299=&imacr;
+entity.302=&Iogon;
+entity.303=&iogon;
+entity.304=&Idot;
+entity.306=&IJlig;
+entity.307=&ijlig;
+entity.308=&Jcirc;
+entity.309=&jcirc;
+entity.310=&Kcedil;
+entity.311=&kcedil;
+entity.312=&kgreen;
+entity.313=&Lacute;
+entity.314=&lacute;
+entity.315=&Lcedil;
+entity.316=&lcedil;
+entity.317=&Lcaron;
+entity.318=&lcaron;
+entity.319=&Lmidot;
+entity.320=&lmidot;
+entity.321=&Lstrok;
+entity.322=&lstrok;
+entity.323=&Nacute;
+entity.324=&nacute;
+entity.325=&Ncedil;
+entity.326=&ncedil;
+entity.327=&Ncaron;
+entity.328=&ncaron;
+entity.329=&napos;
+entity.330=&ENG;
+entity.331=&eng;
+entity.332=&Omacr;
+entity.333=&omacr;
+entity.336=&Odblac;
+entity.337=&odblac;
+entity.340=&Racute;
+entity.341=&racute;
+entity.342=&Rcedil;
+entity.343=&rcedil;
+entity.344=&Rcaron;
+entity.345=&rcaron;
+entity.346=&Sacute;
+entity.347=&sacute;
+entity.348=&Scirc;
+entity.349=&scirc;
+entity.350=&Scedil;
+entity.351=&scedil;
+entity.354=&Tcedil;
+entity.355=&tcedil;
+entity.356=&Tcaron;
+entity.357=&tcaron;
+entity.358=&Tstrok;
+entity.359=&tstrok;
+entity.360=&Utilde;
+entity.361=&utilde;
+entity.362=&Umacr;
+entity.363=&umacr;
+entity.364=&Ubreve;
+entity.365=&ubreve;
+entity.366=&Uring;
+entity.367=&uring;
+entity.368=&Udblac;
+entity.369=&udblac;
+entity.370=&Uogon;
+entity.371=&uogon;
+entity.372=&Wcirc;
+entity.373=&wcirc;
+entity.374=&Ycirc;
+entity.375=&ycirc;
+entity.377=&Zacute;
+entity.378=&zacute;
+entity.379=&Zdot;
+entity.380=&zdot;
+entity.381=&Zcaron;
+entity.382=&zcaron;
+entity.437=&imped;
+entity.501=&gacute;
+entity.711=&Hacek;
+entity.728=&Breve;
+entity.729=&DiacriticalDot;
+entity.730=&ring;
+entity.731=&ogon;
+entity.732=&DiacriticalTilde;
+entity.733=&DiacriticalDoubleAcute;
+entity.785=&DownBreve;
+entity.818=&UnderBar;
+entity.949=&varepsilon;
+entity.962=&varsigma;
+entity.966=&varphi;
+entity.977=&vartheta;
+entity.978=&Upsi;
+entity.981=&straightphi;
+entity.982=&varpi;
+entity.988=&Gammad;
+entity.989=&digamma;
+entity.1008=&varkappa;
+entity.1009=&varrho;
+entity.1013=&straightepsilon;
+entity.1014=&backepsilon;
+entity.1025=&IOcy;
+entity.1026=&DJcy;
+entity.1027=&GJcy;
+entity.1028=&Jukcy;
+entity.1029=&DScy;
+entity.1030=&Iukcy;
+entity.1031=&YIcy;
+entity.1032=&Jsercy;
+entity.1033=&LJcy;
+entity.1034=&NJcy;
+entity.1035=&TSHcy;
+entity.1036=&KJcy;
+entity.1038=&Ubrcy;
+entity.1039=&DZcy;
+entity.1040=&Acy;
+entity.1041=&Bcy;
+entity.1042=&Vcy;
+entity.1043=&Gcy;
+entity.1044=&Dcy;
+entity.1045=&IEcy;
+entity.1046=&ZHcy;
+entity.1047=&Zcy;
+entity.1048=&Icy;
+entity.1049=&Jcy;
+entity.1050=&Kcy;
+entity.1051=&Lcy;
+entity.1052=&Mcy;
+entity.1053=&Ncy;
+entity.1054=&Ocy;
+entity.1055=&Pcy;
+entity.1056=&Rcy;
+entity.1057=&Scy;
+entity.1058=&Tcy;
+entity.1059=&Ucy;
+entity.1060=&Fcy;
+entity.1061=&KHcy;
+entity.1062=&TScy;
+entity.1063=&CHcy;
+entity.1064=&SHcy;
+entity.1065=&SHCHcy;
+entity.1066=&HARDcy;
+entity.1067=&Ycy;
+entity.1068=&SOFTcy;
+entity.1069=&Ecy;
+entity.1070=&YUcy;
+entity.1071=&YAcy;
+entity.1072=&acy;
+entity.1073=&bcy;
+entity.1074=&vcy;
+entity.1075=&gcy;
+entity.1076=&dcy;
+entity.1077=&iecy;
+entity.1078=&zhcy;
+entity.1079=&zcy;
+entity.1080=&icy;
+entity.1081=&jcy;
+entity.1082=&kcy;
+entity.1083=&lcy;
+entity.1084=&mcy;
+entity.1085=&ncy;
+entity.1086=&ocy;
+entity.1087=&pcy;
+entity.1088=&rcy;
+entity.1089=&scy;
+entity.1090=&tcy;
+entity.1091=&ucy;
+entity.1092=&fcy;
+entity.1093=&khcy;
+entity.1094=&tscy;
+entity.1095=&chcy;
+entity.1096=&shcy;
+entity.1097=&shchcy;
+entity.1098=&hardcy;
+entity.1099=&ycy;
+entity.1100=&softcy;
+entity.1101=&ecy;
+entity.1102=&yucy;
+entity.1103=&yacy;
+entity.1105=&iocy;
+entity.1106=&djcy;
+entity.1107=&gjcy;
+entity.1108=&jukcy;
+entity.1109=&dscy;
+entity.1110=&iukcy;
+entity.1111=&yicy;
+entity.1112=&jsercy;
+entity.1113=&ljcy;
+entity.1114=&njcy;
+entity.1115=&tshcy;
+entity.1116=&kjcy;
+entity.1118=&ubrcy;
+entity.1119=&dzcy;
+entity.8196=&emsp13;
+entity.8197=&emsp14;
+entity.8199=&numsp;
+entity.8200=&puncsp;
+entity.8201=&ThinSpace;
+entity.8202=&VeryThinSpace;
+entity.8203=&ZeroWidthSpace;
+entity.8208=&hyphen;
+entity.8213=&horbar;
+entity.8214=&Verbar;
+entity.8216=&OpenCurlyQuote;
+entity.8217=&CloseCurlyQuote;
+entity.8218=&lsquor;
+entity.8220=&OpenCurlyDoubleQuote;
+entity.8221=&CloseCurlyDoubleQuote;
+entity.8222=&ldquor;
+entity.8226=&bullet;
+entity.8229=&nldr;
+entity.8241=&pertenk;
+entity.8244=&tprime;
+entity.8245=&backprime;
+entity.8257=&caret;
+entity.8259=&hybull;
+entity.8271=&bsemi;
+entity.8279=&qprime;
+entity.8287=&MediumSpace;
+entity.8288=&NoBreak;
+entity.8289=&ApplyFunction;
+entity.8290=&InvisibleTimes;
+entity.8291=&InvisibleComma;
+entity.8411=&TripleDot;
+entity.8412=&DotDot;
+entity.8450=&Copf;
+entity.8453=&incare;
+entity.8458=&gscr;
+entity.8459=&HilbertSpace;
+entity.8460=&Poincareplane;
+entity.8461=&Hopf;
+entity.8462=&planckh;
+entity.8463=&hslash;
+entity.8464=&Iscr;
+entity.8465=&Ifr;
+entity.8466=&Laplacetrf;
+entity.8467=&ell;
+entity.8469=&Nopf;
+entity.8470=&numero;
+entity.8471=&copysr;
+entity.8473=&Popf;
+entity.8474=&Qopf;
+entity.8475=&Rscr;
+entity.8476=&Rfr;
+entity.8477=&Ropf;
+entity.8478=&rx;
+entity.8484=&Zopf;
+entity.8486=&ohm;
+entity.8487=&mho;
+entity.8488=&Zfr;
+entity.8489=&iiota;
+entity.8491=&angst;
+entity.8492=&Bernoullis;
+entity.8493=&Cayleys;
+entity.8495=&escr;
+entity.8496=&Escr;
+entity.8497=&Fouriertrf;
+entity.8499=&Mellintrf;
+entity.8500=&orderof;
+entity.8501=&aleph;
+entity.8502=&beth;
+entity.8503=&gimel;
+entity.8504=&daleth;
+entity.8517=&CapitalDifferentialD;
+entity.8518=&DifferentialD;
+entity.8519=&ExponentialE;
+entity.8520=&ImaginaryI;
+entity.8531=&frac13;
+entity.8532=&frac23;
+entity.8533=&frac15;
+entity.8534=&frac25;
+entity.8535=&frac35;
+entity.8536=&frac45;
+entity.8537=&frac16;
+entity.8538=&frac56;
+entity.8539=&frac18;
+entity.8540=&frac38;
+entity.8541=&frac58;
+entity.8542=&frac78;
+entity.8592=&LeftArrow;
+entity.8593=&UpArrow;
+entity.8594=&RightArrow;
+entity.8595=&DownArrow;
+entity.8596=&LeftRightArrow;
+entity.8597=&UpDownArrow;
+entity.8598=&UpperLeftArrow;
+entity.8599=&UpperRightArrow;
+entity.8600=&LowerRightArrow;
+entity.8601=&LowerLeftArrow;
+entity.8602=&nleftarrow;
+entity.8603=&nrightarrow;
+entity.8605=&rightsquigarrow;
+entity.8606=&Larr;
+entity.8607=&Uarr;
+entity.8608=&Rarr;
+entity.8609=&Darr;
+entity.8610=&leftarrowtail;
+entity.8611=&rightarrowtail;
+entity.8612=&LeftTeeArrow;
+entity.8613=&UpTeeArrow;
+entity.8614=&RightTeeArrow;
+entity.8615=&DownTeeArrow;
+entity.8617=&hookleftarrow;
+entity.8618=&hookrightarrow;
+entity.8619=&looparrowleft;
+entity.8620=&looparrowright;
+entity.8621=&leftrightsquigarrow;
+entity.8622=&nleftrightarrow;
+entity.8624=&Lsh;
+entity.8625=&Rsh;
+entity.8626=&ldsh;
+entity.8627=&rdsh;
+entity.8630=&curvearrowleft;
+entity.8631=&curvearrowright;
+entity.8634=&circlearrowleft;
+entity.8635=&circlearrowright;
+entity.8636=&LeftVector;
+entity.8637=&DownLeftVector;
+entity.8638=&RightUpVector;
+entity.8639=&LeftUpVector;
+entity.8640=&RightVector;
+entity.8641=&DownRightVector;
+entity.8642=&RightDownVector;
+entity.8643=&LeftDownVector;
+entity.8644=&RightArrowLeftArrow;
+entity.8645=&UpArrowDownArrow;
+entity.8646=&LeftArrowRightArrow;
+entity.8647=&leftleftarrows;
+entity.8648=&upuparrows;
+entity.8649=&rightrightarrows;
+entity.8650=&downdownarrows;
+entity.8651=&ReverseEquilibrium;
+entity.8652=&Equilibrium;
+entity.8653=&nLeftarrow;
+entity.8654=&nLeftrightarrow;
+entity.8655=&nRightarrow;
+entity.8656=&DoubleLeftArrow;
+entity.8657=&DoubleUpArrow;
+entity.8658=&DoubleRightArrow;
+entity.8659=&DoubleDownArrow;
+entity.8660=&DoubleLeftRightArrow;
+entity.8661=&DoubleUpDownArrow;
+entity.8662=&nwArr;
+entity.8663=&neArr;
+entity.8664=&seArr;
+entity.8665=&swArr;
+entity.8666=&Lleftarrow;
+entity.8667=&Rrightarrow;
+entity.8669=&zigrarr;
+entity.8676=&LeftArrowBar;
+entity.8677=&RightArrowBar;
+entity.8693=&DownArrowUpArrow;
+entity.8701=&loarr;
+entity.8702=&roarr;
+entity.8703=&hoarr;
+entity.8704=&ForAll;
+entity.8705=&complement;
+entity.8706=&PartialD;
+entity.8707=&Exists;
+entity.8708=&NotExists;
+entity.8709=&emptyset;
+entity.8711=&Del;
+entity.8712=&Element;
+entity.8713=&NotElement;
+entity.8715=&ReverseElement;
+entity.8716=&NotReverseElement;
+entity.8719=&Product;
+entity.8720=&Coproduct;
+entity.8721=&Sum;
+entity.8723=&MinusPlus;
+entity.8724=&dotplus;
+entity.8726=&Backslash;
+entity.8728=&SmallCircle;
+entity.8730=&Sqrt;
+entity.8733=&Proportional;
+entity.8735=&angrt;
+entity.8736=&angle;
+entity.8737=&measuredangle;
+entity.8738=&angsph;
+entity.8739=&VerticalBar;
+entity.8740=&NotVerticalBar;
+entity.8741=&DoubleVerticalBar;
+entity.8742=&NotDoubleVerticalBar;
+entity.8743=&wedge;
+entity.8744=&vee;
+entity.8747=&Integral;
+entity.8748=&Int;
+entity.8749=&iiint;
+entity.8750=&ContourIntegral;
+entity.8751=&DoubleContourIntegral;
+entity.8752=&Cconint;
+entity.8753=&cwint;
+entity.8754=&ClockwiseContourIntegral;
+entity.8755=&CounterClockwiseContourIntegral;
+entity.8756=&Therefore;
+entity.8757=&Because;
+entity.8758=&ratio;
+entity.8759=&Proportion;
+entity.8760=&dotminus;
+entity.8762=&mDDot;
+entity.8763=&homtht;
+entity.8764=&Tilde;
+entity.8765=&backsim;
+entity.8766=&mstpos;
+entity.8767=&acd;
+entity.8768=&VerticalTilde;
+entity.8769=&NotTilde;
+entity.8770=&EqualTilde;
+entity.8771=&TildeEqual;
+entity.8772=&NotTildeEqual;
+entity.8773=&TildeFullEqual;
+entity.8774=&simne;
+entity.8775=&NotTildeFullEqual;
+entity.8776=&TildeTilde;
+entity.8777=&NotTildeTilde;
+entity.8778=&approxeq;
+entity.8779=&apid;
+entity.8780=&backcong;
+entity.8781=&CupCap;
+entity.8782=&HumpDownHump;
+entity.8783=&HumpEqual;
+entity.8784=&DotEqual;
+entity.8785=&doteqdot;
+entity.8786=&fallingdotseq;
+entity.8787=&risingdotseq;
+entity.8788=&Assign;
+entity.8789=&eqcolon;
+entity.8790=&eqcirc;
+entity.8791=&circeq;
+entity.8793=&wedgeq;
+entity.8794=&veeeq;
+entity.8796=&triangleq;
+entity.8799=&questeq;
+entity.8800=&NotEqual;
+entity.8801=&Congruent;
+entity.8802=&NotCongruent;
+entity.8804=&leq;
+entity.8805=&GreaterEqual;
+entity.8806=&LessFullEqual;
+entity.8807=&GreaterFullEqual;
+entity.8808=&lneqq;
+entity.8809=&gneqq;
+entity.8810=&NestedLessLess;
+entity.8811=&NestedGreaterGreater;
+entity.8812=&between;
+entity.8813=&NotCupCap;
+entity.8814=&NotLess;
+entity.8815=&NotGreater;
+entity.8816=&NotLessEqual;
+entity.8817=&NotGreaterEqual;
+entity.8818=&LessTilde;
+entity.8819=&GreaterTilde;
+entity.8820=&NotLessTilde;
+entity.8821=&NotGreaterTilde;
+entity.8822=&LessGreater;
+entity.8823=&GreaterLess;
+entity.8824=&NotLessGreater;
+entity.8825=&NotGreaterLess;
+entity.8826=&Precedes;
+entity.8827=&Succeeds;
+entity.8828=&PrecedesSlantEqual;
+entity.8829=&SucceedsSlantEqual;
+entity.8830=&PrecedesTilde;
+entity.8831=&SucceedsTilde;
+entity.8832=&NotPrecedes;
+entity.8833=&NotSucceeds;
+entity.8834=&subset;
+entity.8835=&Superset;
+entity.8837=&nsup;
+entity.8838=&SubsetEqual;
+entity.8839=&SupersetEqual;
+entity.8840=&NotSubsetEqual;
+entity.8841=&NotSupersetEqual;
+entity.8842=&subsetneq;
+entity.8843=&supsetneq;
+entity.8845=&cupdot;
+entity.8846=&UnionPlus;
+entity.8847=&SquareSubset;
+entity.8848=&SquareSuperset;
+entity.8849=&SquareSubsetEqual;
+entity.8850=&SquareSupersetEqual;
+entity.8851=&SquareIntersection;
+entity.8852=&SquareUnion;
+entity.8853=&CirclePlus;
+entity.8854=&CircleMinus;
+entity.8855=&CircleTimes;
+entity.8856=&osol;
+entity.8857=&CircleDot;
+entity.8858=&circledcirc;
+entity.8859=&circledast;
+entity.8861=&circleddash;
+entity.8862=&boxplus;
+entity.8863=&boxminus;
+entity.8864=&boxtimes;
+entity.8865=&dotsquare;
+entity.8866=&RightTee;
+entity.8867=&LeftTee;
+entity.8868=&DownTee;
+entity.8869=&UpTee;
+entity.8871=&models;
+entity.8872=&DoubleRightTee;
+entity.8873=&Vdash;
+entity.8874=&Vvdash;
+entity.8875=&VDash;
+entity.8876=&nvdash;
+entity.8877=&nvDash;
+entity.8878=&nVdash;
+entity.8879=&nVDash;
+entity.8880=&prurel;
+entity.8882=&LeftTriangle;
+entity.8883=&RightTriangle;
+entity.8884=&LeftTriangleEqual;
+entity.8885=&RightTriangleEqual;
+entity.8886=&origof;
+entity.8887=&imof;
+entity.8888=&multimap;
+entity.8889=&hercon;
+entity.8890=&intercal;
+entity.8891=&veebar;
+entity.8893=&barvee;
+entity.8894=&angrtvb;
+entity.8895=&lrtri;
+entity.8896=&Wedge;
+entity.8897=&Vee;
+entity.8898=&Intersection;
+entity.8899=&Union;
+entity.8900=&Diamond;
+entity.8902=&Star;
+entity.8903=&divideontimes;
+entity.8904=&bowtie;
+entity.8905=&ltimes;
+entity.8906=&rtimes;
+entity.8907=&leftthreetimes;
+entity.8908=&rightthreetimes;
+entity.8909=&backsimeq;
+entity.8910=&curlyvee;
+entity.8911=&curlywedge;
+entity.8912=&Subset;
+entity.8913=&Supset;
+entity.8914=&Cap;
+entity.8915=&Cup;
+entity.8916=&pitchfork;
+entity.8917=&epar;
+entity.8918=&lessdot;
+entity.8919=&gtrdot;
+entity.8920=&Ll;
+entity.8921=&Gg;
+entity.8922=&LessEqualGreater;
+entity.8923=&GreaterEqualLess;
+entity.8926=&curlyeqprec;
+entity.8927=&curlyeqsucc;
+entity.8928=&NotPrecedesSlantEqual;
+entity.8929=&NotSucceedsSlantEqual;
+entity.8930=&NotSquareSubsetEqual;
+entity.8931=&NotSquareSupersetEqual;
+entity.8934=&lnsim;
+entity.8935=&gnsim;
+entity.8936=&precnsim;
+entity.8937=&succnsim;
+entity.8938=&NotLeftTriangle;
+entity.8939=&NotRightTriangle;
+entity.8940=&NotLeftTriangleEqual;
+entity.8941=&NotRightTriangleEqual;
+entity.8942=&vellip;
+entity.8943=&ctdot;
+entity.8944=&utdot;
+entity.8945=&dtdot;
+entity.8946=&disin;
+entity.8947=&isinsv;
+entity.8948=&isins;
+entity.8949=&isindot;
+entity.8950=&notinvc;
+entity.8951=&notinvb;
+entity.8953=&isinE;
+entity.8954=&nisd;
+entity.8955=&xnis;
+entity.8956=&nis;
+entity.8957=&notnivc;
+entity.8958=&notnivb;
+entity.8965=&barwedge;
+entity.8966=&Barwed;
+entity.8968=&LeftCeiling;
+entity.8969=&RightCeiling;
+entity.8970=&LeftFloor;
+entity.8971=&RightFloor;
+entity.8972=&drcrop;
+entity.8973=&dlcrop;
+entity.8974=&urcrop;
+entity.8975=&ulcrop;
+entity.8976=&bnot;
+entity.8978=&profline;
+entity.8979=&profsurf;
+entity.8981=&telrec;
+entity.8982=&target;
+entity.8988=&ulcorner;
+entity.8989=&urcorner;
+entity.8990=&llcorner;
+entity.8991=&lrcorner;
+entity.8994=&frown;
+entity.8995=&smile;
+entity.9005=&cylcty;
+entity.9006=&profalar;
+entity.9014=&topbot;
+entity.9021=&ovbar;
+entity.9023=&solbar;
+entity.9084=&angzarr;
+entity.9136=&lmoustache;
+entity.9137=&rmoustache;
+entity.9140=&OverBracket;
+entity.9141=&UnderBracket;
+entity.9142=&bbrktbrk;
+entity.9180=&OverParenthesis;
+entity.9181=&UnderParenthesis;
+entity.9182=&OverBrace;
+entity.9183=&UnderBrace;
+entity.9186=&trpezium;
+entity.9191=&elinters;
+entity.9251=&blank;
+entity.9416=&circledS;
+entity.9472=&HorizontalLine;
+entity.9474=&boxv;
+entity.9484=&boxdr;
+entity.9488=&boxdl;
+entity.9492=&boxur;
+entity.9496=&boxul;
+entity.9500=&boxvr;
+entity.9508=&boxvl;
+entity.9516=&boxhd;
+entity.9524=&boxhu;
+entity.9532=&boxvh;
+entity.9552=&boxH;
+entity.9553=&boxV;
+entity.9554=&boxdR;
+entity.9555=&boxDr;
+entity.9556=&boxDR;
+entity.9557=&boxdL;
+entity.9558=&boxDl;
+entity.9559=&boxDL;
+entity.9560=&boxuR;
+entity.9561=&boxUr;
+entity.9562=&boxUR;
+entity.9563=&boxuL;
+entity.9564=&boxUl;
+entity.9565=&boxUL;
+entity.9566=&boxvR;
+entity.9567=&boxVr;
+entity.9568=&boxVR;
+entity.9569=&boxvL;
+entity.9570=&boxVl;
+entity.9571=&boxVL;
+entity.9572=&boxHd;
+entity.9573=&boxhD;
+entity.9574=&boxHD;
+entity.9575=&boxHu;
+entity.9576=&boxhU;
+entity.9577=&boxHU;
+entity.9578=&boxvH;
+entity.9579=&boxVh;
+entity.9580=&boxVH;
+entity.9600=&uhblk;
+entity.9604=&lhblk;
+entity.9608=&block;
+entity.9617=&blk14;
+entity.9618=&blk12;
+entity.9619=&blk34;
+entity.9633=&Square;
+entity.9642=&FilledVerySmallSquare;
+entity.9643=&EmptyVerySmallSquare;
+entity.9645=&rect;
+entity.9646=&marker;
+entity.9649=&fltns;
+entity.9651=&bigtriangleup;
+entity.9652=&blacktriangle;
+entity.9653=&triangle;
+entity.9656=&blacktriangleright;
+entity.9657=&triangleright;
+entity.9661=&bigtriangledown;
+entity.9662=&blacktriangledown;
+entity.9663=&triangledown;
+entity.9666=&blacktriangleleft;
+entity.9667=&triangleleft;
+entity.9674=&lozenge;
+entity.9675=&cir;
+entity.9708=&tridot;
+entity.9711=&bigcirc;
+entity.9720=&ultri;
+entity.9721=&urtri;
+entity.9722=&lltri;
+entity.9723=&EmptySmallSquare;
+entity.9724=&FilledSmallSquare;
+entity.9733=&bigstar;
+entity.9734=&star;
+entity.9742=&phone;
+entity.9792=&female;
+entity.9794=&male;
+entity.9824=&spadesuit;
+entity.9827=&clubsuit;
+entity.9829=&heartsuit;
+entity.9830=&diamondsuit;
+entity.9834=&sung;
+entity.9837=&flat;
+entity.9838=&natural;
+entity.9839=&sharp;
+entity.10003=&checkmark;
+entity.10007=&cross;
+entity.10016=&maltese;
+entity.10038=&sext;
+entity.10072=&VerticalSeparator;
+entity.10098=&lbbrk;
+entity.10099=&rbbrk;
+entity.10214=&LeftDoubleBracket;
+entity.10215=&RightDoubleBracket;
+entity.10216=&LeftAngleBracket;
+entity.10217=&RightAngleBracket;
+entity.10218=&Lang;
+entity.10219=&Rang;
+entity.10220=&loang;
+entity.10221=&roang;
+entity.10229=&LongLeftArrow;
+entity.10230=&LongRightArrow;
+entity.10231=&LongLeftRightArrow;
+entity.10232=&DoubleLongLeftArrow;
+entity.10233=&DoubleLongRightArrow;
+entity.10234=&DoubleLongLeftRightArrow;
+entity.10236=&longmapsto;
+entity.10239=&dzigrarr;
+entity.10498=&nvlArr;
+entity.10499=&nvrArr;
+entity.10500=&nvHarr;
+entity.10501=&Map;
+entity.10508=&lbarr;
+entity.10509=&bkarow;
+entity.10510=&lBarr;
+entity.10511=&dbkarow;
+entity.10512=&RBarr;
+entity.10513=&DDotrahd;
+entity.10514=&UpArrowBar;
+entity.10515=&DownArrowBar;
+entity.10518=&Rarrtl;
+entity.10521=&latail;
+entity.10522=&ratail;
+entity.10523=&lAtail;
+entity.10524=&rAtail;
+entity.10525=&larrfs;
+entity.10526=&rarrfs;
+entity.10527=&larrbfs;
+entity.10528=&rarrbfs;
+entity.10531=&nwarhk;
+entity.10532=&nearhk;
+entity.10533=&hksearow;
+entity.10534=&hkswarow;
+entity.10535=&nwnear;
+entity.10536=&nesear;
+entity.10537=&seswar;
+entity.10538=&swnwar;
+entity.10547=&rarrc;
+entity.10549=&cudarrr;
+entity.10550=&ldca;
+entity.10551=&rdca;
+entity.10552=&cudarrl;
+entity.10553=&larrpl;
+entity.10556=&curarrm;
+entity.10557=&cularrp;
+entity.10565=&rarrpl;
+entity.10568=&harrcir;
+entity.10569=&Uarrocir;
+entity.10570=&lurdshar;
+entity.10571=&ldrushar;
+entity.10574=&LeftRightVector;
+entity.10575=&RightUpDownVector;
+entity.10576=&DownLeftRightVector;
+entity.10577=&LeftUpDownVector;
+entity.10578=&LeftVectorBar;
+entity.10579=&RightVectorBar;
+entity.10580=&RightUpVectorBar;
+entity.10581=&RightDownVectorBar;
+entity.10582=&DownLeftVectorBar;
+entity.10583=&DownRightVectorBar;
+entity.10584=&LeftUpVectorBar;
+entity.10585=&LeftDownVectorBar;
+entity.10586=&LeftTeeVector;
+entity.10587=&RightTeeVector;
+entity.10588=&RightUpTeeVector;
+entity.10589=&RightDownTeeVector;
+entity.10590=&DownLeftTeeVector;
+entity.10591=&DownRightTeeVector;
+entity.10592=&LeftUpTeeVector;
+entity.10593=&LeftDownTeeVector;
+entity.10594=&lHar;
+entity.10595=&uHar;
+entity.10596=&rHar;
+entity.10597=&dHar;
+entity.10598=&luruhar;
+entity.10599=&ldrdhar;
+entity.10600=&ruluhar;
+entity.10601=&rdldhar;
+entity.10602=&lharul;
+entity.10603=&llhard;
+entity.10604=&rharul;
+entity.10605=&lrhard;
+entity.10606=&UpEquilibrium;
+entity.10607=&ReverseUpEquilibrium;
+entity.10608=&RoundImplies;
+entity.10609=&erarr;
+entity.10610=&simrarr;
+entity.10611=&larrsim;
+entity.10612=&rarrsim;
+entity.10613=&rarrap;
+entity.10614=&ltlarr;
+entity.10616=&gtrarr;
+entity.10617=&subrarr;
+entity.10619=&suplarr;
+entity.10620=&lfisht;
+entity.10621=&rfisht;
+entity.10622=&ufisht;
+entity.10623=&dfisht;
+entity.10629=&lopar;
+entity.10630=&ropar;
+entity.10635=&lbrke;
+entity.10636=&rbrke;
+entity.10637=&lbrkslu;
+entity.10638=&rbrksld;
+entity.10639=&lbrksld;
+entity.10640=&rbrkslu;
+entity.10641=&langd;
+entity.10642=&rangd;
+entity.10643=&lparlt;
+entity.10644=&rpargt;
+entity.10645=&gtlPar;
+entity.10646=&ltrPar;
+entity.10650=&vzigzag;
+entity.10652=&vangrt;
+entity.10653=&angrtvbd;
+entity.10660=&ange;
+entity.10661=&range;
+entity.10662=&dwangle;
+entity.10663=&uwangle;
+entity.10664=&angmsdaa;
+entity.10665=&angmsdab;
+entity.10666=&angmsdac;
+entity.10667=&angmsdad;
+entity.10668=&angmsdae;
+entity.10669=&angmsdaf;
+entity.10670=&angmsdag;
+entity.10671=&angmsdah;
+entity.10672=&bemptyv;
+entity.10673=&demptyv;
+entity.10674=&cemptyv;
+entity.10675=&raemptyv;
+entity.10676=&laemptyv;
+entity.10677=&ohbar;
+entity.10678=&omid;
+entity.10679=&opar;
+entity.10681=&operp;
+entity.10683=&olcross;
+entity.10684=&odsold;
+entity.10686=&olcir;
+entity.10687=&ofcir;
+entity.10688=&olt;
+entity.10689=&ogt;
+entity.10690=&cirscir;
+entity.10691=&cirE;
+entity.10692=&solb;
+entity.10693=&bsolb;
+entity.10697=&boxbox;
+entity.10701=&trisb;
+entity.10702=&rtriltri;
+entity.10703=&LeftTriangleBar;
+entity.10704=&RightTriangleBar;
+entity.10714=&race;
+entity.10716=&iinfin;
+entity.10717=&infintie;
+entity.10718=&nvinfin;
+entity.10723=&eparsl;
+entity.10724=&smeparsl;
+entity.10725=&eqvparsl;
+entity.10731=&blacklozenge;
+entity.10740=&RuleDelayed;
+entity.10742=&dsol;
+entity.10752=&bigodot;
+entity.10753=&bigoplus;
+entity.10754=&bigotimes;
+entity.10756=&biguplus;
+entity.10758=&bigsqcup;
+entity.10764=&iiiint;
+entity.10765=&fpartint;
+entity.10768=&cirfnint;
+entity.10769=&awint;
+entity.10770=&rppolint;
+entity.10771=&scpolint;
+entity.10772=&npolint;
+entity.10773=&pointint;
+entity.10774=&quatint;
+entity.10775=&intlarhk;
+entity.10786=&pluscir;
+entity.10787=&plusacir;
+entity.10788=&simplus;
+entity.10789=&plusdu;
+entity.10790=&plussim;
+entity.10791=&plustwo;
+entity.10793=&mcomma;
+entity.10794=&minusdu;
+entity.10797=&loplus;
+entity.10798=&roplus;
+entity.10799=&Cross;
+entity.10800=&timesd;
+entity.10801=&timesbar;
+entity.10803=&smashp;
+entity.10804=&lotimes;
+entity.10805=&rotimes;
+entity.10806=&otimesas;
+entity.10807=&Otimes;
+entity.10808=&odiv;
+entity.10809=&triplus;
+entity.10810=&triminus;
+entity.10811=&tritime;
+entity.10812=&intprod;
+entity.10815=&amalg;
+entity.10816=&capdot;
+entity.10818=&ncup;
+entity.10819=&ncap;
+entity.10820=&capand;
+entity.10821=&cupor;
+entity.10822=&cupcap;
+entity.10823=&capcup;
+entity.10824=&cupbrcap;
+entity.10825=&capbrcup;
+entity.10826=&cupcup;
+entity.10827=&capcap;
+entity.10828=&ccups;
+entity.10829=&ccaps;
+entity.10832=&ccupssm;
+entity.10835=&And;
+entity.10836=&Or;
+entity.10837=&andand;
+entity.10838=&oror;
+entity.10839=&orslope;
+entity.10840=&andslope;
+entity.10842=&andv;
+entity.10843=&orv;
+entity.10844=&andd;
+entity.10845=&ord;
+entity.10847=&wedbar;
+entity.10854=&sdote;
+entity.10858=&simdot;
+entity.10861=&congdot;
+entity.10862=&easter;
+entity.10863=&apacir;
+entity.10864=&apE;
+entity.10865=&eplus;
+entity.10866=&pluse;
+entity.10867=&Esim;
+entity.10868=&Colone;
+entity.10869=&Equal;
+entity.10871=&ddotseq;
+entity.10872=&equivDD;
+entity.10873=&ltcir;
+entity.10874=&gtcir;
+entity.10875=&ltquest;
+entity.10876=&gtquest;
+entity.10877=&LessSlantEqual;
+entity.10878=&GreaterSlantEqual;
+entity.10879=&lesdot;
+entity.10880=&gesdot;
+entity.10881=&lesdoto;
+entity.10882=&gesdoto;
+entity.10883=&lesdotor;
+entity.10884=&gesdotol;
+entity.10885=&lessapprox;
+entity.10886=&gtrapprox;
+entity.10887=&lneq;
+entity.10888=&gneq;
+entity.10889=&lnapprox;
+entity.10890=&gnapprox;
+entity.10891=&lesseqqgtr;
+entity.10892=&gtreqqless;
+entity.10893=&lsime;
+entity.10894=&gsime;
+entity.10895=&lsimg;
+entity.10896=&gsiml;
+entity.10897=&lgE;
+entity.10898=&glE;
+entity.10899=&lesges;
+entity.10900=&gesles;
+entity.10901=&eqslantless;
+entity.10902=&eqslantgtr;
+entity.10903=&elsdot;
+entity.10904=&egsdot;
+entity.10905=&el;
+entity.10906=&eg;
+entity.10909=&siml;
+entity.10910=&simg;
+entity.10911=&simlE;
+entity.10912=&simgE;
+entity.10913=&LessLess;
+entity.10914=&GreaterGreater;
+entity.10916=&glj;
+entity.10917=&gla;
+entity.10918=&ltcc;
+entity.10919=&gtcc;
+entity.10920=&lescc;
+entity.10921=&gescc;
+entity.10922=&smt;
+entity.10923=&lat;
+entity.10924=&smte;
+entity.10925=&late;
+entity.10926=&bumpE;
+entity.10927=&PrecedesEqual;
+entity.10928=&SucceedsEqual;
+entity.10931=&prE;
+entity.10932=&scE;
+entity.10933=&precneqq;
+entity.10934=&succneqq;
+entity.10935=&precapprox;
+entity.10936=&succapprox;
+entity.10937=&precnapprox;
+entity.10938=&succnapprox;
+entity.10939=&Pr;
+entity.10940=&Sc;
+entity.10941=&subdot;
+entity.10942=&supdot;
+entity.10943=&subplus;
+entity.10944=&supplus;
+entity.10945=&submult;
+entity.10946=&supmult;
+entity.10947=&subedot;
+entity.10948=&supedot;
+entity.10949=&subseteqq;
+entity.10950=&supseteqq;
+entity.10951=&subsim;
+entity.10952=&supsim;
+entity.10955=&subsetneqq;
+entity.10956=&supsetneqq;
+entity.10959=&csub;
+entity.10960=&csup;
+entity.10961=&csube;
+entity.10962=&csupe;
+entity.10963=&subsup;
+entity.10964=&supsub;
+entity.10965=&subsub;
+entity.10966=&supsup;
+entity.10967=&suphsub;
+entity.10968=&supdsub;
+entity.10969=&forkv;
+entity.10970=&topfork;
+entity.10971=&mlcp;
+entity.10980=&DoubleLeftTee;
+entity.10982=&Vdashl;
+entity.10983=&Barv;
+entity.10984=&vBar;
+entity.10985=&vBarv;
+entity.10987=&Vbar;
+entity.10988=&Not;
+entity.10989=&bNot;
+entity.10990=&rnmid;
+entity.10991=&cirmid;
+entity.10992=&midcir;
+entity.10993=&topcir;
+entity.10994=&nhpar;
+entity.10995=&parsim;
+entity.11005=&parsl;
+entity.64256=&fflig;
+entity.64257=&filig;
+entity.64258=&fllig;
+entity.64259=&ffilig;
+entity.64260=&ffllig;
+entity.119964=&Ascr;
+entity.119966=&Cscr;
+entity.119967=&Dscr;
+entity.119970=&Gscr;
+entity.119973=&Jscr;
+entity.119974=&Kscr;
+entity.119977=&Nscr;
+entity.119978=&Oscr;
+entity.119979=&Pscr;
+entity.119980=&Qscr;
+entity.119982=&Sscr;
+entity.119983=&Tscr;
+entity.119984=&Uscr;
+entity.119985=&Vscr;
+entity.119986=&Wscr;
+entity.119987=&Xscr;
+entity.119988=&Yscr;
+entity.119989=&Zscr;
+entity.119990=&ascr;
+entity.119991=&bscr;
+entity.119992=&cscr;
+entity.119993=&dscr;
+entity.119995=&fscr;
+entity.119997=&hscr;
+entity.119998=&iscr;
+entity.119999=&jscr;
+entity.120000=&kscr;
+entity.120001=&lscr;
+entity.120002=&mscr;
+entity.120003=&nscr;
+entity.120005=&pscr;
+entity.120006=&qscr;
+entity.120007=&rscr;
+entity.120008=&sscr;
+entity.120009=&tscr;
+entity.120010=&uscr;
+entity.120011=&vscr;
+entity.120012=&wscr;
+entity.120013=&xscr;
+entity.120014=&yscr;
+entity.120015=&zscr;
+entity.120068=&Afr;
+entity.120069=&Bfr;
+entity.120071=&Dfr;
+entity.120072=&Efr;
+entity.120073=&Ffr;
+entity.120074=&Gfr;
+entity.120077=&Jfr;
+entity.120078=&Kfr;
+entity.120079=&Lfr;
+entity.120080=&Mfr;
+entity.120081=&Nfr;
+entity.120082=&Ofr;
+entity.120083=&Pfr;
+entity.120084=&Qfr;
+entity.120086=&Sfr;
+entity.120087=&Tfr;
+entity.120088=&Ufr;
+entity.120089=&Vfr;
+entity.120090=&Wfr;
+entity.120091=&Xfr;
+entity.120092=&Yfr;
+entity.120094=&afr;
+entity.120095=&bfr;
+entity.120096=&cfr;
+entity.120097=&dfr;
+entity.120098=&efr;
+entity.120099=&ffr;
+entity.120100=&gfr;
+entity.120101=&hfr;
+entity.120102=&ifr;
+entity.120103=&jfr;
+entity.120104=&kfr;
+entity.120105=&lfr;
+entity.120106=&mfr;
+entity.120107=&nfr;
+entity.120108=&ofr;
+entity.120109=&pfr;
+entity.120110=&qfr;
+entity.120111=&rfr;
+entity.120112=&sfr;
+entity.120113=&tfr;
+entity.120114=&ufr;
+entity.120115=&vfr;
+entity.120116=&wfr;
+entity.120117=&xfr;
+entity.120118=&yfr;
+entity.120119=&zfr;
+entity.120120=&Aopf;
+entity.120121=&Bopf;
+entity.120123=&Dopf;
+entity.120124=&Eopf;
+entity.120125=&Fopf;
+entity.120126=&Gopf;
+entity.120128=&Iopf;
+entity.120129=&Jopf;
+entity.120130=&Kopf;
+entity.120131=&Lopf;
+entity.120132=&Mopf;
+entity.120134=&Oopf;
+entity.120138=&Sopf;
+entity.120139=&Topf;
+entity.120140=&Uopf;
+entity.120141=&Vopf;
+entity.120142=&Wopf;
+entity.120143=&Xopf;
+entity.120144=&Yopf;
+entity.120146=&aopf;
+entity.120147=&bopf;
+entity.120148=&copf;
+entity.120149=&dopf;
+entity.120150=&eopf;
+entity.120151=&fopf;
+entity.120152=&gopf;
+entity.120153=&hopf;
+entity.120154=&iopf;
+entity.120155=&jopf;
+entity.120156=&kopf;
+entity.120157=&lopf;
+entity.120158=&mopf;
+entity.120159=&nopf;
+entity.120160=&oopf;
+entity.120161=&popf;
+entity.120162=&qopf;
+entity.120163=&ropf;
+entity.120164=&sopf;
+entity.120165=&topf;
+entity.120166=&uopf;
+entity.120167=&vopf;
+entity.120168=&wopf;
+entity.120169=&xopf;
+entity.120170=&yopf;
+entity.120171=&zopf;
+entity.120484=&imath;
+entity.120485=&jmath;
diff --git a/bundles/XO/res/entityTables/transliterate.properties b/bundles/XO/res/entityTables/transliterate.properties
new file mode 100755
index 0000000..40058ce
--- /dev/null
+++ b/bundles/XO/res/entityTables/transliterate.properties
@@ -0,0 +1,2466 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+#
+# THIS FILE IS GENERATED BY mozilla/intl/unicharutil/tools/gentransliterate.pl
+# PLEASE DO NOT MODIFY THIS FILE BY HAND
+#
+entity.list.name=transliterate
+entity.169=(c)
+#
+#
+# Here are the windows-1252 characters from the range 0x80 - 0x9F
+#
+entity.8364=EUR
+entity.8218=,
+entity.402=f
+entity.8222="
+entity.8224=+
+entity.8225=++
+entity.710=^
+entity.8240=0/00
+entity.8249=<
+entity.338=OE
+entity.8216='
+entity.8217='
+entity.8220="
+entity.8221="
+entity.8226=.
+entity.8211=--
+entity.8212=---
+entity.732=~
+entity.8250=>
+entity.339=oe
+entity.8192=\u0020
+entity.8193=\u0020
+entity.8208=-
+entity.8209=-
+entity.8210=-
+entity.8213=--
+entity.8203=
+entity.8289=
+entity.8290=
+entity.8518=d
+entity.8722=-
+entity.1470=-
+entity.1472=|
+entity.1475=:
+entity.1523='
+entity.1524="
+##
+## End of hand coded section
+## Below are generated from the unicode character database
+##
+entity.160=\u0020
+entity.170=^(a)
+entity.178=^(2)
+entity.179=^(3)
+entity.185=^(1)
+entity.186=^(o)
+entity.188=1/4
+entity.189=1/2
+entity.190=3/4
+entity.192=A`
+entity.193=A'
+entity.194=A^
+entity.195=A~
+entity.196=A"
+entity.197=A*
+entity.199=C,
+entity.200=E`
+entity.201=E'
+entity.202=E^
+entity.203=E"
+entity.204=I`
+entity.205=I'
+entity.206=I^
+entity.207=I"
+entity.209=N~
+entity.210=O`
+entity.211=O'
+entity.212=O^
+entity.213=O~
+entity.214=O"
+entity.217=U`
+entity.218=U'
+entity.219=U^
+entity.220=U"
+entity.221=Y'
+entity.224=a`
+entity.225=a'
+entity.226=a^
+entity.227=a~
+entity.228=a"
+entity.229=a*
+entity.231=c,
+entity.232=e`
+entity.233=e'
+entity.234=e^
+entity.235=e"
+entity.236=i`
+entity.237=i'
+entity.238=i^
+entity.239=i"
+entity.241=n~
+entity.242=o`
+entity.243=o'
+entity.244=o^
+entity.245=o~
+entity.246=o"
+entity.249=u`
+entity.250=u'
+entity.251=u^
+entity.252=u"
+entity.253=y'
+entity.255=y"
+entity.256=A-
+entity.257=a-
+entity.258=A(
+entity.259=a(
+entity.260=A;
+entity.261=a;
+entity.262=C'
+entity.263=c'
+entity.264=C^
+entity.265=c^
+entity.266=C.
+entity.267=c.
+entity.268=C(
+entity.269=c(
+entity.270=D(
+entity.271=d(
+entity.274=E-
+entity.275=e-
+entity.276=E(
+entity.277=e(
+entity.278=E.
+entity.279=e.
+entity.280=E;
+entity.281=e;
+entity.282=E(
+entity.283=e(
+entity.284=G^
+entity.285=g^
+entity.286=G(
+entity.287=g(
+entity.288=G.
+entity.289=g.
+entity.290=G,
+entity.291=g,
+entity.292=H^
+entity.293=h^
+entity.296=I~
+entity.297=i~
+entity.298=I-
+entity.299=i-
+entity.300=I(
+entity.301=i(
+entity.302=I;
+entity.303=i;
+entity.304=I.
+entity.306=IJ
+entity.307=ij
+entity.308=J^
+entity.309=j^
+entity.310=K,
+entity.311=k,
+entity.313=L'
+entity.314=l'
+entity.315=L,
+entity.316=l,
+entity.317=L(
+entity.318=l(
+entity.319=L.
+entity.320=l.
+entity.323=N'
+entity.324=n'
+entity.325=N,
+entity.326=n,
+entity.327=N(
+entity.328=n(
+entity.329='n
+entity.332=O-
+entity.333=o-
+entity.334=O(
+entity.335=o(
+entity.336=O"
+entity.337=o"
+entity.340=R'
+entity.341=r'
+entity.342=R,
+entity.343=r,
+entity.344=R(
+entity.345=r(
+entity.346=S'
+entity.347=s'
+entity.348=S^
+entity.349=s^
+entity.350=S,
+entity.351=s,
+entity.352=S(
+entity.353=s(
+entity.354=T,
+entity.355=t,
+entity.356=T(
+entity.357=t(
+entity.360=U~
+entity.361=u~
+entity.362=U-
+entity.363=u-
+entity.364=U(
+entity.365=u(
+entity.366=U*
+entity.367=u*
+entity.368=U"
+entity.369=u"
+entity.370=U;
+entity.371=u;
+entity.372=W^
+entity.373=w^
+entity.374=Y^
+entity.375=y^
+entity.376=Y"
+entity.377=Z'
+entity.378=z'
+entity.379=Z.
+entity.380=z.
+entity.381=Z(
+entity.382=z(
+entity.383=s
+entity.416=O+
+entity.417=o+
+entity.431=U+
+entity.432=u+
+entity.452=DZ(
+entity.453=Dz(
+entity.454=dz(
+entity.455=LJ
+entity.456=Lj
+entity.457=lj
+entity.458=NJ
+entity.459=Nj
+entity.460=nj
+entity.461=A(
+entity.462=a(
+entity.463=I(
+entity.464=i(
+entity.465=O(
+entity.466=o(
+entity.467=U(
+entity.468=u(
+entity.469=U"-
+entity.470=u"-
+entity.471=U"'
+entity.472=u"'
+entity.473=U"(
+entity.474=u"(
+entity.475=U"`
+entity.476=u"`
+entity.478=A"-
+entity.479=a"-
+entity.480=A.-
+entity.481=a.-
+entity.482=AE-
+entity.483=ae-
+entity.486=G(
+entity.487=g(
+entity.488=K(
+entity.489=k(
+entity.490=O;
+entity.491=o;
+entity.492=O;-
+entity.493=o;-
+entity.494=EZH(
+entity.495=ezh(
+entity.496=j(
+entity.497=DZ
+entity.498=Dz
+entity.499=dz
+entity.500=G'
+entity.501=g'
+entity.504=N`
+entity.505=n`
+entity.506=A*'
+entity.507=a*'
+entity.508=AE'
+entity.509=ae'
+entity.510=O/'
+entity.511=o/'
+entity.512=A``
+entity.513=a``
+entity.514=A(
+entity.515=a(
+entity.516=E``
+entity.517=e``
+entity.518=E(
+entity.519=e(
+entity.520=I``
+entity.521=i``
+entity.522=I(
+entity.523=i(
+entity.524=O``
+entity.525=o``
+entity.526=O(
+entity.527=o(
+entity.528=R``
+entity.529=r``
+entity.530=R(
+entity.531=r(
+entity.532=U``
+entity.533=u``
+entity.534=U(
+entity.535=u(
+entity.536=S,
+entity.537=s,
+entity.538=T,
+entity.539=t,
+entity.542=H(
+entity.543=h(
+entity.550=A.
+entity.551=a.
+entity.552=E,
+entity.553=e,
+entity.554=O"-
+entity.555=o"-
+entity.556=O~-
+entity.557=o~-
+entity.558=O.
+entity.559=o.
+entity.560=O.-
+entity.561=o.-
+entity.562=Y-
+entity.563=y-
+entity.688=^(h)
+entity.690=^(j)
+entity.691=^(r)
+entity.695=^(w)
+entity.696=^(y)
+entity.737=^(l)
+entity.738=^(s)
+entity.739=^(x)
+entity.1632=0
+entity.1633=1
+entity.1634=2
+entity.1635=3
+entity.1636=4
+entity.1637=5
+entity.1638=6
+entity.1639=7
+entity.1640=8
+entity.1641=9
+entity.1776=0
+entity.1777=1
+entity.1778=2
+entity.1779=3
+entity.1780=4
+entity.1781=5
+entity.1782=6
+entity.1783=7
+entity.1784=8
+entity.1785=9
+entity.1984=0
+entity.1985=1
+entity.1986=2
+entity.1987=3
+entity.1988=4
+entity.1989=5
+entity.1990=6
+entity.1991=7
+entity.1992=8
+entity.1993=9
+entity.2406=0
+entity.2407=1
+entity.2408=2
+entity.2409=3
+entity.2410=4
+entity.2411=5
+entity.2412=6
+entity.2413=7
+entity.2414=8
+entity.2415=9
+entity.2534=0
+entity.2535=1
+entity.2536=2
+entity.2537=3
+entity.2538=4
+entity.2539=5
+entity.2540=6
+entity.2541=7
+entity.2542=8
+entity.2543=9
+entity.2548=[1]
+entity.2549=[2]
+entity.2550=[3]
+entity.2551=[4]
+entity.2553=[16]
+entity.2662=0
+entity.2663=1
+entity.2664=2
+entity.2665=3
+entity.2666=4
+entity.2667=5
+entity.2668=6
+entity.2669=7
+entity.2670=8
+entity.2671=9
+entity.2790=0
+entity.2791=1
+entity.2792=2
+entity.2793=3
+entity.2794=4
+entity.2795=5
+entity.2796=6
+entity.2797=7
+entity.2798=8
+entity.2799=9
+entity.2918=0
+entity.2919=1
+entity.2920=2
+entity.2921=3
+entity.2922=4
+entity.2923=5
+entity.2924=6
+entity.2925=7
+entity.2926=8
+entity.2927=9
+entity.3046=0
+entity.3047=1
+entity.3048=2
+entity.3049=3
+entity.3050=4
+entity.3051=5
+entity.3052=6
+entity.3053=7
+entity.3054=8
+entity.3055=9
+entity.3056=[10]
+entity.3057=[100]
+entity.3058=[1000]
+entity.3174=0
+entity.3175=1
+entity.3176=2
+entity.3177=3
+entity.3178=4
+entity.3179=5
+entity.3180=6
+entity.3181=7
+entity.3182=8
+entity.3183=9
+entity.3192=[0]
+entity.3193=[1]
+entity.3194=[2]
+entity.3195=[3]
+entity.3196=[1]
+entity.3197=[2]
+entity.3198=[3]
+entity.3302=0
+entity.3303=1
+entity.3304=2
+entity.3305=3
+entity.3306=4
+entity.3307=5
+entity.3308=6
+entity.3309=7
+entity.3310=8
+entity.3311=9
+entity.3430=0
+entity.3431=1
+entity.3432=2
+entity.3433=3
+entity.3434=4
+entity.3435=5
+entity.3436=6
+entity.3437=7
+entity.3438=8
+entity.3439=9
+entity.3440=[10]
+entity.3441=[100]
+entity.3442=[1000]
+entity.3443=[1/4]
+entity.3444=[1/2]
+entity.3445=[3/4]
+entity.3664=0
+entity.3665=1
+entity.3666=2
+entity.3667=3
+entity.3668=4
+entity.3669=5
+entity.3670=6
+entity.3671=7
+entity.3672=8
+entity.3673=9
+entity.3792=0
+entity.3793=1
+entity.3794=2
+entity.3795=3
+entity.3796=4
+entity.3797=5
+entity.3798=6
+entity.3799=7
+entity.3800=8
+entity.3801=9
+entity.3872=0
+entity.3873=1
+entity.3874=2
+entity.3875=3
+entity.3876=4
+entity.3877=5
+entity.3878=6
+entity.3879=7
+entity.3880=8
+entity.3881=9
+entity.3882=[1/2]
+entity.3883=[3/2]
+entity.3884=[5/2]
+entity.3885=[7/2]
+entity.3886=[9/2]
+entity.3887=[11/2]
+entity.3888=[13/2]
+entity.3889=[15/2]
+entity.3890=[17/2]
+entity.3891=[-1/2]
+entity.4160=0
+entity.4161=1
+entity.4162=2
+entity.4163=3
+entity.4164=4
+entity.4165=5
+entity.4166=6
+entity.4167=7
+entity.4168=8
+entity.4169=9
+entity.4240=0
+entity.4241=1
+entity.4242=2
+entity.4243=3
+entity.4244=4
+entity.4245=5
+entity.4246=6
+entity.4247=7
+entity.4248=8
+entity.4249=9
+entity.4969=[1]
+entity.4970=[2]
+entity.4971=[3]
+entity.4972=[4]
+entity.4973=[5]
+entity.4974=[6]
+entity.4975=[7]
+entity.4976=[8]
+entity.4977=[9]
+entity.4978=[10]
+entity.4979=[20]
+entity.4980=[30]
+entity.4981=[40]
+entity.4982=[50]
+entity.4983=[60]
+entity.4984=[70]
+entity.4985=[80]
+entity.4986=[90]
+entity.4987=[100]
+entity.4988=[10000]
+entity.5870=[17]
+entity.5871=[18]
+entity.5872=[19]
+entity.6112=0
+entity.6113=1
+entity.6114=2
+entity.6115=3
+entity.6116=4
+entity.6117=5
+entity.6118=6
+entity.6119=7
+entity.6120=8
+entity.6121=9
+entity.6128=[0]
+entity.6129=[1]
+entity.6130=[2]
+entity.6131=[3]
+entity.6132=[4]
+entity.6133=[5]
+entity.6134=[6]
+entity.6135=[7]
+entity.6136=[8]
+entity.6137=[9]
+entity.6160=0
+entity.6161=1
+entity.6162=2
+entity.6163=3
+entity.6164=4
+entity.6165=5
+entity.6166=6
+entity.6167=7
+entity.6168=8
+entity.6169=9
+entity.6470=0
+entity.6471=1
+entity.6472=2
+entity.6473=3
+entity.6474=4
+entity.6475=5
+entity.6476=6
+entity.6477=7
+entity.6478=8
+entity.6479=9
+entity.6608=0
+entity.6609=1
+entity.6610=2
+entity.6611=3
+entity.6612=4
+entity.6613=5
+entity.6614=6
+entity.6615=7
+entity.6616=8
+entity.6617=9
+entity.6992=0
+entity.6993=1
+entity.6994=2
+entity.6995=3
+entity.6996=4
+entity.6997=5
+entity.6998=6
+entity.6999=7
+entity.7000=8
+entity.7001=9
+entity.7088=0
+entity.7089=1
+entity.7090=2
+entity.7091=3
+entity.7092=4
+entity.7093=5
+entity.7094=6
+entity.7095=7
+entity.7096=8
+entity.7097=9
+entity.7232=0
+entity.7233=1
+entity.7234=2
+entity.7235=3
+entity.7236=4
+entity.7237=5
+entity.7238=6
+entity.7239=7
+entity.7240=8
+entity.7241=9
+entity.7248=0
+entity.7249=1
+entity.7250=2
+entity.7251=3
+entity.7252=4
+entity.7253=5
+entity.7254=6
+entity.7255=7
+entity.7256=8
+entity.7257=9
+entity.7468=^(A)
+entity.7470=^(B)
+entity.7472=^(D)
+entity.7473=^(E)
+entity.7475=^(G)
+entity.7476=^(H)
+entity.7477=^(I)
+entity.7478=^(J)
+entity.7479=^(K)
+entity.7480=^(L)
+entity.7481=^(M)
+entity.7482=^(N)
+entity.7484=^(O)
+entity.7486=^(P)
+entity.7487=^(R)
+entity.7488=^(T)
+entity.7489=^(U)
+entity.7490=^(W)
+entity.7491=^(a)
+entity.7495=^(b)
+entity.7496=^(d)
+entity.7497=^(e)
+entity.7501=^(g)
+entity.7503=^(k)
+entity.7504=^(m)
+entity.7506=^(o)
+entity.7510=^(p)
+entity.7511=^(t)
+entity.7512=^(u)
+entity.7515=^(v)
+entity.7522=v(i)
+entity.7523=v(r)
+entity.7524=v(u)
+entity.7525=v(v)
+entity.7580=^(c)
+entity.7584=^(f)
+entity.7611=^(z)
+entity.7680=A*
+entity.7681=a*
+entity.7682=B.
+entity.7683=b.
+entity.7684=B.
+entity.7685=b.
+entity.7686=B_
+entity.7687=b_
+entity.7688=C,'
+entity.7689=c,'
+entity.7690=D.
+entity.7691=d.
+entity.7692=D.
+entity.7693=d.
+entity.7694=D_
+entity.7695=d_
+entity.7696=D,
+entity.7697=d,
+entity.7698=D^
+entity.7699=d^
+entity.7700=E-`
+entity.7701=e-`
+entity.7702=E-'
+entity.7703=e-'
+entity.7704=E^
+entity.7705=e^
+entity.7706=E~
+entity.7707=e~
+entity.7708=E,(
+entity.7709=e,(
+entity.7710=F.
+entity.7711=f.
+entity.7712=G-
+entity.7713=g-
+entity.7714=H.
+entity.7715=h.
+entity.7716=H.
+entity.7717=h.
+entity.7718=H"
+entity.7719=h"
+entity.7720=H,
+entity.7721=h,
+entity.7722=H(
+entity.7723=h(
+entity.7724=I~
+entity.7725=i~
+entity.7726=I"'
+entity.7727=i"'
+entity.7728=K'
+entity.7729=k'
+entity.7730=K.
+entity.7731=k.
+entity.7732=K_
+entity.7733=k_
+entity.7734=L.
+entity.7735=l.
+entity.7736=L.-
+entity.7737=l.-
+entity.7738=L_
+entity.7739=l_
+entity.7740=L^
+entity.7741=l^
+entity.7742=M'
+entity.7743=m'
+entity.7744=M.
+entity.7745=m.
+entity.7746=M.
+entity.7747=m.
+entity.7748=N.
+entity.7749=n.
+entity.7750=N.
+entity.7751=n.
+entity.7752=N_
+entity.7753=n_
+entity.7754=N^
+entity.7755=n^
+entity.7756=O~'
+entity.7757=o~'
+entity.7758=O~"
+entity.7759=o~"
+entity.7760=O-`
+entity.7761=o-`
+entity.7762=O-'
+entity.7763=o-'
+entity.7764=P'
+entity.7765=p'
+entity.7766=P.
+entity.7767=p.
+entity.7768=R.
+entity.7769=r.
+entity.7770=R.
+entity.7771=r.
+entity.7772=R.-
+entity.7773=r.-
+entity.7774=R_
+entity.7775=r_
+entity.7776=S.
+entity.7777=s.
+entity.7778=S.
+entity.7779=s.
+entity.7780=S'.
+entity.7781=s'.
+entity.7782=S(.
+entity.7783=s(.
+entity.7784=S..
+entity.7785=s..
+entity.7786=T.
+entity.7787=t.
+entity.7788=T.
+entity.7789=t.
+entity.7790=T_
+entity.7791=t_
+entity.7792=T^
+entity.7793=t^
+entity.7794=U"
+entity.7795=u"
+entity.7796=U~
+entity.7797=u~
+entity.7798=U^
+entity.7799=u^
+entity.7800=U~'
+entity.7801=u~'
+entity.7802=U-"
+entity.7803=u-"
+entity.7804=V~
+entity.7805=v~
+entity.7806=V.
+entity.7807=v.
+entity.7808=W`
+entity.7809=w`
+entity.7810=W'
+entity.7811=w'
+entity.7812=W"
+entity.7813=w"
+entity.7814=W.
+entity.7815=w.
+entity.7816=W.
+entity.7817=w.
+entity.7818=X.
+entity.7819=x.
+entity.7820=X"
+entity.7821=x"
+entity.7822=Y.
+entity.7823=y.
+entity.7824=Z^
+entity.7825=z^
+entity.7826=Z.
+entity.7827=z.
+entity.7828=Z_
+entity.7829=z_
+entity.7830=h_
+entity.7831=t"
+entity.7832=w*
+entity.7833=y*
+entity.7834=a*
+entity.7840=A.
+entity.7841=a.
+entity.7842=A?
+entity.7843=a?
+entity.7844=A^'
+entity.7845=a^'
+entity.7846=A^`
+entity.7847=a^`
+entity.7848=A^?
+entity.7849=a^?
+entity.7850=A^~
+entity.7851=a^~
+entity.7852=A^.
+entity.7853=a^.
+entity.7854=A('
+entity.7855=a('
+entity.7856=A(`
+entity.7857=a(`
+entity.7858=A(?
+entity.7859=a(?
+entity.7860=A(~
+entity.7861=a(~
+entity.7862=A(.
+entity.7863=a(.
+entity.7864=E.
+entity.7865=e.
+entity.7866=E?
+entity.7867=e?
+entity.7868=E~
+entity.7869=e~
+entity.7870=E^'
+entity.7871=e^'
+entity.7872=E^`
+entity.7873=e^`
+entity.7874=E^?
+entity.7875=e^?
+entity.7876=E^~
+entity.7877=e^~
+entity.7878=E^.
+entity.7879=e^.
+entity.7880=I?
+entity.7881=i?
+entity.7882=I.
+entity.7883=i.
+entity.7884=O.
+entity.7885=o.
+entity.7886=O?
+entity.7887=o?
+entity.7888=O^'
+entity.7889=o^'
+entity.7890=O^`
+entity.7891=o^`
+entity.7892=O^?
+entity.7893=o^?
+entity.7894=O^~
+entity.7895=o^~
+entity.7896=O^.
+entity.7897=o^.
+entity.7898=O+'
+entity.7899=o+'
+entity.7900=O+`
+entity.7901=o+`
+entity.7902=O+?
+entity.7903=o+?
+entity.7904=O+~
+entity.7905=o+~
+entity.7906=O+.
+entity.7907=o+.
+entity.7908=U.
+entity.7909=u.
+entity.7910=U?
+entity.7911=u?
+entity.7912=U+'
+entity.7913=u+'
+entity.7914=U+`
+entity.7915=u+`
+entity.7916=U+?
+entity.7917=u+?
+entity.7918=U+~
+entity.7919=u+~
+entity.7920=U+.
+entity.7921=u+.
+entity.7922=Y`
+entity.7923=y`
+entity.7924=Y.
+entity.7925=y.
+entity.7926=Y?
+entity.7927=y?
+entity.7928=Y~
+entity.7929=y~
+entity.8194=\u0020
+entity.8195=\u0020
+entity.8196=\u0020
+entity.8197=\u0020
+entity.8198=\u0020
+entity.8199=\u0020
+entity.8200=\u0020
+entity.8201=\u0020
+entity.8202=\u0020
+entity.8228=.
+entity.8229=..
+entity.8230=...
+entity.8239=\u0020
+entity.8252=!!
+entity.8263=??
+entity.8264=?!
+entity.8265=!?
+entity.8287=\u0020
+entity.8304=^(0)
+entity.8305=^(i)
+entity.8308=^(4)
+entity.8309=^(5)
+entity.8310=^(6)
+entity.8311=^(7)
+entity.8312=^(8)
+entity.8313=^(9)
+entity.8314=^(+)
+entity.8316=^(=)
+entity.8317=^(()
+entity.8318=^())
+entity.8319=^(n)
+entity.8320=v(0)
+entity.8321=v(1)
+entity.8322=v(2)
+entity.8323=v(3)
+entity.8324=v(4)
+entity.8325=v(5)
+entity.8326=v(6)
+entity.8327=v(7)
+entity.8328=v(8)
+entity.8329=v(9)
+entity.8330=v(+)
+entity.8332=v(=)
+entity.8333=v(()
+entity.8334=v())
+entity.8336=v(a)
+entity.8337=v(e)
+entity.8338=v(o)
+entity.8339=v(x)
+entity.8340=schwa
+entity.8360=Rs
+entity.8448=a/c
+entity.8449=a/s
+entity.8450=C
+entity.8453=c/o
+entity.8454=c/u
+entity.8458=g
+entity.8459=H
+entity.8460=H
+entity.8461=H
+entity.8462=h
+entity.8464=I
+entity.8465=I
+entity.8466=L
+entity.8467=l
+entity.8469=N
+entity.8470=No
+entity.8473=P
+entity.8474=Q
+entity.8475=R
+entity.8476=R
+entity.8477=R
+entity.8480=^(SM)
+entity.8481=TEL
+entity.8482=^(TM)
+entity.8484=Z
+entity.8488=Z
+entity.8492=B
+entity.8493=C
+entity.8495=e
+entity.8496=E
+entity.8497=F
+entity.8499=M
+entity.8500=o
+entity.8505=i
+entity.8507=FAX
+entity.8517=D
+entity.8518=d
+entity.8519=e
+entity.8520=i
+entity.8521=j
+entity.8531=1/3
+entity.8532=2/3
+entity.8533=1/5
+entity.8534=2/5
+entity.8535=3/5
+entity.8536=4/5
+entity.8537=1/6
+entity.8538=5/6
+entity.8539=1/8
+entity.8540=3/8
+entity.8541=5/8
+entity.8542=7/8
+entity.8543=1/
+entity.8544=I
+entity.8545=II
+entity.8546=III
+entity.8547=IV
+entity.8548=V
+entity.8549=VI
+entity.8550=VII
+entity.8551=VIII
+entity.8552=IX
+entity.8553=X
+entity.8554=XI
+entity.8555=XII
+entity.8556=L
+entity.8557=C
+entity.8558=D
+entity.8559=M
+entity.8560=i
+entity.8561=ii
+entity.8562=iii
+entity.8563=iv
+entity.8564=v
+entity.8565=vi
+entity.8566=vii
+entity.8567=viii
+entity.8568=ix
+entity.8569=x
+entity.8570=xi
+entity.8571=xii
+entity.8572=l
+entity.8573=c
+entity.8574=d
+entity.8575=m
+entity.8576=[1000]
+entity.8577=[5000]
+entity.8578=[10000]
+entity.8581=[6]
+entity.8582=[50]
+entity.8583=[50000]
+entity.8584=[100000]
+entity.9312=(1)
+entity.9313=(2)
+entity.9314=(3)
+entity.9315=(4)
+entity.9316=(5)
+entity.9317=(6)
+entity.9318=(7)
+entity.9319=(8)
+entity.9320=(9)
+entity.9321=(10)
+entity.9322=(11)
+entity.9323=(12)
+entity.9324=(13)
+entity.9325=(14)
+entity.9326=(15)
+entity.9327=(16)
+entity.9328=(17)
+entity.9329=(18)
+entity.9330=(19)
+entity.9331=(20)
+entity.9332=(1)
+entity.9333=(2)
+entity.9334=(3)
+entity.9335=(4)
+entity.9336=(5)
+entity.9337=(6)
+entity.9338=(7)
+entity.9339=(8)
+entity.9340=(9)
+entity.9341=(10)
+entity.9342=(11)
+entity.9343=(12)
+entity.9344=(13)
+entity.9345=(14)
+entity.9346=(15)
+entity.9347=(16)
+entity.9348=(17)
+entity.9349=(18)
+entity.9350=(19)
+entity.9351=(20)
+entity.9352=1.
+entity.9353=2.
+entity.9354=3.
+entity.9355=4.
+entity.9356=5.
+entity.9357=6.
+entity.9358=7.
+entity.9359=8.
+entity.9360=9.
+entity.9361=10.
+entity.9362=11.
+entity.9363=12.
+entity.9364=13.
+entity.9365=14.
+entity.9366=15.
+entity.9367=16.
+entity.9368=17.
+entity.9369=18.
+entity.9370=19.
+entity.9371=20.
+entity.9372=(a)
+entity.9373=(b)
+entity.9374=(c)
+entity.9375=(d)
+entity.9376=(e)
+entity.9377=(f)
+entity.9378=(g)
+entity.9379=(h)
+entity.9380=(i)
+entity.9381=(j)
+entity.9382=(k)
+entity.9383=(l)
+entity.9384=(m)
+entity.9385=(n)
+entity.9386=(o)
+entity.9387=(p)
+entity.9388=(q)
+entity.9389=(r)
+entity.9390=(s)
+entity.9391=(t)
+entity.9392=(u)
+entity.9393=(v)
+entity.9394=(w)
+entity.9395=(x)
+entity.9396=(y)
+entity.9397=(z)
+entity.9398=(A)
+entity.9399=(B)
+entity.9400=(C)
+entity.9401=(D)
+entity.9402=(E)
+entity.9403=(F)
+entity.9404=(G)
+entity.9405=(H)
+entity.9406=(I)
+entity.9407=(J)
+entity.9408=(K)
+entity.9409=(L)
+entity.9410=(M)
+entity.9411=(N)
+entity.9412=(O)
+entity.9413=(P)
+entity.9414=(Q)
+entity.9415=(R)
+entity.9416=(S)
+entity.9417=(T)
+entity.9418=(U)
+entity.9419=(V)
+entity.9420=(W)
+entity.9421=(X)
+entity.9422=(Y)
+entity.9423=(Z)
+entity.9424=(a)
+entity.9425=(b)
+entity.9426=(c)
+entity.9427=(d)
+entity.9428=(e)
+entity.9429=(f)
+entity.9430=(g)
+entity.9431=(h)
+entity.9432=(i)
+entity.9433=(j)
+entity.9434=(k)
+entity.9435=(l)
+entity.9436=(m)
+entity.9437=(n)
+entity.9438=(o)
+entity.9439=(p)
+entity.9440=(q)
+entity.9441=(r)
+entity.9442=(s)
+entity.9443=(t)
+entity.9444=(u)
+entity.9445=(v)
+entity.9446=(w)
+entity.9447=(x)
+entity.9448=(y)
+entity.9449=(z)
+entity.9450=(0)
+entity.9451=(11)
+entity.9452=(12)
+entity.9453=(13)
+entity.9454=(14)
+entity.9455=(15)
+entity.9456=(16)
+entity.9457=(17)
+entity.9458=(18)
+entity.9459=(19)
+entity.9460=(20)
+entity.9461=(1)
+entity.9462=(2)
+entity.9463=(3)
+entity.9464=(4)
+entity.9465=(5)
+entity.9466=(6)
+entity.9467=(7)
+entity.9468=(8)
+entity.9469=(9)
+entity.9470=(10)
+entity.9471=(0)
+entity.10102=(1)
+entity.10103=(2)
+entity.10104=(3)
+entity.10105=(4)
+entity.10106=(5)
+entity.10107=(6)
+entity.10108=(7)
+entity.10109=(8)
+entity.10110=(9)
+entity.10111=(10)
+entity.10112=(1)
+entity.10113=(2)
+entity.10114=(3)
+entity.10115=(4)
+entity.10116=(5)
+entity.10117=(6)
+entity.10118=(7)
+entity.10119=(8)
+entity.10120=(9)
+entity.10121=(10)
+entity.10122=(1)
+entity.10123=(2)
+entity.10124=(3)
+entity.10125=(4)
+entity.10126=(5)
+entity.10127=(6)
+entity.10128=(7)
+entity.10129=(8)
+entity.10130=(9)
+entity.10131=(10)
+entity.10868=::=
+entity.10869===
+entity.10870====
+entity.11388=v(j)
+entity.11389=^(V)
+entity.11517=[1/2]
+entity.12288=\u0020
+entity.12295=[0]
+entity.12321=[1]
+entity.12322=[2]
+entity.12323=[3]
+entity.12324=[4]
+entity.12325=[5]
+entity.12326=[6]
+entity.12327=[7]
+entity.12328=[8]
+entity.12329=[9]
+entity.12881=(21)
+entity.12882=(22)
+entity.12883=(23)
+entity.12884=(24)
+entity.12885=(25)
+entity.12886=(26)
+entity.12887=(27)
+entity.12888=(28)
+entity.12889=(29)
+entity.12890=(30)
+entity.12891=(31)
+entity.12892=(32)
+entity.12893=(33)
+entity.12894=(34)
+entity.12895=(35)
+entity.12977=(36)
+entity.12978=(37)
+entity.12979=(38)
+entity.12980=(39)
+entity.12981=(40)
+entity.12982=(41)
+entity.12983=(42)
+entity.12984=(43)
+entity.12985=(44)
+entity.12986=(45)
+entity.12987=(46)
+entity.12988=(47)
+entity.12989=(48)
+entity.12990=(49)
+entity.12991=(50)
+entity.42528=0
+entity.42529=1
+entity.42530=2
+entity.42531=3
+entity.42532=4
+entity.42533=5
+entity.42534=6
+entity.42535=7
+entity.42536=8
+entity.42537=9
+entity.43216=0
+entity.43217=1
+entity.43218=2
+entity.43219=3
+entity.43220=4
+entity.43221=5
+entity.43222=6
+entity.43223=7
+entity.43224=8
+entity.43225=9
+entity.43264=0
+entity.43265=1
+entity.43266=2
+entity.43267=3
+entity.43268=4
+entity.43269=5
+entity.43270=6
+entity.43271=7
+entity.43272=8
+entity.43273=9
+entity.43600=0
+entity.43601=1
+entity.43602=2
+entity.43603=3
+entity.43604=4
+entity.43605=5
+entity.43606=6
+entity.43607=7
+entity.43608=8
+entity.43609=9
+entity.64256=ff
+entity.64257=fi
+entity.64258=fl
+entity.64259=ffi
+entity.64260=ffl
+entity.64262=st
+entity.64297=+
+entity.65101=_
+entity.65102=_
+entity.65103=_
+entity.65104=,
+entity.65106=.
+entity.65108=;
+entity.65109=:
+entity.65110=?
+entity.65111=!
+entity.65113=(
+entity.65114=)
+entity.65115={
+entity.65116=}
+entity.65119=#
+entity.65120=&
+entity.65121=*
+entity.65122=+
+entity.65123=-
+entity.65124=<
+entity.65125=>
+entity.65126==
+entity.65128=\u005C
+entity.65129=$
+entity.65130=%
+entity.65131=@
+entity.65281=!
+entity.65282="
+entity.65283=#
+entity.65284=$
+entity.65285=%
+entity.65286=&
+entity.65287='
+entity.65288=(
+entity.65289=)
+entity.65290=*
+entity.65291=+
+entity.65292=,
+entity.65293=-
+entity.65294=.
+entity.65295=/
+entity.65296=0
+entity.65297=1
+entity.65298=2
+entity.65299=3
+entity.65300=4
+entity.65301=5
+entity.65302=6
+entity.65303=7
+entity.65304=8
+entity.65305=9
+entity.65306=:
+entity.65307=;
+entity.65308=<
+entity.65309==
+entity.65310=>
+entity.65311=?
+entity.65312=@
+entity.65313=A
+entity.65314=B
+entity.65315=C
+entity.65316=D
+entity.65317=E
+entity.65318=F
+entity.65319=G
+entity.65320=H
+entity.65321=I
+entity.65322=J
+entity.65323=K
+entity.65324=L
+entity.65325=M
+entity.65326=N
+entity.65327=O
+entity.65328=P
+entity.65329=Q
+entity.65330=R
+entity.65331=S
+entity.65332=T
+entity.65333=U
+entity.65334=V
+entity.65335=W
+entity.65336=X
+entity.65337=Y
+entity.65338=Z
+entity.65339=[
+entity.65340=\u005C
+entity.65341=]
+entity.65342=^
+entity.65343=_
+entity.65344=`
+entity.65345=a
+entity.65346=b
+entity.65347=c
+entity.65348=d
+entity.65349=e
+entity.65350=f
+entity.65351=g
+entity.65352=h
+entity.65353=i
+entity.65354=j
+entity.65355=k
+entity.65356=l
+entity.65357=m
+entity.65358=n
+entity.65359=o
+entity.65360=p
+entity.65361=q
+entity.65362=r
+entity.65363=s
+entity.65364=t
+entity.65365=u
+entity.65366=v
+entity.65367=w
+entity.65368=x
+entity.65369=y
+entity.65370=z
+entity.65371={
+entity.65372=|
+entity.65373=}
+entity.65374=~
+entity.65799=[1]
+entity.65800=[2]
+entity.65801=[3]
+entity.65802=[4]
+entity.65803=[5]
+entity.65804=[6]
+entity.65805=[7]
+entity.65806=[8]
+entity.65807=[9]
+entity.65808=[10]
+entity.65809=[20]
+entity.65810=[30]
+entity.65811=[40]
+entity.65812=[50]
+entity.65813=[60]
+entity.65814=[70]
+entity.65815=[80]
+entity.65816=[90]
+entity.65817=[100]
+entity.65818=[200]
+entity.65819=[300]
+entity.65820=[400]
+entity.65821=[500]
+entity.65822=[600]
+entity.65823=[700]
+entity.65824=[800]
+entity.65825=[900]
+entity.65826=[1000]
+entity.65827=[2000]
+entity.65828=[3000]
+entity.65829=[4000]
+entity.65830=[5000]
+entity.65831=[6000]
+entity.65832=[7000]
+entity.65833=[8000]
+entity.65834=[9000]
+entity.65835=[10000]
+entity.65836=[20000]
+entity.65837=[30000]
+entity.65838=[40000]
+entity.65839=[50000]
+entity.65840=[60000]
+entity.65841=[70000]
+entity.65842=[80000]
+entity.65843=[90000]
+entity.65856=[1/4]
+entity.65857=[1/2]
+entity.65858=[1]
+entity.65859=[5]
+entity.65860=[50]
+entity.65861=[500]
+entity.65862=[5000]
+entity.65863=[50000]
+entity.65864=[5]
+entity.65865=[10]
+entity.65866=[50]
+entity.65867=[100]
+entity.65868=[500]
+entity.65869=[1000]
+entity.65870=[5000]
+entity.65871=[5]
+entity.65872=[10]
+entity.65873=[50]
+entity.65874=[100]
+entity.65875=[500]
+entity.65876=[1000]
+entity.65877=[10000]
+entity.65878=[50000]
+entity.65879=[10]
+entity.65880=[1]
+entity.65881=[1]
+entity.65882=[1]
+entity.65883=[2]
+entity.65884=[2]
+entity.65885=[2]
+entity.65886=[2]
+entity.65887=[5]
+entity.65888=[10]
+entity.65889=[10]
+entity.65890=[10]
+entity.65891=[10]
+entity.65892=[10]
+entity.65893=[30]
+entity.65894=[50]
+entity.65895=[50]
+entity.65896=[50]
+entity.65897=[50]
+entity.65898=[100]
+entity.65899=[300]
+entity.65900=[500]
+entity.65901=[500]
+entity.65902=[500]
+entity.65903=[500]
+entity.65904=[500]
+entity.65905=[1000]
+entity.65906=[5000]
+entity.65907=[5]
+entity.65908=[50]
+entity.65909=[1/2]
+entity.65910=[1/2]
+entity.65911=[2/3]
+entity.65912=[3/4]
+entity.65930=[0]
+entity.66336=[1]
+entity.66337=[5]
+entity.66338=[10]
+entity.66339=[50]
+entity.66369=[90]
+entity.66378=[900]
+entity.66513=[1]
+entity.66514=[2]
+entity.66515=[10]
+entity.66516=[20]
+entity.66517=[100]
+entity.66720=0
+entity.66721=1
+entity.66722=2
+entity.66723=3
+entity.66724=4
+entity.66725=5
+entity.66726=6
+entity.66727=7
+entity.66728=8
+entity.66729=9
+entity.67862=[1]
+entity.67863=[10]
+entity.67864=[20]
+entity.67865=[100]
+entity.68160=[1]
+entity.68161=[2]
+entity.68162=[3]
+entity.68163=[4]
+entity.68164=[10]
+entity.68165=[20]
+entity.68166=[100]
+entity.68167=[1000]
+entity.74752=[2]
+entity.74753=[3]
+entity.74754=[4]
+entity.74755=[5]
+entity.74756=[6]
+entity.74757=[7]
+entity.74758=[8]
+entity.74759=[9]
+entity.74760=[3]
+entity.74761=[4]
+entity.74762=[5]
+entity.74763=[6]
+entity.74764=[7]
+entity.74765=[8]
+entity.74766=[9]
+entity.74767=[4]
+entity.74768=[5]
+entity.74769=[6]
+entity.74770=[7]
+entity.74771=[8]
+entity.74772=[9]
+entity.74773=[1]
+entity.74774=[2]
+entity.74775=[3]
+entity.74776=[4]
+entity.74777=[5]
+entity.74778=[6]
+entity.74779=[7]
+entity.74780=[8]
+entity.74781=[9]
+entity.74782=[1]
+entity.74783=[2]
+entity.74784=[3]
+entity.74785=[4]
+entity.74786=[5]
+entity.74787=[2]
+entity.74788=[3]
+entity.74789=[3]
+entity.74790=[4]
+entity.74791=[5]
+entity.74792=[6]
+entity.74793=[7]
+entity.74794=[8]
+entity.74795=[9]
+entity.74796=[1]
+entity.74797=[2]
+entity.74798=[3]
+entity.74799=[3]
+entity.74800=[4]
+entity.74801=[5]
+entity.74804=[1]
+entity.74805=[2]
+entity.74806=[3]
+entity.74807=[3]
+entity.74808=[4]
+entity.74809=[5]
+entity.74810=[3]
+entity.74811=[3]
+entity.74812=[4]
+entity.74813=[4]
+entity.74814=[4]
+entity.74815=[4]
+entity.74816=[6]
+entity.74817=[7]
+entity.74818=[7]
+entity.74819=[7]
+entity.74820=[8]
+entity.74821=[8]
+entity.74822=[9]
+entity.74823=[9]
+entity.74824=[9]
+entity.74825=[9]
+entity.74826=[2]
+entity.74827=[3]
+entity.74828=[4]
+entity.74829=[5]
+entity.74830=[6]
+entity.74831=[1]
+entity.74832=[2]
+entity.74833=[3]
+entity.74834=[4]
+entity.74835=[4]
+entity.74836=[5]
+entity.74837=[5]
+entity.74840=[1]
+entity.74841=[2]
+entity.74842=[1/3]
+entity.74843=[2/3]
+entity.74844=[5/6]
+entity.74845=[1/3]
+entity.74846=[2/3]
+entity.74847=[1/8]
+entity.74848=[1/4]
+entity.74849=[1/6]
+entity.74850=[1/4]
+entity.119648=[1]
+entity.119649=[2]
+entity.119650=[3]
+entity.119651=[4]
+entity.119652=[5]
+entity.119653=[6]
+entity.119654=[7]
+entity.119655=[8]
+entity.119656=[9]
+entity.119657=[10]
+entity.119658=[20]
+entity.119659=[30]
+entity.119660=[40]
+entity.119661=[50]
+entity.119662=[60]
+entity.119663=[70]
+entity.119664=[80]
+entity.119665=[90]
+entity.119808=A
+entity.119809=B
+entity.119810=C
+entity.119811=D
+entity.119812=E
+entity.119813=F
+entity.119814=G
+entity.119815=H
+entity.119816=I
+entity.119817=J
+entity.119818=K
+entity.119819=L
+entity.119820=M
+entity.119821=N
+entity.119822=O
+entity.119823=P
+entity.119824=Q
+entity.119825=R
+entity.119826=S
+entity.119827=T
+entity.119828=U
+entity.119829=V
+entity.119830=W
+entity.119831=X
+entity.119832=Y
+entity.119833=Z
+entity.119834=a
+entity.119835=b
+entity.119836=c
+entity.119837=d
+entity.119838=e
+entity.119839=f
+entity.119840=g
+entity.119841=h
+entity.119842=i
+entity.119843=j
+entity.119844=k
+entity.119845=l
+entity.119846=m
+entity.119847=n
+entity.119848=o
+entity.119849=p
+entity.119850=q
+entity.119851=r
+entity.119852=s
+entity.119853=t
+entity.119854=u
+entity.119855=v
+entity.119856=w
+entity.119857=x
+entity.119858=y
+entity.119859=z
+entity.119860=A
+entity.119861=B
+entity.119862=C
+entity.119863=D
+entity.119864=E
+entity.119865=F
+entity.119866=G
+entity.119867=H
+entity.119868=I
+entity.119869=J
+entity.119870=K
+entity.119871=L
+entity.119872=M
+entity.119873=N
+entity.119874=O
+entity.119875=P
+entity.119876=Q
+entity.119877=R
+entity.119878=S
+entity.119879=T
+entity.119880=U
+entity.119881=V
+entity.119882=W
+entity.119883=X
+entity.119884=Y
+entity.119885=Z
+entity.119886=a
+entity.119887=b
+entity.119888=c
+entity.119889=d
+entity.119890=e
+entity.119891=f
+entity.119892=g
+entity.119894=i
+entity.119895=j
+entity.119896=k
+entity.119897=l
+entity.119898=m
+entity.119899=n
+entity.119900=o
+entity.119901=p
+entity.119902=q
+entity.119903=r
+entity.119904=s
+entity.119905=t
+entity.119906=u
+entity.119907=v
+entity.119908=w
+entity.119909=x
+entity.119910=y
+entity.119911=z
+entity.119912=A
+entity.119913=B
+entity.119914=C
+entity.119915=D
+entity.119916=E
+entity.119917=F
+entity.119918=G
+entity.119919=H
+entity.119920=I
+entity.119921=J
+entity.119922=K
+entity.119923=L
+entity.119924=M
+entity.119925=N
+entity.119926=O
+entity.119927=P
+entity.119928=Q
+entity.119929=R
+entity.119930=S
+entity.119931=T
+entity.119932=U
+entity.119933=V
+entity.119934=W
+entity.119935=X
+entity.119936=Y
+entity.119937=Z
+entity.119938=a
+entity.119939=b
+entity.119940=c
+entity.119941=d
+entity.119942=e
+entity.119943=f
+entity.119944=g
+entity.119945=h
+entity.119946=i
+entity.119947=j
+entity.119948=k
+entity.119949=l
+entity.119950=m
+entity.119951=n
+entity.119952=o
+entity.119953=p
+entity.119954=q
+entity.119955=r
+entity.119956=s
+entity.119957=t
+entity.119958=u
+entity.119959=v
+entity.119960=w
+entity.119961=x
+entity.119962=y
+entity.119963=z
+entity.119964=A
+entity.119966=C
+entity.119967=D
+entity.119970=G
+entity.119973=J
+entity.119974=K
+entity.119977=N
+entity.119978=O
+entity.119979=P
+entity.119980=Q
+entity.119982=S
+entity.119983=T
+entity.119984=U
+entity.119985=V
+entity.119986=W
+entity.119987=X
+entity.119988=Y
+entity.119989=Z
+entity.119990=a
+entity.119991=b
+entity.119992=c
+entity.119993=d
+entity.119995=f
+entity.119997=h
+entity.119998=i
+entity.119999=j
+entity.120000=k
+entity.120001=l
+entity.120002=m
+entity.120003=n
+entity.120005=p
+entity.120006=q
+entity.120007=r
+entity.120008=s
+entity.120009=t
+entity.120010=u
+entity.120011=v
+entity.120012=w
+entity.120013=x
+entity.120014=y
+entity.120015=z
+entity.120016=A
+entity.120017=B
+entity.120018=C
+entity.120019=D
+entity.120020=E
+entity.120021=F
+entity.120022=G
+entity.120023=H
+entity.120024=I
+entity.120025=J
+entity.120026=K
+entity.120027=L
+entity.120028=M
+entity.120029=N
+entity.120030=O
+entity.120031=P
+entity.120032=Q
+entity.120033=R
+entity.120034=S
+entity.120035=T
+entity.120036=U
+entity.120037=V
+entity.120038=W
+entity.120039=X
+entity.120040=Y
+entity.120041=Z
+entity.120042=a
+entity.120043=b
+entity.120044=c
+entity.120045=d
+entity.120046=e
+entity.120047=f
+entity.120048=g
+entity.120049=h
+entity.120050=i
+entity.120051=j
+entity.120052=k
+entity.120053=l
+entity.120054=m
+entity.120055=n
+entity.120056=o
+entity.120057=p
+entity.120058=q
+entity.120059=r
+entity.120060=s
+entity.120061=t
+entity.120062=u
+entity.120063=v
+entity.120064=w
+entity.120065=x
+entity.120066=y
+entity.120067=z
+entity.120068=A
+entity.120069=B
+entity.120071=D
+entity.120072=E
+entity.120073=F
+entity.120074=G
+entity.120077=J
+entity.120078=K
+entity.120079=L
+entity.120080=M
+entity.120081=N
+entity.120082=O
+entity.120083=P
+entity.120084=Q
+entity.120086=S
+entity.120087=T
+entity.120088=U
+entity.120089=V
+entity.120090=W
+entity.120091=X
+entity.120092=Y
+entity.120094=a
+entity.120095=b
+entity.120096=c
+entity.120097=d
+entity.120098=e
+entity.120099=f
+entity.120100=g
+entity.120101=h
+entity.120102=i
+entity.120103=j
+entity.120104=k
+entity.120105=l
+entity.120106=m
+entity.120107=n
+entity.120108=o
+entity.120109=p
+entity.120110=q
+entity.120111=r
+entity.120112=s
+entity.120113=t
+entity.120114=u
+entity.120115=v
+entity.120116=w
+entity.120117=x
+entity.120118=y
+entity.120119=z
+entity.120120=A
+entity.120121=B
+entity.120123=D
+entity.120124=E
+entity.120125=F
+entity.120126=G
+entity.120128=I
+entity.120129=J
+entity.120130=K
+entity.120131=L
+entity.120132=M
+entity.120134=O
+entity.120138=S
+entity.120139=T
+entity.120140=U
+entity.120141=V
+entity.120142=W
+entity.120143=X
+entity.120144=Y
+entity.120146=a
+entity.120147=b
+entity.120148=c
+entity.120149=d
+entity.120150=e
+entity.120151=f
+entity.120152=g
+entity.120153=h
+entity.120154=i
+entity.120155=j
+entity.120156=k
+entity.120157=l
+entity.120158=m
+entity.120159=n
+entity.120160=o
+entity.120161=p
+entity.120162=q
+entity.120163=r
+entity.120164=s
+entity.120165=t
+entity.120166=u
+entity.120167=v
+entity.120168=w
+entity.120169=x
+entity.120170=y
+entity.120171=z
+entity.120172=A
+entity.120173=B
+entity.120174=C
+entity.120175=D
+entity.120176=E
+entity.120177=F
+entity.120178=G
+entity.120179=H
+entity.120180=I
+entity.120181=J
+entity.120182=K
+entity.120183=L
+entity.120184=M
+entity.120185=N
+entity.120186=O
+entity.120187=P
+entity.120188=Q
+entity.120189=R
+entity.120190=S
+entity.120191=T
+entity.120192=U
+entity.120193=V
+entity.120194=W
+entity.120195=X
+entity.120196=Y
+entity.120197=Z
+entity.120198=a
+entity.120199=b
+entity.120200=c
+entity.120201=d
+entity.120202=e
+entity.120203=f
+entity.120204=g
+entity.120205=h
+entity.120206=i
+entity.120207=j
+entity.120208=k
+entity.120209=l
+entity.120210=m
+entity.120211=n
+entity.120212=o
+entity.120213=p
+entity.120214=q
+entity.120215=r
+entity.120216=s
+entity.120217=t
+entity.120218=u
+entity.120219=v
+entity.120220=w
+entity.120221=x
+entity.120222=y
+entity.120223=z
+entity.120224=A
+entity.120225=B
+entity.120226=C
+entity.120227=D
+entity.120228=E
+entity.120229=F
+entity.120230=G
+entity.120231=H
+entity.120232=I
+entity.120233=J
+entity.120234=K
+entity.120235=L
+entity.120236=M
+entity.120237=N
+entity.120238=O
+entity.120239=P
+entity.120240=Q
+entity.120241=R
+entity.120242=S
+entity.120243=T
+entity.120244=U
+entity.120245=V
+entity.120246=W
+entity.120247=X
+entity.120248=Y
+entity.120249=Z
+entity.120250=a
+entity.120251=b
+entity.120252=c
+entity.120253=d
+entity.120254=e
+entity.120255=f
+entity.120256=g
+entity.120257=h
+entity.120258=i
+entity.120259=j
+entity.120260=k
+entity.120261=l
+entity.120262=m
+entity.120263=n
+entity.120264=o
+entity.120265=p
+entity.120266=q
+entity.120267=r
+entity.120268=s
+entity.120269=t
+entity.120270=u
+entity.120271=v
+entity.120272=w
+entity.120273=x
+entity.120274=y
+entity.120275=z
+entity.120276=A
+entity.120277=B
+entity.120278=C
+entity.120279=D
+entity.120280=E
+entity.120281=F
+entity.120282=G
+entity.120283=H
+entity.120284=I
+entity.120285=J
+entity.120286=K
+entity.120287=L
+entity.120288=M
+entity.120289=N
+entity.120290=O
+entity.120291=P
+entity.120292=Q
+entity.120293=R
+entity.120294=S
+entity.120295=T
+entity.120296=U
+entity.120297=V
+entity.120298=W
+entity.120299=X
+entity.120300=Y
+entity.120301=Z
+entity.120302=a
+entity.120303=b
+entity.120304=c
+entity.120305=d
+entity.120306=e
+entity.120307=f
+entity.120308=g
+entity.120309=h
+entity.120310=i
+entity.120311=j
+entity.120312=k
+entity.120313=l
+entity.120314=m
+entity.120315=n
+entity.120316=o
+entity.120317=p
+entity.120318=q
+entity.120319=r
+entity.120320=s
+entity.120321=t
+entity.120322=u
+entity.120323=v
+entity.120324=w
+entity.120325=x
+entity.120326=y
+entity.120327=z
+entity.120328=A
+entity.120329=B
+entity.120330=C
+entity.120331=D
+entity.120332=E
+entity.120333=F
+entity.120334=G
+entity.120335=H
+entity.120336=I
+entity.120337=J
+entity.120338=K
+entity.120339=L
+entity.120340=M
+entity.120341=N
+entity.120342=O
+entity.120343=P
+entity.120344=Q
+entity.120345=R
+entity.120346=S
+entity.120347=T
+entity.120348=U
+entity.120349=V
+entity.120350=W
+entity.120351=X
+entity.120352=Y
+entity.120353=Z
+entity.120354=a
+entity.120355=b
+entity.120356=c
+entity.120357=d
+entity.120358=e
+entity.120359=f
+entity.120360=g
+entity.120361=h
+entity.120362=i
+entity.120363=j
+entity.120364=k
+entity.120365=l
+entity.120366=m
+entity.120367=n
+entity.120368=o
+entity.120369=p
+entity.120370=q
+entity.120371=r
+entity.120372=s
+entity.120373=t
+entity.120374=u
+entity.120375=v
+entity.120376=w
+entity.120377=x
+entity.120378=y
+entity.120379=z
+entity.120380=A
+entity.120381=B
+entity.120382=C
+entity.120383=D
+entity.120384=E
+entity.120385=F
+entity.120386=G
+entity.120387=H
+entity.120388=I
+entity.120389=J
+entity.120390=K
+entity.120391=L
+entity.120392=M
+entity.120393=N
+entity.120394=O
+entity.120395=P
+entity.120396=Q
+entity.120397=R
+entity.120398=S
+entity.120399=T
+entity.120400=U
+entity.120401=V
+entity.120402=W
+entity.120403=X
+entity.120404=Y
+entity.120405=Z
+entity.120406=a
+entity.120407=b
+entity.120408=c
+entity.120409=d
+entity.120410=e
+entity.120411=f
+entity.120412=g
+entity.120413=h
+entity.120414=i
+entity.120415=j
+entity.120416=k
+entity.120417=l
+entity.120418=m
+entity.120419=n
+entity.120420=o
+entity.120421=p
+entity.120422=q
+entity.120423=r
+entity.120424=s
+entity.120425=t
+entity.120426=u
+entity.120427=v
+entity.120428=w
+entity.120429=x
+entity.120430=y
+entity.120431=z
+entity.120432=A
+entity.120433=B
+entity.120434=C
+entity.120435=D
+entity.120436=E
+entity.120437=F
+entity.120438=G
+entity.120439=H
+entity.120440=I
+entity.120441=J
+entity.120442=K
+entity.120443=L
+entity.120444=M
+entity.120445=N
+entity.120446=O
+entity.120447=P
+entity.120448=Q
+entity.120449=R
+entity.120450=S
+entity.120451=T
+entity.120452=U
+entity.120453=V
+entity.120454=W
+entity.120455=X
+entity.120456=Y
+entity.120457=Z
+entity.120458=a
+entity.120459=b
+entity.120460=c
+entity.120461=d
+entity.120462=e
+entity.120463=f
+entity.120464=g
+entity.120465=h
+entity.120466=i
+entity.120467=j
+entity.120468=k
+entity.120469=l
+entity.120470=m
+entity.120471=n
+entity.120472=o
+entity.120473=p
+entity.120474=q
+entity.120475=r
+entity.120476=s
+entity.120477=t
+entity.120478=u
+entity.120479=v
+entity.120480=w
+entity.120481=x
+entity.120482=y
+entity.120483=z
+entity.120782=0
+entity.120783=1
+entity.120784=2
+entity.120785=3
+entity.120786=4
+entity.120787=5
+entity.120788=6
+entity.120789=7
+entity.120790=8
+entity.120791=9
+entity.120792=0
+entity.120793=1
+entity.120794=2
+entity.120795=3
+entity.120796=4
+entity.120797=5
+entity.120798=6
+entity.120799=7
+entity.120800=8
+entity.120801=9
+entity.120802=0
+entity.120803=1
+entity.120804=2
+entity.120805=3
+entity.120806=4
+entity.120807=5
+entity.120808=6
+entity.120809=7
+entity.120810=8
+entity.120811=9
+entity.120812=0
+entity.120813=1
+entity.120814=2
+entity.120815=3
+entity.120816=4
+entity.120817=5
+entity.120818=6
+entity.120819=7
+entity.120820=8
+entity.120821=9
+entity.120822=0
+entity.120823=1
+entity.120824=2
+entity.120825=3
+entity.120826=4
+entity.120827=5
+entity.120828=6
+entity.120829=7
+entity.120830=8
+entity.120831=9
diff --git a/bundles/XO/res/fonts/mathfont.properties b/bundles/XO/res/fonts/mathfont.properties
new file mode 100755
index 0000000..dd80665
--- /dev/null
+++ b/bundles/XO/res/fonts/mathfont.properties
@@ -0,0 +1,522 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla MathML Project.
+#
+# The Initial Developer of the Original Code is
+# The University Of Queensland.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Roger B. Sidje <rbs@maths.uq.edu.au>
+# Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+##LOCALIZATION NOTE:
+# These are used to display an alert box to warn users when MathML fonts
+# are not installed on their system. The list of missing fonts will be
+# substituted in argument %1$S (see a screenshot in bug 128139).
+mathfont_missing_dialog_title = Missing MathML Fonts
+mathfont_missing_dialog_message = To properly display the MathML on this page you need to install the following fonts:\n%1$S.\n\n\nFor further information see:\nhttp://www.mozilla.org/projects/mathml/fonts
+
+##LOCALIZATION NOTE:
+# Do not translate anything else in this file
+
+# List of fonts that have corresponding properties files containing special
+# glyph tables for stretching MathML characters. See the documentation at the
+# end of this file for details on the setup of the property file associated to
+# each font. Do not include the Unicode table in this list.
+
+font.mathfont-glyph-tables = STIXNonUnicode, STIXSize1, Standard Symbols L
+
+# The ordered list of fonts with which to attempt to stretch MathML
+# characters is controlled by setting pref("font.mathfont-family",
+# "CMSY10, CMEX10, ...") for example, or by setting the font-family list in
+# :-moz-math-stretchy in mathml.css.
+#
+# Preferred fonts for particular stretchy characters may be specified in
+# preferences. Each entry is specified using the Unicode format of the
+# character, and the comma-separated list of fonts like in the font-family
+# property of CSS. A character can request different fonts for its variants
+# and for its parts.
+# e.g. pref("font.mathfont-family.\\u2264.base", "CMSY10, etc")
+# - A ".base" extension indicates the ordered list fonts to look for the glyph
+# at its base size.
+# - The ".variants" extension indicates the ordered list of fonts where to
+# look for glyphs of larger sizes.
+# - The ".parts" extension indicates the ordered list of fonts that should be
+# used to look for the partial glyphs to be used to build up the character.
+#
+# Note: setting base fonts for non-stretchy characters only works
+# for operators that are ultimately handled by nsMathMLChar.
+# @see how |useMathMLChar| is set in nsMathMLmoFrame::Stretch() & Paint().
+
+
+
+# Mappings from Unicode BMP chars to style invariant chars (these chars have
+# their own intrinsic predefined styles).
+# http://www.w3.org/TR/2003/REC-MathML2-20031021/chapter6.html#chars.BMP-SMP
+#
+# The string consists of a list of UTF16 code triples. For each i,
+# * the code at offset 3i is the BMP character
+# * the following two codes at offset 3i+1 and 3i+2 are either
+# * (usually) a surrogate pair representing the corresponding character
+# in the Mathematical Alphanumeric Symbols block, or
+# * when the corresponding styled mathematical character is in the BMP, that
+# BMP character followed by padding in the form of a UNICODE REPLACEMENT
+# CHARACTER U+fffd.
+#
+# Currently only some transformations are performed, and only through the
+# style system. (Bug 114365: Support for the 'mathvariant' attribute.)
+
+# there are no normal style-invariant mathematical alphanumeric symbols.
+#mathvariant.normal =
+
+mathvariant.bold = A\ud835\udc00B\ud835\udc01C\ud835\udc02D\ud835\udc03E\ud835\udc04F\ud835\udc05G\ud835\udc06H\ud835\udc07I\ud835\udc08J\ud835\udc09K\ud835\udc0aL\ud835\udc0bM\ud835\udc0cN\ud835\udc0dO\ud835\udc0eP\ud835\udc0fQ\ud835\udc10R\ud835\udc11S\ud835\udc12T\ud835\udc13U\ud835\udc14V\ud835\udc15W\ud835\udc16X\ud835\udc17Y\ud835\udc18Z\ud835\udc19a\ud835\udc1ab\ud835\udc1bc\ud835\udc1cd\ud835\udc1de\ud835\udc1ef\ud835\udc1fg\ud835\udc20h\ud835\udc21i\ud835\udc22j\ud835\udc23k\ud835\udc24l\ud835\udc25m\ud835\udc26n\ud835\udc27o\ud835\udc28p\ud835\udc29q\ud835\udc2ar\ud835\udc2bs\ud835\udc2ct\ud835\udc2du\ud835\udc2ev\ud835\udc2fw\ud835\udc30x\ud835\udc31y\ud835\udc32z\ud835\udc33\u0391\ud835\udea8\u0392\ud835\udea9\u0393\ud835\udeaa\u0394\ud835\udeab\u0395\ud835\udeac\u0396\ud835\udead\u0397\ud835\udeae\u0398\ud835\udeaf\u0399\ud835\udeb0\u039A\ud835\udeb1\u039B\ud835\udeb2\u039C\ud835\udeb3\u039D\ud835\udeb4\u039E\ud835\udeb5\u039F\ud835\udeb6\u03A0\ud835\udeb7\u03A1\ud835\udeb8\u03F4\ud835\udeb9\u03A3\ud835\udeba\u03A4\ud835\udebb\u03A5\ud835\udebc\u03A6\ud835\udebd\u03A7\ud835\udebe\u03A8\ud835\udebf\u03A9\ud835\udec0\u2207\ud835\udec1\u03B1\ud835\udec2\u03B2\ud835\udec3\u03B3\ud835\udec4\u03B4\ud835\udec5\u03B5\ud835\udec6\u03B6\ud835\udec7\u03B7\ud835\udec8\u03B8\ud835\udec9\u03B9\ud835\udeca\u03BA\ud835\udecb\u03BB\ud835\udecc\u03BC\ud835\udecd\u03BD\ud835\udece\u03BE\ud835\udecf\u03BF\ud835\uded0\u03C0\ud835\uded1\u03C1\ud835\uded2\u03C2\ud835\uded3\u03C3\ud835\uded4\u03C4\ud835\uded5\u03C5\ud835\uded6\u03C6\ud835\uded7\u03C7\ud835\uded8\u03C8\ud835\uded9\u03C9\ud835\udeda\u2202\ud835\udedb\u220A\ud835\udedc\u03D1\ud835\udedd\u03F0\ud835\udede\u03D5\ud835\udedf\u03F1\ud835\udee0\u03D6\ud835\udee10\ud835\udfce1\ud835\udfcf2\ud835\udfd03\ud835\udfd14\ud835\udfd25\ud835\udfd36\ud835\udfd47\ud835\udfd58\ud835\udfd69\ud835\udfd7
+mathvariant.italic = A\ud835\udc34B\ud835\udc35C\ud835\udc36D\ud835\udc37E\ud835\udc38F\ud835\udc39G\ud835\udc3aH\ud835\udc3bI\ud835\udc3cJ\ud835\udc3dK\ud835\udc3eL\ud835\udc3fM\ud835\udc40N\ud835\udc41O\ud835\udc42P\ud835\udc43Q\ud835\udc44R\ud835\udc45S\ud835\udc46T\ud835\udc47U\ud835\udc48V\ud835\udc49W\ud835\udc4aX\ud835\udc4bY\ud835\udc4cZ\ud835\udc4da\ud835\udc4eb\ud835\udc4fc\ud835\udc50d\ud835\udc51e\ud835\udc52f\ud835\udc53g\ud835\udc54h\u210e\ufffdi\ud835\udc56j\ud835\udc57k\ud835\udc58l\ud835\udc59m\ud835\udc5an\ud835\udc5bo\ud835\udc5cp\ud835\udc5dq\ud835\udc5er\ud835\udc5fs\ud835\udc60t\ud835\udc61u\ud835\udc62v\ud835\udc63w\ud835\udc64x\ud835\udc65y\ud835\udc66z\ud835\udc67\u0391\ud835\udee2\u0392\ud835\udee3\u0393\ud835\udee4\u0394\ud835\udee5\u0395\ud835\udee6\u0396\ud835\udee7\u0397\ud835\udee8\u0398\ud835\udee9\u0399\ud835\udeea\u039A\ud835\udeeb\u039B\ud835\udeec\u039C\ud835\udeed\u039D\ud835\udeee\u039E\ud835\udeef\u039F\ud835\udef0\u03A0\ud835\udef1\u03A1\ud835\udef2\u03F4\ud835\udef3\u03A3\ud835\udef4\u03A4\ud835\udef5\u03A5\ud835\udef6\u03A6\ud835\udef7\u03A7\ud835\udef8\u03A8\ud835\udef9\u03A9\ud835\udefa\u2207\ud835\udefb\u03B1\ud835\udefc\u03B2\ud835\udefd\u03B3\ud835\udefe\u03B4\ud835\udeff\u03B5\ud835\udf00\u03B6\ud835\udf01\u03B7\ud835\udf02\u03B8\ud835\udf03\u03B9\ud835\udf04\u03BA\ud835\udf05\u03BB\ud835\udf06\u03BC\ud835\udf07\u03BD\ud835\udf08\u03BE\ud835\udf09\u03BF\ud835\udf0a\u03C0\ud835\udf0b\u03C1\ud835\udf0c\u03C2\ud835\udf0d\u03C3\ud835\udf0e\u03C4\ud835\udf0f\u03C5\ud835\udf10\u03C6\ud835\udf11\u03C7\ud835\udf12\u03C8\ud835\udf13\u03C9\ud835\udf14\u2202\ud835\udf15\u220A\ud835\udf16\u03D1\ud835\udf17\u03F0\ud835\udf18\u03D5\ud835\udf19\u03F1\ud835\udf1a\u03D6\ud835\udf1b
+mathvariant.bold-italic = A\ud835\udc68B\ud835\udc69C\ud835\udc6aD\ud835\udc6bE\ud835\udc6cF\ud835\udc6dG\ud835\udc6eH\ud835\udc6fI\ud835\udc70J\ud835\udc71K\ud835\udc72L\ud835\udc73M\ud835\udc74N\ud835\udc75O\ud835\udc76P\ud835\udc77Q\ud835\udc78R\ud835\udc79S\ud835\udc7aT\ud835\udc7bU\ud835\udc7cV\ud835\udc7dW\ud835\udc7eX\ud835\udc7fY\ud835\udc80Z\ud835\udc81a\ud835\udc82b\ud835\udc83c\ud835\udc84d\ud835\udc85e\ud835\udc86f\ud835\udc87g\ud835\udc88h\ud835\udc89i\ud835\udc8aj\ud835\udc8bk\ud835\udc8cl\ud835\udc8dm\ud835\udc8en\ud835\udc8fo\ud835\udc90p\ud835\udc91q\ud835\udc92r\ud835\udc93s\ud835\udc94t\ud835\udc95u\ud835\udc96v\ud835\udc97w\ud835\udc98x\ud835\udc99y\ud835\udc9az\ud835\udc9b\u0391\ud835\udf1c\u0392\ud835\udf1d\u0393\ud835\udf1e\u0394\ud835\udf1f\u0395\ud835\udf20\u0396\ud835\udf21\u0397\ud835\udf22\u0398\ud835\udf23\u0399\ud835\udf24\u039A\ud835\udf25\u039B\ud835\udf26\u039C\ud835\udf27\u039D\ud835\udf28\u039E\ud835\udf29\u039F\ud835\udf2a\u03A0\ud835\udf2b\u03A1\ud835\udf2c\u03F4\ud835\udf2d\u03A3\ud835\udf2e\u03A4\ud835\udf2f\u03A5\ud835\udf30\u03A6\ud835\udf31\u03A7\ud835\udf32\u03A8\ud835\udf33\u03A9\ud835\udf34\u2207\ud835\udf35\u03B1\ud835\udf36\u03B2\ud835\udf37\u03B3\ud835\udf38\u03B4\ud835\udf39\u03B5\ud835\udf3a\u03B6\ud835\udf3b\u03B7\ud835\udf3c\u03B8\ud835\udf3d\u03B9\ud835\udf3e\u03BA\ud835\udf3f\u03BB\ud835\udf40\u03BC\ud835\udf41\u03BD\ud835\udf42\u03BE\ud835\udf43\u03BF\ud835\udf44\u03C0\ud835\udf45\u03C1\ud835\udf46\u03C2\ud835\udf47\u03C3\ud835\udf48\u03C4\ud835\udf49\u03C5\ud835\udf4a\u03C6\ud835\udf4b\u03C7\ud835\udf4c\u03C8\ud835\udf4d\u03C9\ud835\udf4e\u2202\ud835\udf4f\u220A\ud835\udf50\u03D1\ud835\udf51\u03F0\ud835\udf52\u03D5\ud835\udf53\u03F1\ud835\udf54\u03D6\ud835\udf55
+mathvariant.double-struck = A\ud835\udd38B\ud835\udd39C\u2102\ufffdD\ud835\udd3bE\ud835\udd3cF\ud835\udd3dG\ud835\udd3eH\u210d\ufffdI\ud835\udd40J\ud835\udd41K\ud835\udd42L\ud835\udd43M\ud835\udd44N\u2115\ufffdO\ud835\udd46P\u2119\ufffdQ\u211a\ufffdR\u211d\ufffdS\ud835\udd4aT\ud835\udd4bU\ud835\udd4cV\ud835\udd4dW\ud835\udd4eX\ud835\udd4fY\ud835\udd50Z\u2124\ufffda\ud835\udd52b\ud835\udd53c\ud835\udd54d\ud835\udd55e\ud835\udd56f\ud835\udd57g\ud835\udd58h\ud835\udd59i\ud835\udd5aj\ud835\udd5bk\ud835\udd5cl\ud835\udd5dm\ud835\udd5en\ud835\udd5fo\ud835\udd60p\ud835\udd61q\ud835\udd62r\ud835\udd63s\ud835\udd64t\ud835\udd65u\ud835\udd66v\ud835\udd67w\ud835\udd68x\ud835\udd69y\ud835\udd6az\ud835\udd6b0\ud835\udfd81\ud835\udfd92\ud835\udfda3\ud835\udfdb4\ud835\udfdc5\ud835\udfdd6\ud835\udfde7\ud835\udfdf8\ud835\udfe09\ud835\udfe1
+mathvariant.script = A\ud835\udc9cB\u212c\ufffdC\ud835\udc9eD\ud835\udc9fE\u2130\ufffdF\u2131\ufffdG\ud835\udca2H\u210b\ufffdI\u2110\ufffdJ\ud835\udca5K\ud835\udca6L\u2112\ufffdM\u2133\ufffdN\ud835\udca9O\ud835\udcaaP\ud835\udcabQ\ud835\udcacR\u211b\ufffdS\ud835\udcaeT\ud835\udcafU\ud835\udcb0V\ud835\udcb1W\ud835\udcb2X\ud835\udcb3Y\ud835\udcb4Z\ud835\udcb5a\ud835\udcb6b\ud835\udcb7c\ud835\udcb8d\ud835\udcb9e\u212f\ufffdf\ud835\udcbbg\u210a\ufffdh\ud835\udcbdi\ud835\udcbej\ud835\udcbfk\ud835\udcc0l\ud835\udcc1m\ud835\udcc2n\ud835\udcc3o\u2134\ufffdp\ud835\udcc5q\ud835\udcc6r\ud835\udcc7s\ud835\udcc8t\ud835\udcc9u\ud835\udccav\ud835\udccbw\ud835\udcccx\ud835\udccdy\ud835\udccez\ud835\udccf
+mathvariant.bold-script = A\ud835\udcd0B\ud835\udcd1C\ud835\udcd2D\ud835\udcd3E\ud835\udcd4F\ud835\udcd5G\ud835\udcd6H\ud835\udcd7I\ud835\udcd8J\ud835\udcd9K\ud835\udcdaL\ud835\udcdbM\ud835\udcdcN\ud835\udcddO\ud835\udcdeP\ud835\udcdfQ\ud835\udce0R\ud835\udce1S\ud835\udce2T\ud835\udce3U\ud835\udce4V\ud835\udce5W\ud835\udce6X\ud835\udce7Y\ud835\udce8Z\ud835\udce9a\ud835\udceab\ud835\udcebc\ud835\udcecd\ud835\udcede\ud835\udceef\ud835\udcefg\ud835\udcf0h\ud835\udcf1i\ud835\udcf2j\ud835\udcf3k\ud835\udcf4l\ud835\udcf5m\ud835\udcf6n\ud835\udcf7o\ud835\udcf8p\ud835\udcf9q\ud835\udcfar\ud835\udcfbs\ud835\udcfct\ud835\udcfdu\ud835\udcfev\ud835\udcffw\ud835\udd00x\ud835\udd01y\ud835\udd02z\ud835\udd03
+mathvariant.fraktur = A\ud835\udd04B\ud835\udd05C\u212d\ufffdD\ud835\udd07E\ud835\udd08F\ud835\udd09G\ud835\udd0aH\u210c\ufffdI\u2111\ufffdJ\ud835\udd0dK\ud835\udd0eL\ud835\udd0fM\ud835\udd10N\ud835\udd11O\ud835\udd12P\ud835\udd13Q\ud835\udd14R\u211c\ufffdS\ud835\udd16T\ud835\udd17U\ud835\udd18V\ud835\udd19W\ud835\udd1aX\ud835\udd1bY\ud835\udd1cZ\u2128\ufffda\ud835\udd1eb\ud835\udd1fc\ud835\udd20d\ud835\udd21e\ud835\udd22f\ud835\udd23g\ud835\udd24h\ud835\udd25i\ud835\udd26j\ud835\udd27k\ud835\udd28l\ud835\udd29m\ud835\udd2an\ud835\udd2bo\ud835\udd2cp\ud835\udd2dq\ud835\udd2er\ud835\udd2fs\ud835\udd30t\ud835\udd31u\ud835\udd32v\ud835\udd33w\ud835\udd34x\ud835\udd35y\ud835\udd36z\ud835\udd37
+mathvariant.bold-fraktur = A\ud835\udd6cB\ud835\udd6dC\ud835\udd6eD\ud835\udd6fE\ud835\udd70F\ud835\udd71G\ud835\udd72H\ud835\udd73I\ud835\udd74J\ud835\udd75K\ud835\udd76L\ud835\udd77M\ud835\udd78N\ud835\udd79O\ud835\udd7aP\ud835\udd7bQ\ud835\udd7cR\ud835\udd7dS\ud835\udd7eT\ud835\udd7fU\ud835\udd80V\ud835\udd81W\ud835\udd82X\ud835\udd83Y\ud835\udd84Z\ud835\udd85a\ud835\udd86b\ud835\udd87c\ud835\udd88d\ud835\udd89e\ud835\udd8af\ud835\udd8bg\ud835\udd8ch\ud835\udd8di\ud835\udd8ej\ud835\udd8fk\ud835\udd90l\ud835\udd91m\ud835\udd92n\ud835\udd93o\ud835\udd94p\ud835\udd95q\ud835\udd96r\ud835\udd97s\ud835\udd98t\ud835\udd99u\ud835\udd9av\ud835\udd9bw\ud835\udd9cx\ud835\udd9dy\ud835\udd9ez\ud835\udd9f
+mathvariant.sans-serif = A\ud835\udda0B\ud835\udda1C\ud835\udda2D\ud835\udda3E\ud835\udda4F\ud835\udda5G\ud835\udda6H\ud835\udda7I\ud835\udda8J\ud835\udda9K\ud835\uddaaL\ud835\uddabM\ud835\uddacN\ud835\uddadO\ud835\uddaeP\ud835\uddafQ\ud835\uddb0R\ud835\uddb1S\ud835\uddb2T\ud835\uddb3U\ud835\uddb4V\ud835\uddb5W\ud835\uddb6X\ud835\uddb7Y\ud835\uddb8Z\ud835\uddb9a\ud835\uddbab\ud835\uddbbc\ud835\uddbcd\ud835\uddbde\ud835\uddbef\ud835\uddbfg\ud835\uddc0h\ud835\uddc1i\ud835\uddc2j\ud835\uddc3k\ud835\uddc4l\ud835\uddc5m\ud835\uddc6n\ud835\uddc7o\ud835\uddc8p\ud835\uddc9q\ud835\uddcar\ud835\uddcbs\ud835\uddcct\ud835\uddcdu\ud835\uddcev\ud835\uddcfw\ud835\uddd0x\ud835\uddd1y\ud835\uddd2z\ud835\uddd30\ud835\udfe21\ud835\udfe32\ud835\udfe43\ud835\udfe54\ud835\udfe65\ud835\udfe76\ud835\udfe87\ud835\udfe98\ud835\udfea9\ud835\udfeb
+mathvariant.bold-sans-serif = A\ud835\uddd4B\ud835\uddd5C\ud835\uddd6D\ud835\uddd7E\ud835\uddd8F\ud835\uddd9G\ud835\udddaH\ud835\udddbI\ud835\udddcJ\ud835\uddddK\ud835\udddeL\ud835\udddfM\ud835\udde0N\ud835\udde1O\ud835\udde2P\ud835\udde3Q\ud835\udde4R\ud835\udde5S\ud835\udde6T\ud835\udde7U\ud835\udde8V\ud835\udde9W\ud835\uddeaX\ud835\uddebY\ud835\uddecZ\ud835\uddeda\ud835\uddeeb\ud835\uddefc\ud835\uddf0d\ud835\uddf1e\ud835\uddf2f\ud835\uddf3g\ud835\uddf4h\ud835\uddf5i\ud835\uddf6j\ud835\uddf7k\ud835\uddf8l\ud835\uddf9m\ud835\uddfan\ud835\uddfbo\ud835\uddfcp\ud835\uddfdq\ud835\uddfer\ud835\uddffs\ud835\ude00t\ud835\ude01u\ud835\ude02v\ud835\ude03w\ud835\ude04x\ud835\ude05y\ud835\ude06z\ud835\ude07\u0391\ud835\udf56\u0392\ud835\udf57\u0393\ud835\udf58\u0394\ud835\udf59\u0395\ud835\udf5a\u0396\ud835\udf5b\u0397\ud835\udf5c\u0398\ud835\udf5d\u0399\ud835\udf5e\u039A\ud835\udf5f\u039B\ud835\udf60\u039C\ud835\udf61\u039D\ud835\udf62\u039E\ud835\udf63\u039F\ud835\udf64\u03A0\ud835\udf65\u03A1\ud835\udf66\u03F4\ud835\udf67\u03A3\ud835\udf68\u03A4\ud835\udf69\u03A5\ud835\udf6a\u03A6\ud835\udf6b\u03A7\ud835\udf6c\u03A8\ud835\udf6d\u03A9\ud835\udf6e\u2207\ud835\udf6f\u03B1\ud835\udf70\u03B2\ud835\udf71\u03B3\ud835\udf72\u03B4\ud835\udf73\u03B5\ud835\udf74\u03B6\ud835\udf75\u03B7\ud835\udf76\u03B8\ud835\udf77\u03B9\ud835\udf78\u03BA\ud835\udf79\u03BB\ud835\udf7a\u03BC\ud835\udf7b\u03BD\ud835\udf7c\u03BE\ud835\udf7d\u03BF\ud835\udf7e\u03C0\ud835\udf7f\u03C1\ud835\udf80\u03C2\ud835\udf81\u03C3\ud835\udf82\u03C4\ud835\udf83\u03C5\ud835\udf84\u03C6\ud835\udf85\u03C7\ud835\udf86\u03C8\ud835\udf87\u03C9\ud835\udf88\u2202\ud835\udf89\u220A\ud835\udf8a\u03D1\ud835\udf8b\u03F0\ud835\udf8c\u03D5\ud835\udf8d\u03F1\ud835\udf8e\u03D6\ud835\udf8f0\ud835\udfec1\ud835\udfed2\ud835\udfee3\ud835\udfef4\ud835\udff05\ud835\udff16\ud835\udff27\ud835\udff38\ud835\udff49\ud835\udff5
+mathvariant.sans-serif-italic = A\ud835\ude08B\ud835\ude09C\ud835\ude0aD\ud835\ude0bE\ud835\ude0cF\ud835\ude0dG\ud835\ude0eH\ud835\ude0fI\ud835\ude10J\ud835\ude11K\ud835\ude12L\ud835\ude13M\ud835\ude14N\ud835\ude15O\ud835\ude16P\ud835\ude17Q\ud835\ude18R\ud835\ude19S\ud835\ude1aT\ud835\ude1bU\ud835\ude1cV\ud835\ude1dW\ud835\ude1eX\ud835\ude1fY\ud835\ude20Z\ud835\ude21a\ud835\ude22b\ud835\ude23c\ud835\ude24d\ud835\ude25e\ud835\ude26f\ud835\ude27g\ud835\ude28h\ud835\ude29i\ud835\ude2aj\ud835\ude2bk\ud835\ude2cl\ud835\ude2dm\ud835\ude2en\ud835\ude2fo\ud835\ude30p\ud835\ude31q\ud835\ude32r\ud835\ude33s\ud835\ude34t\ud835\ude35u\ud835\ude36v\ud835\ude37w\ud835\ude38x\ud835\ude39y\ud835\ude3az\ud835\ude3b
+mathvariant.sans-serif-bold-italic = A\ud835\ude3cB\ud835\ude3dC\ud835\ude3eD\ud835\ude3fE\ud835\ude40F\ud835\ude41G\ud835\ude42H\ud835\ude43I\ud835\ude44J\ud835\ude45K\ud835\ude46L\ud835\ude47M\ud835\ude48N\ud835\ude49O\ud835\ude4aP\ud835\ude4bQ\ud835\ude4cR\ud835\ude4dS\ud835\ude4eT\ud835\ude4fU\ud835\ude50V\ud835\ude51W\ud835\ude52X\ud835\ude53Y\ud835\ude54Z\ud835\ude55a\ud835\ude56b\ud835\ude57c\ud835\ude58d\ud835\ude59e\ud835\ude5af\ud835\ude5bg\ud835\ude5ch\ud835\ude5di\ud835\ude5ej\ud835\ude5fk\ud835\ude60l\ud835\ude61m\ud835\ude62n\ud835\ude63o\ud835\ude64p\ud835\ude65q\ud835\ude66r\ud835\ude67s\ud835\ude68t\ud835\ude69u\ud835\ude6av\ud835\ude6bw\ud835\ude6cx\ud835\ude6dy\ud835\ude6ez\ud835\ude6f\u0391\ud835\udf90\u0392\ud835\udf91\u0393\ud835\udf92\u0394\ud835\udf93\u0395\ud835\udf94\u0396\ud835\udf95\u0397\ud835\udf96\u0398\ud835\udf97\u0399\ud835\udf98\u039A\ud835\udf99\u039B\ud835\udf9a\u039C\ud835\udf9b\u039D\ud835\udf9c\u039E\ud835\udf9d\u039F\ud835\udf9e\u03A0\ud835\udf9f\u03A1\ud835\udfa0\u03F4\ud835\udfa1\u03A3\ud835\udfa2\u03A4\ud835\udfa3\u03A5\ud835\udfa4\u03A6\ud835\udfa5\u03A7\ud835\udfa6\u03A8\ud835\udfa7\u03A9\ud835\udfa8\u2207\ud835\udfa9\u03B1\ud835\udfaa\u03B2\ud835\udfab\u03B3\ud835\udfac\u03B4\ud835\udfad\u03B5\ud835\udfae\u03B6\ud835\udfaf\u03B7\ud835\udfb0\u03B8\ud835\udfb1\u03B9\ud835\udfb2\u03BA\ud835\udfb3\u03BB\ud835\udfb4\u03BC\ud835\udfb5\u03BD\ud835\udfb6\u03BE\ud835\udfb7\u03BF\ud835\udfb8\u03C0\ud835\udfb9\u03C1\ud835\udfba\u03C2\ud835\udfbb\u03C3\ud835\udfbc\u03C4\ud835\udfbd\u03C5\ud835\udfbe\u03C6\ud835\udfbf\u03C7\ud835\udfc0\u03C8\ud835\udfc1\u03C9\ud835\udfc2\u2202\ud835\udfc3\u220A\ud835\udfc4\u03D1\ud835\udfc5\u03F0\ud835\udfc6\u03D5\ud835\udfc7\u03F1\ud835\udfc8\u03D6\ud835\udfc9
+mathvariant.monospace = A\ud835\ude70B\ud835\ude71C\ud835\ude72D\ud835\ude73E\ud835\ude74F\ud835\ude75G\ud835\ude76H\ud835\ude77I\ud835\ude78J\ud835\ude79K\ud835\ude7aL\ud835\ude7bM\ud835\ude7cN\ud835\ude7dO\ud835\ude7eP\ud835\ude7fQ\ud835\ude80R\ud835\ude81S\ud835\ude82T\ud835\ude83U\ud835\ude84V\ud835\ude85W\ud835\ude86X\ud835\ude87Y\ud835\ude88Z\ud835\ude89a\ud835\ude8ab\ud835\ude8bc\ud835\ude8cd\ud835\ude8de\ud835\ude8ef\ud835\ude8fg\ud835\ude90h\ud835\ude91i\ud835\ude92j\ud835\ude93k\ud835\ude94l\ud835\ude95m\ud835\ude96n\ud835\ude97o\ud835\ude98p\ud835\ude99q\ud835\ude9ar\ud835\ude9bs\ud835\ude9ct\ud835\ude9du\ud835\ude9ev\ud835\ude9fw\ud835\udea0x\ud835\udea1y\ud835\udea2z\ud835\udea30\ud835\udff61\ud835\udff72\ud835\udff83\ud835\udff94\ud835\udffa5\ud835\udffb6\ud835\udffc7\ud835\udffd8\ud835\udffe9\ud835\udfff
+
+
+# Operator Dictionary indexed on the "form" (i.e., infix, prefix, or suffix).
+# Each entry lists the attributes of the operator, using its Unicode format.
+
+operator.\u0028.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # (
+operator.\u0029.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # )
+operator.\u005B.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # [
+operator.\u005D.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # ]
+operator.\u007B.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # {
+operator.\u007D.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # }
+operator.\u201D.postfix = fence:true lspace:0em rspace:0em # &CloseCurlyDoubleQuote;
+operator.\u2019.postfix = fence:true lspace:0em rspace:0em # &CloseCurlyQuote;
+operator.\u27E8.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # &LeftAngleBracket;
+operator.\u2308.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # &LeftCeiling;
+operator.\u27E6.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # &LeftDoubleBracket;
+operator.\u230A.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # &LeftFloor;
+operator.\u201C.prefix = fence:true lspace:0em rspace:0em # &OpenCurlyDoubleQuote;
+operator.\u2018.prefix = fence:true lspace:0em rspace:0em # &OpenCurlyQuote;
+operator.\u27E9.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # &RightAngleBracket;
+operator.\u2309.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # &RightCeiling;
+operator.\u27E7.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # &RightDoubleBracket;
+operator.\u230B.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # &RightFloor;
+operator.\u2063.infix = separator:true lspace:0em rspace:0em # &InvisibleComma;
+operator.\u002C.infix = separator:true lspace:0em rspace:verythickmathspace # ,
+operator.\u2500.infix = stretchy:horizontal minsize:0 lspace:0em rspace:0em # &HorizontalLine;
+operator.\u007C.infix = stretchy:vertical minsize:0 lspace:0em rspace:0em # &VerticalLine; |
+operator.\u003B.infix = separator:true lspace:0em rspace:thickmathspace # ;
+operator.\u003B.postfix = separator:true lspace:0em rspace:0em # ;
+operator.\u003A\u003D.infix = lspace:thickmathspace rspace:thickmathspace # :=
+operator.\u2254.infix = lspace:thickmathspace rspace:thickmathspace # &Assign;
+operator.\u2235.infix = lspace:thickmathspace rspace:thickmathspace # &Because;
+operator.\u2234.infix = lspace:thickmathspace rspace:thickmathspace # &Therefore;
+operator.\u2758.infix = stretchy:vertical lspace:thickmathspace rspace:thickmathspace # &VerticalSeparator;
+operator.\u002F\u002F.infix = lspace:thickmathspace rspace:thickmathspace # //
+operator.\u2237.infix = lspace:thickmathspace rspace:thickmathspace # &Colon; &Proportion;
+operator.\u0026.prefix = lspace:0em rspace:thickmathspace # &amp;
+operator.\u0026.postfix = lspace:thickmathspace rspace:0em # &amp;
+operator.\u002A\u003D.infix = lspace:thickmathspace rspace:thickmathspace # *=
+operator.\u002D\u003D.infix = lspace:thickmathspace rspace:thickmathspace # -=
+operator.\u002B\u003D.infix = lspace:thickmathspace rspace:thickmathspace # +=
+operator.\u002F\u003D.infix = lspace:thickmathspace rspace:thickmathspace # /=
+operator.\u002D\u003E.infix = lspace:thickmathspace rspace:thickmathspace # ->
+operator.\u003A.infix = lspace:thickmathspace rspace:thickmathspace # :
+operator.\u002E\u002E.postfix = lspace:mediummathspace rspace:0em # ..
+operator.\u002E\u002E\u002E.postfix = lspace:mediummathspace rspace:0em # ...
+operator.\u220B.infix = lspace:thickmathspace rspace:thickmathspace # &SuchThat; &ReverseElement;
+operator.\u2AE4.infix = lspace:thickmathspace rspace:thickmathspace # &DoubleLeftTee;
+operator.\u22A8.infix = lspace:thickmathspace rspace:thickmathspace # &DoubleRightTee;
+operator.\u22A4.infix = lspace:thickmathspace rspace:thickmathspace # &DownTee;
+operator.\u22A3.infix = lspace:thickmathspace rspace:thickmathspace # &LeftTee;
+operator.\u22A2.infix = lspace:thickmathspace rspace:thickmathspace # &RightTee;
+operator.\u21D2.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &Implies; &DoubleRightArrow;
+operator.\u2970.infix = lspace:thickmathspace rspace:thickmathspace # &RoundImplies;
+operator.\u007C\u007C.infix = lspace:mediummathspace rspace:mediummathspace # ||
+operator.\u2A54.infix = stretchy:vertical lspace:mediummathspace rspace:mediummathspace # &Or;
+operator.\u0026\u0026.infix = lspace:thickmathspace rspace:thickmathspace # &amp;&amp;
+operator.\u2A53.infix = stretchy:vertical lspace:mediummathspace rspace:mediummathspace # &And;
+operator.\u0026.infix = lspace:thickmathspace rspace:thickmathspace # &amp;
+operator.\u0021.prefix = lspace:0em rspace:thickmathspace # !
+operator.\u2AEC.prefix = lspace:0em rspace:thickmathspace # &Not;
+operator.\u2203.prefix = lspace:0em rspace:thickmathspace # &Exists;
+operator.\u2200.prefix = lspace:0em rspace:thickmathspace # &ForAll;
+operator.\u2204.prefix = lspace:0em rspace:thickmathspace # &NotExists;
+operator.\u2208.infix = lspace:thickmathspace rspace:thickmathspace # &Element;
+operator.\u2209.infix = lspace:thickmathspace rspace:thickmathspace # &NotElement;
+operator.\u220C.infix = lspace:thickmathspace rspace:thickmathspace # &NotReverseElement;
+operator.\u228F\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotSquareSubset;
+operator.\u22E2.infix = lspace:thickmathspace rspace:thickmathspace # &NotSquareSubsetEqual;
+operator.\u2290\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotSquareSuperset;
+operator.\u22E3.infix = lspace:thickmathspace rspace:thickmathspace # &NotSquareSupersetEqual;
+operator.\u2284.infix = lspace:thickmathspace rspace:thickmathspace # &nsub;
+operator.\u2282\u020D2.infix = lspace:thickmathspace rspace:thickmathspace # &NotSubset;
+operator.\u2288.infix = lspace:thickmathspace rspace:thickmathspace # &NotSubsetEqual;
+operator.\u2AC5\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &nsubseteqq;
+operator.\u2285.infix = lspace:thickmathspace rspace:thickmathspace # &nsup;
+operator.\u2283\u020D2.infix = lspace:thickmathspace rspace:thickmathspace # &NotSuperset;
+operator.\u2289.infix = lspace:thickmathspace rspace:thickmathspace # &NotSupersetEqual;
+operator.\u2AC6\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &nsubseteqq;
+operator.\u228F.infix = lspace:thickmathspace rspace:thickmathspace # &SquareSubset;
+operator.\u2291.infix = lspace:thickmathspace rspace:thickmathspace # &SquareSubsetEqual;
+operator.\u2290.infix = lspace:thickmathspace rspace:thickmathspace # &SquareSuperset;
+operator.\u2292.infix = lspace:thickmathspace rspace:thickmathspace # &SquareSupersetEqual;
+operator.\u22D0.infix = lspace:thickmathspace rspace:thickmathspace # &Subset;
+operator.\u2286.infix = lspace:thickmathspace rspace:thickmathspace # &SubsetEqual;
+operator.\u2AC5.infix = lspace:thickmathspace rspace:thickmathspace # &subseteqq;
+operator.\u2283.infix = lspace:thickmathspace rspace:thickmathspace # &Superset;
+operator.\u2287.infix = lspace:thickmathspace rspace:thickmathspace # &SupersetEqual;
+operator.\u2AC6.infix = lspace:thickmathspace rspace:thickmathspace # &supseteqq;
+operator.\u21D0.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DoubleLeftArrow;
+operator.\u21D4.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DoubleLeftRightArrow;
+operator.\u2950.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DownLeftRightVector;
+operator.\u295E.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DownLeftTeeVector;
+operator.\u21BD.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DownLeftVector;
+operator.\u2956.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DownLeftVectorBar;
+operator.\u295F.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DownRightTeeVector;
+operator.\u21C1.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DownRightVector;
+operator.\u2957.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &DownRightVectorBar;
+operator.\u2190.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftArrow;
+operator.\u21E4.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftArrowBar;
+operator.\u21C6.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftArrowRightArrow;
+operator.\u2194.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftRightArrow;
+operator.\u294E.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftRightVector;
+operator.\u21A4.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftTeeArrow;
+operator.\u295A.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftTeeVector;
+operator.\u21BC.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftVector;
+operator.\u2952.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LeftVectorBar;
+operator.\u2199.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LowerLeftArrow;
+operator.\u2198.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &LowerRightArrow;
+operator.\u2192.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &RightArrow;
+operator.\u21E5.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &RightArrowBar;
+operator.\u21C4.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &RightArrowLeftArrow;
+operator.\u21A6.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &RightTeeArrow;
+operator.\u295B.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &RightTeeVector;
+operator.\u21C0.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &RightVector;
+operator.\u2953.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &RightVectorBar;
+operator.\u2190\u200B.infix = lspace:thickmathspace rspace:thickmathspace # &ShortLeftArrow;
+operator.\u2192\u200B.infix = lspace:thickmathspace rspace:thickmathspace # &ShortRightArrow;
+operator.\u2196.infix = stretchy:vertical lspace:thickmathspace rspace:thickmathspace # &UpperLeftArrow;
+operator.\u2197.infix = stretchy:vertical lspace:thickmathspace rspace:thickmathspace # &UpperRightArrow;
+operator.\u003D.infix = lspace:thickmathspace rspace:thickmathspace # =
+operator.\u003C.infix = lspace:thickmathspace rspace:thickmathspace # &lt;
+operator.\u003E.infix = lspace:thickmathspace rspace:thickmathspace # >
+operator.\u0021\u003D.infix = lspace:thickmathspace rspace:thickmathspace # !=
+operator.\u003D\u003D.infix = lspace:thickmathspace rspace:thickmathspace # ==
+operator.\u003C\u003D.infix = lspace:thickmathspace rspace:thickmathspace # &lt;=
+operator.\u003E\u003D.infix = lspace:thickmathspace rspace:thickmathspace # >=
+operator.\u2261.infix = lspace:thickmathspace rspace:thickmathspace # &Congruent;
+operator.\u224D.infix = lspace:thickmathspace rspace:thickmathspace # &CupCap;
+operator.\u2250.infix = lspace:thickmathspace rspace:thickmathspace # &DotEqual;
+operator.\u2225.infix = stretchy:vertical lspace:thickmathspace rspace:thickmathspace # &DoubleVerticalBar;
+operator.\u2016.infix = stretchy:vertical lspace:thickmathspace rspace:thickmathspace # &Vert; &Verbar;
+operator.\u2A75.infix = lspace:thickmathspace rspace:thickmathspace # &Equal;
+operator.\u2242.infix = lspace:thickmathspace rspace:thickmathspace # &EqualTilde;
+operator.\u21CC.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &Equilibrium;
+operator.\u2265.infix = lspace:thickmathspace rspace:thickmathspace # &GreaterEqual;
+operator.\u22DB.infix = lspace:thickmathspace rspace:thickmathspace # &GreaterEqualLess;
+operator.\u2A8C.infix = lspace:thickmathspace rspace:thickmathspace # &gtreqqless;
+operator.\u2267.infix = lspace:thickmathspace rspace:thickmathspace # &GreaterFullEqual;
+operator.\u2AA2.infix = lspace:thickmathspace rspace:thickmathspace # &GreaterGreater;
+operator.\u2277.infix = lspace:thickmathspace rspace:thickmathspace # &GreaterLess;
+operator.\u2A7E.infix = lspace:thickmathspace rspace:thickmathspace # &GreaterSlantEqual;
+operator.\u2273.infix = lspace:thickmathspace rspace:thickmathspace # &GreaterTilde;
+operator.\u2A86.infix = lspace:thickmathspace rspace:thickmathspace # &gtrapprox;
+operator.\u224E.infix = lspace:thickmathspace rspace:thickmathspace # &HumpDownHump;
+operator.\u224F.infix = lspace:thickmathspace rspace:thickmathspace # &HumpEqual;
+operator.\u22B2.infix = lspace:thickmathspace rspace:thickmathspace # &LeftTriangle;
+operator.\u29CF.infix = lspace:thickmathspace rspace:thickmathspace # &LeftTriangleBar;
+operator.\u22B4.infix = lspace:thickmathspace rspace:thickmathspace # &LeftTriangleEqual;
+operator.\u2264.infix = lspace:thickmathspace rspace:thickmathspace # &le;
+operator.\u22DA.infix = lspace:thickmathspace rspace:thickmathspace # &LessEqualGreater;
+operator.\u2A8B.infix = lspace:thickmathspace rspace:thickmathspace # &lesseqqgtr;
+operator.\u2266.infix = lspace:thickmathspace rspace:thickmathspace # &LessFullEqual;
+operator.\u2276.infix = lspace:thickmathspace rspace:thickmathspace # &LessGreater;
+operator.\u2AA1.infix = lspace:thickmathspace rspace:thickmathspace # &LessLess;
+operator.\u2A7D.infix = lspace:thickmathspace rspace:thickmathspace # &LessSlantEqual;
+operator.\u2272.infix = lspace:thickmathspace rspace:thickmathspace # &LessTilde;
+operator.\u2A85.infix = lspace:thickmathspace rspace:thickmathspace # &lessapprox;
+operator.\u226B.infix = lspace:thickmathspace rspace:thickmathspace # &NestedGreaterGreater;
+operator.\u226A.infix = lspace:thickmathspace rspace:thickmathspace # &NestedLessLess;
+operator.\u2262.infix = lspace:thickmathspace rspace:thickmathspace # &NotCongruent;
+operator.\u226D.infix = lspace:thickmathspace rspace:thickmathspace # &NotCupCap;
+operator.\u2226.infix = lspace:thickmathspace rspace:thickmathspace # &NotDoubleVerticalBar;
+operator.\u2260.infix = lspace:thickmathspace rspace:thickmathspace # &NotEqual;
+operator.\u2242\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotEqualTilde;
+operator.\u226F.infix = lspace:thickmathspace rspace:thickmathspace # &NotGreater;
+operator.\u003E\u20D2.infix = lspace:thickmathspace rspace:thickmathspace # &nvgt;
+operator.\u2271.infix = lspace:thickmathspace rspace:thickmathspace # &NotGreaterEqual;
+operator.\u2266\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotGreaterFullEqual;
+operator.\u2A7D\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotLessSlantEqual;
+operator.\u226B\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotGreaterGreater;
+operator.\u2279.infix = lspace:thickmathspace rspace:thickmathspace # &NotGreaterLess;
+operator.\u2A7E\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotGreaterSlantEqual;
+operator.\u2275.infix = lspace:thickmathspace rspace:thickmathspace # &NotGreaterTilde;
+operator.\u224E\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotHumpDownHump;
+operator.\u224F\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotHumpEqual;
+operator.\u22EA.infix = lspace:thickmathspace rspace:thickmathspace # &NotLeftTriangle;
+operator.\u29CF\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotLeftTriangleBar;
+operator.\u22EC.infix = lspace:thickmathspace rspace:thickmathspace # &NotLeftTriangleEqual;
+operator.\u226E.infix = lspace:thickmathspace rspace:thickmathspace # &NotLess;
+operator.\u003C\u20D2.infix = lspace:thickmathspace rspace:thickmathspace # &nvlt;
+operator.\u2270.infix = lspace:thickmathspace rspace:thickmathspace # &NotLessEqual;
+# There is no &NotLessFullEqual;
+operator.\u2278.infix = lspace:thickmathspace rspace:thickmathspace # &NotLessGreater;
+operator.\u226A\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotLessLess;
+operator.\u2274.infix = lspace:thickmathspace rspace:thickmathspace # &NotLessTilde;
+operator.\u2AA2\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotNestedGreaterGreater;
+operator.\u2AA1\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotNestedLessLess;
+operator.\u2280.infix = lspace:thickmathspace rspace:thickmathspace # &NotPrecedes;
+operator.\u2AAF\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotPrecedesEqual;
+operator.\u22E0.infix = lspace:thickmathspace rspace:thickmathspace # &NotPrecedesSlantEqual;
+operator.\u22EB.infix = lspace:thickmathspace rspace:thickmathspace # &NotRightTriangle;
+operator.\u29D0\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotRightTriangleBar;
+operator.\u22ED.infix = lspace:thickmathspace rspace:thickmathspace # &NotRightTriangleEqual;
+operator.\u2281.infix = lspace:thickmathspace rspace:thickmathspace # &NotSucceeds;
+operator.\u2AB0\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotSucceedsEqual;
+operator.\u22E1.infix = lspace:thickmathspace rspace:thickmathspace # &NotSucceedsSlantEqual;
+operator.\u227F\u0338.infix = lspace:thickmathspace rspace:thickmathspace # &NotSucceedsTilde;
+operator.\u2241.infix = lspace:thickmathspace rspace:thickmathspace # &NotTilde;
+operator.\u2244.infix = lspace:thickmathspace rspace:thickmathspace # &NotTildeEqual;
+operator.\u2247.infix = lspace:thickmathspace rspace:thickmathspace # &NotTildeFullEqual;
+operator.\u2249.infix = lspace:thickmathspace rspace:thickmathspace # &NotTildeTilde;
+operator.\u2224.infix = lspace:thickmathspace rspace:thickmathspace # &NotVerticalBar;
+operator.\u227A.infix = lspace:thickmathspace rspace:thickmathspace # &Precedes;
+operator.\u2AAF.infix = lspace:thickmathspace rspace:thickmathspace # &PrecedesEqual;
+operator.\u227C.infix = lspace:thickmathspace rspace:thickmathspace # &PrecedesSlantEqual;
+operator.\u227E.infix = lspace:thickmathspace rspace:thickmathspace # &PrecedesTilde;
+operator.\u2AB3.infix = lspace:thickmathspace rspace:thickmathspace # &prE;
+operator.\u2AB7.infix = lspace:thickmathspace rspace:thickmathspace # &precapprox;
+operator.\u221D.infix = lspace:thickmathspace rspace:thickmathspace # &Proportional;
+operator.\u21CB.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &ReverseEquilibrium;
+operator.\u22B3.infix = lspace:thickmathspace rspace:thickmathspace # &RightTriangle;
+operator.\u29D0.infix = lspace:thickmathspace rspace:thickmathspace # &RightTriangleBar;
+operator.\u22B5.infix = lspace:thickmathspace rspace:thickmathspace # &RightTriangleEqual;
+operator.\u227B.infix = lspace:thickmathspace rspace:thickmathspace # &Succeeds;
+operator.\u2AB0.infix = lspace:thickmathspace rspace:thickmathspace # &SucceedsEqual;
+operator.\u227D.infix = lspace:thickmathspace rspace:thickmathspace # &SucceedsSlantEqual;
+operator.\u227F.infix = lspace:thickmathspace rspace:thickmathspace # &SucceedsTilde;
+operator.\u2AB4.infix = lspace:thickmathspace rspace:thickmathspace # &scE;
+operator.\u2AB8.infix = lspace:thickmathspace rspace:thickmathspace # &succapprox;
+operator.\u223C.infix = lspace:thickmathspace rspace:thickmathspace # &Tilde;
+operator.\u2243.infix = lspace:thickmathspace rspace:thickmathspace # &TildeEqual;
+operator.\u2245.infix = lspace:thickmathspace rspace:thickmathspace # &TildeFullEqual;
+operator.\u2248.infix = lspace:thickmathspace rspace:thickmathspace # &TildeTilde;
+operator.\u22A5.infix = lspace:thickmathspace rspace:thickmathspace # &UpTee;
+operator.\u2223.infix = stretchy:vertical lspace:thickmathspace rspace:thickmathspace # &VerticalBar;
+operator.\u2294.infix = stretchy:vertical lspace:mediummathspace rspace:mediummathspace # &SquareUnion;
+operator.\u22C3.infix = stretchy:vertical lspace:mediummathspace rspace:mediummathspace # &Union;
+operator.\u228E.infix = stretchy:vertical lspace:mediummathspace rspace:mediummathspace # &UnionPlus;
+operator.\u002D.infix = lspace:mediummathspace rspace:mediummathspace # -
+operator.\u002B.infix = lspace:mediummathspace rspace:mediummathspace # +
+operator.\u22C2.infix = stretchy:vertical lspace:mediummathspace rspace:mediummathspace # &Intersection;
+operator.\u2213.infix = lspace:mediummathspace rspace:mediummathspace # &MinusPlus;
+operator.\u00B1.infix = lspace:mediummathspace rspace:mediummathspace # &PlusMinus;
+operator.\u2293.infix = stretchy:vertical lspace:mediummathspace rspace:mediummathspace # &SquareIntersection;
+operator.\u22C1.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &Vee;
+operator.\u2296.prefix = largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &CircleMinus;
+operator.\u2295.prefix = largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &CirclePlus;
+operator.\u2A01.prefix = largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &bigoplus;
+operator.\u2211.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &Sum;
+operator.\u22C3.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &Union;
+operator.\u228E.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &UnionPlus;
+operator.\u2A04.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &biguplus;
+operator.\u2A06.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &bigsqcup;
+operator.\u006C\u0069\u006D.prefix = movablelimits:true lspace:0em rspace:thinmathspace # lim
+operator.\u006D\u0061\u0078.prefix = movablelimits:true lspace:0em rspace:thinmathspace # max
+operator.\u006D\u0069\u006E.prefix = movablelimits:true lspace:0em rspace:thinmathspace # min
+operator.\u2212.infix = lspace:mediummathspace rspace:mediummathspace # official Unicode minus sign
+operator.\u2212.prefix = lspace:0em rspace:veryverythinmathspace # official Unicode minus sign
+operator.\u2296.infix = lspace:thinmathspace rspace:thinmathspace # &CircleMinus;
+operator.\u2295.infix = lspace:thinmathspace rspace:thinmathspace # &CirclePlus;
+operator.\u2232.prefix = stretchy:vertical largeop:true lspace:0em rspace:0em # &ClockwiseContourIntegral;
+operator.\u222E.prefix = stretchy:vertical largeop:true lspace:0em rspace:0em # &ContourIntegral;
+operator.\u2233.prefix = stretchy:vertical largeop:true lspace:0em rspace:0em # &CounterClockwiseContourIntegral;
+operator.\u222F.prefix = stretchy:vertical largeop:true lspace:0em rspace:0em # &DoubleContourIntegral;
+operator.\u222B.prefix = stretchy:vertical largeop:true lspace:0em rspace:0em # &Integral;
+operator.\u22D3.infix = lspace:thinmathspace rspace:thinmathspace # &Cup;
+operator.\u22D2.infix = lspace:thinmathspace rspace:thinmathspace # &Cap;
+operator.\u2240.infix = lspace:thinmathspace rspace:thinmathspace # &VerticalTilde;
+operator.\u22C0.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &Wedge;
+operator.\u2297.prefix = largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &CircleTimes;
+operator.\u2A02.prefix = largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &bigotimes;
+operator.\u2210.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &Coproduct;
+operator.\u220F.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &Product;
+operator.\u22C2.prefix = stretchy:vertical largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &Intersection;
+operator.\u2210.infix = lspace:thinmathspace rspace:thinmathspace # &Coproduct;
+operator.\u2606.infix = lspace:thinmathspace rspace:thinmathspace # &star;
+operator.\u22C6.infix = lspace:thinmathspace rspace:thinmathspace # &Star;
+operator.\u2299.prefix = largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &CircleDot;
+operator.\u2A00.prefix = largeop:true movablelimits:true lspace:0em rspace:thinmathspace # &bigodot;
+operator.\u002A.infix = lspace:thinmathspace rspace:thinmathspace # *
+operator.\u2062.infix = lspace:0em rspace:0em # &InvisibleTimes;
+operator.\u00B7.infix = lspace:thinmathspace rspace:thinmathspace # &CenterDot;
+operator.\u2297.infix = lspace:thinmathspace rspace:thinmathspace # &CircleTimes;
+operator.\u22C1.infix = lspace:thinmathspace rspace:thinmathspace # &Vee;
+operator.\u22C0.infix = lspace:thinmathspace rspace:thinmathspace # &Wedge;
+operator.\u22C4.infix = lspace:thinmathspace rspace:thinmathspace # &Diamond;
+operator.\u2216.infix = stretchy:vertical lspace:thinmathspace rspace:thinmathspace # &Backslash;
+operator.\u002F.infix = stretchy:vertical lspace:thinmathspace rspace:thinmathspace # /
+operator.\u002D.prefix = lspace:0em rspace:veryverythinmathspace # -
+operator.\u002B.prefix = lspace:0em rspace:veryverythinmathspace # +
+operator.\u2213.prefix = lspace:0em rspace:veryverythinmathspace # &MinusPlus;
+operator.\u00B1.prefix = lspace:0em rspace:veryverythinmathspace # &PlusMinus;
+operator.\u002E.infix = lspace:0em rspace:0em # .
+operator.\u2A2F.infix = lspace:verythinmathspace rspace:verythinmathspace # &Cross;
+operator.\u002A\u002A.infix = lspace:verythinmathspace rspace:verythinmathspace # **
+operator.\u2299.infix = lspace:verythinmathspace rspace:verythinmathspace # &CircleDot;
+operator.\u2218.infix = lspace:verythinmathspace rspace:verythinmathspace # &SmallCircle;
+operator.\u25A1.prefix = lspace:0em rspace:verythinmathspace # &Square;
+operator.\u2207.prefix = lspace:0em rspace:verythinmathspace # &Del;
+operator.\u2202.prefix = lspace:0em rspace:verythinmathspace # &PartialD;
+operator.\u2145.prefix = lspace:0em rspace:verythinmathspace # &CapitalDifferentialD;
+operator.\u2146.prefix = lspace:0em rspace:verythinmathspace # &DifferentialD;
+operator.\u221A.prefix = stretchy:vertical lspace:0em rspace:verythinmathspace # &Sqrt;
+operator.\u21D3.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &DoubleDownArrow;
+operator.\u27F8.infix = stretchy:horizontal lspace:verythinmathspace rspace:verythinmathspace # &DoubleLongLeftArrow;
+operator.\u27FA.infix = stretchy:horizontal lspace:verythinmathspace rspace:verythinmathspace # &DoubleLongLeftRightArrow;
+operator.\u27F9.infix = stretchy:horizontal lspace:verythinmathspace rspace:verythinmathspace # &DoubleLongRightArrow;
+operator.\u21D1.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &DoubleUpArrow;
+operator.\u21D5.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &DoubleUpDownArrow;
+operator.\u2193.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &DownArrow;
+operator.\u2913.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &DownArrowBar;
+operator.\u21F5.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &DownArrowUpArrow;
+operator.\u21A7.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &DownTeeArrow;
+operator.\u2961.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &LeftDownTeeVector;
+operator.\u21C3.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &LeftDownVector;
+operator.\u2959.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &LeftDownVectorBar;
+operator.\u2951.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &LeftUpDownVector;
+operator.\u2960.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &LeftUpTeeVector;
+operator.\u21BF.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &LeftUpVector;
+operator.\u2958.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &LeftUpVectorBar;
+operator.\u27F5.infix = stretchy:horizontal lspace:verythinmathspace rspace:verythinmathspace # &LongLeftArrow;
+operator.\u27F7.infix = stretchy:horizontal lspace:verythinmathspace rspace:verythinmathspace # &LongLeftRightArrow;
+operator.\u27F6.infix = stretchy:horizontal lspace:verythinmathspace rspace:verythinmathspace # &LongRightArrow;
+operator.\u296F.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &ReverseUpEquilibrium;
+operator.\u295D.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &RightDownTeeVector;
+operator.\u21C2.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &RightDownVector;
+operator.\u2955.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &RightDownVectorBar;
+operator.\u294F.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &RightUpDownVector;
+operator.\u295C.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &RightUpTeeVector;
+operator.\u21BE.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &RightUpVector;
+operator.\u2954.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &RightUpVectorBar;
+operator.\u2193\u200B.infix = lspace:verythinmathspace rspace:verythinmathspace # &ShortDownArrow;
+operator.\u2191\u200B.infix = lspace:verythinmathspace rspace:verythinmathspace # &ShortUpArrow;
+operator.\u2191.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &UpArrow;
+operator.\u2912.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &UpArrowBar;
+operator.\u21C5.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &UpArrowDownArrow;
+operator.\u2195.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &UpDownArrow;
+operator.\u296E.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &UpEquilibrium;
+operator.\u21A5.infix = stretchy:vertical lspace:verythinmathspace rspace:verythinmathspace # &UpTeeArrow;
+operator.\u005E.infix = lspace:verythinmathspace rspace:verythinmathspace # ^
+operator.\u003C\u003E.infix = lspace:verythinmathspace rspace:verythinmathspace # &lt;>
+operator.\u0027.postfix = lspace:verythinmathspace rspace:0em # '
+operator.\u0021.postfix = lspace:verythinmathspace rspace:0em # !
+operator.\u0021\u0021.postfix = lspace:verythinmathspace rspace:0em # !!
+operator.\u007E.infix = lspace:verythinmathspace rspace:verythinmathspace # ~
+operator.\u0040.infix = lspace:verythinmathspace rspace:verythinmathspace # @
+operator.\u002D\u002D.postfix = lspace:verythinmathspace rspace:0em # --
+operator.\u002D\u002D.prefix = lspace:0em rspace:verythinmathspace # --
+operator.\u002B\u002B.postfix = lspace:verythinmathspace rspace:0em # ++
+operator.\u002B\u002B.prefix = lspace:0em rspace:verythinmathspace # ++
+operator.\u2061.infix = lspace:0em rspace:0em # &ApplyFunction;
+operator.\u003F.infix = lspace:verythinmathspace rspace:verythinmathspace # ?
+operator.\u005F.infix = lspace:verythinmathspace rspace:verythinmathspace # _
+operator.\u02D8.postfix = accent:true lspace:0em rspace:0em # &Breve;
+operator.\u00B8.postfix = accent:true lspace:0em rspace:0em # &Cedilla;
+operator.\u0060.postfix = accent:true lspace:0em rspace:0em # &DiacriticalGrave;
+operator.\u02D9.postfix = accent:true lspace:0em rspace:0em # &DiacriticalDot;
+operator.\u02DD.postfix = accent:true lspace:0em rspace:0em # &DiacriticalDoubleAcute;
+operator.\u00B4.postfix = accent:true lspace:0em rspace:0em # &DiacriticalAcute;
+operator.\u02DC.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &DiacriticalTilde;
+operator.\u00A8.postfix = accent:true lspace:0em rspace:0em # &DoubleDot;
+operator.\u0311.postfix = accent:true lspace:0em rspace:0em # &DownBreve;
+operator.\u02C7.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &Hacek;
+operator.\u005E.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &Hat;
+operator.\u00AF.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &OverBar;
+operator.\u23DE.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &OverBrace; (Unicode)
+operator.\uFE37.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &OverBrace; (MathML 2.0)
+operator.\u23B4.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &OverBracket;
+operator.\u23DC.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &OverParenthesis; (Unicode)
+operator.\uFE35.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &OverParenthesis; (MathML 2.0)
+operator.\u20DB.postfix = accent:true lspace:0em rspace:0em # &TripleDot;
+operator.\u0332.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &UnderBar;
+operator.\u23DF.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &UnderBrace; (Unicode)
+operator.\uFE38.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &UnderBrace; (MathML 2.0)
+operator.\u23B5.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &UnderBracket;
+operator.\u23DD.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &UnderParenthesis; (Unicode)
+operator.\uFE36.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &UnderParenthesis; (MathML 2.0)
+operator.\u2225.prefix = stretchy:vertical fence:true lspace:.0em rspace:.0em # &DoubleVerticalBar;
+operator.\u2225.postfix = stretchy:vertical fence:true lspace:.0em rspace:.0em # &DoubleVerticalBar;
+operator.\u2016.prefix = stretchy:vertical fence:true lspace:.0em rspace:.0em # &Vert; &Verbar;
+operator.\u2016.postfix = stretchy:vertical fence:true lspace:.0em rspace:.0em # &Vert; &Verbar;
+operator.\u2223.prefix = stretchy:vertical fence:true lspace:.0em rspace:.0em # &VerticalBar;
+operator.\u2223.postfix = stretchy:vertical fence:true lspace:.0em rspace:.0em # &VerticalBar;
+operator.\u007C.prefix = stretchy:vertical fence:true lspace:.0em rspace:.0em # |
+operator.\u007C.postfix = stretchy:vertical fence:true lspace:.0em rspace:.0em # |
+operator.\u20D7.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &#x20D7;
+operator.\u20D6.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &#x20D6;
+operator.\u20E1.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &#x20E1;
+operator.\u20D1.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &#x20D1;
+operator.\u20D0.postfix = stretchy:horizontal accent:true lspace:0em rspace:0em # &#x20D0;
+operator.\u21A9.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &hookleftarrow; &larrhk;
+operator.\u21AA.infix = stretchy:horizontal lspace:thickmathspace rspace:thickmathspace # &hookrightarrow; &rarrhk;
+operator.\u23B0.prefix = stretchy:vertical fence:true lspace:0em rspace:0em # &lmoustache; &lmoust;
+operator.\u23B1.postfix = stretchy:vertical fence:true lspace:0em rspace:0em # &rmoustache; &rmoust;
+operator.\u22C5.infix = lspace:thinmathspace rspace:thinmathspace # &cdot;
+operator.\u2282.infix = lspace:thickmathspace rspace:thickmathspace # &subset;
+
+
+##################################################################################
+# DOCUMENTATION ON HOW TO SETUP THE PROPERTY FILE ASSOCIATED TO EACH FONT
+# More fonts can be supported for stretchy characters by setting up mathfont
+# property files as described below.
+#
+# Each font should have its set of glyph data. For example, the glyph data for
+# the "Symbol" font and the "MT Extra" font are in "mathfontSymbol.properties"
+# and "mathfontMTExtra.properties", respectively. The font property file is a
+# set of all the stretchy MathML characters that can be rendered with that font
+# using larger and/or partial glyphs. Each stretchy character is associated to
+# a list in the font property file which gives, in that order, the 4 partial
+# glyphs: top (or left), middle, bottom (or right), glue; and the variants of
+# bigger sizes (if any). A position that is not relevant to a particular character
+# is indicated there with the UNICODE REPLACEMENT CHARACTER 0xFFFD.
+#
+# Characters that need to be built from other characters are said to be composite.
+# For example, characters like over/underbrace in CMEX10 have to be built from two
+# half stretchy chars and joined in the middle (TeXbook, p.225). Several (i.e., 2
+# or more) child characters can be composed in order to render another chararacter.
+# To specify such characters, their list of glyphs in the property file should be
+# given as space-separated segments of glyphs. Each segment gives the 4 partial glyphs
+# with which to build the child character that will be joined with its other siblings.
diff --git a/bundles/XO/res/fonts/mathfontSTIXNonUnicode.properties b/bundles/XO/res/fonts/mathfontSTIXNonUnicode.properties
new file mode 100755
index 0000000..d461815
--- /dev/null
+++ b/bundles/XO/res/fonts/mathfontSTIXNonUnicode.properties
@@ -0,0 +1,101 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla MathML Project.
+#
+# The Initial Developer of the Original Code is
+# The University of Queensland.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Roger B. Sidje <rbs@maths.uq.edu.au>
+# Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# LOCALIZATION NOTE: FILE
+# Do not translate anything in this file
+
+# This file contains the list of some stretchy MathML chars that
+# can be rendered with STIXNonUnicode.
+
+external.1 = STIXGeneral
+
+# [ T/L | M | B/R | G | size0 ... size{N-1} ]
+# E0B4 stix-arrow hookleft
+# E0B5 stix-arrow hookright
+# E10B stix-extender for horizontal solid (normal) arrow
+# E10B in STIXNonUnicode is the same height as U+23AF in STIXGeneral but has a
+# different advance.
+\u21A9 = \u2190@1\uFFFD\uE0B5\uE10B # hookleftarrow, larrhk
+\u21AA = \uE0B4\uFFFD\u2192@1\uE10B # hookrightarrow, rarrhk
+
+# 0E10E stix-stix-extender for vertical double arrow
+# 0E10F stix-extender for horizontal double arrow
+\u21D0 = \u21D0@1\uFFFD\uFFFD\uE10F\uFFFD\u27F8@1 # DoubleLeftArrow, Leftarrow, lArr
+\u21D1 = \u21D1@1\uFFFD\uFFFD\uE10E # DoubleUpArrow, Uparrow, uArr
+\u21D2 = \uFFFD\uFFFD\u21D2@1\uE10F\uFFFD\u27F9@1 # DoubleRightArrow, Implies, Rightarrow, rArr
+\u21D3 = \uFFFD\uFFFD\u21D3@1\uE10E # DoubleDownArrow, Downarrow, dArr
+\u21D4 = \u21D0@1\uFFFD\u21D2@1\uE10F\uFFFD\u27FA@1 # DoubleLeftRightArrow, Leftrightarrow, hArr, iff
+\u21D5 = \u21D1@1\uFFFD\u21D3@1\uE10E # DoubleUpDownArrow, Updownarrow, vArr
+
+# STIXGeneral U+22A2/U+22A3 RIGHT/LEFT TACK are different heights to U+23AF.
+# Could use LONG RIGHT/LEFT TACK instead, but STIXNonUnicode provides
+# E0B6 stix-maps-to-relation tail
+\u21A4 = \u2190@1\uFFFD\uE0B6\uE10B\uFFFD\u27FB@1 # LeftTeeArrow, mapstoleft
+\u21A6 = \uE0B6\uFFFD\u2192@1\uE10B\uFFFD\u27FC@1 # RightTeeArrow, map, mapsto
+\u295A = \u21BC@1\uFFFD\uE0B6\uE10B # LeftTeeVector
+\u295B = \uE0B6\uFFFD\u21C0@1\uE10B # RIGHTWARDS HARPOON WITH BARB UP FROM BAR, RightTeeVector
+\u295E = \u21BD@1\uFFFD\uE0B6\uE10B # DownLeftTeeVector
+\u295F = \uE0B6\uFFFD\u21C1@1\uE10B # RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR, DownRightTeeVector
+
+# E13B stix-left end of extensible overbrace
+# E13C stix-right end of extensible overbrace
+# E13D stix-left end of extensible underbrace
+# E13E stix-right end of extensible underbrace
+# E13F stix-extensible horizontal for curly over and under braces
+# E140 stix-center of extensible overbrace
+# E141 stix-center of extensible underbrace
+# E13F is the wrong height for overbrace:
+# use E14A stix-extensible horizontal for over paren or square bracket
+# U+FE37 and U+FE38 are from the MathML 2.0 spec.
+\uFE37 = \uE13B\uE140\uE13C\uE14A # OverBrace
+\uFE38 = \uE13D\uE141\uE13E\uE13F # UnderBrace
+# Unicode added U+23DE and U+23DF:
+# http://www.unicode.org/reports/tr25/#_TocDelimiters
+\u23DE = \uE13B\uE140\uE13C\uE14A # OverBrace
+\u23DF = \uE13D\uE141\uE13E\uE13F # UnderBrace
+# TODO:
+# E142 stix-left end of extensible overparen (CMEX10 x40 rotated 90deg)
+# E143 stix-right end of extensible overparen (CMEX10 x30 rotated 90deg)
+# E144 stix-left end of extensible underparen (CMEX10 x41 rotated 90deg)
+# E145 stix-right end of extensible underparen (CMEX10 x31 rotated 90deg)
+# E146 stix-left end of extensible over square bracket (CMEX10 x34 rotated 90deg)
+# E147 stix-right end of extensible over square bracket (CMEX10 x32 rotated 90deg)
+# E148 stix-left end of extensible under square bracket (CMEX10 x35 rotated 90deg)
+# E149 stix-right end of extensible under square bracket (CMEX10 x33 rotated 90deg)
+# E14A stix-extensible horizontal for over paren or square bracket (CMEX10 x42 rotated 90deg)
+# E14B stix-extensible horizontal for under paren or square bracket
diff --git a/bundles/XO/res/fonts/mathfontSTIXSize1.properties b/bundles/XO/res/fonts/mathfontSTIXSize1.properties
new file mode 100755
index 0000000..ef368a2
--- /dev/null
+++ b/bundles/XO/res/fonts/mathfontSTIXSize1.properties
@@ -0,0 +1,64 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla MathML Project.
+#
+# The Initial Developer of the Original Code is
+# The University of Queensland.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Roger B. Sidje <rbs@maths.uq.edu.au>
+# Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# LOCALIZATION NOTE: FILE
+# Do not translate anything in this file
+
+# This file contains the list of some stretchy MathML chars that
+# can be rendered with STIXSize* set of fonts,
+# with some help from STIXNonUnicode.
+
+external.1 = STIXNonUnicode
+external.2 = STIXSize2
+external.3 = STIXSize3
+external.4 = STIXSize4
+external.5 = STIXSize5
+
+# [ T/L | M | B/R | G | size0 ... size{N-1} ]
+\u0028 = \u239B\uFFFD\u239D\u239C\uFFFD((@2(@3(@4 # (
+\u0029 = \u239E\uFFFD\u23A0\u239F\uFFFD))@2)@3)@4 # )
+\u005B = \u23A1\uFFFD\u23A3\u23A2\u005B[[@2[@3[@4 # [
+\u005D = \u23A4\uFFFD\u23A6\u23A5\u005D]]@2]@3]@4 # ]
+\u007B = \u23A7\u23A8\u23A9\u23AA\u007B{{@2{@3{@4 # {
+\u007D = \u23AB\u23AC\u23AD\u23AA\u007D}}@2}@3}@4 # }
+
+# E000 stix-radical symbol vertical extender
+# E001 stix-radical symbol top corner
+\u221A = \uE001@1\uFFFD\u221A@4\uE000@1\uFFFD\u221A\u221A@2\u221A@3 # Sqrt, radic
+
+\u222B = \u2320\uFFFD\u2321\u23AE\u222B # Integral, int
diff --git a/bundles/XO/res/fonts/mathfontStandardSymbolsL.properties b/bundles/XO/res/fonts/mathfontStandardSymbolsL.properties
new file mode 100755
index 0000000..8c9cbd7
--- /dev/null
+++ b/bundles/XO/res/fonts/mathfontStandardSymbolsL.properties
@@ -0,0 +1,77 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla MathML Project.
+#
+# The Initial Developer of the Original Code is
+# The University of Queensland.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Roger B. Sidje <rbs@maths.uq.edu.au>
+# Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# LOCALIZATION NOTE: FILE
+# Do not translate anything in this file
+
+# This file contains the list of all stretchy MathML chars that
+# can be rendered with Standard Symbols L.
+
+# [ T/L | M | B/R | G | size0 ... size{N-1} ]
+\u0028 = \uF8EB\uFFFD\uF8ED\uF8EC\u0028 # (
+\u0029 = \uF8F6\uFFFD\uF8F8\uF8F7\u0029 # )
+\u005B = \uF8EE\uFFFD\uF8F0\uF8EF\u005B # [
+\u005D = \uF8F9\uFFFD\uF8FB\uF8FA\u005D # ]
+\u007B = \uF8F1\uF8F2\uF8F3\uF8F4\u007B # {
+\u007C = \uFFFD\uFFFD\uFFFD\u007C\u007C # |
+\u007D = \uF8FC\uF8FD\uF8FE\uF8F4\u007D # }
+
+\u00AF = \uFFFD\uFFFD\uFFFD\uF8E5\u00AF # ad-hoc: overbar is stretched with the radical extender
+\u0332 = \uFFFD\uFFFD\uFFFD\u005F\u0332 # ad-hock: UnderBar (0x0332) is stretched with underscore
+
+\u2190 = \u2190\uFFFD\uFFFD\uF8E7\u2190 # LeftArrow, larr, leftarrow
+\u2191 = \u2191\uFFFD\uFFFD\uF8E6\u2191 # UpArrow, uarr, uparrow
+\u2192 = \uFFFD\uFFFD\u2192\uF8E7\u2192 # RightArrow, rarr, rightarrow
+\u2193 = \uFFFD\uFFFD\u2193\uF8E6\u2193 # DownArrow, darr, downarrow
+\u2194 = \u2190\uFFFD\u2192\uF8E7\u2194 # LeftRightArrow, harr, leftrightarrow
+\u2195 = \u2191\uFFFD\u2193\uF8E6\u2195 # UpDownArrow, updownarrow, varr
+
+\u222B = \u2320\uFFFD\u2321\uF8F5\u222B # Integral, int
+# If there are problems with the font-supplied glue use a rule:
+# \u222B = \u2320\uFFFD\u2321\uFFFD\u222B # Integral, int
+
+# Using parts of [ and ]
+\u2308 = \uF8EE\uFFFD\uFFFD\uF8EF\u2308 # LeftCeiling, lceil
+\u2309 = \uF8F9\uFFFD\uFFFD\uF8FA\u2309 # RightCeiling, rceil
+\u230A = \uFFFD\uFFFD\uF8F0\uF8EF\u230A # LeftFloor, lfloor
+\u230B = \uFFFD\uFFFD\uF8FB\uF8FA\u230B # RightFloor, rfloor
+
+# same as normal arrows
+\u27F5 = \u2190\uFFFD\uFFFD\uF8E7\u27F5 # LongLeftArrow
+\u27F6 = \uFFFD\uFFFD\u2192\uF8E7\u27F6 # LongRightArrow
+\u27F7 = \u2190\uFFFD\u2192\uF8E7\u27F7 # LongLeftRightArrow
diff --git a/bundles/XO/res/fonts/mathfontUnicode.properties b/bundles/XO/res/fonts/mathfontUnicode.properties
new file mode 100755
index 0000000..5afd524
--- /dev/null
+++ b/bundles/XO/res/fonts/mathfontUnicode.properties
@@ -0,0 +1,123 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla MathML Project.
+#
+# The Initial Developer of the Original Code is
+# The University of Queensland.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Roger B. Sidje <rbs@maths.uq.edu.au>
+# Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+# LOCALIZATION NOTE: FILE
+# Do not translate anything in this file
+
+# This file contains the list of all stretchy MathML chars that
+# can be rendered using only Unicode code points.
+
+# [ T/L | M | B/R | G | size0 ... size{N-1} ]
+\u0028 = \u239B\uFFFD\u239D\u239C\u0028 # (
+\u0029 = \u239E\uFFFD\u23A0\u239F\u0029 # )
+\u005B = \u23A1\uFFFD\u23A3\u23A2\u005B # [
+\u005D = \u23A4\uFFFD\u23A6\u23A5\u005D # ]
+\u007B = \u23A7\u23A8\u23A9\u23AA\u007B # {
+\u007C = \uFFFD\uFFFD\uFFFD\u007C\u007C # |
+\u007D = \u23AB\u23AC\u23AD\u23AA\u007D # }
+
+# OverBar is stretched with U+0305 COMBINING OVERLINE which "connects on left and right"
+\u00AF = \uFFFD\uFFFD\uFFFD\u0305\u00AF # OverBar
+#\u0305 doesn't appear to be referenced by the MathML spec
+\u0332 = \uFFFD\uFFFD\uFFFD\u0332\u0332 # COMBINING LOW LINE, UnderBar
+
+\u2016 = \uFFFD\uFFFD\uFFFD\u2016\u2016 # DOUBLE VERTICAL LINE, Vert, Verbar
+
+\u2190 = \u2190\uFFFD\uFFFD\u23AF\u2190\u27F5 # LeftArrow, larr, leftarrow
+\u2191 = \u2191\uFFFD\uFFFD\u23D0\u2191 # UpArrow, uarr, uparrow
+\u2192 = \uFFFD\uFFFD\u2192\u23AF\u2192\u27F6 # RightArrow, rarr, rightarrow
+\u2193 = \uFFFD\uFFFD\u2193\u23D0\u2193 # DownArrow, darr, downarrow
+\u2194 = \u2190\uFFFD\u2192\u23AF\u2194\u27F7 # LeftRightArrow, harr, leftrightarrow
+\u2195 = \u2191\uFFFD\u2193\u23D0\u2195 # UpDownArrow, updownarrow, varr
+
+# For STIXGeneral U+22A2/U+22A3 RIGHT/LEFT TACK are different heights to U+23AF.
+# Could use LONG RIGHT/LEFT TACK instead, but STIXNonUnicode provides
+# E0B6 stix-maps-to-relation tail
+#\u21A4 = \u2190\uFFFD\u27DE\u23AF\u21A6\u27FB # LeftTeeArrow, mapstoleft
+#\u21A6 = \u27DD\uFFFD\u2192\u23AF\u21A6\u27FC # RightTeeArrow, map, mapsto
+#\u295A = \u21BC\uFFFD\u27DE\u23AF\u295A # LeftTeeVector
+#\u295B = \u27DD\uFFFD\u21C0\u23AF\u295B # RIGHTWARDS HARPOON WITH BARB UP FROM BAR, RightTeeVector
+#\u295E = \u21BD\uFFFD\u27DE\u23AF\u295E # DownLeftTeeVector
+#\u295F = \u27DD\uFFFD\u21C1\u23AF\u295F # RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR, DownRightTeeVector
+# Cambria Math does not have U+27DD/U+27DE
+\u21A4 = \u2190\uFFFD\u22A3\u23AF\u21A6\u27FB # LeftTeeArrow, mapstoleft
+\u21A6 = \u22A2\uFFFD\u2192\u23AF\u21A6\u27FC # RightTeeArrow, map, mapsto
+\u295A = \u21BC\uFFFD\u22A3\u23AF\u295A # LeftTeeVector
+\u295B = \u22A2\uFFFD\u21C0\u23AF\u295B # RIGHTWARDS HARPOON WITH BARB UP FROM BAR, RightTeeVector
+\u295E = \u21BD\uFFFD\u22A3\u23AF\u295E # DownLeftTeeVector
+\u295F = \u22A2\uFFFD\u21C1\u23AF\u295F # RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR, DownRightTeeVector
+
+\u21C0 = \uFFFD\uFFFD\u21C0\u23AF\u21C0 # RightVector, rharu, rightharpoonup
+\u21C1 = \uFFFD\uFFFD\u21C1\u23AF\u21C1 # DownRightVector, rhard, rightharpoon down
+\u21BC = \u21BC\uFFFD\uFFFD\u23AF\u21BC # LeftVector, leftharpoonup, lharu
+\u21BD = \u21BD\uFFFD\uFFFD\u23AF\u21BD # DownLeftVector, leftharpoondown, lhard
+\u21D0 = \uFFFD\uFFFD\uFFFD\uFFFD\u21D0\u27F8 # DoubleLeftArrow, Leftarrow, lArr
+\u21D2 = \uFFFD\uFFFD\uFFFD\uFFFD\u21D2\u27F9 # DoubleRightArrow, Implies, Rightarro
+\u21D4 = \uFFFD\uFFFD\uFFFD\uFFFD\u21D4\u27FA # DoubleLeftRightArrow, Leftrightarrow, hArr, iff
+
+# \u221A radical may be made from RADICAL SYMBOL BOTTOM U+23B7 but few fonts
+# support this character and it is not clear what the appropriate vertical
+# glue whould be.
+
+\u2223 = \uFFFD\uFFFD\uFFFD\u2223\u2223 # VerticalBar, mid
+\u2225 = \uFFFD\uFFFD\uFFFD\u2225\u2225 # DoubleVerticalBar, par, parallel
+
+# If fonts have U+23AE INTEGRAL EXTENSION:
+# (STIXSize1, Cambria Math, DejaVu Sans/Serif, Apple's Symbol)
+\u222B = \u2320\uFFFD\u2321\u23AE\u222B # Integral, int
+# Many fonts don't have U+23AE. For these fonts, a rule can be used as glue:
+# \u222B = \u2320\uFFFD\u2321\uFFFD\u222B # Integral, int
+
+# Using parts of [ and ] (could use box drawings instead)
+\u2308 = \u23A1\uFFFD\uFFFD\u23A2\u2308 # LeftCeiling, lceil
+\u2309 = \u23A4\uFFFD\uFFFD\u23A5\u2309 # RightCeiling, rceil
+\u230A = \uFFFD\uFFFD\u23A3\u23A2\u230A # LeftFloor, lfloor
+\u230B = \uFFFD\uFFFD\u23A6\u23A5\u230B # RightFloor, rfloor
+
+# Support for l/r moustache from the parts of lbrace { and rbrace }
+\u23B0 = \u23A7\uFFFD\u23AD\u23AA\u23B0 # lmoustache, lmoust
+\u23B1 = \u23AB\uFFFD\u23A9\u23AA\u23B1 # rmoustache, rmoust
+
+# Using normal arrows as heads instead of long arrows for the sake of
+# Apple's Symbol font.
+\u27F5 = \u2190\uFFFD\uFFFD\u23AF\u27F5 # LongLeftArrow
+\u27F6 = \uFFFD\uFFFD\u2192\u23AF\u27F6 # LongRightArrow
+\u27F7 = \u2190\uFFFD\u2192\u23AF\u27F7 # LongLeftRightArrow
+
+\u294E = \u21BC\uFFFD\u21C0\u23AF\u294E #LEFT BARB UP RIGHT BARB UP HARPOON, LeftRightVector
+\u2950 = \u21BD\uFFFD\u21C1\u23AF\u2950 #LEFT BARB DOWN RIGHT BARB DOWN HARPOON , DownLeftRightVector
diff --git a/bundles/XO/res/forms.css b/bundles/XO/res/forms.css
new file mode 100755
index 0000000..a90057d
--- /dev/null
+++ b/bundles/XO/res/forms.css
@@ -0,0 +1,592 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ Styles for old GFX form widgets
+ **/
+
+
+@namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
+@namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
+
+*|*::-moz-fieldset-content {
+ display: block;
+ height: 100%; /* Need this so percentage heights of kids work right */
+}
+
+/* miscellaneous form elements */
+
+legend {
+ padding-left: 2px;
+ padding-right: 2px;
+ border: none;
+ position: static ! important;
+ float: none ! important;
+ width: -moz-fit-content ! important;
+ min-width: 0 ! important;
+ max-width: none ! important;
+ height: auto ! important;
+ min-height: 0 ! important;
+ max-height: none ! important;
+ white-space: nowrap;
+}
+
+fieldset {
+ display: block;
+ margin-left: 2px;
+ margin-right: 2px;
+ padding: 0.35em 0.625em 0.75em;
+ border: 2px groove ThreeDFace;
+}
+
+label {
+ cursor: default;
+}
+
+/* default inputs, text inputs, and selects */
+
+/* Note: Values in nsNativeTheme IsWidgetStyled function
+ need to match textfield background/border values here */
+
+input {
+ -moz-appearance: textfield;
+ /* The sum of border-top, border-bottom, padding-top, padding-bottom
+ must be the same here, for buttons, and for <select> (including its
+ internal padding magic) */
+ padding: 1px 0 1px 0;
+ border: 2px inset ThreeDFace;
+ background-color: -moz-Field;
+ color: -moz-FieldText;
+ font: -moz-field;
+ text-rendering: optimizeLegibility;
+ line-height: normal !important;
+ text-align: start;
+ text-transform: none;
+ word-spacing: normal;
+ letter-spacing: normal;
+ cursor: text;
+ -moz-binding: url("chrome://global/content/platformHTMLBindings.xml#inputFields");
+ text-indent: 0;
+ -moz-user-select: text;
+ text-shadow: none;
+}
+
+input > .anonymous-div {
+ white-space: pre;
+ word-wrap: normal !important;
+}
+
+textarea {
+ margin: 1px 0 1px 0;
+ border: 2px inset ThreeDFace;
+ background-color: -moz-Field;
+ color: -moz-FieldText;
+ font: medium -moz-fixed;
+ text-rendering: optimizeLegibility;
+ text-align: start;
+ text-transform: none;
+ word-spacing: normal;
+ letter-spacing: normal;
+ vertical-align: text-bottom;
+ cursor: text;
+ -moz-binding: url("chrome://global/content/platformHTMLBindings.xml#textAreas");
+ -moz-appearance: textfield-multiline;
+ text-indent: 0;
+ -moz-user-select: text;
+ text-shadow: none;
+ word-wrap: break-word;
+}
+
+textarea > scrollbar {
+ cursor: default;
+}
+
+textarea > .anonymous-div,
+input > .anonymous-div {
+ overflow: auto;
+ border: 0px !important;
+ /* The 1px horizontal padding is for parity with Win/IE */
+ padding: 0px 1px;
+ margin: 0px;
+ /* XXXldb I'm not sure if we really want the 'text-decoration: inherit',
+ but it's needed to make 'text-decoration' "work" on text inputs. */
+ text-decoration: inherit;
+ ime-mode: inherit;
+}
+
+input:-moz-read-write,
+textarea:-moz-read-write {
+ -moz-user-modify: read-write !important;
+}
+
+select {
+ margin: 0;
+ border-color: ThreeDFace;
+ background-color: -moz-Field;
+ color: -moz-FieldText;
+ font: -moz-list;
+ line-height: normal !important;
+ white-space: nowrap !important;
+ word-wrap: normal !important;
+ text-align: start;
+ cursor: default;
+ -moz-box-sizing: border-box;
+ -moz-user-select: none;
+ -moz-appearance: menulist;
+ border-width: 2px;
+ border-style: inset;
+ text-indent: 0;
+ overflow: -moz-hidden-unscrollable;
+ text-shadow: none;
+}
+
+/* Need the "select[size][multiple]" selector to override the settings on
+ 'select[size="1"]', eg if one has <select size="1" multiple> */
+
+select[size],
+select[multiple],
+select[size][multiple] {
+ /* Different alignment and padding for listbox vs combobox */
+ vertical-align: text-bottom;
+ padding: 1px 0 1px 0;
+ -moz-appearance: listbox;
+}
+
+select[size="0"],
+select[size="1"] {
+ /* Except this is not a listbox */
+ vertical-align: baseline;
+ padding: 0;
+ -moz-appearance: menulist;
+}
+
+select > input[type="button"] {
+ width: 12px;
+ height: 12px;
+ white-space: nowrap;
+ position: static !important;
+ background-image: url("arrow.gif") !important;
+ background-repeat: no-repeat !important;
+ background-position: center !important;
+ -moz-appearance: menulist-button;
+
+ /* Make sure to size correctly if the combobox has a non-auto height. */
+ height: 100% ! important;
+ -moz-box-sizing: border-box ! important;
+
+ /*
+ Make sure to align properly with the display frame. Note that we
+ want the baseline of the combobox to match the baseline of the
+ display frame, so the dropmarker is what gets the vertical-align.
+ */
+ vertical-align: top !important;
+}
+
+select > input[type="button"]:active {
+ background-image: url("arrowd.gif") !important;
+}
+
+select:empty {
+ width: 2.5em;
+}
+
+*|*::-moz-display-comboboxcontrol-frame {
+ overflow: -moz-hidden-unscrollable;
+ /* This top/bottom padding plus the combobox top/bottom border need to
+ add up to the top/bottom borderpadding of text inputs and buttons */
+ padding-top: 1px;
+ padding-bottom: 1px;
+ -moz-padding-start: 4px;
+ -moz-padding-end: 0;
+ background-color: inherit;
+ color: inherit;
+ white-space: nowrap;
+ text-align: inherit;
+ -moz-user-select: none;
+ /* Make sure to size correctly if the combobox has a non-auto height. */
+ height: 100% ! important;
+ -moz-box-sizing: border-box ! important;
+}
+
+select::-moz-scrolled-content {
+ display: block !important;
+}
+
+option {
+ display: block;
+ float: none !important;
+ position: static !important;
+ min-height: 1em;
+ line-height: normal !important;
+ -moz-user-select: none;
+ text-indent: 0;
+ white-space: nowrap !important;
+ word-wrap: normal !important;
+}
+
+select > option {
+ padding-top : 0;
+ padding-bottom: 0;
+ -moz-padding-start: 3px;
+ -moz-padding-end: 5px;
+}
+
+option:checked {
+ background-color: -moz-html-cellhighlight !important;
+ color: -moz-html-cellhighlighttext !important;
+}
+
+select:focus > option:checked,
+select:focus > optgroup > option:checked {
+ background-color: Highlight ! important;
+ color: HighlightText ! important;
+}
+
+optgroup {
+ display: block;
+ float: none !important;
+ position: static !important;
+ font: -moz-list;
+ line-height: normal !important;
+ font-style: italic;
+ font-weight: bold;
+ font-size: inherit;
+ -moz-user-select: none;
+ text-indent: 0;
+ white-space: nowrap !important;
+ word-wrap: normal !important;
+}
+
+optgroup > option {
+ -moz-padding-start: 20px;
+ font-style: normal;
+ font-weight: normal;
+}
+
+optgroup:before {
+ display: block;
+ content: attr(label);
+}
+
+*|*::-moz-dropdown-list {
+ z-index: 2147483647;
+ background-color: inherit;
+ -moz-user-select: none;
+ position: static !important;
+ float: none !important;
+
+ /*
+ * We can't change the padding here, because that would affect our
+ * intrinsic width, since we scroll. But at the same time, we want
+ * to make sure that our left border+padding matches the left
+ * border+padding of a combobox so that our scrollbar will line up
+ * with the dropmarker. So set our left border to 2px.
+ */
+ border: 1px outset black !important;
+ border-left-width: 2px ! important;
+}
+
+input[disabled],
+textarea[disabled],
+option[disabled],
+optgroup[disabled],
+select[disabled] {
+ -moz-user-input: disabled;
+ -moz-user-focus: ignore;
+ color: GrayText;
+ background-color: ThreeDFace;
+ cursor: inherit;
+}
+
+option[disabled],
+optgroup[disabled] {
+ background-color: transparent;
+}
+
+/* hidden inputs */
+input[type="hidden"] {
+ -moz-appearance: none;
+ display: none;
+ padding: 0;
+ border: 0;
+ cursor: auto;
+ -moz-user-focus: ignore;
+ -moz-binding: none;
+}
+
+/* image buttons */
+input[type="image"] {
+ -moz-appearance: none;
+ padding: 0;
+ border: none;
+ background-color: transparent;
+ font-family: sans-serif;
+ font-size: small;
+ cursor: pointer;
+ -moz-binding: none;
+}
+
+input[type="image"][disabled] {
+ cursor: inherit;
+}
+
+input[type="image"]:focus {
+ /* Don't specify the outline-color, we should always use initial value. */
+ outline: 1px dotted;
+}
+
+/* file selector */
+input[type="file"] {
+ -moz-appearance: none;
+ white-space: nowrap;
+ cursor: default;
+ -moz-binding: none;
+
+ padding: 0 !important;
+ border-style: none !important;
+}
+
+input[type="file"] > input[type="text"] {
+ border-color: inherit;
+ background-color: inherit;
+ color: inherit;
+ font-size: inherit;
+ letter-spacing: inherit;
+}
+
+/* button part of file selector */
+input[type="file"] > input[type="button"] {
+ height: inherit;
+ font-size: inherit;
+ letter-spacing: inherit;
+}
+
+/* radio buttons */
+input[type="radio"] {
+ -moz-appearance: radio;
+ margin: 3px 3px 0px 5px;
+ -moz-border-radius: 100% !important;
+}
+
+/* check boxes */
+input[type="checkbox"] {
+ -moz-appearance: checkbox;
+ margin: 3px 3px 3px 4px;
+ -moz-border-radius: 0 !important;
+}
+
+/* common features of radio buttons and check boxes */
+
+/* NOTE: The width, height, border-width, and padding here must all
+ add up the way nsFormControlFrame::GetIntrinsic(Width|Height)
+ expects them to, or they will not come out with total width equal
+ to total height on sites that set their 'width' or 'height' to 'auto'.
+ (Should we maybe set !important on width and height, then?) */
+input[type="radio"],
+input[type="checkbox"] {
+ -moz-box-sizing: border-box;
+ width: 13px;
+ height: 13px;
+ cursor: default;
+ padding: 0 !important;
+ -moz-binding: none;
+ /* same colors as |input| rule, but |!important| this time. */
+ background-color: -moz-Field ! important;
+ color: -moz-FieldText ! important;
+ border: 2px inset ThreeDFace ! important;
+}
+
+input[type="radio"][disabled],
+input[type="radio"][disabled]:active,
+input[type="radio"][disabled]:hover,
+input[type="radio"][disabled]:hover:active,
+input[type="checkbox"][disabled],
+input[type="checkbox"][disabled]:active,
+input[type="checkbox"][disabled]:hover,
+input[type="checkbox"][disabled]:hover:active {
+ padding: 1px;
+ border: 1px inset ThreeDShadow ! important;
+ /* same as above, but !important */
+ color: GrayText ! important;
+ background-color: ThreeDFace ! important;
+ cursor: inherit;
+}
+
+input[type="checkbox"]:focus,
+input[type="radio"]:focus {
+ border-style: groove !important;
+}
+
+input[type="checkbox"]:hover:active,
+input[type="radio"]:hover:active {
+ background-color: ThreeDFace ! important;
+ border-style: inset !important;
+}
+
+/* buttons */
+
+/* Note: Values in nsNativeTheme IsWidgetStyled function
+ need to match button background/border values here */
+
+button,
+input[type="reset"],
+input[type="button"],
+input[type="submit"] {
+ -moz-appearance: button;
+ /* The sum of border-top, border-bottom, padding-top, padding-bottom
+ must be the same here, for text inputs, and for <select>. For
+ buttons, make sure to include the -moz-focus-inner border/padding. */
+ padding: 0px 6px 0px 6px;
+ border: 2px outset ButtonFace;
+ background-color: ButtonFace;
+ color: ButtonText;
+ font: -moz-button;
+ line-height: normal !important;
+ white-space: pre;
+ cursor: default;
+ -moz-box-sizing: border-box;
+ -moz-user-select: none;
+ -moz-binding: none;
+ text-align: center;
+ text-shadow: none;
+}
+
+button {
+ /* Buttons should lay out like "normal" html, mostly */
+ white-space: inherit;
+ text-indent: 0;
+}
+
+*|*::-moz-button-content {
+ display: block;
+}
+
+button:hover,
+input[type="reset"]:hover,
+input[type="button"]:hover,
+input[type="submit"]:hover {
+ background-color: -moz-buttonhoverface;
+ color: -moz-buttonhovertext;
+}
+
+button:active:hover,
+input[type="reset"]:active:hover,
+input[type="button"]:active:hover,
+input[type="submit"]:active:hover {
+ padding: 0px 5px 0px 7px;
+ border-style: inset;
+ background-color: ButtonFace;
+ color: ButtonText;
+}
+
+button::-moz-focus-inner,
+input[type="reset"]::-moz-focus-inner,
+input[type="button"]::-moz-focus-inner,
+input[type="submit"]::-moz-focus-inner,
+input[type="file"] > input[type="button"]::-moz-focus-inner {
+ padding: 0px 2px 0px 2px;
+ border: 1px dotted transparent;
+}
+
+button:focus::-moz-focus-inner,
+input[type="reset"]:focus::-moz-focus-inner,
+input[type="button"]:focus::-moz-focus-inner,
+input[type="submit"]:focus::-moz-focus-inner,
+input[type="file"] > input[type="button"]:focus::-moz-focus-inner {
+ border-color: ButtonText;
+}
+
+button[disabled]:active, button[disabled],
+input[type="reset"][disabled]:active,
+input[type="reset"][disabled],
+input[type="button"][disabled]:active,
+input[type="button"][disabled],
+select[disabled] > input[type="button"],
+select[disabled] > input[type="button"]:active,
+input[type="submit"][disabled]:active,
+input[type="submit"][disabled] {
+ /* The sum of border-top, border-bottom, padding-top, padding-bottom
+ must be the same here and for text inputs */
+ padding: 0px 6px 0px 6px;
+ border: 2px outset ButtonFace;
+ color: GrayText;
+ cursor: inherit;
+}
+
+ /*
+ * Make form controls inherit 'unicode-bidi' transparently as required by
+ * their various anonymous descendants and pseudo-elements:
+ *
+ * <textarea> and <input type="text">:
+ * inherit into the XULScroll frame with class 'anonymous-div' which is a
+ * child of the text control.
+ *
+ * Buttons (either <button>, <input type="submit">, <input type="button">
+ * or <input type="reset">)
+ * inherit into the ':-moz-button-content' pseudo-element.
+ *
+ * <select>:
+ * inherit into the ':-moz-display-comboboxcontrol-frame' pseudo-element and
+ * the <optgroup>'s ':before' pseudo-element, which is where the label of
+ * the <optgroup> gets displayed. The <option>s don't use anonymous boxes,
+ * so they need no special rules.
+ */
+textarea > .anonymous-div,
+input > .anonymous-div,
+*|*::-moz-button-content,
+*|*::-moz-display-comboboxcontrol-frame,
+optgroup:before {
+ unicode-bidi: inherit;
+}
+
+ /*
+ * Force the text control child of file input controls to have left-to-right
+ * directionality. Otherwise filenames containing right-to-left characters
+ * will be reordered with chaotic results.
+ */
+input[type="file"] > input[type="text"] {
+ direction: ltr !important;
+ text-align: inherit;
+}
+
+@media print {
+ input, textarea, select, button {
+ -moz-user-input: none !important;
+ }
+
+ input[type="file"] { height: 2em; }
+}
+
diff --git a/bundles/XO/res/grabber.gif b/bundles/XO/res/grabber.gif
new file mode 100755
index 0000000..06749a6
--- /dev/null
+++ b/bundles/XO/res/grabber.gif
Binary files differ
diff --git a/bundles/XO/res/hiddenWindow.html b/bundles/XO/res/hiddenWindow.html
new file mode 100755
index 0000000..f045a79
--- /dev/null
+++ b/bundles/XO/res/hiddenWindow.html
@@ -0,0 +1 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title></title></head><body></body></html> \ No newline at end of file
diff --git a/bundles/XO/res/html.css b/bundles/XO/res/html.css
new file mode 100755
index 0000000..fd23037
--- /dev/null
+++ b/bundles/XO/res/html.css
@@ -0,0 +1,526 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Blake Ross <BlakeR1234@aol.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+@namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
+@namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
+
+/* bidi */
+
+[dir="rtl"] {
+ direction: rtl;
+ unicode-bidi: embed;
+}
+[dir="ltr"] {
+ direction: ltr;
+ unicode-bidi: embed;
+}
+bdo[dir] {
+ unicode-bidi: bidi-override;
+}
+
+/* blocks */
+
+html, div, map, dt, isindex, form {
+ display: block;
+}
+
+body {
+ display: block;
+ margin: 8px;
+}
+
+p, dl, multicol {
+ display: block;
+ margin: 1em 0;
+}
+
+dd {
+ display: block;
+ -moz-margin-start: 40px;
+}
+
+blockquote {
+ display: block;
+ margin: 1em 40px;
+}
+
+address {
+ display: block;
+ font-style: italic;
+}
+
+center {
+ display: block;
+ text-align: -moz-center;
+}
+
+blockquote[type=cite] {
+ display: block;
+ margin: 1em 0px;
+ -moz-padding-start: 1em;
+ -moz-border-start: solid;
+ border-color: blue;
+ border-width: thin;
+}
+
+span[_moz_quote=true] {
+ color: blue;
+}
+
+pre[_moz_quote=true] {
+ color: blue;
+}
+
+h1 {
+ display: block;
+ font-size: 2em;
+ font-weight: bold;
+ margin: .67em 0;
+}
+
+h2 {
+ display: block;
+ font-size: 1.5em;
+ font-weight: bold;
+ margin: .83em 0;
+}
+
+h3 {
+ display: block;
+ font-size: 1.17em;
+ font-weight: bold;
+ margin: 1em 0;
+}
+
+h4 {
+ display: block;
+ font-weight: bold;
+ margin: 1.33em 0;
+}
+
+h5 {
+ display: block;
+ font-size: 0.83em;
+ font-weight: bold;
+ margin: 1.67em 0;
+}
+
+h6 {
+ display: block;
+ font-size: 0.67em;
+ font-weight: bold;
+ margin: 2.33em 0;
+}
+
+listing {
+ display: block;
+ font-family: -moz-fixed;
+ font-size: medium;
+ white-space: pre;
+ margin: 1em 0;
+}
+
+xmp, pre, plaintext {
+ display: block;
+ font-family: -moz-fixed;
+ white-space: pre;
+ margin: 1em 0;
+}
+
+/* tables */
+
+table {
+ display: table;
+ border-spacing: 2px;
+ border-collapse: separate;
+ margin-top: 0;
+ margin-bottom: 0;
+ /* XXXldb do we want this if we're border-collapse:collapse ? */
+ -moz-box-sizing: border-box;
+ text-indent: 0;
+}
+
+table[align="left"] {
+ float: left;
+}
+
+table[align="right"] {
+ float: right;
+ text-align: start;
+}
+
+table[rules]:not([rules="none"]) {
+ border-collapse: collapse;
+}
+
+/* caption inherits from table not table-outer */
+caption {
+ display: table-caption;
+ text-align: center;
+ -moz-box-sizing: border-box;
+}
+
+table[align="center"] > caption {
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table[align="center"] > caption[align="left"] {
+ margin-right: 0;
+}
+
+table[align="center"] > caption[align="right"] {
+ margin-left: 0;
+}
+
+tr {
+ display: table-row;
+ vertical-align: inherit;
+}
+
+col {
+ display: table-column;
+}
+
+colgroup {
+ display: table-column-group;
+}
+
+tbody {
+ display: table-row-group;
+ vertical-align: middle;
+}
+
+thead {
+ display: table-header-group;
+ vertical-align: middle;
+}
+
+tfoot {
+ display: table-footer-group;
+ vertical-align: middle;
+}
+
+/* for XHTML tables without tbody */
+table > tr {
+ vertical-align: middle;
+}
+
+td {
+ display: table-cell;
+ vertical-align: inherit;
+ text-align: inherit;
+ padding: 1px;
+}
+
+th {
+ display: table-cell;
+ vertical-align: inherit;
+ font-weight: bold;
+ padding: 1px;
+}
+
+tr > form:-moz-is-html, tbody > form:-moz-is-html,
+thead > form:-moz-is-html, tfoot > form:-moz-is-html,
+table > form:-moz-is-html {
+ /* Important: don't show these forms in HTML */
+ display: none !important;
+}
+
+/* inlines */
+
+q:before {
+ content: open-quote;
+}
+
+q:after {
+ content: close-quote;
+}
+
+b, strong {
+ font-weight: bolder;
+}
+
+i, cite, em, var, dfn {
+ font-style: italic;
+}
+
+tt, code, kbd, samp {
+ font-family: -moz-fixed;
+}
+
+u, ins {
+ text-decoration: underline;
+}
+
+s, strike, del {
+ text-decoration: line-through;
+}
+
+blink {
+ text-decoration: blink;
+}
+
+big {
+ font-size: larger;
+}
+
+small {
+ font-size: smaller;
+}
+
+sub {
+ vertical-align: sub;
+ font-size: smaller;
+ line-height: normal;
+}
+
+sup {
+ vertical-align: super;
+ font-size: smaller;
+ line-height: normal;
+}
+
+nobr {
+ white-space: nowrap;
+}
+
+/* titles */
+abbr[title], acronym[title] {
+ border-bottom: dotted 1px;
+}
+
+/* lists */
+
+ul, menu, dir {
+ display: block;
+ list-style-type: disc;
+ margin: 1em 0;
+ -moz-padding-start: 40px;
+}
+
+ol {
+ display: block;
+ list-style-type: decimal;
+ margin: 1em 0;
+ -moz-padding-start: 40px;
+}
+
+li {
+ display: list-item;
+}
+
+/* nested lists have no top/bottom margins */
+ul ul, ul ol, ul dir, ul menu, ul dl,
+ol ul, ol ol, ol dir, ol menu, ol dl,
+dir ul, dir ol, dir dir, dir menu, dir dl,
+menu ul, menu ol, menu dir, menu menu, menu dl,
+dl ul, dl ol, dl dir, dl menu, dl dl {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+/* 2 deep unordered lists use a circle */
+ol ul, ul ul, menu ul, dir ul,
+ol menu, ul menu, menu menu, dir menu,
+ol dir, ul dir, menu dir, dir dir {
+ list-style-type: circle;
+}
+
+/* 3 deep (or more) unordered lists use a square */
+ol ol ul, ol ul ul, ol menu ul, ol dir ul,
+ol ol menu, ol ul menu, ol menu menu, ol dir menu,
+ol ol dir, ol ul dir, ol menu dir, ol dir dir,
+ul ol ul, ul ul ul, ul menu ul, ul dir ul,
+ul ol menu, ul ul menu, ul menu menu, ul dir menu,
+ul ol dir, ul ul dir, ul menu dir, ul dir dir,
+menu ol ul, menu ul ul, menu menu ul, menu dir ul,
+menu ol menu, menu ul menu, menu menu menu, menu dir menu,
+menu ol dir, menu ul dir, menu menu dir, menu dir dir,
+dir ol ul, dir ul ul, dir menu ul, dir dir ul,
+dir ol menu, dir ul menu, dir menu menu, dir dir menu,
+dir ol dir, dir ul dir, dir menu dir, dir dir dir {
+ list-style-type: square;
+}
+
+
+/* leafs */
+
+/* <hr> noshade and color attributes are handled completely by
+ * the nsHTMLHRElement attribute mapping code
+ */
+hr {
+ display: block;
+ height: 2px;
+ border: 1px inset;
+ margin: 0.5em auto 0.5em auto;
+ color: gray;
+ -moz-float-edge: margin-box;
+ -moz-box-sizing: border-box;
+}
+
+hr[size="1"] {
+ border-style: solid none none none;
+}
+
+*|*:-moz-any-link img, img[usemap], object[usemap] {
+ border: 2px solid;
+}
+
+img:-moz-broken::before, input:-moz-broken::before,
+img:-moz-user-disabled::before, input:-moz-user-disabled::before,
+img:-moz-loading::before, input:-moz-loading::before,
+applet:-moz-empty-except-children-with-localname(param):-moz-broken::before,
+applet:-moz-empty-except-children-with-localname(param):-moz-user-disabled::before {
+ content: -moz-alt-content !important;
+ unicode-bidi: embed;
+}
+
+object:-moz-broken > *|*, applet:-moz-broken > *|*
+object:-moz-user-disabled > *|*, applet:-moz-user-disabled > *|* {
+ /*
+ Inherit in the object's alignment so that if we aren't aligned explicitly
+ we'll end up in the right place vertically. See bug 36997. Note that this
+ is not !important because we _might_ be aligned explicitly.
+ */
+ vertical-align: inherit;
+}
+
+img:-moz-suppressed, input:-moz-suppressed, object:-moz-suppressed,
+embed:-moz-suppressed, applet:-moz-suppressed {
+ /*
+ Set visibility too in case the page changes display. Note that we _may_
+ want to just set visibility and not display, in general, if we find that
+ display:none breaks too many layouts. And if we decide we really do want
+ people to be able to right-click blocked images, etc, we need to set
+ neither one, and hack the painting code.... :(
+ */
+ display: none !important;
+ visibility: hidden !important;
+}
+
+img[usemap], object[usemap] {
+ color: blue;
+}
+
+frameset {
+ display: block ! important;
+ overflow: -moz-hidden-unscrollable;
+ position: static ! important;
+ float: none ! important;
+ border: none ! important;
+}
+
+frame {
+ border: none ! important;
+}
+
+iframe {
+ border: 2px inset;
+}
+
+noframes {
+ display: none;
+}
+
+spacer {
+ position: static ! important;
+ float: none ! important;
+}
+
+canvas {
+ -moz-user-select: none;
+}
+
+/* focusable content: anything w/ tabindex >=0 is focusable */
+abbr:focus, acronym:focus, address:focus, applet:focus, b:focus,
+base:focus, big:focus, blockquote:focus, br:focus, canvas:focus, caption:focus,
+center:focus, cite:focus, code:focus, col:focus, colgroup:focus, dd:focus,
+del:focus, dfn:focus, dir:focus, div:focus, dl:focus, dt:focus, em:focus,
+fieldset:focus, font:focus, form:focus, h1:focus, h2:focus, h3:focus, h4:focus,
+h5:focus, h6:focus, hr:focus, i:focus, img:focus, ins:focus,
+kbd:focus, label:focus, legend:focus, li:focus, link:focus, menu:focus,
+object:focus, ol:focus, p:focus, pre:focus, q:focus, s:focus, samp:focus,
+small:focus, span:focus, strike:focus, strong:focus, sub:focus, sup:focus,
+table:focus, tbody:focus, td:focus, tfoot:focus, th:focus, thead:focus,
+tr:focus, tt:focus, u:focus, ul:focus, var:focus {
+ /* Don't specify the outline-color, we should always use initial value. */
+ outline: 1px dotted;
+}
+
+/* hidden elements */
+area, base, basefont, head, meta, script, style, title,
+noembed, param {
+ display: none;
+}
+
+/* media elements */
+video > xul|videocontrols, audio > xul|videocontrols {
+ display: -moz-box;
+ -moz-box-orient: vertical;
+ -moz-binding: url("chrome://global/content/bindings/videocontrols.xml#videoControls");
+}
+
+video:not([controls]) > xul|videocontrols,
+audio:not([controls]) > xul|videocontrols {
+ visibility: hidden;
+}
+
+audio:not([controls]) {
+ display: none;
+}
+
+/* emulation of non-standard HTML <marquee> tag */
+marquee {
+ width: -moz-available;
+ display: inline-block;
+ vertical-align: text-bottom;
+ text-align: start;
+ -moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-horizontal');
+}
+
+marquee[direction="up"], marquee[direction="down"] {
+ -moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-vertical');
+ height: 200px;
+}
+
+/* PRINT ONLY rules follow */
+@media print {
+
+ marquee { -moz-binding: none; }
+
+}
diff --git a/bundles/XO/res/html/folder.png b/bundles/XO/res/html/folder.png
new file mode 100755
index 0000000..6fa6c15
--- /dev/null
+++ b/bundles/XO/res/html/folder.png
Binary files differ
diff --git a/bundles/XO/res/langGroups.properties b/bundles/XO/res/langGroups.properties
new file mode 100755
index 0000000..7e18dd4
--- /dev/null
+++ b/bundles/XO/res/langGroups.properties
@@ -0,0 +1,239 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Erik van der Poel
+# Jungshik Shin
+# Katsuhiko Momoi
+# Henri Sivonen
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+#
+# References: http://www.omniglot.com/writing/atoz.htm
+# http://www.loc.gov/standards/iso639-2/englangn.html
+# http://www.ethnologue.com
+# http://www.worldlanguage.com/Languages/
+# http://www.rosettaproject.org/
+# http://www.sweb.cz/ls78/diacritics.htm
+# see also toolkit/locales/en-US/chrome/global/languageNames.properties
+# and bug 178491
+#
+#ab=x-cyrillic
+# Strictly speaking, Avestan did not use Arabic script but Aramaic
+# (arc)/Avestan script.)
+#ae=ar
+
+af=x-western
+alg=x-cans
+am=x-ethi
+ar=ar
+as=x-beng
+be=x-cyrillic
+bg=x-cyrillic
+bn=x-beng
+br=x-western
+bs=x-central-euro
+ca=x-western
+ce=x-central-euro
+ch=x-western
+co=x-western
+cr=x-cans
+cs=x-central-euro
+#cu=x-cyrillic
+cv=x-cyrillic
+# XXX Latin Ext. A is also used for cy.
+cy=x-western
+da=x-western
+de=x-western
+#dv=Thaanna
+#dz=Tibetan
+#ee=x-western(?) (Ewe uses characters outside Latin-1 as well)
+el=el
+en=x-western
+# Esperanto: Latin-3
+eo=x-western
+es=x-western
+et=x-baltic
+eu=x-western
+fa=ar
+#ff=x-western(?) : Fulfulde
+fi=x-western
+# XXX Latin Ext. A is also used for fj.
+fj=x-western
+fo=x-western
+fr=x-western
+fy=x-western
+ga=x-western
+#XXX Latin Ext. A and Ext. additional block are used for Gaelic (8859-14)
+gd=x-western
+# gl : ISO-8859-13
+gl=x-western
+#ha=x-western : Latin and Ajami scripts
+gu=x-gujr
+he=he
+hi=x-devanagari
+ht=x-western
+hr=x-central-euro
+# XXX Latin Ext. A is also used for hsb.
+hsb=x-western
+hu=x-central-euro
+hy=x-armn
+ia=x-western
+id=x-western
+ie=x-western
+is=x-western
+it=x-western
+iu=x-cans
+ja=ja
+ka=x-geor
+km=x-khmr
+kn=x-knda
+ko=ko
+ks=ar
+#ku=ar
+# XXX Latin Ext. A is also used for kw(Cornish).
+kw=x-western
+#ky=x-cyrillic
+# XXX Latin Ext. A is also used for Latin.
+la=x-western
+lb=x-western
+lt=x-baltic
+lv=x-baltic
+#XXX Latin Ext. A is also used for Maori.
+mi=x-western
+mk=x-cyrillic
+ml=x-mlym
+#mo=x-central-euro / x-cyrillic
+mr=x-devanagari
+ms=x-western
+# Maltese: Latin-3
+mt=x-western
+nb=x-western
+ne=x-devanagari
+nl=x-western
+nn=x-western
+no=x-western
+# XXX : x-central-euro may be better
+nv=x-western
+oc=x-western
+oj=x-cans
+om=x-ethi
+or=x-orya
+os=x-cyrillic
+#pa: Punjabi is usually written in Gurmukhi script in India and Arabic script
+# in Pakistan. We make pa default to Gurmukhi based on comments in bug 248690
+pa-in=x-guru
+pa-pk=ar
+pa=x-guru
+pl=x-central-euro
+ps=ar
+pt=x-western
+qu=x-western
+rm=x-western
+ro=x-central-euro
+ru=x-cyrillic
+sa=x-devanagari
+sc=x-western
+sd=ar
+# African language (but related with French)
+sg=x-western
+sh=x-central-euro
+si=x-sinh
+sk=x-central-euro
+sl=x-central-euro
+so=x-western
+sq=x-western
+sr=x-cyrillic
+sv=x-western
+sw=x-western
+ta=x-tamil
+te=x-telu
+th=th
+tig=x-ethi
+tk=x-cyrillic
+#tk=tr # (The country declared in 1992 to gradually move to Latin script)
+tlh=x-western
+tr=tr
+tt=tr
+uk=x-cyrillic
+ur=ar
+# XXX : Vietnamese may need be put into a script group of its own
+vi=x-western
+vo=x-western
+wa=x-western
+yi=he
+#Latin Ext. A and Latin Extended Additional block are used for Yoruba.
+#yo=x-western
+zh-cn=zh-CN
+# XXX : The following two entries are added as a quick fix (bug 251241).
+# When we have a general solution for ISO 15924 (script codes), the issue has
+# to be revisited.
+zh-hans=zh-CN
+zh-hant=zh-TW
+zh-tw=zh-TW
+zh-hk=zh-HK
+zh=zh-CN
+zh-min-nan=x-western
+zu=x-western
+#
+#==============================
+#
+# mapping mozilla's internal x-* to themselves (see bug 256257)
+x-western=x-western
+x-central-euro=x-central-euro
+x-cyrillic=x-cyrillic
+# el
+# tr
+# he
+# ar
+x-baltic=x-baltic
+# th
+# ja
+# zh-CN
+# ko
+# zh-TW
+x-tamil=x-tamil
+x-devanagari=x-devanagari
+x-unicode=x-unicode
+x-user-def=x-user-def
+x-armn=x-armn
+x-geor=x-geor
+# These self-mappings are not necessary unless somebody use them to specify
+# lang in (X)HTML/XML documents, which they shouldn't. (see bug 256257)
+#x-beng=x-beng
+#x-cans=x-cans
+#x-ethi=x-ethi
+#x-guru=x-guru
+#x-gujr=x-gujr
+#x-khmr=x-khmr
+#x-mlym=x-mlym
diff --git a/bundles/XO/res/language.properties b/bundles/XO/res/language.properties
new file mode 100755
index 0000000..e03793f
--- /dev/null
+++ b/bundles/XO/res/language.properties
@@ -0,0 +1,261 @@
+aa.accept = false
+ab.accept = false
+ae.accept = false
+af.accept = true
+ak.accept = false
+am.accept = true
+an.accept = true
+ar.accept = true
+ar-ae.accept = true
+ar-bh.accept = true
+ar-dz.accept = true
+ar-eg.accept = true
+ar-iq.accept = true
+ar-jo.accept = true
+ar-kw.accept = true
+ar-lb.accept = true
+ar-ly.accept = true
+ar-ma.accept = true
+ar-om.accept = true
+ar-qa.accept = true
+ar-sa.accept = true
+ar-sy.accept = true
+ar-tn.accept = true
+ar-ye.accept = true
+as.accept = true
+ast.accept = true
+av.accept = false
+az.accept = true
+ba.accept = false
+be.accept = true
+bg.accept = true
+bh.accept = false
+bi.accept = false
+bm.accept = false
+bn.accept = true
+bo.accept = false
+br.accept = true
+bs.accept = true
+ca.accept = true
+ce.accept = true
+ch.accept = true
+co.accept = true
+cr.accept = true
+cs.accept = true
+cu.accept = false
+cv.accept = true
+cy.accept = true
+da.accept = true
+de.accept = true
+de-at.accept = true
+de-ch.accept = true
+de-de.accept = true
+de-li.accept = true
+de-lu.accept = true
+dv.accept = false
+dz.accept = false
+ee.accept = false
+el.accept = true
+en.accept = true
+en-au.accept = true
+en-bz.accept = true
+en-ca.accept = true
+en-gb.accept = true
+en-ie.accept = true
+en-jm.accept = true
+en-nz.accept = true
+en-ph.accept = true
+en-tt.accept = true
+en-us.accept = true
+en-za.accept = true
+en-zw.accept = true
+eo.accept = true
+es.accept = true
+es-ar.accept = true
+es-bo.accept = true
+es-cl.accept = true
+es-co.accept = true
+es-cr.accept = true
+es-do.accept = true
+es-ec.accept = true
+es-es.accept = true
+es-gt.accept = true
+es-hn.accept = true
+es-mx.accept = true
+es-ni.accept = true
+es-pa.accept = true
+es-pe.accept = true
+es-pr.accept = true
+es-py.accept = true
+es-sv.accept = true
+es-uy.accept = true
+es-ve.accept = true
+et.accept = true
+eu.accept = true
+fa.accept = true
+fa-ir.accept = true
+ff.accept = false
+fi.accept = true
+fj.accept = true
+fo.accept = true
+fr.accept = true
+fr-be.accept = true
+fr-ca.accept = true
+fr-ch.accept = true
+fr-fr.accept = true
+fr-lu.accept = true
+fr-mc.accept = true
+fur.accept = true
+fy.accept = true
+ga.accept = true
+gd.accept = true
+gl.accept = true
+gn.accept = false
+gu.accept = true
+gv.accept = false
+ha.accept = false
+he.accept = true
+hi.accept = true
+ho.accept = false
+hsb.accept = true
+hr.accept = true
+ht.accept = true
+hu.accept = true
+hy.accept = true
+hz.accept = false
+ia.accept = true
+id.accept = true
+ie.accept = true
+ig.accept = false
+ii.accept = false
+ik.accept = false
+io.accept = false
+is.accept = true
+it.accept = true
+it-ch.accept = true
+iu.accept = true
+ja.accept = true
+jv.accept = false
+ka.accept = true
+kg.accept = false
+ki.accept = false
+kk.accept = true
+kl.accept = false
+km.accept = true
+kn.accept = true
+ko.accept = true
+ko-kp.accept = true
+ko-kr.accept = true
+kok.accept = false
+kr.accept = false
+ks.accept = true
+ku.accept = false
+kv.accept = false
+kw.accept = false
+ky.accept = true
+la.accept = true
+lb.accept = true
+lg.accept = false
+li.accept = false
+ln.accept = false
+lo.accept = false
+lt.accept = true
+lu.accept = false
+lv.accept = true
+mg.accept = false
+mh.accept = false
+mi.accept = true
+mk.accept = false
+mk-mk.accept = true
+ml.accept = true
+mn.accept = false
+mo.accept = true
+mr.accept = true
+ms.accept = true
+mt.accept = true
+my.accept = true
+na.accept = false
+nb.accept = true
+nd.accept = false
+ne.accept = true
+ng.accept = true
+nl.accept = true
+nl-be.accept = true
+nn.accept = true
+no.accept = true
+nr.accept = false
+nso.accept = false
+nv.accept = true
+ny.accept = false
+oc.accept = true
+oj.accept = false
+om.accept = true
+or.accept = true
+os.accept = false
+pa.accept = true
+pa-in.accept = true
+pa-pk.accept = true
+pi.accept = false
+pl.accept = true
+ps.accept = false
+pt.accept = true
+pt-br.accept = true
+qu.accept = true
+rm.accept = true
+rn.accept = false
+ro.accept = true
+ro-md.accept = false
+ru.accept = true
+ru-md.accept = false
+sa.accept = true
+sc.accept = true
+sd.accept = true
+sg.accept = true
+si.accept = true
+sk.accept = true
+sl.accept = true
+so.accept = true
+sq.accept = true
+sr.accept = true
+ss.accept = false
+st.accept = false
+su.accept = false
+sv.accept = true
+sv-fi.accept = true
+sv-se.accept = true
+sw.accept = true
+ta.accept = true
+te.accept = true
+tg.accept = false
+th.accept = true
+ti.accept = false
+tig.accept = true
+tk.accept = true
+tl.accept = false
+tlh.accept = true
+tn.accept = false
+to.accept = false
+tr.accept = true
+ts.accept = false
+tt.accept = true
+tw.accept = false
+ty.accept = false
+ug.accept = false
+uk.accept = true
+ur.accept = false
+uz.accept = false
+ve.accept = true
+vi.accept = true
+vo.accept = true
+wa.accept = true
+wo.accept = false
+xh.accept = true
+yi.accept = true
+yo.accept = false
+za.accept = false
+zh.accept = true
+zh-cn.accept = true
+zh-hk.accept = true
+zh-sg.accept = true
+zh-tw.accept = true
+zu.accept = true
diff --git a/bundles/XO/res/loading-image.gif b/bundles/XO/res/loading-image.gif
new file mode 100755
index 0000000..1d57ca5
--- /dev/null
+++ b/bundles/XO/res/loading-image.gif
Binary files differ
diff --git a/bundles/XO/res/mathml.css b/bundles/XO/res/mathml.css
new file mode 100755
index 0000000..458cc56
--- /dev/null
+++ b/bundles/XO/res/mathml.css
@@ -0,0 +1,455 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla MathML Project.
+ *
+ * The Initial Developer of the Original Code is
+ * The University Of Queensland.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Roger B. Sidje <rbs@maths.uq.edu.au>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+/**************************************************************************/
+/* namespace for MathML elements */
+/**************************************************************************/
+
+@namespace url(http://www.w3.org/1998/Math/MathML);
+
+/**************************************************************************/
+/* <math> - outermost math element */
+/* Put Cambria before Cambria Math as Cambria Math has neither bold nor */
+/* italic. */
+/**************************************************************************/
+
+math {
+ direction: ltr;
+ unicode-bidi: embed;
+ display: inline;
+ font-size: inherit;
+ font-style: normal;
+ font-family: STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
+ text-rendering: optimizeLegibility;
+ -moz-float-edge: margin-box;
+}
+math[mode="display"], math[display="block"] {
+ display: block;
+ text-align: -moz-center;
+}
+math[display="inline"] {
+ display: inline;
+}
+::-moz-math-inline {
+ display: inline;
+}
+
+/**************************************************************************/
+/* Style switching during frame construction depending on the context of <mi>:
+ These rules are not used when mathvariant or fontstyle is specified
+ explicitly.
+/**************************************************************************/
+
+/* If the textual content of an <mi> consists of a single character
+ with a corresponding mathematical italic alphanumeric character,
+ then try to emulate that character */
+[-moz-math-font-style="italic"] {
+ font-style: italic;
+ font-weight: normal;
+}
+/* If the textual content consists of multiple characters, then the default is
+ mathvariant=normal. It seems that mathvariant=normal should be interpreted
+ to mean non-slanted:
+
+ http://www.w3.org/TR/2003/REC-MathML2-20031021/chapter3.html#presm.commatt
+
+ "In particular, inheritance of the mathvariant attribute does not follow
+ the CSS model. The default value for this attribute is "normal"
+ (non-slanted) for all tokens except mi. ... (The deprecated fontslant
+ attribute also behaves this way.)"
+ */
+[-moz-math-font-style="normal"] {
+ font-style: normal;
+}
+/* A style-invariant character preserves its own style */
+[-moz-math-font-style="invariant"] {
+ font-style: normal;
+ font-weight: normal;
+}
+
+/**************************************************************************/
+/* attributes common to all tags */
+/**************************************************************************/
+
+/* deprecated attributes from MathML 1.0 */
+
+/* fontstyle */
+[fontstyle="normal"] {
+ font-style: normal;
+}
+[fontstyle="italic"] {
+ font-style: italic;
+}
+/* fontweight */
+[fontweight="normal"] {
+ font-weight: normal;
+}
+[fontweight="bold"] {
+ font-weight: bold;
+}
+
+/* attributes from MathML 2.0 */
+
+/* These ones are handled in the back-end:
+ mathcolor (replaces 'color'):
+ #rgb | #rrggbb | html-color-name
+ mathbackground (replaces 'background'):
+ #rgb | #rrggbb | html-color-name
+*/
+/* mathvariant (replaces 'fontstyle' & 'fontweight' & 'fontslant'):
+ normal | bold | italic | bold-italic | double-struck | bold-fraktur | script |
+ bold-script | fraktur | sans-serif | bold-sans-serif | sans-serif-italic |
+ sans-serif-bold-italic | monospace
+
+ Note1: Back-end code for these is not yet written (bug 114365):
+ double-struck, script, fraktur, bold-fraktur, bold-script
+
+ Note2: Don't use the 'font' shorthand because it resets the font-size and this
+ breaks the propagation of the scriptlevel size.
+
+ XXX bugs 46622 & 114365: need -moz-math-serif, etc, to only lookup math fonts
+
+ The meaning of mathvariant=normal is unclear as there is no interpretation
+ that "corresponds to SMP Math Alphanumeric Symbol characters"
+ (http://www.w3.org/TR/2003/REC-MathML2-20031021/chapter3.html#presm.commatt),
+ but let's assume an explicit mathvariant=normal is an attempt to reset all
+ style.
+*/
+[mathvariant] { /* shared and same as [mathvariant="normal"] */
+ /* reset all font properties except those that affect the size */
+ font-style: normal;
+ font-variant: normal;
+ font-weight: normal;
+}
+[mathvariant="bold-fraktur"],
+[mathvariant="bold-script"] {
+ font-weight: bold;
+}
+[mathvariant="bold"] {
+ font-weight: bold;
+}
+[mathvariant="italic"] {
+ font-style: italic;
+}
+[mathvariant="bold-italic"] {
+ font-weight: bold;
+ font-style: italic;
+}
+[mathvariant="sans-serif"] {
+ font-family: sans-serif;
+}
+[mathvariant="bold-sans-serif"] {
+ font-weight: bold;
+ font-family: sans-serif;
+}
+[mathvariant="sans-serif-italic"] {
+ font-family: sans-serif;
+ font-style: italic;
+}
+[mathvariant="sans-serif-bold-italic"] {
+ font-family: sans-serif;
+ font-weight: bold;
+ font-style: italic;
+}
+[mathvariant="monospace"] {
+ font-family: monospace;
+}
+
+/**************************************************************************/
+/* tags with generated content */
+/**************************************************************************/
+
+ms {
+ display: inline;
+}
+ms:before {
+ content: open-quote;
+}
+ms:after {
+ content: close-quote;
+}
+
+merror {
+ display: block;
+ font-family: sans-serif;
+ font-weight: bold;
+ white-space: pre;
+ margin: 1em;
+ padding: 1em;
+ border-width: thin;
+ border-style: inset;
+ border-color: red;
+ font-size: 14pt;
+ background-color: lightyellow;
+}
+
+/**************************************************************************/
+/* mtable and its related tags */
+/**************************************************************************/
+
+mtable {
+ display: inline-table;
+ border-collapse: separate;
+ border-spacing: 0;
+ text-indent: 0;
+}
+mtable[frame="none"] {
+ border: none;
+}
+mtable[frame="solid"] {
+ border: solid thin;
+}
+mtable[frame="dashed"] {
+ border: dashed thin;
+}
+
+mtr {
+ display: table-row;
+ vertical-align: baseline;
+}
+
+mtd {
+ display: table-cell;
+ vertical-align: inherit;
+ text-align: -moz-center;
+ white-space: nowrap;
+}
+
+/* Don't support mtr without mtable, nor mtd without mtr */
+:not(mtable) > mtr,
+:not(mtr) > mtd {
+ display: none !important;
+}
+
+/***********************/
+/* -- mtd: columnalign */
+
+mtd[-moz-math-columnalign="left"],
+mtd[columnalign="left"] {
+ text-align: left;
+}
+mtd[-moz-math-columnalign="right"],
+mtd[columnalign="right"] {
+ text-align: right;
+}
+mtd[-moz-math-columnalign="center"],
+mtd[columnalign="center"] {
+ text-align: -moz-center;
+}
+
+/*************************/
+/* -- mtr, mtd: rowalign */
+
+mtr[-moz-math-rowalign="top"],
+mtr[rowalign="top"],
+mtd[rowalign="top"] {
+ vertical-align: top;
+}
+mtr[-moz-math-rowalign="bottom"],
+mtr[rowalign="bottom"],
+mtd[rowalign="bottom"] {
+ vertical-align: bottom;
+}
+mtr[-moz-math-rowalign="center"],
+mtr[rowalign="center"],
+mtd[rowalign="center"] {
+ vertical-align: middle;
+}
+mtr[-moz-math-rowalign="baseline"],
+mtr[rowalign="baseline"],
+mtd[rowalign="baseline"] {
+ vertical-align: baseline;
+}
+/* -- not yet supported --
+mtr[-moz-math-rowalign="axis"],
+mtr[rowalign="axis"],
+mtd[rowalign="axis"] {
+ vertical-align: mathline;
+}
+*/
+
+/**********************************************************************/
+/* rules to achieve the default spacing between cells. The back-end code
+ will set the internal attributes depending on the cell's position.
+ These rules are hard-coded, the comments indicate what would be
+ desirable if the style data could be changed on the fly to pick
+ the values that users may set with the attributes of <mtable> */
+mtd {
+ padding-right: 0.4em; /* half of columnspacing[colindex] */
+ padding-left: 0.4em; /* half of columnspacing[colindex-1] */
+ padding-bottom: 0.5ex; /* half of rowspacing[rowindex] */
+ padding-top: 0.5ex; /* half of rowspacing[rowindex-1] */
+}
+/* turn off the spacing at the periphery of boundary cells */
+mtr:first-child > mtd {
+ padding-top: 0ex;
+}
+mtr:last-child > mtd {
+ padding-bottom: 0ex;
+}
+mtd:first-child {
+ padding-left: 0em;
+}
+mtd:last-child {
+ padding-right: 0em;
+}
+/* re-instate the spacing if the table has a surrounding frame */
+mtable[frame="solid"] > mtr:first-child > mtd,
+mtable[frame="dashed"] > mtr:first-child > mtd {
+ padding-top: 0.5ex; /* framespacing.top */
+}
+mtable[frame="solid"] > mtr:last-child > mtd,
+mtable[frame="dashed"] > mtr:last-child > mtd {
+ padding-bottom: 0.5ex; /* framespacing.bottom */
+}
+mtable[frame="solid"] > mtr > mtd:first-child,
+mtable[frame="dashed"] > mtr > mtd:first-child {
+ padding-left: 0.4em; /* framespacing.left */
+}
+mtable[frame="solid"] > mtr > mtd:last-child,
+mtable[frame="dashed"] > mtr > mtd:last-child {
+ padding-right: 0.4em; /* framespacing.right */
+}
+
+/**********************************************************************/
+/* internal settings to support 'rowlines' and 'columnlines'. To
+ achieve the recommended behavior, the back-end code will avoid setting
+ unsuitable rules on the cells on the first row and the first column.
+ In general, however, authors can use the 'border' property of CSS to
+ achieve varying effects down to the level of the table cell. */
+mtr[-moz-math-rowline="none"] > mtd {
+ border-top: none;
+}
+mtr[-moz-math-rowline="solid"] > mtd {
+ border-top: solid thin;
+}
+mtr[-moz-math-rowline="dashed"] > mtd {
+ border-top: dashed thin;
+}
+mtd[-moz-math-columnline="none"] {
+ border-left: none;
+}
+mtd[-moz-math-columnline="solid"] {
+ border-left: solid thin;
+}
+mtd[-moz-math-columnline="dashed"] {
+ border-left: dashed thin;
+}
+
+
+/**************************************************************************/
+/* Style used for stretchy symbols *must* be normal to avoid misaligments */
+/* By leaving the font-family empty, the MathML engine will use the value
+ provided by the mathfont-family property in the mathfont.properties file
+ or the value of the user's pref("font.mathfont-family", "...").
+
+ Authors can make elements on a document to be stretched with different
+ fonts, e.g.,
+
+ To request the use of TeX fonts, you can add a <style>...</style> with:
+ <mo myfonts="tex">...</mo> with the associated CSS declaration
+ mo[myfonts="tex"]::-moz-math-stretchy {
+ font-family: CMSY10, CMEX10;
+ }
+
+ To request the use of Mathematica fonts, you can add a <style>...</style> with:
+ <mo myfonts="mathematica">...</mo> with the associated CSS declaration
+ mo[myfonts="mathematica"]::-moz-math-stretchy {
+ font-family: Math1, Math2, Math4;
+ }
+
+ Of course, if you just want all of the stretchy characters in your
+ document to be stretched with your preferred list, you can just do:
+ ::-moz-math-stretchy {
+ font-family: [your-particular-list]
+ }
+
+ Note that like other fonts in the document, users can override this by
+ clicking the pref to override document fonts.
+/**************************************************************************/
+
+::-moz-math-stretchy {
+ font-style: normal;
+ font-family: serif; /* an empty family is ignored as an error and behaves like inherit */
+/* background-color: #3C6; */
+}
+::-moz-math-anonymous {
+}
+
+/**********************************************************************/
+/* Hide embedded semantic MathML content (as opposed to presentational
+ content, which we render). Ideally, here is the behavior that we want:
+
+ if there is an annotation-xml[encoding="MathML-Presentation"]
+ render that annotation, and ignore the first child of the
+ <semantics> element and all other annotations,
+ else
+ render the first child of <semantics> and ignore all annotations
+
+ But this cannot be expressed with CSS. As a stop-gap, just render
+ the first child to cater for most of the common cases - bug 154931.
+*/
+semantics > :not(:first-child) {
+ display: none;
+}
+
+/**********************************************************************/
+/* This is used when wrapping non-MathML inline elements inside math. */
+*|*::-moz-mathml-anonymous-block {
+ display: inline-block !important;
+ position: static !important;
+ text-indent: 0;
+}
+
+/*****************************************/
+/* Controlling scriptlevel */
+/*****************************************/
+
+/* mfrac, munder, mover and munderover change the scriptlevels of their children using
+ -moz-math-increment-script-level because regular CSS rules are insufficient to
+ control when the scriptlevel should be incremented */
+:-moz-math-increment-script-level { -moz-script-level:+1; }
+
+/* all other cases can be described using regular CSS, so we do it this way because it's
+ more efficient and less code */
+mroot > :not(:first-child) { -moz-script-level:+2; }
+
+msub > :not(:first-child),
+msup > :not(:first-child),
+msubsup > :not(:first-child),
+mmultiscripts > :not(:first-child) { -moz-script-level:+1; }
diff --git a/bundles/XO/res/quirk.css b/bundles/XO/res/quirk.css
new file mode 100755
index 0000000..9c3042d
--- /dev/null
+++ b/bundles/XO/res/quirk.css
@@ -0,0 +1,274 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+@namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
+
+
+/* Quirk: make orphaned LIs have inside bullet (b=1049) */
+
+/* force inside position for orphaned lis */
+li {
+ list-style-position: inside;
+}
+
+/* restore outside position for lists inside LIs */
+li ul, li ol, li dir, li menu {
+ list-style-position: outside;
+}
+
+/* undo previous two rules for properly nested lists */
+ ul ul, ul ol, ul dir, ul menu, ul li,
+ ol ul, ol ol, ol dir, ol menu, ol li,
+ dir ul, dir ol, dir dir, dir menu, dir li,
+menu ul, menu ol, menu dir, menu menu, menu li {
+ list-style-position: inherit;
+}
+
+
+/* Quirk: ensure that we get proper padding if the very first
+ * node in an LI is another UL or OL. This is an ugly way to
+ * fix the problem, because it extends the LI up into what
+ * would otherwise appear to be the ULs space. (b=38832) */
+
+/* Note: this fix will fail once we implement marker box
+ * alignment correctly. */
+li > ul:-moz-first-node,
+li > ol:-moz-first-node {
+ padding-top: 1em;
+}
+
+
+/* Quirk: prevent bullet from resizing with the list item
+ * see bug 97351
+ */
+
+li::-moz-list-bullet {
+ font-size: -moz-initial;
+}
+
+
+table {
+ text-align: start;
+ white-space: normal; /* compatible with IE & spec */
+ line-height: normal;
+
+ /* Quirk: cut off all font inheritance in tables except for family. */
+ font-size: -moz-initial;
+ font-weight: -moz-initial;
+ font-style: -moz-initial;
+ font-variant: -moz-initial;
+}
+
+/*
+ * Make table borders gray for compatibility with what other browsers do
+ * in all modes, rather than using the foreground color.
+ */
+table, td, th {
+ border-color: gray;
+}
+
+
+/* Quirk: collapse top margin of BODY and TD and bottom margin of TD */
+
+/*
+ * While it may seem simpler to use :-moz-first-node and :-moz-last-node without
+ * tags, it's slower, since we have to do the :-moz-first-node or :-moz-last-node
+ * check on every single element in the document. If we list all the
+ * element names for which the UA stylesheet specifies a margin, the
+ * selectors will be hashed in the RuleHash and things will be much more
+ * efficient.
+ */
+body > p:-moz-first-node, td > p:-moz-first-node, th > p:-moz-first-node,
+body > dl:-moz-first-node, td > dl:-moz-first-node, th > dl:-moz-first-node,
+body > multicol:-moz-first-node, td > multicol:-moz-first-node, th > multicol:-moz-first-node,
+body > blockquote:-moz-first-node, td > blockquote:-moz-first-node, th > blockquote:-moz-first-node,
+body > h1:-moz-first-node, td > h1:-moz-first-node, th > h1:-moz-first-node,
+body > h2:-moz-first-node, td > h2:-moz-first-node, th > h2:-moz-first-node,
+body > h3:-moz-first-node, td > h3:-moz-first-node, th > h3:-moz-first-node,
+body > h4:-moz-first-node, td > h4:-moz-first-node, th > h4:-moz-first-node,
+body > h5:-moz-first-node, td > h5:-moz-first-node, th > h5:-moz-first-node,
+body > h6:-moz-first-node, td > h6:-moz-first-node, th > h6:-moz-first-node,
+body > listing:-moz-first-node, td > listing:-moz-first-node, th > listing:-moz-first-node,
+body > plaintext:-moz-first-node, td > plaintext:-moz-first-node, th > plaintext:-moz-first-node,
+body > xmp:-moz-first-node, td > xmp:-moz-first-node, th > xmp:-moz-first-node,
+body > pre:-moz-first-node, td > pre:-moz-first-node, th > pre:-moz-first-node,
+body > ul:-moz-first-node, td > ul:-moz-first-node, th > ul:-moz-first-node,
+body > menu:-moz-first-node, td > menu:-moz-first-node, th > menu:-moz-first-node,
+body > dir:-moz-first-node, td > dir:-moz-first-node, th > dir:-moz-first-node,
+body > ol:-moz-first-node, td > ol:-moz-first-node, th > ol:-moz-first-node {
+ margin-top: 0;
+}
+
+td > p:-moz-last-node, th > p:-moz-last-node {
+ margin-bottom: 0;
+}
+
+/* Similar as above, but for empty elements
+ * collapse the bottom or top margins of empty elements
+ * - see bug 97361
+ */
+body > p:-moz-only-whitespace:-moz-first-node,
+td > p:-moz-only-whitespace:-moz-first-node, th > p:-moz-only-whitespace:-moz-first-node,
+body > dl:-moz-only-whitespace:-moz-first-node, td > dl:-moz-only-whitespace:-moz-first-node,
+th > dl:-moz-only-whitespace:-moz-first-node, body > multicol:-moz-only-whitespace:-moz-first-node,
+td > multicol:-moz-only-whitespace:-moz-first-node, th > multicol:-moz-only-whitespace:-moz-first-node,
+body > blockquote:-moz-only-whitespace:-moz-first-node, td > blockquote:-moz-only-whitespace:-moz-first-node,
+th > blockquote:-moz-only-whitespace:-moz-first-node, body > h1:-moz-only-whitespace:-moz-first-node,
+td > h1:-moz-only-whitespace:-moz-first-node, th > h1:-moz-only-whitespace:-moz-first-node,
+body > h2:-moz-only-whitespace:-moz-first-node, td > h2:-moz-only-whitespace:-moz-first-node,
+th > h2:-moz-only-whitespace:-moz-first-node, body > h3:-moz-only-whitespace:-moz-first-node,
+td > h3:-moz-only-whitespace:-moz-first-node, th > h3:-moz-only-whitespace:-moz-first-node,
+body > h4:-moz-only-whitespace:-moz-first-node, td > h4:-moz-only-whitespace:-moz-first-node,
+th > h4:-moz-only-whitespace:-moz-first-node, body > h5:-moz-only-whitespace:-moz-first-node,
+td > h5:-moz-only-whitespace:-moz-first-node, th > h5:-moz-only-whitespace:-moz-first-node,
+body > h6:-moz-only-whitespace:-moz-first-node, td > h6:-moz-only-whitespace:-moz-first-node,
+th > h6:-moz-only-whitespace:-moz-first-node, body > listing:-moz-only-whitespace:-moz-first-node,
+td > listing:-moz-only-whitespace:-moz-first-node, th > listing:-moz-only-whitespace:-moz-first-node,
+body > plaintext:-moz-only-whitespace:-moz-first-node, td > plaintext:-moz-only-whitespace:-moz-first-node,
+th > plaintext:-moz-only-whitespace:-moz-first-node, body > xmp:-moz-only-whitespace:-moz-first-node,
+td > xmp:-moz-only-whitespace:-moz-first-node, th > xmp:-moz-only-whitespace:-moz-first-node,
+body > pre:-moz-only-whitespace:-moz-first-node, td > pre:-moz-only-whitespace:-moz-first-node,
+th > pre:-moz-only-whitespace:-moz-first-node, body > ul:-moz-only-whitespace:-moz-first-node,
+td > ul:-moz-only-whitespace:-moz-first-node, th > ul:-moz-only-whitespace:-moz-first-node,
+body > menu:-moz-only-whitespace:-moz-first-node, td > menu:-moz-only-whitespace:-moz-first-node,
+th > menu:-moz-only-whitespace:-moz-first-node, body > dir:-moz-only-whitespace:-moz-first-node,
+td > dir:-moz-only-whitespace:-moz-first-node, th > dir:-moz-only-whitespace:-moz-first-node,
+body > ol:-moz-only-whitespace:-moz-first-node, td > ol:-moz-only-whitespace:-moz-first-node,
+th > ol:-moz-only-whitespace:-moz-first-node {
+ margin-bottom: 0;
+}
+
+td > p:-moz-only-whitespace:-moz-last-node, th > p:-moz-only-whitespace:-moz-last-node,
+td > dl:-moz-only-whitespace:-moz-last-node, th > dl:-moz-only-whitespace:-moz-last-node,
+td > multicol:-moz-only-whitespace:-moz-last-node, th > multicol:-moz-only-whitespace:-moz-last-node,
+td > blockquote:-moz-only-whitespace:-moz-last-node, th > blockquote:-moz-only-whitespace:-moz-last-node,
+td > h1:-moz-only-whitespace:-moz-last-node, th > h1:-moz-only-whitespace:-moz-last-node,
+td > h2:-moz-only-whitespace:-moz-last-node, th > h2:-moz-only-whitespace:-moz-last-node,
+td > h3:-moz-only-whitespace:-moz-last-node, th > h3:-moz-only-whitespace:-moz-last-node,
+td > h4:-moz-only-whitespace:-moz-last-node, th > h4:-moz-only-whitespace:-moz-last-node,
+td > h5:-moz-only-whitespace:-moz-last-node, th > h5:-moz-only-whitespace:-moz-last-node,
+td > h6:-moz-only-whitespace:-moz-last-node, th > h6:-moz-only-whitespace:-moz-last-node,
+td > listing:-moz-only-whitespace:-moz-last-node, th > listing:-moz-only-whitespace:-moz-last-node,
+td > plaintext:-moz-only-whitespace:-moz-last-node, th > plaintext:-moz-only-whitespace:-moz-last-node,
+td > xmp:-moz-only-whitespace:-moz-last-node, th > xmp:-moz-only-whitespace:-moz-last-node,
+td > pre:-moz-only-whitespace:-moz-last-node, th > pre:-moz-only-whitespace:-moz-last-node,
+td > ul:-moz-only-whitespace:-moz-last-node, th > ul:-moz-only-whitespace:-moz-last-node,
+td > menu:-moz-only-whitespace:-moz-last-node, th > menu:-moz-only-whitespace:-moz-last-node,
+td > dir:-moz-only-whitespace:-moz-last-node, th > dir:-moz-only-whitespace:-moz-last-node,
+td > ol:-moz-only-whitespace:-moz-last-node, th > ol:-moz-only-whitespace:-moz-last-node {
+ margin-top: 0;
+}
+
+
+/* Quirk: support the ways of making PRE have wrapping */
+
+pre[wrap], pre[cols], pre[width] {
+ white-space: pre-wrap;
+}
+
+
+/* Quirk: DD not in DL has text-indent instead of margin (b=5119) */
+
+:not(dl) > dd {
+ display: inline;
+ margin: 0;
+}
+
+:not(dl) > dd:before {
+ display: inline;
+ white-space: pre;
+ font-size: 1px;
+ line-height: 0;
+ content: "\A ";
+ -moz-margin-end: 40px;
+}
+
+
+/* quirk to indent nested DL elements (b=8749) */
+
+dl > dl {
+ display: block;
+ -moz-margin-start: 40px;
+}
+
+
+/* Quirk: MAP acts like an inline, not a block */
+
+map {
+ display: inline;
+}
+
+
+/* Quirk: Make floated images have a margin (b=58899) */
+
+img[align=left] {
+ margin-right: 3px;
+}
+
+img[align=right] {
+ margin-left: 3px;
+}
+
+
+/* Quirk: Make sure that the residual style tags' size info.
+ * does not take precedence over heading tags' size. (b=77352)
+ * Note: This special attribute is set only for a residual
+ * style tag within a heading tag.
+ */
+
+/* XXX This is a potential performance problem. This should not be
+ * using an attribute!
+ */
+*[_moz-rs-heading] {
+ font-size: inherit !important;
+}
+
+
+/*
+ * Quirk: Use border-box box sizing for text inputs, password inputs, and
+ * textareas. (b=184478 on why we use content-box sizing in standards mode)
+ */
+
+/* Note that all other <input>s already use border-box
+ sizing, so we're ok with this selector */
+input:not([type=image]), textarea {
+ -moz-box-sizing: border-box;
+}
+
+/* Quirk: give form margin for compat (b=41806) */
+form{
+ margin-bottom: 1em;
+}
diff --git a/bundles/XO/res/svg.css b/bundles/XO/res/svg.css
new file mode 100755
index 0000000..41dd451
--- /dev/null
+++ b/bundles/XO/res/svg.css
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla SVG project.
+ *
+ * The Initial Developer of the Original Code is
+ * Crocodile Clips Ltd.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+@namespace url(http://www.w3.org/2000/svg);
+
+/* XXX see bugs #71191 and #172574 before applying xbl binding to
+ * either 'svg' or 'svg:not(:root)'
+ */
+
+style, script, symbol {
+ display: none;
+}
+
+switch {
+ -moz-binding: none !important;
+}
+
+svg:not(:root), symbol, image, marker, pattern, foreignObject {
+ overflow: hidden;
+}
+
+foreignObject {
+ margin: 0 ! important;
+ padding: 0 ! important;
+ border-width: 0 ! important;
+}
+
+*|*::-moz-svg-foreign-content {
+ display: block !important;
+ position: static !important;
+ text-indent: 0;
+}
diff --git a/bundles/XO/res/table-add-column-after-active.gif b/bundles/XO/res/table-add-column-after-active.gif
new file mode 100755
index 0000000..3ec50b8
--- /dev/null
+++ b/bundles/XO/res/table-add-column-after-active.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-column-after-hover.gif b/bundles/XO/res/table-add-column-after-hover.gif
new file mode 100755
index 0000000..29679f9
--- /dev/null
+++ b/bundles/XO/res/table-add-column-after-hover.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-column-after.gif b/bundles/XO/res/table-add-column-after.gif
new file mode 100755
index 0000000..8891be9
--- /dev/null
+++ b/bundles/XO/res/table-add-column-after.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-column-before-active.gif b/bundles/XO/res/table-add-column-before-active.gif
new file mode 100755
index 0000000..1e20529
--- /dev/null
+++ b/bundles/XO/res/table-add-column-before-active.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-column-before-hover.gif b/bundles/XO/res/table-add-column-before-hover.gif
new file mode 100755
index 0000000..7b54537
--- /dev/null
+++ b/bundles/XO/res/table-add-column-before-hover.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-column-before.gif b/bundles/XO/res/table-add-column-before.gif
new file mode 100755
index 0000000..d4a3ffe
--- /dev/null
+++ b/bundles/XO/res/table-add-column-before.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-row-after-active.gif b/bundles/XO/res/table-add-row-after-active.gif
new file mode 100755
index 0000000..cc01da2
--- /dev/null
+++ b/bundles/XO/res/table-add-row-after-active.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-row-after-hover.gif b/bundles/XO/res/table-add-row-after-hover.gif
new file mode 100755
index 0000000..a829351
--- /dev/null
+++ b/bundles/XO/res/table-add-row-after-hover.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-row-after.gif b/bundles/XO/res/table-add-row-after.gif
new file mode 100755
index 0000000..3f1a39d
--- /dev/null
+++ b/bundles/XO/res/table-add-row-after.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-row-before-active.gif b/bundles/XO/res/table-add-row-before-active.gif
new file mode 100755
index 0000000..34f1e0a
--- /dev/null
+++ b/bundles/XO/res/table-add-row-before-active.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-row-before-hover.gif b/bundles/XO/res/table-add-row-before-hover.gif
new file mode 100755
index 0000000..e8f1d10
--- /dev/null
+++ b/bundles/XO/res/table-add-row-before-hover.gif
Binary files differ
diff --git a/bundles/XO/res/table-add-row-before.gif b/bundles/XO/res/table-add-row-before.gif
new file mode 100755
index 0000000..1682170
--- /dev/null
+++ b/bundles/XO/res/table-add-row-before.gif
Binary files differ
diff --git a/bundles/XO/res/table-remove-column-active.gif b/bundles/XO/res/table-remove-column-active.gif
new file mode 100755
index 0000000..4dfbde4
--- /dev/null
+++ b/bundles/XO/res/table-remove-column-active.gif
Binary files differ
diff --git a/bundles/XO/res/table-remove-column-hover.gif b/bundles/XO/res/table-remove-column-hover.gif
new file mode 100755
index 0000000..fd11bb5
--- /dev/null
+++ b/bundles/XO/res/table-remove-column-hover.gif
Binary files differ
diff --git a/bundles/XO/res/table-remove-column.gif b/bundles/XO/res/table-remove-column.gif
new file mode 100755
index 0000000..d8071da
--- /dev/null
+++ b/bundles/XO/res/table-remove-column.gif
Binary files differ
diff --git a/bundles/XO/res/table-remove-row-active.gif b/bundles/XO/res/table-remove-row-active.gif
new file mode 100755
index 0000000..4dfbde4
--- /dev/null
+++ b/bundles/XO/res/table-remove-row-active.gif
Binary files differ
diff --git a/bundles/XO/res/table-remove-row-hover.gif b/bundles/XO/res/table-remove-row-hover.gif
new file mode 100755
index 0000000..fd11bb5
--- /dev/null
+++ b/bundles/XO/res/table-remove-row-hover.gif
Binary files differ
diff --git a/bundles/XO/res/table-remove-row.gif b/bundles/XO/res/table-remove-row.gif
new file mode 100755
index 0000000..d8071da
--- /dev/null
+++ b/bundles/XO/res/table-remove-row.gif
Binary files differ
diff --git a/bundles/XO/res/ua.css b/bundles/XO/res/ua.css
new file mode 100755
index 0000000..f7a1e07
--- /dev/null
+++ b/bundles/XO/res/ua.css
@@ -0,0 +1,248 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+@import url(resource://gre/res/html.css);
+@import url(chrome://global/content/xul.css);
+
+@namespace parsererror url(http://www.mozilla.org/newlayout/xml/parsererror.xml);
+
+/* magic -- some of these rules are important to keep pages from overriding
+ them
+*/
+
+/* Tables */
+
+*|*::-moz-table {
+ display: table !important;
+ -moz-box-sizing: border-box; /* XXX do we really want this? */
+}
+
+*|*::-moz-inline-table {
+ display: inline-table !important;
+ -moz-box-sizing: border-box; /* XXX do we really want this? */
+}
+
+*|*::-moz-table-outer {
+ display: inherit !important; /* table or inline-table */
+ margin: 0 ! important;
+ padding: 0 ! important;
+ border: none ! important;
+ float: inherit;
+ clear: inherit;
+ position: inherit;
+ top: inherit;
+ right: inherit;
+ bottom: inherit;
+ left: inherit;
+ z-index: inherit;
+ page-break-before: inherit;
+ page-break-after: inherit;
+ vertical-align: inherit; /* needed for inline-table */
+ line-height: inherit; /* needed for vertical-align on inline-table */
+}
+
+*|*::-moz-table-row {
+ display: table-row !important;
+}
+
+/* The ::-moz-table-column pseudo-element is for extra columns at the end
+ of a table. */
+*|*::-moz-table-column {
+ display: table-column !important;
+}
+
+*|*::-moz-table-column-group {
+ display: table-column-group !important;
+}
+
+*|*::-moz-table-row-group {
+ display: table-row-group !important;
+}
+
+*|*::-moz-table-cell {
+ display: table-cell !important;
+ white-space: inherit;
+}
+
+/* Lists */
+
+*|*::-moz-list-bullet, *|*::-moz-list-number {
+ display: inline;
+ vertical-align: baseline;
+ -moz-margin-end: 8px;
+}
+
+/* Links */
+
+*|*:-moz-any-link {
+ cursor: pointer;
+}
+
+*|*:-moz-any-link:focus {
+ /* Don't specify the outline-color, we should always use initial value. */
+ outline: 1px dotted;
+}
+
+/* Miscellaneous */
+
+*|*::-moz-anonymous-block, *|*::-moz-cell-content {
+ display: block !important;
+ position: static !important;
+}
+
+*|*::-moz-anonymous-block, *|*::-moz-anonymous-positioned-block {
+ /* we currently inherit from the inline that is split */
+ outline: inherit;
+ outline-offset: inherit;
+ clip-path: inherit;
+ filter: inherit;
+ mask: inherit;
+ -moz-box-ordinal-group: inherit !important;
+}
+
+*|*::-moz-xul-anonymous-block {
+ display: block ! important;
+ position: static ! important;
+ float: none ! important;
+ -moz-box-ordinal-group: inherit !important;
+}
+
+*|*::-moz-scrolled-content, *|*::-moz-scrolled-canvas,
+*|*::-moz-scrolled-page-sequence {
+ /* e.g., text inputs, select boxes */
+ padding: inherit;
+ /* The display doesn't affect the kind of frame constructed here. This just
+ affects auto-width sizing of the block we create. */
+ display: block;
+ -moz-box-orient: inherit;
+ /* make unicode-bidi inherit, otherwise it has no effect on text inputs and
+ blocks with overflow: scroll; */
+ unicode-bidi: inherit;
+ -moz-column-count: inherit;
+ -moz-column-width: inherit;
+ -moz-column-gap: inherit;
+ /* Do not change these. nsCSSFrameConstructor depends on them to create a good
+ frame tree. */
+ position: static !important;
+ float: none !important;
+}
+
+*|*::-moz-viewport, *|*::-moz-viewport-scroll, *|*::-moz-canvas, *|*::-moz-scrolled-canvas {
+ display: block !important;
+ background-color: inherit;
+}
+
+*|*::-moz-viewport-scroll {
+ overflow: auto;
+}
+
+*|*::-moz-column-content {
+ /* the column boxes inside a column-flowed block */
+ /* make unicode-bidi inherit, otherwise it has no effect on column boxes */
+ unicode-bidi: inherit;
+ /* inherit the outer frame's display, otherwise we turn into an inline */
+ display: inherit !important;
+ /* Carry through our parent's height so that %-height children get
+ their heights set */
+ height: 100%;
+}
+
+*|*::-moz-page, *|*::-moz-page-sequence, *|*::-moz-scrolled-page-sequence {
+ display: block !important;
+ background: transparent;
+}
+
+*|*::-moz-pagecontent {
+ display: block !important;
+}
+
+*|*::-moz-pagebreak {
+ display: block !important;
+}
+
+*|*::-moz-anonymous-positioned-block {
+ display: block !important;
+ position: relative;
+ top: inherit;
+ left: inherit;
+ bottom: inherit;
+ right: inherit;
+ z-index: inherit;
+ clip: inherit;
+ opacity: inherit;
+}
+
+/* Printing */
+
+@media print {
+
+ * {
+ cursor: default !important;
+ }
+
+ *|*::-moz-viewport, *|*::-moz-viewport-scroll, *|*::-moz-canvas,
+ *|*::-moz-scrolled-canvas {
+ background-color: #737373 !important;
+ }
+
+}
+
+/* XML parse error reporting */
+
+parsererror|parsererror {
+ display: block;
+ font-family: sans-serif;
+ font-weight: bold;
+ white-space: pre;
+ margin: 1em;
+ padding: 1em;
+ border-width: thin;
+ border-style: inset;
+ border-color: red;
+ font-size: 14pt;
+ background-color: lightyellow;
+}
+
+parsererror|sourcetext {
+ display: block;
+ white-space: pre;
+ font-family: -moz-fixed;
+ margin-top: 2em;
+ margin-bottom: 1em;
+ color: red;
+ font-weight: bold;
+ font-size: 12pt;
+}
diff --git a/bundles/XO/res/unixcharset.properties b/bundles/XO/res/unixcharset.properties
new file mode 100755
index 0000000..d55a8b5
--- /dev/null
+++ b/bundles/XO/res/unixcharset.properties
@@ -0,0 +1,622 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1999
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# IBM Corporation
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+##
+## NOTE: THIS FILE IS DEPRECATED
+## except for those *nix systems that do not support
+## nl_langinfo(CODESET) this file should not be used
+##
+##
+## Platform specific section.
+## Map a given locale name in a particular platform (OS) to a charset name
+## This have highgher priority than the all section
+## Use this section to overwrite those locale name which *CONFLICT WITH*
+## most other platform
+## Do not use this section if the locale is unique in the platform. Only use
+## this when it have CONFLICT w/ other platform.
+##
+## Example, most platform use EUC-JP in "japanese" locale, but
+## hpux, unixware, and sco use Shift_JIS, so we put
+## locale.all.japanese=EUC-JP
+## in the all platform section and put
+## locale.HP-UXB.10.japanese=Shift_JIS
+## locale.SCOOS5.0.japanese=Shift_JIS
+## in the platform specific section
+##
+## The key is "locale." + OSTYPE + "." + locale name
+## Read mozilla/config/config.mk to find out the correct OSTYPE
+## for your system.
+##
+## References:
+## Solaris - http://www.sun.com/software/white-papers/wp-unicode/
+## - http://www.sun.com/software/white-papers/wp-eurocurrency/
+## - http://www.sun.com/software/white-papers/wp-cttlanguage/
+## AIX - http://www.software.ibm.com/ts/mqseries/library/manuals/amqaac/AMQAAC2Q.HTM
+## <have not check the following>
+## http://www.rs6000.ibm.com/doc_link/en_US/a_doc_lib/aixbman/baseadmn/locale.htm
+## HP - http://www.hp.com/unixwork/euro/release_notes/index.html
+## <have not check the following>
+## IRIX -
+##
+locale.HP-UXB.10.japanese=Shift_JIS
+locale.SCOOS5.0.japanese=Shift_JIS
+##
+## All platform section
+## Put the general locale to charset mapping here.
+## If somehow two platform use the same locale name with different
+## charset, put the least common one in the platform specific section
+## This section have lower priority than the platform specific section
+##
+## The key is "locale.all." + locale name
+# AIX
+locale.all.ar_AA=ISO-8859-6
+# AIX
+locale.all.Ar_AA=x-IBM1046
+# Solaris
+locale.all.Ar_ARM=ISO-8859-6
+locale.all.american.iso88591=ISO-8859-1
+locale.all.bulgarian=ISO-8859-2
+locale.all.bg_BG.ISO8859-5=ISO-8859-5
+# AIX
+locale.all.bg_BG=ISO-8859-5
+locale.all.C=ISO-8859-1
+# HP
+locale.all.C.iso885915=ISO-8859-15
+locale.all.c-french.iso88591=ISO-8859-1
+locale.all.chinese=GB2312
+locale.all.chinese-s=GB2312
+locale.all.chinese-t.big5=Big5
+locale.all.cs=ISO-8859-2
+locale.all.cs_CZ=ISO-8859-2
+locale.all.cs_CZ.ISO8859-2=ISO-8859-2
+locale.all.cs_CZ.88592=ISO-8859-2
+locale.all.czech=ISO-8859-2
+locale.all.da=ISO-8859-1
+# Solaris
+locale.all.da.ISO8859-15=ISO-8859-15
+locale.all.da_DK.ISO8859-15=ISO-8859-15
+locale.all.da_DK.ISO8859-15@euro=ISO-8859-15
+# Solaris
+locale.all.da.ISO8859-15@euro=ISO-8859-15
+locale.all.da_DK.88591=ISO-8859-1
+# HP
+locale.all.da_DK.iso885915@euro=ISO-8859-15
+locale.all.da_DK.ISO8859-1=ISO-8859-1
+locale.all.da_DK=ISO-8859-1
+# AIX
+#locale.all.Da_DK=IBM-850
+locale.all.danish.iso88591=ISO-8859-1
+locale.all.dutch.iso88591=ISO-8859-1
+locale.all.de=ISO-8859-1
+# Solaris
+locale.all.de.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.de.ISO8859-15@euro=ISO-8859-15
+# Solaris
+locale.all.de.UTF-8=UTF-8
+# Solaris
+locale.all.de.UTF-8@euro=UTF-8
+locale.all.de_AT=ISO-8859-1
+# Solaris
+locale.all.de_AT.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.de_AT.ISO8859-15@euro=ISO-8859-15
+locale.all.de_CH=ISO-8859-1
+locale.all.de_CH.88591=ISO-8859-1
+locale.all.de_CH.ISO8859-1=ISO-8859-1
+locale.all.de_DE.ISO8859-15=ISO-8859-15
+locale.all.de_DE.ISO8859-15@euro=ISO-8859-15
+# AIX
+#locale.all.De_CH=IBM-850
+locale.all.de_DE=ISO-8859-1
+locale.all.de_DE.88591=ISO-8859-1
+# HP
+locale.all.de_DE.iso885915=ISO-8859-15
+# HP
+locale.all.de_DE.iso885915@euro=ISO-8859-15
+locale.all.de_DE.ISO8859-1=ISO-8859-1
+# AIX
+#locale.all.De_DE=IBM-850
+# Solaris
+locale.all.el_GR.ISO8859-7=ISO-8859-7
+locale.all.el_GR.ISO8859-7@euro=ISO-8859-7
+locale.all.en_AU.ISO8859-1=ISO-8859-1
+locale.all.en_CA.ISO8859-1=ISO-8859-1
+# AIX
+locale.all.el_GR=ISO-8859-7
+locale.all.en=ISO-8859-1
+locale.all.en_AU=ISO-8859-1
+locale.all.en_CA=ISO-8859-1
+locale.all.en_GB=ISO-8859-1
+# Solaris
+locale.all.en_GB.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.en_GB.ISO8859-15@euro=ISO-8859-15
+locale.all.en_GB.88591=ISO-8859-1
+locale.all.en_GB.ISO8859-1=ISO-8859-1
+# HP
+locale.all.en_GB.iso885915@euro=ISO-8859-15
+# AIX
+#locale.all.En_GB=IBM-850
+# Solaris
+locale.all.en_IE.ISO8859-1=ISO-8859-1
+locale.all.en_IE.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.en_IE.ISO8859-15@euro=ISO-8859-15
+locale.all.en_JP=EUC-JP
+locale.all.en_JP.IBM-eucJP=EUC-JP
+locale.all.En_JP.IBM-932=Shift_JIS
+locale.all.En_JP=Shift_JIS
+locale.all.en_KR=EUC-KR
+locale.all.en_KR.IBM-eucKR=EUC-KR
+locale.all.en_TH=ISO-8859-1
+locale.all.en_TW=x-euc-tw
+locale.all.en_TW.IBM-eucTW=x-euc-tw
+locale.all.en_US=ISO-8859-1
+locale.all.en_US.88591=ISO-8859-1
+locale.all.en_US.ISO8859-1=ISO-8859-1
+#FreeBSD
+locale.all.en_US.ISO_8859-1=ISO-8859-1
+locale.all.da_DK.ISO_8859-1=ISO-8859-1
+locale.all.de_AT.ISO_8859-1=ISO-8859-1
+locale.all.de_CH.ISO_8859-1=ISO-8859-1
+locale.all.de_DE.ISO_8859-1=ISO-8859-1
+locale.all.en_AU.ISO_8859-1=ISO-8859-1
+locale.all.en_CA.ISO_8859-1=ISO-8859-1
+locale.all.en_GB.ISO_8859-1=ISO-8859-1
+locale.all.es_ES.ISO_8859-1=ISO-8859-1
+locale.all.fi_FI.ISO_8859-1=ISO-8859-1
+locale.all.fr_BE.ISO_8859-1=ISO-8859-1
+locale.all.fr_CA.ISO_8859-1=ISO-8859-1
+locale.all.fr_CH.ISO_8859-1=ISO-8859-1
+locale.all.fr_FR.ISO_8859-1=ISO-8859-1
+locale.all.is_IS.ISO_8859-1=ISO-8859-1
+locale.all.it_CH.ISO_8859-1=ISO-8859-1
+locale.all.it_IT.ISO_8859-1=ISO-8859-1
+locale.all.la_LN.ISO_8859-1=ISO-8859-1
+locale.all.nl_BE.ISO_8859-1=ISO-8859-1
+locale.all.nl_NL.ISO_8859-1=ISO-8859-1
+locale.all.no_NO.ISO_8859-1=ISO-8859-1
+locale.all.pt_PT.ISO_8859-1=ISO-8859-1
+locale.all.sv_SE.ISO_8859-1=ISO-8859-1
+# FreeBSD 8859-15
+locale.all.da_DK.DIS_8859-15=ISO-8859-15
+locale.all.de_AT.DIS_8859-15=ISO-8859-15
+locale.all.de_CH.DIS_8859-15=ISO-8859-15
+locale.all.de_DE.DIS_8859-15=ISO-8859-15
+locale.all.en_AU.DIS_8859-15=ISO-8859-15
+locale.all.en_CA.DIS_8859-15=ISO-8859-15
+locale.all.en_GB.DIS_8859-15=ISO-8859-15
+locale.all.en_US.DIS_8859-15=ISO-8859-15
+locale.all.es_ES.DIS_8859-15=ISO-8859-15
+locale.all.fi_FI.DIS_8859-15=ISO-8859-15
+locale.all.fr_BE.DIS_8859-15=ISO-8859-15
+locale.all.fr_CA.DIS_8859-15=ISO-8859-15
+locale.all.fr_CH.DIS_8859-15=ISO-8859-15
+locale.all.fr_FR.DIS_8859-15=ISO-8859-15
+locale.all.is_IS.DIS_8859-15=ISO-8859-15
+locale.all.it_CH.DIS_8859-15=ISO-8859-15
+locale.all.it_IT.DIS_8859-15=ISO-8859-15
+locale.all.la_LN.DIS_8859-15=ISO-8859-15
+locale.all.nl_BE.DIS_8859-15=ISO-8859-15
+locale.all.nl_NL.DIS_8859-15=ISO-8859-15
+locale.all.no_NO.DIS_8859-15=ISO-8859-15
+locale.all.pt_PT.DIS_8859-15=ISO-8859-15
+locale.all.sv_SE.DIS_8859-15=ISO-8859-15
+# FreeBSD 8859-2
+locale.all.cs_CZ.ISO_8859-2=ISO-8859-2
+locale.all.hr_HR.ISO_8859-2=ISO-8859-2
+locale.all.hu_HU.ISO_8859-2=ISO-8859-2
+locale.all.la_LN.ISO_8859-2=ISO-8859-2
+locale.all.pl_PL.ISO_8859-2=ISO-8859-2
+locale.all.sl_SI.ISO_8859-2=ISO-8859-2
+# FreeBSD 8859-4
+locale.all.la_LN.ISO_8859-4=ISO-8859-4
+locale.all.lt_LT.ISO_8859-4=ISO-8859-4
+# FreeBSD 8859-5
+locale.all.ru_RU.ISO_8859-5=ISO-8859-5
+locale.all.ru_SU.ISO_8859-5=ISO-8859-5
+# FreeBSD Russian
+locale.all.ru_SU.KOI8-R=KOI8-R
+# FreeBSD Ukrainian
+locale.all.uk_UA.KOI8-U=KOI8-U
+# Solaris
+locale.all.en_US.UTF-8=UTF-8
+# Solaris
+locale.all.en_US.UTF-8@euro=UTF-8
+# AIX
+#locale.all.En_US=IBM-850
+locale.all.english.iso88591=ISO-8859-1
+locale.all.es=ISO-8859-1
+# Solaris
+locale.all.es.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.es.ISO8859-15@euro=ISO-8859-15
+# Solaris
+locale.all.es.UTF-8=UTF-8
+# Solaris
+locale.all.es.UTF-8@euro=UTF-8
+locale.all.es_ES=ISO-8859-1
+locale.all.es_ES.ISO8859-15=ISO-8859-15
+locale.all.es_ES.ISO8859-15@euro=ISO-8859-15
+locale.all.es_AR.ISO8859-1=ISO-8859-1
+locale.all.es_BO.ISO8859-1=ISO-8859-1
+locale.all.es_CL.ISO8859-1=ISO-8859-1
+locale.all.es_CO.ISO8859-1=ISO-8859-1
+locale.all.es_CR.ISO8859-1=ISO-8859-1
+locale.all.es_EC.ISO8859-1=ISO-8859-1
+locale.all.es_GT.ISO8859-1=ISO-8859-1
+locale.all.es_MX.ISO8859-1=ISO-8859-1
+locale.all.es_NI.ISO8859-1=ISO-8859-1
+locale.all.es_PA.ISO8859-1=ISO-8859-1
+locale.all.es_PE.ISO8859-1=ISO-8859-1
+locale.all.es_PY.ISO8859-1=ISO-8859-1
+locale.all.es_SV.ISO8859-1=ISO-8859-1
+locale.all.es_UY.ISO8859-1=ISO-8859-1
+locale.all.es_VE.ISO8859-1=ISO-8859-1
+# HP
+locale.all.es_ES.iso885915=ISO-8859-15
+# HP
+locale.all.es_ES.iso885915@euro=ISO-8859-15
+locale.all.es_ES.88591=ISO-8859-1
+locale.all.es_ES.ISO8859-1=ISO-8859-1
+# AIX
+#locale.all.En_ES=IBM-850
+# Solaris
+locale.all.et_EE.ISO8859-15=ISO-8859-15
+# AIX
+#locale.all.Et_ET=IBM-922
+# AIX
+locale.all.ET_ET=UTF-8
+locale.all.fi=ISO-8859-1
+# Solaris
+locale.all.fi.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.fi.ISO8859-15@euro=ISO-8859-15
+locale.all.fi_FI=ISO-8859-1
+locale.all.fi_FI.88591=ISO-8859-1
+locale.all.fi_FI.ISO8859-1=ISO-8859-1
+locale.all.fi_FI.ISO8859-15=ISO-8859-15
+locale.all.fi_FI.ISO8859-15@euro=ISO-8859-15
+# HP
+locale.all.fi_FI.iso885915@euro=ISO-8859-15
+# AIX
+#locale.all.Fi_ES=IBM-850
+locale.all.finnish.iso88591=ISO-8859-1
+locale.all.fr=ISO-8859-1
+# Solaris
+locale.all.fr.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.fr.ISO8859-15@euro=ISO-8859-15
+# Solaris
+locale.all.fr.UTF-8=UTF-8
+# Solaris
+locale.all.fr.UTF-8@euro=UTF-8
+locale.all.fr_BE=ISO-8859-1
+# Solaris
+locale.all.fr_BE.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.fr_BE.ISO8859-15@euro=ISO-8859-15
+locale.all.fr_BE.88591=ISO-8859-1
+locale.all.fr_BE.ISO8859-1=ISO-8859-1
+locale.all.fr_BE.iso8859=ISO-8859-1
+# AIX
+#locale.all.Fr_BE=IBM-850
+locale.all.fr_CA=ISO-8859-1
+locale.all.fr_CA.88591=ISO-8859-1
+locale.all.fr_CA.iso8859=ISO-8859-1
+# HP
+locale.all.fr_CA.iso885915@euro=ISO-8859-15
+locale.all.fr_CA.ISO8859-1=ISO-8859-1
+# AIX
+#locale.all.Fr_CA=IBM-850
+locale.all.fr_CH=ISO-8859-1
+locale.all.fr_CH.88591=ISO-8859-1
+locale.all.fr_CH.iso8859=ISO-8859-1
+locale.all.fr_CH.ISO8859-1=ISO-8859-1
+# Solaris
+locale.all.fr_FR.ISO8859-15=ISO-8859-15
+locale.all.fr_FR.ISO8859-15@euro=ISO-8859-15
+# AIX
+#locale.all.Fr_CH=IBM-850
+locale.all.fr_FR=ISO-8859-1
+locale.all.fr_FR.88591=ISO-8859-1
+locale.all.fr_FR.iso8859=ISO-8859-1
+# HP
+locale.all.fr_FR.iso885915=ISO-8859-15
+# HP
+locale.all.fr_FR.iso885915@euro=ISO-8859-15
+locale.all.fr_FR.ISO8859-1=ISO-8859-1
+# AIX
+#locale.all.Fr_FR=IBM-850
+locale.all.french.iso88591=ISO-8859-1
+locale.all.german.iso88591=ISO-8859-1
+# Solaris
+locale.all.he_HE=ISO-8859-8
+locale.all.he_IL=ISO-8859-8
+locale.all.hr_HR.ISO8859-2=ISO-8859-2
+# AIX
+locale.all.hr_HR=ISO-8859-2
+locale.all.hu_HU=ISO-8859-2
+locale.all.hu_HU.88592=ISO-8859-2
+locale.all.hu_HU.ISO8859-2=ISO-8859-2
+locale.all.hungarian=ISO-8859-2
+locale.all.icelandic.iso88591=ISO-8859-1
+locale.all.iso_8859_1=ISO-8859-1
+locale.all.is=ISO-8859-1
+locale.all.is_IS=ISO-8859-1
+locale.all.is_IS.88591=ISO-8859-1
+locale.all.is_IS.ISO8859-1=ISO-8859-1
+# HP
+locale.all.is_IS.iso885915@euro=ISO-8859-15
+# AIX
+#locale.all.Is_IS=IBM-850
+locale.all.it=ISO-8859-1
+# Solaris
+locale.all.it.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.it.ISO8859-15@euro=ISO-8859-15
+# Solaris
+locale.all.it.UTF-8=UTF-8
+# Solaris
+locale.all.it.UTF-8@euro=UTF-8
+locale.all.it_IT.ISO8859-15=ISO-8859-15
+locale.all.it_IT.ISO8859-15@euro=ISO-8859-15
+# AIX
+#locale.all.It_IT=IBM-850
+locale.all.italian.iso8859-1=ISO-8859-1
+locale.all.it_CH=ISO-8859-1
+locale.all.it_IT=ISO-8859-1
+locale.all.it_IT.88591=ISO-8859-1
+locale.all.it_IT.ISO8859-1=ISO-8859-1
+# HP
+locale.all.it_IT.iso885915=ISO-8859-15
+# HP
+locale.all.it_IT.iso885915@euro=ISO-8859-15
+# AIX
+locale.all.iw_IL=ISO-8859-8
+# AIX
+#locale.all.Iw_IL=IBM-856
+locale.all.ja=EUC-JP
+locale.all.Ja_JP.IBM-932=Shift_JIS
+locale.all.Ja_JP=Shift_JIS
+locale.all.japanese=EUC-JP
+locale.all.japanese.euc=EUC-JP
+locale.all.ja_JP=EUC-JP
+# Solaris
+locale.all.ja_JP.UTF-8=UTF-8
+# Solaris
+locale.all.ja_JP.UTF-8@euro=UTF-8
+locale.all.ja_JP.EUC=EUC-JP
+locale.all.ja_JP.eucJP=EUC-JP
+locale.all.ja_JP.SJIS=Shift_JIS
+locale.all.ja_JP.PCK=Shift_JIS
+locale.all.ja_JP.IBM-eucJP=EUC-JP
+locale.all.ja_JP.mscode=Shift_JIS
+locale.all.ja_JP.ujis=EUC-JP
+locale.all.katakana=Shift_JIS
+locale.all.ko=EUC-KR
+locale.all.ko_KR=EUC-KR
+# Solaris
+locale.all.ko_KR.UTF-8=UTF-8
+# Solaris
+locale.all.ko_KR.UTF-8@euro=UTF-8
+locale.all.ko_KR.euc=EUC-KR
+locale.all.ko_KR.euckr=EUC-KR
+locale.all.ko_KR.eucKR=EUC-KR
+locale.all.ko_KR.IBM-eucKR=EUC-KR
+locale.all.ko_KR.EUC=EUC-KR
+locale.all.ko.UTF-8=UTF-8
+locale.all.korean=EUC-KR
+# Solaris
+locale.all.lt_LT.ISO8859-13=ISO-8859-13
+# AIX
+#locale.all.Lt_LT=IBM-921
+# AIX
+locale.all.LT_LT=UTF-8
+# Solaris
+locale.all.lv_LV.ISO8859-13=ISO-8859-13
+# AIX
+#locale.all.Lt_LV=IBM-921
+# AIX
+locale.all.LT_LV=UTF-8
+# Solaris
+locale.all.mk_MK.ISO8859-5=ISO-8859-5
+# AIX
+locale.all.mk_MK=ISO-8859-5
+locale.all.nl=ISO-8859-1
+# Solaris
+locale.all.nl.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.nl.ISO8859-15@euro=ISO-8859-15
+locale.all.nl_BE=ISO-8859-1
+# Solaris
+locale.all.nl_BE.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.nl_BE.ISO8859-15@euro=ISO-8859-15
+locale.all.nl_BE.88591=ISO-8859-1
+locale.all.nl_BE.ISO8859-1=ISO-8859-1
+# Solaris
+locale.all.nl_NL.ISO8859-15=ISO-8859-15
+locale.all.nl_NL.ISO8859-15@euro=ISO-8859-15
+# AIX
+#locale.all.NL_BE=IBM-850
+locale.all.nl_NL=ISO-8859-1
+locale.all.nl_NL.88591=ISO-8859-1
+locale.all.nl_NL.ISO8859-1=ISO-8859-1
+# HP
+locale.all.nl_NL.iso885915@euro=ISO-8859-15
+# AIX
+#locale.all.NL_NL=IBM-850
+locale.all.no=ISO-8859-1
+locale.all.no_NO=ISO-8859-1
+locale.all.no_NO.88591=ISO-8859-1
+locale.all.no_NO.ISO8859-1=ISO-8859-1
+# Solaris
+locale.all.no_NO.ISO8859-1@bokmal=ISO-8859-1
+locale.all.no_NO.ISO8859-1@nynorsk=ISO-8859-1
+# HP
+locale.all.no_NO.iso885915@euro=ISO-8859-15
+# AIX
+#locale.all.No_NO=IBM-850
+locale.all.norwegian.iso88591=ISO-8859-1
+locale.all.pl=ISO-8859-2
+locale.all.pl_PL=ISO-8859-2
+locale.all.pl_PL.88592=ISO-8859-2
+locale.all.pl_PL.ISO8859-2=ISO-8859-2
+locale.all.polish=ISO-8859-2
+locale.all.portuguese.iso88591=ISO-8859-1
+locale.all.pt=ISO-8859-1
+# Solaris
+locale.all.pt.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.pt.ISO8859-15@euro=ISO-8859-15
+# Solaris
+locale.all.pt_BR.ISO8859-1=ISO-8859-1
+locale.all.pt_PT.ISO8859-15=ISO-8859-15
+locale.all.pt_PT.ISO8859-15@euro=ISO-8859-15
+# AIX
+#locale.all.Pt.PT=IBM-850
+locale.all.pt_PT=ISO-8859-1
+locale.all.pt_PT.88591=ISO-8859-1
+# HP
+locale.all.pt_PT.iso885915@euro=ISO-8859-15
+locale.all.pt_PT.ISO8859-1=ISO-8859-1
+# Solaris
+locale.all.ro_RO.ISO8859-2=ISO-8859-2
+# AIX
+locale.all.ro_RO=ISO-8859-5
+# Solaris
+#locale.all.ru_RU.ANSI1251= ??? ANSI-1251 ???
+locale.all.ru_RU.ISO8859-5=ISO-8859-5
+# AIX
+locale.all.ru_RU=ISO-8859-5
+locale.all.ru_RU.KOI8-R=KOI8-R
+# RedHat 7 reported by Garaschenko Slava <slava@maze.ambernet.kiev.ua bug 70601
+locale.all.ru_RU.koi8r=KOI8-R
+# RedHat 7 reported by Garaschenko Slava <slava@maze.ambernet.kiev.ua bug 70601
+locale.all.ru_UA=KOI8-U
+locale.all.rumanian=ISO-8859-2
+locale.all.serbocroatian=ISO-8859-2
+locale.all.sh=ISO-8859-2
+# Solaris
+locale.all.sh_BA.ISO8859-2@bosnia=ISO-8859-2
+locale.all.sl_SI.ISO8859-2=ISO-8859-2
+locale.all.sq_AL.ISO8859-2=ISO-8859-2
+# AIX
+locale.all.sh_SP=ISO-8859-2
+locale.all.sk=ISO-8859-2
+locale.all.sk_SK=ISO-8859-2
+locale.all.sk_SK.88592=ISO-8859-2
+locale.all.sk_SK.ISO8859-2=ISO-8859-2
+locale.all.slovene=ISO-8859-2
+locale.all.spanish.iso88591=ISO-8859-1
+# AIX
+locale.all.sq_AL=ISO-8859-1
+# Solaris
+locale.all.sr_YU.ISO8859-5=ISO-8859-5
+# AIX
+locale.all.sr_SP=ISO-8859-5
+locale.all.sv=ISO-8859-1
+# Solaris
+locale.all.sv.ISO8859-15=ISO-8859-15
+# Solaris
+locale.all.sv.ISO8859-15@euro=ISO-8859-15
+# Solaris
+locale.all.sv.UTF-8=UTF-8
+# Solaris
+locale.all.sv.UTF-8@euro=UTF-8
+locale.all.sv_SE=ISO-8859-1
+locale.all.sv_SE.88591=ISO-8859-1
+locale.all.sv_SE.ISO8859-15=ISO-8859-15
+locale.all.sv_SE.ISO8859-15@euro=ISO-8859-15
+# HP
+locale.all.sv_SE.iso885915=ISO-8859-15
+# HP
+locale.all.sv_SE.iso885915@euro=ISO-8859-15
+locale.all.sv_SE.ISO8859-1=ISO-8859-1
+locale.all.Sv_SE=IBM-850
+# AIX
+locale.all.swedish.iso88591=ISO-8859-1
+# Solaris
+locale.all.tr_TR.ISO8859-9=ISO-8859-9
+# AIX
+locale.all.tr_TR=ISO-8859-9
+# Solaris
+locale.all.th_TH=TIS-620
+locale.all.th_TH.TIS620=TIS-620
+locale.all.th=TIS-620
+locale.all.th_TH.UTF-8=UTF-8
+locale.all.tchinese=x-euc-tw
+# RedHat 7 reported by Garaschenko Slava <slava@maze.ambernet.kiev.ua bug 70601
+locale.all.uk_UA=KOI8-U
+locale.all.zh=GB2312
+locale.all.zh_CN=GB2312
+locale.all.zh_CN.EUC=GB2312
+locale.all.zh.GBK=x-gbk
+locale.all.zh_CN.UTF-8=UTF-8
+locale.all.zh.UTF-8=UTF-8
+locale.all.zh_TW.EUC=x-euc-tw
+locale.all.zh_TW.BIG5=Big5
+locale.all.zh_HK.HKSCS=x-hkscs
+# saw the following name from news://xcin.linux.org.tw/tlug.cle-devel
+locale.all.zh_CN.GB2312=GB2312
+# AIX
+locale.all.ZH_CN=UTF-8
+locale.all.zh_CN.ugb=GB2312
+locale.all.zh_CN.GBK=x-gbk
+locale.all.zh_HK.big5=Big5
+locale.all.zh_HK.eucTW=x-euc-tw
+locale.all.zh_TW=x-euc-tw
+locale.all.zh_TW.IBM-eucTW=x-euc-tw
+locale.all.zh_TW.eucTW=x-euc-tw
+locale.all.zh_TW.eucTW@chuyin=x-euc-tw
+locale.all.zh_TW.eucTW@radical=x-euc-tw
+locale.all.zh_TW.eucTW@stroke=x-euc-tw
+locale.all.zh_TW.big5=Big5
+locale.all.zh_TW.big5@chuyin=Big5
+locale.all.zh_TW.big5@radical=Big5
+locale.all.zh_TW.big5@stroke=Big5
+locale.all.zh_TW.ucns=x-euc-tw
+# AIX
+locale.all.Zh_TW.big5=Big5
+# CLE 0.8
+locale.all.zh_TW.Big5=Big5
+# SunOS 5.7 according to pofeng@linux.org.tw (already above)
+# locale.all.zh_TW.BIG5=Big5
+# OpenVMS
+locale.all.ja_JP.sdeckanji=EUC-JP
diff --git a/bundles/XO/res/viewsource.css b/bundles/XO/res/viewsource.css
new file mode 100755
index 0000000..3305897
--- /dev/null
+++ b/bundles/XO/res/viewsource.css
@@ -0,0 +1,119 @@
+@charset "utf-8";
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Blake Ross <BlakeR1234@aol.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+@namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
+
+*|*:root {
+ background-color: white;
+}
+#viewsource {
+ font-family: -moz-fixed;
+ font-weight: normal;
+ color: black;
+ white-space: pre;
+}
+#viewsource.wrap {
+ white-space: pre-wrap;
+ word-wrap: break-word;
+}
+pre {
+ font: inherit;
+ color: inherit;
+ white-space: inherit;
+ margin: 0;
+}
+.start-tag {
+ color: purple;
+ font-weight: bold;
+}
+.end-tag {
+ color: purple;
+ font-weight: bold;
+}
+.comment {
+ color: green;
+ font-style: italic;
+}
+.cdata {
+ color: #CC0066;
+}
+.doctype {
+ color: steelblue;
+ font-style: italic;
+}
+.pi {
+ color: orchid;
+ font-style: italic;
+}
+.entity {
+ color:#FF4500;
+ font-weight: normal;
+}
+.text {
+ font-weight: normal;
+}
+.attribute-name {
+ color: black;
+ font-weight: bold;
+}
+.attribute-value {
+ color: blue;
+ font-weight: normal;
+}
+.summary {
+ display: block;
+ background-color: #FFFFCC;
+ width: 90%;
+ border: solid;
+ border-width: 1pt;
+ font-family: sans-serif;
+}
+.popup {
+ font-weight: normal;
+}
+.markupdeclaration {
+ color: steelblue;
+ font-style: italic;
+}
+.error, .error > .start-tag, .error > .end-tag,
+.error > .comment, .error > .cdata, .error > .doctype,
+.error > .pi, .error > .entity, .error > .attribute-name,
+.error > .attribute-value {
+ color: red;
+ font-weight: bold;
+}
diff --git a/bundles/XO/run-mozilla.sh b/bundles/XO/run-mozilla.sh
new file mode 100755
index 0000000..37e81b7
--- /dev/null
+++ b/bundles/XO/run-mozilla.sh
@@ -0,0 +1,401 @@
+#!/bin/sh
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+cmdname=`basename "$0"`
+MOZ_DIST_BIN=`dirname "$0"`
+MOZ_DEFAULT_NAME="./${cmdname}-bin"
+MOZ_APPRUNNER_NAME="./mozilla-bin"
+MOZ_VIEWER_NAME="./viewer"
+MOZ_PROGRAM=""
+
+exitcode=0
+#
+##
+## Functions
+##
+##########################################################################
+moz_usage()
+{
+echo "Usage: ${cmdname} [options] [program]"
+echo ""
+echo " options:"
+echo ""
+echo " -g Run in debugger."
+echo " --debug"
+echo ""
+echo " -d debugger Debugger to use."
+echo " --debugger debugger"
+echo ""
+echo " Examples:"
+echo ""
+echo " Run the viewer"
+echo ""
+echo " ${cmdname} viewer"
+echo ""
+echo " Run the mozilla-bin binary"
+echo ""
+echo " ${cmdname} mozilla-bin"
+echo ""
+echo " Debug the viewer in a debugger"
+echo ""
+echo " ${cmdname} -g viewer"
+echo ""
+echo " Debug the mozilla-bin binary in gdb"
+echo ""
+echo " ${cmdname} -g mozilla-bin -d gdb"
+echo ""
+ return 0
+}
+##########################################################################
+moz_bail()
+{
+ message=$1
+ echo
+ echo "$cmdname: $message"
+ echo
+ exit 1
+}
+##########################################################################
+moz_test_binary()
+{
+ binary=$1
+ if [ -f "$binary" ]
+ then
+ if [ -x "$binary" ]
+ then
+ return 1
+ fi
+ fi
+ return 0
+}
+##########################################################################
+moz_get_debugger()
+{
+ debuggers="ddd gdb dbx bdb"
+ debugger="notfound"
+ done="no"
+ for d in $debuggers
+ do
+ moz_test_binary /bin/type
+ if [ $? -eq 1 ]
+ then
+ dpath=`LC_MESSAGES=C type ${d} | awk '{print $3;}' | sed -e 's/\.$//'`
+ else
+ dpath=`which ${d}`
+ fi
+ if [ -x "$dpath" ]
+ then
+ debugger=$dpath
+ break
+ fi
+ done
+ echo $debugger
+ return 0
+}
+##########################################################################
+moz_run_program()
+{
+ prog=$MOZ_PROGRAM
+ ##
+ ## Make sure the program is executable
+ ##
+ if [ ! -x "$prog" ]
+ then
+ moz_bail "Cannot execute $prog."
+ fi
+ ##
+ ## Run the program
+ ##
+ "$prog" ${1+"$@"}
+ exitcode=$?
+}
+##########################################################################
+moz_debug_program()
+{
+ prog=$MOZ_PROGRAM
+ ##
+ ## Make sure the program is executable
+ ##
+ if [ ! -x "$prog" ]
+ then
+ moz_bail "Cannot execute $prog."
+ fi
+ if [ -n "$moz_debugger" ]
+ then
+ moz_test_binary /bin/type
+ if [ $? -eq 1 ]
+ then
+ debugger=`LC_MESSAGES=C type $moz_debugger | awk '{print $3;}' | sed -e 's/\.$//'`
+ else
+ debugger=`which $moz_debugger`
+ fi
+ else
+ debugger=`moz_get_debugger`
+ fi
+ if [ -x "$debugger" ]
+ then
+ tmpfile=`mktemp /tmp/mozargs.XXXXXX` || { echo "Cannot create temporary file" >&2; exit 1; }
+ trap " [ -f \"$tmpfile\" ] && /bin/rm -f -- \"$tmpfile\"" 0 1 2 3 13 15
+ # echo -n isn't portable, so pipe through perl -pe chomp instead
+ echo "set args" | perl -pe 'chomp' > $tmpfile
+ for PARAM in "$@"
+ do
+ echo " '$PARAM'" | perl -pe 'chomp' >> $tmpfile
+ done
+ echo >> $tmpfile
+# If you are not using ddd, gdb and know of a way to convey the arguments
+# over to the prog then add that here- Gagan Saksena 03/15/00
+ case `basename $debugger` in
+ gdb) echo "$debugger $prog -x $tmpfile"
+ $debugger "$prog" -x $tmpfile
+ exitcode=$?
+ ;;
+ ddd) echo "$debugger --debugger \"gdb -x $tmpfile\" $prog"
+ $debugger --debugger "gdb -x $tmpfile" "$prog"
+ exitcode=$?
+ ;;
+ *) echo "$debugger $prog ${1+"$@"}"
+ $debugger "$prog" ${1+"$@"}
+ exitcode=$?
+ ;;
+ esac
+ else
+ echo "Could not find a debugger on your system."
+ fi
+}
+##########################################################################
+##
+## Command line arg defaults
+##
+moz_debug=0
+moz_debugger=""
+#
+##
+## Parse the command line
+##
+while [ $# -gt 0 ]
+do
+ case $1 in
+ -g | --debug)
+ moz_debug=1
+ shift
+ ;;
+ -d | --debugger)
+ moz_debugger=$2;
+ if [ "${moz_debugger}" != "" ]; then
+ shift 2
+ else
+ echo "-d requires an argument"
+ exit 1
+ fi
+ ;;
+ *)
+ break;
+ ;;
+ esac
+done
+#
+##
+## Program name given in $1
+##
+if [ $# -gt 0 ]
+then
+ MOZ_PROGRAM=$1
+ shift
+fi
+##
+## Program not given, try to guess a default
+##
+if [ -z "$MOZ_PROGRAM" ]
+then
+ ##
+ ## Try this script's name with '-bin' appended
+ ##
+ if [ -x "$MOZ_DEFAULT_NAME" ]
+ then
+ MOZ_PROGRAM=$MOZ_DEFAULT_NAME
+ ## Try viewer (this should be deprecated)
+ ##
+ elif [ -x "$MOZ_VIEWER_NAME" ]
+ then
+ MOZ_PROGRAM=$MOZ_VIEWER_NAME
+ ##
+ ## Try mozilla-bin
+ ##
+ elif [ -x "$MOZ_APPRUNNER_NAME" ]
+ then
+ MOZ_PROGRAM=$MOZ_APPRUNNER_NAME
+ fi
+fi
+#
+#
+##
+## Make sure the program is executable
+##
+if [ ! -x "$MOZ_PROGRAM" ]
+then
+ moz_bail "Cannot execute $MOZ_PROGRAM."
+fi
+#
+##
+## Set MOZILLA_FIVE_HOME
+##
+MOZILLA_FIVE_HOME=$MOZ_DIST_BIN
+
+if [ -z "$MRE_HOME" ]; then
+ MRE_HOME=$MOZILLA_FIVE_HOME
+fi
+##
+## Set LD_LIBRARY_PATH
+##
+## On Solaris we use $ORIGIN (set in RUNPATH) instead of LD_LIBRARY_PATH
+## to locate shared libraries.
+##
+## When a shared library is a symbolic link, $ORIGIN will be replaced with
+## the real path (i.e., what the symbolic link points to) by the runtime
+## linker. For example, if dist/bin/libxul.so is a symbolic link to
+## toolkit/library/libxul.so, $ORIGIN will be "toolkit/library" instead of "dist/bin".
+## So the runtime linker will use "toolkit/library" NOT "dist/bin" to locate the
+## other shared libraries that libxul.so depends on. This only happens
+## when a user (developer) tries to start firefox, thunderbird, or seamonkey
+## under dist/bin. To solve the problem, we should rely on LD_LIBRARY_PATH
+## to locate shared libraries.
+##
+## Note:
+## We test $MOZ_DIST_BIN/*.so. If any of them is a symbolic link,
+## we need to set LD_LIBRARY_PATH.
+##########################################################################
+moz_should_set_ld_library_path()
+{
+ [ `uname -s` != "SunOS" ] && return 0
+ for sharedlib in $MOZ_DIST_BIN/*.so
+ do
+ [ -h $sharedlib ] && return 0
+ done
+ return 1
+}
+if moz_should_set_ld_library_path
+then
+ LD_LIBRARY_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARY_PATH+":$LD_LIBRARY_PATH"}
+fi
+
+if [ -n "$LD_LIBRARYN32_PATH" ]
+then
+ LD_LIBRARYN32_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARYN32_PATH+":$LD_LIBRARYN32_PATH"}
+fi
+if [ -n "$LD_LIBRARYN64_PATH" ]
+then
+ LD_LIBRARYN64_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARYN64_PATH+":$LD_LIBRARYN64_PATH"}
+fi
+if [ -n "$LD_LIBRARY_PATH_64" ]; then
+ LD_LIBRARY_PATH_64=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/plugins:${MRE_HOME}${LD_LIBRARY_PATH_64+":$LD_LIBRARY_PATH_64"}
+fi
+#
+#
+## Set SHLIB_PATH for HPUX
+SHLIB_PATH=${MOZ_DIST_BIN}:${MRE_HOME}${SHLIB_PATH+":$SHLIB_PATH"}
+#
+## Set LIBPATH for AIX
+LIBPATH=${MOZ_DIST_BIN}:${MRE_HOME}${LIBPATH+":$LIBPATH"}
+#
+## Set DYLD_LIBRARY_PATH for Mac OS X (Darwin)
+DYLD_LIBRARY_PATH=${MOZ_DIST_BIN}:${MRE_HOME}${DYLD_LIBRARY_PATH+":$DYLD_LIBRARY_PATH"}
+#
+## Set LIBRARY_PATH for BeOS
+LIBRARY_PATH=${MOZ_DIST_BIN}:${MOZ_DIST_BIN}/components:${MRE_HOME}${LIBRARY_PATH+":$LIBRARY_PATH"}
+#
+## Set ADDON_PATH for BeOS
+ADDON_PATH=${MOZ_DIST_BIN}${ADDON_PATH+":$ADDON_PATH"}
+#
+## Solaris Xserver(Xsun) tuning - use shared memory transport if available
+if [ "$XSUNTRANSPORT" = "" ]
+then
+ XSUNTRANSPORT="shmem"
+ XSUNSMESIZE="512"
+ export XSUNTRANSPORT XSUNSMESIZE
+fi
+
+# Disable Gnome crash dialog
+GNOME_DISABLE_CRASH_DIALOG=1
+export GNOME_DISABLE_CRASH_DIALOG
+
+if [ "$moz_debug" -eq 1 ]
+then
+ echo "MOZILLA_FIVE_HOME=$MOZILLA_FIVE_HOME"
+ echo " LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
+ if [ -n "$LD_LIBRARYN32_PATH" ]
+ then
+ echo "LD_LIBRARYN32_PATH=$LD_LIBRARYN32_PATH"
+ fi
+ if [ -n "$LD_LIBRARYN64_PATH" ]
+ then
+ echo "LD_LIBRARYN64_PATH=$LD_LIBRARYN64_PATH"
+ fi
+ if [ -n "$LD_LIBRARY_PATH_64" ]; then
+ echo "LD_LIBRARY_PATH_64=$LD_LIBRARY_PATH_64"
+ fi
+ if [ -n "$DISPLAY" ]; then
+ echo "DISPLAY=$DISPLAY"
+ fi
+ if [ -n "$FONTCONFIG_PATH" ]; then
+ echo "FONTCONFIG_PATH=$FONTCONFIG_PATH"
+ fi
+ if [ -n "$MOZILLA_POSTSCRIPT_PRINTER_LIST" ]; then
+ echo "MOZILLA_POSTSCRIPT_PRINTER_LIST=$MOZILLA_POSTSCRIPT_PRINTER_LIST"
+ fi
+ echo "DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH"
+ echo " LIBRARY_PATH=$LIBRARY_PATH"
+ echo " SHLIB_PATH=$SHLIB_PATH"
+ echo " LIBPATH=$LIBPATH"
+ echo " ADDON_PATH=$ADDON_PATH"
+ echo " MOZ_PROGRAM=$MOZ_PROGRAM"
+ echo " MOZ_TOOLKIT=$MOZ_TOOLKIT"
+ echo " moz_debug=$moz_debug"
+ echo " moz_debugger=$moz_debugger"
+fi
+#
+export MOZILLA_FIVE_HOME LD_LIBRARY_PATH
+export SHLIB_PATH LIBPATH LIBRARY_PATH ADDON_PATH DYLD_LIBRARY_PATH
+
+if [ $moz_debug -eq 1 ]
+then
+ moz_debug_program ${1+"$@"}
+else
+ moz_run_program ${1+"$@"}
+fi
+
+exit $exitcode
diff --git a/bundles/XO/searchplugins/amazondotcom.xml b/bundles/XO/searchplugins/amazondotcom.xml
new file mode 100755
index 0000000..b5e42dd
--- /dev/null
+++ b/bundles/XO/searchplugins/amazondotcom.xml
@@ -0,0 +1,13 @@
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>Amazon.com</ShortName>
+<Description>Amazon.com Search</Description>
+<InputEncoding>ISO-8859-1</InputEncoding>
+<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHgSURBVHjalFM9TNtQEP4cB7PwM1RITUXIgsRaYEEVEyKZwhiyZAQyd0BhpFOlIjoBqhjSqVQMoVMLLAjEwECCQJkSkBqJYDOAFOMKFSf28d7DTUxiUDnp/Pzeu/vuu7t3ICKF6SLTMv2/lB0fRWKfjwDm4JJisYh0Oo3fpZLYT0SjSCQS8JAFMADNDZ3NZsnf1taiqVTKi4nGASruk5lkkmTmMB6JUKFQqO+DfX1eABWeQoVR6f7HSdM0obqu48Yw8G1tDT82NsRd1TSbU9BbGPCog8PDj+jLzurFoAVgMh4XxoNDQ6SqKi0tL9eBvAB8zZwymYxYY7EYAoEA8vm82BNTg6XUIs0MeGTZoR1mhXSnwNl4pmAbjU7mcjkKhkL1ynMnntZ4OEw3VyrV8utk7s5TdW++0QXz+1i3P7IK36t+PCfVn1OQOoOA0gXr5DPak+cPXbBK+/T3S69AtY3LJ98vZ1or/iLr+pTuvr59/A6s003UdqZFJF/PCKQ3o5CUznoBST2AfbEF/9iqYEDaIfwj73VJPEfgNTe0tWNYR0uwy9uOW0OkrgHI7z5ADo2C7v48nLV3XHKAT+x/1m1sX58xsBxg8rZJrDYD8DHHp4aJj/MK09sXjPOt46PcCzAACXY8/u34wN0AAAAASUVORK5CYII=</Image>
+<Url type="text/html" method="GET" template="http://www.amazon.com/exec/obidos/external-search/">
+ <Param name="field-keywords" value="{searchTerms}"/>
+ <Param name="mode" value="blended"/>
+ <Param name="tag" value="mozilla-20"/>
+ <Param name="sourceid" value="Mozilla-search"/>
+</Url>
+<SearchForm>http://www.amazon.com/</SearchForm>
+</SearchPlugin>
diff --git a/bundles/XO/searchplugins/answers.xml b/bundles/XO/searchplugins/answers.xml
new file mode 100755
index 0000000..f272397
--- /dev/null
+++ b/bundles/XO/searchplugins/answers.xml
@@ -0,0 +1,13 @@
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>Answers.com</ShortName>
+<Description>Dictionary Search on Answers.com</Description>
+<InputEncoding>UTF-8</InputEncoding>
+<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////K////4f////E////5f///+n////P////mv///0EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8E////fv///+//////////////////////7NnP/+LFtv/////+////of///xYAAAAAAAAAAAAAAAD///8D////lf////////////j0//bi1v/OlXf/tGU9/6FCEv/OmH3////////////////D////FgAAAAAAAAAA////avPm4P/evaz/8NbI//7r3//23M3/xYRi/5kzAP/Df1z//u/l//749P/v4dn/+PPw/////6j///8B////GP///+W/f1//smM7//bczf/+69///uvf/9ytlP+ZMwD/5se3/+/f1//AgmP/nj0N/927qv/////+////QP///2z/////8NvQ/8WCYP/+69///uvf//7r3/+7ckz/pUkb/9m1ov+ePQ3/okUW/8+fh//38O3//////////5r///+t//////7y6v/Cflv/58Cr//DRwP/mwKv/okQU/8ODYv/cuqj/yZN4//Tq5f/+9e///vDn///////////Q////yf/////+7+b/05yA/65ZLv+9dVD/sF40/5kzAP/kvKb//vTu//Tr5v/7+Pb//vfz//707f//////////6f///8X//////vDm/+K4ov/KjGz//ure/8uNbf+jRBX/+OTX/+3b0v+jSBr/pk0h/717Wv/Wrpr//Pn4/////+b///+i//////7z7f/02Mj/wn5b//vl2P+uWS7/vXhU//v49//48u//1q6a/717Wv+oUSb/tWxH//jz8P/////K////V///////+/j//ure/8aFZP/fs5v/oEAQ/9q1o/+zaEL/1ayX//718P/+9/P/+PHu//jz8P//////////h////wr////O///////38v/YpYr/tGQ7/6ZLHf/06eX/s2dB/549Df/x49z//vDn//7x6f//////////8////yoAAAAA////R/////v/////7dXI/5kzAP+7cUv//vHp/+vYzv+bNwX/vHlY//38/P///////////////30AAAAAAAAAAAAAAAD///9n////+/z5+P++e1n/3LGc//7w5//++PT/0KKL/8OIa//9/Pv//////////5X///8GAAAAAAAAAAAAAAAAAAAAAP///0n////K///////////////////////////+/v7/////5v///2z///8CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////Cv///1f///+g////xP///8n///+r////bP///xoAAAAAAAAAAAAAAAAAAAAA+B////AH///AA///wAH//4AB//+AAP//AAD//wAA//8AAP//AAD//4AA//+AAf//wAP//+AD///wD////D///w==</Image>
+<Url type="text/html" method="GET" template="http://www.answers.com/main/ntquery">
+ <Param name="s" value="{searchTerms}"/>
+ <Param name="gwp" value="13"/>
+</Url>
+<Url type="application/x-suggestions+json" method="GET"
+ template="http://www.answers.com/main/startswith?output=json&amp;client=firefox&amp;s={searchTerms}"/>
+<SearchForm>http://www.answers.com/</SearchForm>
+</SearchPlugin>
diff --git a/bundles/XO/searchplugins/creativecommons.xml b/bundles/XO/searchplugins/creativecommons.xml
new file mode 100755
index 0000000..7baf3b0
--- /dev/null
+++ b/bundles/XO/searchplugins/creativecommons.xml
@@ -0,0 +1,11 @@
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>Creative Commons</ShortName>
+<Description>Find photos, movies, music, and text to rip, sample, mash, and share.</Description>
+<InputEncoding>utf-8</InputEncoding>
+<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJUSURBVDiNjZO9S1thGMXPvTfJFbnkipNkLLS0ksFg0M0lf4CboNCEgIIg/RiKtEOn0qGWTtbVoBYcIji10I9J0ApWCjp0kRaXdhHjTW4+uGnur4NJ8GOwZ3nf4TnnfZ5z3scAdBGGYdyVdN+yrGHTNNOtVqsVhuG+pO+S3gE/LtV3BIxzPDJNc8FxHGN0dNRKpVIGoJ2dndr+/r5Vr9cl6bmkN0AoSQIEyHXdj5KYnZ3F932uolKpkM/nK5KQ9FmSCZwLOI7zQBLr6+vXiFdRLBaDtsiTTve3YrFYkM/nbyR3MDU1dSKpLumO+vr6Xruui+d5AFSrVVZWVtjY2KDRaABwdHTE4uIie3t7AJTLZaLRaFXSCyUSid1MJgOA53n09/eTTqdJJpPMzc2xurqKbduMj48Tj8fZ3d0FYHBw8FjSezmOU56fnwdgeXkZ27ap1WpUKhWazSZjY2Nks1kASqVSd4zp6eljSX/MtiHdRDpnEATyfb+bkiSVSqXu3TCM8xgHBga+dkY4OzvDdV2GhoZIJBLMzMxQKBSIRqNkMhlisRhbW1sAJJPJn5I+KB6Pv7poou/7rK2tsbm5SRAEXROXlpY4ODgAoFarYdu2J+llN8ZcLvffMeZyud+SGpLuCVBPT89jSRQKhRvJxWKxISmU9JTOT5Rk9Pb2fpHE5OQkJycn14inp6dMTEx4bdM/SbKAy8sk6WEkElmwLCuSSqUYGRmxgHB7e7t+eHgYazabgaRnkt7SeZnr63xbUtYwjGHTNNNhGP4F9iR9a6/zr4v1/wDE1D9XlC4rrAAAAABJRU5ErkJggg==</Image>
+<Url type="text/html" method="GET" template="http://search.creativecommons.org/">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="sourceid" value="Mozilla-search"/>
+</Url>
+<SearchForm>http://search.creativecommons.org/</SearchForm>
+</SearchPlugin>
diff --git a/bundles/XO/searchplugins/eBay.xml b/bundles/XO/searchplugins/eBay.xml
new file mode 100755
index 0000000..532f103
--- /dev/null
+++ b/bundles/XO/searchplugins/eBay.xml
@@ -0,0 +1,10 @@
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>eBay</ShortName>
+<Description>eBay - Online auctions</Description>
+<InputEncoding>ISO-8859-1</InputEncoding>
+<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAA/wAAAABAAABAQAAAgEAAAMBAAAD/QAAAAIAAAECAAACAgAAAwIAAAP+AAAAAwAAAQMAAAIDAAADAwAAA/8AAAAD/AABA/wAAgP8AAMD/AAD//wAAAABAAEAAQACAAEAAwABAAP8AQAAAQEAAQEBAAIBAQADAQEAA/0BAAACAQABAgEAAgIBAAMCAQAD/gEAAAMBAAEDAQACAwEAAwMBAAP/AQAAA/0AAQP9AAID/QADA/0AA//9AAAAAgABAAIAAgACAAMAAgAD/AIAAAECAAEBAgACAQIAAwECAAP9AgAAAgIAAQICAAICAgADAgIAA/4CAAADAgABAwIAAgMCAAMDAgAD/wIAAAP+AAED/gACA/4AAwP+AAP//gAAAAMAAQADAAIAAwADAAMAA/wDAAABAwABAQMAAgEDAAMBAwAD/QMAAAIDAAECAwACAgMAAwIDAAP+AwAAAwMAAQMDAAIDAwADAwMAA/8DAAAD/wABA/8AAgP/AAMD/wAD//8AAAAD/AEAA/wCAAP8AwAD/AP8A/wAAQP8AQED/AIBA/wDAQP8A/0D/AACA/wBAgP8AgID/AMCA/wD/gP8AAMD/AEDA/wCAwP8AwMD/AP/A/wAA//8AQP//AID//wDA//8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8fHx8fHx8fHx8fHx8AAB8cGRkUFAcHBx8fBUKfAAAfFBkfHxNHF4cb29vCnwAAHxkZFBQUBx8HG98bwp8fAB8ZGR8UGQcXhxvb28KFXx8fHZkZGRNHBwcfG8jCgoQfAB8fHx8HBx8b29vCnwPCnwAAAB8fBwcfHx8EBB8Dwp8AAAAAHx8fHwAfHx8AHx8fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AACAAwAAAAMAAAADAAAAAQAAAAAAAAAAAACAAAAA4AAAAPCIAAD//wAA//8AAP//AAA=</Image>
+<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4">
+ <Param name="satitle" value="{searchTerms}"/>
+</Url>
+<SearchForm>http://search.ebay.com/</SearchForm>
+</SearchPlugin>
diff --git a/bundles/XO/searchplugins/google.xml b/bundles/XO/searchplugins/google.xml
new file mode 100755
index 0000000..60a6e93
--- /dev/null
+++ b/bundles/XO/searchplugins/google.xml
@@ -0,0 +1,17 @@
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>Google</ShortName>
+<Description>Google Search</Description>
+<InputEncoding>UTF-8</InputEncoding>
+<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA</Image>
+<Url type="application/x-suggestions+json" method="GET" template="http://suggestqueries.google.com/complete/search?output=firefox&amp;client=firefox&amp;hl={moz:locale}&amp;q={searchTerms}"/>
+<Url type="text/html" method="GET" template="http://www.google.com/search">
+ <Param name="q" value="{searchTerms}"/>
+ <Param name="ie" value="utf-8"/>
+ <Param name="oe" value="utf-8"/>
+ <Param name="aq" value="t"/>
+ <!-- Dynamic parameters -->
+ <Param name="rls" value="{moz:distributionID}:{moz:locale}:{moz:official}"/>
+ <MozParam name="client" condition="defaultEngine" trueValue="firefox-a" falseValue="firefox"/>
+</Url>
+<SearchForm>http://www.google.com/firefox</SearchForm>
+</SearchPlugin>
diff --git a/bundles/XO/searchplugins/wikipedia.xml b/bundles/XO/searchplugins/wikipedia.xml
new file mode 100755
index 0000000..36b8ed4
--- /dev/null
+++ b/bundles/XO/searchplugins/wikipedia.xml
@@ -0,0 +1,15 @@
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>Wikipedia (en)</ShortName>
+<Description>Wikipedia, the free encyclopedia</Description>
+<InputEncoding>UTF-8</InputEncoding>
+<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAEAgQAhIOEAMjHyABIR0gA6ejpAGlqaQCpqKkAKCgoAPz9%2FAAZGBkAmJiYANjZ2ABXWFcAent6ALm6uQA8OjwAiIiIiIiIiIiIiI4oiL6IiIiIgzuIV4iIiIhndo53KIiIiB%2FWvXoYiIiIfEZfWBSIiIEGi%2FfoqoiIgzuL84i9iIjpGIoMiEHoiMkos3FojmiLlUipYliEWIF%2BiDe0GoRa7D6GPbjcu1yIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</Image>
+<Url type="application/x-suggestions+json" method="GET" template="http://en.wikipedia.org/w/api.php">
+ <Param name="action" value="opensearch"/>
+ <Param name="search" value="{searchTerms}"/>
+</Url>
+<Url type="text/html" method="GET" template="http://en.wikipedia.org/wiki/Special:Search">
+ <Param name="search" value="{searchTerms}"/>
+ <Param name="sourceid" value="Mozilla-search"/>
+</Url>
+<SearchForm>http://en.wikipedia.org/wiki/Special:Search</SearchForm>
+</SearchPlugin>
diff --git a/bundles/XO/searchplugins/yahoo.xml b/bundles/XO/searchplugins/yahoo.xml
new file mode 100755
index 0000000..94ac633
--- /dev/null
+++ b/bundles/XO/searchplugins/yahoo.xml
@@ -0,0 +1,14 @@
+<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
+<ShortName>Yahoo</ShortName>
+<Description>Yahoo Search</Description>
+<InputEncoding>UTF-8</InputEncoding>
+<Image width="16" height="16">data:image/x-icon;base64,R0lGODlhEAAQAJECAP8AAAAAAP///wAAACH5BAEAAAIALAAAAAAQABAAAAIplI+py+0NogQuyBDEnEd2kHkfFWUamEzmpZSfmaIHPHrRguUm/fT+UwAAOw==</Image>
+<Url type="application/x-suggestions+json" method="GET"
+ template="http://ff.search.yahoo.com/gossip?output=fxjson&amp;command={searchTerms}" />
+<Url type="text/html" method="GET" template="http://search.yahoo.com/search">
+ <Param name="p" value="{searchTerms}"/>
+ <Param name="ei" value="UTF-8"/>
+ <MozParam name="fr" condition="pref" pref="yahoo-fr" />
+</Url>
+<SearchForm>http://search.yahoo.com/</SearchForm>
+</SearchPlugin>
diff --git a/bundles/XO/setup.py b/bundles/XO/setup.py
new file mode 100755
index 0000000..c30f0e5
--- /dev/null
+++ b/bundles/XO/setup.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2006, Red Hat, 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+
+from sugar.activity import bundlebuilder
+
+bundlebuilder.start('Karma')
diff --git a/bundles/XO/update.locale b/bundles/XO/update.locale
new file mode 100755
index 0000000..beb9970
--- /dev/null
+++ b/bundles/XO/update.locale
@@ -0,0 +1 @@
+en-US
diff --git a/bundles/XO/updater b/bundles/XO/updater
new file mode 100755
index 0000000..1956111
--- /dev/null
+++ b/bundles/XO/updater
Binary files differ
diff --git a/bundles/XO/updater.ini b/bundles/XO/updater.ini
new file mode 100755
index 0000000..1d86156
--- /dev/null
+++ b/bundles/XO/updater.ini
@@ -0,0 +1,4 @@
+; This file is in the UTF-8 encoding
+[Strings]
+Title=Firefox Update
+Info=Firefox is installing your updates and will start in a few moments…
diff --git a/bundles/xo b/bundles/xo
deleted file mode 160000
-Subproject a74a6275da1a0189ce67aa653d30dca88fc4f8f