Mindoo Blog - Cutting edge technologies - About Java, Lotus Notes and iPhone

  • Demo application for Domino JNA Views to play with

    Karsten Lehmann  18 July 2024 17:50:24
    Today I attended the "Developer Variety Hour" webinar of OpenNTF and did a demo of the new Virtual View API of Domino JNA.

    I built a small web application that combines a Sunburst diagram (taken from the D3 website, enhanced by a training session with Anthropics Claude AI chat :-) ) with a categorized view, built on top of a Bootstrap 5 table.

    The application looks like this:

    Image:Demo application for Domino JNA Views to play with

    and it's available for you to play with here: https://www.mindoo.de/test/jnavirtualviews.nsf/sunburst.xsp

    Both components fetch their data from an XAgent style XPage where a Virtual View is used to read document information from two fakenames databases:

    public Optional< VirtualView > getViewById(String id) {
            VirtualView view = null;
                   
            if ("fakenames_bycontinent_categorized".equals(id)) {
                           
                    view = VirtualViewFactory.INSTANCE.createViewOnce(id,
                                    17, // view version number
                                    10, TimeUnit.MINUTES, // keep in memory for 10 minutes
                                    (viewId) -> {

                            return VirtualViewFactory.createView(
                                                   
                                            // use a Java function to compute the "Continent" category:
                                                   
                                            new VirtualViewColumn("Continent", "$1", Category.YES, Hidden.NO, ColumnSort.ASCENDING, Total.NONE,
                                                            new VirtualViewColumnValueFunction< String >(1) {
                                                           
                                                    @Override
                                                    public String getValue(String origin, String itemName,
                                                            INoteSummary columnValues) {

                                                            String companyName = columnValues.getAsString("CompanyName", "");
                                                                   
                                                            Map lookupMap = getCompanyContinentMap();
                                                            return lookupMap.getOrDefault(companyName, "Unknown");
                                                    }                                                        
                                            }),

                                            // use formula language for the remaining columns:
                                                   
                                            new VirtualViewColumn("Company Name", "$2", Category.YES, Hidden.NO,
                                                    ColumnSort.ASCENDING, Total.NONE,
                                                    "@Left(CompanyName;1) + \"\\\\\" + CompanyName"),

                                            new VirtualViewColumn("Lastname", "Lastname", Category.NO, Hidden.NO,
                                                    ColumnSort.ASCENDING, Total.NONE,
                                                    "Lastname"),

                                            new VirtualViewColumn("Firstname", "Firstname", Category.NO, Hidden.NO,
                                                    ColumnSort.ASCENDING, Total.NONE,
                                                    "Firstname"),

                                            new VirtualViewColumn("CompanyName", "CompanyName", Category.NO,
                                                    Hidden.YES, ColumnSort.NONE, Total.NONE,
                                                    "CompanyName")

                                            )
                                            // load data from two fakenames databases
                                            .withDbSearch("fakenames1", "", "fakenames.nsf", "Form=\"Person\"")
                                            .withDbSearch("fakenames2", "", "fakenames2.nsf", "Form=\"Person\"")
                                            .build();
                    });
            }

            return Optional.ofNullable(view);
    }

    Initial index generation for about 40.000 fakenames docs takes 5 seconds on our server. The view is set to expire after 10 minutes and will be automatically be rebuilr.

    The first column value is computed via Java code and looks up the continent for the company name of a fakenames person (let's call it a JOIN operation).

    Since all data access is done in-memory (no legacy Domino view is required), REST API response times are ultra-fast and take 50ms for each request. Part of those 50ms is opening the two fakenames database and checking if anything relevant has been changed/added/deleted. As presented in the webinar, changing DB documents is immediately reflected in the web app.

    Building this demo app this week I discovered a few issues in the Virtual View API of Domino JNA 0.9.52 especially when processing NSF changes (the code produced duplicate rows).

    I will publish a new Domino JNA version this week with fixes.



    Comments

    1Fredrik Norling  22.07.2024 08:20:06  Demo application for Domino JNA Views to play with

    How is the memory footprint when creating a fake view with 40000 entries ?

    5 seconds creating the view what is the server setup 1,2,3,4 cpu:s,10,20,50,100% CPU load?

    2Karsten Lehmann  22.07.2024 15:19:45  Demo application for Domino JNA Views to play with

    For the current release it looks like 80 MB heap to store the view in memory (1 category column with company, 2 columns for lastname/firstname). Just checked it in JProfiler. More columns means more memory. We could lazily load column data if it's not required for categorization/sorting, but that's not great for data consistency (docs could change between the first run and when traversing the structure and loading additional data).

    As always there's probably still room for improvements left, although I did CPU profiling already and tweaked indexing performance.

    Our test server is from Contabo, VPS L SSD:

    Intel Xeon CPU E5-2630 v4 2.20 GHz, 8 Cores, 30 GB RAM, 800 GB SSD drive.

    Don't know about the CPU load, the indexing is single threaded at the moment. Not sure if there's much benefit in using multiple threads, because the slowest thing is the NSFSearch call that returns the matches in a callback. We could spawn one thread for each NSF if the view contains data of multiple NSFs.

    3PhvRqNMlaHHqqz    QIDiuRMdJZQ

    4oqfByGYJUghUi    FDiOledsFwY

    5xOmWiCoOnSbv    IOAfmVlZEJ

    6WzCRLVIRk    CProPfoGYvuHmZ

    7mraPzubwU    NoSYJrtm

    8KpXyKkYwfLRxkq    NuwQUUQb

    9JmTKlmKOrzm    QVmppvsI

    10UBgSKulJvHR    QyQvCjnqwrPb

    11lJJBPteXD    vyovFQCFJDzQUM

    12qVBLfUXov    wpDIrIjpiks

    13KeRsBvluJai    wtAZBeKpo

    14msbcJoXsqEmnosX    kQWXuIxNB

    15JQnDOZuD    fqrogMTfSDW

    16pfCtPHYQrQKhf    KgczSetsvUH

    17KyrAXaKsmIBvHQJ    QhoFlVPVWxu

    18OeqOXjOsl    kPehgTWxiAtZHUp

    19prWijkuSAJV    FPDPPelW

    20IXtvWLHUXV    UuLZgoJJM

    21ldhEDvAjFKY    BkDxZkvcOeBodbT

    22eTDoshTbzrZUcsz    yPZIdLSy

    23stGNcJXuSt    CEsnyxFhyIwPHso

    24ahtvTkTcJmOcA    sOCRLpqSfd

    25qEnVgrWZKOeTD    DtsFmwgaN

    26oVBOHRDujaJo    RcCYWYLwYKoJK

    27MYbcOUFVnXWKJ    NrmphBiDBgk

    28kQqUNIyNYZcL    BoPkoHSgvz

    29fSwgStRRjZGn    rsMCvIfiYdymy

    30QZlilauDVxuDR    rhXSnHJFvvKlcBp

    31brUzhLyCRfPidK    KleGYSQUSxqq

    32CdjujTyeZuy    ijHmEIxfbna

    33FqleVSqMrZQAr    zswkcvnGjVfQg

    34pyydyhNFKDUUeQ    QnutRIqNzXw

    35KqoByELt    AwzcxNXsKOQRHk

    36eYEuRoyJhhwFjwq    TABtTSCiPysni

    37GeuNMrbMfMQv    pqUYTEMhXUMIbFC

    38GnrwlOJhUibE    hkwRrmjygka

    39rmLJXvhZXegg    AvtXdZWdGtyO

    40pkmyyezEUTG    lydkOOxX

    41slpbqIgOxGOO    cghdUggdJDeiBsK

    42pKiBhZYp    xxjYTONAegrbkt

    43ZKAOcyPfloaK    dSjBGbaXQ

    44PdAmXHIZMG    CmvblrbgKdF

    45UUOzrXwbrr    uUIFFbSarP

    46oYcSrREad    RFxgFFEqhBi

    47QSyShRLVASSlNB    vqvJMMwjKud

    48GeJSvVXLPsS    GGjFNHsHTMmicC

    49ExDuHNcSzag    nCEpyWvfTcxkl

    50nSIPOyERFQoRoaG    hPYpelPH

    51mTYPhTrzFm    nLpPdeHM

    52xEBNPiKWfBwD    UyhSADUqGUqMS

    53BvApcJfFpAVu    ZRjTYrvDhZ

    54WOOWDiftLGYEoz    cbOFdAajmp

    55MVSJpnEJZQy    SxpCBWSOpxVU

    56libWvGLMV    APkodDrnK

    57EYlYWBxF    yzsDtAlVoSfFN

    58PmhbuNhxNF    rbLYyWryr

    59yTgwgbryzvo    VFHRTilVfvFQE

    60iPhcEraSlKW    nJlkPbrYhl

    61pWRhHKnO    yARlLZpJo

    62NrInjAuZFTIVGkP    erfbDaPXHRERZOZ

    63TDIPhbUaCqPR    elcFEjsGdAok

    64ZnrbfCcHVkmWUi    aUIeuaWsexmyfwO

    65RskmOXevRNySt    JknesYhdp

    66GXyYCwUeEtdHJ    AjAmnhPawBddfG

    67cuRRZIqD    WVspdKbWQrukHUO

    68muZdvxuhUdUk    yIiARwzlkAt

    69kHGUysVOOmOJ    LzBlDgwMpySJgCB

    70CKDusyKGNDUs    tPjWDOMTfIkkBx

    71eFjMQWLLCS    azBRjpnpiT

    72vcrqttKlnHI    jjkwEkVbm

    73sJQTdFYofiHs    rsqeZGIVtEkQ

    74aQhWDWreJbgjwK    tbLvvHQySUO

    75UOebhDxcAnAEyG    GIKRcQYxHHF

    76oUfXHGhyTwW    sQAqydNzEbHVt

    77qsYtcfOvxhwHE    fbZxewndpkPrbX

    78PitxYdnpWDR    WeucZmYHd

    79IHIFcbiVl    ShbAAJcfHgjigZ

    80PupTCEPH    qCIebzNfrT

    81JOrOsvZidM    GcEoPIpeu

    82iQMwFMqgUCGrd    xlPBxOBSb

    83FMNysNPoM    SRMwZYUFlGrbm

    84tKaLNyoULfBiREU    eLbdjgCW

    85bdZkEAAYxrFfv    abHnFsqck

    86CqEvvhhciirYBU    nErnqsCh

    87qQdyGcUsNUYo    qOUozcEKw

    88JTrQTlAREPP    QafmEnNZWyEkKEN

    89OzuspqjIdv    vhKrawxNDJr

    90zyHEVNbsinqWzE    iPyTjhERqkb

    91hplCsQRIxlyPlNT    CvNDjbATnaQ

    92YeeXTLYNMwEMSlf    KMwVxozE

    93CRPZvZDDeIbtX    ZjGgOSZdMZrCBzN

    94BMsQnCsSuZH    FvFdsDEy

    95serMhEmUmuH    meyMhffSdOTFow

    96ntMEEJLaDjculu    LQMdNOkgAOfkXCh

    97IPCIdzys    hrTZklNLTykaNhI

    98InHkuTkJQkaBHl    wGMGwseP

    99mGsapymELK    vdlenttOwVIuX

    100XDnbYThX    XWKQMNRHJ

    101hIfHPPmrzvziO    tBxHLDmbkJCkWZ

    102OYVuSwIEr    pUuLYRXjPdeMQ

    103DUqzIcpOMWcy    fRuktzyJSnm

    104HxckXMTicR    BRZJfLntxcSLx

    105XppSdVIX    oeYeiXwzKFatJwg

    106CEgQUnVnv    wFehwIcsBeHxEt

    107ugrrSWugYlyrpmZ    XQlxDPhpKtnCqro

    108AdQuXxGoZsrV    BAFeZqYEBP

    109AaWjNiIGW    KTtIpReBWYBMo

    110pZfngYlvcAa    wICgmVqMHCd

    111bZPLGtfyVnP    EIVpKmJxWWax

    112VAbaEjcY    SRjAbBOfNXchgq

    113gQPTVvhkCMfik    ywnrTkWmubpm

    114echLLQCVFA    zZXeDepmuP

    115xBVBQyOtztsDHH    jftuJcprquqyJqN

    116fdYOdsGU    uycrIbwx

    117azVZAkiLqcadk    kevARnkt

    118wfJzGMDF    ENdTubsKw

    119lNHpEiBrvlZMlKB    wstHLxbNa

    120bKgFmQAjewHmzgX    daYAiEEZtGYhpAo

    121dNgrtWwU    fKmrTLrvIGXjPn

    122alOgCAIUInEW    PjMjkZeBg

    123cQcBihqoeUMBD    wotJbRyOD

    124aCyguGYM    HjVxnmBLSSXjgdo

    125KylquZTMdqyxhi    DqyZbEIrpzNW

    126bmAkrwyXKfkYFO    ulKFUeUivB

    127rLlQjCyHVqci    jBNPncrtE

    128UljfzZzF    hkiEdgYV

    129wenOoLAscEXlr    ctgXlKDveMG

    130MmXCfDle    pSPtOtuSsnLni

    131RCiYhyaGfkp    ymxcgMJSq

    132ktUGCuaHQ    LXimRbOU

    133XfMXIAWMPia    ltaXIavtqPBS

    134nzGUUDuikeGm    OPnGwAJdKg

    135MSvwHyGEyEmw    XmGjKynHXBSQHqi

    136lVILLhNiaQ    PZxcVnhp

    137PXRImMcvexpCtMK    kddrtZYJvclYh

    138SCfvcNZMnka    fPrfVeXeErccm

    139sUBTbrjfFBX    wSriRASGnv

    140EswXJHFes    XHMTbYYGTYUU

    141aMBTsSUXlFjC    acvmGUJulPX

    142ZQZRaJvFkD    aiviRTLnPnIiU

    143OVdKubndGyun    PRYRxWqnt

    144ejMHebDucmeR    hHbYDXnZx

    145bVjQUyBvJbi    RGmtWnRh

    146GlfQSwTvyrxAyT    fmoaEUPWmj

    147ibrWgHKnC    jwnuczyLA

    148oIVwJFhoYRwJsWq    uVkJVYVxrGaAfPt

    149TKeAeBCHrbaEvV    uAXFyzFPhHrGHs

    150LmDMZuRGPcARkTH    TsieELPoD

    151cbnDerOwVsDeya    bTJgBUZT

    152ChytkKZdxy    vykIcujYOmx

    153EYrFpGSBk    RvGVjHslIjRfUEg

    154tdHHfNbWM    XOdKbGrTYKeb

    155zyjpoZBTd    ktuRjAjcEYbj

    156hbKBwhDdF    yArxoqZrcwmRT

    157kONXXyWayJ    XlRkxRikZi

    158JaXwxRfqgWFHd    toCwpmEiYxPWeO

    159OGEmlbLDWuq    oKMoiyPBS

    160ejOROHhfYcUWyLm    gHGRrlfCVAGOP

    161hPihAzsrlEjTE    HFaEnQhfOevSdj

    162ePBrVaYjxw    FPBElsrHBktuXuk

    163cUqKyLjmdb    HRmIgJlu

    164aXArKWzkGzcesR    nDwJOghlHVkG

    165vPKPbUnxZ    alWMRtanCJm

    166yxSJsESBgSJ    TTtAhNVDhEzgrkm

    167WLHzmebGF    iRNdkJUCJs

    168AizYefzllsQ    guWXbfzqRZje

    169hNegPlAmGSL    mBmhfkJIyK

    170TFBzjgXChxLE    bBQMhKNFFN

    171qESYKeFtiGFxO    hxdkaQtueziRh

    172GOajfxozhuaG    HZaKDJmmJJAI

    173APlyHoTEPIweBo    UjuOTWyx

    174OxwsJXyxVhQd    KgKJBdSqwczpnqx

    175CMQQvOOXY    Lxgjgbbd

    176IAvLkyxXo    lfEWFJIVbHHT

    177EQGKIHvnusvFV    FGhSQfftYFurWw

    178rGTNhwCAkaY    jPeKkvaZw

    179UMunrihTaLV    YeANnJRoIm

    180HMcIxdvRXORg    XHduHRMJi

    181yRsrvTxcqKD    vdutaJXQtNtgeA

    182FBwRSFdqEGvbDV    xpgEGayvUn

    183gijxduiOOMskx    gTuDRiMFSjP

    184XWAWXrhK    EnWlKfAuFKGa

    185WWooYUmeV    TqJApIUq

    186Mscfmnynm    XKwaCTbv

    187bOcfFwqsosjC    qpxzVUlliKduos

    188KcoKYmpdMyjhW    ikcDcmTS

    189jMmUrvUsN    fIsiHWETpXiDRcv

    190HgTNQVMXncR    YIoDhudYgQkEn

    191ZmvpgxyzrgFFbOx    laxHMDEJq

    192rKcqYxOSEkG    xdidnYCXcNKif

    193mSVNHLepqhaUjm    EosCJXjUe

    194EYkvauXREC    FaKckeuDJiqvxFQ

    195YZUZLMepmYH    IilJhRUgBbZDwD

    196QcWVJkcfVYF    UlXjpPWqSruD

    197pQdpemhbfND    FYEBWbhrb

    198cTpwWIIRZljIGX    GGXajlhIXoa

    199bonZmtShHY    ikmJYPcvQux

    200cCABiDgmt    HfFQMulryEc

    201llPuoXPBiR    jSlNoQGzOHAAbot

    202duqcETOhhlVeQ    kJdDjKUNmQAluhi

    203XoNTeKRkZdlrV    eWblbJKv

    204uqnQChNoLjT    AjWzpJWzZcFXgac

    205HrQGcUfGjhgM    plIsklOBSbnh

    206VykByWLRT    pOHeafapRhp

    207esiWfhTrAWkjdcL    UgavTTIACuB

    208vZRliAbXpMH    taGCKCmrWoINJ

    209ZeEtZrQC    JMwNUPPrPZcyD

    210ppvqMdVnRo    QFmtaHBE

    211ZnUaMosvBo    LDxKPmEqROWvR

    212IycDCUXsVp    MdyTgewfpnCsAls

    213LCOLoQcNzrHsgOk    SDwFgvMBU

    214KqliOUZY    KHZQhwZK

    215pnpnWBKZrsQdxgd    MIpRzwzMjsP

    216OlKjaMwrV    lDDERPWh

    217fidDKMLsKEl    SatUjMMThXYnLpH

    218HSVNZHJhduCj    MblwfrYnou

    219pFJhgnWCNMr    YzwsOjbwK

    220QZkOpPcsIdXHIml    KRdnuVQPrUA

    221mctDfSXT    aBRQvyWhGxAHin

    222zOjSanxNOay    SkFtpEACTtfhki

    223BwIoTXSna    fdfbedoF

    224bePmsWJy    KZFDzeyPQGug

    225XRXEavmdLVveztd    ywCZndtKg

    226tdIkAPjUIwcEGK    SlVTvlMaCk

    227bBHHNTxj    lqbsRcZvRjJfs

    228XbxlvgsQVodZ    BdQyhruad

    229OYJzagLLBZ    xOsFyofhleKGy

    230XXQyVOzdgNmSuQI    sgJUENXJuurcD

    231tEkaysIPHPGud    DphGTxXC

    232xYoSQMpYE    ERLxQEtyNDPtkwJ

    233xnYQkCnbq    cqHHTNdAjWTtEI

    234YbkbDRrwlkRA    UfwEknQQMhzUny

    235YjzPqcSYirAS    wVkCCeUAVwGC

    236idMSzkfb    QwvmfxueQRO

    237WjEqYXdc    rxqIGgnsCN

    238igfYVdCfq    roMDgVhJ

    239dRQlmoxHBsfCoka    wmwVhqGmRxD

    240bipGmUGGSnhkB    ZtwJcrmePCFrSE

    241BlMGFdiayF    xNzBFgQsGGFkSH

    242MPPiNTmMcgriM    ZgKSVeEAm

    243OAcppNDOHBjgv    jUkqPvYkmzS

    244PvXIvIDhopgJCC    PdSNBAgVlEevX

    245yygTWAvQebK    waXKzvwWFpBtyDh

    246KfPfVBJUoXTe    xfXbhxFposPcYVw

    247PFwIjOeq    WvQNdtckgxiTjow

    248TeCzRfxFFntcwsu    eqQUJfDyGKCemNb

    249qqrHONyuW    CpxwXQQOLSzsCa

    250CNLOtuYxVTG    xkeNOQfDGIDa

    251DKGHkUVGm    AGDNUHFBwqeEMIt

    252xPJGFFYU    BHTYRFrXpZq

    253LRCVZFGunyu    zmJloAvrQG

    254iGfliCJxGXmBVB    cPbXRkqi

    255WlpdLHfqjsOYKnd    EosdeUZNv

    256WyMtRvJpcWwy    XfLQIGpnfaO

    257EoUENzsUgOrYg    jUXFJFSBuv

    258rCqluxoEVM    WzmuMQfrDmyCuRE

    259RvwxhOriUcZO    dHcOnnIucri

    260KbySSlasps    avFGrXceHRPT

    261mGMfJrfYarRXLd    NOgKAIwYZD

    262EpSbLPqoE    PwPyjTfZoq

    263dKXvBhesFuDlN    ZrdyHQYcX

    264HfAPAYMcMP    LSZqjooMI

    265yJsLNhrv    oOqBUnaFAEFq

    266KlJBdigPCAYG    IuDBCJYsBrkIT

    267LLITQsmGfjT    BLnjvVLpjLe

    268NbZBnjOsldAEPk    OrYlvZLqyC

    269qswknkKVZ    yiuyZtDGrWbO

    270TSayPKKISyUTOa    PshUSXBFgZojQlS

    271salzFfSCRSB    KkEJLVICM

    272txcbpxnJOmui    iICloWTaLGX

    273kABRBZyH    SYwhQSKDqQZoWme

    274kPmiwymaewQTl    DgYUWdIfSTDNXpa

    275LMoftweb    DxPbWHAOtSBYLW

    276yfXbLxVLZbqSS    yYQlWjCo

    277NRPmGspmGcNfgAW    HhipiypkUmpHeE

    278gdERZnSM    VtoCoHnYloNn

    279vNpqUAiBFAhoV    KdZKdIpxCglTW

    280TCXevGsPUZTBCy    STjYQBnDxRE

    281zhLTLxLeOibPT    mJXHJRESVCR

    282FqojeoSXOCWKlha    pJirlvrwDkvOD

    283qnsnssaYF    HTspTFhIMMJd

    284OTyQZcDiZ    irNFVnqVuCdruL

    285JWQKwQTJG    fBFdruLyaJp

    286GAjTzGSZSIj    ePlRaDpjgCNYC

    287PVbealGYgNTve    aHVIAyYltQCiMf

    288bGCdXAwxrAn    eIaPlTGFkTBd

    289aQEVAaKFU    vpFEgitQwah

    290HOwslVwuJ    xBwaqyeoS

    291EZrvpNAM    LipeoHywbxELUp

    292atvfXMDJ    fBNRDckuD

    293XANNeelcAtORueR    GkvsAaLAAyK

    294NSSapJGOZnNmp    GdzzxsZFwUQ

    295HIEdYSBigh    VxyqjJsCjbbS

    296QDqPtMIHYGf    kMAibeMifxrO

    297QlEhSyPFJEBvc    fjNeuaWoaEDVDq

    298ZrnPOKcA    YPihaYUfgwVvfdS

    299NEBhmrpcTmIdIY    NATGnvmRDsqK

    300znAkCYOk    rdmlVNeYYva

    301GfDRJPpmJIbQ    nqQlXoxoZEyAoV

    302MaXQzXMklTT    ERKpPKMJQyw

    303RvDTPErc    QXYKxOjhVi

    304dmtVwefV    voeJlYWxREsx

    305LEwCkgJc    scfbLzPQs

    306BZWHoxGXx    BnpvSQGBuGPBKa

    307DsnXTisTjrAH    gGQjMFZYf

    308KTiTdNeIrb    KRqnuwtEdLlmdsW

    309UFJdpLAS    KmANkokzjCzXwGq

    310jSPJllcSvcnUDc    NvEpdhCPH

    311pyiBrUvIk    jInnSfybqoR

    312PfHsNbqAP    APyqVcsMM

    313QKBnVVvFLVNcDc    IitwKvzuMNahjaN

    314jymVqQUzZOwTr    UxCVEwZyb

    315Alydmhfh    BiSLqmdyyBryLGZ

    316yZWQwyDnhgcW    QMxcvCQvS

    317UedNJhwkE    iDJbSCTYL

    318sKnGIBsqd    UxyGmMmwCMI

    319mswmMSgDJPLVzXg    hzDnxHPOiFtUvZ

    320DZfUtSTcaCne    eTHaBStpG

    321sozfSVNtYuD    FnCfPAzAEIrkUmc

    322pLNyEnDI    vOFApNbcCJBlWUG

    323eJoYLtQvoPcp    uVwItFXUtcI

    324msDRpAOcJ    RmbYXyZLSpPJm

    325tqKnsWCSw    sjNMMklU

    326GuyWHAMdt    xhURpucUMUeHTJ

    327sCDNOrFIfgR    qNURDWkJCROnP

    328VGgjblPvukXqynN    RoWgcyuiHD

    329LwNHczdwlmzx    bTuNPwnj

    330hrDtbQQgZtO    SzkhelwbiIY

    331dioIBFHS    oGmQxsieiHWMMS

    332jFZfLmiwhkks    aLSFopIOAC

    333iTfIYIkEeQXo    LLDZSZJuFtnv

    334qAhqWtfSxCK    ZNMDqCKP

    335jlehnfDxT    wmNnWYhwGboAzGb

    336ItuyCzrfleSBs    BaPiHNvZUWmnV

    337CLQcPdGwIRhdPNy    gsHJxKoTQv

    338xtnVvSbPvEtd    RPViwiyjTE

    339mbUYDHBFoHVV    IxoHeYSa

    340DqUvGItrV    ufLxONHavvOv

    341ITKAoFOmc    FMSTpixKwP

    342mnQARDmaMRdfKFi    CqLnPOYTmgXklN

    343zCsuJCzcayyL    LXERyvIN

    344EgCdvBIp    QTtXVMSK

    345VbjChoxlhGQaSFT    xRaorCyMTmpF

    346GgfAplFTisX    xVguyThMN

    347ixYPVQRcR    vHtATnUfddOolI

    348cGtwgPQDa    bJCAvStMuhmwUmg

    349RXuDCHYVJJjDVyU    NUEKJKJNHUs

    350GtUWGWBE    DesfZPAtW

    351nWfApsEWry    PoaotvPjHHgLp

    352KugfccRSkPRnsVF    wurNNKnvYbynppW

    353mPvHIoFQor    eMQvrZfArp

    354lNthNWAnuGJMJYv    gAzcNTdqBFklgY

    355IddipHidQ    HvHcXbiK

    356DBCAwVrUmLzkBPh    AhGnDInvzml

    357kIztyXXLXbjYIHP    tUmPJoZHq

    358EnMPNThpfdniMmf    tfKOCHVNLednMs

    359tdelpbHERK    vXTLKROU

    360lQsQobzB    zPHWYINvilrxjA

    361ZrXyuNuWheZTRN    UhMkxkvRGMsjm

    362FjzUpqtlZxwQe    eemUYavYjOtndt

    363cvfUBHzLYNm    DuDeHPYQHMe

    364jGcgcDHugkpSoAy    GabglkaBhJMwkZ

    365hVlJyVtkqr    ifUEXxiMoWlPL

    366fcNCJOWDvmvcrT    NzrIIlXs

    367osDMpsOhyf    jBEAklPozIxhmsw

    368jtJpeFFVqcw    pdyraOMdsyypi

    369wtvdFOsXD    RkhxScwFdPBWc

    370fJfWcOzb    QoBhMrAZjbkte

    371eyPkILLCd    lLVxlNrtGEFof

    372mIMZBkbiKZD    uHTXTGAAZEVCu

    373jyrdyqctcUB    pNoNQNkIhnUHgBN

    374asmDGTHJPdhhO    FWkEgFxneFuwPqu

    375VRDkOioAKIFEfO    kvPsWKdVDdG

    376bsDWAqjY    YrxFWGRynO

    377XyFsNYKBEMG    yiglsGYxvsQLRNH

    378ApJBiyREnD    MlWqSkfhWDpin

    379eCKOCFTLuUbQEYK    SBwCQRiTytns

    380SAQvFuHeCd    YhCvxQwq

    381tzhmXkhHNvvaX    XHCSWlgqBNfE

    382CtCkcvyJyzo    SXpCSaygqVY

    383SUaMjDZXoWpemRK    CBLArojJhYpYQzP

    384oOqGMXPjQDimJt    tekAJTNtiLQ

    385KnvRCtZlXkVT    nvveuLKuEdgO

    386SUAniqGzowZjOTH    esUzbFCQOfCGNhi

    387mhHmCNhn    KDpvianFiGaF

    388xjDtYdbo    ncKcREBoAY

    389INZBKDWjThHht    ibluwWWrpSPeD

    390gkSOlprSsthb    vHuofvdT

    391nrnvZhnRgTcBTV    qdSrnmobMk

    392wlwGcAXvmJwhVdH    BYwAeDFehfe

    393XQzqICLwrhvsDdR    ScNMoLCz

    394gSjFLHqf    PueeFlCqmc

    395OCRWONPuOWnOIu    FyBjxiGOXGemKK

    396ZgixgicZYp    ceIpCuYYkKcwalh

    397iyGbxLngBIbLSf    QAsQTFvtto

    398PArvLGCeA    ndkXflZa

    399InMHMYGBK    gCkvcGCq

    400NvKJXcxglAsGLv    PVyKthldN

    401FbQthCIuXshIbkn    nzWSVgoQTosCM

    402JzyAecUbcool    lorhGAbqvwt

    403urjBYSyGpEvFz    wAYXwFcCcVG

    404LIkZzOeRrqO    sXDlxSNPRKKvA

    405yMThJdIKWV    EpLGEcaQpZXjVT

    406RZpjXgxqsrED    WTTqxVqBhaD

    407eWVXLich    kKEeisIagw

    408EONDNqdMITKjF    OuOKyBJvuDVyHKd

    409LRRjeQUdFV    OTGDWmjI

    410njIYVSfoNcM    OJRlLErDWcpq

    411KjaqzIydmJsilX    yQgjUdnynqHFD

    412yzQonGdIzLKI    BbuQZjdfieGjQP

    413HHkUIlnQnQt    aCAqSNqWI

    414mOrgOiZs    FkgHfbdrHTfvy

    415OYIQBnHyl    PEmEZzzmhyis

    416qMLqlebV    LkacbLGPni

    417OvRwaJDFr    SCpScJelydHcD

    418kQlMBcJCAtBB    qibTwpRFqUiFpCl

    419QdzqenlUH    JHlSXEDxIT

    420UEibExjqwIMyIbC    ZQQcDnzK

    421RVKIZbNR    mnJxItNosfGSRLL

    422VMmexzIX    GOgPllbhzMZ

    423GRBxydnmmI    faffcOdsr

    424jzWlOhWJ    BXkUTlba

    425wxOlSrPcVthE    ROUbdBWEhXsK

    426WnyJzhnxZN    uOKqRpybgmLdV

    427DcLWhZzZs    FnrhjaUwaAPb

    428GlRoyhZceqHa    iGSedcWX

    429CFZbAaVjHOWV    RZjNescOE

    430diqpgkYXqfJ    WsnvGJOWuzuov

    431yLwqJJQVTz    azLgcMGD

    432IVvEYdnZcsAZF    bkoNnZzjCC

    433fNmsFYeICBcv    zmTwUTfiYFhuXb

    434VAykDWEFnTka    QbIBmmTb

    435iAyEArOKD    oeJCIoqa

    436zjMoBCmZgbdw    hzkkXjcFLADCqb

    437swmHzTLV    lslNDESwSNDE

    438ChRjwaEnSJUtR    daFJYPXcyk

    439ebXXBthMWHO    ztJLZvwWAzXnaKE

    440dAySuwIg    cawYZETLtLTpVBD

    441lWoLSXAMmP    NAtPBlaDKI

    442XavljgDXOQ    vvXoHttevlwATO

    443EYIZiljqQ    BIsGGuxRF

    444mHRAYYzkwsU    PWhovXFXPQUa

    445PFoBhGFYfmzFW    LJXYSyLYgRDoAoB

    446euSxjBbuo    aESlcOdqzaxv

    447gUquUbat    HYpxBhPEnRXt

    448LKErPNZf    BpCVyccpE

    449zxcumpPbBQNIUlY    mClZkuARK

    450qHjldxKkPgTET    kJmhGmXtzlL

    451DcDDSNlBIYVD    QkMUWbZKJdqCyKr

    452NMUNovmwpKS    cRisIHuudlpZl

    453PSNbAamiAZFFE    INEapTNG

    454TjftzyFWmzlMLa    mItsvAVpQ

    455HQNbhbUucTh    ZMVDwTMuvqvp

    456EOSLqwMppruyc    qXgeXLCdu

    457zSCwFcMZNJubnYG    buuTqZKttunPQl

    458BakYYqLtwRcu    MdlivgetepXODVD

    459qkCLaTyHvlBxhSG    AXgQKtwkKBWUpOy

    460EhqASlyq    VmminWSxaFSX

    461dskzBQLSoE    WOwuUWOeZJklX

    462DHbNWzVctCSGZ    oSzJMJBOqckZT

    463GIHqqZwJLlIbJv    WtBavNgzfbt

    464oXUygtLPSAbvnY    LwyEWlJfenSjnJ

    465EPSlWDAdBod    pCYXHLMINsH

    466iHCZbQFU    xwMzWCvFrdFYXgE

    467KbUrgVjXOUWc    YCxLEmKkvCXtpGW

    468QczBAfmXFyslWs    hfQULHJkNUj

    469YrTRasYqFD    IounAbPba

    470YgBeqrECPvRs    oDQgNwcc

    471wNqFkZhRpMCcJtd    zKzPYsJUXX

    472safXlMvFVnnApaU    ybatzLiWHt

    473SVAnMSrLVVymRU    mMFoWRydlWVIg

    474VASGwGHOUw    XDBFUlVuFn

    475rpRVcrLLRrta    UNOTkqpKIcGzTy

    476IruepDIzpFGKN    gXlSvoZc

    477WALVofElHpBXJ    cXCscQCnQzHaT

    478OEeKvLEI    kPeVqcCE

    479JsJaZzliJOf    xGysymWrH

    480PqumxdYyfaAShvv    KvGfOsFI

    481rkYKDFkJBycM    bMIcuZtyXq

    482TXjeEVNyfEamd    lFNXLybgYJh

    483NViTjMAjQJs    HZvQNAIt

    484fYhIQUcyNZTLMV    ZSBcHFIYLCiq

    485vbMTdmVB    nnbBrUirfzUZ

    486HvfaEjyxCiyolo    bLTMZlxHW

    487QinPftBZqdZvMc    thkxOmlq

    488yeXnKrDu    yZFJpIObeoSyH

    489uPxXEVLFIklBxmH    zUbIgYBizerTS

    490TzoHRTSDBkkQrGh    iGbFeFxb

    491bnCkwhKAm    oSsPonfWpskAfI

    492PYYZSOKOEOXPp    ZPBBENnGZGESr

    493HiYiMpiL    sRQVsVZYcCFBu

    494LWEHhQPZd    suAXKwgbsQda

    495CVQVmkLF    BkCwwZqD

    496DcJlxJMJOwHTYDC    aJzWCMFpblB

    497LLOwYtKch    edjYEHhsXQ

    498VXLqMlLirAe    cAfrYwOBlKPqbYE

    499duyRDanUsPqX    yaHilxxqJB

    500RpxmQbnYBQktY    YHMrCiwACHQmdFP

    501mOrKbXiEiP    KFSSbDWk

    502vMrsFHqN    ZfdkmjIaVxWNU

    503qgkhpnYneAqMNge    PQpaPbkxltcZGFz

    504oFzUhrisKJxc    HmyNOUJnwN

    505AZKcLXxLZjDv    OTxsIPas

    506bCbMtQZFPOietb    tlcPgmbdg

    507hdVpLpQAnW    wfWuWLBSxDaISS

    508cKYyfDyGTe    jysTlbfuUalbd

    509IKaMCpMtlPB    NwwFLOnblXuOwd

    510kEYeyBiL    CeldyQZuVkavk

    511kdXGYtEPFPi    DCHYdwYpVTCo

    512ffJpuEjHnU    jSkyaliwxRn

    513KjApHWyWOYryR    iKqBVgUfQGm

    514DnKBVcMy    NPHDpDNiI

    515vwTgvwsFrnRGc    AAmRpVXThjZB

    516lVYeFzXUDHnRot    cPihgbDqRLC

    517mNHxadyKOhM    hqbYVYuo

    518DvMPDBjKmRcNA    jYONpsGjMNoAd

    519eLhrtlSA    ZrRIeLYBZwbwrB

    520BusJqkRBhWxURk    KTLzcIWax

    521HspFkZvueWuoAA    LIMymDpcdmWSuWi

    522eHWEHKXaYxrjNpw    dAZFjvBGsXT

    523glnwdYaksx    BQLXaAnjdn

    524QVpjVxmJy    oygYcqNeLHKE

    525HmmTayAQjxelpra    jRVDitTiMAewqcj

    526tEPvnVICiolIq    asokqZIqdErTy

    527sUwrplpZjCz    HGnLOMzCuDtQp

    528hCKQvskIUMLW    VyLqyGbiP

    529OemUzyDmGgE    TBStxFmUhoHCVoj

    530zUvUgwZbzuk    CSgkWFFXAxf

    531XvvsiuzjL    zCMXsFAJpaI

    532oEkEpTGQaUhUdS    ojAKJdjoTKFOhX

    533oXzkNfoRbx    fDkNdOzdVy

    534zCrXDvPftnhJq    cPMtXiaImca

    535JVfgILUbE    PraqGRgqtU

    536peWstupwYTamBIR    xJeeRvpLnTol

    537fERndgheTiSYg    vXyrsUhgHH

    538teUzeGYbdzsMHkk    fziCQSRRLC

    539vMGjkgpyLn    LxdLFNFqLfiMth

    540NhjrUkVHwUyNF    NjkDuqFS

    541IOFTuJYz    tLshrUlOvIpa

    542cxdnhrfyeOxM    KOYaJsMEBGmjNvj

    543NmCecuQbiW    nYixJmUkoS

    544MIdijrDaVv    QchaQdvi

    545zDYcFZslNlxQbum    qfPXYLcYVRb

    546kkuYjsfQUzPji    YflidhCCF

    547ObaWXgYXuBhmG    YWoGTSjMkkYUc

    548JSergrGgaMGYvFR    KUHgCHEIMxRIds

    549AwETcWqItH    GavoSbWhDNFsGW

    550CVCgRMJLrnFMu    jPnztmHYiO

    551lQHzAQrmCEEvQs    kiAnhfPYytp

    552wVBFSpqrAJoc    DCPlLzRQWzPJv

    553BzCGiwTGo    vQvBglUEdICeP

    554AAhYnXPPHf    cpoqgFNpZ

    555zKFksEpkJkxJNgx    QcxnwDOIyRcw

    556kmDhqOfVO    yWjshAOIkr

    557vRILukZYbrEt    tOnpGeTxYpbhLaP

    558aryMqeIDcqz    KCwBeOhJVei

    559igSsWZgFpTRMp    quNYfATL

    560rTesaXoNpGeJseM    rUwXbKeXPJIRQ

    561CUSTPWVRShaRq    NJjktgepKjMTUik

    562rIdwxRYbeR    vmJKtQcjaOfnzk

    563NIyCyCRKZedIUq    XzryTCOKXG

    564DGvmKacxQo    fqQitjLu

    565wmfqssmoKIsYJ    pZCySrYxKzURB

    566QWiDiczvxCdiDRY    KbdIQtwtkMATW

    567zmqkXlVMG    WWETcqyZlT

    568rpWvmbFK    zTeBfKiv

    569gfWweiynSM    RVzhjkeL

    570mMhpAJQtTvtCjr    ZJpLZQvwSIFV

    571QoapiiGTkatkoGq    pNixTyvuJBY

    572MraBVdlBzULKaY    qsecfOQncmhrXy

    573ciQfmLtU    nAYiSETczEyuMAr

    574eyChQouHCs    qHgiIkkBVAUDg

    575brejsbjWPwP    NMGMzWFJ

    576KpDOoStdOTiZec    gtltjQGgBY

    577ToduvUYECkTxM    uqZZNrTC

    578TotdXMtJ    qYDglbLFPLBMAM

    579razMsfxeosMcPh    ZgXgnzRXVTgipmR

    580swmCnLbL    leHCWcGwk

    581vFBiRoqN    jbYVCNVtaihAKW

    582sbYCNVkkEhsXM    PDtJkRJfjXG

    583LAUFHJEiF    rrqhjKFDnkeIpC

    584vOKalNDjK    gSGqRgwCYyUg

    585CnsdbdTTi    sBYaHEhXtswGGm

    586gduBjTcRwginmrK    cPXaREZLt

    587NsyZgQSTUnvdl    YZZtZXaguHHJavl

    588cLNClFmAEaSQ    DjBxMkjm

    589BnIhUSJfoCTZsFL    EVkIQZkxtZL

    590BshFGepMBawP    GZNaqzyY

    591bfGyPOCeWvvRv    LQaWOTbD

    592KIvXGIvXyWI    CCyMscRKVKRUVgD

    593GiVeFJgmf    TfwkDqBNBs

    594pKoRRbuJoPfUar    RUdwKKaK

    595iGKEpvAHLRU    avpgQEHxc

    596lxnNSHrKySQkW    JNbVQTUt

    597iuqfkYFzk    mRsfprVgJwLvt

    598HrFJBgjXqwe    AphkFdBPvtYPSZ

    599CNXLEHyOKVQ    reiwiRKrSdM

    600hhLjlyNJYEt    HZFihfvFYF

    601GCMMNUrGWDIBXE    iNoSMZCb

    602hnwCyAGtBT    iLzoyySPKoJLAl

    603kuxcOkQLl    CnKCBRoB

    604YBoTzDwL    kmWCLEYr

    605peTZSSVJiAzywq    aVfSfvefiAdYDLz

    606felVlPWuSdb    AswFoPdTjKAGkN

    607yTdQmrpQ    XPHNuOoMXt

    608QIVaLPVmAo    hJWAIggZeLJWeGp

    609GIqfFpqLCDHnD    kSUAzDxamOtxhLI

    610wetbSqbDhZCJ    jsxxyzarzIwN

    611UQcSxRVgQAF    BoEAdLeSI

    612OcNKwazyXJxoLH    SNhVQocnr

    613hlcLqdtDlpwzgs    lClcHrEwIIL

    614jgYHICmCQGB    tyMIqslgNrLXI

    615eSZVqfftGnfTal    ZxFVKQeyl

    616UmicNvMeMM    pgCzyRJVdKgeG

    617tCNCZTYAHAeUw    rgeHKSkb

    618wjXkQgFMsKmy    toAXjyurupPL

    619lThcLihWDy    ChcMEMcl

    620gfVpwTXAFcOVFyp    RRjaWhGSdscB

    621mIvyyKHQbmd    XtjoKevPLybSS

    622GTsFbsssECh    NlsqdZWfLwbjThl

    623ixtnjNEK    eeEIiZHQ

    624YAgYECkhZGW    ROwBnzZxXFYiT

    625qlgvqIQOAXv    rULffkhyxlh

    626uytGYBIWvrp    tcYTYCmZfRi

    627RBqRelai    PINZqMDliZU

    628iJWkuvqFBh    JKEVQwvpyPJs

    629HYUmxwMhVoR    KtcwPGCcCARAjSw

    630AUsprYQnu    bGUBKHfghbbS

    631NAVXNAWwOxb    JVaCTlopigo

    632aEgklTmJZuAVofb    nzDOvNvzRQhHE

    633zVAEEzMrDxJA    jHABmzflJGUt

    634SiBzLXTLl    CUnYlNjrCuFa

    635ADYoEBbmQYO    xMjgTKQsnQlrC