Data Integration Guide with SQL Database by Example

Help

Copyright ©

Mindbreeze GmbH, A-4020 Linz, 2017.

All rights reserved. All hardware and software names used are registered trade names and/or registered trademarks of the respective manufacturers.

These documents are highly confidential. No rights to our software or our professional services, or results of our professional services, or other protected rights can be based on the handing over and presentation of these documents. Distribution, publication or duplication is not permitted.

.

IntroductionPermanent link for this heading

This guide will help to integrate an SQL database table into Mindbreeze Enterprise Search. Based on a demo database table hosted on a Microsoft SQL Server the full procedure of setting up the Talend job through configuration within Mindbreeze and finally some troubleshooting hints will be shown in this paper.

PreparationPermanent link for this heading

You will need to take care of the following steps in order to get this example to work:

  • Mindbreeze installation (this example is shown on a Mindbreeze installation running on Microsoft Windows).
  • Mindbreeze license including the Data Integration Connector.
  • Talend Open Studio >= 5.0.2 (as installed on Mindbreeze InSpire appliance) – with the configuration of the Mindbreeze user components (for details see the configuration white paper for the Data Integration Connector)
  • Reachable Microsoft SQL server hosting the target database table to be crawled.
  • SQL service user able to connect to the Microsoft SQL server and having read permissions on the desired database.

Prerequisites on the Microsoft SQL ServerPermanent link for this heading

In order to be able to connect to the Microsoft SQL server from within the Talend Open Studio you need to turn on the following connection properties:

  • SQL Server Browser (this service needs to be running and is required to retrieve database schemas).
  • SQL Server Protocols: TCP/IP (this protocol is required to connect from the Talend connector).
  • SQL Server Authentication: the “SQL Server Authentication mode” is required to connect from the Talend connector.
  • The service user used to connect to the SQL database for crawling the data needs to have login permissions and full read access to the target database (at least “Select” and “View Definition” permissions on the target table).

Example DescriptionPermanent link for this heading

The example database table used for this paper “supportticket” is intended to be used for storing the basic data of support tickets and is defined on the SQL server the following way.

Configuration of Talend Job for Data IntegrationPermanent link for this heading

After all prerequisites are fulfilled you can start creating a new Talend job for crawling the SQL database table and mapping the required table columns to extracted metadata attributes for the Mindbreeze search.

Start the Talend Open Studio for Data Integration (e.g.: C:\TOS_DI-r78327-V5.0.2\TOS_DI-win-x86_64.exe). Open either the existing Mindbreeze Demo project (from the Mindbreeze InSpire appliance) or create a new project.

The next step is to create a new job (defining the input source, the column mapping and the resulting output properties) and specify the job name.

Setup Database ConnectionPermanent link for this heading

Create a new database connection to your Microsoft SQL Server by means of navigating in the Repository window to “Metadata > Db Connections” and choosing the context menu entry “Create connection” and assign a connection name (without spaces and special chars).

Choose DB Type “Microsoft SQL Server” and fill in the connection properties:

  • Login:<myTestuser>
  • Password:<myPassword>
  • Server:localhost
  • Port:1433
  • Database:<testdb>
  • Schema:(blank)
  • Additional parameters:instance=SQLEXPRESS

Finally, you could test the connection with the “Check” button.

Import Database Table SchemaPermanent link for this heading

The next step is to import the database table schema for the desired table (supportticket).

Select “Retrieve Schema” from the context menu of your database connection. You can skip any filter restrictions and proceed with “Next” to the selection of the table schema of the “” database table.

After selecting the schema for table it can be imported with the “Finish” button and it will be available as data input source for the job in the “Table schemas” of your “Db Connections”.

You should check and maybe adapt the column data types in the schema definition (especially for data types of kind date or datetime) by means of editing the schema again (“Edit Schema” from the context menu).

Verify if the date parser format for your values from the database are correctly or change the „Date Pattern“ appropriately:

