Changeset 142
- Timestamp:
- Sat Jul 26 10:14:15 2008
- Files:
-
- branches/stable-1.8/WikidPadStarter.py (modified) (diff)
- branches/stable-1.8/extensions/WikiSyntax.py (modified) (diff)
- branches/stable-1.8/wikidpad_unicode.iss (modified) (diff)
- branches/stable-1.8/WikidPadHelp/data/WIKIWORDPROPS.grl (modified)
- branches/stable-1.8/WikidPadHelp/data/WIKIRELATIONS.grl (modified)
- branches/stable-1.8/WikidPadHelp/data/ChangeLog.wiki (modified) (diff)
- branches/stable-1.8/WikidPadHelp/data/WIKIWORDS.grl (modified)
- branches/stable-1.8/lib/pwiki/wikidata/compact_sqlite/DbStructure.py (modified) (diff)
- branches/stable-1.8/lib/pwiki/wikidata/original_gadfly/DbStructure.py (modified) (diff)
- branches/stable-1.8/lib/pwiki/SearchAndReplaceDialogs.py (modified) (diff)
- branches/stable-1.8/lib/pwiki/StringOps.py (modified) (diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
branches/stable-1.8/WikidPadStarter.py
r141 r142 25 25 # (2, 0, 200, 0) is 2.0final 26 26 27 VERSION_TUPLE = ("wikidPad", 1, 8, 11 3, 1)27 VERSION_TUPLE = ("wikidPad", 1, 8, 114, 0) 27 27 28 VERSION_STRING = "wikidPad 1.8rc1 3_1"28 VERSION_STRING = "wikidPad 1.8rc14" 28 28 29 29 if not hasattr(sys, 'frozen'): -
branches/stable-1.8/extensions/WikiSyntax.py
r113 r142 3 3 4 4 import pwiki.srePersistent as re 5 from pwiki.StringOps import mbcsDec 5 from pwiki.StringOps import mbcsDec, UPPERCASE, LOWERCASE 5 5 6 6 locale.setlocale(locale.LC_ALL, '') 7 7 8 9 8 # String containing the delimiter between the title of a wiki word (to show in 10 9 # HTML and the real word, as e.g. [title | WikiWord] … … 76 75 # TODO To unicode 77 76 78 UPPERCASE = mbcsDec(string.uppercase)[0] 79 LOWERCASE = mbcsDec(string.lowercase)[0] 77 # UPPERCASE = mbcsDec(string.uppercase)[0] 78 # LOWERCASE = mbcsDec(string.lowercase)[0] 80 79 LETTERS = UPPERCASE + LOWERCASE 81 80 -
branches/stable-1.8/wikidpad_unicode.iss
r141 r142 39 39 SolidCompression=true 40 40 AppName=WikidPad 41 AppVerName=WikidPad 1.8rc1 341 AppVerName=WikidPad 1.8rc14 41 41 DefaultDirName={pf}\WikidPad 42 42 DefaultGroupName=WikidPad 43 43 AppID={{22A83C29-58A8-4CAB-8EDC-918D74F8429E} 44 VersionInfoVersion=1.8.113.1 45 VersionInfoTextVersion=WikidPad 1.8rc13 44 VersionInfoVersion=1.8.114.0 45 VersionInfoTextVersion=WikidPad 1.8rc14 46 46 LicenseFile=C:\DATEN\Projekte\Wikidpad\Current\license.txt 47 47 AllowNoIcons=true 48 48 ShowLanguageDialog=yes 49 49 Compression=lzma/ultra 50 OutputBaseFilename=WikidPad-1.8rc1 350 OutputBaseFilename=WikidPad-1.8rc14 50 50 InternalCompressLevel=ultra 51 AppCopyright=© 2005-200 7Jason Horman, Michael Butscher, Gerhard Reitmayr51 AppCopyright=© 2005-2008 Jason Horman, Michael Butscher, Gerhard Reitmayr 51 51 UsePreviousAppDir=true 52 52 [Components] -
branches/stable-1.8/WikidPadHelp/data/ChangeLog.wiki
r139 r142 2 2 3 3 4 Jul. 26, 2008 (1.8rc14) 5 6 * Better handling of malformed regular expressions 7 in search fields 8 * Support for all uppercase and lowercase letters in the 9 Unicode set for creating camel-case wiki words independent 10 of OS language 11 12 13 4 14 Jan. 25, 2008 (1.8rc13) 5 15 -
branches/stable-1.8/lib/pwiki/wikidata/compact_sqlite/DbStructure.py
r139 r142 872 872 searchOp.booleanOp = True 873 873 874 try: 875 # Raises exception if search is invalid 876 searchOp.rebuildSearchOpTree() 877 except: 878 continue 879 874 880 datablock = searchOp.getPackedSettings() 875 881 -
branches/stable-1.8/lib/pwiki/wikidata/original_gadfly/DbStructure.py
r139 r142 617 617 searchOp.booleanOp = True 618 618 619 try: 620 # Raises exception if search is invalid 621 searchOp.rebuildSearchOpTree() 622 except: 623 continue 624 619 625 datablock = searchOp.getPackedSettings() 620 626 -
branches/stable-1.8/lib/pwiki/SearchAndReplaceDialogs.py
r133 r142 191 191 self.Update() 192 192 193 def ensureNotShowSearching(self): 194 """ 195 This function is called after a search operation and a call to 196 showFound may have happened. If it did not happen, 197 the list is cleared. 198 """ 199 if self.isShowingSearching: 200 # This can only happend if showFound wasn't called 201 self.showFound(None, None, None) 202 193 203 194 204 def showFound(self, sarOp, found, wikiDocument): … … 265 275 self.SetItemCount(len(self.foundinfo)) 266 276 self.Refresh() 267 277 267 277 268 278 def GetSelectedWord(self): … … 477 487 self.Thaw() 478 488 self.SetCursor(wx.NullCursor) 489 self.ctrls.htmllbPages.ensureNotShowSearching() 479 490 480 491 481 492 def OnSearchWiki(self, evt): 482 self._refreshPageList() 483 if not self.ctrls.htmllbPages.IsEmpty(): 484 self.ctrls.htmllbPages.SetFocus() 485 self.ctrls.htmllbPages.SetSelection(0) 486 493 try: 494 self._refreshPageList() 495 if not self.ctrls.htmllbPages.IsEmpty(): 496 self.ctrls.htmllbPages.SetFocus() 497 self.ctrls.htmllbPages.SetSelection(0) 498 except re.error, e: 499 self.pWiki.displayErrorMessage(u'Error in regular expression', 500 unicode(e)) 501 502 487 503 def OnSetPageList(self, evt): 488 504 """ … … 521 537 def _findNext(self): 522 538 if self.listNeedsRefresh: 523 # Refresh list and start from beginning 524 self._refreshPageList() 539 try: 540 # Refresh list and start from beginning 541 self._refreshPageList() 542 except re.error, e: 543 self.pWiki.displayErrorMessage(u'Error in regular expression', 544 unicode(e)) 545 return 525 546 526 547 if self.ctrls.htmllbPages.GetCount() == 0: 527 548 return 528 529 while True:530 531 #########self.ctrls.lb.SetSelection(self.listPosNext)532 533 wikiWord = guiToUni(self.ctrls.htmllbPages.GetSelectedWord())534 535 if not wikiWord:536 self.ctrls.htmllbPages.SetSelection(0)537 wikiWord = guiToUni(self.ctrls.htmllbPages.GetSelectedWord())538 549 539 if self.pWiki.getCurrentWikiWord() != wikiWord: 540 self.pWiki.openWikiPage(wikiWord) 541 nextOnPage = False 542 else: 543 nextOnPage = True 544 545 searchOp = self.buildSearchReplaceOperation() 546 searchOp.replaceOp = False 547 if nextOnPage: 548 pagePosNext = self.pWiki.getActiveEditor().executeSearch(searchOp, 549 -2)[1] 550 else: 551 pagePosNext = self.pWiki.getActiveEditor().executeSearch(searchOp, 552 0)[1] 553 554 if pagePosNext != -1: 555 return # Found 550 try: 551 while True: 552 #########self.ctrls.lb.SetSelection(self.listPosNext) 556 553 557 if self.ctrls.htmllbPages.GetSelection() == \ 558 self.ctrls.htmllbPages.GetCount() - 1: 559 # Nothing more found on the last page in list, so back to 560 # begin of list and stop 561 self.ctrls.htmllbPages.SetSelection(0) 562 return 554 wikiWord = guiToUni(self.ctrls.htmllbPages.GetSelectedWord()) 563 555 564 # Otherwise: Go to next page in list 565 self.ctrls.htmllbPages.SetSelection( 566 self.ctrls.htmllbPages.GetSelection() + 1) 556 if not wikiWord: 557 self.ctrls.htmllbPages.SetSelection(0) 558 wikiWord = guiToUni(self.ctrls.htmllbPages.GetSelectedWord()) 559 560 if self.pWiki.getCurrentWikiWord() != wikiWord: 561 self.pWiki.openWikiPage(wikiWord) 562 nextOnPage = False 563 else: 564 nextOnPage = True 565 566 searchOp = self.buildSearchReplaceOperation() 567 searchOp.replaceOp = False 568 if nextOnPage: 569 pagePosNext = self.pWiki.getActiveEditor().executeSearch(searchOp, 570 -2)[1] 571 else: 572 pagePosNext = self.pWiki.getActiveEditor().executeSearch(searchOp, 573 0)[1] 574 575 if pagePosNext != -1: 576 return # Found 577 578 if self.ctrls.htmllbPages.GetSelection() == \ 579 self.ctrls.htmllbPages.GetCount() - 1: 580 # Nothing more found on the last page in list, so back to 581 # begin of list and stop 582 self.ctrls.htmllbPages.SetSelection(0) 583 return 584 585 # Otherwise: Go to next page in list 586 self.ctrls.htmllbPages.SetSelection( 587 self.ctrls.htmllbPages.GetSelection() + 1) 588 except re.error, e: 589 self.pWiki.displayErrorMessage(u'Error in regular expression', 590 unicode(e)) 567 591 568 592 … … 582 606 return 583 607 584 self._refreshPageList() 585 586 if self.ctrls.htmllbPages.GetCount() == 0: 587 return 608 try: 609 self._refreshPageList() 588 610 589 # self.pWiki.saveCurrentDocPage() 590 591 sarOp = self.buildSearchReplaceOperation() 592 sarOp.replaceOp = True 593 594 # wikiData = self.pWiki.getWikiData() 595 wikiDocument = self.pWiki.getWikiDocument() 596 597 for i in xrange(self.ctrls.htmllbPages.GetCount()): 598 self.ctrls.htmllbPages.SetSelection(i) 599 wikiWord = guiToUni(self.ctrls.htmllbPages.GetSelectedWord()) 600 wikiPage = wikiDocument.getWikiPageNoError(wikiWord) 611 if self.ctrls.htmllbPages.GetCount() == 0: 612 return 613 614 # self.pWiki.saveCurrentDocPage() 615 616 sarOp = self.buildSearchReplaceOperation() 617 sarOp.replaceOp = True 618 619 # wikiData = self.pWiki.getWikiData() 620 wikiDocument = self.pWiki.getWikiDocument() 621 622 for i in xrange(self.ctrls.htmllbPages.GetCount()): 623 self.ctrls.htmllbPages.SetSelection(i) 624 wikiWord = guiToUni(self.ctrls.htmllbPages.GetSelectedWord()) 625 wikiPage = wikiDocument.getWikiPageNoError(wikiWord) 601 626 # text = wikiData.getContent(wikiWord) 602 text = wikiPage.getLiveTextNoTemplate() 603 if text is None: 604 continue 605 606 charStartPos = 0 607 608 while True: 609 try: 610 found = sarOp.searchText(text, charStartPos) 611 start, end = found[:2] 612 except: 613 # Regex error -> Stop searching 614 return 627 text = wikiPage.getLiveTextNoTemplate() 628 if text is None: 629 continue 630 631 charStartPos = 0 632 633 while True: 634 try: 635 found = sarOp.searchText(text, charStartPos) 636 start, end = found[:2] 637 except: 638 # Regex error -> Stop searching 639 return 640 641 if start is None: break 615 642 616 if start is None: break 617 618 repl = sarOp.replace(text, found) 619 text = text[:start] + repl + text[end:] # TODO Faster? 620 charStartPos = start + len(repl) 621 643 repl = sarOp.replace(text, found) 644 text = text[:start] + repl + text[end:] # TODO Faster? 645 charStartPos = start + len(repl) 646 622 647 # wikiData.setContent(wikiWord, text) 623 wikiPage.replaceLiveText(text) 624 648 wikiPage.replaceLiveText(text) 649 625 650 # # Reopen current word because its content could have been overwritten before 626 651 # self.pWiki.openWikiPage(self.pWiki.getCurrentWikiWord(), 627 652 # addToHistory=False, forceReopen=True) 628 629 self._refreshPageList() 653 654 self._refreshPageList() 655 656 except re.error, e: 657 self.pWiki.displayErrorMessage(u'Error in regular expression', 658 unicode(e)) 630 659 631 660 … … 634 663 def OnSaveSearch(self, evt): 635 664 sarOp = self.buildSearchReplaceOperation() 665 try: 666 sarOp.rebuildSearchOpTree() 667 except re.error, e: 668 self.pWiki.displayErrorMessage(u'Error in regular expression', 669 unicode(e)) 670 return 636 671 637 672 if len(sarOp.searchStr) > 0: … … 715 750 def OnLoadAndRunSearch(self, evt): 716 751 if self._loadSearch(): 717 self._refreshPageList() 752 try: 753 self._refreshPageList() 754 except re.error, e: 755 self.pWiki.displayErrorMessage(u'Error in regular expression', 756 unicode(e)) 757 718 758 719 759 def _loadSearch(self): … … 858 898 sarOp = self._buildSearchOperation() 859 899 sarOp.replaceOp = False 860 self._nextSearch(sarOp) 861 862 self.firstFind = False 900 try: 901 self._nextSearch(sarOp) 902 self.firstFind = False 903 except re.error, e: 904 self.pWiki.displayErrorMessage(u'Error in regular expression', 905 unicode(e)) 863 906 864 907 … … 1019 1062 except re.error, e: 1020 1063 wx.MessageBox("Bad regular expression '%s':\n%s" % 1021 (pattern, unicode(e)), u" Regular expression error",1064 (pattern, unicode(e)), u"Error in regular expression", 1021 1064 wx.OK, self) 1022 1065 return None … … 1328 1371 """ 1329 1372 self.searchText = text 1330 self._refreshPageList() 1373 try: 1374 self._refreshPageList() 1375 except re.error, e: 1376 self.mainControl.displayErrorMessage(u'Error in regular expression', 1377 unicode(e)) 1331 1378 1332 1379 … … 1353 1400 self.Thaw() 1354 1401 self.SetCursor(wx.NullCursor) 1402 self.resultBox.ensureNotShowSearching() 1403 -
branches/stable-1.8/lib/pwiki/StringOps.py
r139 r142 923 923 return compactToBinCompact(difflibToCompact(ops, b)) 924 924 925 926 # ---------- Unicode constants ---------- 927 928 # UPPERCASE = None 929 # LOWERCASE = None 930 # 931 # def _fillConsts(): 932 # global UPPERCASE, LOWERCASE 933 # from unicodedata import category 934 # 935 # uc = [] 936 # lc = [] 937 # 938 # for i in xrange(0, 0x10000): 939 # c = unichr(i) 940 # if category(c) == "Ll": 941 # lc.append(c) 942 # elif category(c) == "Lu": 943 # uc.append(c) 944 # 945 # UPPERCASE = u"".join(uc) 946 # LOWERCASE = u"".join(lc) 947 # 948 # _fillConsts() 949 950 951 # Interestingly it isn't noticeably faster to set the constants directly than 952 # calculating it at each start, but it doesn't need "unicodedata.pyd" 953 954 LOWERCASE = u'abcdefghijklmnopqrstuvwxyz\xaa\xb5\xba\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\u0101\u0103\u0105\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117\u0119\u011b\u011d\u011f\u0121\u0123\u0125\u0127\u0129\u012b\u012d\u012f\u0131\u0133\u0135\u0137\u0138\u013a\u013c\u013e\u0140\u0142\u0144\u0146\u0148\u0149\u014b\u014d\u014f\u0151\u0153\u0155\u0157\u0159\u015b\u015d\u015f\u0161\u0163\u0165\u0167\u0169\u016b\u016d\u016f\u0171\u0173\u0175\u0177\u017a\u017c\u017e\u017f\u0180\u0183\u0185\u0188\u018c\u018d\u0192\u0195\u0199\u019a\u019b\u019e\u01a1\u01a3\u01a5\u01a8\u01aa\u01ab\u01ad\u01b0\u01b4\u01b6\u01b9\u01ba\u01bd\u01be\u01bf\u01c6\u01c9\u01cc\u01ce\u01d0\u01d2\u01d4\u01d6\u01d8\u01da\u01dc\u01dd\u01df\u01e1\u01e3\u01e5\u01e7\u01e9\u01eb\u01ed\u01ef\u01f0\u01f3\u01f5\u01f9\u01fb\u01fd\u01ff\u0201\u0203\u0205\u0207\u0209\u020b\u020d\u020f\u0211\u0213\u0215\u0217\u0219\u021b\u021d\u021f\u0223\u0225\u0227\u0229\u022b\u022d\u022f\u0231\u0233\u0250\u0251\u0252\u0253\u0254\u0255\u0256\u0257\u0258\u0259\u025a\u025b\u025c\u025d\u025e\u025f\u0260\u0261\u0262\u0263\u0264\u0265\u0266\u0267\u0268\u0269\u026a\u026b\u026c\u026d\u026e\u026f\u0270\u0271\u0272\u0273\u0274\u0275\u0276\u0277\u0278\u0279\u027a\u027b\u027c\u027d\u027e\u027f\u0280\u0281\u0282\u0283\u0284\u0285\u0286\u0287\u0288\u0289\u028a\u028b\u028c\u028d\u028e\u028f\u0290\u0291\u0292\u0293\u0294\u0295\u0296\u0297\u0298\u0299\u029a\u029b\u029c\u029d\u029e\u029f\u02a0\u02a1\u02a2\u02a3\u02a4\u02a5\u02a6\u02a7\u02a8\u02a9\u02aa\u02ab\u02ac\u02ad\u0390\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9\u03ca\u03cb\u03cc\u03cd\u03ce\u03d0\u03d1\u03d5\u03d6\u03d7\u03d9\u03db\u03dd\u03df\u03e1\u03e3\u03e5\u03e7\u03e9\u03eb\u03ed\u03ef\u03f0\u03f1\u03f2\u03f3\u03f5\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0450\u0451\u0452\u0453\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u045d\u045e\u045f\u0461\u0463\u0465\u0467\u0469\u046b\u046d\u046f\u0471\u0473\u0475\u0477\u0479\u047b\u047d\u047f\u0481\u048b\u048d\u048f\u0491\u0493\u0495\u0497\u0499\u049b\u049d\u049f\u04a1\u04a3\u04a5\u04a7\u04a9\u04ab\u04ad\u04af\u04b1\u04b3\u04b5\u04b7\u04b9\u04bb\u04bd\u04bf\u04c2\u04c4\u04c6\u04c8\u04ca\u04cc\u04ce\u04d1\u04d3\u04d5\u04d7\u04d9\u04db\u04dd\u04df\u04e1\u04e3\u04e5\u04e7\u04e9\u04eb\u04ed\u04ef\u04f1\u04f3\u04f5\u04f9\u0501\u0503\u0505\u0507\u0509\u050b\u050d\u050f\u0561\u0562\u0563\u0564\u0565\u0566\u0567\u0568\u0569\u056a\u056b\u056c\u056d\u056e\u056f\u0570\u0571\u0572\u0573\u0574\u0575\u0576\u0577\u0578\u0579\u057a\u057b\u057c\u057d\u057e\u057f\u0580\u0581\u0582\u0583\u0584\u0585\u0586\u0587\u1e01\u1e03\u1e05\u1e07\u1e09\u1e0b\u1e0d\u1e0f\u1e11\u1e13\u1e15\u1e17\u1e19\u1e1b\u1e1d\u1e1f\u1e21\u1e23\u1e25\u1e27\u1e29\u1e2b\u1e2d\u1e2f\u1e31\u1e33\u1e35\u1e37\u1e39\u1e3b\u1e3d\u1e3f\u1e41\u1e43\u1e45\u1e47\u1e49\u1e4b\u1e4d\u1e4f\u1e51\u1e53\u1e55\u1e57\u1e59\u1e5b\u1e5d\u1e5f\u1e61\u1e63\u1e65\u1e67\u1e69\u1e6b\u1e6d\u1e6f\u1e71\u1e73\u1e75\u1e77\u1e79\u1e7b\u1e7d\u1e7f\u1e81\u1e83\u1e85\u1e87\u1e89\u1e8b\u1e8d\u1e8f\u1e91\u1e93\u1e95\u1e96\u1e97\u1e98\u1e99\u1e9a\u1e9b\u1ea1\u1ea3\u1ea5\u1ea7\u1ea9\u1eab\u1ead\u1eaf\u1eb1\u1eb3\u1eb5\u1eb7\u1eb9\u1ebb\u1ebd\u1ebf\u1ec1\u1ec3\u1ec5\u1ec7\u1ec9\u1ecb\u1ecd\u1ecf\u1ed1\u1ed3\u1ed5\u1ed7\u1ed9\u1edb\u1edd\u1edf\u1ee1\u1ee3\u1ee5\u1ee7\u1ee9\u1eeb\u1eed\u1eef\u1ef1\u1ef3\u1ef5\u1ef7\u1ef9\u1f00\u1f01\u1f02\u1f03\u1f04\u1f05\u1f06\u1f07\u1f10\u1f11\u1f12\u1f13\u1f14\u1f15\u1f20\u1f21\u1f22\u1f23\u1f24\u1f25\u1f26\u1f27\u1f30\u1f31\u1f32\u1f33\u1f34\u1f35\u1f36\u1f37\u1f40\u1f41\u1f42\u1f43\u1f44\u1f45\u1f50\u1f51\u1f52\u1f53\u1f54\u1f55\u1f56\u1f57\u1f60\u1f61\u1f62\u1f63\u1f64\u1f65\u1f66\u1f67\u1f70\u1f71\u1f72\u1f73\u1f74\u1f75\u1f76\u1f77\u1f78\u1f79\u1f7a\u1f7b\u1f7c\u1f7d\u1f80\u1f81\u1f82\u1f83\u1f84\u1f85\u1f86\u1f87\u1f90\u1f91\u1f92\u1f93\u1f94\u1f95\u1f96\u1f97\u1fa0\u1fa1\u1fa2\u1fa3\u1fa4\u1fa5\u1fa6\u1fa7\u1fb0\u1fb1\u1fb2\u1fb3\u1fb4\u1fb6\u1fb7\u1fbe\u1fc2\u1fc3\u1fc4\u1fc6\u1fc7\u1fd0\u1fd1\u1fd2\u1fd3\u1fd6\u1fd7\u1fe0\u1fe1\u1fe2\u1fe3\u1fe4\u1fe5\u1fe6\u1fe7\u1ff2\u1ff3\u1ff4\u1ff6\u1ff7\u2071\u207f\u210a\u210e\u210f\u2113\u212f\u2134\u2139\u213d\u2146\u2147\u2148\u2149\ufb00\ufb01\ufb02\ufb03\ufb04\ufb05\ufb06\ufb13\ufb14\ufb15\ufb16\ufb17\uff41\uff42\uff43\uff44\uff45\uff46\uff47\uff48\uff49\uff4a\uff4b\uff4c\uff4d\uff4e\uff4f\uff50\uff51\uff52\uff53\uff54\uff55\uff56\uff57\uff58\uff59\uff5a' 955 UPPERCASE = u'ABCDEFGHIJKLMNOPQRSTUVWXYZ\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\u0100\u0102\u0104\u0106\u0108\u010a\u010c\u010e\u0110\u0112\u0114\u0116\u0118\u011a\u011c\u011e\u0120\u0122\u0124\u0126\u0128\u012a\u012c\u012e\u0130\u0132\u0134\u0136\u0139\u013b\u013d\u013f\u0141\u0143\u0145\u0147\u014a\u014c\u014e\u0150\u0152\u0154\u0156\u0158\u015a\u015c\u015e\u0160\u0162\u0164\u0166\u0168\u016a\u016c\u016e\u0170\u0172\u0174\u0176\u0178\u0179\u017b\u017d\u0181\u0182\u0184\u0186\u0187\u0189\u018a\u018b\u018e\u018f\u0190\u0191\u0193\u0194\u0196\u0197\u0198\u019c\u019d\u019f\u01a0\u01a2\u01a4\u01a6\u01a7\u01a9\u01ac\u01ae\u01af\u01b1\u01b2\u01b3\u01b5\u01b7\u01b8\u01bc\u01c4\u01c7\u01ca\u01cd\u01cf\u01d1\u01d3\u01d5\u01d7\u01d9\u01db\u01de\u01e0\u01e2\u01e4\u01e6\u01e8\u01ea\u01ec\u01ee\u01f1\u01f4\u01f6\u01f7\u01f8\u01fa\u01fc\u01fe\u0200\u0202\u0204\u0206\u0208\u020a\u020c\u020e\u0210\u0212\u0214\u0216\u0218\u021a\u021c\u021e\u0220\u0222\u0224\u0226\u0228\u022a\u022c\u022e\u0230\u0232\u0386\u0388\u0389\u038a\u038c\u038e\u038f\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9\u03aa\u03ab\u03d2\u03d3\u03d4\u03d8\u03da\u03dc\u03de\u03e0\u03e2\u03e4\u03e6\u03e8\u03ea\u03ec\u03ee\u03f4\u0400\u0401\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b\u040c\u040d\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f\u0460\u0462\u0464\u0466\u0468\u046a\u046c\u046e\u0470\u0472\u0474\u0476\u0478\u047a\u047c\u047e\u0480\u048a\u048c\u048e\u0490\u0492\u0494\u0496\u0498\u049a\u049c\u049e\u04a0\u04a2\u04a4\u04a6\u04a8\u04aa\u04ac\u04ae\u04b0\u04b2\u04b4\u04b6\u04b8\u04ba\u04bc\u04be\u04c0\u04c1\u04c3\u04c5\u04c7\u04c9\u04cb\u04cd\u04d0\u04d2\u04d4\u04d6\u04d8\u04da\u04dc\u04de\u04e0\u04e2\u04e4\u04e6\u04e8\u04ea\u04ec\u04ee\u04f0\u04f2\u04f4\u04f8\u0500\u0502\u0504\u0506\u0508\u050a\u050c\u050e\u0531\u0532\u0533\u0534\u0535\u0536\u0537\u0538\u0539\u053a\u053b\u053c\u053d\u053e\u053f\u0540\u0541\u0542\u0543\u0544\u0545\u0546\u0547\u0548\u0549\u054a\u054b\u054c\u054d\u054e\u054f\u0550\u0551\u0552\u0553\u0554\u0555\u0556\u10a0\u10a1\u10a2\u10a3\u10a4\u10a5\u10a6\u10a7\u10a8\u10a9\u10aa\u10ab\u10ac\u10ad\u10ae\u10af\u10b0\u10b1\u10b2\u10b3\u10b4\u10b5\u10b6\u10b7\u10b8\u10b9\u10ba\u10bb\u10bc\u10bd\u10be\u10bf\u10c0\u10c1\u10c2\u10c3\u10c4\u10c5\u1e00\u1e02\u1e04\u1e06\u1e08\u1e0a\u1e0c\u1e0e\u1e10\u1e12\u1e14\u1e16\u1e18\u1e1a\u1e1c\u1e1e\u1e20\u1e22\u1e24\u1e26\u1e28\u1e2a\u1e2c\u1e2e\u1e30\u1e32\u1e34\u1e36\u1e38\u1e3a\u1e3c\u1e3e\u1e40\u1e42\u1e44\u1e46\u1e48\u1e4a\u1e4c\u1e4e\u1e50\u1e52\u1e54\u1e56\u1e58\u1e5a\u1e5c\u1e5e\u1e60\u1e62\u1e64\u1e66\u1e68\u1e6a\u1e6c\u1e6e\u1e70\u1e72\u1e74\u1e76\u1e78\u1e7a\u1e7c\u1e7e\u1e80\u1e82\u1e84\u1e86\u1e88\u1e8a\u1e8c\u1e8e\u1e90\u1e92\u1e94\u1ea0\u1ea2\u1ea4\u1ea6\u1ea8\u1eaa\u1eac\u1eae\u1eb0\u1eb2\u1eb4\u1eb6\u1eb8\u1eba\u1ebc\u1ebe\u1ec0\u1ec2\u1ec4\u1ec6\u1ec8\u1eca\u1ecc\u1ece\u1ed0\u1ed2\u1ed4\u1ed6\u1ed8\u1eda\u1edc\u1ede\u1ee0\u1ee2\u1ee4\u1ee6\u1ee8\u1eea\u1eec\u1eee\u1ef0\u1ef2\u1ef4\u1ef6\u1ef8\u1f08\u1f09\u1f0a\u1f0b\u1f0c\u1f0d\u1f0e\u1f0f\u1f18\u1f19\u1f1a\u1f1b\u1f1c\u1f1d\u1f28\u1f29\u1f2a\u1f2b\u1f2c\u1f2d\u1f2e\u1f2f\u1f38\u1f39\u1f3a\u1f3b\u1f3c\u1f3d\u1f3e\u1f3f\u1f48\u1f49\u1f4a\u1f4b\u1f4c\u1f4d\u1f59\u1f5b\u1f5d\u1f5f\u1f68\u1f69\u1f6a\u1f6b\u1f6c\u1f6d\u1f6e\u1f6f\u1fb8\u1fb9\u1fba\u1fbb\u1fc8\u1fc9\u1fca\u1fcb\u1fd8\u1fd9\u1fda\u1fdb\u1fe8\u1fe9\u1fea\u1feb\u1fec\u1ff8\u1ff9\u1ffa\u1ffb\u2102\u2107\u210b\u210c\u210d\u2110\u2111\u2112\u2115\u2119\u211a\u211b\u211c\u211d\u2124\u2126\u2128\u212a\u212b\u212c\u212d\u2130\u2131\u2133\u213e\u213f\u2145\uff21\uff22\uff23\uff24\uff25\uff26\uff27\uff28\uff29\uff2a\uff2b\uff2c\uff2d\uff2e\uff2f\uff30\uff31\uff32\uff33\uff34\uff35\uff36\uff37\uff38\uff39\uff3a'
