From 5894d49dcf7b94f9742c9436a77d755002882dd3 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Sun, 15 May 2022 15:06:55 +0100 Subject: [PATCH] New "Character Variant" search prefix. --- manual/gui.rst | 203 +++++++++++++++++++---------- manual/images/search.png | Bin 24816 -> 24767 bytes manual/images/search_button.png | Bin 655 -> 1836 bytes src/calibre/db/search.py | 14 +- src/calibre/gui2/dialogs/search.py | 11 +- 5 files changed, 151 insertions(+), 77 deletions(-) diff --git a/manual/gui.rst b/manual/gui.rst index 877579a223..5fdd8cddce 100644 --- a/manual/gui.rst +++ b/manual/gui.rst @@ -327,9 +327,9 @@ The Search & Sort section allows you to perform several powerful actions on your .. _search_interface: -The search interface +The Search interface --------------------- -You can search all the metadata by entering search terms in the Search bar. Searches are case insensitive. For example:: +You can search all book metadata by entering search terms in the Search bar. For example:: Asimov Foundation format:lrf @@ -340,26 +340,92 @@ are available in the LRF format. Some more examples:: title:"The Ring" or "This book is about a ring" format:epub publisher:feedbooks.com -Searches are by default 'contains'. An item matches if the search string appears anywhere in the indicated metadata. -Two other kinds of searches are available: equality search and search using `regular expressions `_. +.. _search_kinds: + +*Search kinds* + +There are four search kinds: `contains`, `equality`, `regular expression` (see `regular expressions `_), and `character variant`. You choose the search kind with a prefix character. + +*'Contains' searches* + +Searches with no prefix character are `contains` and are by default case insensitive. An item matches if the search string appears anywhere in the indicated metadata. You can make `contains` searches case sensitive by checking the option `Case sensitive searching` in :guilabel:`Preferences / Searching`. If the search option `Unaccented characters match accented characters and punctuation is ignored` is checked then a character will match all its variants (e.g., `e` matches `é`, `è`, `ê`, and `ë`) and all punctuation including spaces are ignored. For example, if the `Unaccented characters match ...` option is checked then given the two book titles: + + 1. Big, Bothéred, and Bad + 2. Big Bummer + +then these searches find: + + * ``title:"er"`` matches both ('e' matches both 'é' and 'e'). + * ``title:"g "`` matches both because spaces are ignored. + * ``title:"g,"`` matches both because the comma is ignored. + * ``title:"gb"`` matches both because ', ' is ignored in book 1 and spaces are ignored in book 2. + * ``title:"g b"`` matches both because comma and space are ignored. + * ``title:"db"`` matches #1 because the space in 'and Bad' is ignored. + * ``title:","`` matches both (it actually matches all books) because commas are ignored. + +If the `Unaccented characters match ...` option is not checked then character variants, punctuation, and spacing are all significant. + +You can set only one of the search options `Case sensitive searching` and `Unaccented characters match accented characters and punctuation is ignored`. + +*'Equality' searches* Equality searches are indicated by prefixing the search string with an equals sign (=). For example, the query -``tag:"=science"`` will match "science", but not "science fiction" or "hard science". Regular expression searches are -indicated by prefixing the search string with a tilde (~). Any `Python-compatible regular expression `_ can -be used. Note that backslashes used to escape special characters in regular expressions must be doubled because single backslashes will be removed during query parsing. For example, to match a literal parenthesis you must enter ``\\(``. Regular expression searches are 'contains' searches unless the expression contains anchors. +``tag:"=science"`` will match `science`, but not `science fiction` or `hard science`. Character variants are significant: `é` doesn't match `e`. -Should you need to search for a string with a leading equals or tilde, prefix the string with a backslash. +Two variants of equality searches are used for hierarchical items (e.g., A.B.C): hierarchical prefix searches and hierarchical component searches. The first, indicated by a single period after the equals (``=.``) matches the initial parts of a hierarchical item. The second, indicated by two periods after the the equals (``=..``) matches an internal name in the hierarchical item. Examples, using the tag ``History.Military.WWII`` as the value: -Enclose search strings with quotes (") if the string contains parenthesis or spaces. For example, to search -for the tag ``Science Fiction`` you would need to search for ``tag:"=science fiction"``. If you search for -``tag:=science fiction`` you will find all books with the tag 'science' and containing the word 'fiction' in any -metadata. + * ``tags:"=.History"`` : True. ``History`` is a prefix of the tag. + * ``tags:"=.History.Military"`` : True. ``History.Military`` is a prefix of the tag. + * ``tags:"=.History.Military.WWII"`` : True. ``History.Military.WWII`` is a prefix of the tag, albeit an improper one. + * ``tags:"=.Military"`` : False. ``Military`` is not a prefix of the tag. + * ``tags:"=.WWII"`` : False. ``WWII`` is not a prefix of the tag. + * ``tags:"=..History"`` : True. The hierarchy contains the value ``History``. + * ``tags:"=..Military"`` : True. The hierarchy contains the value ``Military``. + * ``tags:"=..WWII"`` : True. The hierarchy contains the value ``WWII``. + * ``tags:"=..Military.WWII"`` : False. The ``..`` search looks for single values. + +*'Regular expression' searches* + +Regular expression searches are indicated by prefixing the search string with a tilde (~). Any `Python-compatible regular expression `_ can be used. Backslashes used to escape special characters in regular expressions must be doubled because single backslashes will be removed during query parsing. For example, to match a literal parenthesis you must enter ``\\(``. Regular expression searches are 'contains' searches unless the expression is anchored. Character variants are significant: ``~e`` doesn't match ``é``. + +*'Character variant' searches* + +Character variant searches are indicated by prefixing the search string with a caret (^). This search is similar to the `contains` search (above) except that: + + * letter case is always ignored. + * character variants always match each other. + * punctuation is always significant. + +The search options `Unaccented characters match accented characters and punctuation is ignored` and `Case sensitive searching` are ignored. They have no effect on this search's behavior. + +The following compares this search to a contains search assuming the `Unaccented characters match...` option is checked (see above) given the same two book titles: + + 1. Big, Bothéred, and Bad + 2. Big Bummer + +then these character variant searches find: + + * ``title:"^er"`` matches both ('e' matches both 'é' and 'e') + * ``title:"^g"`` matches both + * ``title:"^g "`` matches #2 because the space is significant + * ``title:"^g,"`` matches #1 because the comma is significant + * ``title:"^gb"`` matches nothing because space and comma are significant + * ``title:"^g b"`` matches #2 because the comma is significant + * ``title:"^db"`` matches nothing + * ``title:"^,"`` matches #1 (instead of all books) because the comma is significant + +*More information* + +To search for a string that begins with an equals, tilde, or caret; prefix the string with a backslash. + +Enclose search strings with quotes (") if the string contains parenthesis or spaces. For example, to find books with the tag ``Science Fiction`` you must search for ``tag:"=science fiction"``. If you search for ``tag:=science fiction`` you will find all books with the tag ``science`` and the word ``fiction`` in any metadata. You can build advanced search queries easily using the :guilabel:`Advanced search dialog` accessed by -clicking the button |sbi|. +clicking the button |sbi| on the left of the search box. -Available fields for searching are: ``tag, title, author, publisher, series, series_index, rating, cover, -comments, format, identifiers, date, pubdate, search, size, vl`` and custom columns. If a device is plugged in, the ``ondevice`` field becomes available, when searching the calibre library view. To find the search name (actually called the `lookup name`) for a custom column, hover your mouse over the column header in the library view. +Available fields for searching are: ``tag, title, author, publisher, series, series_index, rating, cover, comments, format, identifiers, date, pubdate, search, size, vl`` and custom columns. If a device is plugged in, the ``ondevice`` field becomes available, when searching the calibre library view. To find the search name (actually called the `lookup name`) for a custom column, hover your mouse over the column header in the library view. + +*Dates* The syntax for searching for dates is:: @@ -367,7 +433,7 @@ The syntax for searching for dates is:: date:<=2000-1-3 Will find all books added to calibre before 3 Jan, 2000 pubdate:=2009 Will find all books published in 2009 -If the date is ambiguous, the current locale is used for date comparison. For example, in an mm/dd/yyyy +If the date is ambiguous then the current locale is used for date comparison. For example, in an mm/dd/yyyy locale 2/1/2009 is interpreted as 1 Feb 2009. In a dd/mm/yyyy locale it is interpreted as 2 Jan 2009. Some special date strings are available. The string ``today`` translates to today's date, whatever it is. The strings ``yesterday`` and ``thismonth`` (or the translated equivalent in the current language) also work. @@ -379,48 +445,61 @@ For example:: To avoid potential problems with translated strings when using a non-English version of calibre, the strings ``_today``, ``_yesterday``, ``_thismonth``, and ``_daysago`` are always available. They are not translated. -You can search for books that have a format of a certain size like this:: - - size:>1.1M Will find books with a format larger than 1.1MB - size:<=1K Will find books with a format smaller than 1KB +*Searching dates and numeric values with relational comparisons* Dates and numeric fields support the relational operators ``=`` (equals), ``>`` (greater than), ``>=`` (greater than or equal to), ``<`` (less than), ``<=`` (less than or equal to), and ``!=`` (not equal to). Rating fields are considered to be numeric. For example, the search ``rating:>=3`` will find all books rated 3 or higher. -You can search for the number of items in multiple-valued fields such as tags. These searches begin with the character ``#``, then use the same syntax as numeric fields. For example, to find all books with more than 4 tags use ``tags:#>4``. To find all books with exactly 10 tags use ``tags:#=10``. +You can search for books that have a format of a certain size like this: -Series indices are searchable. For the standard series, the search name is 'series_index'. For + * ``size:>1.1M`` will find books with a format larger than 1.1MB + * ``size:<=1K`` will find books with a format smaller than or equal to 1KB + +You can search for the number of items in multiple-valued fields such as tags using the character ``#`` then using the same syntax as numeric fields. For example, to find all books with more than 4 tags use ``tags:#>4``. To find all books with exactly 10 tags use ``tags:#=10``. + +*Series indices* + +Series indices are searchable. For the standard series, the search name is ``series_index``. For custom series columns, use the column search name followed by _index. For example, to search the indices for a custom series column named ``#my_series``, you would use the search name ``#my_series_index``. Series indices are numbers, so you can use the relational operators described above. -The special field ``search`` is used for saved searches. So if you save a search with the name +*Saved searches* + +The special field ``search`` is used for :ref:`saved searches `. If you save a search with the name "My spouse's books" you can enter ``search:"My spouse's books"`` in the Search bar to reuse the saved search. More about saving searches below. -The special field ``vl`` is used to search for books in a Virtual library. For -example, ``vl:Read`` will find all the books in the *Read* Virtual library. The search +*Virtual libraries* + +The special field ``vl`` is used to search for books in a virtual library. For +example, ``vl:Read`` will find all the books in the *Read* virtual library. The search ``vl:Read and vl:"Science Fiction"`` will find all the books that are in both the *Read* and -*Science Fiction* Virtual libraries. The value following ``vl:`` must be the name of a -Virtual library. If the Virtual library name contains spaces then surround it with quotes. +*Science Fiction* virtual libraries. The value following ``vl:`` must be the name of a +virtual library. If the virtual library name contains spaces then surround it with quotes. -You can search for the absence or presence of a field using the special "true" and "false" values. For example:: +*Whether a field has a value* - cover:false will give you all books without a cover - series:true will give you all books that belong to a series - comments:false will give you all books with an empty comment - format:false will give you all books with no actual files (empty records) +You can search for the absence or presence of a value for a field using "true" and "false". For example: -Yes/no custom columns are searchable. Searching for ``false``, ``empty``, or ``blank`` will find all books + * ``cover:false`` finds all books without a cover + * ``series:true`` finds all books that are in a series + * ``series:false`` finds all books that are not in a series + * ``comments:false`` finds all books with an empty comment + * ``formats:false`` finds all books with no book files (empty records) + +*Yes/no custom columns* + +Searching Yes/no custom columns for ``false``, ``empty``, or ``blank`` will find all books with undefined values in the column. Searching for ``true`` will find all books that do not have undefined values in the column. Searching for ``yes`` or ``checked`` will find all books with ``Yes`` in the column. Searching for ``no`` or ``unchecked`` will find all books with ``No`` in the column. Note that the words ``yes``, ``no``, ``blank``, ``empty``, ``checked`` and ``unchecked`` are translated; you can use either the current language's equivalent word or the English word. The words ``true`` and ``false`` and the special values ``_yes``, ``_no``, and ``_empty`` are not translated. -Hierarchical items (e.g. A.B.C) use an extended syntax to match initial parts of the hierarchy. This is done by adding a period between the exact match indicator (=) and the text. For example, the query ``tags:=.A`` will find the tags `A` and `A.B`, but will not find the tags `AA` or `AA.B`. The query ``tags:=.A.B`` will find the tags `A.B` and `A.B.C`, but not the tag `A`. +*Identifiers* -Identifiers (e.g., ISBN, DOI, LCCN, etc.) also use an extended syntax. First, note that an identifier has the form ``type:value``, as in ``isbn:123456789``. The extended syntax permits you to specify independently which type and value to search for. Both the type and the value parts of the query can use `equality`, `contains`, or `regular expression` matches. Examples: +Identifiers (e.g., ISBN, DOI, LCCN, etc.) use an extended syntax. An identifier has the form ``type:value``, as in ``isbn:123456789``. The extended syntax permits you to specify independently the type and value to search for. Both the type and the value parts of the query can use any of the :ref:`search kinds `. Examples: * ``identifiers:true`` will find books with any identifier. * ``identifiers:false`` will find books with no identifier. @@ -432,6 +511,23 @@ Identifiers (e.g., ISBN, DOI, LCCN, etc.) also use an extended syntax. First, no * ``identifiers:=isbn:=123456789`` will find books with a type equal to ISBN having a value equal to `123456789`. * ``identifiers:i:1`` will find books with a type containing an `i` having a value containing a `1`. +*Search using templates* + +You can search using a template in :ref:`templatelangcalibre` instead of a metadata field. To do so you enter a template, a search type, and the value to search for. The syntax is:: + + template: (the template) #@#: (search type) : (the value) + +The ``template`` is any valid calibre template language template. The ``search type`` must be one of ``t`` (text search), ``d`` (date search), ``n`` (numeric search), or ``b`` (set/not set (boolean)). The ``value`` is whatever you want, and can use the :ref:`search kinds ` described above for the various search types. You must quote the entire search string if there are spaces anywhere in it. + +Examples: + + * ``template:"program: connected_device_name('main')#@#:t:kindle"`` -- is true when the ``kindle`` device is connected. + * ``template:"program: select(formats_sizes(), 'EPUB')#@#:n:>1000000"`` -- finds books with EPUB files larger than 1 MB. + * ``template:"program: select(formats_modtimes('iso'), 'EPUB')#@#:d:>10daysago"`` -- finds books with EPUB files newer than 10 days ago. + +You can build template search queries easily using the :guilabel:`Advanced search dialog` accessed by clicking the button |sbi|. You can test templates on specific books using the calibre :guilabel:`Template tester`, which can be added to the toolbars or menus via :guilabel:`Preferences->Toolbars & menus`. It can also be assigned a keyboard shortcut via :guilabel:`Preferences->Shortcuts`. + +*Advanced search dialog* .. |sbi| image:: images/search_button.png :align: middle @@ -441,30 +537,6 @@ Identifiers (e.g., ISBN, DOI, LCCN, etc.) also use an extended syntax. First, no :guilabel:`Advanced search dialog` -You can search using a template in the :ref:`templatelangcalibre` instead of a -metadata field. To do so you enter a template, a search type, and the value to -search for. The syntax is:: - - template: (the template) #@#: (search type) : (the value) - -The ``template`` is any valid calibre template language template. The ``search -type`` must be one of ``t`` (text search), ``d`` (date search), ``n`` (numeric -search), or ``b`` (set/not set (boolean)). The ``value`` is whatever you want. -It can use the special operators described above for the various search types. -You must quote the entire search string if there are spaces anywhere in it. - -Examples: - - * ``template:"program: connected_device_name('main')#@#:t:kindle"`` -- is true when the ``kindle`` device is connected - * ``template:"program: select(formats_sizes(), 'EPUB')#@#:n:>1000000"`` -- finds books with EPUB files larger than 1 MB - * ``template:"program: select(formats_modtimes('iso'), 'EPUB')#@#:d:>10daysago"`` -- finds books with EPUB files newer than 10 days ago - -You can build template search queries easily using the :guilabel:`Advanced -search dialog` accessed by clicking the button |sbi|. You can test templates on -specific books using the calibre :guilabel:`Template tester`. This can be added -to the toolbars or menus via :guilabel:`Preferences->Toolbars & menus`. It can -also be assigned a keyboard shortcut via :guilabel:`Preferences->Shortcuts`. - .. _saved_searches: Saving searches @@ -472,9 +544,7 @@ Saving searches calibre allows you to save a frequently used search under a special name and then reuse that search with a single click. To do this, create your search either by typing it in the Search bar or using the Tag browser. Then type the name you would like to give to the search in the Saved Searches box next to the Search bar. Click the plus icon next to the saved searches box to save the search. -Now you can access your saved search in the Tag browser under :guilabel:`Saved -searches`. A single click will allow you to reuse any arbitrarily complex -search easily, without needing to re-create it. +Now you can access your saved search in the Tag browser under :guilabel:`Saved searches`. A single click will allow you to reuse any arbitrarily complex search easily, without needing to re-create it. Virtual libraries ------------------- @@ -488,14 +558,9 @@ learn how to create and use Virtual libraries, see the tutorial: Temporarily marking books ---------------------------- -You can temporarily mark arbitrary sets of books. Marked books will have a pin -on them and can be searched for with ``marked:true``. To do so press -:kbd:`Ctrl+m` or go to :guilabel:`Preferences->Toolbars & menus` and add the -:guilabel:`Mark books` button to the main toolbar. You can even create multiple -types of marks by right clicking the :guilabel:`Mark books` button and choosing -:guilabel:`Mark books with text label`. The text label you enter, can later be -searched for with: ``marked:the-text-you-entered``. +You can temporarily mark arbitrary sets of books. Marked books will have a pin on them and can be found with the search ``marked:true``. To mark a book press :kbd:`Ctrl+m` or go to :guilabel:`Preferences->Toolbars & menus` and add the :guilabel:`Mark books` button to the main toolbar. +You can mark books with a specific text label by right clicking the :guilabel:`Mark books` button and choosing :guilabel:`Mark books with text label`. Books marked with text labels can later be found using the search ``marked:"=the-text-you-entered"``. .. _config_filename_metadata: diff --git a/manual/images/search.png b/manual/images/search.png index f490eff154d030589d152ce38623ea32153aa9df..f4f5c48f4e65fb21775863209407dc13c481b887 100644 GIT binary patch literal 24767 zcmb5V1yGz(w=GBn51ya_f;$9vNC?3#xHs-j9q97-ZhC+w}2M32HDIux|2lq-74(^2+(o5h-`ysIy@PTY6 zq2UMzhyM5Z??oH~IuRV)2RKR5&&sZ;2T(7o_uFYSH>6+Z!*YA~6k=vO`wlkJykU|M*LIIyGo7K6ezy7D}eMks;_x!=>me;ZD-a?Sd@K;U}AJPUX2D&?DciuS5JiAWu&ZXB1BpPeQk(kLRpc-_}EYW>?`J zVVjVrBekQ#0VL8Xamam~$Mcb8aCJCW==GA&MGDa|gYezqvFcOT4}P4>k9=1bJN@v4 z{QON0&c--c|2o|Nspdic$^14WSb`DezKgdxNt~uj{NSx05Znel&^H6BeNrs!Is|ia zB+T`Lcpdv;U=*Wzn%RwnPhmuZ?RI);bz1M<5WDU6K30cvbKy_`o%4ys?Vw#g{3&$u z=_bKv;kK-kAoIQx*YUGODmt#u<;eBpWA9Vt!$7zcm8a*(pFgA|4d=%Lk`B! ze(s+&A|N8cng(q!Mr1@Q7r%3GK|{jGo$=95nsFmv~ zT&Uw1P3+MqM~$lR*>7}rf?D0l=0#*9Kc@n1s8}ZeJ#;=@ZU{bgf|y|mKCaCSFZ|g% zO1FI{d59l&i6D3DW6Sr7cah%OclRGC7TGJdQAr^lt|Oy|ul!!UdKEV>Q@ONb7OyH- zhB+n`5s`|o!wh`e0gXiPE^D-G(-SB2ToI13gVzt%q&9(W)FI2l5f@`&WX28oxvcU2 zgM%ZBPr2LEME1ZdP^*-9gmN2~v%#2jSCtwIhO$!G7$lu|XozvCS_Hh&Yl(Bu!gv&U zf$v~+up3wWik;zf%2r$9YgVZ?$;}>`;_FYM_ZjKGJ=&VoOS+MP<~6rJots@iUC$XNBVM&=l7zW=PRSX8vDYZDd65EvIVW>4#j*QMIO z$8fR-MqUs2FA36eKfFHbW)Ef1btB~Gkis+L;BPvU;dw^{EgyTtsm76S2G+?gYlTC$ z>vP*433Y4upbBEq&3o~YuUByIhaFho)0CyWhJ%}ZCscKO^>h~M(uDuXuJyx|u6TpF zEXfyGvC9%{;OPKZvZS!Ty=h-w`EjeN`Fv}$?^#(n_A)z0+$Xw6ux)nPVAk;7-jdeve7YYQCNa0yek7@! zIaK${s;TlEQA@y(eP8V9@)U5)DAbZw&=w#8^s$~A@71FG)52w0YZ!(5aql#H$JQ~U z_tUiIDjuXs-4oVfIUxL4{&ZNo+;X{B?gNwOUWU}x*;`s0>iG%PUazG2kt$9Ku(=x; z-=>!{qq{yeKMeNogiwewaHoz{=0{>;5hvsGui~-j>SR(F%9A#phC!rU%r*nR9Gz)- zdNMFH#yvMGC}Po$)Qor59 z&*&z~< zqvh9flGYVeUM3(={V-nwp?AC7`{QEZ4p!mzRU>)aL(3wH+6$)$LHK1w0@z$VM0a9G(avZPc+NPVH9 zw(j)tuC%@&<$mY6)uTnt*BG43j1lKccZg3XOADkWDmJCoi<-qPS{l}dM*prMNSR|q zkDXasp8dTVzOa-#b&dER7j+<@C50HWlNNp*vXuX$?)9tZ%hT#^hYX&-%)^wnR3vv^9R7T5g=la2-vOs$rpz0?ue_EY43Upj8a692+r5M z8UOr&+#Pl~6S5=!^wzc<0dBV4`>Hyl_3>^$<95(Ai^ZmnLHP0|B5R^>BWn`yxL3{!cz4 zd`K$2NH5@=YkvIrVG{($k6rd(ZL^j^42T+Mnk&WCEM#C3jFZZ(BeZ#`l@T*sc!1r= zvi#Vy{j-@fP!}Jndg1-himPAVg=1!^*X8Krd4E{Hyj1hmIA4(etIouskBpwUR4h6Q zMI4*xP7vvh2LZfv|VwC*Y9K32ph)2DlEXy0`$ z!;V}a_jBB7vYtNfPtsHRI`?X?ovTD=&>e>RqN9Vcu#m~{4Mij-hVpV^!yLsHq9*N{ z2N$4uvC);K+drD+V9OM!k&CCj9jAE9K9>zo_b|t<_2tQE?j26T>)TV(HlG%q8HT`n zi)mXLE6|(Pk4@c#;tdn)%f7g6C(t{g`bo8WIdGpnM|fjE%3yTW+|rZci;Fg+l&&yV zI{%boNxDXJHoDded8Brp>j?(^9E&S`*s@Y#Y<&kU6BKjF+uE$JGOz|*AEI|EgHH#o z+9SlMC!L6eupFpajC$mR4uw%EQ=7H5rPn_V`isfIKf#2(framVAQtA5Dp`vjfDB8lL7%Ns)=2(p#UR;2pM(AnOtQ zBpScrkE{8Q?0m|n9b%_oBl~+iBTJxC5|r9J7IN|?d~>GB)S`f_3lMej>3+1!~$jD3Z$(}}{C7WWdq2_yeCX!c7C|B>r=x-owH}Xd(PmDtW@eJc z#IkQbU`QPQ_?op^&(XjnQ=56AKUY|P#}|)WtI>NMKBlERHgQn_+FrELefqhi|h{N9)u4${aE?yONVmSIr~E~3!6yT8EI7))c6Dny0f_>h%2ksVSuOvP{E3x3{5$yZM$!ew}AtV8PNE0-DTt##R%rq0D|<_qQigcJx3kY{liMnO!@P*K62B1=qZk6TJHK)-dUCreTFJTcHIpO0K0L7QEUm+mu|zM>Qq;oNr7$Mumu{DEB* z79Y1>`!(ehDo!ZNTE@imK*dr60>)4C(+!>XjTJdVi<{TBZC*$sOQ_Tu2TCO@U z`>|bVi87$MfYhV95S6fyRN3eQ8u~N`cG_XDCs#_06wK{g>RNYx?HVIv?1SdJt4WM> z1Ey5sDZJm#A}TsFh<)kqd#>hWJSjai8ZnO0{%e{mR80O1w6>GIXr``-j>b^pZ=J%` zm7udgkYD1<({-w!8S-8E{lYfQW4*n->yg4oTRy89+1QT*FEHaTh7E-299Z5{8l=Wx zR_zA3c1UpQ{wc;ekfa$EsL$E!pt6R!x0@IiYS2PsWkm-DeTOXT26Ib}9P1r2q&8UI zb}i4pEAp=r?H*SqyQU40QaHqjlQLc%x%SGvm|SkTKWaX1yZ7t6ds(!1&??pW z`>I+BOYu3OA;ftWG3?Dn44Y2yn)4OQ$`vob7sDcd{x!|-!~3l_y}PGbbC{*(Ct* z95e10XCRN44cZmHU`#HmQ^Nw@?Ley6*E25(3>78F;MW7F_Z^*4xlh=t^ar9V8jhoa({pWVwh&HNNcr7gxeJzj43EGmje3Vn(zXI#8_ zH1a&y!?o~EfAE$?b@DMi>+35AdTX?+ukTomo};hrtQ201<2I*WZ_;Q|)Nq$0&NrKr zlq#(W!B0wH>Mi#|)a`>e&~04BsNwRK&{Pf^rFW8kET3X*m1WmG9nKh*+ipt7yJ|eR zh%)wZ$xG6%ww5bRKsOug%OW7A+R=lNk~8V03ro!F04ow}Pk-5`hC^Kn3JRZ7JfF`| zO6V0|`!e`@c@sLYH(0dnhXaiJMy)APR@0`Fhei-~(b=t)2$AD!@eMy`_ot~0^CAye z)3&^8=9TT~;4$rhD9dY#bp-H2+|SKm#O_&p#=+zqN@1+s_}sEv^*9mPwOW$n@qSrE@$D5>qHz@=l&LqRO-;U&kh=G^0k(XQ5V z6VL5N%AV_23O+B9X54W!eTFbm5+lhXRV5(dcZ?WyeJMv zc)a!(VyIn&S3J+gd}P~ghs0z>A3T;*TF%E{_mW>4fmC# zebt}?XZ%s)1ZJJP@r1S-fX6!g^x?zf!(+EHk?{zwe+7gW-yfrCi9Lb91rY%uf|$P!I(E^h z2J*TDZhIOu6`DBw1ia{XB&8JMvfDQChA*+*6YLt)=6Ra{dDwjRBTF8~PWxNat;?@os9eX1j^z2UPD+Z8KRY|S zJvy0RW+ZJU;F+&wR;sRG9AJ0mFBDI#1bhScUR6b zq=W2mpF-yFHx>*sNGFju|3r1V@V&BM0CfEbUf)E3OxxoT7S6Z7XQ zXynr`A_7(4v!uT1ZxSz_`oc7GNz^yg;pIM+b@&&NYu|f~xEQT45uzaQnfLm-PKGI5 z@UcIo43FCE0Qo6Fjf9jU*|i<^q-xDdx{y_R)i(FdCDnsd(Txl9bKnHQ_za(w3vwpm>rdd%MNR7O9zVoJ(y3K<6w{sRw0Jgo z=jJ!PRo3zv6FgEW=|kv*d1QzimRaU7xAeljvv%&BT`zC>SoyGc9(u{z`1xzTvR746 z^svexaw#urrom^^F`TADgW=2bObOimteR)dP(uu@4l>2i@t~6y-Tl(e z>E0Ma#8PEtDLG&?q3NEN zy&P=2P~>tsGuqv?bdruP^0q|P?j6hgqWdApq^zrEg7%|uu$jbVluIvA%h%E@EHcWG zEW%HJc8y&=Z^hBX%OgI$4>+$3!CShRiZ!3_I&&PrXbcsa3fum%-MzS_i|=vt!@^}m zP@bhlqg4G+@U7m7x%Oaf_+Jc#F_UW<0glh1EG*F$>HB#cHY;s8j_+JVI&m5v9$w|+ zwfdF|d=>^dqfTaw9^(3xK_ztEeA7Kv$`brCGRj#_I{uzH=36?_KhI5aYdN4ZK;C)k z0M<)I7goB69Nt0~6kIn^A1h&W0VXZjdJFTNDFz0~uyMH?gHxVvBCvUMa(QK+O9W^%X>ob zbQ6Qa8_S})UzJ!^t8t`m&sI*pmEuzCj}QUce708Qb7yv7f9$&9Z&Q!3Js)m#;AqGx z9Mp}C;?yXl{M=4QYuV>^UO7W*p77G%Mg!2k=x5IWWSM$-a^=pFP+NojEw=AC@7e zqdJ2v&nmknT;M~=wB*vdySvGSrx4#Ac^#ap=_VqH2(;o8IikJ_tDD0~9&()cL6cVe zng;CVmeegYa~XQA$v0y$R!*=*0QVs(how;ZH_!d1_EmYA3VW7frFsrF7B3aK&zH*+ z_AVJvJvlOas0&A$eQTfo6`VhiSk>K|9^B-rJ=HndWf>JnWuAD4^%8MS~9M4oO@ z)LHvBDK#xEG90)MIrQHqnu%8aqKX~~m*WA1Zo_Av8( zIO-tkx%?dH4ieC5P4>2WE;7W9+L1*aV_Z;v?T34H1Mek-XH)M!wm_&n!mg5Ev-<~U zSj9@5%n(C1j42(RI&<~CZFc-{t>T4cpc?|5M4olAAN$PoegdS5rL-I;s+p`ED(i z9=Q+04nx#PXf!?D?AJ2!3N$wYXmCmGLSy-zx9^GBL5P|z0R>@b_j_s1Kb2-F11#KT*|7MG^ZW8Ly25Q< zfm{~aZtQq)SuF9C{r2JWL!q=pL#JGdX>Fpu1QDJ?A4lNe`ra(UW+OM|Sh$$MyW_ci zeSJetA31V*d1j`kxn}0eTu#@z40|F<#m7git6cBO5=i&v(dwaxUJM9`h)-9xPgiaC zNBgr$dtN%pF~HIg6uy#z2sDhQZQLJ2APYbK3_EW2$7PF0I`gCK_)_Mlr@QXR?N&xg4A-%B3<0TNjkzpdpFGgXNG6>HloHOQTc zm5=o?W0cP&sn2D3)69MRn>TM1eA(Y|Z}U5j%7V@1=-*}a*FA*nem$am1y@5n-k$Eb zKh0$I`HF}8{!bFh{&=eAuJFT}v}nBzbWbk>I>BPj0teR40#{fcF9etfT~$WHF7kyB zo!|aK8diS0mGg>Or)lyK^Y@J4&59os{e?4r3Hnt$i+5$8wIBdT(6n1zD;LQA49A$w zVer2Nj=(j)bN=y+RQ}KSZ|B$gIbdn$7A^B#0Fq6`wei3H$2Ef{_OXfe5B3K0RmRyE zO%edwx7`SeZqf|k(Pyq5K1F%}d&zdZ>NWczH08ENN~&+xCIjsshYt&1;KB(xP_ z5GJ_bmi!VLuzEP(P^zV$;~7|RJ0*xYSsSK&KwVO$I=Fq*^V4jfp4Ov;OBpA{PHOhN6Wqm!HFxCx=63&}y!`)p=O5V^>0e|2Ps07&JV9SqnS2Q^nC{OSoC%r8D-@*U$0I6>vFa3<<1F z)TnT)7}zfztHmq@ed^y+wdrVGlpXAo8!ZEWbg?LyUe(BVL{{*NsKf5u+9N-F1@~Pi zvnesoRf8d!0-3BA^h3JLyi||9(S6SF%&Ze$qb+t}z^Qf$ZN7r!8vY zKNd;50n9)m-#q^37q&r*mi>_5A9bZ$4`>&fG~SoQY|5b#r>6<3=x~?d+NJe()hVcv z&&RTR+$cw+&UM-pE*55XRyWRde#r!-HB4J1a9U;+Sk~oLEE^0Z?-XjwFim}5(<;!> z2Ag1b92WQjdWKo%MdxFGiCo1%4%DL#0(M#3gy|2)%x{-^rkD)ElIoUaq!h+43hkMO zH7*fA?bb1c*`@2t@7|NhwWBAG!>`NYvc_CgQK0?btx(`shx|a3T1%&WyY_aVT1t%v zx3%XQ4kj3+&L$5T4jT0lRqh3!YU8U4?Jl3s^ICV?GTul`Y4W`8PviT#Jz{Ez@NSRW z#bW1e8mO3#5Jv`TMQQOvg!Hb5V@erVo|Db4r)z!~Lh3Fj{c#N9ktByw0)k)g=|bN* zpT^`&MW?z087*sVVsOIWwfKsfq$EbHs66ux9`vY~0p7VJg!_iomzrF~z|2j|+cRh1 zra0`b!>#!xxJ=n~c0XiNJ*Bz2DP;VSss7iHNnhx2-)5>67ZIrd@a8|N)(f?MvTEhY zTXGTW$}ST1o{oW4oWSVcT1^n|yEZC)$$xJeXFh#+HprQ@LES z6C6y@bDUOOEm}J4{&@@;vYMk+8cf_C^x|_RxI`_@{Krh@-LU8U-zY%FeMu7}wVK?L zs6EOZ(&jI}#iJw{HlLd{Za5eWi|3zmg{VzwauK~J;7biF$z!&iH)uP5?{DMRMc<=PfU-4yH(ZNYfoMWXaQ44dn z+sBO0t3&4tKJxOy^n}i@dsp*+269=@gu3zwD)ro5UZw2yE)sMuQ}+S&uT-BClXvMQ zZJV9ZN5_FD5$@%w6vsLgtMGzP3bJHS?4?kC16@fPCa5))I`LaEsrnLx!=U7%tHM39 zzE5w_==kj-rI4vhzG zKV>ze0i#_t1gn21EzO;yVdtWsi$%#gUe(Kt`0iaAvTm@|;@u&h%+ESfj(0+NX2N}+ zUM@1J6ZzCA4ZB^!1{IO|c-3aYi33i4;>koS3fdO6J7Yd)R=+<|`+qoU{gLP>Cqf&a zpJ;wJhb2kZI@k-2;p^r_wP2lyXcd#!bRX2g_P!6RG`p|0mav6}FF1uLW&M~`Mq=9R zawfFs8$pP3G8A7W1)GZT+E)4<{;JdAzX1q^*2`%vzklV>0te_w?frj+6t*LNeYi05 zI9-f4!`e+d1|?RM!UkBm_YxI(Q~@7Ms8Q)8Dmwr}Y21Gtw-6OqgNr~O7E3lHGG}x& z)KZz|Fk#e$`8NsEXkH-C=783sTw8fKrD_@7LW}QaE5&xnZ9B~a$SnZ$(w{${nv;R~ z@LejmsblO2_dps5{OIaGSPL5CS9DkYjA zt1Nfp6_yBQIjBe3rJu*N2{RgbjVrWxp@WwEoH~Yjbs@)kcg4CMT4%f5wqOfs)ja$>?)&BXTB%3ba{4s< znpmNeHnu5yZlSyNO7mB$(Q$Ec0QZEBw)!~`7|{g-YwN?i%l+)^Y_xu>5iLo*{0=Qi z-~`-n-v2)ufC?}FsPWP|VFL|K_miIuy7hwWqpGgVZ@`+B>Wm2k|DCdLU0Z4Q1K99g zaMQw%gSY=s43Ur;rsj7rCSQ>{qbhwIkPRtc_yHikcRwJ}nf3zOp;~0DgNF`~q$bd}s?~hyf=D*n90O#n{nIUph2yzg6cs zH9-kcU@>3qNlA12t5xVl$J)H;gO22;(9$ia`DgwGGD9Ir@b!rw!J&=B^Mm7Y-@3x4 z_mh(Xd?n-cCCT;ieHY+kx-h1RrQ0c`S&rL3QK$l@zWM#(O#>#-=@!Run#RRtzsOg60O}%Y;Q8u51V>;Plx%YPI5-@MM@Vi-mvf_c&)rJ<)6VVXu5Qg zH;BQ(Jl`t9HLqO0zLS-tqia|3Qk?SU2=n(SoI)osoZP_GHJ;g^_HVLbZPtd?+px{P z)}LZV?*>C({S%Q~2-+kJh;EpC4y=%jibN(0W>8x!!rm~))xk%`5uu~PLiL{4 zo&jbfqXpPbF!spDFfZhT}?6T7JKPeAt#;4yd zXxgsQ95xv-_QU=@-?TU88^2e<%2!rcrduQF4FtUjT>|Q;q(W|u8g*T$$ zP1Yw@1hgfNW_$7GCHE9iwAA@C2JNh8-aqO)Rb(zR^5))rZjpAz$bry?S9b~s#8$CtLJ^B z?e4BgF&<&sJFumhla@4$iDk@2Kp*#>+?4FtC=V))TDwlblyRMWS9i_dfDapU`p^3JHT z6ooSS1}$TKjM|g(6eR~_EJdlvWzRuO>C+sFjMnk*yV}htdtU;L`keq~BOcs7Uj@?& zb1uev{+iTKHSufb((9WmMpp^YI)AIJ}3YhTMyA|DSnIBT0_ ztQ5kg^asXeRGP0rBNb@f>IO^cS7$53*D0m+NxSTt-evCFJ(HlOyp2!-L5tt4|hVjO+B`o+Q|^7m$IYDU08gEA{6bQp1qYLLuea%$)7$G zVJVsx#JqxLL?p>%$5|kp5wQ?l`#BE%c}@%BH7rHkd!gvT936& zXGVn$C^$cX<_rurgeaP{nXez6+){|luW@>Yt#Rd9O66uq#vZ<$7cU7CK4R<{h{hJ; zBH^Le8PYvUEVd`6XLZ%?Ad$ada940DG6Ur2di53$Z~p*#B;+N(H(H~xgh}|wjs0hx z7@U_hJ{{;pj^|0;Y_mv{@nVZdMTgurRIT2~=@K{vts)<~^Jp(Z(+8~ji4=ZTo}Gds za2Wf@ev0TY>(w_7Y{v?3M$XRguzD`#uQRLt?XKjtd}a5$D@FfY72E|4aOaBi95j;Z zTBY@W)H63-0LGJ+JRbVn-y|y9F$&KjdgTH$L8XQtBE)SRq9D>b9RV zi6_~R2Rw*sJtj%;Di!#r*qUY;v9uXFxz|)cQR)}lJP}9y(kXbT{4;v}osxqYos^gI z^W%gw4$l+Pc4|(n4eJvX*|TE^E|z{)f;?4mp>Pl2JEpvgk9&Yp0N&tTN2(*X$j#8a zy{srgmK9~)=8k$!#<@eYG4swB*e;ZSnqUK5}@cb}+ zT~QgVrq24s2y5OGhH`+--M<)wvHpA`CnY(S?JXS^b%HYarcS@~FbDuDvJ)oOM<;}$TFKDmVKnK%+K_~`&J3|KEs zAq$%h^@cl+fHV^LxnrqL>@UZF8@lO0fRX$H4hekwnSJ#77rKb}yU;GFT!&?^YbSn8 zxbI76-9)xL5fi!M_N(4Y-p^fCq|Hpq?_Bbqfd^*6Kmv;k!2T&UIAijmc>INfvp?ac z1f%`~H+G~~(SRPSiOSMj9>}l9k}Xm^25qz*bb9IP)#mJ>wRK4B#;eRUXth2j^8Nk| zy`%42#{%Lqe=R7fR8gCP@PBq;{Lk{kY>f0deJf**@5_TBLFJ%scRA4%4By;b9@|aH9+B`q}12A__e6`uXVy5za<)_SpxPs|0!6%C*|F5=?+Uu z+4eED=+Wj<0@94tvdP=I1b|UGlBErE-0~{1NoC#QV)jSUog=cSk@_!*l~ECW>EBKn ze$Qf=k770yWC!8kj{wjR+6Jhm_`}f(p#P&W#pu<)oU>EgG`SH-lJ#;lrl`X6m)kG2 z(T7#`%Bv{$@0^;&4Rv(_#==izmLX3r&u_gG<@8orEt<*56&NDX4W^Z(%aQa`+{GMB zWv_ZWGcDfREz1f4ygRzdNb;}BDsxr>pRrO*qra^g>=#_ z0x5t-{?wsxIfrz3Gy?X6k)pS)!JJM1w%Bf*4VwuQ5Pp`wTY@jU8s< zS5J9q7DXGvM^6i%tZh8$<%b(j&A5RRr;UwGNb8-$BjFyfzZb>$-=MU?51F)L0H;s^ zO*Bv0fc7&42Suc4_wQ-G2h7a5?d=r&dPutQ(4p^g6A)B_ky%gG)nG8&6Mq z2%m6kjp+J%$)?XnL zMq0Oiu4Yxi{)-dwS>+Q78G(F!-;tDHG`fXp9=j;uR0Fr9(7(xwZ1GTCOPF}K)umVe za$%d0Cd7(z7RXK;08q_X9!MaDG$SQj5vbB0mFjKbo=A$SL$Ddyv6-nZSa>>bn==am z)qWKz|G_m@-_lg~&34R~HwA^mmU8xo@w^1p{1`bhpmtUfv25;XM#8&ELu)+q7vrAP zvy!FDyiB}uPAN_gsY<1nYf0mcj=OHQaZJGcRXHnDzrb6Piuke%9!Q|c({jtmDO%nM zUK0Z*G#v4tLm{6>y^(xB(by!6BauG&uPnK!Lg<^?!;2K#<4M0=g);I7!B7%AX*V5} zKFRblx_he4VC8J!UbtCr!3^}R{GxiB98TGZ@l|>D3DcT~RM4NKlw`+VX@qT{z^oWb z&6Ur%EY96nGAAQUYd*AI6gMq2gs=4hog$eCJTE*#LJ(!~AMukmN-=}pJzzB6x!$?G z2&!S1madhy1{&Fd^LBKYQI_9veSLfUh{`YN_IB`O@?`R1FVysG-KNljd3!pIki?lk zIU{fIg239-!ZoplNJb>pQI`gQ!MQo1E=OO(oM1&_Ia873yBE*Zw;KBcjf6?0!wl9% z009l4zOvFbF*e==BHu4x1T#Q3V&3#u5r$?%YikBvDL{4s4z86pVL(3tuqXSVwu`FiA3E{|G_?0=LU4wPs>?xKAUE?w5PLy%H{WWp4T` z?A9?rAnJGxx1H*La)u7UH!RsQr8BmE0kCX(pERf*mGm`+mT|{9a%6)^1KyG&h1d`K zCLyC10jY#jm5yT1OynBa3-J-@_1QW-wI!rCtqf^${1J|~XPdxI0T+H;xbM35CoAoM z!vpg{TXvj(DPkKsNvd7K8HQ<&@Nub0&&l9@6(h@SCL?}d0ID_uL}+x7*YyKjbj3&% z#uC*ETuB~~iY&)Xw>c6C#LS7Bp;mOj71xEZImRerSFYs8*P5>u5sInNijN({IWICN zg!IbZzR@o(LLv)Z2*(pzi2X+M<9Rd3_s8yM;h?*$W*`;sHYMYARwEDqIHVM-(6q>x zF2-3$uu{V;k7Cv4Ic2o6vsd!^9+FO}i_3m~Ywh#{goR3~$hM|EXiV<9gyCT6isyZf zquYDjJhE%f?UPP|#*G=c*xOFy4h*%b4CwXNM_sjjivT8_c?slBoZRsKgKA((CWK)f zX$;4P1}5z#meJKKN`RF7Pq4Cz%);BH*FEUK7T6 z)o+(=N;|ARUQ+!BME)PiC4rx)O)r6al^eB%oDbCN0sFJV3-D73ETALjx1;%X49NdQ z`mEUYLgn!3yoi8Ze(?Vw!S8*(7<%hUyeFp4XWFQvzA97n8UXu`GUJtc@g)=^Hphxg$lP$kpl?FWxtHlAYot zW!fY`E?tnUuT{2wJyy2AR?fs22SXt3;!r>2%gcZ>oXTIKeHp&waMTS6Z%YA!B7Y?OT9#hf;k|6<`qvk5zY!(riuvO*(If#DwT2N_GN-_~yhcN5 zka1Rk#{y{z%V~kNm2$EH&nYgCn9cUGLQjeU|2O>#Lbif@!$-w-1Cx9f$pa(4#0>sz zqpfZBrE(zKFCTSBuECAjphzc+qun5SaauD2K`j zeZe(vLhW_EZ0#icjOkUB+F2KDncYRluHx}J2`{o@TRKlP)7Vz1vx5hL>}YbCtW5%X zo}XMH03@ivlren@g&U^S+o^+lKp7`Ea}Wja4iJ_1392Xmq{hE3)T^`?0vH+Em1jmq z4Jg~}mnt2tVHn%{?lR*m)L8&r*kaE~(h4 zFzjojveruK1MZspH@z@7jf6MM6_%r+?j$13O|{L)&Wi=~6*lhpkY) zMD(I-X&7Tb4f_NEIXP3Bv!m#LC?ST!nrBL=e4yp**7Fz0gpB|N1wcZn5pDzW4G9vF zl7x$%%91x^@F5OXF6}MG!0^dtqXbIadJ3__vbMJTZasA;#!E3;#H=Yrb7Wb_xL?D~ zN&-2IBp-?rW_;7}aVMXIL?D?iwgV*W=mBH>dvP?3>+4?ta2hiJfO99x0(Fr&aRXZT zekQaCG_iok)hpjhc$u{k&H-$Cc-?hD)Z{$c+$#3mpaPS=R#he2#e3)76-UI0j1f~df-D(oFB@i% z1FhpC=)n@#k#DPZ@23P{x}9_O${H|z?U&L}Z<~I{)JGfTofbAF{I?ch#4Iz6Oqet7 znp@m3bVSA0J+TOa${W-73-qA{+IS0x!!i3X+@I*oIc(Q78 z%7DkJ5nIy3qIREjcg)}S!&`nOLWIbxs@MRwYAX)4Vo;=7CH0~pPa?jD$+ z?BU?J;v%QF?x~xptLIHB$i1oTlZp54;7xVz)lI_GqZV9vh8%SM55Qzm&+ERnx z;UrFd^rt6@{E3KlZ9w1*WT&7J@NmD?-V3^1IO7C9=N(pTR1GVt?iD%B zC9AdTB=PAwD_q-+0KjRE+fPklzS~6R8;$#}-bp&-I~>TaOT6l66Zc7lj|`_TWH z1`2h90MG;+gz4LmU|=`ghuPtE%)%~9@;){?*#Fle*b%>*ccPfeatY}GvX&SeEGhXn z+DUC9_=3S6kT*Y`V-qVuFciwS(P zq3#W!52BQIxgJ%SNHH6(M=ACL2H%TC{eu#X!m8h*P3n)vP}6X{jb!ll^|}obDuwan z(J$)VjxPLc6J%u_acAF?=)W2G?6Ni*-uzL!?~42m1E)U!!<4)<`i=W?B1mhO9#QR| zZITCBBq^D`RH}F3qefGbiR`;Sw&y{kJlxWkISfl|(3tB`jX!!L8~2%s%XUg*Lxhc_ z)u1r4)~Qdz2xR!%j3(|egSYYeP5}G#dj!aR-lmrf~$Yy0f15=1)aV*m>_uwAm!evDNcQ>K3U6SVC`<4 zR4P>PGd`aGG<89pc+S+x9}0v*&Vj>i)#~_D9zXQ+rEZ1|{&h0k#eeT2uViZu*qA>FlOuYZ5>*UN_Z#dFk{oE4q-cSXfdHAbynDfcZMU1|WO`wl4xXYCsDQ zYzKDc1hx;r0eig+4cCF~iqASTXT}QDS|;L$*&d;*X)Rl5i<_gJU4@P{0DZq(dOa6d zS@RJfN2@0&)K_(_Pq1M=a+PpUpAn`ENxZdbx0)C)sR2WyrxGTdKnvsTUiVjr3-#qX z|Eg)aQ~2s~kKluhXGLA{nwjozz&`PPN`E!9=lAJ0>vRN;SB zb{$YnZEY6y0Z¬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 Y1K?$WIpVjHr~m)}07*qoM6N<$f=eoPBme*a delta 643 zcmV-}0(||f4vz(p7k?iJ0ssI22{c&S00073NklX2dXb5%-fD&iUT`I~;qYwcNLAC=C2W@SQKfXNw`ST-%=>F{sK%;QR!GDSYnt^n% zfW~0>1rer(fB*g!7gl+B27UYX4I=XM=Pz?p+w80&O5@k(ZNy@ZkRadv|_*|M~UHHq@e8j-Zg^nZYlBn(^6L8;^NZM z*5cq`=j7zl*VmVolVkYvL+I0eiSJK&e!a=c%q2M$y?=gkSCR9l?Ekl%&#v^^$MxaPoy(Urlv;!S=m&D*i9t3m_NSb5)>vmnRaxy?fD_K`tqw4H$TalI~Nw^ zBFh4~N_>`X+n+IRxc+MUC(-^%eQ4To7T1*5k%OtY{`vFghYufLy?XWh`HLq{o<4f? z7>2+%0Fv2Y6zc2I)gro++D dZ#oWr3ji diff --git a/src/calibre/db/search.py b/src/calibre/db/search.py index 301deab4a1..cc81e8472e 100644 --- a/src/calibre/db/search.py +++ b/src/calibre/db/search.py @@ -14,7 +14,7 @@ from calibre.constants import preferred_encoding, DEBUG from calibre.db.utils import force_to_bool from calibre.utils.config_base import prefs from calibre.utils.date import parse_date, UNDEFINED_DATE, now, dt_as_local -from calibre.utils.icu import primary_no_punc_contains, sort_key +from calibre.utils.icu import primary_no_punc_contains, primary_contains, sort_key from calibre.utils.localization import lang_map, canonicalize_lang from calibre.utils.search_query_parser import SearchQueryParser, ParseException from polyglot.builtins import iteritems, string_or_bytes @@ -22,6 +22,7 @@ from polyglot.builtins import iteritems, string_or_bytes CONTAINS_MATCH = 0 EQUALS_MATCH = 1 REGEXP_MATCH = 2 +ACCENT_MATCH = 3 # Utils {{{ @@ -37,6 +38,9 @@ def _matchkind(query, case_sensitive=False): elif query.startswith('~'): matchkind = REGEXP_MATCH query = query[1:] + elif query.startswith('^'): + matchkind = ACCENT_MATCH + query = query[1:] if not case_sensitive and matchkind != REGEXP_MATCH: # leave case in regexps because it can be significant e.g. \S \W \D @@ -59,10 +63,7 @@ def _match(query, value, matchkind, use_primary_find_in_search=True, case_sensit if internal_match_ok: if query == t: return True - comps = [c.strip() for c in t.split('.') if c.strip()] - for comp in comps: - if sq == comp: - return True + return sq in [c.strip() for c in t.split('.') if c.strip()] elif query[0] == '.': if t.startswith(query[1:]): ql = len(query) - 1 @@ -74,6 +75,9 @@ def _match(query, value, matchkind, use_primary_find_in_search=True, case_sensit flags = regex.UNICODE | regex.VERSION1 | regex.FULLCASE | (0 if case_sensitive else regex.IGNORECASE) if regex.search(query, t, flags) is not None: return True + elif matchkind == ACCENT_MATCH: + if primary_contains(query, t): + return True elif matchkind == CONTAINS_MATCH: if not case_sensitive and use_primary_find_in_search: if primary_no_punc_contains(query, t): diff --git a/src/calibre/gui2/dialogs/search.py b/src/calibre/gui2/dialogs/search.py index f49b47f29f..09f6ce573e 100644 --- a/src/calibre/gui2/dialogs/search.py +++ b/src/calibre/gui2/dialogs/search.py @@ -11,7 +11,7 @@ from qt.core import ( ) from calibre import strftime -from calibre.library.caches import CONTAINS_MATCH, EQUALS_MATCH +from calibre.library.caches import CONTAINS_MATCH, EQUALS_MATCH, REGEXP_MATCH from calibre.gui2 import gprefs from calibre.gui2.complete2 import EditWithComplete from calibre.utils.icu import sort_key @@ -66,6 +66,7 @@ def create_match_kind(self): _("Contains: the word or phrase matches anywhere in the metadata field"), _("Equals: the word or phrase must match the entire metadata field"), _("Regular expression: the expression must match anywhere in the metadata field"), + _("Character variant: 'contains' with accents ignored and punctuation significant") ]) l = QHBoxLayout() l.addWidget(la), l.addWidget(m) @@ -427,8 +428,10 @@ class SearchDialog(QDialog): self.mc = '' elif mk == EQUALS_MATCH: self.mc = '=' - else: + elif mk == REGEXP_MATCH: self.mc = '~' + else: + self.mc = '^' all, any, phrase, none = map(lambda x: str(x.text()), (self.all, self.any, self.phrase, self.none)) all, any, none = map(self.tokens, (all, any, none)) @@ -466,8 +469,10 @@ class SearchDialog(QDialog): self.mc = '' elif mk == EQUALS_MATCH: self.mc = '=' - else: + elif mk == REGEXP_MATCH: self.mc = '~' + else: + self.mc = '^' ans = [] self.box_last_values = {}