In our example we have to change the „Date Pattern“ from the default value of “dd-MM-yyyy” to the data representation in our database table (as seen above): “yyyy-MM-dd”. The time part for datetime values will be passed directly and recognized without any special definition.

This screenshot shows the correctly adapted first Date Pattern for the column createdon. The second column has not been changed yet but also needs to be changed to the same value: “yyyy-MM-dd”.

Finally save the changed Schema settings.

Configure the Talend JobPermanent link for this heading

A simple Talend job normally consists of 3 objects:

  • The input data source where the data comes from (in this example this is the SQL database input)
  • The output data source where the data should be sent to (for Mindbreeze Data Integration jobs this will always be the “MindbreezeIndexOutput”)
  • And processing instructions how to map the input data to the output data (the “tMap” is a commonly used element to define such a mapping)

Setup SQL-InputPermanent link for this heading

Drag and drop the table schema of the “supportticket” database table from the left tree to the job workspace and select “tMSSqlInput” as type of component to create.

Setup Mindbreeze Index OutputPermanent link for this heading

The next step is to add the output datasource by searching for the term “Mindbreeze” in the Palette of Talend components and dragging the “MindbreezeIndexOutput” element to the right side of the workspace.

Note: If you do not find any Mindbreeze components in the palette the user components may not have been setup correctly in the global Talend preferences.

Setup Column Mapping (tMap)Permanent link for this heading

The last but most important step is to configure the mapping of the input data to the output data required for the Mindbreeze crawler. Therefore, we search for the term “tmap” in the palette and drag the “tMap” component to the middle of the workspace.

In order to complete the job we have to connect the 3 components by means of dragging a connection line with the “right” mouse button from the input to the tMap and also from the tMap to the output.

Finally it should look like this:

Now we “only” need to setup the column mapping by opening the tMap-properties with a “double-click”.

For every Data Integration job we will need at least the following 4 properties which are required by the Mindbreeze crawler:

  • key: … should be mapped to a unique ID column for that data source. Must be of type “String”.
  • title: … the column or content for this property will be used as title in the search results
  • extension: … normally you should define the value to „txt“ in order to tell Mindbreeze to filter textual content as text.
  • categoryClass: … could be used to separate the results of this data source from other results

Note: These internal properties need to have a valid value and must not be “null” so check for “null”-values with IF-like expressions and assign alternative values in that cases.

You can always test the result of the current mapping by means of saving the changes and starting a test run of the job. Because we only have yet mapped those four base columns we will only get those data in the result of the test run.

So let us extend the mapping to get all essential columns into the output.

There are some additional Mindbreeze internal columns, which could be used for mapping additional properties:

  • acl: (list of string values) in the format: "TestUser1||GRANT"
  • date: (type "Date") … will be used as the internal date property of search results and normally displayed with the results.
  • modificationDate: (type "Date") … will be used for updating indexed documents in the index (normally not displayed in the search results)
  • content: (type "String") … this property is used to store the full-text-indexed content of the search result.

Now we have extended the mapping with some of the optional internal columns and will get an extended output from the test-run also including the date properties (you could check them for correctness against the original database data) and the content (displayed as binary data – but should contain values if the original data source contains a text for the corresponding record)

We could now map all of the other remaining properties from the database (maybe we will not need every column) to a property name of our decision (it could get the same name or a better one).

If you like you can modify some property values using Java-expressions like the following one:

row1.subject == null ? "no subject" : row1.priority + ": " + row1.subject

Note: You should always prevent null-values to reduce logging of avoidable errors.

And if we run the job we will hopefully get all the properties we wanted to have and which should be available for the Mindbreeze search afterwards.

Export the Talend JobPermanent link for this heading

Finally we have to save and export the Talend job.

Specify that the exported job should be extracted and keep in mind the target directory of this export.

Locate the exported job on the file system and look up the generated class name in the run script:

C:\mes\TalendJobs\SupportTicket_0.1\SupportTicket\SupportTicket_run.bat

For the configuration of the Talend job within Mindbreeze you will need the base job path (containing the „lib“ folder: “C:\mes\TalendJobs\SupportTicket_0.1” and the class name found in the run script: “mindbreeze.supportticket_0_1.SupportTicket”.

Configuration of MindbreezePermanent link for this heading

Create a new Index with a reasonable display name an appropriate Index path on the file system.

Then create a new Data Source and select “DataIntegation” as Category (Note: if this option is not available you did forget to install the Data Integration-plugin ZIP-file) and choose a Source Name which will be displayed in the search client.

Last but not least you have to define the Talend Job properties:

  • Directory of Job: … the base path of the exported Talend job (containing the „lib“ folder)
  • Main Class: … the main Java class as generated into the run script

Save the changes and restart the Mindbreeze Node service.

If everything was set up correctly you should find a log message like the following in the Mindbreeze log of the Data Integration Crawler (e.g. C:\mes\logs\current\log-mescrawler_launchedservice-DataIntegration_Support+Tickets\2015-02-27_12-44-48.581290\log-mescrawler_launchedservice.log):

2015-02-27 12:44:57.394226 [5268] com.mindbreeze.enterprisesearch.connectors.commons.crawlerbase.CrawlRun INFO: Finished crawling run 1 successfully - statistics: itemsFound: 8

Finally check if you receive search results within the Mindbreeze search client.

The default presentation of the custom Data Integration source already shows title, date and the content but we would also like some other properties to be displayed so we have to adapt the categoryDescriptor.xml for the Data Integration plugin.

Note: If you have to change the Talend job later on and have made major changes you should delete the old index from file system and re-create it.

Adapting the categoryDescriptor.xmlPermanent link for this heading

As a good starting point for building your own categoryDescriptor.xml you should take the original Data Integration plugin ZIP-file and modify it for your needs.

Most customization can be done by modifying the categoryDescriptor.xml. The default one for the Data Integration connector looks somehow like this:

<?xml version="1.0" encoding="UTF-8"?>

<category id="DataIntegration" supportsPublic="true">

<name>Data Integration</name>

</category>

But you could also take a look at another categoryDescriptor.xml from another of the basic plugins shipped with our product. E.g. the WebConnector-Plugin already contains a list of translated metadata properties and also a specific Open action.

Adding own Metadata ColumnsPermanent link for this heading

A Metadata definition looks like following example:

<metadata>

  <metadatum aggregatable="true" id="current_state" visible="true">
    <name xml:lang="en">Ticket State</name>
    <name xml:lang="de">Ticket State</name>
  </metadatum>

  ...

</metadata>

… the ID is the mapping to identify the column as it was defined by the tMap output column name.

The following properties can be defined additionally to language specific names:

  • aggregatable: if this option is true the column will be available as filter property (should only be defined for properties with values allowing clustering the results – on the other hand if the value is unique for each result it is useless to define the column aggregatable)
  • visible: defines whether the column is displayed in the default result representation

Replacing the IconsPermanent link for this heading

  • The small icon that is shown in the data sources list in the search client is represented by the “categoryIcon.png” file in the ZIP archive of the plugin. You could simply replace that icon with an 16x16 Icon of your decision
  • You could also specify a preview icon for the results with the icon-Tag inside the categoryDescriptor.xml. It requires a unique ID, size attributes defining height and width and the image itself is encoded as Base64-Value within the value-attribute.

<context>

<Icon alt="Ticket" height="16" width="16"

    id="tag:mindbreeze.com,2007/contextitems/contexticon;ticket"

            mimetype="image/png"

            type="tag:mindbreeze.com,2007/contextitems/contexticon"

            value="

iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wIXECgw/xAFagAAAS1JREFUOMvFkz1uwkAUhL/nNV4Zesw9wgUILYq4gymCgCiRIG3gCkAOEnMFTgMNFT8W65cCpOAIAqmY8knzaTQ7C/eWvA8Gpd1uN3HOPQFyo0+NMYm1tkcrjmuzJNH/apYk2orjmu+c88tRxHq91tVqJSJ/hBBhu9kQRZGWo0icc74PoFmGqspkPMZae9G/3W55brdJ01Q0ywA4AIAgCPgYDi+agyAAYL/fIyLo8e4fKlEKhQKf0+nZBM45ur1eDoTqCeCo17e36/WrctpTDtDtdAjD8KzROUej0eCxXs/dc4DhaJSjh2FIsVi8nkA8D0Dn87kU/B9mpVLhoVr99ZICoOJ5AuAbY/bLxQJAms3mzQteLhYYY5wM+v1SmqbT45S5ecqe9xVY+3L3z8g3o1Sele9r3SQAAAAASUVORK5CYII= " />

</context>

Adding Custom ActionsPermanent link for this heading

It is possible to define custom actions based on some specific meta data. For example to open a ticket search result in a custom ticketing web application.

<context>

<Menu>

<Action name="Open" pattern="http://intranet.mycompany.com/ticketing/show.html?ticketid={{mes:key}}">

  <name xml:lang="en">Open Ticket</name>

  <name xml:lang="de">Ticket Öffnen</name>

</Action>

</Menu>

</context>

You could apply your modified categoryDescriptor.xml by uploading the changed plugin ZIP-archive from the Mindbreeze Config UI.

Note: It is recommended to rename any modified plugin with a custom name for better detection of changes on product updates.

Another possibility to apply only the categoryDescriptor.xml is by means of using the mesextension commandline tool (this could be useful for testing):

C:\ >mesextension --interface=categorydescriptor --category=DataIntegration
       --file=C:\Temp\categoryDescriptor.xml --overwrite install

After applying these changes, you have to restart the Mindbreeze Node service and you should receive a beautiful representation of the search results including all additional metadata properties (also in the filters on the right if defined aggregatable).


Troubleshooting ProblemsPermanent link for this heading

Talend Job ProblemsPermanent link for this heading

First of all we have to ensure that the Talend job does run in the Talend Open Studio. Then we have to check that every property we want to search for within Mindbreeze is already included the result of the test run of the Talend job, because otherwise Mindbreeze will not ever get this data to process.

Talend Job Test Run not runningPermanent link for this heading

If the Talend job does not run, you should check the “Problems” view (Note: there are two different Problem views – a general one of Eclipse and another one of Talend – you can open those views from within the “Window > Show view…” menu).

One reason for having problems with running the Talend job is an unclean environment which could be solved by refreshing the workspace and trying again or sometimes you even have to close the whole Talend Studio cleanup some temporary files from the file system and restart the Studio again.

Data Type ErrorsPermanent link for this heading

If you get an error of “Type mismatch”, you should check the mapping of input and output data types. Often an ID column from the intput is received as numeric value and is expected on the output side as String-value – so you need to convert the value with Java-expressions.

Problems with Mindbreeze Search ResultsPermanent link for this heading

No Search ResultsPermanent link for this heading

If you do not retrieve any search results (by an “ALL” in the new Data Integration data source) you should check the following possible reasons:

  • Check the log file of the Data Integration crawler

For example you may see the following error message in the log file:

2015-02-27 12:37:32.643950 [812] com.mindbreeze.enterprisesearch.connectors.commons.crawlerbase.CrawlRun ERROR: CrawlRun was unsuccessful, cause:

java.lang.ClassNotFoundException: Mindbreeze.supportticket_0_1.SupportTicket

This error was caused by a wrong spelling of the class name with an upper case first letter instead of a lower case one: mindbreeze.supportticket_0_1.SupportTicket

Restart the Mindbreeze Node service and check the new log file.

  • Check the access restrictions on this index (“Unrestricted Public Access”)

No Content in Search ResultsPermanent link for this heading

If the search results do not display any textual content below the base properties it may not have been crawled correct because of following possible reasons:

  • Source data is not mapped to internal column “content
  • extension” property is set wrong (for textual content you must set it to the value “txt”)

Properties not shown in Search ResultsPermanent link for this heading

If the desired property is not one of the basic internal properties it will not be shown by default. You need to define the property either in the categoryDescriptor.xml as visible metadata or explicitly in the search app.

You should also check if the property was correctly retrieved by the Talend job from within the test run result.


AppendixPermanent link for this heading

categoryDescriptor.xmlPermanent link for this heading

Here is the full content of the categoryDescriptor.xml used for this example:

<?xml version="1.0" encoding="UTF-8"?>

<category id="DataIntegration" supportsPublic="true">

<name>Data Integration</name>

<metadata>

<metadatum aggregatable="true" id="current_state" visible="true">

<name xml:lang="en">Ticket State</name>

<name xml:lang="de">Ticket Status</name>

</metadatum>

<metadatum aggregatable="true" id="priority" visible="true">

<name xml:lang="en">Ticket Priority</name>

<name xml:lang="de">Ticket Priorität</name>

</metadatum>

<metadatum aggregatable="true" id="category" visible="true">

<name xml:lang="en">Ticket Category</name>

<name xml:lang="de">Ticket Kategorie</name>

</metadatum>

<metadatum aggregatable="true" id="datasource/modificationDate" visible="true">

<name xml:lang="en">Modification Date</name>

<name xml:lang="de">Änderungsdatum</name>

</metadatum>

<metadatum aggregatable="true" id="assigned_to" visible="true">

<name xml:lang="en">Assigned To</name>

<name xml:lang="de">Zugeordnet zu</name>

</metadatum>

<metadatum aggregatable="false" id="customer_name" visible="true">

<name xml:lang="en">Customer Name</name>

<name xml:lang="de">Kundenname</name>

</metadatum>

<metadatum aggregatable="false" id="customer_email" visible="true">

<name xml:lang="en">Customer E-Mail</name>

<name xml:lang="de">Kunden E-Mail</name>

</metadatum>

<metadatum aggregatable="true" id="customer_city" visible="true">

<name xml:lang="en">Customer City</name>

<name xml:lang="de">Wohnort des Kunden</name>

</metadatum>

<metadatum aggregatable="true" id="customer_zipcode" visible="true">

<name xml:lang="en">Customer ZIP Code</name>

<name xml:lang="de">ZIP Code des Kunden</name>

</metadatum>

</metadata>

<context>

<Menu>

<Action name="Open" pattern="http://intranet.mycompany.com/ticketing/show.html?ticketid={{mes:key}}">

  <name xml:lang="en">Open Ticket</name>

  <name xml:lang="de">Ticket Öffnen</name>

</Action>

</Menu>

<Icon alt="Ticket" height="89" width="64"

    id="tag:mindbreeze.com,2007/contextitems/contexticon;ticket"

            mimetype="image/png"

            type="tag:mindbreeze.com,2007/contextitems/contexticon"

            value="

iVBORw0KGgoAAAANSUhEUgAAAEAAAABZCAYAAACOsCKNAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wIXEDUVS3i9MQAAD5JJREFUeNrtnHmMXfV1xz/nd+/b583m8czYDrjBxGZx2IrNYgoYJ5TERVCRNBVNgUBSElAjqmZppBJVUVUSIaIWpdAk2KFJEUsbKASbpXEgbAWCHMM0LAEZb/GCl7Hn7cv9nf5x73vvvmXGpmWZN/hKV3rvrr9zfud8z/ec3+/+BCCTyZBOpykWi2mP6JKSiFPyyCtYwpvSHZvQ2mwVSyVSLee1fGDj8PBwqe3SfD4/XLbR8/P3LZqVcPNfM44zFxEQmfTB03YLd5QqKFjP25Ir6o2bT9nw4KaxR7b+2Wcv8wBkz549xOOxeKVqP2XXHPs3TsQcD4IYQQVEpC64dIkGtKYBBVVFFNQqoHhVfeXSu85d8sgDd+TqfTo+UTwhe9/ik9OJ4u0iooiIGjBiQNS/THzFShd0vtStQEEFqxaxgKqqqkzkzOVHfm7LvwHWBciV3WRPNP8P4PhdbgQxNCwgUIB0k/trwwNEg6MWQSGd8L4D/ATAV0BJ82nHzMUIakBMILgRFAHRrjH/uvyioAYRH8rVaGAdgmBGa9e5AJ6nFgn7fCC8iI+DGBRtwsNpLbyCwaCiqPrWjPXFUmmWww0bj+AL7Pt747dv/uL7RDe4gWmAoICvBAn+tFiy2+Q8hpDEimCCJwBGuicMImDVt+aABNQ7z2hTmDQdUSTocZXgStNd/h9us9bwSzqHMBMWXHyQbEZU7ULhG0jYJHMNBMMHzUFY5IzaOslm+IBvhxXwQVeAO70IjIc4CSQ2ijgJwKKVCWxxhw9f7wITc6eP8Er0w1cTW/T15qQGsIWd5J++AK1m33ElTAsXUFslceq/Elv0dVS1DbFNYpTU8uegUnjHizLTQgEmtQB3aBmoTtrD4sSIzL/mHY/T5v3p8RLqFer/nVlnBFJOLZ2kFna/AlSVxNK7SC57GGfgDNQrUN31aCONm2Lzdj/f3WFQVYn+3pW4s87E9B5PYumPSX38Vajsp/zm7SBSx4Cm3BbwMpsov3Fbl2OALeMMnRNYu2/L4qaQxOmUXvs7Sq/cVD+utoraCrY0TnnT/WTuX4IzNHRQK5nmYdAikXSzX4vgDC7FTqzDGTgOgNxT11DZ8h9+MuM6mFQCd3Z/UN+SblbAZCmJ4ox8kvIbd5FddzVOr4M7q6/dFbqeCEkEm30d07u4KdxVtj4M+jKI4A7FJrn33clT31MMEONSeuVbYL2GU+Tfwk6MIY6DmPc+Kr/3b6xmKY79VT0qTPz0RExfpB39Z6oCFA8TGw4B4HFNUWFmKkAVVQ8ifTi9JxA79vr6qZ6VP8ekF4Hb618z09JhVUXcJKkzH8Qkj+wQE4TUsjU+2dn3AvlfXQpq3zOLMO+28E7/SaRWbMAkj5zSz1UVZ/BUes5/DZHYO0543icXsMQWfxsRc1A/rzNDEZzhz8BMsABUcXqOfvt+OWf5zMAAMS6Zn83Gy5bf9n1O/+DMAEGJ9uMOMm23w2Xxwwo4rIDDCjisgA+8AtTaDvFrBkkpkx91AWwwmxJLY0qMDdmH0j3TZMPiaZ2RN2Sw9ePSToTkbWuxO62hdY6QqpUPoPs3LKCRpobHZLVdXV27aaffgj8nNFBADQeaHH4mCR/IpTTVGlosYBKZdYYYvU7mAlYnV1oLAKpa0Gr9hJhI13R+BwzwXcBaT+ohYsr6hsUZupDUx18mvXILiaX3o15xGkjqgJM6tNJ6IwyadiYoUylTcYc/TXLpP1H+7YNkH/sG3v7daKb8vosfXfQVksufxWbG3zYpCizA1q2khoe07hYiR1wMQGnsOjR/N+XX/gJJ9yDps4id9ENwB9FqkejCbxH9yDdRr0xkwfW4876Ae8QXSZ79CyILrkerOdR6RBZ8E3fe53GPuDY497doNedjlfVw5/81yXMeI3byj8AZ9tvhDBI78fuoVyRxxhrcOVfgjnwCMRESp92JJE8Gq23tD+O8NmSvRwHp5D4a9HztE5TiyzcAkL5oPc7sP0ZtFgRM/ENE5izH5hXFYgZOwfSfjlbKuMNnElv8FST+UQrrbyO28HJii28FPNzhZcQWfxWJHUth/SpiC68gdvz3UFskcdp9xI/7Erlnrgf6SH3sKVRGwLhE5q4gteJ/sPki1fGd2FIOsHjj26m8tbep3VOQ2HAYtG3hwf9URhsmI2DzY+SevhRvYpzk0ptILnsC9TL1V2ib6vz/Yhzyz34O78Aqylt+hjNyLraQq58rPHcl3oEfUt66FmfkPJQB3KGTmHjoKjT7GIXnViLGEJl/Rb15ld89T+6X52EzD+CNPw6epTh2LSaxMWg7jW9nJBzltIkKBy6gjWnSNVuxIe4c7KIGu/85Cs8uJ/fkl3FnHYtJX95wLBviEmHuDZiUQSSO5l/FuHFsvtywxZSDSAItvIZEEmjJAcDbsQaJuKB5tFxAIgMNBbz5c0xPL2IiiDi1AiSCA1Ya7a7zf613cCCrNFPhqRIe8ftTYsPg9IKJAHvqL7WFTb4gsWEwCUxitP0R7gBazePMXonNv4U4ofDp9vnnhi7A5naC9SdQxU+5CbUVTO8ZSDRBZfsLoQea+hR4VQvGAYmh2EmnxreERAHk0IhQsMUX34g756z6/+r4Jiobb8UdGUKrRdKfXOsbQmFv28BGeuVLaCWDifWSeejzmN506NwYWsliYmkm1l6JxEsUXrqZ+IlfJnrU2Ti9R1Dd/TqVjbcQ+dDiNjj39o4hCyIMfHYX+Wf+kuq+NZ0HYToQIQF4cv22k0747em/xhjfJoz/3ZDUIqUJLEBc7EQaZ/RCKlvuQUwGZyDaIEXxS6hsvRfTZ/H2lXAHhdS563AGF7L/zlHcOddSfuN7OP1xJAaps9bhDBzN/jvn4M65pn7OxP0kVUtg+i6hsn0t4hzA6fPfZXPgZYu4wzFEfOMVMw/cJVS33oEznPQVYP3ArzUXsIFrW0vfn24bBHLNFqCd9NOwF7VVTHofNns7zqAg4o/rC/6XGVq4G3fIV54ZjTaN9krMwWZW4Y6k/I+XQpMkTMs5UH9GTAxs4R6cgca7fMwAk4rVu1UUsFvR0pZA+BYaK9opvQlngwEGSIgMWMDRWqDw7wiUEjYvkbC+TBt4VH63hsq29QimPkZYu7Gy7UEqW0d8a2u5t/7ctvdPRm46TKb2ey0Egk1KaGCArZXEtFYSkmbAkA6gWM11BgzjIs4o6r2FSJTyxu+CteBG/e/3tIozazl4ecobb/LPOdGD0vB3IPlpMKIQEQq5gDYzY5mcPmo1Q+pjY5hoT8AhLGJccKIUN/wjiVO/RvbxL6CZdYhEmgm3VyS55BZsaTf5X5530LKsqiLRYUx8FG9iQyPkvR0FSGsZwLbUBK2VtsypVhPsVBORKKVXV6OFMrGFl+CMHE/+qRtAoLrjP5HEPCpvPoQ7FA1qDV7IlAS1ZfDKgYBeMAXOCVmhDdzJgC2SPPNutFQiu+50nOSAT7FqzxTjx/6plGA7UPsWKnwQLTbfLSaKt+M2vPFV2OI2UIu3azV23yqcvkGi81cQO+ZTqFXE6SF5+n30XrSV1HnPoZVsSNFKfPHNpM55AhP/MGLSJH7/J/RetJX44psRDLFj/h6TmoPTP5/0BWNoeQJxekid99/0XrSV2ILrfYXSIYE5hOTQ1C2gPQno/NCwiai2MwwTw/SMYgsGiQ74Md4mGF/9EfJP3oAWG3mpM3g+0aMuIrP2M3jjG0ie+zBeZhfjq+fjzD6DyDG3Ut25Dpvfh5fdReFXt+DtK5Fa8STegV2M/2CE4qv/5TO/qdqqHWsCLRbQETBqN0pAL1t2naT0DOBViR51HWo9sg+djzNYgfL9mGTS96LkKMmzvs/EvZdgnO24cy7E6ZmLt/t14idfjbfnBeILz8cbfxaqE2gxh/fWv+AM9YGCO7yI+KnXITzu409b26SlI9uwoYkK+8esbSCldMqdWvaDVB4kMRfUYlLR4KNs01iMwU2g1QrJc26EqOvTbCByxDk4s/4QzDDlzS+gRa8R/4xBHJfco6dR2fwMiVO+QfzE1aiWpm6b0Mjxg9S/yQJ8EFSsSJ0s1Xv0/1owF5fqtn8H4+IMnYtWM02lNzuxmdyjF+POOgp35E/wdvk0urLpp+SfWEb+qbMpPHsxEq2CVjGp2Wil5Mf72FxKL15C8cVbiR69EpvJTT0GEFABq2BFaq5r2nIBCY8GBV+QY3WKxELBRBHjBgrWxmIFJoK3ey3e3lfoWbEaLRfATXDgjiiYBLgxbPllqjtfIHnmd8g+MkbxlVWkln8XrXwbsJQ3/YLS2BepbFtD/KNfpf+yDPt/nKL/sjfRUg6JpSis/xGYeHtds27qwYfgYVdtzQUeWPfikrO3f+J5xIBD/UtxPzKZKWO1VnJUd2VxhmZh4i6qHt7efUAcdyjtz/nPxHH6z6ay7T6cwV7QCbzxCpF5s1FbprprP5g4kZEUXqaI0/dHVMd/A4VXcYYH/J6x89DKAFr4NZKoIvELqO54CJOM4PTHOyN+LReoRWGr4Pmhtv/Pty8AdrudKZNSXzTkIFmiuCki81L1awQHd9bsxn+J4PRWQR8jMi+Y808/JlE7HyUyOly/3ulJgn0Mtw/oHawXPdXswMR3orG4H4p5isictG+99uBDYB0EaCJCfr5QSxpUmnv9/z04Ki1M7FCvDR+VUIGqcc0hLe0hoaII9QJRCwjSUha3XT5ApC1MkDYMaAFBVd/3tQUi1HbvyLC2pMO1qGa1QzpMiP/XtOZ0w8pBh6AF20LY6JQOa0j4+uojtXJwN1uANoiQhpPBkAs0xXVo0Eg5RNzqmrFB7VwRCidDdRasBx1cnN6btIN4C8MPgaC1qFWsARMKMQr++jvdagXSPMzn459irLYMjkp7+NMaNa5VU7tts35kExtKCG2njMUfGfIrQh6oqwEGWD8X0OBjBq+bIoIGvd+YEeIPfwZUmDYQ9LWlQr24UCurGxsaGZLusIT6CnKB8dbXE7TBiGXrFJlypeLhESyhp4gqeII4YFVALCa8yNJ0nDvV0iYPGyykpL71ajDW0DxBwreAveMTB3IluzMeM6M1zq2Oby4SLKio0l044DfX1tN0PF94tUqhbPfg571VA/Dyb8a2P7yh9IMA8BRPUU8RD197wa6h39N1b22jeDSOWd8MHtlQ/ufA+g+YtWvXktj7TOaq1RO3Z3O6Gaui1r/Ren4urTaskOm91wT22+zLIF4NA1SyOd18xaoD64BtNcTzR34jSLHC8fd8qf+qPzgmcnkqJgO+l0j3McImAueDX7ak40+/Vrn907fsvxeYAF6aTKQhYBhIMvOm05eA7cDu2oH/BTw+CdV54/GjAAAAAElFTkSuQmCC" />

</context>

</category>