diff --git a/.Copy2AddInFolder.cmd b/.Copy2AddInFolder.cmd deleted file mode 100644 index eca5efe..0000000 --- a/.Copy2AddInFolder.cmd +++ /dev/null @@ -1 +0,0 @@ -copy ACLibFilterFormWizard.accdb .\access-add-in\ACLibFilterFormWizard.accda diff --git a/.CreateWorkingFileFormAddInFolder.cmd b/.CreateWorkingFileFormAddInFolder.cmd deleted file mode 100644 index 48222c7..0000000 --- a/.CreateWorkingFileFormAddInFolder.cmd +++ /dev/null @@ -1,19 +0,0 @@ -@echo off - -if exist .\ACLibFilterFormWizard.accdb ( -set /p CopyFile=ACLibFilterFormWizard.accdb exists .. overwrite with access-add-in\ACLibFilterFormWizard.accda? [Y/N]: -) else ( -set CopyFile=Y -) - -if /I %CopyFile% == Y ( - echo File is copied ... -) else ( - echo Batch is cancelled - pause - exit -) - -copy .\access-add-in\ACLibFilterFormWizard.accda ACLibFilterFormWizard.accdb - -timeout 2 \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f65a117 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,42 @@ +# gitattributes template for Microsoft Access database source files +# Source: https://github.com/joyfullservice/msaccess-vcs-integration +# + +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Ensure that source files use CRLF for newlines, in case they are downloaded +# in a compressed archive directly from GitHub. (Otherwise class modules may +# not be imported correctly. See issue #150 for more details.) +############################################################################### +# Most source files use this extension +*.bas text eol=crlf +# Class modules +*.cls text eol=crlf +# Some object definitions +*.xml text eol=crlf +# SQL output +*.sql text eol=crlf +# Forms 2.0 form definitions (rarely used) +*.frm text eol=crlf +# Common source file +*.json text eol=crlf + +############################################################################### +# Clarify that the source language is VBA (Auto-detection not always accurate) +# https://github.com/github/linguist/blob/master/docs/overrides.md +############################################################################### +*.bas linguist-language=VBA +*.cls linguist-language=VBA +*.twin linguist-language=VBA + +# Git files +*.gitattributes text +*.gitattributes linguist-language=gitattributes + +# Ignore files (like .npmignore or .gitignore) +*.*ignore text +*.*ignore export-ignore diff --git a/.github/workflows/build-accdb.yml b/.github/workflows/build-accdb.yml new file mode 100644 index 0000000..13a85eb --- /dev/null +++ b/.github/workflows/build-accdb.yml @@ -0,0 +1,51 @@ +name: Build-accdb (on push, pull) + +on: + push: + branches: + - main + - feature/** + - bugfix/** + paths: + - 'source/**' + pull_request: + branches: + - main + workflow_dispatch: + +permissions: + contents: write + id-token: write + attestations: write + +jobs: + build: + runs-on: [self-hosted, Windows, Office] + + steps: + - name: "Checkout code for release tag" + uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.tag_name }} + + - name: "Build Access file (accdb/accde)" + id: build_access_file + uses: AccessCodeLib/msaccess-vcs-build@main + with: + source-dir: "source" + target-dir: "access-add-in" + file-name: "ACLibFilterFormWizard.accda" + timeout-minutes: 10 + + - name: "Upload Build Artifact" + uses: actions/upload-artifact@v4 + id: "upload" + with: + name: "Install files" + path: "./access-add-in/*" + if-no-files-found: warn + - name: "Attestation" + uses: actions/attest-build-provenance@v2 + with: + subject-name: "Install files" + subject-digest: sha256:${{ steps.upload.outputs.artifact-digest }} diff --git a/.github/workflows/build-release-zip-file.yml b/.github/workflows/build-release-zip-file.yml new file mode 100644 index 0000000..ae73c08 --- /dev/null +++ b/.github/workflows/build-release-zip-file.yml @@ -0,0 +1,83 @@ +name: Build-install-zip-file (on release) + +on: + release: + types: [published] + +permissions: + contents: write + id-token: write + attestations: write + +jobs: + build: + runs-on: [self-hosted, Windows, Office] + + steps: + - name: "Checkout code for release tag" + uses: actions/checkout@v4 + with: + ref: ${{ github.event.release.tag_name }} + + - name: "Build Access file (accdb/accde)" + id: build_access_file + uses: AccessCodeLib/msaccess-vcs-build@main + with: + source-dir: "source" + target-dir: "access-add-in" + file-name: "ACLibFilterFormWizard.accda" + timeout-minutes: 10 + + - name: "Create versioned ZIP file" + run: | + $zipName = "ACLibFilterFormWizard_${{ github.event.release.tag_name }}.zip" + Compress-Archive -Path .\access-add-in\* -DestinationPath $zipName + echo "ZIP_NAME=$zipName" | Out-File -FilePath $env:GITHUB_ENV -Append + + - name: "Upload ZIP to GitHub Release" + uses: softprops/action-gh-release@v1 + with: + files: ${{ env.ZIP_NAME }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: "Calculate SHA256 of ZIP" + id: hash + shell: pwsh + run: | + $zipName = "${{ env.ZIP_NAME }}" + $hash = Get-FileHash -Algorithm SHA256 -Path $zipName + $digest = "sha256:$($hash.Hash.ToLower())" + echo "ZIP_DIGEST=$digest" | Out-File -FilePath $env:GITHUB_ENV -Append + echo "digest=$digest" >> $env:GITHUB_OUTPUT + + - name: "Attestation" + uses: actions/attest-build-provenance@v2 + id: attestation + with: + subject-name: "${{ env.ZIP_NAME }}" + subject-digest: "${{ steps.hash.outputs.digest }}" + + - name: "Update release description with attestation URL" + shell: pwsh + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + TAG: ${{ github.event.release.tag_name }} + run: | + $ErrorActionPreference = "Stop" + + # get current release notes + $oldBody = gh release view $env:TAG --repo $env:REPO --json body --template "{{.body}}" + + # build Attestation URL + $attestationId = "${{ steps.attestation.outputs.attestation-id }}" + $attestationUrl = "https://github.com/$($env:REPO)/attestations/$attestationId" + + # join release notes with Attestation url + $newBody = "$oldBody`n`nAttestation: $attestationUrl" + + # save release notes + gh release edit $env:TAG --repo $env:REPO --notes "$newBody" + + diff --git a/.gitignore b/.gitignore index c6f3b71..fe82cce 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,23 @@ -/*.accdb +# gitattributes template for Microsoft Access database source files +# Website: https://github.com/joyfullservice/msaccess-vcs-addin +# + +# Ignore Microsoft Access database binary files (Build these from source) +*.accda +*.accdb +*.mdb + +# Ignore database lock files +*.laccdb +*.ldb + +# The local VCS index file is paired with the binary database file +# and should not be comitted to version control. +vcs-index.json + +# Ignore any dotenv files (used for external database connections) +*.env + +# Ignore log files generated by the VCS Add-in +# Comment out the following line if you wish to include log files in git. +*.log diff --git a/access-add-in/ACLibFilterFormWizard.accda b/access-add-in/ACLibFilterFormWizard.accda deleted file mode 100644 index 749e95a..0000000 Binary files a/access-add-in/ACLibFilterFormWizard.accda and /dev/null differ diff --git a/source/codelib/base/defGlobal.bas b/source/codelib/base/defGlobal.bas deleted file mode 100644 index 255920f..0000000 --- a/source/codelib/base/defGlobal.bas +++ /dev/null @@ -1,92 +0,0 @@ -Attribute VB_Name = "defGlobal" -Attribute VB_Description = "Allgemeine Konstanten und Eigenschaften" -'--------------------------------------------------------------------------------------- -' Modul: defGlobal -'--------------------------------------------------------------------------------------- -'/** -' -' Allgemeine Konstanten und Eigenschaften -' -' -' \ingroup base -'**/ -'--------------------------------------------------------------------------------------- -' -' base/defGlobal.bas -' _codelib/license.bas -' base/modApplication.bas -' -'--------------------------------------------------------------------------------------- -' -Option Explicit -Option Compare Text -Option Private Module - -'--------------------------------------------------------------------------------------- -' -' Konstanten -' - - -'--------------------------------------------------------------------------------------- -' -' Hilfs-Variablen -' - - -'--------------------------------------------------------------------------------------- -' -' Hilfs-Prozeduren -' - -' -' Private Hilfsvariablen für die Prozeduren -' -Private m_ApplicationName As String 'Zwischenspeicher für Anwendungsnamen, falls - 'CurrentApplication.ApplicationName nicht läuft - -'--------------------------------------------------------------------------------------- -' Property: CurrentApplicationName -'--------------------------------------------------------------------------------------- -'/** -' -' Name der aktuellen Anwendung -' -' String -' -' Verwendet CurrentApplication.ApplicationName -' -'**/ -'--------------------------------------------------------------------------------------- -Public Property Get CurrentApplicationName() As String -' incl. emergency error handler if CurrentApplication is not instantiated - -On Error GoTo HandleErr - - CurrentApplicationName = CurrentApplication.ApplicationName - -ExitHere: - Exit Property - -HandleErr: - CurrentApplicationName = GetApplicationNameFromDb - Resume ExitHere - -End Property - -Private Function GetApplicationNameFromDb() As String - - If Len(m_ApplicationName) = 0 Then -On Error Resume Next -'1. Value from title property - m_ApplicationName = CodeDb.Properties("AppTitle").Value - If Len(m_ApplicationName) = 0 Then -'2. Value from file name - m_ApplicationName = CodeDb.Name - m_ApplicationName = Left$(m_ApplicationName, InStrRev(m_ApplicationName, ".") - 1) - End If - End If - - GetApplicationNameFromDb = m_ApplicationName - -End Function diff --git a/source/codelib/readme.md b/source/codelib/readme.md deleted file mode 100644 index a5c7e2a..0000000 --- a/source/codelib/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -Shared files from access-codelib.net - -### License -BSD (see [_codelib/license.bas](https://github.com/AccessCodeLib/FilterFormWizard/blob/master/source/codelib/_codelib/license.bas)) - -### Source -* Subversion: https://svn.access-codelib.net/svn/codelib/ -* GitHub: https://github.com/AccessCodeLib/AccessCodeLib - - diff --git a/source/dbs-properties.json b/source/dbs-properties.json new file mode 100644 index 0000000..0c04d79 --- /dev/null +++ b/source/dbs-properties.json @@ -0,0 +1,204 @@ +{ + "Info": { + "Class": "clsDbProperty", + "Description": "Database Properties (DAO)" + }, + "Items": { + "AccessVersion": { + "Value": "09.50", + "Type": 10 + }, + "AllowBuiltInToolbars": { + "Value": true, + "Type": 1 + }, + "AllowDatasheetSchema": { + "Value": false, + "Type": 1 + }, + "AllowFullMenus": { + "Value": true, + "Type": 1 + }, + "AllowShortcutMenus": { + "Value": true, + "Type": 1 + }, + "AllowSpecialKeys": { + "Value": true, + "Type": 1 + }, + "AllowToolbarChanges": { + "Value": true, + "Type": 1 + }, + "ANSI Query Mode": { + "Value": 0, + "Type": 4 + }, + "AppTitle": { + "Value": "Access Code Library - FilterForm Wizard", + "Type": 10 + }, + "Auto Compact": { + "Value": 0, + "Type": 4 + }, + "Build": { + "Value": 231, + "Type": 4 + }, + "CheckTruncatedNumFields": { + "Value": 1, + "Type": 4 + }, + "Clear Cache on Close": { + "Value": 0, + "Type": 4 + }, + "CollatingOrder": { + "Value": 1033, + "Type": 3 + }, + "Connect": { + "Value": "", + "Type": 12 + }, + "DesignMasterID": { + "Value": "", + "Type": 15 + }, + "DesignWithData": { + "Value": false, + "Type": 1 + }, + "HasOfflineLists": { + "Value": 70, + "Type": 3 + }, + "Name": { + "Value": "rel:ACLibFilterFormWizard.accdb", + "Type": 12 + }, + "NavPane Category": { + "Value": 0, + "Type": 4 + }, + "NavPane Closed": { + "Value": 0, + "Type": 4 + }, + "NavPane Sort By": { + "Value": 1, + "Type": 4 + }, + "NavPane View By": { + "Value": 0, + "Type": 4 + }, + "NavPane Width": { + "Value": 794, + "Type": 4 + }, + "Never Cache": { + "Value": 0, + "Type": 4 + }, + "Perform Name AutoCorrect": { + "Value": 0, + "Type": 4 + }, + "Picture Property Storage Format": { + "Value": 1, + "Type": 4 + }, + "ProjVer": { + "Value": 142, + "Type": 3 + }, + "QueryTimeout": { + "Value": 60, + "Type": 3 + }, + "RecordsAffected": { + "Value": 0, + "Type": 4 + }, + "ReplicaID": { + "Value": "", + "Type": 15 + }, + "Show Navigation Pane Search Bar": { + "Value": 1, + "Type": 4 + }, + "Show Values in Indexed": { + "Value": 1, + "Type": 4 + }, + "Show Values in Non-Indexed": { + "Value": 1, + "Type": 4 + }, + "Show Values in Remote": { + "Value": 0, + "Type": 4 + }, + "Show Values Limit": { + "Value": 1000, + "Type": 4 + }, + "ShowDocumentTabs": { + "Value": true, + "Type": 1 + }, + "StartUpShowDBWindow": { + "Value": true, + "Type": 1 + }, + "StartUpShowStatusBar": { + "Value": true, + "Type": 1 + }, + "Theme Resource Name": { + "Value": "Office", + "Type": 10 + }, + "Themed Form Controls": { + "Value": 1, + "Type": 4 + }, + "Track Name AutoCorrect Info": { + "Value": 0, + "Type": 4 + }, + "Transactions": { + "Value": true, + "Type": 1 + }, + "Updatable": { + "Value": true, + "Type": 1 + }, + "Use Microsoft Access 2007 compatible cache": { + "Value": 0, + "Type": 4 + }, + "UseAppIconForFrmRpt": { + "Value": false, + "Type": 1 + }, + "UseMDIMode": { + "Value": 1, + "Type": 2 + }, + "Version": { + "Value": "14.0", + "Type": 12 + }, + "WebDesignMode": { + "Value": 0, + "Type": 2 + } + } +} diff --git a/source/documents.json b/source/documents.json new file mode 100644 index 0000000..3498ada --- /dev/null +++ b/source/documents.json @@ -0,0 +1,20 @@ +{ + "Info": { + "Class": "clsDbDocument", + "Description": "Database Documents Properties (DAO)" + }, + "Items": { + "Databases": { + "SummaryInfo": { + "Author": "Josef Pötzl", + "Category": "ACLib Wizard", + "Comments": "Filter-Formulare mit Klasse", + "Company": "access-codelib.net", + "Hyperlink base": "access-codelib.net", + "Manager": "Josef Pötzl", + "Subject": "ACLib Wizard", + "Title": "ACLib FilterForm Wizard" + } + } + } +} diff --git a/source/forms/frmFilterFormWizard.bas b/source/forms/frmFilterFormWizard.bas new file mode 100644 index 0000000..d5a3dc7 --- /dev/null +++ b/source/forms/frmFilterFormWizard.bas @@ -0,0 +1,1088 @@ +Version =20 +VersionRequired =20 +Begin Form + AllowFilters = NotDefault + RecordSelectors = NotDefault + ShortcutMenu = NotDefault + AutoCenter = NotDefault + NavigationButtons = NotDefault + AllowDeletions = NotDefault + AllowAdditions = NotDefault + KeyPreview = NotDefault + DefaultView =0 + ScrollBars =0 + TabularFamily =119 + PictureAlignment =2 + DatasheetGridlinesBehavior =3 + Cycle =1 + GridY =10 + Width =10771 + DatasheetFontHeight =10 + ItemSuffix =136 + Left =2835 + Top =1470 + Right =13605 + Bottom =7823 + RecSrcDt = Begin + 0x668d2cd46a58e440 + End + Caption ="ACLib FilterForm Wizard" + OnCurrent ="[Event Procedure]" + OnOpen ="[Event Procedure]" + DatasheetFontName ="Arial" + FilterOnLoad =0 + ShowPageMargins =0 + AllowLayoutView =0 + DatasheetGridlinesColor12 =12632256 + Begin + Begin Label + BackStyle =0 + FontName ="Tahoma" + End + Begin Rectangle + SpecialEffect =3 + BackStyle =0 + BorderLineStyle =0 + Width =850 + Height =850 + End + Begin Line + BorderLineStyle =0 + Width =1701 + End + Begin Image + BackStyle =0 + OldBorderStyle =0 + BorderLineStyle =0 + SizeMode =3 + PictureAlignment =2 + Width =1701 + Height =1701 + BorderThemeColorIndex =3 + BorderShade =90.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + End + Begin CommandButton + Width =1701 + Height =283 + FontSize =8 + FontWeight =400 + ForeColor =-2147483630 + FontName ="Tahoma" + BorderLineStyle =0 + End + Begin OptionButton + BorderLineStyle =0 + LabelX =230 + LabelY =-30 + BorderThemeColorIndex =3 + BorderShade =90.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + End + Begin CheckBox + SpecialEffect =2 + BorderLineStyle =0 + LabelX =230 + LabelY =-30 + End + Begin OptionGroup + SpecialEffect =3 + BorderLineStyle =0 + Width =1701 + Height =1701 + End + Begin TextBox + FELineBreak = NotDefault + SpecialEffect =2 + OldBorderStyle =0 + BorderLineStyle =0 + Width =1701 + LabelX =-1701 + FontName ="Tahoma" + AsianLineBreak =255 + End + Begin ComboBox + SpecialEffect =2 + BorderLineStyle =0 + Width =1701 + LabelX =-1701 + FontName ="Tahoma" + End + Begin Subform + BorderLineStyle =0 + Width =1701 + Height =1701 + BorderThemeColorIndex =3 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + BorderShade =90.0 + ShowPageHeaderAndPageFooter =1 + End + Begin ToggleButton + Width =283 + Height =283 + FontSize =8 + FontWeight =400 + ForeColor =-2147483630 + FontName ="Tahoma" + BorderLineStyle =0 + End + Begin Section + CanGrow = NotDefault + Height =6362 + BackColor =-2147483633 + Name ="Detailbereich" + Begin + Begin Label + OldBorderStyle =1 + BorderWidth =1 + OverlapFlags =93 + TextFontCharSet =2 + TextAlign =1 + TextFontFamily =2 + Left =2345 + Top =5394 + Width =295 + Height =295 + FontSize =16 + ForeColor =5026082 + Name ="labCopyModulFilterStringBuilder" + FontName ="Marlett" + OnClick ="[Event Procedure]" + VerticalAnchor =1 + LayoutCachedLeft =2345 + LayoutCachedTop =5394 + LayoutCachedWidth =2640 + LayoutCachedHeight =5689 + End + Begin Label + OldBorderStyle =1 + BorderWidth =1 + OverlapFlags =93 + TextFontCharSet =2 + TextAlign =1 + TextFontFamily =2 + Left =2345 + Top =4710 + Width =295 + Height =295 + FontSize =16 + ForeColor =5026082 + Name ="labCopyModulFilterControlManager" + FontName ="Marlett" + VerticalAnchor =1 + LayoutCachedLeft =2345 + LayoutCachedTop =4710 + LayoutCachedWidth =2640 + LayoutCachedHeight =5005 + End + Begin Label + OldBorderStyle =1 + BorderWidth =1 + OverlapFlags =93 + TextFontCharSet =2 + TextAlign =1 + TextFontFamily =2 + Left =2345 + Top =5769 + Width =295 + Height =295 + FontSize =16 + ForeColor =5026082 + Name ="labCopyModulSqlTools" + FontName ="Marlett" + VerticalAnchor =1 + LayoutCachedLeft =2345 + LayoutCachedTop =5769 + LayoutCachedWidth =2640 + LayoutCachedHeight =6064 + End + Begin Label + OldBorderStyle =1 + BorderWidth =1 + OverlapFlags =93 + TextFontCharSet =2 + TextAlign =1 + TextFontFamily =2 + Left =2345 + Top =4371 + Width =295 + Height =295 + FontSize =16 + ForeColor =5026082 + Name ="labCopyModules" + FontName ="Marlett" + VerticalAnchor =1 + LayoutCachedLeft =2345 + LayoutCachedTop =4371 + LayoutCachedWidth =2640 + LayoutCachedHeight =4666 + End + Begin Line + OverlapFlags =85 + SpecialEffect =2 + Left =2748 + Top =4210 + Width =0 + Height =2098 + Name ="Linie49" + VerticalAnchor =1 + LayoutCachedLeft =2748 + LayoutCachedTop =4210 + LayoutCachedWidth =2748 + LayoutCachedHeight =6308 + End + Begin TextBox + AllowAutoCorrect = NotDefault + SpecialEffect =0 + OverlapFlags =85 + BackStyle =0 + IMESentenceMode =3 + Width =0 + Height =0 + Name ="sysFirst" + + End + Begin CommandButton + Enabled = NotDefault + TabStop = NotDefault + OverlapFlags =93 + Left =7426 + Top =5832 + Width =3072 + Height =375 + FontSize =10 + TabIndex =18 + Name ="cmdAddFilterCodeToForm" + Caption ="Insert Form Code" + OnClick ="[Event Procedure]" + FontName ="Verdana" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =7426 + LayoutCachedTop =5832 + LayoutCachedWidth =10498 + LayoutCachedHeight =6207 + Overlaps =1 + End + Begin Label + OverlapFlags =85 + Left =315 + Top =4740 + Width =1991 + Height =255 + FontSize =9 + Name ="labCaptionCopyModulFilterControlManager" + Caption ="FilterControlManager" + VerticalAnchor =1 + LayoutCachedLeft =315 + LayoutCachedTop =4740 + LayoutCachedWidth =2306 + LayoutCachedHeight =4995 + End + Begin Label + OverlapFlags =85 + Left =315 + Top =5419 + Width =1991 + Height =255 + FontSize =9 + Name ="labCaptionCopyModulFilterStringBuilder" + Caption ="FilterStringBuilder" + VerticalAnchor =1 + LayoutCachedLeft =315 + LayoutCachedTop =5419 + LayoutCachedWidth =2306 + LayoutCachedHeight =5674 + End + Begin Label + OverlapFlags =85 + Left =315 + Top =5794 + Width =1991 + Height =255 + FontSize =9 + Name ="labCaptionCopyModulSqlTools" + Caption ="SqlTools" + VerticalAnchor =1 + LayoutCachedLeft =315 + LayoutCachedTop =5794 + LayoutCachedWidth =2306 + LayoutCachedHeight =6049 + End + Begin CommandButton + Transparent = NotDefault + OverlapFlags =215 + Left =2345 + Top =5394 + Width =295 + Height =295 + TabIndex =15 + Name ="cmdCopyModulFilterStringBuilder" + Caption ="Befehl69" + OnClick ="[Event Procedure]" + VerticalAnchor =1 + + LayoutCachedLeft =2345 + LayoutCachedTop =5394 + LayoutCachedWidth =2640 + LayoutCachedHeight =5689 + Overlaps =1 + End + Begin CommandButton + Transparent = NotDefault + OverlapFlags =215 + Left =2345 + Top =4710 + Width =295 + Height =295 + TabIndex =11 + Name ="cmdCopyModulFilterControlManager" + Caption ="Befehl69" + OnClick ="[Event Procedure]" + VerticalAnchor =1 + + LayoutCachedLeft =2345 + LayoutCachedTop =4710 + LayoutCachedWidth =2640 + LayoutCachedHeight =5005 + Overlaps =1 + End + Begin CommandButton + Transparent = NotDefault + OverlapFlags =215 + Left =2345 + Top =5769 + Width =295 + Height =295 + TabIndex =17 + Name ="cmdCopyModulSqlTools" + Caption ="Befehl69" + OnClick ="[Event Procedure]" + VerticalAnchor =1 + + LayoutCachedLeft =2345 + LayoutCachedTop =5769 + LayoutCachedWidth =2640 + LayoutCachedHeight =6064 + Overlaps =1 + End + Begin Label + FontUnderline = NotDefault + OverlapFlags =93 + Left =84 + Top =4393 + Width =2145 + Height =255 + FontSize =9 + FontWeight =700 + ForeColor =16737792 + Name ="labCopyCaption" + Caption ="Install classes:" + OnMouseDown ="[Event Procedure]" + OnMouseMove ="[Event Procedure]" + Tag ="LANG:" + VerticalAnchor =1 + LayoutCachedLeft =84 + LayoutCachedTop =4393 + LayoutCachedWidth =2229 + LayoutCachedHeight =4648 + End + Begin CommandButton + Transparent = NotDefault + OverlapFlags =223 + Left =2345 + Top =4371 + Width =295 + Height =295 + TabIndex =9 + Name ="cmdCopyModules" + Caption ="Befehl69" + OnClick ="[Event Procedure]" + VerticalAnchor =1 + + LayoutCachedLeft =2345 + LayoutCachedTop =4371 + LayoutCachedWidth =2640 + LayoutCachedHeight =4666 + Overlaps =1 + End + Begin ComboBox + LimitToList = NotDefault + OverlapFlags =85 + IMESentenceMode =3 + Left =2003 + Top =165 + Width =3402 + Height =285 + FontSize =10 + TabIndex =3 + Name ="cbxFormName" + RowSourceType ="Table/Query" + AfterUpdate ="[Event Procedure]" + FontName ="Verdana" + OnGotFocus ="[Event Procedure]" + + LayoutCachedLeft =2003 + LayoutCachedTop =165 + LayoutCachedWidth =5405 + LayoutCachedHeight =450 + Begin + Begin Label + OverlapFlags =85 + Left =77 + Top =165 + Width =1920 + Height =285 + FontSize =10 + Name ="labSelectForm" + Caption ="Filter form:" + FontName ="Verdana" + Tag ="LANG:" + LayoutCachedLeft =77 + LayoutCachedTop =165 + LayoutCachedWidth =1997 + LayoutCachedHeight =450 + End + End + End + Begin Subform + Enabled = NotDefault + OverlapFlags =87 + SpecialEffect =3 + Left =84 + Top =895 + Width =10605 + Height =3255 + TabIndex =7 + BorderColor =-2147483630 + Name ="sfrFilterControls" + SourceObject ="Form.frmFilterFormWizard_SF_Controls" + HorizontalAnchor =2 + VerticalAnchor =2 + + LayoutCachedLeft =84 + LayoutCachedTop =895 + LayoutCachedWidth =10689 + LayoutCachedHeight =4150 + BorderThemeColorIndex =-1 + BorderShade =100.0 + Begin + Begin Label + OverlapFlags =93 + Left =84 + Top =610 + Width =1920 + Height =285 + FontSize =10 + Name ="labFilterControls" + Caption ="Filter controls:" + Tag ="LANG:" + LayoutCachedLeft =84 + LayoutCachedTop =610 + LayoutCachedWidth =2004 + LayoutCachedHeight =895 + End + End + End + Begin OptionGroup + Enabled = NotDefault + OverlapFlags =93 + Left =3120 + Top =4705 + Width =3742 + Height =1304 + TabIndex =10 + Name ="ApplyFilterMethodOptions" + AfterUpdate ="[Event Procedure]" + DefaultValue ="0" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =3120 + LayoutCachedTop =4705 + LayoutCachedWidth =6862 + LayoutCachedHeight =6009 + Begin + Begin Label + BackStyle =1 + OverlapFlags =215 + TextAlign =2 + Left =3240 + Top =4590 + Width =1536 + Height =240 + BackColor =-2147483633 + Name ="labUseFilterMethodOptions" + Caption ="ApplyFilter method" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + LayoutCachedLeft =3240 + LayoutCachedTop =4590 + LayoutCachedWidth =4776 + LayoutCachedHeight =4830 + End + Begin OptionButton + OverlapFlags =87 + Left =3270 + Top =4977 + OptionValue =0 + Name ="ApplyFilterMethodOptions_Opt0" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =3270 + LayoutCachedTop =4977 + LayoutCachedWidth =3530 + LayoutCachedHeight =5217 + Begin + Begin Label + OverlapFlags =247 + Left =3495 + Top =4945 + Width =3075 + Height =240 + Name ="labUseFilterMethodOptions0" + Caption ="insert sample code" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + LayoutCachedLeft =3495 + LayoutCachedTop =4945 + LayoutCachedWidth =6570 + LayoutCachedHeight =5185 + End + End + End + Begin OptionButton + OverlapFlags =87 + Left =3270 + Top =5287 + TabIndex =1 + OptionValue =1 + Name ="ApplyFilterMethodOptions_Opt1" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =3270 + LayoutCachedTop =5287 + LayoutCachedWidth =3530 + LayoutCachedHeight =5527 + Begin + Begin Label + OverlapFlags =247 + Left =3499 + Top =5260 + Width =3049 + Height =240 + Name ="labUseFilterMethodOptions1" + Caption ="filter current form" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + LayoutCachedLeft =3499 + LayoutCachedTop =5260 + LayoutCachedWidth =6548 + LayoutCachedHeight =5500 + End + End + End + Begin OptionButton + OverlapFlags =87 + Left =3270 + Top =5630 + TabIndex =2 + OptionValue =2 + Name ="ApplyFilterMethodOptions_Opt2" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =3270 + LayoutCachedTop =5630 + LayoutCachedWidth =3530 + LayoutCachedHeight =5870 + Begin + Begin Label + OverlapFlags =247 + Left =3499 + Top =5600 + Width =1114 + Height =240 + Name ="labUseFilterMethodOptions3" + Caption ="Subform" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + LayoutCachedLeft =3499 + LayoutCachedTop =5600 + LayoutCachedWidth =4613 + LayoutCachedHeight =5840 + End + End + End + End + End + Begin ComboBox + Enabled = NotDefault + RowSourceTypeInt =1 + OverlapFlags =247 + IMESentenceMode =3 + ListWidth =3402 + Left =4613 + Top =5600 + Width =2061 + TabIndex =16 + Name ="cbxApplyFilterSubForm" + RowSourceType ="Value List" + ColumnWidths ="3402" + AfterUpdate ="[Event Procedure]" + OnGotFocus ="[Event Procedure]" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =4613 + LayoutCachedTop =5600 + LayoutCachedWidth =6674 + LayoutCachedHeight =5840 + End + Begin Label + OverlapFlags =215 + TextAlign =3 + Left =1176 + Top =4183 + Width =1548 + Height =210 + FontSize =7 + Name ="labCodeInstalled" + Caption ="already installed" + FontName ="Small Fonts" + Tag ="LANG:" + VerticalAnchor =1 + LayoutCachedLeft =1176 + LayoutCachedTop =4183 + LayoutCachedWidth =2724 + LayoutCachedHeight =4393 + End + Begin OptionGroup + Enabled = NotDefault + OverlapFlags =223 + Left =7260 + Top =4720 + Width =3458 + Height =1574 + TabIndex =12 + Name ="FormCodeOptions" + AfterUpdate ="[Event Procedure]" + DefaultValue ="1" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =7260 + LayoutCachedTop =4720 + LayoutCachedWidth =10718 + LayoutCachedHeight =6294 + Begin + Begin Label + BackStyle =1 + OverlapFlags =215 + Left =7376 + Top =4590 + Width =1395 + Height =240 + BackColor =-2147483633 + Name ="labFormCodeOptions" + Caption ="Filter code" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + LayoutCachedLeft =7376 + LayoutCachedTop =4590 + LayoutCachedWidth =8771 + LayoutCachedHeight =4830 + End + Begin OptionButton + OverlapFlags =87 + Left =7365 + Top =4937 + OptionValue =1 + Name ="FormCodeOptions_Opt1" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =7365 + LayoutCachedTop =4937 + LayoutCachedWidth =7625 + LayoutCachedHeight =5177 + Begin + Begin Label + OverlapFlags =247 + Left =7594 + Top =4905 + Width =2948 + Height =240 + Name ="labFormCodeOptions1" + Caption ="FilterControlManager methods" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + LayoutCachedLeft =7594 + LayoutCachedTop =4905 + LayoutCachedWidth =10542 + LayoutCachedHeight =5145 + End + End + End + Begin OptionButton + OverlapFlags =87 + Left =7365 + Top =5517 + TabIndex =1 + OptionValue =2 + Name ="FormCodeOptions_Opt2" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =7365 + LayoutCachedTop =5517 + LayoutCachedWidth =7625 + LayoutCachedHeight =5757 + Begin + Begin Label + OverlapFlags =247 + Left =7594 + Top =5490 + Width =2948 + Height =240 + Name ="Label130" + Caption ="FilterStringBuilder methods" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + LayoutCachedLeft =7594 + LayoutCachedTop =5490 + LayoutCachedWidth =10542 + LayoutCachedHeight =5730 + End + End + End + End + End + Begin ComboBox + OverlapFlags =87 + IMESentenceMode =3 + ColumnCount =4 + Left =8831 + Top =4195 + Width =1836 + TabIndex =8 + Name ="cbxSqlLang" + RowSourceType ="Table/Query" + RowSource ="SELECT tabSqlLangFormat.SqlLang, tabSqlLangFormat.SqlDateFormat, tabSqlLangForma" + "t.SqlBooleanTrueString, tabSqlLangFormat.SqlWildCardString FROM tabSqlLangFormat" + " ORDER BY tabSqlLangFormat.SqlLang;" + ColumnWidths ="1701;0;0;0" + StatusBarText ="Select SQL dialect" + DefaultValue ="\"Jet/DAO\"" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + + LayoutCachedLeft =8831 + LayoutCachedTop =4195 + LayoutCachedWidth =10667 + LayoutCachedHeight =4435 + Begin + Begin Label + OverlapFlags =93 + TextAlign =3 + Left =7766 + Top =4195 + Width =1065 + Height =240 + RightMargin =29 + Name ="labSqlLang" + Caption ="SQL dialect:" + Tag ="LANG:" + HorizontalAnchor =1 + VerticalAnchor =1 + LayoutCachedLeft =7766 + LayoutCachedTop =4195 + LayoutCachedWidth =8831 + LayoutCachedHeight =4435 + End + End + End + Begin ComboBox + Enabled = NotDefault + RowSourceTypeInt =1 + OverlapFlags =87 + IMESentenceMode =3 + ListWidth =2268 + Left =8423 + Top =308 + Width =1659 + TabIndex =4 + Name ="cbxRemoveFilterCtl" + RowSourceType ="Value List" + + LayoutCachedLeft =8423 + LayoutCachedTop =308 + LayoutCachedWidth =10082 + LayoutCachedHeight =548 + Begin + Begin Label + OverlapFlags =93 + TextAlign =3 + Left =5496 + Top =312 + Width =2925 + Height =240 + RightMargin =29 + Name ="labRemoveFilterCtl" + Caption ="CommandButton \"Remove Filter\":" + Tag ="LANG:" + LayoutCachedLeft =5496 + LayoutCachedTop =312 + LayoutCachedWidth =8421 + LayoutCachedHeight =552 + End + End + End + Begin ComboBox + Enabled = NotDefault + RowSourceTypeInt =1 + OverlapFlags =87 + IMESentenceMode =3 + Left =8423 + Top =24 + Width =1659 + TabIndex =1 + Name ="cbxApplyFilterCtl" + RowSourceType ="Value List" + ColumnWidths ="2268" + + LayoutCachedLeft =8423 + LayoutCachedTop =24 + LayoutCachedWidth =10082 + LayoutCachedHeight =264 + Begin + Begin Label + OverlapFlags =93 + TextAlign =3 + Left =5496 + Top =28 + Width =2925 + Height =240 + RightMargin =29 + Name ="labUseFilterCtl" + Caption ="CommandButton \"Apply Filter\":" + Tag ="LANG:" + LayoutCachedLeft =5496 + LayoutCachedTop =28 + LayoutCachedWidth =8421 + LayoutCachedHeight =268 + End + End + End + Begin ComboBox + Enabled = NotDefault + RowSourceTypeInt =1 + OverlapFlags =87 + IMESentenceMode =3 + ListWidth =2268 + Left =8424 + Top =598 + Width =1659 + TabIndex =6 + Name ="cbxAutoFilterCtl" + RowSourceType ="Value List" + + LayoutCachedLeft =8424 + LayoutCachedTop =598 + LayoutCachedWidth =10083 + LayoutCachedHeight =838 + Begin + Begin Label + OverlapFlags =93 + TextAlign =3 + Left =5497 + Top =602 + Width =2925 + Height =240 + RightMargin =29 + Name ="labAutoFilterCtl" + Caption ="AutoFilter Checkbox:" + Tag ="LANG:" + LayoutCachedLeft =5497 + LayoutCachedTop =602 + LayoutCachedWidth =8422 + LayoutCachedHeight =842 + End + End + End + Begin Label + FontUnderline = NotDefault + OverlapFlags =85 + TextAlign =1 + Left =56 + Top =6122 + Width =2568 + Height =240 + ForeColor =16737792 + Name ="labCheckVersion" + Caption ="Check wizard version" + OnClick ="[Event Procedure]" + OnMouseMove ="[Event Procedure]" + Tag ="unchecked|LANG:" + VerticalAnchor =1 + LayoutCachedLeft =56 + LayoutCachedTop =6122 + LayoutCachedWidth =2624 + LayoutCachedHeight =6362 + End + Begin CommandButton + Enabled = NotDefault + OverlapFlags =87 + Left =2004 + Top =595 + Width =3402 + Height =284 + FontSize =7 + TabIndex =5 + Name ="cmdFillFilterControlsFromDataSource" + Caption ="Fill list with names from data source" + StatusBarText ="Please select the data form in the 'ApplyFilter method' option" + OnClick ="[Event Procedure]" + Tag ="LANG:" + ControlTipText ="Please select the data form in the 'ApplyFilter method' option" + + LayoutCachedLeft =2004 + LayoutCachedTop =595 + LayoutCachedWidth =5406 + LayoutCachedHeight =879 + BackColor =-2147483633 + Overlaps =1 + End + Begin ComboBox + LimitToList = NotDefault + TabStop = NotDefault + RowSourceTypeInt =1 + SpecialEffect =0 + OldBorderStyle =0 + OverlapFlags =85 + TextAlign =2 + IMESentenceMode =3 + Left =10128 + Top =24 + Width =561 + Height =228 + TabIndex =2 + BackColor =14151142 + Name ="cbxLangCode" + RowSourceType ="Value List" + RowSource ="\"DE\";\"EN\"" + AfterUpdate ="[Event Procedure]" + HorizontalAnchor =1 + + LayoutCachedLeft =10128 + LayoutCachedTop =24 + LayoutCachedWidth =10689 + LayoutCachedHeight =252 + End + Begin CheckBox + Enabled = NotDefault + OverlapFlags =215 + Left =7605 + Top =5191 + TabIndex =14 + Name ="cbUseFilterControlTagConverter" + DefaultValue ="False" + + LayoutCachedLeft =7605 + LayoutCachedTop =5191 + LayoutCachedWidth =7865 + LayoutCachedHeight =5431 + Begin + Begin Label + OverlapFlags =247 + Left =7833 + Top =5160 + Width =2760 + Height =240 + Name ="Label132" + Caption ="Filter definition in tag property" + Tag ="LANG:" + LayoutCachedLeft =7833 + LayoutCachedTop =5160 + LayoutCachedWidth =10593 + LayoutCachedHeight =5400 + End + End + End + Begin Label + OldBorderStyle =1 + BorderWidth =1 + OverlapFlags =95 + TextFontCharSet =2 + TextAlign =1 + TextFontFamily =2 + Left =2345 + Top =5019 + Width =295 + Height =295 + FontSize =16 + ForeColor =5026082 + Name ="labCopyModulFilterControltagConverter" + FontName ="Marlett" + VerticalAnchor =1 + LayoutCachedLeft =2345 + LayoutCachedTop =5019 + LayoutCachedWidth =2640 + LayoutCachedHeight =5314 + End + Begin Label + OverlapFlags =85 + TextAlign =3 + Left =315 + Top =5044 + Width =1991 + Height =255 + TopMargin =14 + Name ="labCaptionCopyModulFilterControlTagConverter" + Caption ="FilterControlTagConverter" + VerticalAnchor =1 + LayoutCachedLeft =315 + LayoutCachedTop =5044 + LayoutCachedWidth =2306 + LayoutCachedHeight =5299 + End + Begin CommandButton + Transparent = NotDefault + OverlapFlags =215 + Left =2345 + Top =5019 + Width =295 + Height =295 + TabIndex =13 + Name ="cmdCopyModulFilterControlTagConverter" + Caption ="Befehl69" + OnClick ="[Event Procedure]" + VerticalAnchor =1 + + LayoutCachedLeft =2345 + LayoutCachedTop =5019 + LayoutCachedWidth =2640 + LayoutCachedHeight =5314 + Overlaps =1 + End + End + End + End +End +CodeBehindForm +' See "frmFilterFormWizard.cls" diff --git a/source/forms/frmFilterFormWizard.cls b/source/forms/frmFilterFormWizard.cls new file mode 100644 index 0000000..6aac5e0 --- /dev/null +++ b/source/forms/frmFilterFormWizard.cls @@ -0,0 +1,755 @@ +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = True +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +'--------------------------------------------------------------------------------------- +' Form: frmFilterFormWizard +'--------------------------------------------------------------------------------------- +'/** +' \author Josef Poetzl +' +' Wizard form for filter code import +' +' +'**/ +'------------------------------------------------------------------------------------ +' +Option Compare Database +Option Explicit + +Private m_OpenModules As Long +Private m_CodeModulImporter As AppFileCodeModulTransfer + +Private Const SubFormApplyFilterOption As Long = 2 +Private Const FILTERFORMWIZARD_TEXT_CREATENEW As String = "" + +Private WithEvents m_L10nDict As L10nDict +Attribute m_L10nDict.VB_VarHelpID = -1 + +Private Property Get SourceDb() As DAO.Database + Set SourceDb = CurrentDb +End Property + +Private Property Get CodeModulImporter() As AppFileCodeModulTransfer + If m_CodeModulImporter Is Nothing Then + Set m_CodeModulImporter = New AppFileCodeModulTransfer + m_CodeModulImporter.UseVbComponentsImport = APPLICATION_FILTERCODEMODULE_USEVBCOMPONENTSIMPORT + End If + Set CodeModulImporter = m_CodeModulImporter +End Property + +Private Sub cbxFormName_AfterUpdate() + + Dim FormName As String + Dim FormSelected As Boolean + Dim FormRef As Form + + RefreshAddFilterButtonEnableMode + + FormName = Nz(Me.cbxFormName.Value, vbNullString) + FormSelected = (Len(FormName) > 0) + + Me.sfrFilterControls.Enabled = FormSelected + Me.cbxApplyFilterCtl.Enabled = FormSelected + Me.cbxRemoveFilterCtl.Enabled = FormSelected + Me.cbxAutoFilterCtl.Enabled = FormSelected + + Me.ApplyFilterMethodOptions.Enabled = FormSelected + With Me.cbxApplyFilterSubForm + .Enabled = FormSelected And (Me.ApplyFilterMethodOptions = SubFormApplyFilterOption) + .Value = Null + End With + + With Me.FormCodeOptions + .Enabled = FormSelected + Me.cbUseFilterControlTagConverter.Enabled = FormSelected And (.Value = 1) + End With + + If Not FormSelected Then + Me.cbxFormName.RowSource = vbNullString + Me.sfrFilterControls.Form.InitFilterForm Nothing + Me.cbxApplyFilterSubForm.RowSource = vbNullString + Exit Sub + End If + + Set FormRef = GetFilterFormRef + + LoadControlsFromForm FormRef + +End Sub + +Private Sub RefreshAddFilterButtonEnableMode() + + Dim EnableBtn As Boolean + + EnableBtn = (Len(Nz(Me.cbxFormName.Value, vbNullString)) > 0) + + If EnableBtn Then + If Me.ApplyFilterMethodOptions.Value = 2 Then + EnableBtn = (Len(Nz(Me.cbxApplyFilterSubForm.Value, vbNullString)) > 0) + End If + End If + + Me.cmdAddFilterCodeToForm.Enabled = EnableBtn + +End Sub + +Private Function GetFilterFormRef() As Form + + Dim FormName As String + + FormName = Nz(Me.cbxFormName.Value, vbNullString) + If Len(FormName) = 0 Then + Set GetFilterFormRef = Nothing + Exit Function + End If + + OpenFormIfClosed FormName + Set GetFilterFormRef = Application.Forms(FormName) + +End Function + +Private Sub OpenFormIfClosed(ByVal FormName As String) + If Not CurrentProject.AllForms(FormName).IsLoaded Then + DoCmd.OpenForm FormName, acDesign, , , , acHidden + End If +End Sub + +Private Sub cbxFormName_GotFocus() + LoadForms +End Sub + +Private Sub LoadForms() + Me.cbxFormName.RowSource = "Select Name FROM [" & SourceDb.Name & "].MSysObjects where Type = -32768 Order By Name" +End Sub + +Private Sub cbxLangCode_AfterUpdate() + With Me.cbxLangCode + If IsNull(.Value) Then + .Value = "EN" + End If + L10n.LangCode = .Value + End With +End Sub + +Private Sub cbxApplyFilterSubForm_AfterUpdate() + SetFillFilterControlsFromDataSourceMode + RefreshAddFilterButtonEnableMode +End Sub + +Private Sub cbxApplyFilterSubForm_GotFocus() + RefreshSubFormList +End Sub + +Private Sub RefreshSubFormList() + + Dim frm As Form + Dim ctl As Control + + Me.cbxApplyFilterSubForm.RowSource = vbNullString + + Set frm = GetFilterFormRef + If frm Is Nothing Then + Exit Sub + End If + + For Each ctl In frm.Controls + Select Case ctl.ControlType + Case AcControlType.acSubform + Me.cbxApplyFilterSubForm.AddItem ctl.Name + End Select + Next + +End Sub + +Private Sub AddFilterCodeToForm(ByVal ImporterRef As IFilterFormCodeBuilder) + + Dim FormName As String + Dim ApplyFilterCtlName As String + Dim RemoveFilterCtlName As String + Dim AutoFilterCtlName As String + Dim FilterControlTagConverterMode As Long + + FormName = Nz(Me.cbxFormName.Value, vbNullString) + If Len(FormName) = 0 Then + MsgBox "Bitte zuerst Formular auswählen!", , CurrentApplication.ApplicationName + Exit Sub + End If + + ApplyFilterCtlName = Nz(Me.cbxApplyFilterCtl.Value, vbNullString) + RemoveFilterCtlName = Nz(Me.cbxRemoveFilterCtl.Value, vbNullString) + AutoFilterCtlName = Nz(Me.cbxAutoFilterCtl.Value, vbNullString) + + AddChangeFilterControlsToForm FormName, ApplyFilterCtlName, RemoveFilterCtlName, AutoFilterCtlName + + If Me.FormCodeOptions.Value = 1 Then + FilterControlTagConverterMode = Abs(Nz(Me.cbUseFilterControlTagConverter.Value, 0)) + Else + FilterControlTagConverterMode = 0 + End If + + With New FilterFormCodeImporter + + Set .Importer = ImporterRef + + If AddControlsToImporter(.Self, FormName, FilterControlTagConverterMode <> 0) Then ' New Controls added to Header + If FilterControlTagConverterMode = 1 Then + FilterControlTagConverterMode = 2 'use Me.Section(acHeader).Controls + End If + End If + + .WriteToForm FormName, _ + Nz(Me.ApplyFilterMethodOptions.Value, 0), _ + Nz(Me.cbxApplyFilterSubForm.Value, vbNullString), _ + Nz(Me.cbxSqlLang.Column(1), vbNullString), _ + Nz(Me.cbxSqlLang.Column(2), vbNullString), _ + Nz(Me.cbxSqlLang.Column(3), vbNullString), _ + GetCheckedControlName(ApplyFilterCtlName), _ + GetCheckedControlName(RemoveFilterCtlName), _ + GetCheckedControlName(AutoFilterCtlName), _ + FilterControlTagConverterMode + + End With + + CheckModules + + Me.SetFocus + +End Sub + +Private Property Get FilterFormWizardText_CreateNew() As String + FilterFormWizardText_CreateNew = L10n.Text(FILTERFORMWIZARD_TEXT_CREATENEW) +End Property + + +Private Sub AddChangeFilterControlsToForm(ByVal FilterFormName As String, ByRef ApplyFilterCtlName As String, ByRef RemoveFilterCtlName As String, ByRef AutoFilterCtlName As String) + + Dim SaveForm As Boolean + + If ApplyFilterCtlName = FilterFormWizardText_CreateNew Then + ApplyFilterCtlName = "cmdApplyFilter" + AddChangeFilterControlToForm FilterFormName, ApplyFilterCtlName, acCommandButton, L10n.Text("Filter anwenden") + SaveForm = True + End If + + If RemoveFilterCtlName = FilterFormWizardText_CreateNew Then + RemoveFilterCtlName = "cmdRemoveFilter" + AddChangeFilterControlToForm FilterFormName, RemoveFilterCtlName, acCommandButton, L10n.Text("Filter löschen") + SaveForm = True + End If + + If AutoFilterCtlName = FilterFormWizardText_CreateNew Then + AutoFilterCtlName = "cbAutoFilter" + AddChangeFilterControlToForm FilterFormName, AutoFilterCtlName, acCheckBox, L10n.Text("Autofilter"), True + SaveForm = True + End If + + If SaveForm Then + DoCmd.Save acForm, FilterFormName + End If + +End Sub + +Private Sub AddChangeFilterControlToForm(ByVal FilterFormName As String, _ + ByRef ControlName As String, _ + ByVal ControlType As AcControlType, _ + ByVal ControlCaption As String, _ + Optional ByVal DefaultValue As Variant) + + Const DistanceBetweenControls As Long = 72 + + Dim InsertLabelControl As Boolean + + Select Case ControlType + Case AcControlType.acCommandButton, AcControlType.acOptionButton, AcControlType.acLabel + InsertLabelControl = False + Case Else + InsertLabelControl = True + End Select + + With New FormDesigner + .FormName = FilterFormName + With .AddControl(ControlType, ControlName, acHeader, , , , , DistanceBetweenControls, InsertLabelControl, ControlCaption) + If Not InsertLabelControl Then + .Caption = ControlCaption + End If + ControlName = .Name + If Not IsMissing(DefaultValue) Then + .DefaultValue = DefaultValue + End If + End With + End With + +End Sub + +Private Function AddControlsToImporter(ByVal Importer As FilterFormCodeImporter, ByVal FilterFormName As String, ByVal UseFilterDefinitionInTagProperty As Boolean) As Boolean + AddControlsToImporter = Me.sfrFilterControls.Form.AddControlsToImporter(Importer, FilterFormName, UseFilterDefinitionInTagProperty) +End Function + +Private Sub cmdAddFilterCodeToForm_Click() + + Select Case Me.FormCodeOptions.Value + Case 1 + AddFilterCodeToForm New FilterControlManagerCodeBuilder + Case 2 + AddFilterCodeToForm New FilterStringBuilderCodeBuilder + End Select + +End Sub + +Private Sub cmdFillFilterControlsFromDataSource_Click() + + Dim FilterFormName As String + Dim SubFormName As String + + FilterFormName = Nz(Me.cbxFormName.Value, vbNullString) + If Len(FilterFormName) = 0 Then Exit Sub + + Select Case Me.ApplyFilterMethodOptions.Value + Case 1 + ' keine weiteren Anpassungen + Case 2 + SubFormName = Nz(Me.cbxApplyFilterSubForm.Value, vbNullString) + If Len(SubFormName) = 0 Then Exit Sub + Case Else + Exit Sub + End Select + + If Not CurrentProject.AllForms(FilterFormName).IsLoaded Then + DoCmd.OpenForm FilterFormName, acDesign, , , , acWindowNormal + End If + + With Application.Forms(FilterFormName) + Select Case Me.ApplyFilterMethodOptions.Value + Case 1 + FillFilterControlsFromDataSource .RecordSource + Case 2 + FillFilterControlsFromDataSource .Controls(SubFormName).Form.RecordSource + End Select + + End With + +End Sub + +Private Sub FillFilterControlsFromDataSource(ByVal DataSource As String) + + Dim fld As DAO.Field + + If Len(DataSource) = 0 Then + MsgBox "Es ist keine Datenquelle eingestellt!", vbExclamation, "Filter aus Datenfelder erzeugen" + Exit Sub + End If + + With CurrentDb.OpenRecordset(DataSource) + For Each fld In .Fields + AddFilterControlFromDataField fld + Next + .Close + End With + +End Sub + +Private Sub AddFilterControlFromDataField(ByVal DataField As DAO.Field) + Me.sfrFilterControls.Form.InsertFilterRecord DataField.Name, DataField.Type +End Sub + +Private Sub Form_Current() + CheckModules True, True +End Sub + +Private Sub OpenReplaceModulesContextMenu(ByRef MenuControlRef As Control, ByVal X As Single, ByVal Y As Single) + + Dim mnu As WinApiShortcutMenu + Dim SelectedMenuItem As Long + + Set mnu = New WinApiShortcutMenu + + With mnu + .ControlSection = acDetail + Set .AccessForm = Me + Set .MenuControl = MenuControlRef + + .AddMenuItem 3, L10n.Text("Update code modules in the add-in from the SCC repository (master).") + .AddMenuItem 4, L10n.Text("Update code modules in the add-in from the SCC repository (draft).") + .AddMenuItem 0, "", MF_SEPARATOR + .AddMenuItem 1, L10n.Text("Replace all code modules (existing modules are overwritten)") + .AddMenuItem 2, L10n.Text("Replace all code modules except 'SqlTools' (SqlTools remains unchanged)") + + End With + + SelectedMenuItem = mnu.OpenMenu(X, Y) + Select Case SelectedMenuItem + Case 1 + ReplaceAllModules True + Case 2 + ReplaceAllModules False + Case 3 + RefreshCodeModulesFromSccRepo False + Case 4 + RefreshCodeModulesFromSccRepo True + Case Else + ' + End Select + + Set mnu = Nothing + +End Sub + +Private Sub ReplaceAllModules(Optional ByVal WithSqlTools As Boolean = False) + + Dim ModulesReplaced As Boolean + +On Error Resume Next + + With CodeModulImporter + If WithSqlTools Then + ModulesReplaced = .ReplaceCodeModules("SqlTools", "StringCollection", "FilterStringBuilder", "FilterControlEventBridge", "FilterControl", "FilterControlCollection", "FilterControlManager", "FilterControlTagConverter") + Else + ModulesReplaced = .ReplaceCodeModules("StringCollection", "FilterStringBuilder", "FilterControlEventBridge", "FilterControl", "FilterControlCollection", "FilterControlManager", "FilterControlTagConverter") + End If + End With + + If ModulesReplaced Then + + SetModulCopyControls "CopyModulSqlTools", True + SetModulCopyControls "CopyModulFilterStringBuilder", True + SetModulCopyControls "CopyModulFilterControlManager", True + SetModulCopyControls "CopyModules", True + + If m_OpenModules = 0 Then + MsgBox "Codemodule wurden aktualisiert.", , CurrentApplication.ApplicationName + End If + + m_OpenModules = 0 + + End If + +End Sub + +Private Sub Form_Open(ByRef Cancel As Integer) + Me.cbxLangCode.Value = L10n.LangCode + L10n.TranslateControls Me.Controls + Set m_L10nDict = L10n + SetFormCaption +End Sub + +Private Sub SetFormCaption() + Me.Caption = "ACLib FilterForm Wizard " & ChrW(&H25AA) & " Version " & CurrentApplication.Version & " (" & L10n.Text("Filter Classes") & ": SCC-Rev. " & SccRev & ")" +End Sub + +Private Sub FormCodeOptions_AfterUpdate() + + With Me.cbUseFilterControlTagConverter + .Enabled = (Me.FormCodeOptions.Value = 1) + If Not .Enabled Then + .Value = False + End If + End With + +End Sub + +Private Sub labCheckVersion_Click() + + Select Case L10n.ControlTag(Me.labCheckVersion.Tag) + Case "unchecked" + SetNewVersionInfo + Case "NewVersionExists" + OpenDownloadSource + Case Else + ' + End Select + +End Sub + +Private Sub labCheckVersion_MouseMove(ByRef Button As Integer, ByRef Shift As Integer, ByRef X As Single, ByRef Y As Single) + If L10n.ControlTag(Me.labCheckVersion.Tag) <> "VersionUptodate" Then + modWinApi_Mouse.MouseCursor IDC_HAND + End If +End Sub + +Private Sub labCopyCaption_MouseDown(ByRef Button As Integer, ByRef Shift As Integer, ByRef X As Single, ByRef Y As Single) + + If Button = 1 Or Button = 2 Then + OpenReplaceModulesContextMenu Me.labCopyCaption, X, Y + End If + +End Sub + +Private Sub CheckModules(Optional ByVal WithControlManager As Boolean = True, Optional ByVal WithTagConverter As Boolean = False) + + Dim CheckOk As Boolean + +On Error Resume Next + + m_OpenModules = 0 + + With CodeModulImporter + CheckOk = .CheckCodeModules("SqlTools") + m_OpenModules = m_OpenModules + 1 + CheckOk + SetModulCopyControls "CopyModulSqlTools", CheckOk + + CheckOk = .CheckCodeModules("StringCollection", "FilterStringBuilder") + m_OpenModules = m_OpenModules + 1 + CheckOk + SetModulCopyControls "CopyModulFilterStringBuilder", CheckOk + + If WithControlManager Then + CheckOk = .CheckCodeModules("FilterControlEventBridge", "FilterControl", "FilterControlCollection", "FilterControlManager") + m_OpenModules = m_OpenModules + 1 + CheckOk + SetModulCopyControls "CopyModulFilterControlManager", CheckOk + + If WithTagConverter Then + CheckOk = .CheckCodeModules("FilterControlTagConverter") + m_OpenModules = m_OpenModules + 1 + CheckOk + SetModulCopyControls "CopyModulFilterControlTagConverter", CheckOk + End If + + End If + + CheckOk = (m_OpenModules = 0) + SetModulCopyControls "CopyModules", CheckOk + End With + +End Sub + +Private Sub cmdCopyModulSqlTools_Click() + + CodeModulImporter.TransferCodeModules "SqlTools" + m_OpenModules = m_OpenModules - 1 + SetModulCopyControls "CopyModulSqlTools", True + +End Sub + +Private Sub cmdCopyModulFilterControlManager_Click() + + With CodeModulImporter + .TransferCodeModules "FilterControlEventBridge", "FilterControl", "FilterControlCollection", "FilterControlManager" + m_OpenModules = m_OpenModules - 1 + If Not .CheckCodeModules("StringCollection", "FilterStringBuilder") Then + cmdCopyModulFilterStringBuilder_Click + End If + SetModulCopyControls "CopyModulFilterControlManager", True + End With + +End Sub + +Private Sub cmdCopyModulFilterControlTagConverter_Click() + + With CodeModulImporter + .TransferCodeModules "FilterControlTagConverter" + m_OpenModules = m_OpenModules - 1 + If Not .CheckCodeModules("FilterControlEventBridge", "FilterControl", "FilterControlCollection", "FilterControlManager") Then + cmdCopyModulFilterControlManager_Click + End If + SetModulCopyControls "CopyModulFilterControlTagConverter", True + End With + +End Sub + +Private Sub cmdCopyModulFilterStringBuilder_Click() + + With CodeModulImporter + .TransferCodeModules "StringCollection", "FilterStringBuilder" + m_OpenModules = m_OpenModules - 1 + If Not .CheckCodeModules("SqlTools") Then + cmdCopyModulSqlTools_Click + End If + SetModulCopyControls "CopyModulFilterStringBuilder", True + End With + +End Sub + +Private Sub cmdCopyModules_Click() + + CodeModulImporter.TransferCodeModules "SqlTools", "StringCollection", "FilterStringBuilder", "FilterControlEventBridge", "FilterControl", "FilterControlCollection", "FilterControlManager", "FilterControlTagConverter" + SetModulCopyControls "CopyModulSqlTools", True + SetModulCopyControls "CopyModulFilterStringBuilder", True + SetModulCopyControls "CopyModulFilterControlManager", True + SetModulCopyControls "CopyModulFilterControlTagConverter", True + SetModulCopyControls "CopyModules", True + m_OpenModules = 0 + +End Sub + +Private Sub SetModulCopyControls(ByVal ModulCodeName As String, ByVal Exists As Boolean) + + Dim ModuleCodeCaption As String + Dim BorderStyle As Long + +On Error Resume Next + + If Exists Then Me.sysFirst.SetFocus + Me.Controls("cmd" & ModulCodeName).Enabled = Not Exists + If Exists Then + ModuleCodeCaption = "b" + BorderStyle = 0 + Else + ModuleCodeCaption = vbNullString + BorderStyle = 1 + End If + With Me.Controls("lab" & ModulCodeName) + .Caption = ModuleCodeCaption + .BorderStyle = BorderStyle + End With + + If ModulCodeName <> "CopyModules" And m_OpenModules = 0 Then + SetModulCopyControls "CopyModules", True + End If + +End Sub + +Private Sub labCopyCaption_MouseMove(ByRef Button As Integer, ByRef Shift As Integer, ByRef X As Single, ByRef Y As Single) + modWinApi_Mouse.MouseCursor IDC_HAND +End Sub + +Private Sub m_L10nDict_LanguageChanged() + If Nz(Me.cbxLangCode.Value, vbNullString) <> L10n.LangCode Then + Me.cbxLangCode.Value = L10n.LangCode + End If + SetFormCaption + L10n.TranslateControls Me.Controls + + If Len(Me.cbxFormName.Value) > 0 Then + LoadControlsFromForm GetFilterFormRef + End If +End Sub + +Private Sub ApplyFilterMethodOptions_AfterUpdate() + + With Me.cbxApplyFilterSubForm + .Enabled = (Me.ApplyFilterMethodOptions = SubFormApplyFilterOption) + If .Enabled = False Then .Value = Null + End With + + SetFillFilterControlsFromDataSourceMode + + RefreshAddFilterButtonEnableMode + +End Sub + +Private Sub SetFillFilterControlsFromDataSourceMode() + + With Me.cmdFillFilterControlsFromDataSource + Select Case Me.ApplyFilterMethodOptions + Case 1 + .Enabled = True + Case 2 + .Enabled = (Len(Nz(Me.cbxApplyFilterSubForm.Value, vbNullString)) > 0) + Case Else + .Enabled = False + End Select + + If .Enabled Then + .ControlTipText = vbNullString + Else + .ControlTipText = L10n.Text("Please set the data form in the 'ApplyFilter method' option first!") + End If + End With + +End Sub + +Private Sub LoadControlsFromForm(ByVal FormRef As Form) + + Dim ctl As Control + + ClearFilterCtlCombobox Me.cbxApplyFilterCtl + ClearFilterCtlCombobox Me.cbxRemoveFilterCtl + ClearFilterCtlCombobox Me.cbxAutoFilterCtl + + If FormRef Is Nothing Then + Exit Sub + End If + + Me.cbxApplyFilterCtl.AddItem FilterFormWizardText_CreateNew + Me.cbxRemoveFilterCtl.AddItem FilterFormWizardText_CreateNew + Me.cbxAutoFilterCtl.AddItem FilterFormWizardText_CreateNew + + For Each ctl In FormRef.Controls + Select Case ctl.ControlType + Case AcControlType.acCommandButton + + Me.cbxApplyFilterCtl.AddItem ctl.Name + Me.cbxRemoveFilterCtl.AddItem ctl.Name + + Case AcControlType.acCheckBox, AcControlType.acToggleButton + + Me.cbxAutoFilterCtl.AddItem ctl.Name + + End Select + Next + + Me.sfrFilterControls.Form.InitFilterForm FormRef + +End Sub + +Private Sub ClearFilterCtlCombobox(ByVal CbxRef As ComboBox) + With CbxRef + .RowSource = vbNullString + .Value = Null + End With +End Sub + +Private Sub SetNewVersionInfo() + + Dim AhProcParams(1) As Variant + Dim AhResumeMode As ApplicationHandlerResumeModes + Dim AhResumeMessage As Variant + + Call CurrentApplication.CallExtensionProcedure("AppVersion", "NewVersionExists", AhResumeMode, AhResumeMessage, AhProcParams) + + If AhResumeMode <> AppResumeMode_Completed Then + If AhResumeMode = AppResumeMode_Error Then + If Len(AhResumeMessage) > 0 Then + MsgBox AhResumeMessage, vbExclamation, "Error during version check" + End If + End If + Exit Sub + End If + + With Me.labCheckVersion + If AhResumeMessage = False Then + .Caption = L10n.Text("Current version is installed") + .Tag = "VersionUptodate" '& L10n.LangSeparatorChar '& "LANG:Wizard-Version prüfen" + .ForeColor = 0 + .FontUnderline = False + ElseIf AhResumeMessage = True Then + .Caption = FormatText("Neue Version ({0}) verfügbar", AhProcParams(0)) + .ControlTipText = AhProcParams(1) + .Tag = "NewVersionExists" '& L10n.LangSeparatorChar & "LANG:Wizard-Version prüfen" + Else + + End If + End With + +End Sub + +Private Sub OpenDownloadSource() + Application.FollowHyperlink APPLICATION_DOWNLOADSOURCE, , True, False +End Sub + +Private Function GetCheckedControlName(ByVal ControlNameToCheck As String) As String + GetCheckedControlName = Replace(ControlNameToCheck, " ", "_") +End Function + +Private Sub RefreshCodeModulesFromSccRepo(ByVal UseDraft As Boolean) + + With New ACLibGitHubImporter + + If UseDraft Then + .BranchName = "draft" + End If + + If .RevisionString(True) = SccRevMin Then + If MsgBox("All modules are already up to date." & vbNewLine & "Still re-insert?", vbYesNo + vbDefaultButton2, CurrentApplication.ApplicationName) <> vbYes Then + Exit Sub + End If + End If + + .UpdateCodeModules + + End With + + MsgBox "Code has been updated", , CurrentApplication.ApplicationName + + SetFormCaption + +End Sub diff --git a/source/forms/frmFilterFormWizard.json b/source/forms/frmFilterFormWizard.json new file mode 100644 index 0000000..4cdda2e --- /dev/null +++ b/source/forms/frmFilterFormWizard.json @@ -0,0 +1,28 @@ +{ + "Info": { + "Class": "clsDbForm", + "Description": "frmFilterFormWizard Print Settings" + }, + "Items": { + "Printer": { + "Orientation": "Portrait", + "PaperSize": "A4" + }, + "Margins": { + "LeftMargin": 1.0097, + "TopMargin": 1.0097, + "RightMargin": 1.0097, + "BotMargin": 1.0097, + "DataOnly": false, + "Width": 5, + "Height": 3, + "DefaultSize": true, + "Columns": 1, + "ColumnSpacing": 0.25, + "RowSpacing": 0, + "ItemLayout": "Horizontal Columns", + "FastPrint": 1, + "Datasheet": 1 + } + } +} diff --git a/source/forms/frmFilterFormWizard_SF_Controls.bas b/source/forms/frmFilterFormWizard_SF_Controls.bas new file mode 100644 index 0000000..0ea8dfe --- /dev/null +++ b/source/forms/frmFilterFormWizard_SF_Controls.bas @@ -0,0 +1,577 @@ +Version =20 +VersionRequired =20 +Begin Form + NavigationButtons = NotDefault + AllowDesignChanges = NotDefault + ScrollBars =2 + PictureAlignment =2 + DatasheetGridlinesBehavior =3 + GridY =10 + Width =10050 + DatasheetFontHeight =11 + ItemSuffix =33 + Left =3300 + Top =3443 + Right =13635 + Bottom =6428 + RecSrcDt = Begin + 0xc4d680b8ef58e440 + End + RecordSource ="tabFilterControls" + OnCurrent ="[Event Procedure]" + DatasheetFontName ="Calibri" + OnLoad ="[Event Procedure]" + FilterOnLoad =0 + OrderByOnLoad =0 + OrderByOnLoad =0 + DatasheetBackColor12 =-2147483643 + ShowPageMargins =0 + DatasheetAlternateBackColor =16053492 + DatasheetGridlinesColor12 =15062992 + FitToScreen =1 + Begin + Begin Label + BackStyle =0 + FontSize =11 + FontName ="Calibri" + ThemeFontIndex =1 + BackThemeColorIndex =1 + BorderThemeColorIndex =1 + ForeThemeColorIndex =2 + ForeTint =60.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + End + Begin CommandButton + Width =1701 + Height =283 + FontSize =11 + FontWeight =400 + FontName ="Calibri" + ForeThemeColorIndex =2 + ForeShade =50.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + BackColor =-2147483633 + BorderLineStyle =0 + BorderThemeColorIndex =3 + BorderShade =90.0 + ThemeFontIndex =1 + End + Begin OptionButton + BorderLineStyle =0 + LabelX =230 + LabelY =-30 + BorderThemeColorIndex =3 + BorderShade =90.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + End + Begin CheckBox + BorderLineStyle =0 + LabelX =230 + LabelY =-30 + BorderThemeColorIndex =3 + BorderShade =90.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + End + Begin OptionGroup + SpecialEffect =3 + BorderLineStyle =0 + Width =1701 + Height =1701 + BorderThemeColorIndex =3 + BorderShade =90.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + End + Begin TextBox + FELineBreak = NotDefault + BorderLineStyle =0 + Width =1701 + LabelX =-1701 + FontSize =11 + FontName ="Calibri" + AsianLineBreak =1 + BackThemeColorIndex =1 + BorderThemeColorIndex =3 + BorderShade =90.0 + ThemeFontIndex =1 + ForeThemeColorIndex =2 + ForeShade =50.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + End + Begin ComboBox + BorderLineStyle =0 + Width =1701 + LabelX =-1701 + FontSize =11 + FontName ="Calibri" + AllowValueListEdits =1 + InheritValueList =1 + ThemeFontIndex =1 + BackThemeColorIndex =1 + BorderThemeColorIndex =3 + BorderShade =90.0 + ForeThemeColorIndex =2 + ForeShade =50.0 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + End + Begin FormHeader + Height =285 + Name ="Formularkopf" + AlternateBackThemeColorIndex =1 + AlternateBackShade =95.0 + BackThemeColorIndex =2 + BackTint =20.0 + Begin + Begin Label + OverlapFlags =85 + Left =5831 + Width =2040 + Height =285 + FontSize =10 + Name ="labControl" + Caption ="Control" + FontName ="Tahoma" + Tag ="LANG:" + LayoutCachedLeft =5831 + LayoutCachedWidth =7871 + LayoutCachedHeight =285 + ThemeFontIndex =-1 + End + Begin Label + OverlapFlags =85 + Left =56 + Width =2157 + Height =285 + FontSize =10 + Name ="labDataField" + Caption ="Data field" + FontName ="Tahoma" + Tag ="LANG:" + LayoutCachedLeft =56 + LayoutCachedWidth =2213 + LayoutCachedHeight =285 + ThemeFontIndex =-1 + End + Begin Label + OverlapFlags =85 + Left =3746 + Width =1815 + Height =285 + FontSize =10 + Name ="labRelaionalOperator" + Caption ="Relational operator" + FontName ="Tahoma" + Tag ="LANG:" + LayoutCachedLeft =3746 + LayoutCachedWidth =5561 + LayoutCachedHeight =285 + ThemeFontIndex =-1 + End + Begin Label + OverlapFlags =85 + Left =2268 + Width =1380 + Height =285 + FontSize =10 + Name ="labDataType" + Caption ="Data type" + FontName ="Tahoma" + Tag ="LANG:" + LayoutCachedLeft =2268 + LayoutCachedWidth =3648 + LayoutCachedHeight =285 + ThemeFontIndex =-1 + End + Begin Label + OverlapFlags =85 + Left =7875 + Width =2175 + Height =285 + FontSize =10 + Name ="labControl2" + Caption ="Other controls" + FontName ="Tahoma" + Tag ="LANG:" + LayoutCachedLeft =7875 + LayoutCachedWidth =10050 + LayoutCachedHeight =285 + ThemeFontIndex =-1 + End + End + End + Begin Section + Height =642 + Name ="Detailbereich" + AlternateBackThemeColorIndex =1 + AlternateBackShade =97.0 + BackThemeColorIndex =1 + Begin + Begin ComboBox + RowSourceTypeInt =1 + OverlapFlags =85 + IMESentenceMode =3 + ListWidth =3402 + Left =5831 + Top =29 + Width =2041 + Height =285 + FontSize =10 + TabIndex =3 + ConditionalFormat = Begin + 0x0100000090000000010000000100000000000000000000001700000000000000 , + 0x00000000ffffff00000000000000000000000000000000000000000000000000 , + 0x0000000000000000000000000000000000000000000000000000000000000000 , + 0x5b006300620043007200650061007400650043006f006e00740072006f006c00 , + 0x5d003d00540072007500650000000000 + End + Name ="fcControl" + ControlSource ="Control" + RowSourceType ="Value List" + ColumnWidths ="3402" + FontName ="Tahoma" + AllowValueListEdits =0 + + LayoutCachedLeft =5831 + LayoutCachedTop =29 + LayoutCachedWidth =7872 + LayoutCachedHeight =314 + ThemeFontIndex =-1 + ConditionalFormat14 = Begin + 0x01000100000001000000000000000000000000000000ffffff00160000005b00 , + 0x6300620043007200650061007400650043006f006e00740072006f006c005d00 , + 0x3d005400720075006500000000000000000000000000000000000000000000 + End + End + Begin ComboBox + LimitToList = NotDefault + OverlapFlags =85 + IMESentenceMode =3 + ColumnCount =2 + Left =3746 + Top =29 + Width =1803 + Height =285 + FontSize =10 + TabIndex =2 + BoundColumn =1 + Name ="fcRelationalOperator" + ControlSource ="RelationalOperator" + RowSourceType ="Table/Query" + RowSource ="SELECT tabRelationalOperators.RelationalOperator, tabRelationalOperators.Relatio" + "nalOperatorCode FROM tabRelationalOperators ORDER BY tabRelationalOperators.Orde" + "rPos;" + ColumnWidths ="1134;0" + FontName ="Tahoma" + AllowValueListEdits =0 + + LayoutCachedLeft =3746 + LayoutCachedTop =29 + LayoutCachedWidth =5549 + LayoutCachedHeight =314 + ThemeFontIndex =-1 + End + Begin ComboBox + OverlapFlags =85 + IMESentenceMode =3 + ColumnCount =2 + Left =2268 + Top =29 + Width =1353 + Height =285 + FontSize =10 + TabIndex =1 + BoundColumn =1 + Name ="fcDataType" + ControlSource ="DataType" + RowSourceType ="Table/Query" + RowSource ="SELECT tabSqlFieldDataTypes.SqlFieldDataType, tabSqlFieldDataTypes.SqlFieldDataT" + "ypeCode FROM tabSqlFieldDataTypes ORDER BY tabSqlFieldDataTypes.SqlFieldDataType" + ";" + ColumnWidths ="1134;0" + FontName ="Tahoma" + AllowValueListEdits =0 + + LayoutCachedLeft =2268 + LayoutCachedTop =29 + LayoutCachedWidth =3621 + LayoutCachedHeight =314 + ThemeFontIndex =-1 + End + Begin CheckBox + OverlapFlags =85 + Left =5465 + Top =390 + TabIndex =7 + Name ="fcRelationalOperatorNot" + ControlSource ="RelationalOperatorNot" + DefaultValue ="False" + + LayoutCachedLeft =5465 + LayoutCachedTop =390 + LayoutCachedWidth =5725 + LayoutCachedHeight =630 + Begin + Begin Label + OverlapFlags =127 + Left =5135 + Top =360 + Width =330 + Height =240 + FontSize =8 + Name ="labRelationalOperatorNot" + Caption ="Not" + FontName ="Tahoma" + LayoutCachedLeft =5135 + LayoutCachedTop =360 + LayoutCachedWidth =5465 + LayoutCachedHeight =600 + ThemeFontIndex =-1 + End + End + End + Begin CheckBox + OverlapFlags =85 + Left =4181 + Top =390 + TabIndex =5 + Name ="fcWildCardSuffix" + ControlSource ="WildCardSuffix" + DefaultValue ="False" + + LayoutCachedLeft =4181 + LayoutCachedTop =390 + LayoutCachedWidth =4441 + LayoutCachedHeight =630 + Begin + Begin Label + OverlapFlags =119 + Left =3746 + Top =360 + Width =435 + Height =240 + FontSize =8 + Name ="labWildCardSuffix" + Caption ="xxx*" + FontName ="Tahoma" + LayoutCachedLeft =3746 + LayoutCachedTop =360 + LayoutCachedWidth =4181 + LayoutCachedHeight =600 + ThemeFontIndex =-1 + End + End + End + Begin CheckBox + OverlapFlags =247 + Left =4886 + Top =390 + TabIndex =6 + Name ="fcWildCardPrefix" + ControlSource ="WildCardPrefix" + DefaultValue ="False" + + LayoutCachedLeft =4886 + LayoutCachedTop =390 + LayoutCachedWidth =5146 + LayoutCachedHeight =630 + Begin + Begin Label + OverlapFlags =119 + Left =4451 + Top =360 + Width =435 + Height =240 + FontSize =8 + Name ="labWildCardPrefix" + Caption ="*xxx" + FontName ="Tahoma" + LayoutCachedLeft =4451 + LayoutCachedTop =360 + LayoutCachedWidth =4886 + LayoutCachedHeight =600 + ThemeFontIndex =-1 + End + End + End + Begin TextBox + OverlapFlags =85 + IMESentenceMode =3 + Left =56 + Top =29 + Width =2160 + Height =285 + FontSize =10 + Name ="fcDataField" + ControlSource ="DataField" + FontName ="Tahoma" + + LayoutCachedLeft =56 + LayoutCachedTop =29 + LayoutCachedWidth =2216 + LayoutCachedHeight =314 + ThemeFontIndex =-1 + End + Begin TextBox + OverlapFlags =85 + IMESentenceMode =3 + Left =7938 + Top =29 + Width =2056 + Height =285 + FontSize =10 + TabIndex =4 + Name ="fcControl2" + ControlSource ="Control2" + StatusBarText ="Mehrere Steuerelemente mit Komma trennen" + FontName ="Tahoma" + ConditionalFormat = Begin + 0x0100000090000000010000000100000000000000000000001700000000000000 , + 0x00000000ffffff00000000000000000000000000000000000000000000000000 , + 0x0000000000000000000000000000000000000000000000000000000000000000 , + 0x5b006300620043007200650061007400650043006f006e00740072006f006c00 , + 0x5d003d00540072007500650000000000 + End + HorizontalAnchor =2 + + LayoutCachedLeft =7938 + LayoutCachedTop =29 + LayoutCachedWidth =9994 + LayoutCachedHeight =314 + ThemeFontIndex =-1 + ConditionalFormat14 = Begin + 0x01000100000001000000000000000000000000000000ffffff00160000005b00 , + 0x6300620043007200650061007400650043006f006e00740072006f006c005d00 , + 0x3d005400720075006500000000000000000000000000000000000000000000 + End + End + Begin CheckBox + OverlapFlags =93 + Left =6222 + Top =390 + TabIndex =8 + Name ="cbCreateControl" + ControlSource ="CreateControl" + AfterUpdate ="[Event Procedure]" + DefaultValue ="False" + + LayoutCachedLeft =6222 + LayoutCachedTop =390 + LayoutCachedWidth =6482 + LayoutCachedHeight =630 + Begin + Begin Label + OverlapFlags =255 + Left =5831 + Top =360 + Width =414 + Height =240 + FontSize =8 + Name ="labCreateControl" + Caption ="New" + FontName ="Tahoma" + Tag ="LANG:" + LayoutCachedLeft =5831 + LayoutCachedTop =360 + LayoutCachedWidth =6245 + LayoutCachedHeight =600 + ThemeFontIndex =-1 + ForeThemeColorIndex =0 + ForeTint =100.0 + End + End + End + Begin OptionGroup + TabStop = NotDefault + SpecialEffect =0 + OldBorderStyle =0 + OverlapFlags =247 + Left =5839 + Top =336 + Width =4137 + Height =300 + TabIndex =9 + Name ="ogNewControlType" + ControlSource ="ControlType" + OnEnter ="[Event Procedure]" + + LayoutCachedLeft =5839 + LayoutCachedTop =336 + LayoutCachedWidth =9976 + LayoutCachedHeight =636 + Begin + Begin OptionButton + OverlapFlags =119 + Left =6689 + Top =396 + OptionValue =109 + Name ="ogfldTextbox" + + LayoutCachedLeft =6689 + LayoutCachedTop =396 + LayoutCachedWidth =6949 + LayoutCachedHeight =636 + Begin + Begin Label + OverlapFlags =247 + Left =6919 + Top =336 + Width =876 + Height =300 + Name ="labCreateTextbox" + Caption ="TextBox" + LayoutCachedLeft =6919 + LayoutCachedTop =336 + LayoutCachedWidth =7795 + LayoutCachedHeight =636 + End + End + End + Begin OptionButton + OverlapFlags =119 + Left =7992 + Top =396 + TabIndex =1 + OptionValue =111 + Name ="ogfldCombobox" + + LayoutCachedLeft =7992 + LayoutCachedTop =396 + LayoutCachedWidth =8252 + LayoutCachedHeight =636 + Begin + Begin Label + OverlapFlags =247 + Left =8219 + Top =336 + Width =1032 + Height =300 + Name ="labCreateCombobox" + Caption ="ComboBox" + LayoutCachedLeft =8219 + LayoutCachedTop =336 + LayoutCachedWidth =9251 + LayoutCachedHeight =636 + End + End + End + End + End + End + End + Begin FormFooter + Height =0 + Name ="Formularfuß" + AlternateBackThemeColorIndex =1 + AlternateBackShade =95.0 + BackThemeColorIndex =1 + End + End +End +CodeBehindForm +' See "frmFilterFormWizard_SF_Controls.cls" diff --git a/source/forms/frmFilterFormWizard_SF_Controls.cls b/source/forms/frmFilterFormWizard_SF_Controls.cls new file mode 100644 index 0000000..33bc2e7 --- /dev/null +++ b/source/forms/frmFilterFormWizard_SF_Controls.cls @@ -0,0 +1,358 @@ +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = True +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +'--------------------------------------------------------------------------------------- +' Form: frmFilterFormWizard_SF_Controls +'--------------------------------------------------------------------------------------- +'/** +' \author Josef Poetzl +' +' Wizard form subform for FilterControls import +' +' +'**/ +'--------------------------------------------------------------------------------------- +' +Option Compare Database +Option Explicit + +#Const ADODB_EARLYBINDING = 0 + +#If ADODB_EARLYBINDING = 1 Then + +#Else + Public Enum CursorTypeEnum + adOpenKeyset = 1 + End Enum + + Public Enum CursorLocationEnum + adUseClient = 3 + End Enum + + Public Enum LockTypeEnum + adLockOptimistic = 3 + End Enum +#End If + +Private WithEvents m_LngDict As L10nDict +Attribute m_LngDict.VB_VarHelpID = -1 + +Public Sub InitFilterForm(ByVal FrmRef As Form) + + InitDataSource + LoadControlsFromForm FrmRef + +End Sub + +Private Sub InitDataSource() + +#If ADODB_EARLYBINDING = 1 Then + Dim rst As ADODB.Recordset +#Else + Dim rst As Object +#End If + + Set rst = CreateObject("ADODB.Recordset") + rst.CursorLocation = adUseClient + rst.Open "select * from tabFilterControls", CodeProject.Connection, adOpenKeyset, adLockOptimistic + Set rst.ActiveConnection = Nothing + + Set Me.Recordset = rst + +End Sub + +Private Sub LoadControlsFromForm(ByVal FrmRef As Form) + + Dim ctl As Control + + Me.fcControl.RowSource = vbNullString + + If FrmRef Is Nothing Then + Exit Sub + End If + + For Each ctl In FrmRef.Controls + Select Case ctl.ControlType + Case AcControlType.acTextBox, AcControlType.acComboBox, _ + AcControlType.acCheckBox, AcControlType.acListBox, _ + AcControlType.acOptionButton, AcControlType.acOptionGroup, _ + AcControlType.acToggleButton + + Me.fcControl.AddItem ctl.Name + + End Select + Next + +End Sub + +Public Function AddControlsToImporter(ByVal Importer As FilterFormCodeImporter, ByVal FilterFormName As String, ByVal UseFilterDefinitionInTagProperty As Boolean) As Boolean + +#If ADODB_EARLYBINDING = 1 Then + Dim rst As ADODB.Recordset +#Else + Dim rst As Object +#End If + + Dim RelOp As String + Dim UseBetweenRelOp As Boolean + Dim FilterCtl As Control + Dim FrmDsgnr As FormDesigner + + Set rst = Me.Recordset.Clone + If rst.RecordCount = 0 Then + Exit Function + End If + + Dim DataFieldName As String + Dim ControlName As String, ControlName2 As String + + Dim SaveForm As Boolean + + If UseFilterDefinitionInTagProperty Then + Set FrmDsgnr = New FormDesigner + FrmDsgnr.FormName = FilterFormName + End If + + With rst + Do While Not .EOF + + RelOp = Nz(.Fields("RelationalOperator"), vbNullString) + UseBetweenRelOp = (RelOp = "SQL_Between") + + If UseFilterDefinitionInTagProperty Then + RelOp = GetRelationalOperatorKey(RelOp) + If .Fields("WildCardSuffix") = True Then + RelOp = RelOp & "*" + End If + If .Fields("WildCardPrefix") = True Then + RelOp = "*" & RelOp + End If + If .Fields("RelationalOperatorNot") = True Then + RelOp = "Not " & RelOp + End If + Else + If .Fields("WildCardSuffix") = True Then + RelOp = RelOp & " + SQL_Add_WildCardSuffix" + End If + If .Fields("WildCardPrefix") = True Then + RelOp = RelOp & " + SQL_Add_WildCardPrefix" + End If + If .Fields("RelationalOperatorNot") = True Then + RelOp = "SQL_Not + " & RelOp + End If + End If + + DataFieldName = Nz(.Fields("DataField").Value, vbNullString) + + If .Fields("CreateControl").Value = True Then + Set FilterCtl = InsertFormControl(FilterFormName, Nz(.Fields("ControlType").Value, acTextBox), DataFieldName, UseBetweenRelOp, ControlName, ControlName2, UseFilterDefinitionInTagProperty) + SaveForm = True + AddControlsToImporter = True + Else + ControlName = Nz(.Fields("Control").Value, vbNullString) + ControlName2 = Nz(.Fields("Control2"), vbNullString) + If UseFilterDefinitionInTagProperty Then + Set FilterCtl = FrmDsgnr.Form.Controls(ControlName) + End If + End If + + If UseFilterDefinitionInTagProperty Then + FilterCtl.Tag = GetFilterControlTag(Nz(.Fields("DataType").Value, vbNullString), RelOp, DataFieldName, ControlName2) + SaveForm = True + Else + ControlName = GetCheckedControlName(ControlName) + ControlName2 = GetCheckedControlName(ControlName2) + Importer.AddFilterControlDefinition DataFieldName, _ + Nz(.Fields("DataType"), vbNullString), _ + RelOp, _ + ControlName, _ + ControlName2 + End If + + Set FilterCtl = Nothing + ControlName = vbNullString + ControlName2 = vbNullString + .MoveNext + + Loop + End With + + If UseFilterDefinitionInTagProperty Then + Set FrmDsgnr = Nothing + End If + + If SaveForm Then + DoCmd.Save acForm, FilterFormName + End If + +End Function + +Private Function GetFilterControlTag(ByVal DataTypeText As String, ByVal RelOpText As String, ByVal DataFieldName As String, ByVal ControlName2 As String) As String + + Dim ControlTag As String + Const SeparatorChar As String = "|" + + ControlTag = Replace(DataTypeText, "SQL_", vbNullString) & SeparatorChar & RelOpText & SeparatorChar & DataFieldName & SeparatorChar & ControlName2 + + Do While Right(ControlTag, 1) = SeparatorChar + ControlTag = Left(ControlTag, Len(ControlTag) - 1) + Loop + + GetFilterControlTag = ControlTag + +End Function + +Private Function GetRelationalOperatorKey(ByVal RelationalOperatorCode As String) As String + With CodeProject.Connection.Execute("select RelationalOperator from tabRelationalOperators where RelationalOperatorCode = '" & Replace(RelationalOperatorCode, "'", "''") & "'") + If Not .EOF Then + GetRelationalOperatorKey = .Fields(0).Value + End If + .Close + End With +End Function + +Private Function InsertFormControl(ByVal FilterFormName As String, ByVal ControlType As AcControlType, ByVal DataFieldName As String, ByVal UseBetweenRelOp As Boolean, ByRef ControlName As String, ByRef Control2Name As String, ByVal UseFilterDefinitionInTagProperty As Boolean) As Control + + Const DistanceBetweenControls As Long = 72 + + Dim FilterCtl As Control + Dim LabCtl As Control + + Dim ControlCaption As String, Control2Caption As String + Dim CreateControl2 As Boolean + + ControlCaption = DataFieldName + If StrComp(Left(DataFieldName, 1), UCase(Left(DataFieldName, 1)), vbBinaryCompare) <> 0 Then + DataFieldName = UCase(Left(DataFieldName, 1)) & Mid(DataFieldName, 2) + End If + ControlName = GetCheckedControlName("fctl" & DataFieldName) + + With New FormDesigner + + .FormName = FilterFormName + + If UseBetweenRelOp Then + CreateControl2 = True + Control2Caption = ControlCaption & " bis" + If UseFilterDefinitionInTagProperty Then + Control2Name = "x" & ControlName & "Max" + Else + Control2Name = ControlName & "Max" + ControlName = ControlName & "Min" + End If + ControlCaption = ControlCaption & " von" + End If + + Set FilterCtl = .AddControl(ControlType, ControlName, acHeader, , , , , DistanceBetweenControls, True, ControlCaption) + ControlName = FilterCtl.Name + If CreateControl2 Then + Set LabCtl = FilterCtl.Controls(0) + Control2Name = .AddControl(ControlType, Control2Name, acHeader, LabCtl.Left + LabCtl.Width + DistanceBetweenControls, LabCtl.Top, , , DistanceBetweenControls, True, Control2Caption).Name + End If + + End With + + Set InsertFormControl = FilterCtl + +End Function + +Private Sub cbCreateControl_AfterUpdate() + + Dim CreateNewControl As Boolean + + CreateNewControl = Me.cbCreateControl.Value + + With Me.ogNewControlType + .TabStop = Nz(.Value, False) + If CreateNewControl Then + .Value = acTextBox + Else + .Value = Null + End If + + End With + +End Sub + +Private Sub Form_Current() + Me.ogNewControlType.TabStop = Nz(Me.cbCreateControl.Value) +End Sub + +Private Sub Form_Load() + L10n.TranslateControls Me.Controls + Set m_LngDict = L10n +End Sub + +Private Sub m_LngDict_DictionaryRefreshed() + L10n.TranslateControls Me.Controls +End Sub + +Private Sub ogNewControlType_Enter() + Me.ogNewControlType.Locked = (Me.cbCreateControl.Value = False) +End Sub + +Private Function GetCheckedControlName(ByVal ControlNameToCheck As String) As String + GetCheckedControlName = Replace(ControlNameToCheck, " ", "_") +End Function + +Public Sub InsertFilterRecord(ByVal DataFieldName As String, ByVal DataFieldType As DAO.DataTypeEnum) + + Dim FieldDataType As SqlFieldDataType + + Select Case DataFieldType + Case DAO.DataTypeEnum.dbBinary, DAO.DataTypeEnum.dbGUID, DAO.DataTypeEnum.dbVarBinary + Exit Sub + Case 101 ' 101 = DAO.DataTypeEnum.dbAttachment + Exit Sub + End Select + + FieldDataType = ConvertDaoDataTypeToSqlFieldDataType(DataFieldType) + + With Me.Recordset + .AddNew + .Fields("DataField").Value = DataFieldName + .Fields("DataType").Value = ConvertSqlFieldDataTypeToString(FieldDataType) + If FieldDataType = SQL_Text Then + .Fields("RelationalOperator").Value = "SQL_Like" + .Fields("WildCardSuffix").Value = True + Else + .Fields("RelationalOperator").Value = "SQL_Equal" + .Fields("WildCardSuffix").Value = False + End If + .Fields("CreateControl").Value = True + .Fields("ControlType").Value = acTextBox + .Fields("WildCardPrefix").Value = False + .Fields("RelationalOperatorNot").Value = False + .Update + End With + +End Sub + +Private Function ConvertDaoDataTypeToSqlFieldDataType(ByVal DT As DAO.DataTypeEnum) As SqlFieldDataType + + Select Case DT + Case DAO.DataTypeEnum.dbBigInt, DAO.DataTypeEnum.dbByte, DAO.DataTypeEnum.dbDecimal, DAO.DataTypeEnum.dbCurrency, DAO.DataTypeEnum.dbDouble, DAO.DataTypeEnum.dbFloat, DAO.DataTypeEnum.dbInteger, DAO.DataTypeEnum.dbLong, DAO.DataTypeEnum.dbNumeric, DAO.DataTypeEnum.dbSingle + ConvertDaoDataTypeToSqlFieldDataType = SqlFieldDataType.SQL_Numeric + Case DAO.DataTypeEnum.dbDate, DAO.DataTypeEnum.dbTime + ConvertDaoDataTypeToSqlFieldDataType = SqlFieldDataType.SQL_Date + Case DAO.DataTypeEnum.dbBoolean + ConvertDaoDataTypeToSqlFieldDataType = SqlFieldDataType.SQL_Boolean + Case Else + ConvertDaoDataTypeToSqlFieldDataType = SqlFieldDataType.SQL_Text + End Select + +End Function + +Private Function ConvertSqlFieldDataTypeToString(ByVal DT As SqlFieldDataType) As String + Select Case DT + Case SqlFieldDataType.SQL_Text + ConvertSqlFieldDataTypeToString = "SQL_Text" + Case SqlFieldDataType.SQL_Numeric + ConvertSqlFieldDataTypeToString = "SQL_Numeric" + Case SqlFieldDataType.SQL_Date + ConvertSqlFieldDataTypeToString = "SQL_Date" + Case SqlFieldDataType.SQL_Boolean + ConvertSqlFieldDataTypeToString = "SQL_Boolean" + End Select +End Function diff --git a/source/frmFilterFormWizard.frm b/source/frmFilterFormWizard.frm deleted file mode 100644 index f6a049e..0000000 Binary files a/source/frmFilterFormWizard.frm and /dev/null differ diff --git a/source/frmFilterFormWizard_SF_Controls.frm b/source/frmFilterFormWizard_SF_Controls.frm deleted file mode 100644 index 8cbfab2..0000000 Binary files a/source/frmFilterFormWizard_SF_Controls.frm and /dev/null differ diff --git a/source/macros/Autoexec.bas b/source/macros/Autoexec.bas new file mode 100644 index 0000000..09dd41f --- /dev/null +++ b/source/macros/Autoexec.bas @@ -0,0 +1,18 @@ +Version =196611 +ColumnsShown =0 +Begin + Action ="RunCode" + Comment ="base/Autoexec.macro" + Argument ="CheckApplicationStartUpMethod()" +End +Begin + Comment ="_AXL:\015\012<codelib><file>" +End +Begin + Comment ="_AXL:base/Autoexec.macro</file></codelib>CheckApplicationStartUpMethod()" +End diff --git a/source/codelib/_codelib/addins/shared/ACLibGitHubImporter.cls b/source/modules/ACLibGitHubImporter.cls similarity index 98% rename from source/codelib/_codelib/addins/shared/ACLibGitHubImporter.cls rename to source/modules/ACLibGitHubImporter.cls index 61acbc9..18e23b4 100644 --- a/source/codelib/_codelib/addins/shared/ACLibGitHubImporter.cls +++ b/source/modules/ACLibGitHubImporter.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -126,24 +126,24 @@ End Property ' Sub: UpdateCodeModules '--------------------------------------------------------------------------------------- Public Sub UpdateCodeModules() - + Dim SelectSql As String Dim IsFirstRecord As Boolean - + SelectSql = "select id, url from usys_Appfiles where url > ''" - + With CreateObject("ADODB.Recordset") .CursorLocation = 3 'adUseClient .Open SelectSql, CodeProject.Connection, 1, 1 ' 1 = adOpenKeyset, 1 = adLockReadOnly Set .ActiveConnection = Nothing - + IsFirstRecord = True Do While Not .EOF UpdateCodeModuleInTable .Fields(0).Value, .Fields(1).Value, IsFirstRecord If IsFirstRecord Then IsFirstRecord = False .MoveNext Loop - + .Close End With @@ -153,11 +153,11 @@ End Sub Private Sub UpdateCodeModuleInTable(ByVal ModuleName As String, ByVal ACLibPath As String, Optional ByVal Requery As Boolean = False) Dim TempFile As String - - + + TempFile = FileTools.TempPath & ModuleName & FileTools.GetFileExtension(ACLibPath, True) DownloadACLibFileFromWeb ACLibPath, TempFile - + CurrentApplication.SaveAppFile ModuleName, TempFile, False, "SccRev", Me.RevisionString(Requery) Kill TempFile @@ -169,21 +169,21 @@ Friend Sub DownloadACLibFileFromWeb(ByVal ACLibPath As String, ByVal TargetFileP DownLoadUrl = FillRepositoryData(GitHubContentBaseUrl) DownLoadUrl = Replace(DownLoadUrl, "{path}", ACLibPath) - + DownloadFileFromWeb DownLoadUrl, TargetFilePath End Sub Private Function FillRepositoryData(ByVal StringWithPlaceHolder As String) As String - + Dim TempValue As String - + TempValue = Replace(StringWithPlaceHolder, "{owner}", RepositoryOwner) TempValue = Replace(TempValue, "{repo}", RepositoryName) TempValue = Replace(TempValue, "{branch}", BranchName) - + FillRepositoryData = TempValue - + End Function Private Function GetLastCommitFromWeb() As Date @@ -194,20 +194,20 @@ Private Function GetLastCommitFromWeb() As Date Dim CommitUrl As String Dim LastCommitInfo As String - + CommitUrl = FillRepositoryData(GitHubApiBaseUrl) & "commits/" & BranchName Const RevisionTag As String = "Revision " Dim JsonString As String JsonString = GetJsonString(CommitUrl) - + Dim LastCommitPos As Long LastCommitPos = InStr(1, JsonString, """committer"":") LastCommitPos = InStr(LastCommitPos, JsonString, """date"":") + Len("date"": """) '"date": "2023-05-14T09:34:04Z" LastCommitInfo = Mid(JsonString, LastCommitPos, Len("2023-05-14T09:34:04")) - + GetLastCommitFromWeb = CDate(Replace(LastCommitInfo, "T", " ")) End Function @@ -218,13 +218,13 @@ Friend Function GetJsonString(ByVal ApiUrl As String) As String Dim ApiAuthToken As String Dim json As Object Dim xml As Object 'MSXML2.XMLHTTP6 - + ApiUrl = FillRepositoryData(ApiUrl) - + ApiAuthToken = GitHubApiAuthorizationToken Set xml = CreateObject("MSXML2.XMLHTTP.6.0") - + xml.Open "GET", ApiUrl, False If Len(ApiAuthToken) > 0 Then xml.setRequestHeader "Authorization", ApiAuthToken @@ -235,7 +235,7 @@ Friend Function GetJsonString(ByVal ApiUrl As String) As String DoEvents Wend ApiResponse = xml.responseText - + GetJsonString = ApiResponse End Function @@ -245,7 +245,7 @@ Private Sub OpenIEandLoadHtmlDoc(ByVal Url As String, ByRef IE As Object, ByRef Dim TimeOut As Long Dim RunInTimeOut As Boolean Dim ErrHdlCnt As Long - + Dim ErrNumber As Long Dim ErrDescription As String @@ -263,16 +263,16 @@ On Error Resume Next On Error GoTo 0 Err.Raise ErrNumber, "ACLibWebImporter.OpenIEandLoadHtmlDoc", ErrDescription End If - + On Error GoTo 0 - + With IE TimeOut = Timer + 10 Do While .Busy And (Not RunInTimeOut) DoEvents If Timer > TimeOut Then RunInTimeOut = True Loop - + If Not RunInTimeOut Then .Visible = 0 .navigate Url @@ -282,7 +282,7 @@ On Error GoTo 0 If Timer > TimeOut Then RunInTimeOut = True Loop End If - + If RunInTimeOut Then On Error Resume Next IE.Quit @@ -290,9 +290,9 @@ On Error GoTo 0 On Error GoTo 0 Err.Raise vbObjectError, "OpenIEandLoadHtmlDoc", "Time-Out beim Laden von '" & Url & "'" End If - + Set HtmlDoc = IE.Document - + End With End Sub diff --git a/source/codelib/_codelib/addins/shared/AppFileCodeModulTransfer.cls b/source/modules/AppFileCodeModulTransfer.cls similarity index 98% rename from source/codelib/_codelib/addins/shared/AppFileCodeModulTransfer.cls rename to source/modules/AppFileCodeModulTransfer.cls index 41b4f0f..5c83592 100644 --- a/source/codelib/_codelib/addins/shared/AppFileCodeModulTransfer.cls +++ b/source/modules/AppFileCodeModulTransfer.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -64,7 +64,7 @@ End Property ' '--------------------------------------------------------------------------------------- Public Sub TransferCodeModules(ParamArray CodeModulNames() As Variant) - + Dim i As Long Dim ArrSize As Long @@ -86,11 +86,11 @@ End Sub ' '--------------------------------------------------------------------------------------- Public Function ReplaceCodeModules(ParamArray CodeModulNames() As Variant) As Boolean - + Dim i As Long Dim ArrSize As Long Dim vbp As Object 'VBProject - + 'VBProject of the application: Set vbp = VbeTools.CurrentVbProject @@ -98,19 +98,19 @@ Public Function ReplaceCodeModules(ParamArray CodeModulNames() As Variant) As Bo If Not (vbp Is Nothing) Then ArrSize = UBound(CodeModulNames) For i = 0 To ArrSize - + If CheckCodeModule(CodeModulNames(i)) And (UseVbComponentsImport = False) Then - 'Modul löschen + 'Modul löschen vbp.VBComponents.Remove vbp.VBComponents(CodeModulNames(i)) End If - + 'Module aktualisieren TransferCodeModul CurrentProject, acModule, CodeModulNames(i) - + Next ReplaceCodeModules = True End If - + Set vbp = Nothing End Function @@ -129,7 +129,7 @@ End Function ' '--------------------------------------------------------------------------------------- Public Function CheckCodeModules(ParamArray CodeModulNames() As Variant) As Boolean - + Dim i As Long Dim ModulesExists As Boolean Dim ArrSize As Long @@ -139,7 +139,7 @@ Public Function CheckCodeModules(ParamArray CodeModulNames() As Variant) As Bool For i = 0 To ArrSize ModulesExists = ModulesExists And CheckCodeModule(CodeModulNames(i), False) Next - + CheckCodeModules = ModulesExists End Function @@ -160,7 +160,7 @@ End Function '--------------------------------------------------------------------------------------- Public Function CheckCodeModule(ByVal CodeModulName As String, _ Optional ByVal TransferMissingModule As Boolean = False) As Boolean - + Dim rst As DAO.Recordset Dim IsMissing As Boolean @@ -168,12 +168,12 @@ Public Function CheckCodeModule(ByVal CodeModulName As String, _ IsMissing = rst.EOF rst.Close Set rst = Nothing - + If IsMissing And TransferMissingModule Then TransferCodeModul CurrentProject, acModule, CodeModulName IsMissing = False End If - + CheckCodeModule = Not IsMissing End Function @@ -194,7 +194,7 @@ Public Sub TransferCodeModul(ByVal TargetProject As Access.CurrentProject, _ ByVal ObjType As AcObjectType, ByVal CodeModulName As String) Dim FileName As String - + FileName = FileTools.GetNewTempFileName CurrentApplication.CreateAppFile CodeModulName, FileName If UseVbComponentsImport And ObjType = acModule Then @@ -215,12 +215,12 @@ Public Sub TransferCodeModul(ByVal TargetProject As Access.CurrentProject, _ TargetProject.Application.LoadFromText ObjType, CodeModulName, FileName End If Kill FileName - - + + End Sub Private Sub ConvertToSaveAsTextFile(ByVal FilePath As String) - + Const SEARCHSTRING_ATTRIBUTNAME_BEGIN As String = "Attribute VB_Name = """ Dim Pos As Long @@ -233,23 +233,23 @@ Private Sub ConvertToSaveAsTextFile(ByVal FilePath As String) CheckString = String$(LOF(FileNumber), 0) Get FileNumber, , CheckString Close FileNumber - + Pos = InStr(1, CheckString, SEARCHSTRING_ATTRIBUTNAME_BEGIN) If Pos <= 1 Then Exit Sub End If - + CheckString = Mid(CheckString, Pos) - + NewFile = FilePath & "_SaT" FileNumber = FreeFile Open NewFile For Binary Access Write As FileNumber Put FileNumber, , CheckString Close FileNumber - + Kill FilePath Name NewFile As FilePath - + End Sub Private Property Get CurrentCodeModulWriter() As CodeModuleWriter diff --git a/source/codelib/base/ApplicationHandler.cls b/source/modules/ApplicationHandler.cls similarity index 99% rename from source/codelib/base/ApplicationHandler.cls rename to source/modules/ApplicationHandler.cls index 85b4446..9306eba 100644 --- a/source/codelib/base/ApplicationHandler.cls +++ b/source/modules/ApplicationHandler.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -66,12 +66,12 @@ Private Const SYSCOLOR_COLOR_APPWORKSPACE As Long = 12 Private Declare PtrSafe Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" ( _ ByVal HWnd1 As Long, ByVal HWnd2 As Long, _ ByVal Lpsz1 As String, ByVal Lpsz2 As String) As Long - + Private Declare PtrSafe Function CreateSolidBrush Lib "gdi32.dll" (ByVal CrColor As Long) As Long Private Declare PtrSafe Function SetClassLong Lib "user32" Alias "SetClassLongA" ( _ ByVal Hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long - + Private Declare PtrSafe Function RedrawWindow Lib "user32" ( _ ByVal Hwnd As Long, LprcUpdate As Any, _ ByVal HrgnUpdate As Long, ByVal FuRedraw As Long) As Long @@ -83,12 +83,12 @@ Private Declare PtrSafe Function GetSysColor Lib "user32" (ByVal NumIndex As Lon Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" ( _ ByVal HWnd1 As Long, ByVal HWnd2 As Long, _ ByVal Lpsz1 As String, ByVal Lpsz2 As String) As Long - + Private Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal CrColor As Long) As Long Private Declare Function SetClassLong Lib "user32" Alias "SetClassLongA" ( _ ByVal Hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long - + Private Declare Function RedrawWindow Lib "user32" ( _ ByVal Hwnd As Long, LprcUpdate As Any, _ ByVal HrgnUpdate As Long, ByVal FuRedraw As Long) As Long @@ -141,12 +141,12 @@ Public Event ExtensionProcedureCall(ByVal Key As String, ByVal ProcedureName As Public Event AppFileBeforeCreateFile( _ ByVal sFileID As String, ByVal sFileName As String, _ ByRef ResumeMode As ApplicationHandlerResumeModes, ByRef ResumeMessage As Variant) - + Public Event AppFileBeforeSaveFile( _ ByVal sFileID As String, ByVal sFileName As String, ByVal SaveVersion As Boolean, _ ByRef ResumeMode As ApplicationHandlerResumeModes, ByRef ResumeMessage As Variant, _ ByVal ExtFieldName As String, ByVal ExtFieldValue As Variant) - + Public Event UpdateApplication( _ ByRef ResumeMode As ApplicationHandlerResumeModes, ByRef ResumeMessage As Variant) @@ -158,7 +158,7 @@ Public Event NewVersionExists( _ Public Event BeforeOpenStartForm( _ ByRef ResumeMode As ApplicationHandlerResumeModes, ByRef ResumeMessage As Variant) - + Public Event BeforeStartApplication( _ ByRef ResumeMode As ApplicationHandlerResumeModes, ByRef ResumeMessage As Variant) @@ -184,28 +184,28 @@ On Error Resume Next End Sub Public Sub Dispose(Optional ByRef ResumeMode As ApplicationHandlerResumeModes, Optional ByRef ResumeMessage As Variant) - + Dim TempResumeMode As ApplicationHandlerResumeModes Dim TempResumeMessage As Variant - + On Error Resume Next - + RaiseEvent BeforeDispose(TempResumeMode, TempResumeMessage) If TempResumeMode = AppResumeMode_Cancel Then ResumeMode = TempResumeMode ResumeMessage = TempResumeMessage Exit Sub End If - + Set m_AppDb = Nothing - + m_Disposed = True - + RaiseEvent AfterDispose(TempResumeMode, TempResumeMessage) - + ResumeMode = AppResumeMode_Completed ResumeMessage = TempResumeMessage - + End Sub '--------------------------------------------------------------------------------------- @@ -223,11 +223,11 @@ End Sub ' '--------------------------------------------------------------------------------------- Public Function Start(Optional ByRef ResumeMessage As Variant) As Boolean - + Dim CurrentStartFormName As String Dim EventResumeMode As ApplicationHandlerResumeModes Dim EventResumeMessage As Variant - + 'Event interface for application start ' ... enables e.g. the execution of a login process RaiseEvent BeforeStartApplication(EventResumeMode, EventResumeMessage) @@ -257,7 +257,7 @@ Public Function Start(Optional ByRef ResumeMessage As Variant) As Boolean Exit Function End If End If - + 'Event interface for start form '... allows changing the start form by means of extensions ' e.g. if a user-specific form is to be opened @@ -274,7 +274,7 @@ Public Function Start(Optional ByRef ResumeMessage As Variant) As Boolean Case Else CurrentStartFormName = Me.ApplicationStartFormName End Select - + If Len(CurrentStartFormName) > 0 Then DoCmd.OpenForm CurrentStartFormName End If @@ -357,9 +357,9 @@ Public Property Get Version() As String '**/ m_APPLICATIONVERSION = "" End If - + Version = m_APPLICATIONVERSION - + End Property Public Property Let Version(ByVal AppVersion As String) @@ -440,7 +440,7 @@ Friend Sub SetAppIcon(ByVal AppIconFile As String, Optional ByVal UseAppIconForF SetAppDbProperty DBPROPNAME_APPICON, dbText, AppIconFile SetAppDbProperty DBPROPNAME_USE_APPICON_FOR_FRMRPT, dbBoolean, UseAppIconForFrmRpt Else - '1. Prüfen ob AppFile-Erweiterung vorhanden ist + '1. Prüfen ob AppFile-Erweiterung vorhanden ist RaiseEvent CheckExtension(EXTENSION_KEY_APPFILE, CheckVar) If CheckVar Then CheckVar = CreateAppFile("AppIcon", AppIconFile) @@ -478,10 +478,10 @@ Public Sub SetApplicationProperty(ByVal PropName As String, ByVal PropValue As V End Sub Private Sub SetAppDbProperty(ByVal PropName As String, ByVal PropType As Long, ByVal PropValue As Variant) - + Dim db As DAO.Database Dim PropCol As DAO.Properties - + Set db = AppDb Set PropCol = db.Properties If DbPropertyExists(PropCol, PropName) Then @@ -499,13 +499,13 @@ Private Sub SetAppDbProperty(ByVal PropName As String, ByVal PropType As Long, B End Sub Private Sub DeleteAppDbProperty(ByVal PropName As String) - + Dim db As DAO.Database Dim PropCol As DAO.Properties Set db = AppDb Set PropCol = db.Properties - + If DbPropertyExists(PropCol, PropName) Then PropCol.Delete PropName End If @@ -513,7 +513,7 @@ Private Sub DeleteAppDbProperty(ByVal PropName As String) End Sub Private Function DbPropertyExists(ByRef PropCol As DAO.Properties, ByVal PropName As String) As Boolean - + Dim Prop As DAO.Property For Each Prop In PropCol @@ -531,7 +531,7 @@ Private Sub WriteApplicationLogEntry(ByVal Msg As String) Dim FileNo As Long LogFile = CurrentProject.Path & "\" & LOG_FILE - + FileNo = FreeFile Open LogFile For Append As FileNo Print #FileNo, Msg @@ -548,7 +548,7 @@ Public Sub WriteLog(ByVal Msg As String, _ Dim EventResumeMessage As Variant RaiseEvent NewAppLog(LogType, Msg, Args, ResumeMode, EventResumeMessage) - + If ResumeMode = 0 And (WriteToFileIfNoEventResponse Or WriteLogToFileIfNoEventResponse Or LogType = AppLogType_Error) Then 'no one has reacted or reported an abort => WriteApplicationLogEntry Msg = Now() & ": " & Msg @@ -652,7 +652,7 @@ Public Function NewerAppVersionExists() As Boolean Dim ResumeMode As ApplicationHandlerResumeModes Dim ResumeMessage As Boolean - + RaiseEvent NewVersionExists(ResumeMode, ResumeMessage) NewerAppVersionExists = ResumeMessage @@ -661,7 +661,7 @@ End Function Private Function CheckVersionUpdate() As Boolean ' True = Update required - + Dim EventResumeMode As ApplicationHandlerResumeModes Dim EventResumeMessage As Variant @@ -710,17 +710,17 @@ Public Function GetExtensionInstance(ByVal ExtensionKey As String, Optional ByVa RaiseEvent ExtensionInstance(ExtensionKey, InstanceKey, ExtRef) Set GetExtensionInstance = ExtRef - + End Function Public Function GetExtensionProperty(ByVal ExtensionKey As String, ByVal PropertyName As String, _ Optional ByVal ValueIfMissing As Variant = Empty) As Variant - + Dim EventResumeMode As ApplicationHandlerResumeModes Dim EventResumeMessage As Variant RaiseEvent ExtensionPropertyLookup(ExtensionKey, PropertyName, EventResumeMode, EventResumeMessage) - + If EventResumeMode = AppResumeMode_Completed Then GetExtensionProperty = EventResumeMessage Else @@ -731,7 +731,7 @@ End Function Public Function UpdateApplication() As Boolean ' True = Close application - + ' => Outsourced to extension: this makes the usage more flexible ' and everyone can choose which update method to follow @@ -764,7 +764,7 @@ End Function Public Sub CallExtensionProcedure(ByVal Key As String, ByVal ProcedureName As String, _ ByRef ResumeMode As ApplicationHandlerResumeModes, ByRef ResumeMessage As Variant, _ ByRef Params() As Variant) - + RaiseEvent ExtensionProcedureCall(Key, ProcedureName, ResumeMode, ResumeMessage, Params) - + End Sub diff --git a/source/codelib/base/ApplicationHandler_AppFile.cls b/source/modules/ApplicationHandler_AppFile.cls similarity index 97% rename from source/codelib/base/ApplicationHandler_AppFile.cls rename to source/modules/ApplicationHandler_AppFile.cls index c6cdddf..49979eb 100644 --- a/source/codelib/base/ApplicationHandler_AppFile.cls +++ b/source/modules/ApplicationHandler_AppFile.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -7,7 +7,7 @@ Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = False Attribute VB_Exposed = False -Attribute VB_Description = "Erweiterung für ApplicationHandler-Klasse: Anwendungsspezifische Dateien verwalten" +Attribute VB_Description = "Erweiterung für ApplicationHandler-Klasse: Anwendungsspezifische Dateien verwalten" '--------------------------------------------------------------------------------------- ' Class: base.ApplicationHandler_File '--------------------------------------------------------------------------------------- @@ -108,10 +108,10 @@ Private Sub GetExtensionPropertyLookup(ByVal PropertyName As String, _ Select Case PropertyName Case EXTENSION_PROPERTY_APPFILETABLENAME ResumeMessage = TABLE_APPFILES - + Case Else 'Property wurde nicht erkannt ResumeMode = AppResumeMode_Error - + End Select End Sub @@ -149,34 +149,34 @@ Public Function CreateAppFile(ByVal FileID As String, ByVal FileName As String, With CodeDb.OpenRecordset(SelectSql) If Not .EOF Then - + Set fld = .Fields(0) FieldSize = fld.FieldSize - + If FieldSize > 0 Then ReDim Binfile(FieldSize - 1) Binfile = fld.GetChunk(0, FieldSize) CreateFileFromByteArray FileName, Binfile CreateAppFile = True End If - + End If .Close End With - + End Function Private Sub CreateFileFromByteArray(ByVal FileName As String, ByRef Binfile() As Byte) - + Dim FileNo As Integer - + FileTools.CreateDirectoryIfMissing FileTools.GetDirFromFullFileName(FileName) FileNo = FreeFile Open FileName For Binary As #FileNo Put #FileNo, , Binfile() Close #FileNo - + End Sub '--------------------------------------------------------------------------------------- @@ -207,7 +207,7 @@ Public Function SaveAppFile(ByVal FileID As String, ByVal FileName As String, _ Dim Version As String Dim FileInfo As WinApiFileInfo Dim SelectSql As String - + On Error GoTo HandleErr FileNo = FreeFile @@ -250,20 +250,20 @@ On Error GoTo HandleErr End If rst.Fields(TABLE_FIELD_VERSION) = Version End If - + If Len(ExtFieldName) > 0 Then rst.Fields(ExtFieldName).Value = ExtFieldValue End If - + rst.Update rst.Close Set rst = Nothing - + SaveAppFile = True ExitHere: Exit Function - + HandleErr: Dim TabCreateErrCnt As Long Dim ErrNumber As Long, ErrDescription As String @@ -284,7 +284,7 @@ HandleErr: End Function Private Function CreateAppFileTable() As Boolean - + Dim CreateTableSql As String CreateTableSql = "create table " & TABLE_APPFILES & " ( " & TABLE_FIELD_ID & " varchar(20) primary key, " & _ @@ -309,10 +309,10 @@ Private Sub m_ApplicationHandler_AppFileBeforeCreateFile(ByVal FileID As String, Completed = CreateAppFile(FileID, FileName) If Completed Then ResumeMode = ApplicationHandlerResumeModes.AppResumeMode_Completed - Else 'Fehler rückmelden + Else 'Fehler rückmelden ResumeMode = ApplicationHandlerResumeModes.AppResumeMode_Error End If - + End Sub ' AppFileBeforeSaveFile @@ -329,5 +329,5 @@ Private Sub m_ApplicationHandler_AppFileBeforeSaveFile(ByVal FileID As String, B Else 'resume error ResumeMode = ApplicationHandlerResumeModes.AppResumeMode_Error End If - + End Sub diff --git a/source/codelib/base/ApplicationHandler_ExtensionCollection.cls b/source/modules/ApplicationHandler_ExtensionCollection.cls similarity index 99% rename from source/codelib/base/ApplicationHandler_ExtensionCollection.cls rename to source/modules/ApplicationHandler_ExtensionCollection.cls index 66233f5..eb765b0 100644 --- a/source/codelib/base/ApplicationHandler_ExtensionCollection.cls +++ b/source/modules/ApplicationHandler_ExtensionCollection.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -88,7 +88,7 @@ Public Sub Add(ByVal ExtensionRef As Object) End Sub Public Sub Dispose() - + Dim MaxCnt As Long Dim CheckCnt As Long diff --git a/source/codelib/base/ApplicationHandler_Version.cls b/source/modules/ApplicationHandler_Version.cls similarity index 98% rename from source/codelib/base/ApplicationHandler_Version.cls rename to source/modules/ApplicationHandler_Version.cls index 6299eb5..dacb8fb 100644 --- a/source/codelib/base/ApplicationHandler_Version.cls +++ b/source/modules/ApplicationHandler_Version.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -80,11 +80,11 @@ Private Sub m_ApplicationHandler_ExtensionProcedureCall(ByVal ExtensionKeyToChec If ExtensionKeyToCheck <> EXTENSION_KEY Then Exit Sub End If - + On Error GoTo HandleErr - + ResumeMode = AppResumeMode_Completed - + Select Case ProcedureName Case "NewVersionExists" ResumeMessage = NewVersionExists(ProcParams(0), ProcParams(1)) @@ -93,11 +93,11 @@ On Error GoTo HandleErr End Select Exit Sub - + HandleErr: ResumeMode = AppResumeMode_Error ResumeMessage = Err.Description - + End Sub 'ExtensionPropertyLookup @@ -120,7 +120,7 @@ End Sub Public Function NewVersionExists(Optional ByRef NewVersion As Variant, Optional ByRef VersionRemarks As Variant) As Boolean NewVersionExists = (CheckVersion(NewVersion, VersionRemarks) = VerState_Newer) - + End Function @@ -135,11 +135,11 @@ Private Sub GetExtensionPropertyLookup(ByVal PropertyName As String, _ ResumeMode = AppResumeMode_Completed Select Case PropertyName - + Case Else 'Property was not recognized ResumeMode = AppResumeMode_Error ResumeMessage = "Property '" & PropertyName & "' is not supported" - + End Select End Sub @@ -162,10 +162,10 @@ Public Function CheckVersion(Optional ByRef NewVersion As Variant, Optional ByRe Dim DownloadVersion As String Dim DownloadVersionRemarks As String - + DownloadVersion = GetVersionFromDownloadSource(XmlVersionCheckFile, DownloadVersionRemarks) CheckVersion = CompareVersions(m_ApplicationHandler.Version, DownloadVersion) - + If CheckVersion = VerState_Newer Then NewVersion = DownloadVersion VersionRemarks = DownloadVersionRemarks @@ -184,13 +184,13 @@ End Property Private Function GetVersionFromDownloadSource(ByVal XmlFile As String, ByRef VersionRemarks As String) As String Dim XmlDoc As Object ' MSXML2.DOMDocument60 - + Set XmlDoc = CreateObject("MSXML.DOMDocument") 'New MSXML2.DOMDocument60 XmlDoc.async = False If Not XmlDoc.Load(XmlFile) Then Err.Raise XmlDoc.parseError.errorCode, , XmlDoc.parseError.Reason End If - + GetVersionFromDownloadSource = XmlDoc.getElementsByTagName("version").Item(0).Text VersionRemarks = XmlDoc.getElementsByTagName("remarks").Item(0).Text @@ -204,7 +204,7 @@ Private Function GetVersionNumbers(ByVal VersionString As String) As Long() VersionNumberStrings = Split(VersionString, ".") ReDim VersionNumbers(UBound(VersionNumberStrings)) - + Dim i As Long For i = LBound(VersionNumberStrings) To UBound(VersionNumberStrings) VersionNumbers(i) = Val(VersionNumberStrings(i)) @@ -218,18 +218,18 @@ Private Function CompareVersions(ByVal BaseVersion As String, ByVal NewVersion A Dim BaseVersionNumbers() As Long Dim NewVersionNumbers() As Long - + BaseVersionNumbers = GetVersionNumbers(BaseVersion) NewVersionNumbers = GetVersionNumbers(NewVersion) - + Dim i As Long - + Dim MaxIndex As Long MaxIndex = UBound(NewVersionNumbers) If UBound(BaseVersionNumbers) < MaxIndex Then MaxIndex = UBound(BaseVersionNumbers) End If - + For i = LBound(NewVersionNumbers) To MaxIndex If BaseVersionNumbers(i) <> NewVersionNumbers(i) Then CompareVersions = -1 + 2 * Abs(BaseVersionNumbers(i) > NewVersionNumbers(i)) diff --git a/source/codelib/_codelib/addins/shared/CodeModuleWriter.cls b/source/modules/CodeModuleWriter.cls similarity index 97% rename from source/codelib/_codelib/addins/shared/CodeModuleWriter.cls rename to source/modules/CodeModuleWriter.cls index 8fb4d24..1a93992 100644 --- a/source/codelib/_codelib/addins/shared/CodeModuleWriter.cls +++ b/source/modules/CodeModuleWriter.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -38,14 +38,14 @@ Option Explicit #Else Private m_CodeModule As Object Private m_CurrentVbProject As Object - + Public Enum vbext_ProcKind vbext_pk_Proc = 0 vbext_pk_Let = 1 vbext_pk_Set = 2 vbext_pk_Get = 3 End Enum - + Public Enum vbext_ComponentType vbext_ct_StdModule = 1 vbext_ct_ClassModule = 2 @@ -69,7 +69,7 @@ Public Property Get CodeModule() As Object #End If Set CodeModule = m_CodeModule - + End Property #If VBIDE_EARLYBINDING Then @@ -95,7 +95,7 @@ Public Sub AddCodeToEventProcedure(ByVal EventName As String, ByVal ObjectName A Dim ProcEndLine As Long Dim CodeCheckLineStart As Long Dim CodeCheckLineEnd As Long - + StartLine = FindEventProcedureBodyLine(EventName, ObjectName, ProcEndLine) If StartLine < 0 Then @@ -105,11 +105,11 @@ Public Sub AddCodeToEventProcedure(ByVal EventName As String, ByVal ObjectName A CodeCheckLineEnd = ProcEndLine CodeExists = m_CodeModule.Find(Code, CodeCheckLineStart, 0, CodeCheckLineEnd, 0, True) End If - + If Not CodeExists Then m_CodeModule.InsertLines StartLine + 1, vbNewLine & Code End If - + End Sub Private Function FindEventProcedureBodyLine(ByVal EventName As String, ByVal ObjectName As String, _ @@ -164,7 +164,7 @@ Friend Property Get CurrentVbProject() As Object If m_CurrentVbProject Is Nothing Then Set m_CurrentVbProject = VbeTools.CurrentVbProject End If - + Set CurrentVbProject = m_CurrentVbProject End Property @@ -194,19 +194,19 @@ Public Sub ImportVbComponent(ByVal ComponentType As vbext_ComponentType, ByVal C End If Next - If CodeModuleExists Then ' überprüfen, ob Typen übereinstimmen + If CodeModuleExists Then ' überprüfen, ob Typen übereinstimmen If vbc.Type <> ComponentType Then VbcCol.Remove vbc Set vbc = Nothing CodeModuleExists = False End If End If - + If Not CodeModuleExists Then Set vbc = VbcCol.Add(ComponentType) vbc.Name = CodeModulName End If - + Set cm = vbc.CodeModule cm.DeleteLines 1, cm.CountOfLines cm.AddFromFile ImportFile @@ -218,8 +218,8 @@ Public Sub ImportVbComponent(ByVal ComponentType As vbext_ComponentType, ByVal C 'End DeleteClassHeaderLinesFromCodeModul cm End If - - 'Leerzeilen am Ende säubern + + 'Leerzeilen am Ende säubern Do While Len(Trim$(cm.Lines(cm.CountOfLines, 1))) = 0 And cm.CountOfLines > 1 cm.DeleteLines cm.CountOfLines Loop @@ -240,10 +240,10 @@ Private Function GetComponentTypeFromFile(ByVal FilePath As String) As vbext_Com CheckString = String$(LOF(FileNumber), 0) Get FileNumber, , CheckString Close FileNumber - - 'Pos von VB_Name ermitteln (= Kennzeichen für Standardmodul oder Klasse) + + 'Pos von VB_Name ermitteln (= Kennzeichen für Standardmodul oder Klasse) Pos = InStr(1, CheckString, SEARCHSTRING_ATTRIBUTNAME_BEGIN) - + 'Typ bestimmen If Pos > 0 Then CmType = vbext_ComponentType.vbext_ct_StdModule diff --git a/source/codelib/file/FileTools.bas b/source/modules/FileTools.bas similarity index 94% rename from source/codelib/file/FileTools.bas rename to source/modules/FileTools.bas index b12fcdd..d5bf826 100644 --- a/source/codelib/file/FileTools.bas +++ b/source/modules/FileTools.bas @@ -1,5 +1,5 @@ -Attribute VB_Name = "FileTools" -Attribute VB_Description = "Funktionen für Dateioperationen" +Attribute VB_Name = "FileTools" +Attribute VB_Description = "Funktionen für Dateioperationen" '--------------------------------------------------------------------------------------- ' Package: file.FileTools '--------------------------------------------------------------------------------------- @@ -24,14 +24,14 @@ Option Explicit Option Private Module #If USELOCALIZATION_DE = 1 Then -Private Const SELECTBOX_FILE_DIALOG_TITLE As String = "Datei auswählen" -Private Const SELECTBOX_FOLDER_DIALOG_TITLE As String = "Ordner auswählen" -Private Const SELECTBOX_OPENTITLE As String = "auswählen" +Private Const SELECTBOX_FILE_DIALOG_TITLE As String = "Datei auswählen" +Private Const SELECTBOX_FOLDER_DIALOG_TITLE As String = "Ordner auswählen" +Private Const SELECTBOX_OPENTITLE As String = "auswählen" Private Const FILTERSTRING_ALL_FILES As String = "Alle Dateien (*.*)" #Else Private Const SELECTBOX_FILE_DIALOG_TITLE As String = "Select file" Private Const SELECTBOX_FOLDER_DIALOG_TITLE As String = "Select folder" -Private Const SELECTBOX_OPENTITLE As String = "auswählen" +Private Const SELECTBOX_OPENTITLE As String = "auswählen" Private Const FILTERSTRING_ALL_FILES As String = "All Files (*.*)" #End If @@ -57,8 +57,8 @@ Private Declare PtrSafe Function API_GetTempFilename Lib "kernel32" Alias "GetTe ByVal lpPrefixString As String, _ ByVal wUnique As Long, _ ByVal lpTempFileName As String) As Long - -Private Declare PtrSafe Function API_ShellExecuteA Lib "shell32.dll" ( _ + +Private Declare PtrSafe Function API_ShellExecuteA Lib "shell32.dll" Alias "ShellExecuteA" ( _ ByVal Hwnd As LongPtr, _ ByVal lOperation As String, _ ByVal lpFile As String, _ @@ -81,7 +81,7 @@ Private Declare Function API_GetTempFilename Lib "kernel32" Alias "GetTempFileNa ByVal wUnique As Long, _ ByVal lpTempFileName As String) As Long -Private Declare Function API_ShellExecuteA Lib "shell32.dll" ( _ +Private Declare Function API_ShellExecuteA Lib "shell32.dll" Alias "ShellExecuteA" ( _ ByVal Hwnd As Long, _ ByVal lOperation As String, _ ByVal lpFile As String, _ @@ -162,13 +162,13 @@ Private Function WizHook_GetFileName( _ ' 2: Eigenschaften ' 3: Liste ' 4: Miniaturansicht -' 5: Große Symbole +' 5: Große Symbole ' 6: Kleine Symbole 'flags 4: Set Current Dir -' 8: Mehrfachauswahl möglich +' 8: Mehrfachauswahl möglich ' 32: Ordnerauswahldialog -' 64: Wert im Parameter "View" berücksichtigen +' 64: Wert im Parameter "View" berücksichtigen Dim SelectedFileString As String Dim WizHookRetVal As Long @@ -214,25 +214,25 @@ End Function ' '--------------------------------------------------------------------------------------- Public Function UncPath(ByVal Path As String, Optional ByVal IgnoreErrors As Boolean = True) As String - + Dim UNC As String * 512 - + If VBA.Len(Path) = 1 Then Path = Path & ":" - + If WNetGetConnection(VBA.Left$(Path, 2), UNC, VBA.Len(UNC)) Then - + If IgnoreErrors Then UncPath = Path Else Err.Raise 5 ' Invalid procedure call or argument End If - + Else UncPath = VBA.Left$(UNC, VBA.InStr(UNC, vbNullChar) - 1) & VBA.Mid$(Path, 3) - + End If - + End Function '--------------------------------------------------------------------------------------- @@ -282,7 +282,7 @@ Public Function GetNewTempFileName(Optional ByVal PathToUse As String = "", _ Optional ByVal FileExtension As String = "") As String Dim NewTempFileName As String - + If Len(PathToUse) = 0 Then PathToUse = TempPath End If @@ -513,7 +513,7 @@ Public Function DirExists(ByVal FullPath As String) As Boolean DirExists = (VBA.Dir$(FullPath, vbDirectory Or vbReadOnly Or vbHidden Or vbSystem) = ".") VBA.Dir$ "\" ' Avoiding error: issue #109 - + End Function '--------------------------------------------------------------------------------------- @@ -664,7 +664,7 @@ Public Function GetRelativPathFromFullPath(ByVal FullPath As String, _ Optional ByVal DisableDecreaseBaseDir As Boolean = False) As String Dim RelativPath As String - + If FullPath = BaseDir Then GetRelativPathFromFullPath = "." Exit Function @@ -675,7 +675,7 @@ Public Function GetRelativPathFromFullPath(ByVal FullPath As String, _ GetRelativPathFromFullPath = "." Exit Function End If - + If Not DisableDecreaseBaseDir Then RelativPath = TryGetRelativPathWithDecreaseBaseDir(FullPath, BaseDir, EnableRelativePrefix) Else @@ -690,7 +690,7 @@ Public Function GetRelativPathFromFullPath(ByVal FullPath As String, _ End If End If End If - + GetRelativPathFromFullPath = RelativPath End Function @@ -701,7 +701,7 @@ Private Function TryGetRelativPathWithDecreaseBaseDir(ByVal FullPath As String, Dim DecreaseCounter As Long Dim Pos As Long Dim i As Long - + RelativPath = BaseDir Do While InStr(1, FullPath, RelativPath) = 0 @@ -713,7 +713,7 @@ Private Function TryGetRelativPathWithDecreaseBaseDir(ByVal FullPath As String, Exit Do End If Loop - + If Len(RelativPath) > 0 Then RelativPath = Replace(FullPath, RelativPath, vbNullString) For i = 1 To DecreaseCounter @@ -848,26 +848,60 @@ End Function ' Boolean ' '--------------------------------------------------------------------------------------- -Public Function OpenFile(ByVal FilePath As String, Optional ByVal ReadOnlyMode As Boolean = False) As Boolean +Public Function OpenFile(ByVal FilePath As String, Optional ByVal ReadOnlyMode As Boolean = False, _ + Optional ByVal DefaultFileFolderIfFileNameOnly As String = vbNullString) As Boolean Const FileNotFoundErrorTextTemplate As String = "File '{FilePath}' not found." Dim FileNotFoundErrorText As String + Dim FilePath2Open As String + + If Len(DefaultFileFolderIfFileNameOnly) > 0 Then + FilePath2Open = BuildFullFileName(FilePath, DefaultFileFolderIfFileNameOnly) + Else + FilePath2Open = FilePath + End If + + If Len(VBA.Dir(FilePath2Open)) = 0 Then - If Len(VBA.Dir(FilePath)) = 0 Then - #If USELOCALIZATION = 1 Then - FileNotFoundErrorText = Replace(L10n.Text(FileNotFoundErrorTextTemplate), "{FilePath}", FilePath) + FileNotFoundErrorText = Replace(L10n.Text(FileNotFoundErrorTextTemplate), "{FilePath}", FilePath2Open) #Else - FileNotFoundErrorText = Replace(FileNotFoundErrorTextTemplate, "{FilePath}", FilePath) + FileNotFoundErrorText = Replace(FileNotFoundErrorTextTemplate, "{FilePath}", FilePath2Open) #End If Err.Raise VbaErrNo_FileNotFound, "FileTools.OpenFile", FileNotFoundErrorText Exit Function End If - OpenFile = ShellExecute(FilePath, "open") - + OpenFile = ShellExecute(FilePath2Open, "open") + End Function +Public Function BuildFullFileName(ByVal FileName As String, ByVal DefaultFileFolderIfFileNameOnly As String) As String + + If Len(DefaultFileFolderIfFileNameOnly) = 0 Then + BuildFullFileName = FileName + Exit Function + End If + + If Left(FileName, 2) = "\\" Then 'Win-Share + BuildFullFileName = FileName + Exit Function + End If + + If Mid(FileName, 2, 1) = ":" Then 'Laufwerksbuchstabe + BuildFullFileName = FileName + Exit Function + End If + + If Left(FileName, 1) <> "\" And Right(DefaultFileFolderIfFileNameOnly, 1) <> "\" Then + DefaultFileFolderIfFileNameOnly = DefaultFileFolderIfFileNameOnly & "\" + End If + + BuildFullFileName = DefaultFileFolderIfFileNameOnly & FileName + +End Function + + '--------------------------------------------------------------------------------------- ' Function: OpenFilePath '--------------------------------------------------------------------------------------- @@ -887,7 +921,7 @@ Public Function OpenFilePath(ByVal FolderPath As String) As Boolean Dim FolderNotFoundErrorText As String If Len(VBA.Dir(FolderPath, vbDirectory)) = 0 Then - + #If USELOCALIZATION = 1 Then FolderNotFoundErrorText = Replace(L10n.Text(FolderNotFoundErrorTextTemplate), "{FolderPath}", FolderPath) #Else @@ -898,7 +932,7 @@ Public Function OpenFilePath(ByVal FolderPath As String) As Boolean End If OpenFilePath = ShellExecute(FolderPath, "open") - + End Function Private Function ShellExecute(ByVal FilePath As String, _ @@ -917,7 +951,7 @@ Private Function ShellExecute(ByVal FilePath As String, _ DeskWin = Application.hWndAccessApp Ret = API_ShellExecuteA(DeskWin, ApiOperation, FilePath, vbNullString, vbNullString, vbNormalFocus) End If - + If Ret = SE_ERR_NOTFOUND Then #If USELOCALIZATION = 1 Then FileNotFoundErrorText = Replace(L10n.Text(FileNotFoundErrorTextTemplate), "{FilePath}", FilePath) @@ -930,16 +964,16 @@ Private Function ShellExecute(ByVal FilePath As String, _ ElseIf Ret = SE_ERR_NOASSOC Then ShellExecute = False Exit Function -' ToDo: "Öffnen mit"-Dialog verwenden: +' ToDo: "Öffnen mit"-Dialog verwenden: 'Wenn die Dateierweiterung noch nicht bekannt ist... - 'wird der "Öffnen mit..."-Dialog angezeigt. + 'wird der "Öffnen mit..."-Dialog angezeigt. ' Directory = Space$(260) ' Ret = GetSystemDirectory(Directory, Len(Directory)) ' Directory = Left$(Directory, Ret) ' Call ShellExecuteA(DeskWin, vbNullString, "RUNDLL32.EXE", "shell32.dll, OpenAs_RunDLL " & _ ' FilePath, Directory, vbNormalFocus) End If - + ShellExecute = True End Function diff --git a/source/FilterControlManagerCodeBuilder.cls b/source/modules/FilterControlManagerCodeBuilder.cls similarity index 92% rename from source/FilterControlManagerCodeBuilder.cls rename to source/modules/FilterControlManagerCodeBuilder.cls index 1a47568..7a5855e 100644 --- a/source/FilterControlManagerCodeBuilder.cls +++ b/source/modules/FilterControlManagerCodeBuilder.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -17,15 +17,6 @@ Attribute VB_Exposed = False ' Josef Poetzl ' '--------------------------------------------------------------------------------------- - -'--------------------------------------------------------------------------------------- -' -' %AppFolder%/source/FilterControlManagerCodeBuilder.cls -' _codelib/license.bas -' %AppFolder%/source/IFilterFormCodeBuilder.cls -' _codelib/addins/shared/AppFileCodeModulTransfer.cls -' -'--------------------------------------------------------------------------------------- ' Option Compare Database Option Explicit @@ -58,24 +49,24 @@ Private Property Get IFilterFormCodeBuilder_ClassInitalisationCode( _ Optional ByVal RemoveFilterCtlName As String, _ Optional ByVal AutoFilterCtlName As String, _ Optional ByVal FilterControlTagConverterMode As Long = 0) As String - + Dim Code As String Code = _ "Private Sub m_FilterControlManager_FilterStringChanged(ByVal NewFilterString As String)" & vbNewLine & _ " ApplyFilter NewFilterString" & vbNewLine & _ "End Sub" & vbNewLine - + If Len(ApplyFilterCtlName) > 0 Then Code = Code & vbNewLine & _ "Private Sub m_FilterControlManager_FilterValuesChanged()" & vbNewLine & _ " SetApplyFilterSignal" & vbNewLine & _ "End Sub" & vbNewLine - + Code = Code & vbNewLine & _ "Private Sub SetApplyFilterSignal()" & vbNewLine & _ "' " & L10n.Text("Notwendigen Klick auf ""Filter anwenden"" signalisieren") & vbNewLine - + If Len(AutoFilterCtlName) > 0 Then Code = Code & _ " If Me." & AutoFilterCtlName & ".Value = False Then" & vbNewLine & _ @@ -85,10 +76,10 @@ Private Property Get IFilterFormCodeBuilder_ClassInitalisationCode( _ Code = Code & _ " Me." & ApplyFilterCtlName & ".FontBold = True" & vbNewLine End If - + Code = Code & _ "End Sub" & vbNewLine - + End If Code = Code & vbNewLine & _ @@ -99,7 +90,7 @@ Private Property Get IFilterFormCodeBuilder_ClassInitalisationCode( _ " Set m_FilterControlManager = New FilterControlManager" & vbNewLine & _ " m_FilterControlManager.ConfigSqlFormat """ & SqlDateFormat & """, """ & SqlBooleanTrueString & """, """ & SqlWildCardString & """" & vbNewLine & _ " InitFilterControls" & vbNewLine - + If Len(AutoFilterCtlName) Then Code = Code & " m_FilterControlManager.AutoFilterOn = Nz(Me." & AutoFilterCtlName & ".Value, False)" & vbNewLine Else @@ -115,7 +106,7 @@ Private Property Get IFilterFormCodeBuilder_ClassInitalisationCode( _ Code = Code & vbNewLine & _ GetInitFilterControlsCode(FilterControlCodeLines, FilterControlTagConverterMode <> 0, FilterControlTagConverterMode = 2) - + Code = Code & vbNewLine & _ GetRemoveFilterCode() @@ -124,22 +115,22 @@ Private Property Get IFilterFormCodeBuilder_ClassInitalisationCode( _ End Property Private Function GetInitFilterControlsCode(ByVal FilterControlCodeLines As String, ByVal UseFilterControlTagConverter As Boolean, ByVal UseHeaderControls As Boolean) As String - + Dim Code As String Dim ControlsCollectionCode As String Code = _ "Private Sub InitFilterControls()" & vbNewLine & _ vbNewLine - + If UseFilterControlTagConverter Then - + If UseHeaderControls Then ControlsCollectionCode = "Me.Section(acHeader).Controls" Else ControlsCollectionCode = "Me.Controls" End If - + Code = Code & _ " With New FilterControlTagConverter" & vbNewLine & _ " .AddFilterControls FilterControlManager.FilterControls, " & ControlsCollectionCode & vbNewLine & _ @@ -152,11 +143,11 @@ Private Function GetInitFilterControlsCode(ByVal FilterControlCodeLines As Strin vbNewLine & _ " End With" & vbNewLine End If - + Code = Code & _ vbNewLine & _ "End Sub" & vbNewLine - + GetInitFilterControlsCode = Code End Function @@ -188,13 +179,13 @@ End Function Private Function IFilterFormCodeBuilder_GetFilterControlCodeLine(ByVal DataField As String, ByVal DataType As String, ByVal RelationalOperator As String, _ ByVal Control As String, ByVal Control2 As String) As String - + Dim FcLine As String CheckControlRefCode Control FcLine = "Add """ & DataField & """, " & DataType & ", " & RelationalOperator & ", " & Control - + If Len(Control2) > 0 Then CheckControlRefCode Control2 FcLine = FcLine & ", " & Control2 @@ -213,9 +204,9 @@ Private Function IFilterFormCodeBuilder_GetMultiFilterControlCodeLine(ByVal Data For i = LBound(ControlArray) To UBound(ControlArray) CheckControlRefCode ControlArray(i) Next - + FcLine = "AddMultiControlCriteria """ & DataField & """, " & DataType & ", " & RelationalOperator & ", Null, " & Join(ControlArray, ", ") - + IFilterFormCodeBuilder_GetMultiFilterControlCodeLine = FcLine End Function @@ -239,8 +230,8 @@ Private Function GetRemoveFilterCode() As String Dim Code As String Code = "Private Sub RemoveFilter()" & vbNewLine & _ - "' FilterControlManager.RemoveFilter ""1=0"" ' 1=0 .. " & L10n.Text("damit nach dem Entfernen der Filterwerte keine Datensätze angezeigt werden") & vbNewLine & _ - " FilterControlManager.RemoveFilter ' " & L10n.Text("ohne Parameterübergabe werden alle Datensätze angezeigt") & vbNewLine & _ + "' FilterControlManager.RemoveFilter ""1=0"" ' 1=0 .. " & L10n.Text("damit nach dem Entfernen der Filterwerte keine Datensätze angezeigt werden") & vbNewLine & _ + " FilterControlManager.RemoveFilter ' " & L10n.Text("ohne Parameterübergabe werden alle Datensätze angezeigt") & vbNewLine & _ "End Sub" & vbNewLine GetRemoveFilterCode = Code diff --git a/source/FilterFormCodeImporter.cls b/source/modules/FilterFormCodeImporter.cls similarity index 94% rename from source/FilterFormCodeImporter.cls rename to source/modules/FilterFormCodeImporter.cls index f21dd8c..9e0ed7c 100644 --- a/source/FilterFormCodeImporter.cls +++ b/source/modules/FilterFormCodeImporter.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -17,16 +17,6 @@ Attribute VB_Exposed = False ' Josef Poetzl ' '--------------------------------------------------------------------------------------- - -'--------------------------------------------------------------------------------------- -' -' %AppFolder%/source/FilterFormCodeImporter.cls -' _codelib/license.bas -' _codelib/addins/shared/CodeModuleWriter.cls -' _codelib/addins/shared/AppFileCodeModulTransfer.cls -' %AppFolder%/source/IFilterFormCodeBuilder.cls -' -'--------------------------------------------------------------------------------------- ' Option Compare Database Option Explicit @@ -72,9 +62,9 @@ Friend Sub WriteToForm(ByVal FormName As String, _ Optional ByVal RemoveFilterCtlName As String, _ Optional ByVal AutoFilterCtlName As String, _ Optional ByVal FilterControlTagConverterMode As Long = 0) - + CheckRequiredCodeModules CodeModulImporter - + If CurrentProject.AllForms(FormName).IsLoaded Then DoCmd.Close acForm, FormName End If @@ -111,56 +101,56 @@ Private Sub AddCodeToForm(ByVal FrmRef As Form, _ With New CodeModuleWriter .Load "Form_" & FrmRef.Name - + TempCode = DeclarationCode If Len(TempCode) > 0 Then TempCode = TempCode & vbNewLine End If - + TempCode = TempCode & _ ClassInitalisationCode(KindOfApplyFilterMethode, ApplyFilterMethodeSubFormName, _ SqlDateFormat, SqlBooleanTrueString, SqlWildCardString, _ ApplyFilterCtlName, RemoveFilterCtlName, AutoFilterCtlName, FilterControlTagConverterMode) .AddCode TempCode - + TempCode = FormLoadCode If Len(TempCode) > 0 Then .AddCodeToEventProcedure "Load", "Form", TempCode End If - + TempCode = FormUnLoadCode If Len(TempCode) > 0 Then .AddCodeToEventProcedure "Unload", "Form", TempCode End If - + If Len(ApplyFilterCtlName) > 0 Then TempCode = ApplyFilterCtlCode If Len(TempCode) > 0 Then .AddCodeToEventProcedure "Click", ApplyFilterCtlName, TempCode End If End If - + If Len(AutoFilterCtlName) > 0 Then TempCode = AutoFilterCtlCode(AutoFilterCtlName) If Len(TempCode) > 0 Then .AddCodeToEventProcedure "Click", AutoFilterCtlName, TempCode End If End If - + If Len(RemoveFilterCtlName) > 0 Then TempCode = RemoveFilterCtlCode If Len(TempCode) > 0 Then .AddCodeToEventProcedure "Click", RemoveFilterCtlName, TempCode End If End If - + TempCode = FilterControlValueChangedEventFunction(ApplyFilterCtlName, AutoFilterCtlName) If Len(TempCode) > 0 Then .AddCode TempCode InsertFilterControlValueChangedEventFunction FrmRef End If - + End With End Sub @@ -188,7 +178,7 @@ Private Property Get ClassInitalisationCode( _ ByVal RemoveFilterCtlName As String, _ ByVal AutoFilterCtlName As String, _ ByVal FilterControlTagConverterMode As Long) As String - + ClassInitalisationCode = m_Importer.ClassInitalisationCode( _ GetApplyFilterMethodeCode(KindOfApplyFilterMethode, ApplyFilterMethodeSubFormName, ApplyFilterCtlName, False), _ GetFilterControlCodeLines, m_FilterControlNames, _ @@ -202,11 +192,11 @@ Private Function GetApplyFilterMethodeCode( _ ByVal ApplyFilterMethodeSubFormName As String, _ ByVal ApplyFilterCtlName As String, _ ByVal AddDebugLine As Boolean) As String - + Dim MethodeCode As String Dim SufFormRefCode As String Dim LinePrefix As String - + Select Case KindOfApplyFilterMethode Case 0 LinePrefix = "'" @@ -225,25 +215,25 @@ Private Function GetApplyFilterMethodeCode( _ MethodeCode = _ "Private Sub ApplyFilter(ByVal NewFilterString As String)" & vbNewLine - + If AddDebugLine Then MethodeCode = MethodeCode & vbNewLine & _ " Debug.Print ""FilterText:""; NewFilterString" & vbNewLine End If - + MethodeCode = MethodeCode & _ vbNewLine & _ LinePrefix & " With Me" & SufFormRefCode & vbNewLine & _ LinePrefix & " .Filter = NewFilterString" & vbNewLine & _ LinePrefix & " .FilterOn = (Len(.Filter) > 0)" & vbNewLine & _ LinePrefix & " End With" & vbNewLine - - + + If Len(ApplyFilterCtlName) > 0 Then MethodeCode = MethodeCode & vbNewLine & _ " Me." & ApplyFilterCtlName & ".FontBold = False" & vbNewLine End If - + MethodeCode = MethodeCode & vbNewLine & _ "End Sub" @@ -291,7 +281,7 @@ Private Property Get FilterControlValueChangedEventFunction(ByVal ApplyFilterCtl End Property Private Sub InsertFilterControlValueChangedEventFunction(ByVal FormRef As Form) - + Dim FcltName As Variant Dim ctl As Control @@ -301,17 +291,17 @@ Private Sub InsertFilterControlValueChangedEventFunction(ByVal FormRef As Form) ctl.AfterUpdate = "=FilterControlValueChanged()" End If Next - + End Sub Public Sub AddFilterControlDefinition(ByVal DataField As String, ByVal DataType As String, ByVal RelationalOperator As String, _ ByVal Control As String, ByVal Control2 As String) - + Dim ControlArray() As String If Len(Control2) > 0 Then If Not (RelationalOperator Like "*SQL_Between*") Then - ' Control + Control2 werden nur bei Between benötigt => Rest: MultiFilterControlCodeLine + ' Control + Control2 werden nur bei Between benötigt => Rest: MultiFilterControlCodeLine If Len(Control) > 0 Then If Len(Control2) > 0 Then Control2 = "," & Control2 @@ -335,7 +325,7 @@ Public Sub AddFilterControlDefinition(ByVal DataField As String, ByVal DataType If Len(Control2) > 0 Then m_FilterControlNames.Add Control2 End If - + m_FilterControlLines.Add GetFilterControlCodeLine(DataField, DataType, RelationalOperator, Control, Control2) End Sub diff --git a/source/FilterStringBuilderCodeBuilder.cls b/source/modules/FilterStringBuilderCodeBuilder.cls similarity index 93% rename from source/FilterStringBuilderCodeBuilder.cls rename to source/modules/FilterStringBuilderCodeBuilder.cls index 94b0e3a..ff7f366 100644 --- a/source/FilterStringBuilderCodeBuilder.cls +++ b/source/modules/FilterStringBuilderCodeBuilder.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -17,15 +17,6 @@ Attribute VB_Exposed = False ' Josef Poetzl ' '--------------------------------------------------------------------------------------- - -'--------------------------------------------------------------------------------------- -' -' %AppFolder%/source/FilterStringBuilderCodeBuilder.cls -' _codelib/license.bas -' %AppFolder%/source/IFilterFormCodeBuilder.cls -' _codelib/addins/shared/AppFileCodeModulTransfer.cls -' -'--------------------------------------------------------------------------------------- ' Option Compare Database Option Explicit @@ -57,11 +48,11 @@ Private Property Get IFilterFormCodeBuilder_ClassInitalisationCode( _ Optional ByVal RemoveFilterCtlName As String, _ Optional ByVal AutoFilterCtlName As String, _ Optional ByVal FilterControlTagConverterMode As Long = 0) As String - + Dim Code As String Code = GetRefreshFilterCode() & vbNewLine - + Code = Code & vbNewLine & _ ApplyFilterMethodeCode & vbNewLine @@ -78,7 +69,7 @@ Private Property Get IFilterFormCodeBuilder_ClassInitalisationCode( _ " End With" & vbNewLine & _ vbNewLine & _ "End Function" & vbNewLine - + Code = Code & vbNewLine & _ GetRemoveFilterCode(ApplyFilterCtlName, FilterControlNames) @@ -106,7 +97,7 @@ Private Function GetRemoveFilterCode(ByVal ApplyFilterCtlName As String, ByVal F " RemoveFilterValues" & vbNewLine & _ "' ApplyFilter ""0=1"" ' " & L10n.Text("Don't show records") & vbNewLine & _ " ApplyFilter vbNullString ' " & L10n.Text("Show all records") & vbNewLine - + If Len(ApplyFilterCtlName) > 0 Then Code = Code & _ " Me." & ApplyFilterCtlName & ".FontBold = False" & vbNewLine @@ -114,7 +105,7 @@ Private Function GetRemoveFilterCode(ByVal ApplyFilterCtlName As String, ByVal F Code = Code & _ "End Sub" & vbNewLine - + Code = Code & vbNewLine & GetRemoveFilterValuesCode(FilterControlNames) GetRemoveFilterCode = Code @@ -122,7 +113,7 @@ Private Function GetRemoveFilterCode(ByVal ApplyFilterCtlName As String, ByVal F End Function Private Function GetRemoveFilterValuesCode(ByVal FilterControlNames As StringCollection) As String - + Dim Code As String Code = "Private Sub RemoveFilterValues()" & vbNewLine & _ @@ -131,30 +122,30 @@ Private Function GetRemoveFilterValuesCode(ByVal FilterControlNames As StringCol " fctl.Value = Null" & vbNewLine & _ " Next" & vbNewLine & _ "End Sub" & vbNewLine - + Code = Code & vbNewLine & GetGetFilterControlsCode(FilterControlNames) GetRemoveFilterValuesCode = Code - + End Function Private Function GetGetFilterControlsCode(ByVal FilterControlNames As StringCollection) As String - + Dim Code As String Code = "Private Function GetFilterControls() As Collection" & vbNewLine & _ " Dim fctlCol As Collection" & vbNewLine & vbNewLine & _ " Set fctlCol = New Collection" & vbNewLine & _ " '" & L10n.Text("Add filter controls") & ":" & vbNewLine - + Code = Code & FilterControlNames.ToString(vbNewLine, " fctlCol.Add Me.", , True) & vbNewLine - + Code = Code & _ " Set GetFilterControls = fctlCol" & vbNewLine & _ "End Function" '& vbNewLine - + GetGetFilterControlsCode = Code - + End Function @@ -184,13 +175,13 @@ End Function Private Function IFilterFormCodeBuilder_GetFilterControlCodeLine(ByVal DataField As String, ByVal DataType As String, ByVal RelationalOperator As String, _ ByVal Control As String, ByVal Control2 As String) As String - + Dim FcLine As String CheckControlRefCode Control FcLine = "Add """ & DataField & """, " & DataType & ", " & RelationalOperator & ", " & Control - + If Len(Control2) > 0 Then CheckControlRefCode Control2 FcLine = FcLine & ", " & Control2 @@ -209,7 +200,7 @@ Private Function IFilterFormCodeBuilder_GetMultiFilterControlCodeLine(ByVal Data For i = LBound(ControlArray) To UBound(ControlArray) CheckControlRefCode ControlArray(i) Next - + FcLine = "Add """ & DataField & """, " & DataType & ", , " & RelationalOperator & ", Array(" & Join(ControlArray, ", ") & "), , Null" IFilterFormCodeBuilder_GetMultiFilterControlCodeLine = FcLine @@ -233,38 +224,38 @@ Private Function GetControlValueChangedCode(ByVal ApplyFilterCtlName As String, Dim Code As String Dim ApplyFilterCtlLine As String - + If Len(ApplyFilterCtlName) + Len(AutoFilterCtlName) = 0 Then GetControlValueChangedCode = vbNullString Exit Function End If Code = "Private Function FilterControlValueChanged()" & vbNewLine - + If Len(ApplyFilterCtlName) > 0 Then ApplyFilterCtlLine = " Me." & ApplyFilterCtlName & ".FontBold = True" & vbNewLine End If - + If Len(AutoFilterCtlName) > 0 Then Code = Code & _ " If Me." & AutoFilterCtlName & ".Value = True Then" & vbNewLine & _ " RefreshFilter" & vbNewLine - + If Len(ApplyFilterCtlName) > 0 Then Code = Code & _ " Else" & vbNewLine & _ " " & ApplyFilterCtlLine End If - + Code = Code & _ " End If" & vbNewLine Else Code = Code & ApplyFilterCtlLine End If - + Code = Code & _ "End Function" - + GetControlValueChangedCode = Code - + End Function diff --git a/source/codelib/_codelib/addins/shared/FormDesigner.cls b/source/modules/FormDesigner.cls similarity index 97% rename from source/codelib/_codelib/addins/shared/FormDesigner.cls rename to source/modules/FormDesigner.cls index b2d0d37..5e457ca 100644 --- a/source/codelib/_codelib/addins/shared/FormDesigner.cls +++ b/source/modules/FormDesigner.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -51,22 +51,22 @@ Public Property Let FormName(ByVal NewValue As String) End Property Private Function GetFormInDesignMode(ByVal FormName As String) As Form - + Dim FormIsLoaded As Boolean - + FormIsLoaded = CurrentProject.AllForms(FormName).IsLoaded - + If FormIsLoaded Then If Application.Forms(FormName).CurrentView <> 0 Then DoCmd.Close acForm, FormName FormIsLoaded = False End If End If - + If Not FormIsLoaded Then DoCmd.OpenForm FormName, acDesign, , , , acWindowNormal End If - + Set GetFormInDesignMode = Application.Forms(FormName) End Function @@ -76,58 +76,58 @@ Public Function AddControl(ByVal ControlType As AcControlType, ByVal ControlName Optional ByVal ControlWidth As Variant, Optional ByVal ControlHeight As Variant, _ Optional ByVal DistanceBetweenControls As Long = 72, _ Optional ByVal InsertLabelControl As Boolean = True, Optional ByVal LabelControlCaption As String) As Control - + Dim ctl As Control Dim LabelCtl As Label - + Dim NextFreeLeftPos As Long, NextFreeTopPos As Long If IsMissing(LeftPos) Or IsMissing(TopPos) Then FindNextControlPos Section, NextFreeLeftPos, NextFreeTopPos, DistanceBetweenControls If IsMissing(LeftPos) Then LeftPos = NextFreeLeftPos If IsMissing(TopPos) Then TopPos = NextFreeTopPos End If - + Set ctl = Application.CreateControl(m_Form.Name, ControlType, Section, , , LeftPos, TopPos, ControlWidth, ControlHeight) - + If Len(ControlName) > 0 Then ControlName = GetCheckedControlName(ControlName) ctl.Name = ControlName End If - + Set AddControl = ctl - + If InsertLabelControl Then - + If Len(LabelControlCaption) = 0 Then LabelControlCaption = ControlName End If - + Set LabelCtl = Application.CreateControl(m_Form.Name, acLabel, Section, ctl.Name, , LeftPos, TopPos, ctl.Width, ctl.Height) LabelCtl.Name = GetCheckedControlName("lab" & ctl.Name) LabelCtl.Caption = LabelControlCaption ctl.Top = LabelCtl.Top + LabelCtl.Height End If - + End Function Private Function GetCheckedControlName(ByVal ControlName As String) As String - + Dim CheckedControlName As String Dim i As Long - + CheckedControlName = ControlName Do While ControlExists(CheckedControlName) i = i + 1 CheckedControlName = ControlName & i Loop - + GetCheckedControlName = CheckedControlName - + End Function Private Function ControlExists(ByVal ControlName As String) As Boolean - + Dim ctl As Control For Each ctl In m_Form.Controls If ctl.Name = ControlName Then @@ -144,9 +144,9 @@ Private Sub FindNextControlPos(ByVal ControlSection As AcSection, ByRef LeftPos Dim MinLeft As Long Dim MaxTop As Long Dim ErrCnt As Long - + On Error GoTo HandleErr - + If m_Form.Section(ControlSection).Controls.Count > 0 Then MinLeft = m_Form.InsideWidth For Each ctl In m_Form.Section(ControlSection).Controls @@ -158,19 +158,19 @@ On Error GoTo HandleErr End If Next End If - + If MinLeft = 0 Then MinLeft = DistanceBetweenControls End If LeftPos = MinLeft - + TopPos = MaxTop + DistanceBetweenControls Exit Sub - + HandleErr: If Err.Number = 2462 Then 'auf Section kann nicht zugegriffen werden - + Select Case ControlSection Case acHeader, acFooter m_Form.SetFocus @@ -178,12 +178,12 @@ HandleErr: Case acPageHeader, acPageFooter DoCmd.RunCommand acCmdPageHdrFtr End Select - + If ErrCnt < 2 Then ErrCnt = ErrCnt + 1 Resume End If - + End If Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext diff --git a/source/IFilterFormCodeBuilder.cls b/source/modules/IFilterFormCodeBuilder.cls similarity index 87% rename from source/IFilterFormCodeBuilder.cls rename to source/modules/IFilterFormCodeBuilder.cls index a48fc80..46abd62 100644 --- a/source/IFilterFormCodeBuilder.cls +++ b/source/modules/IFilterFormCodeBuilder.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -17,14 +17,6 @@ Attribute VB_Exposed = False ' Josef Poetzl ' '--------------------------------------------------------------------------------------- - -'--------------------------------------------------------------------------------------- -' -' %AppFolder%/source/IFilterFormCodeBuilder.cls -' _codelib/license.bas -' _codelib/addins/shared/AppFileCodeModulTransfer.cls -' -'--------------------------------------------------------------------------------------- ' Option Compare Database Option Explicit diff --git a/source/codelib/localization/L10nDict.cls b/source/modules/L10nDict.cls similarity index 98% rename from source/codelib/localization/L10nDict.cls rename to source/modules/L10nDict.cls index 9858e10..d9eb7c6 100644 --- a/source/codelib/localization/L10nDict.cls +++ b/source/modules/L10nDict.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -77,11 +77,11 @@ Private Sub FillDict() Dim rst As DAO.Recordset Dim Key As DAO.Field Dim Msg As DAO.Field - + Set m_Dict = CreateObject("Scripting.Dictionary") - + On Error GoTo HandleErr - + Set rst = CodeDb.OpenRecordset("select KeyText, LngText from " & LngDictTableName & " where " & SqlTools.BuildCriteria("LangCode", SQL_Text, SQL_Equal, LangCode), dbOpenForwardOnly) With rst Set Key = .Fields("KeyText") @@ -94,11 +94,11 @@ On Error GoTo HandleErr rst.MoveNext Loop End With - + rst.Close - + RaiseEvent DictionaryRefreshed - + Exit Sub HandleErr: @@ -114,21 +114,21 @@ End Sub Friend Function CreateL10nDictTable() As Boolean Dim CreateTableDDL As String - + On Error GoTo HandleErr - + CreateTableDDL = "create table " & LngDictTableName & "(" & _ " LangCode varchar(2), KeyText varchar(255), LngText varchar(255)" & _ ", CONSTRAINT PK_" & LngDictTableName & " PRIMARY KEY (LangCode, KeyText)" & _ ")" - + CodeProject.Connection.Execute CreateTableDDL Application.RefreshDatabaseWindow - + CreateL10nDictTable = True - + Exit Function - + HandleErr: CreateL10nDictTable = False @@ -176,9 +176,9 @@ End Property Public Function GetUserLanguageID() As Long Dim AccApp As Object - + Set AccApp = Application - + On Error GoTo AccAppInterFaceErr GetUserLanguageID = AccApp.LanguageSettings.LanguageID(2) @@ -206,14 +206,14 @@ Public Function ControlTag(ByVal TagText As String) As String End Function Private Sub AddTextToTable(ByVal BaseText As String) - + Dim LngText As String - + LngText = BaseText If m_LangCode <> BaseLangCode Then LngText = m_LangCode & ":" & LngText End If - + With CodeDb.OpenRecordset(LngDictTableName, dbOpenTable, dbAppendOnly) .AddNew .Fields("LangCode").Value = LangCode @@ -222,13 +222,13 @@ Private Sub AddTextToTable(ByVal BaseText As String) .Update .Close End With - + End Sub Public Sub TranslateControls(ByVal ControlList As Controls) Dim ctl As Control - + For Each ctl In ControlList TranslateControl ctl Next @@ -247,11 +247,11 @@ Private Sub TranslateControl(ByVal CtlRef As Control) TextKeySeparatorString = Chr(1) TagText = CtlRef.Tag - + If Len(TagText) = 0 Then Exit Sub End If - + Pos = InStr(1, TagText, LangSeparatorChar & "LANG:") If Pos > 0 Then TagTextPrefix = Left(TagText, Pos) @@ -275,9 +275,9 @@ Private Sub TranslateControl(ByVal CtlRef As Control) End If End If End With - + SetControlText CtlRef, ControlTextKeys - + End Sub Private Function GetControlTextKeys(ByVal CtlRef As Control) As String() @@ -290,7 +290,7 @@ Private Function GetControlTextKeys(ByVal CtlRef As Control) As String() With CtlRef ControlTipText = .ControlTipText - + Select Case .ControlType Case AcControlType.acLabel CaptionText = .Caption @@ -304,12 +304,12 @@ Private Function GetControlTextKeys(ByVal CtlRef As Control) As String() StatusBarText = .StatusBarText End Select End With - + ControlTextKeys(0) = CaptionText ControlTextKeys(1) = ControlTipText ControlTextKeys(2) = StatusBarText ControlTextKeys(3) = FormatText - + GetControlTextKeys = ControlTextKeys End Function @@ -320,19 +320,19 @@ Private Sub SetControlText(ByVal CtlRef As Control, ByRef ControlTextKeys() As S If Len(ControlTextKeys(0)) > 0 Then .Caption = Text(ControlTextKeys(0)) End If - + If Len(ControlTextKeys(1)) > 0 Then .ControlTipText = Text(ControlTextKeys(1)) End If - + If Len(ControlTextKeys(2)) > 0 Then .StatusBarText = Text(ControlTextKeys(2)) End If - + If Len(ControlTextKeys(3)) > 0 Then .Format = Text(ControlTextKeys(3)) End If - + End With End Sub @@ -342,15 +342,15 @@ Public Function MsgBox(ByVal Prompt As Variant, _ Optional ByVal Title As Variant, _ Optional ByVal HelpFile As Variant, _ Optional ByVal Context As Variant) As VbMsgBoxResult - + If Not IsMissing(Prompt) Then Prompt = Me.Text(Prompt) End If - + If Not IsMissing(Title) Then Title = Me.Text(Title) End If - + MsgBox = VBA.MsgBox(Prompt, Buttons, Title, HelpFile, Context) End Function @@ -365,11 +365,11 @@ Public Function InputBox(ByVal Prompt As Variant, _ If Not IsMissing(Prompt) Then Prompt = Me.Text(Prompt) End If - + If Not IsMissing(Title) Then Title = Me.Text(Title) End If - + InputBox = VBA.InputBox(Prompt, Title, Default, XPos, YPos, HelpFile, Context) End Function diff --git a/source/codelib/localization/L10nTools.bas b/source/modules/L10nTools.bas similarity index 97% rename from source/codelib/localization/L10nTools.bas rename to source/modules/L10nTools.bas index 8c54552..b8c056e 100644 --- a/source/codelib/localization/L10nTools.bas +++ b/source/modules/L10nTools.bas @@ -1,4 +1,4 @@ -Attribute VB_Name = "L10nTools" +Attribute VB_Name = "L10nTools" '--------------------------------------------------------------------------------------- ' Package: localization.L10nTools '--------------------------------------------------------------------------------------- @@ -6,7 +6,7 @@ Attribute VB_Name = "L10nTools" ' Localization (L10n) Functions ' ' Author: -' Josef Pötzl +' Josef Pötzl ' ' Remarks: ' Use compiler constant L10nMsgBoxReplacement to overwrite MsgBox and InPutBox functions. diff --git a/source/codelib/data/SqlTools.cls b/source/modules/SqlTools.cls similarity index 82% rename from source/codelib/data/SqlTools.cls rename to source/modules/SqlTools.cls index d054208..997606c 100644 --- a/source/codelib/data/SqlTools.cls +++ b/source/modules/SqlTools.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -51,13 +51,17 @@ Private Const SQL_DEFAULT_BOOLTRUESTRING As String = "" ' "" => SqlBooleanTrueSt ' Enter value to disable (e.g. "True or 1") Private Const SQL_DEFAULT_WILDCARD As String = "%" ' % = default value, ' set required variations via SqlWildCardString - + Private Const SqlAndConcatString As String = " And " Private Const SqlOrConcatString As String = " Or " -Private m_SqlDateFormat As String -Private m_SqlBooleanTrueString As String -Private m_SqlWildCardString As String +Private Type SqlFormatSettings + SqlDateFormat As String + SqlBooleanTrueString As String + SqlWildCardString As String +End Type + +Private m_SqlFormat As SqlFormatSettings Private Const ResultTextIfNull As String = "Null" @@ -91,9 +95,61 @@ Public Enum SqlLogicalOperator SQL_CommaSeparator = 3 End Enum +Public Enum SqlDialect + SQL_Custom = 0 + SQL_DAO = 1 + SQL_TSQL = 2 +End Enum + '################################## ' Group: Class support +'--------------------------------------------------------------------------------------- +' Function: SelectDialect +'--------------------------------------------------------------------------------------- +' +' Create a new instance with basic settings of the selected dialect +' +' Parameters: +' +' UseDialect - use setting of dialect (as base) +' NewSqlDateFormat - use this date format instead of base dialect +' NewSqlBooleanTrueString - use this text for true instead of base dialect +' NewSqlWildCardString - use this wildcard string instead of base dialect +' +' Returns: +' +' SqlTools instance with config form base +' +' See Also: +' NewInstance +' +'--------------------------------------------------------------------------------------- +Public Function FromDialect(ByVal UseDialect As SqlDialect, _ + Optional ByVal NewSqlDateFormat As String = SQL_DEFAULT_DATEFORMAT, _ + Optional ByVal NewSqlBooleanTrueString As String = SQL_DEFAULT_BOOLTRUESTRING, _ + Optional ByVal NewSqlWildCardString As String = SQL_DEFAULT_WILDCARD) As SqlTools + + Dim NewSlqToolsInstance As SqlTools + + Select Case UseDialect + Case SqlDialect.SQL_DAO + Set NewSlqToolsInstance = Me.DAO + Case SqlDialect.SQL_TSQL + Set NewSlqToolsInstance = Me.TSql + Case Else + Set NewSlqToolsInstance = Me.Clone + End Select + + If Len(NewSqlDateFormat) > 0 Then NewSlqToolsInstance.SqlDateFormat = NewSqlDateFormat + If Len(NewSqlBooleanTrueString) > 0 Then NewSlqToolsInstance.SqlBooleanTrueString = NewSqlBooleanTrueString + If Len(NewSqlWildCardString) > 0 Then NewSlqToolsInstance.SqlWildCardString = NewSqlWildCardString + + Set FromDialect = NewSlqToolsInstance + +End Function + + '--------------------------------------------------------------------------------------- ' Function: Clone '--------------------------------------------------------------------------------------- @@ -118,7 +174,6 @@ Public Function Clone(Optional ByVal NewSqlDateFormat As String = SQL_DEFAULT_DA Optional ByVal NewSqlBooleanTrueString As String = SQL_DEFAULT_BOOLTRUESTRING, _ Optional ByVal NewSqlWildCardString As String = SQL_DEFAULT_WILDCARD) As SqlTools - If Len(NewSqlDateFormat) = 0 Then NewSqlDateFormat = Me.SqlDateFormat If Len(NewSqlBooleanTrueString) = 0 Then NewSqlBooleanTrueString = Me.SqlBooleanTrueString If Len(NewSqlWildCardString) = 0 Then NewSqlWildCardString = Me.SqlWildCardString @@ -137,7 +192,7 @@ End Function Public Function NewInstance(ByVal NewSqlDateFormat As String, _ ByVal NewSqlBooleanTrueString As String, _ ByVal NewSqlWildCardString As String) As SqlTools - + Dim NewInst As SqlTools Set NewInst = New SqlTools @@ -151,6 +206,66 @@ Public Function NewInstance(ByVal NewSqlDateFormat As String, _ End Function +'--------------------------------------------------------------------------------------- +' Function: InitSqlDialect +'--------------------------------------------------------------------------------------- +' +' Config sql text output format for specific sql dialect +' +' Parameters: +' +' SqlDateFormat - output string format for date values +' SqlBooleanTrueString - output string format for boolean values +' SqlWildCardString - wildcard string (e.g. * .. dao, % .. T-SQL) +' +'--------------------------------------------------------------------------------------- +Friend Sub InitSqlDialect(ByVal UseDialect As SqlDialect, _ + Optional ByVal NewSqlDateFormat As String = SQL_DEFAULT_DATEFORMAT, _ + Optional ByVal NewSqlBooleanTrueString As String = SQL_DEFAULT_BOOLTRUESTRING, _ + Optional ByVal NewSqlWildCardString As String = SQL_DEFAULT_WILDCARD) + + Dim SqlFormat As SqlFormatSettings + + Select Case UseDialect + Case SqlDialect.SQL_DAO + SqlFormat = DaoSqlFormat + Case SqlDialect.SQL_TSQL + SqlFormat = TSqlSqlFormat + Case Else + ' set nothing => use NewSql* parameter + End Select + + If Len(NewSqlDateFormat) > 0 Then SqlFormat.SqlDateFormat = NewSqlDateFormat + If Len(NewSqlBooleanTrueString) > 0 Then SqlFormat.SqlBooleanTrueString = NewSqlBooleanTrueString + If Len(NewSqlWildCardString) > 0 Then SqlFormat.SqlWildCardString = NewSqlWildCardString + + InitSqlFormat SqlFormat.SqlDateFormat, SqlFormat.SqlBooleanTrueString, SqlFormat.SqlWildCardString + + +End Sub + +'--------------------------------------------------------------------------------------- +' Function: InitSqlFormat +'--------------------------------------------------------------------------------------- +' +' Config sql text output format for specific sql dialect +' +' Parameters: +' +' SqlDateFormat - output string format for date values +' SqlBooleanTrueString - output string format for boolean values +' SqlWildCardString - wildcard string (e.g. * .. dao, % .. T-SQL) +' +'--------------------------------------------------------------------------------------- +Friend Sub InitSqlFormat(ByVal SqlDateFormat As String, _ + ByVal SqlBooleanTrueString As String, _ + ByVal SqlWildCardString As String) + + Me.SqlDateFormat = SqlDateFormat + Me.SqlBooleanTrueString = SqlBooleanTrueString + Me.SqlWildCardString = SqlWildCardString + +End Sub '################################## ' Group: SQL dialect preferences @@ -163,7 +278,21 @@ End Function ' '--------------------------------------------------------------------------------------- Public Property Get DAO() As SqlTools - Set DAO = Me.NewInstance("\#yyyy-mm-dd hh:nn:ss\#", "True", "*") + With DaoSqlFormat + Set DAO = Me.NewInstance(.SqlDateFormat, .SqlBooleanTrueString, .SqlWildCardString) + End With +End Property + +Private Property Get DaoSqlFormat() As SqlFormatSettings + + Dim SqlFormat As SqlFormatSettings + + SqlFormat.SqlDateFormat = "\#yyyy-mm-dd hh:nn:ss\#" + SqlFormat.SqlBooleanTrueString = "True" + SqlFormat.SqlWildCardString = "*" + + DaoSqlFormat = SqlFormat + End Property '--------------------------------------------------------------------------------------- @@ -174,7 +303,21 @@ End Property ' '--------------------------------------------------------------------------------------- Public Property Get TSql() As SqlTools - Set TSql = Me.NewInstance("'yyyymmdd hh:nn:ss'", "1", "%") + With TSqlSqlFormat + Set TSql = Me.NewInstance(.SqlDateFormat, .SqlBooleanTrueString, .SqlWildCardString) + End With +End Property + +Private Property Get TSqlSqlFormat() As SqlFormatSettings + + Dim SqlFormat As SqlFormatSettings + + SqlFormat.SqlDateFormat = "'yyyymmdd hh:nn:ss'" + SqlFormat.SqlBooleanTrueString = "1" + SqlFormat.SqlWildCardString = "%" + + TSqlSqlFormat = SqlFormat + End Property ' Configuration for SQL dialect @@ -187,15 +330,15 @@ End Property ' '--------------------------------------------------------------------------------------- Public Property Get SqlWildCardString() As String - If Len(m_SqlWildCardString) > 0 Then - SqlWildCardString = m_SqlWildCardString + If Len(m_SqlFormat.SqlWildCardString) > 0 Then + SqlWildCardString = m_SqlFormat.SqlWildCardString Else SqlWildCardString = SQL_DEFAULT_WILDCARD End If End Property Public Property Let SqlWildCardString(ByVal NewValue As String) - m_SqlWildCardString = NewValue + m_SqlFormat.SqlWildCardString = NewValue End Property '--------------------------------------------------------------------------------------- @@ -206,15 +349,15 @@ End Property ' '--------------------------------------------------------------------------------------- Public Property Get SqlDateFormat() As String - If Len(m_SqlDateFormat) > 0 Then - SqlDateFormat = m_SqlDateFormat + If Len(m_SqlFormat.SqlDateFormat) > 0 Then + SqlDateFormat = m_SqlFormat.SqlDateFormat Else SqlDateFormat = SQL_DEFAULT_DATEFORMAT End If End Property Public Property Let SqlDateFormat(ByVal NewValue As String) - m_SqlDateFormat = NewValue + m_SqlFormat.SqlDateFormat = NewValue End Property '--------------------------------------------------------------------------------------- @@ -225,15 +368,15 @@ End Property ' '--------------------------------------------------------------------------------------- Public Property Get SqlBooleanTrueString() As String - If Len(m_SqlBooleanTrueString) > 0 Then - SqlBooleanTrueString = m_SqlBooleanTrueString + If Len(m_SqlFormat.SqlBooleanTrueString) > 0 Then + SqlBooleanTrueString = m_SqlFormat.SqlBooleanTrueString Else SqlBooleanTrueString = SQL_DEFAULT_BOOLTRUESTRING End If End Property Public Property Let SqlBooleanTrueString(ByVal NewValue As String) - m_SqlBooleanTrueString = NewValue + m_SqlFormat.SqlBooleanTrueString = NewValue End Property '################################## @@ -266,31 +409,31 @@ Public Function BuildCriteria(ByVal FieldName As String, ByVal FieldDataType As Dim FilterValueString As String Dim OperatorString As String Dim Criteria As String - + If (RelationalOperator And [_IgnoreAll]) = [_IgnoreAll] Then Exit Function End If - + If IsMissing(IgnoreValue) Then If Not DisableIgnoreNullValue Then DisableIgnoreNullValue = True End If IgnoreValue = Null End If - + ' Special cases (part 1): If Not IsArray(FilterValue) Then - + If FilterValue = "{NULL}" Or FilterValue = "{LEER}" Or FilterValue = "{EMPTY}" Then FilterValue = Null DisableIgnoreNullValue = True End If - + If FilterValue2 = "{NULL}" Or FilterValue2 = "{LEER}" Or FilterValue2 = "{EMPTY}" Then FilterValue2 = Null DisableIgnoreNullValue = True End If - + If (RelationalOperator And SQL_AllowSqlDirect) = SQL_AllowSqlDirect Then If FilterValue Like "{*@*}" Then ' Idee von Ulrich: Anwender schreibt SQL-Ausdruck Criteria = Replace(Mid(FilterValue, 2, Len(FilterValue) - 2), "@", FieldName) @@ -301,42 +444,40 @@ Public Function BuildCriteria(ByVal FieldName As String, ByVal FieldDataType As Exit Function End If End If - + End If - + If NullFilterOrEmptyFilter(FieldName, FieldDataType, RelationalOperator, Nz(FilterValue, FilterValue2), IgnoreValue, Criteria, DisableIgnoreNullValue) Then BuildCriteria = Criteria Exit Function End If - - If (RelationalOperator And SQL_SplitValueToArray) = SQL_SplitValueToArray Then - If InStr(1, FilterValue, ";") > 0 Then - FilterValue = Split(CharTrim(FilterValue, ";"), ";") - End If - RelationalOperator = RelationalOperator Xor SQL_SplitValueToArray + + If TryBuildSplitToArrayCriteria(FieldName, FieldDataType, RelationalOperator, FilterValue, IgnoreValue, Criteria) Then + BuildCriteria = Criteria + Exit Function End If - + 'Special cases (part 2): If Not IsArray(FilterValue) Then - + If FieldDataType = SQL_Numeric Or FieldDataType = SQL_Date Then - + If FilterValue = "*" And RelationalOperator = SQL_Equal Then BuildCriteria = BuildCriteria(FieldName, FieldDataType, SQL_Not, Null, Null, 0, True) Exit Function End If - + If IsNull(FilterValue2) Then If TryBuildNumericSpecialCasesCriteria(FieldName, FieldDataType, RelationalOperator, FilterValue, IgnoreValue, DisableIgnoreNullValue, Criteria) Then BuildCriteria = Criteria Exit Function End If End If - + ConfigNumericSpecials RelationalOperator, FilterValue, FilterValue2 - + End If - + End If If TryBuildInCriteria(FieldName, FieldDataType, RelationalOperator, FilterValue, IgnoreValue, Criteria) Then @@ -387,7 +528,7 @@ Public Function BuildCriteria(ByVal FieldName As String, ByVal FieldDataType As BuildCriteria = FieldName & OperatorString & FilterValueString Exit Function End If - + OperatorString = GetRelationalOperatorString(RelationalOperator) Criteria = FieldName & " " & OperatorString & " " & FilterValueString @@ -420,7 +561,7 @@ End Function '--------------------------------------------------------------------------------------- Public Function ConvertToSqlText(ByVal Value As Variant, _ ByVal FieldDataType As SqlFieldDataType) As String - + Select Case FieldDataType Case SqlFieldDataType.SQL_Text ConvertToSqlText = TextToSqlText(Value) @@ -433,7 +574,7 @@ Public Function ConvertToSqlText(ByVal Value As Variant, _ Case Else Err.Raise vbObjectError, "SqlTools.ConvertToSqlText", "FieldDataType '" & FieldDataType & "' not supported" End Select - + End Function '--------------------------------------------------------------------------------------- @@ -458,19 +599,19 @@ End Function Public Function TextToSqlText(ByVal Value As Variant, _ Optional ByVal Delimiter As String = SQL_DEFAULT_TEXTDELIMITER, _ Optional ByVal WithoutLeftRightDelim As Boolean = False) As String - + Dim Result As String - + If IsNull(Value) Then TextToSqlText = ResultTextIfNull Exit Function End If - + Result = Replace$(Value, Delimiter, Delimiter & Delimiter) If Not WithoutLeftRightDelim Then Result = Delimiter & Result & Delimiter End If - + TextToSqlText = Result End Function @@ -496,7 +637,7 @@ Public Function DateToSqlText(ByVal Value As Variant, _ DateToSqlText = ResultTextIfNull Exit Function End If - + If Not IsDate(Value) Then Err.Raise vbObjectError, "SqlTools.DateToSqlText", "Der Wert '" & Value & "' vom Parameter Value ist kein Datumswert!" End If @@ -507,7 +648,7 @@ Public Function DateToSqlText(ByVal Value As Variant, _ Err.Raise SqlToolsErrorNumbers.ERRNR_NOCONFIG, "DateToSqlText", "date format is not defined" End If End If - + DateToSqlText = VBA.Format$(Value, FormatString) End Function @@ -537,26 +678,26 @@ Public Function NumberToSqlText(ByVal Value As Variant) As String NumberToSqlText = ResultTextIfNull Exit Function End If - + Value = ConvertToNumeric(Value) - + Result = Trim$(Str$(Value)) If Left(Result, 1) = "." Then Result = "0" & Result End If - + NumberToSqlText = Result - + End Function Friend Function ConvertToNumeric(ByVal Value As Variant) As Variant - + Const CheckNumber As Double = 1.23 - + Dim CheckText As String Dim DecimalSeparatorToReplace As String Dim NewDecimalSeparator As String - + If IsNull(Value) Then ConvertToNumeric = Null Exit Function @@ -564,7 +705,7 @@ Friend Function ConvertToNumeric(ByVal Value As Variant) As Variant ConvertToNumeric = Null Exit Function End If - + CheckText = CStr(CheckNumber) If InStr(1, CheckText, ",") > 0 Then DecimalSeparatorToReplace = "." @@ -573,16 +714,16 @@ Friend Function ConvertToNumeric(ByVal Value As Variant) As Variant DecimalSeparatorToReplace = "," NewDecimalSeparator = "." End If - + If InStr(1, Value, DecimalSeparatorToReplace) > 0 Then Value = Replace(Value, DecimalSeparatorToReplace, NewDecimalSeparator) Do While Value Like "*" & NewDecimalSeparator & "*" & NewDecimalSeparator & "*" Value = Replace(Value, NewDecimalSeparator, vbNullString, 1, 1) Loop End If - + ConvertToNumeric = CDbl(Value) - + End Function '--------------------------------------------------------------------------------------- @@ -618,7 +759,7 @@ Public Function BooleanToSqlText(ByVal Value As Variant, _ Else BooleanToSqlText = "0" End If - + End Function Private Function ConfigNumericSpecials( _ @@ -633,7 +774,7 @@ Private Function ConfigNumericSpecials( _ RelationalOperator = RelationalOperator Or SQL_LessThan FilterValue = Mid(FilterValue, 2) End If - + If Left(FilterValue, 1) = ">" Then If ((RelationalOperator And SQL_Equal) = SQL_Equal) Then RelationalOperator = RelationalOperator - SQL_Equal @@ -646,7 +787,7 @@ Private Function ConfigNumericSpecials( _ RelationalOperator = RelationalOperator Or SQL_Equal FilterValue = Mid(FilterValue, 2) End If - + If Right(FilterValue, 1) = "*" Then RelationalOperator = RelationalOperator Or SQL_Add_WildCardSuffix ElseIf Right(FilterValue2, 1) = "*" Then @@ -655,61 +796,61 @@ Private Function ConfigNumericSpecials( _ End Function -Private Function GetNextDigitNumber(ByVal Z As Variant, Optional AddToAbsoluteValue As Boolean = False) As Double - +Private Function GetNextDigitNumber(ByVal NumValue As Variant, Optional AddToAbsoluteValue As Boolean = False) As Double + Dim TestString As String - Dim KommaPos As Long - Dim digits As Long + Dim DecSignPos As Long + Dim Digits As Long Dim IsNegativ As Boolean Const AdditionalDecDigit As String = "1" Const AdditionalDecDigitKorr As Double = 0.1 - - TestString = Trim(CStr(ConvertToNumeric(Replace(CStr(Z), "*", AdditionalDecDigit)))) - + + TestString = Trim(CStr(ConvertToNumeric(Replace(CStr(NumValue), "*", AdditionalDecDigit)))) + If Left(TestString, 1) = "-" And (Not AddToAbsoluteValue) Then - GetNextDigitNumber = CDbl(Replace(CStr(Z), "*", vbNullString)) + GetNextDigitNumber = CDbl(Replace(CStr(NumValue), "*", vbNullString)) Exit Function End If - + If Left(TestString, 1) = "-" Then IsNegativ = True End If - - KommaPos = InStrRev(TestString, DecimalMarker) - If KommaPos = 0 Then ' next integer + + DecSignPos = InStrRev(TestString, DecimalMarker) + If DecSignPos = 0 Then ' next integer If AddToAbsoluteValue And IsNegativ Then - GetNextDigitNumber = CDbl(Replace(CStr(Z), "*", vbNullString)) - 1 + GetNextDigitNumber = CDbl(Replace(CStr(NumValue), "*", vbNullString)) - 1 Else - GetNextDigitNumber = CDbl(Replace(CStr(Z), "*", vbNullString)) + 1 + GetNextDigitNumber = CDbl(Replace(CStr(NumValue), "*", vbNullString)) + 1 End If Exit Function End If - - digits = Len(TestString) - KommaPos - 1 - + + Digits = Len(TestString) - DecSignPos - 1 + If Left(TestString, 1) = "-" Then IsNegativ = True End If - + If AddToAbsoluteValue And IsNegativ Then - GetNextDigitNumber = CDbl(TestString) + AdditionalDecDigitKorr / 10 ^ digits - AdditionalDecDigitKorr / 10 ^ (digits - 1) + GetNextDigitNumber = CDbl(TestString) + AdditionalDecDigitKorr / 10 ^ Digits - AdditionalDecDigitKorr / 10 ^ (Digits - 1) Else - GetNextDigitNumber = CDbl(TestString) + (1 - AdditionalDecDigitKorr) / 10 ^ digits + GetNextDigitNumber = CDbl(TestString) + (1 - AdditionalDecDigitKorr) / 10 ^ Digits End If - + End Function Private Property Get DecimalMarker() As String Static DecChar As String - Dim X As String - + Dim CheckString As String + If Len(DecChar) = 0 Then - X = Trim(CStr(1.2)) - DecChar = Mid(X, 2, 1) + CheckString = Trim(CStr(1.2)) + DecChar = Mid(CheckString, 2, 1) End If - + DecimalMarker = DecChar End Property @@ -717,17 +858,17 @@ End Property Private Function CharTrim(ByVal ValueToTrim As String, ByVal TrimChar As String) As String Dim TrimString As String - + TrimString = " " & TrimChar Do While InStr(1, ValueToTrim, TrimString) ValueToTrim = Replace(ValueToTrim, TrimString, TrimChar) Loop - + TrimString = TrimChar & " " Do While InStr(1, ValueToTrim, TrimString) ValueToTrim = Replace(ValueToTrim, TrimString, TrimChar) Loop - + CharTrim = ValueToTrim End Function @@ -736,7 +877,7 @@ Friend Function GetRelationalOperatorString(ByRef RelationalOperator As SqlRelat Dim OperatorString As String Dim op As SqlRelationalOperators - + If (RelationalOperator And SQL_In) = SQL_In Then OperatorString = OperatorString & "In" If (RelationalOperator And SQL_Not) = SQL_Not Then @@ -745,14 +886,14 @@ Friend Function GetRelationalOperatorString(ByRef RelationalOperator As SqlRelat GetRelationalOperatorString = OperatorString Exit Function End If - + If (RelationalOperator And SQL_Not) = SQL_Not Then - + op = RelationalOperator Xor SQL_Not - - If op = SqlRelationalOperators.SQL_Equal Then ' => "=" zu "<>" .. null berücksichtigen? + + If op = SqlRelationalOperators.SQL_Equal Then ' => "=" zu "<>" .. null berücksichtigen? RelationalOperator = SQL_LessThan + SQL_GreaterThan - ElseIf op = SQL_GreaterThan + SQL_LessThan Then ' => "<>" zu "=" .. null berücksichtigen? + ElseIf op = SQL_GreaterThan + SQL_LessThan Then ' => "<>" zu "=" .. null berücksichtigen? RelationalOperator = SQL_Equal Else RelationalOperator = RelationalOperator Xor SQL_Not @@ -775,7 +916,7 @@ Friend Function GetRelationalOperatorString(ByRef RelationalOperator As SqlRelat If (RelationalOperator And SQL_LessThan) = SQL_LessThan Then OperatorString = OperatorString & "<" End If - + If (RelationalOperator And SQL_GreaterThan) = SQL_GreaterThan Then OperatorString = OperatorString & ">" End If @@ -807,7 +948,7 @@ Private Function TryBuildWildCardSuffixOrPreBuildParams(ByVal FieldName As Strin Else ' Consider the whole day ... FieldName >= DateValue and FieldName < DateAdd("d", 1, FilterValue)) Criteria = BuildCriteria(FieldName, FieldDataType, SQL_GreaterThan + SQL_Equal, FilterValue, , , False) & _ SqlAndConcatString & _ - BuildCriteria(FieldName, FieldDataType, SQL_LessThan, DateAdd("d", 1, CDate(CLng(FilterValue))), , , False) + BuildCriteria(FieldName, FieldDataType, SQL_LessThan, DateAdd("d", 1, CDate(CLng(CDate(FilterValue)))), , , False) TryBuildWildCardSuffixOrPreBuildParams = True Exit Function End If @@ -815,7 +956,7 @@ Private Function TryBuildWildCardSuffixOrPreBuildParams(ByVal FieldName As Strin If (RelationalOperator And SQL_Equal) = SQL_Equal Then RelationalOperator = RelationalOperator - SQL_Equal End If - FilterValue = DateAdd("d", 1, CDate(CLng(FilterValue))) + FilterValue = DateAdd("d", 1, CDate(CLng(CDate(FilterValue)))) End If ElseIf FieldDataType = SQL_Numeric Then If (RelationalOperator And SQL_LessThan) = 0 Then ' no < daher: >, >= or only = @@ -862,13 +1003,13 @@ Private Function TryBuildNumericSpecialCasesCriteria(ByRef FieldName As String, Dim CriteriaBuild As Boolean Dim TempArr() As String - + Const FilterValue2 As Variant = Null If VarType(FilterValue) = vbString Then FilterValue = Trim(FilterValue) End If - + If FilterValue Like "[0-9]*..*[0-9]*" Or FilterValue Like "[+-][0-9]*..*[0-9]*" Then TempArr = Split(FilterValue, "..") Criteria = BuildCriteria(FieldName, FieldDataType, SQL_Between, Trim(TempArr(0)), Trim(TempArr(1)), IgnoreValue, DisableIgnoreNullValue) @@ -882,7 +1023,7 @@ Private Function TryBuildNumericSpecialCasesCriteria(ByRef FieldName As String, FilterValue = Replace(FilterValue, "--", "-{M}") FilterValue = Replace(FilterValue, "-", "..") FilterValue = Replace(FilterValue, "{M}", "-") - + TempArr = Split(FilterValue, "..") Criteria = BuildCriteria(FieldName, FieldDataType, SQL_Between, Trim(TempArr(0)), Trim(TempArr(1)), IgnoreValue, DisableIgnoreNullValue) CriteriaBuild = True @@ -892,21 +1033,73 @@ Private Function TryBuildNumericSpecialCasesCriteria(ByRef FieldName As String, CriteriaBuild = True End If End If - + TryBuildNumericSpecialCasesCriteria = CriteriaBuild End Function -Private Function TryBuildArrayCriteria(ByRef FieldName As String, ByVal FieldDataType As SqlFieldDataType, _ + +Private Function TryBuildSplitToArrayCriteria(ByRef FieldName As String, ByVal FieldDataType As SqlFieldDataType, _ ByRef RelationalOperator As SqlRelationalOperators, _ ByRef FilterValue As Variant, _ ByRef IgnoreValue As Variant, _ ByRef Criteria As String) As Boolean + + Dim ValueSplitted As Boolean + Dim CriteriaConcatString As String + + If (RelationalOperator And SQL_SplitValueToArray) = SQL_SplitValueToArray Then + + RelationalOperator = RelationalOperator Xor SQL_SplitValueToArray + + If InStr(1, FilterValue, SqlOrConcatString, vbTextCompare) > 0 Then + FilterValue = Replace(FilterValue, SqlOrConcatString, ";") + End If + + If InStr(1, FilterValue, SqlAndConcatString, vbTextCompare) > 0 Then + FilterValue = Replace(FilterValue, SqlAndConcatString, "+") + End If + + If InStr(1, FilterValue, ";") > 0 Then + If InStr(1, FilterValue, "+") > 0 Then + RelationalOperator = RelationalOperator Or SQL_SplitValueToArray + End If + CriteriaConcatString = SqlOrConcatString + FilterValue = Split(CharTrim(FilterValue, ";"), ";") + ValueSplitted = True + ElseIf InStr(1, FilterValue, "+") > 0 Then + CriteriaConcatString = SqlAndConcatString + FilterValue = Split(CharTrim(FilterValue, "+"), "+") + ValueSplitted = True + End If + End If + + If ValueSplitted Then + + If CriteriaConcatString = SqlOrConcatString Then + If TryBuildInCriteria(FieldName, FieldDataType, RelationalOperator, FilterValue, IgnoreValue, Criteria) Then + Exit Function + End If + End If + + TryBuildSplitToArrayCriteria = TryBuildArrayCriteria(FieldName, FieldDataType, RelationalOperator, FilterValue, IgnoreValue, Criteria, CriteriaConcatString) + + End If + +End Function + + +Private Function TryBuildArrayCriteria(ByRef FieldName As String, ByVal FieldDataType As SqlFieldDataType, _ + ByRef RelationalOperator As SqlRelationalOperators, _ + ByRef FilterValue As Variant, _ + ByRef IgnoreValue As Variant, _ + ByRef Criteria As String, _ + Optional ByVal CriteriaConcatString As String = SqlOrConcatString) As Boolean Dim itm As Variant Dim ItmCriteria As String - + Dim arrFilterValue() As Variant - + If Not IsArray(FilterValue) Then Exit Function End If @@ -915,11 +1108,11 @@ Private Function TryBuildArrayCriteria(ByRef FieldName As String, ByVal FieldDat For Each itm In FilterValue ItmCriteria = BuildCriteria(FieldName, FieldDataType, RelationalOperator, itm, , IgnoreValue, False) If Len(ItmCriteria) > 0 Then - Criteria = Criteria & SqlOrConcatString & ItmCriteria + Criteria = Criteria & CriteriaConcatString & ItmCriteria End If Next If Len(Criteria) > 0 Then - Criteria = Mid(Criteria, Len(SqlOrConcatString) + 1) ' 1. Or wegschneiden + Criteria = Mid(Criteria, Len(CriteriaConcatString) + 1) ' 1. Or wegschneiden End If TryBuildArrayCriteria = True @@ -961,7 +1154,7 @@ Private Function TryBuildInCriteria(ByRef FieldName As String, ByVal FieldDataTy End If If Len(FilterValueString) > 0 Then - + If RemoveNullFromInValueString(FilterValueString) Then Criteria = FieldName & " Is Null" If Len(FilterValueString) > 0 Then @@ -970,7 +1163,7 @@ Private Function TryBuildInCriteria(ByRef FieldName As String, ByVal FieldDataTy Else Criteria = FieldName & OperatorString & "(" & FilterValueString & ")" End If - + End If TryBuildInCriteria = True @@ -983,15 +1176,15 @@ Private Function TryBuildBetweenCriteria(ByRef FieldName As String, ByVal FieldD ByRef FilterValue2 As Variant, _ ByRef IgnoreValue As Variant, _ ByRef Criteria As String) As Boolean - + Dim Criteria1 As String Dim Criteria2 As String - + If (RelationalOperator And SQL_Between) = False Then TryBuildBetweenCriteria = False Exit Function End If - + If (RelationalOperator And SQL_Not) = SQL_Not Then 'Reverse condition Criteria1 = BuildCriteria(FieldName, FieldDataType, SQL_LessThan, FilterValue, , IgnoreValue, False) Criteria2 = BuildCriteria(FieldName, FieldDataType, SQL_GreaterThan, FilterValue2, , IgnoreValue, False) @@ -999,7 +1192,7 @@ Private Function TryBuildBetweenCriteria(ByRef FieldName As String, ByVal FieldD TryBuildBetweenCriteria = True Exit Function End If - + If FieldDataType = SQL_Numeric Then If FilterValue2 Like "<=*" Then 'cut away FilterValue2 = Mid(FilterValue2, 3) @@ -1052,7 +1245,7 @@ Private Function NullFilterOrEmptyFilter(ByVal FieldName As String, ByVal FieldD ByVal Value As Variant, ByVal IgnoreValue As Variant, _ ByRef NullFilterString As String, _ Optional ByVal DisableIgnoreNullValue As Boolean = False) As Boolean - + If IsObject(IgnoreValue) Then If IgnoreValue Is Nothing Then If IsNull(Value) Then @@ -1068,7 +1261,7 @@ Private Function NullFilterOrEmptyFilter(ByVal FieldName As String, ByVal FieldD Exit Function End If End If - + If IsNull(Value) Then If DisableIgnoreNullValue Then NullFilterString = FieldName & " Is Null" @@ -1098,7 +1291,7 @@ On Error Resume Next Else NullFilterOrEmptyFilter = ValuesAreEqual(FieldDataType, Value, IgnoreValue) End If - + If (RelationalOperator And SQL_Not) = SQL_Not Then NullFilterString = Replace(NullFilterString, "Is Null", "Is Not Null") End If @@ -1106,7 +1299,7 @@ On Error Resume Next End Function Private Function ValuesAreEqual(ByVal FieldDataType As SqlFieldDataType, ByVal Value As Variant, ByVal Value2 As Variant) As Boolean - + If IsArray(Value2) Then ValuesAreEqual = ArrayContains(FieldDataType, Value2, Value) ElseIf IsNull(Value) Then @@ -1131,7 +1324,7 @@ Private Function ValuesAreEqual(ByVal FieldDataType As SqlFieldDataType, ByVal V End Function Private Function ArrayContains(ByVal FieldDataType As SqlFieldDataType, ByVal ArrayToCheck As Variant, ByVal SearchValue As Variant) As Boolean - + Dim i As Long If IsNull(SearchValue) Then @@ -1151,7 +1344,7 @@ Private Function ArrayContains(ByVal FieldDataType As SqlFieldDataType, ByVal Ar End Function Private Function ArrayContainsNull(ByVal ArrayToCheck As Variant) As Boolean - + Dim i As Long For i = LBound(ArrayToCheck) To UBound(ArrayToCheck) @@ -1167,7 +1360,7 @@ End Function Private Function GetValueArrayString(ByVal Value As Variant, ByVal FieldDataType As SqlFieldDataType, _ ByVal Delimiter As String, ByVal IgnoreValue As Variant) As String - + Dim i As Long Dim s As String @@ -1196,22 +1389,22 @@ Private Function RemoveNullFromInValueString(ByRef ValueString As String) As Boo Const NullCheckString As String = ",Null," Dim TestString As String - + TestString = "," & ValueString & "," If Not (InStr(1, TestString, NullCheckString) > 0) Then RemoveNullFromInValueString = False Exit Function End If - + TestString = Replace(TestString, NullCheckString, ",") - + If Len(TestString) > 1 Then ValueString = Mid(TestString, 2, Len(TestString) - 2) Else ValueString = vbNullString End If - + RemoveNullFromInValueString = True End Function diff --git a/source/codelib/text/StringCollection.cls b/source/modules/StringCollection.cls similarity index 57% rename from source/codelib/text/StringCollection.cls rename to source/modules/StringCollection.cls index 83b8d10..34133ec 100644 --- a/source/codelib/text/StringCollection.cls +++ b/source/modules/StringCollection.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -11,7 +11,7 @@ Attribute VB_Exposed = False ' Class: text.StringCollection '--------------------------------------------------------------------------------------- ' -' Collection functions for strings +' Collection for strings ' ' Author: ' Josef Poetzl @@ -39,27 +39,85 @@ Private Sub Class_Terminate() Set m_Items = Nothing End Sub +'--------------------------------------------------------------------------------------- +' Property: Self +'--------------------------------------------------------------------------------------- +' +' Reference to self (Me) +' +' Remarks: +' Useful for with-block +' +' Returns: +' Database.StringCollection +' +'--------------------------------------------------------------------------------------- Public Property Get Self() As StringCollection Set Self = Me End Property +'--------------------------------------------------------------------------------------- +' Property: Items +'--------------------------------------------------------------------------------------- +' +' Collection with items +' +' Returns: +' VBA.Collection +' +'--------------------------------------------------------------------------------------- Public Property Get Items() As Collection Set Items = m_Items End Property +'--------------------------------------------------------------------------------------- +' Property: Item +'--------------------------------------------------------------------------------------- +' +' Item of Collection +' +' Parameters: +' Index - (Variant) +' +' Returns: +' Item string - (String) +' +'--------------------------------------------------------------------------------------- Public Property Get Item(ByVal Index As Variant) As String Item = m_Items.Item(Index) End Property Public Property Let Item(ByVal Index As Variant, ByVal NewValue As String) +Attribute Item.VB_UserMemId = 0 m_Items.Add NewValue, , , Index m_Items.Remove Index End Property +'--------------------------------------------------------------------------------------- +' Sub: Add +'--------------------------------------------------------------------------------------- +' +' Add string to collection +' +' Parameters: +' Item to add - (String) +' +'--------------------------------------------------------------------------------------- Public Sub Add(ByVal Item As String) m_Items.Add Item End Sub +'--------------------------------------------------------------------------------------- +' Sub: AddFromArray +'--------------------------------------------------------------------------------------- +' +' Add items form an array to collection +' +' Parameters: +' ArrayToAdd - (Variant) +' ItemStringFormat - (String) Format each item of Array with ItemStringFormat before add to collection +' +'--------------------------------------------------------------------------------------- Public Sub AddFromArray(ByRef ArrayToAdd As Variant, Optional ByVal ItemStringFormat As String = vbNullString) Dim i As Long @@ -70,23 +128,50 @@ Public Sub AddFromArray(ByRef ArrayToAdd As Variant, Optional ByVal ItemStringFo End Sub -Public Sub AddFromCollection(ByVal CollectionRef As Object, Optional ByVal ItemStringFormat As String = vbNullString) -'Object, damit alle Collections mit Enumarable- u. Item(index)-Interface durchlaufen werden können +'--------------------------------------------------------------------------------------- +' Sub: AddFromCollection +'--------------------------------------------------------------------------------------- +' +' Add items form a collection to string collection +' +' Parameters: +' CollectionToAppend - (Object) .. so that all collections with Enumarable and Item(index) interface can be run through +' ItemStringFormat - (String) Format each item of collection with ItemStringFormat before add to collection +' +'--------------------------------------------------------------------------------------- +Public Sub AddFromCollection(ByVal CollectionToAppend As Object, Optional ByVal ItemStringFormat As String = vbNullString) Dim itm As Variant - For Each itm In CollectionRef + For Each itm In CollectionToAppend m_Items.Add Format(itm, ItemStringFormat) Next End Sub +'--------------------------------------------------------------------------------------- +' Function: ToString +'--------------------------------------------------------------------------------------- +' +' Return Collection items as joined String +' +' Parameters: +' Delimiter - (String) Example: ", " => "Item1, Item2, Item3" +' ItemPrefix - (String) Prefix for each item +' ItemSuffix - (String) Suffix for each item +' IgnoreEmptyValue - (Boolean) don't output an empty item +' IgnoreDuplicateValues - (Boolean) True = don't output duplicate items +' +' Returns: +' String +' +'--------------------------------------------------------------------------------------- Public Function ToString(Optional ByVal Delimiter As String = ", ", _ Optional ByVal ItemPrefix As String = vbNullString, _ Optional ByVal ItemSuffix As String = vbNullString, _ Optional ByVal IgnoreEmptyValue As Boolean = False, _ Optional ByVal IgnoreDuplicateValues As Boolean = False) As String - + Dim s As String s = VBA.Join(ToStringArray(IgnoreEmptyValue, IgnoreDuplicateValues), ItemSuffix & Delimiter & ItemPrefix) @@ -96,6 +181,20 @@ Public Function ToString(Optional ByVal Delimiter As String = ", ", _ End Function +'--------------------------------------------------------------------------------------- +' Function: ToStringArray +'--------------------------------------------------------------------------------------- +' +' Return Collection items as String array +' +' Parameters: +' IgnoreEmptyValue - (Boolean) don't output an empty item +' IgnoreDuplicateValues - (Boolean) True = don't output duplicate items +' +' Returns: +' String array +' +'--------------------------------------------------------------------------------------- Public Function ToStringArray(Optional ByVal IgnoreEmptyValue As Boolean = False, _ Optional ByVal IgnoreDuplicateValues As Boolean = False) As String() @@ -109,7 +208,7 @@ Public Function ToStringArray(Optional ByVal IgnoreEmptyValue As Boolean = False ToStringArray = ItemArray Exit Function End If - + If IgnoreEmptyValue Then If IgnoreDuplicateValues Then ToStringArray = RemoveDuplicateValues(GetArrayWithoutEmptyValues()) @@ -129,7 +228,7 @@ Public Function ToStringArray(Optional ByVal IgnoreEmptyValue As Boolean = False Else ToStringArray = ItemArray End If - + End Function Private Function GetArrayWithoutEmptyValues() As String() @@ -154,17 +253,17 @@ Private Function GetArrayWithoutEmptyValues() As String() ItemArray(ItemIndex) = itm End If Next - + If ItemIndex = -1 Then Erase ItemArray GetArrayWithoutEmptyValues = ItemArray Exit Function End If - + If ItemIndex < (m_Items.Count - 1) Then ReDim Preserve ItemArray(0 To ItemIndex) End If - + GetArrayWithoutEmptyValues = ItemArray End Function @@ -182,9 +281,9 @@ Private Function RemoveDuplicateValues(ByRef ArrayToCheck() As String) As String RemoveDuplicateValues = ArrayToCheck Exit Function End If - + ReDim ItemArray(MaxArrayIndex) - + ItemIndex = -1 For Each ArrayItem In ArrayToCheck If Not ValueExistsInArray(ItemArray, ArrayItem, ItemIndex) Then @@ -192,28 +291,28 @@ Private Function RemoveDuplicateValues(ByRef ArrayToCheck() As String) As String ItemArray(ItemIndex) = ArrayItem End If Next - + If ItemIndex < (m_Items.Count - 1) Then ReDim Preserve ItemArray(0 To ItemIndex) End If - + RemoveDuplicateValues = ItemArray - + End Function Private Function ValueExistsInArray(ByRef ArrayToCheck() As String, ByVal ValueToCheck As String, ByVal CheckUntilArrayIndex As Long) As Boolean - + Dim i As Long - + If CheckUntilArrayIndex < 0 Then Exit Function End If - + For i = LBound(ArrayToCheck) To CheckUntilArrayIndex If StrComp(ArrayToCheck(i), ValueToCheck, vbBinaryCompare) = 0 Then ValueExistsInArray = True Exit Function End If Next - + End Function diff --git a/source/codelib/text/StringTools.bas b/source/modules/StringTools.bas similarity index 98% rename from source/codelib/text/StringTools.bas rename to source/modules/StringTools.bas index 3255050..2670a0a 100644 --- a/source/codelib/text/StringTools.bas +++ b/source/modules/StringTools.bas @@ -1,4 +1,4 @@ -Attribute VB_Name = "StringTools" +Attribute VB_Name = "StringTools" Attribute VB_Description = "String-Hilfsfunktionen" '--------------------------------------------------------------------------------------- ' Package: text.StringTools @@ -59,22 +59,22 @@ End Enum ' '--------------------------------------------------------------------------------------- Public Function IsNullOrEmpty(ByVal ValueToTest As Variant, Optional ByVal IgnoreSpaces As Boolean = False) As Boolean - + Dim TempValue As String - + If IsNull(ValueToTest) Then IsNullOrEmpty = True Exit Function End If - + TempValue = CStr(ValueToTest) - + If IgnoreSpaces Then TempValue = Trim$(TempValue) End If - + IsNullOrEmpty = (Len(TempValue) = 0) - + End Function '--------------------------------------------------------------------------------------- @@ -96,17 +96,17 @@ Public Function FormatText(ByVal FormatString As String, ParamArray Args() As Va Dim Arg As Variant Dim Temp As String Dim i As Long - + #If USELOCALIZATION = 1 Then FormatString = L10n.Text(FormatString) #End If - + Temp = FormatString For Each Arg In Args Temp = Replace(Temp, "{" & i & "}", CStr(Arg)) i = i + 1 Next - + FormatText = Temp End Function @@ -141,15 +141,15 @@ Public Function FormatX(ByVal Expression As Variant, Optional ByVal FormatString Optional ByVal FirstWeekOfYear As VbFirstWeekOfYear = vbFirstJan1) As String Dim Hours As Long - + If Not IsDate(Expression) Then - If IsNumeric(Expression) Then ' falls Zeitberechnung übergeben wird, ohne auf CDate zu konvertieren + If IsNumeric(Expression) Then ' falls Zeitberechnung übergeben wird, ohne auf CDate zu konvertieren If InStr(1, Replace(FormatString, "[hh]", "[h]"), "[h]") > 0 Then Expression = CDate(Expression) End If End If End If - + If IsDate(Expression) Then If InStr(1, FormatString, "[h", vbTextCompare) > 0 Then Hours = Fix(Round(CDate(Expression) * 24, 1)) @@ -162,7 +162,7 @@ Public Function FormatX(ByVal Expression As Variant, Optional ByVal FormatString End If End If End If - + FormatX = VBA.Format$(Expression, FormatString, FirstDayOfWeek, FirstWeekOfYear) End Function @@ -320,7 +320,7 @@ End Function ' '--------------------------------------------------------------------------------------- Public Function Trim(ByVal Value As String, Optional ByVal TrimType As TrimOption = TrimOption.TrimBoth) As String - + Select Case TrimType Case TrimOption.TrimBoth Trim = VBA.Trim$(Value) @@ -335,7 +335,7 @@ Public Function Trim(ByVal Value As String, Optional ByVal TrimType As TrimOptio Trim = Value Exit Function End Select - + End Function '--------------------------------------------------------------------------------------- @@ -402,7 +402,7 @@ Public Function Replicate(ByVal Value As String, ByVal Number As Long) As String Dim ValueLen As Long Dim TempString As String Dim i As Long - + If Number = 0 Then Replicate = vbNullString Exit Function @@ -410,9 +410,9 @@ Public Function Replicate(ByVal Value As String, ByVal Number As Long) As String Replicate = Value Exit Function End If - + ValueLen = Len(Value) - + If ValueLen = 0 Then Replicate = vbNullString Exit Function @@ -420,13 +420,13 @@ Public Function Replicate(ByVal Value As String, ByVal Number As Long) As String Replicate = String$(Number, Value) Exit Function End If - + TempString = String$(Number * ValueLen, Chr(0)) - + For i = 1 To Number Mid$(TempString, (i - 1) * ValueLen + 1, ValueLen) = Value Next - + Replicate = TempString - + End Function diff --git a/source/codelib/_codelib/addins/shared/VbeTools.cls b/source/modules/VbeTools.cls similarity index 99% rename from source/codelib/_codelib/addins/shared/VbeTools.cls rename to source/modules/VbeTools.cls index 477a780..2e8971b 100644 --- a/source/codelib/_codelib/addins/shared/VbeTools.cls +++ b/source/modules/VbeTools.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -82,7 +82,7 @@ Friend Property Get FindVbProject(ByVal FilePath As String) As Object End If Next End If - + Set FindVbProject = Proj End Property @@ -138,7 +138,7 @@ Public Function CodeModuleExists(ByVal CodeModulName As String, Optional VbProje If VbProjectToScan Is Nothing Then Set VbProjectToScan = CurrentVbProject End If - + Set VbcCol = VbProjectToScan.VBComponents For Each vbc In VbcCol If vbc.Name = CodeModulName Then @@ -146,5 +146,5 @@ Public Function CodeModuleExists(ByVal CodeModulName As String, Optional VbProje Exit For End If Next - + End Function diff --git a/source/codelib/api/winapi/WinApiFileInfo.cls b/source/modules/WinApiFileInfo.cls similarity index 99% rename from source/codelib/api/winapi/WinApiFileInfo.cls rename to source/modules/WinApiFileInfo.cls index 36a9c7b..9f597fd 100644 --- a/source/codelib/api/winapi/WinApiFileInfo.cls +++ b/source/modules/WinApiFileInfo.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -141,38 +141,38 @@ Private Function GetVersion(ByVal FilePath As String, _ GetVersion = False Exit Function End If - + ReDim BufferString(Size) Ret = GetFileVersionInfo(FilePath, 0&, Size, BufferString(0)) If Ret = 0 Then GetVersion = False Exit Function End If - + Ret = VerQueryValue(BufferString(0), "\", VerPointer, VerBufLen) If Ret = 0 Then GetVersion = False Exit Function End If - + Call MoveMemory(FileInfo, VerPointer, Len(FileInfo)) - + With FileInfo - + GetFileInfo.FileVersion = _ Trim$(Str$((.dwFileVersionMS And &HFFFF0000) \ &H10000)) & "." & _ Trim$(Str$(.dwFileVersionMS And &HFFFF&)) & "." & _ Trim$(Str$((.dwFileVersionLS And &HFFFF0000) \ &H10000)) & "." & _ Trim$(Str$(.dwFileVersionLS And &HFFFF&)) - + GetFileInfo.ProductVersion = _ Trim$(Str$((.dwProductVersionMS And &HFFFF0000) \ &H10000)) & "." & _ Trim$(Str$(.dwProductVersionMS And &HFFFF&)) & "." & _ Trim$(Str$((.dwProductVersionLS And &HFFFF0000) \ &H10000)) & "." & _ Trim$(Str$(.dwProductVersionLS And &HFFFF&)) - + End With - + GetVersion = True End Function diff --git a/source/codelib/api/winapi/WinApiLayoutTools.cls b/source/modules/WinApiLayoutTools.cls similarity index 99% rename from source/codelib/api/winapi/WinApiLayoutTools.cls rename to source/modules/WinApiLayoutTools.cls index ef80de9..3647fdb 100644 --- a/source/codelib/api/winapi/WinApiLayoutTools.cls +++ b/source/modules/WinApiLayoutTools.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -110,9 +110,9 @@ Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal DC As Long, ByVal Inde ' '--------------------------------------------------------------------------------------- Public Sub SetBackColor(ByVal Hwnd As LongPtr, ByVal Color As Long) - + Dim NewBrush As LongPtr - + 'Create Brush NewBrush = CreateSolidBrush(Color) 'Assign Brush diff --git a/source/codelib/api/winapi/WinApiShortcutMenu.cls b/source/modules/WinApiShortcutMenu.cls similarity index 96% rename from source/codelib/api/winapi/WinApiShortcutMenu.cls rename to source/modules/WinApiShortcutMenu.cls index c3cd540..d2c52a3 100644 --- a/source/codelib/api/winapi/WinApiShortcutMenu.cls +++ b/source/modules/WinApiShortcutMenu.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -20,7 +20,7 @@ Attribute VB_Exposed = False ' ' Remarks: '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -' | Adapted variant from API example by Jörg Ostendorp of AEK10 +' | Adapted variant from API example by Jörg Ostendorp of AEK10 '+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ' '--------------------------------------------------------------------------------------- @@ -42,7 +42,7 @@ Private Type POINTAPI Y As Long End Type -Private Type RECT +Private Type Rect Left As Long Top As Long Right As Long @@ -130,16 +130,16 @@ Private Declare PtrSafe Function TranslateMessage _ Private Declare PtrSafe Function GetWindowRect _ Lib "user32.dll" ( _ ByVal Hwnd As LongPtr, _ - ByRef lpRect As RECT _ + ByRef lpRect As Rect _ ) As LongPtr - + Private Declare PtrSafe Function SetMenuDefaultItem _ Lib "user32" ( _ ByVal hMenu As LongPtr, _ ByVal uItem As LongPtr, _ ByVal fByPos As LongPtr _ ) As LongPtr - + #Else Private m_Helper As Long 'Auxiliary window handle @@ -223,7 +223,7 @@ Private Declare Function GetWindowRect _ ByVal Hwnd As Long, _ ByRef lpRect As RECT _ ) As Long - + Private Declare Function SetMenuDefaultItem _ Lib "user32" ( _ ByVal hMenu As Long, _ @@ -232,7 +232,7 @@ Private Declare Function SetMenuDefaultItem _ ) As Long #End If - + 'Message Private Const WM_COMMAND As Long = &H111 Private Const WM_MOUSELEAVE As Long = &H2A3 @@ -316,7 +316,7 @@ Public Property Get MenuControl() As Access.Control End Property Public Property Set MenuControl(ByRef MnuCtl As Access.Control) - + #If VBA7 Then Dim lngSectionHwnd As LongPtr #Else @@ -325,7 +325,7 @@ Public Property Set MenuControl(ByRef MnuCtl As Access.Control) Dim ParentObj As Object Set m_MenuControl = MnuCtl - + Set ParentObj = m_MenuControl.Parent If TypeOf ParentObj Is Access.Page Then Set ParentObj = ParentObj.Parent.Parent @@ -333,23 +333,23 @@ Public Property Set MenuControl(ByRef MnuCtl As Access.Control) If m_AccessForm Is Nothing Then Set m_AccessForm = ParentObj End If - + Select Case m_Section Case 0 'Detailbereich lngSectionHwnd = WindowTools.GetDetailSection(ParentObj.Hwnd) Case 1 'Kopf lngSectionHwnd = WindowTools.GetHeaderSection(ParentObj.Hwnd) - Case 2 ' Fuß + Case 2 ' Fuß lngSectionHwnd = WindowTools.GetFooterSection(ParentObj.Hwnd) Case Else lngSectionHwnd = WindowTools.GetDetailSection(ParentObj.Hwnd) End Select Set ParentObj = Nothing - + 'DoCmd.Restore '??? wozu ??? 'Hilfsfenster am Ursprung des Detailbereichs erstellen zur Positionsbestimmung 'wenn das Formular gescrollt wird - + m_Helper = CreateWindowEx(0, _ "Static", _ "Helper", _ @@ -357,9 +357,9 @@ Public Property Set MenuControl(ByRef MnuCtl As Access.Control) 0, 0, 0, 0, _ lngSectionHwnd, _ 0, 0, 0) - 'Wenn die Buttons nicht im Detailbereich sondern im Header oder Footer eingefügt werden, + 'Wenn die Buttons nicht im Detailbereich sondern im Header oder Footer eingefügt werden, 'kann auf das Hilsfenter verzichtet werden. Da diese Bereiche nicht gescrollt werden - 'können, können Sie auch direkt zur Positionsbestimmung des Kontextmenüs herangezogen + 'können, können Sie auch direkt zur Positionsbestimmung des Kontextmenüs herangezogen 'werden ' => ??? wie ? @@ -390,10 +390,10 @@ Public Sub AddMenuItem(ByVal MenuItemNumber As Long, ByVal ItemText As String, _ Optional ByVal ItemType As MenuItemStyle = MF_STRING, _ Optional ByVal SubMenu As Long = 0, _ Optional ByVal DefaultItem As Boolean = False) - + m_ItemCnt = m_ItemCnt + 1 ReDim Preserve m_MenuItems(m_ItemCnt) - + With m_MenuItems(m_ItemCnt) .ItemNumber = MenuItemNumber .ItemText = ItemText @@ -408,7 +408,7 @@ End Sub ' Function: OpenMenu '--------------------------------------------------------------------------------------- ' -' Öffnet das Popup-Menü +' Öffnet das Popup-Menü ' ' Parameters: ' X - desired X position ... can be omitted if Control was specified @@ -431,24 +431,24 @@ Public Function OpenMenu(Optional ByVal X As Single = 0, Optional ByVal Y As Sin #End If Dim Message As APIMSG - Dim RcHelper As RECT + Dim RcHelper As Rect Dim ButtonLeft As Long Dim ButtonTop As Long Dim XPos As Long Dim YPos As Long - + Dim ParentObj As Object - Dim AccFormRect As RECT + Dim AccFormRect As Rect 'Otherwise, nothing is displayed when ENTER is pressed: DoEvents - + 'Create empty menu MenuHwnd = CreatePopupMenu - + 'Add entries Dim i As Long - + For i = 1 To m_ItemCnt With m_MenuItems(i) If .SubMenu > 0 Then @@ -464,17 +464,17 @@ Public Function OpenMenu(Optional ByVal X As Single = 0, Optional ByVal Y As Sin Else AppendMenu MenuHwnd, .ItemType, .ItemNumber, .ItemText End If - + If .DefaultItem Then SetMenuDefaultItem MenuHwnd, .ItemNumber - 1, &H400& - + End With - + Next i 'Determine position '- Auxiliary window (~section window) absolute GetWindowRect m_Helper, RcHelper - + If m_MenuControl Is Nothing Then GetWindowRect m_AccessForm.Hwnd, AccFormRect ButtonLeft = LayoutTools.GetPixelFromTwips(X) + AccFormRect.Left @@ -487,9 +487,9 @@ Public Function OpenMenu(Optional ByVal X As Single = 0, Optional ByVal Y As Sin '- calc with each other XPos = RcHelper.Left + ButtonLeft - 1 YPos = RcHelper.Top + ButtonTop - + 'Show menu - + If m_MenuControl Is Nothing Then Set ParentObj = m_AccessForm Else @@ -498,25 +498,25 @@ Public Function OpenMenu(Optional ByVal X As Single = 0, Optional ByVal Y As Sin Set ParentObj = ParentObj.Parent.Parent End If End If - + TrackPopupMenu MenuHwnd, TPM_BOTTOMALIGN, XPos, YPos, _ ByVal 0&, ParentObj.Hwnd, ByVal 0& - + 'Message-Loop (Attention: for normal forms Application.hWndAccessApp, for POPUPS Form.Hwnd) - + If m_AccessForm.PopUp = True Then Hwnd = m_AccessForm.Hwnd Else Hwnd = Application.hWndAccessApp End If - + Dim RepeatGetMessage As Boolean Do ' Security sleep in case there are problems with windows message. (WM_MOUSELEAVE] RepeatGetMessage = False GetMessage Message, Hwnd, ByVal 0&, ByVal 0& TranslateMessage Message DispatchMessage Message - + 'Evaluate message If Message.Message = WM_COMMAND Then OpenMenu = Message.wParam @@ -526,7 +526,7 @@ Public Function OpenMenu(Optional ByVal X As Single = 0, Optional ByVal Y As Sin OpenMenu = 0 End If Loop While RepeatGetMessage - + 'Destroy menu DestroyMenu MenuHwnd diff --git a/source/codelib/api/winapi/WinApiWindowTools.cls b/source/modules/WinApiWindowTools.cls similarity index 89% rename from source/codelib/api/winapi/WinApiWindowTools.cls rename to source/modules/WinApiWindowTools.cls index 084dd7e..ef1e5cc 100644 --- a/source/codelib/api/winapi/WinApiWindowTools.cls +++ b/source/modules/WinApiWindowTools.cls @@ -1,4 +1,4 @@ -VERSION 1.0 CLASS +VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END @@ -19,7 +19,7 @@ Attribute VB_Exposed = False ' Source info: '--------------------------------------------------------------------------------------- '| The procedures GetMDI, GetHeaderSection, GetDetailSection, GetFooterSection and GetControl -'| are taken from the AEK10 lecture by Jörg Ostendorp +'| are taken from the AEK10 lecture by Jörg Ostendorp '--------------------------------------------------------------------------------------- ' '--------------------------------------------------------------------------------------- @@ -149,15 +149,15 @@ End Function Public Function GetControl(ByRef FormRef As Access.Form, ByVal Hwnd As LongPtr, _ ByVal ClassName As String, ByVal ControlName As String) As LongPtr - 'Exitieren mehrere Controls der gleichen Klasse auf einem Formular, z.B. TabControls, besteht das Problem, daß + 'Exitieren mehrere Controls der gleichen Klasse auf einem Formular, z.B. TabControls, besteht das Problem, daß 'deren Reihenfolge nicht definiert ist (anders also als bei den Sektionsfenstern) 'In diesem Fall kann man alle Kindfenster dieser Klasse in einer Schleife durchlaufen - 'und z.B. prüfen, ob die Position des Fensters des zurückgegebenen Handles - 'mit der des Access-Steuerelementes übereinstimmt. - 'Nachfolgend wird hierfür die undokumentierte Funktion accHittest verwendet. + 'und z.B. prüfen, ob die Position des Fensters des zurückgegebenen Handles + 'mit der des Access-Steuerelementes übereinstimmt. + 'Nachfolgend wird hierfür die undokumentierte Funktion accHittest verwendet. 'Dieser werden als Parameter die Screenkoordinaten der linken oberen Ecke eines - 'Steuerelementes übergeben. Befindet sich dort ein Objekt, erhält man dieses als Rückgabewert. - 'Ist der Name des Objektes identisch mit dem übergebenen Steuerelementnamen, so + 'Steuerelementes übergeben. Befindet sich dort ein Objekt, erhält man dieses als Rückgabewert. + 'Ist der Name des Objektes identisch mit dem übergebenen Steuerelementnamen, so 'hat man das Handle ermittelt: On Error Resume Next @@ -169,11 +169,11 @@ On Error Resume Next h = 0 Do - 'Erstes (h=0)/nächstes (h<>0) Control auf dem Sektionsfenster ermitteln + 'Erstes (h=0)/nächstes (h<>0) Control auf dem Sektionsfenster ermitteln h = FindWindowEx(Hwnd, h, ClassName, vbNullString) 'Bildschirmkoordinaten dieses Controls ermitteln - 'dafür die Punktkoordinaten aus dem letzten Durchlauf zurücksetzen, sonst wird addiert! + 'dafür die Punktkoordinaten aus dem letzten Durchlauf zurücksetzen, sonst wird addiert! pt.X = 0 pt.Y = 0 ClientToScreen h, pt @@ -187,7 +187,7 @@ On Error Resume Next End If Loop While h <> 0 - 'Handle zurückgeben + 'Handle zurückgeben GetControl = h End Function diff --git a/source/codelib/_codelib/license.bas b/source/modules/_AccessCodeLib_license.bas similarity index 98% rename from source/codelib/_codelib/license.bas rename to source/modules/_AccessCodeLib_license.bas index 9f34738..a5dab1a 100644 --- a/source/codelib/_codelib/license.bas +++ b/source/modules/_AccessCodeLib_license.bas @@ -1,4 +1,4 @@ -Attribute VB_Name = "_AccessCodeLib_license" +Attribute VB_Name = "_AccessCodeLib_license" '--------------------------------------------------------------------------------------- ' access-codelib.net Lizenz '--------------------------------------------------------------------------------------- @@ -53,9 +53,9 @@ Option Compare Text Option Explicit Public Function GetAccessCodeLibLicense() As String - + On Error Resume Next - + GetAccessCodeLibLicense = _ "Copyright (c) access-codelib.net" & vbNewLine & _ "All rights reserved." & vbNewLine & vbNewLine & _ diff --git a/source/_config_Application.bas b/source/modules/_config_Application.bas similarity index 83% rename from source/_config_Application.bas rename to source/modules/_config_Application.bas index 679a128..c372263 100644 --- a/source/_config_Application.bas +++ b/source/modules/_config_Application.bas @@ -1,4 +1,4 @@ -Attribute VB_Name = "_config_Application" +Attribute VB_Name = "_config_Application" '--------------------------------------------------------------------------------------- ' Modul: _initApplication '--------------------------------------------------------------------------------------- @@ -6,22 +6,6 @@ Attribute VB_Name = "_config_Application" ' Application configuration ' '--------------------------------------------------------------------------------------- - -'--------------------------------------------------------------------------------------- -' -' %AppFolder%/source/_config_Application.bas -' base/_config_Application.bas -' _codelib/license.bas -' %AppFolder%/source/defGlobal_ACLibFilterFormWizard.bas -' base/_initApplication.bas -' base/modApplication.bas -' base/ApplicationHandler.cls -' base/ApplicationHandler_AppFile.cls -' _codelib/addins/shared/AppFileCodeModulTransfer.cls -' base/modErrorHandler.bas -' localization/L10nTools.bas -' -'--------------------------------------------------------------------------------------- ' ' Don't forget: set USELOCALIZATION = 1 as Compiler argument in Project properties ' @@ -31,8 +15,7 @@ Option Explicit Option Private Module 'Version -Private Const APPLICATION_VERSION As String = "1.8.4" '2024-01 - +Private Const APPLICATION_VERSION As String = "1.8.5" '2025-06 #Const USE_CLASS_APPLICATIONHANDLER_APPFILE = 1 #Const USE_CLASS_APPLICATIONHANDLER_VERSION = 1 @@ -80,24 +63,24 @@ On Error GoTo HandleErr End If With CurrentAppHandlerRef - + 'To be on the safe side, set AccDb Set .AppDb = CodeDb 'must point to CodeDb, 'as this application is used as an add-in - + 'Application name .ApplicationName = APPLICATION_NAME .ApplicationFullName = APPLICATION_FULLNAME .ApplicationTitle = APPLICATION_TITLE - + 'Version .Version = APPLICATION_VERSION - + 'Form called at the end of CurrentApplication.Start .ApplicationStartFormName = ApplicationStartFormName - + End With - + '---------------------------------------------------------------------------- ' Extensions: ' @@ -105,7 +88,7 @@ On Error GoTo HandleErr With m_Extensions Set .ApplicationHandler = CurrentAppHandlerRef .Add New ApplicationHandler_AppFile - + #If USE_CLASS_APPLICATIONHANDLER_VERSION = 1 Then Dim AppHdlVersion As ApplicationHandler_Version Set AppHdlVersion = New ApplicationHandler_Version diff --git a/source/codelib/base/_initApplication.bas b/source/modules/_initApplication.bas similarity index 97% rename from source/codelib/base/_initApplication.bas rename to source/modules/_initApplication.bas index 3db9603..72dd547 100644 --- a/source/codelib/base/_initApplication.bas +++ b/source/modules/_initApplication.bas @@ -1,4 +1,4 @@ -Attribute VB_Name = "_initApplication" +Attribute VB_Name = "_initApplication" '--------------------------------------------------------------------------------------- ' Package: base._initApplication '--------------------------------------------------------------------------------------- diff --git a/source/codelib/base/modApplication.bas b/source/modules/modApplication.bas similarity index 97% rename from source/codelib/base/modApplication.bas rename to source/modules/modApplication.bas index c8a3e42..1cb71d9 100644 --- a/source/codelib/base/modApplication.bas +++ b/source/modules/modApplication.bas @@ -1,5 +1,5 @@ -Attribute VB_Name = "modApplication" -Attribute VB_Description = "Standard-Prozeduren für die Arbeit mit ApplicationHandler" +Attribute VB_Name = "modApplication" +Attribute VB_Description = "Standard-Prozeduren für die Arbeit mit ApplicationHandler" '--------------------------------------------------------------------------------------- ' Package: base.modApplication '--------------------------------------------------------------------------------------- @@ -121,13 +121,13 @@ Public Sub DisposeCurrentApplicationHandler() Dim CheckCnt As Long, MaxCnt As Long On Error Resume Next - + If Not m_ApplicationHandler Is Nothing Then m_ApplicationHandler.Dispose End If - + Set m_ApplicationHandler = Nothing - + End Sub diff --git a/source/codelib/base/modErrorHandler.bas b/source/modules/modErrorHandler.bas similarity index 98% rename from source/codelib/base/modErrorHandler.bas rename to source/modules/modErrorHandler.bas index 326f2d4..895214d 100644 --- a/source/codelib/base/modErrorHandler.bas +++ b/source/modules/modErrorHandler.bas @@ -1,5 +1,5 @@ -Attribute VB_Name = "modErrorHandler" -Attribute VB_Description = "Prozeduren für die Fehlerbehandlung" +Attribute VB_Name = "modErrorHandler" +Attribute VB_Description = "Prozeduren für die Fehlerbehandlung" '--------------------------------------------------------------------------------------- ' Package: base.modErrorHandler '--------------------------------------------------------------------------------------- @@ -169,7 +169,7 @@ Public Function HandleError(ByVal ErrNumber As Long, ByVal ErrSource As String, If ErrHandlerMode = ACLibErrorHandlerMode.[_aclibErr_default] Then ErrHandlerMode = m_DefaultErrorHandlerMode End If - + HandleError = ProcHandleError(ErrNumber, ErrSource, ErrDescription, ErrHandlerMode) End Function @@ -182,23 +182,23 @@ Private Function ProcHandleError(ByRef ErrNumber As Long, ByRef ErrSource As Str Dim NewErrSource As String Dim NewErrDescription As String Dim CurrentErrSource As String - + NewErrDescription = Err.Description CurrentErrSource = Err.Source - + On Error Resume Next - + NewErrSource = ErrSource If Len(NewErrSource) = 0 Then NewErrSource = CurrentErrSource ElseIf CurrentErrSource <> GetApplicationVbProjectName Then NewErrSource = NewErrSource & ERRORSOURCE_DELIMITERSYMBOL & CurrentErrSource End If - + If Len(ErrDescription) > 0 Then NewErrDescription = ErrDescription End If - + 'Output to file If (ErrHandlerMode And ACLibErrorHandlerMode.aclibErrFile) Then PrintToFile ErrNumber, NewErrSource, NewErrDescription @@ -225,22 +225,22 @@ On Error GoTo 0 End Function Public Sub ShowErrorMessage(ByVal ErrNumber As Long, ByRef ErrSource As String, ByRef ErrDescription As String) - + Dim ErrMsgBoxTitle As String Dim Pos As Long Dim TempString As String On Error Resume Next - + Const LineBreakPos As Long = 50 - + Pos = InStr(1, ErrSource, ERRORSOURCE_DELIMITERSYMBOL, vbBinaryCompare) If Pos > 1 Then ErrMsgBoxTitle = Left$(ErrSource, Pos - 1) Else ErrMsgBoxTitle = ErrSource End If - + If Len(ErrSource) > LineBreakPos Then Pos = InStr(LineBreakPos, ErrSource, ERRORSOURCE_DELIMITERSYMBOL) If Pos > 0 Then @@ -252,7 +252,7 @@ On Error Resume Next ErrSource = TempString & ErrSource End If End If - + VBA.MsgBox "Error " & ErrNumber & ": " & vbNewLine & ErrDescription & vbNewLine & vbNewLine & "(" & ErrSource & ")", _ vbCritical + vbSystemModal + vbMsgBoxSetForeground, ErrMsgBoxTitle @@ -260,16 +260,16 @@ End Sub Private Sub PrintToFile(ByRef ErrNumber As Long, ByRef ErrSource As String, _ ByRef ErrDescription As String) - + Dim FileSource As String Dim f As Long Dim WriteToFile As Boolean Dim PathToErrLogFile As String - + On Error Resume Next - + WriteToFile = True - + FileSource = "[" & ErrSource & "]" PathToErrLogFile = ErrorHandlerLogFile If Len(PathToErrLogFile) = 0 Then @@ -281,18 +281,18 @@ On Error Resume Next "yyyy-mm-tt hh:nn:ss "); FileSource; _ " Error "; CStr(ErrNumber); ": "; ErrDescription Close #f - + End Sub Private Function GetApplicationVbProjectName() As String - + Static VbProjectName As String - + Dim DbFile As String Dim vbp As Object - + On Error Resume Next - + If Len(VbProjectName) = 0 Then VbProjectName = Access.VBE.ActiveVBProject.Name DbFile = CurrentDb.Name @@ -306,5 +306,5 @@ On Error Resume Next End If End If GetApplicationVbProjectName = VbProjectName - + End Function diff --git a/source/modules/modMSAccessVcsSupport.bas b/source/modules/modMSAccessVcsSupport.bas new file mode 100644 index 0000000..a717eb8 --- /dev/null +++ b/source/modules/modMSAccessVcsSupport.bas @@ -0,0 +1,12 @@ +Attribute VB_Name = "modMSAccessVcsSupport" +Option Compare Database +Option Explicit + +Public Sub VcsRunBeforeExport() + + With New ACLibGitHubImporter + .BranchName = "master" + .UpdateCodeModules + End With + +End Sub diff --git a/source/codelib/api/winapi/modWinAPI_Mouse.bas b/source/modules/modWinApi_Mouse.bas similarity index 97% rename from source/codelib/api/winapi/modWinAPI_Mouse.bas rename to source/modules/modWinApi_Mouse.bas index 6feae17..fe91893 100644 --- a/source/codelib/api/winapi/modWinAPI_Mouse.bas +++ b/source/modules/modWinApi_Mouse.bas @@ -1,4 +1,4 @@ -Attribute VB_Name = "modWinApi_Mouse" +Attribute VB_Name = "modWinApi_Mouse" '--------------------------------------------------------------------------------------- ' Package: api.winapi.modWinApi_Mouse '--------------------------------------------------------------------------------------- @@ -55,10 +55,10 @@ End Enum ' '--------------------------------------------------------------------------------------- Public Sub MouseCursor(ByVal CursorType As IDC_MouseCursor) - + Dim CursorPtr As LongPtr - + CursorPtr = LoadCursorBynum(0&, CursorType) SetCursor CursorPtr - + End Sub diff --git a/source/codelib/_codelib/addins/shared/modWizardCodeModulesData.bas b/source/modules/modWizardCodeModulesData.bas similarity index 95% rename from source/codelib/_codelib/addins/shared/modWizardCodeModulesData.bas rename to source/modules/modWizardCodeModulesData.bas index f323e7e..c325f38 100644 --- a/source/codelib/_codelib/addins/shared/modWizardCodeModulesData.bas +++ b/source/modules/modWizardCodeModulesData.bas @@ -1,4 +1,4 @@ -Attribute VB_Name = "modWizardCodeModulesData" +Attribute VB_Name = "modWizardCodeModulesData" '--------------------------------------------------------------------------------------- ' Package: _codelib.addins.shared.modWizardCodeModulesData '--------------------------------------------------------------------------------------- @@ -22,23 +22,23 @@ Option Explicit Option Private Module Public Property Get SccRev() As String - + With CodeDb.OpenRecordset("select max(SccRev) from usys_AppFiles") If Not .EOF Then SccRev = Nz(.Fields(0).Value, 0) End If .Close End With - + End Property Public Property Get SccRevMin() As String - + With CodeDb.OpenRecordset("select Min(SccRev) from usys_AppFiles") If Not .EOF Then SccRevMin = Nz(.Fields(0).Value, "0") End If .Close End With - + End Property diff --git a/source/modWizardTools.bas b/source/modules/modWizardTools.bas similarity index 90% rename from source/modWizardTools.bas rename to source/modules/modWizardTools.bas index 44f8b84..581b518 100644 --- a/source/modWizardTools.bas +++ b/source/modules/modWizardTools.bas @@ -1,4 +1,4 @@ -Attribute VB_Name = "modWizardTools" +Attribute VB_Name = "modWizardTools" Option Compare Database Option Explicit @@ -6,7 +6,7 @@ Public Function CheckApplicationStartUpMethod() If CurrentDb.Name Like "*.accda" Then MsgBox "The add-in must be installed into the Access add-in directory using the add-in manager. Afterwards it has to be started via the menu entry '" & APPLICATION_NAME & "'.", _ vbExclamation, APPLICATION_NAME & ": Incorrect start" - + Application.Quit End If End Function diff --git a/source/nav-pane-groups.json b/source/nav-pane-groups.json new file mode 100644 index 0000000..5dff1ef --- /dev/null +++ b/source/nav-pane-groups.json @@ -0,0 +1,24 @@ +{ + "Info": { + "Class": "clsDbNavPaneGroup", + "Description": "Navigation Pane Custom Groups" + }, + "Items": { + "Categories": [ + { + "Name": "Benutzerdefiniert", + "Flags": 0, + "Position": 2, + "Groups": [ + { + "Name": "Benutzerdefinierte Gruppe 1", + "Flags": 0, + "Position": 2, + "Objects": [ + ] + } + ] + } + ] + } +} diff --git a/source/proj-properties.json b/source/proj-properties.json new file mode 100644 index 0000000..a113700 --- /dev/null +++ b/source/proj-properties.json @@ -0,0 +1,9 @@ +{ + "Info": { + "Class": "clsDbProjProperty", + "Description": "Project Properties (Access)" + }, + "Items": { + "VCS Source Path": "\\source" + } +} diff --git a/source/project.json b/source/project.json new file mode 100644 index 0000000..00e38af --- /dev/null +++ b/source/project.json @@ -0,0 +1,10 @@ +{ + "Info": { + "Class": "clsDbProject", + "Description": "Project" + }, + "Items": { + "FileFormat": 12, + "RemovePersonalInformation": false + } +} diff --git a/source/queries/L10n_Overview.bas b/source/queries/L10n_Overview.bas new file mode 100644 index 0000000..1d11f7b --- /dev/null +++ b/source/queries/L10n_Overview.bas @@ -0,0 +1,102 @@ +Operation =6 +Option =0 +Begin InputTables + Name ="L10n_Dict" +End +Begin OutputColumns + Expression ="L10n_Dict.KeyText" + GroupLevel =2 + Expression ="L10n_Dict.LangCode" + GroupLevel =1 + Alias ="MaxOfLngText" + Expression ="Max(L10n_Dict.LngText)" +End +Begin Groups + Expression ="L10n_Dict.KeyText" + GroupLevel =2 + Expression ="L10n_Dict.LangCode" + GroupLevel =1 +End +dbBoolean "ReturnsRecords" ="-1" +dbInteger "ODBCTimeout" ="60" +dbByte "RecordsetType" ="0" +dbBoolean "OrderByOn" ="0" +dbByte "Orientation" ="0" +dbByte "DefaultView" ="2" +dbBoolean "FilterOnLoad" ="0" +dbBoolean "OrderByOnLoad" ="-1" +dbBoolean "TotalsRow" ="0" +Begin + Begin + dbText "Name" ="DE" + dbLong "AggregateType" ="-1" + dbInteger "ColumnWidth" ="5565" + dbBoolean "ColumnHidden" ="0" + dbInteger "ColumnOrder" ="3" + End + Begin + dbText "Name" ="EN" + dbLong "AggregateType" ="-1" + dbInteger "ColumnWidth" ="5190" + dbBoolean "ColumnHidden" ="0" + dbInteger "ColumnOrder" ="2" + End + Begin + dbText "Name" ="EN.KeyText" + dbLong "AggregateType" ="-1" + End + Begin + dbText "Name" ="EN.LangCode" + dbLong "AggregateType" ="-1" + End + Begin + dbText "Name" ="DE.LangCode" + dbLong "AggregateType" ="-1" + End + Begin + dbText "Name" ="DE.KeyText" + dbLong "AggregateType" ="-1" + End + Begin + dbText "Name" ="L10n_Dict.LangCode" + dbLong "AggregateType" ="-1" + End + Begin + dbText "Name" ="L10n_Dict.KeyText" + dbLong "AggregateType" ="-1" + dbInteger "ColumnOrder" ="1" + dbInteger "ColumnWidth" ="5985" + dbBoolean "ColumnHidden" ="0" + End + Begin + dbText "Name" ="L10n_Dict.LngText" + dbLong "AggregateType" ="-1" + End + Begin + dbText "Name" ="PIVOT" + dbLong "AggregateType" ="-1" + End +End +Begin + State =0 + Left =0 + Top =40 + Right =1595 + Bottom =836 + Left =-1 + Top =-1 + Right =1571 + Bottom =309 + Left =0 + Top =0 + ColumnsShown =559 + Begin + Left =61 + Top =66 + Right =205 + Bottom =210 + Top =0 + Name ="L10n_Dict" + Name ="" + End +End diff --git a/source/queries/L10n_Overview.sql b/source/queries/L10n_Overview.sql new file mode 100644 index 0000000..edeaae3 --- /dev/null +++ b/source/queries/L10n_Overview.sql @@ -0,0 +1,7 @@ +TRANSFORM Max(L10n_Dict.LngText) AS MaxOfLngText +SELECT + L10n_Dict.KeyText +FROM + L10n_Dict +GROUP BY + L10n_Dict.KeyText PIVOT L10n_Dict.LangCode; diff --git a/source/tables/L10n_Dict.xml b/source/tables/L10n_Dict.xml new file mode 100644 index 0000000..164c1ff --- /dev/null +++ b/source/tables/L10n_Dict.xml @@ -0,0 +1,497 @@ + + + + DE + <Create new> + <Neu erstellen> + + + DE + ACLib FilterForm Wizard + ACLib FilterForm Wizard + + + DE + ACLib FilterForm Wizard: Incorrect start + ACLib FilterForm Wizard: Fehlerhafter Start + + + DE + Add filter controls + Filter-Steuerelemente anfügen + + + DE + All modules are already up to date. +Still re-insert? + Es sind bereits alle Module auf dem neuesten Stand. +Trotzdem neu einlesen? + + + DE + already installed + bereits installiert + + + DE + ApplyFilter method + ApplyFilter-Methode + + + DE + AutoFilter Checkbox: + AutoFilter-Checkbox: + + + DE + Check wizard version + Wizard-Version prüfen + + + DE + Code has been updated + Codemodule wurden aktualisiert + + + DE + CommandButton "Apply Filter": + CommandButton "Filter anwenden": + + + DE + CommandButton "Remove Filter": + CommandButton "Filter löschen": + + + DE + Control + Steuerelement + + + DE + Current version is installed + Aktuelle Version ist installiert + + + DE + Data field + Datenfeld + + + DE + Data type + Datentyp + + + DE + Don't show records + Anzeige leeren + + + DE + Error during version check + Fehler bei Versionsprüfung + + + DE + Fill list with names from data source + FilterControl-Liste mit Namen aus Datenquelle füllen + + + DE + Filter Classes + Filter-Klassen + + + DE + Filter code + Filter-Variante + + + DE + Filter controls: + Filter-Controls: + + + DE + filter current form + aktuelles Formular filtern + + + DE + Filter definition in tag property + Filter-Definition in Tag-Eigenschaft + + + DE + Filter form: + Filter-Formular: + + + DE + FilterControlManager methods + FilterControlManager-Methoden + + + DE + FilterStringBuilder methods + FilterStringBuilder-Methoden + + + DE + Insert Form Code + Formular-Code einfügen + + + DE + insert sample code + auskommentierten Beispiel-Code einfügen + + + DE + Install classes: + Klassen installieren: + + + DE + New + Neu + + + DE + New version ({0}) available + Neue Version ({0}) verfügbar + + + DE + or with checkbox: + oder z. B. mittels Checkbox: + + + DE + Other controls + weitere Steuerelemente + + + DE + Please select the data form in the "ApplyFilter method" option + Bitte wählen Sie die Datenform in der Option "ApplyFilter method" aus + + + DE + Please select the data form in the 'ApplyFilter method' option + Bitte wählen Sie die Datenform in der Option "ApplyFilter method" aus + + + DE + Please set the data form in the 'ApplyFilter method' option first! + Bitte zuerst in der 'ApplyFilter-Methode'-Option das Datenformular einstellen! + + + DE + Relational operator + Vergleichsoperator + + + DE + Replace all code modules (existing modules are overwritten) + Alle Codemodule erneuern (vorhandene Module werden überschrieben) + + + DE + Replace all code modules except 'SqlTools' (SqlTools remains unchanged) + Alle Codemodule außer 'SqlTools' erneuern (SqlTools bleibt unverändert) + + + DE + Select SQL dialect + SQL-Dialekt auswählen + + + DE + Show all records + Alle Datensätze anzeigen + + + DE + show 'apply filter' is required + Notwendigen Klick auf "Filter anwenden" signalisieren + + + DE + SQL dialect: + SQL-Dialekt: + + + DE + Subform + Unterformular + + + DE + The add-in must be installed into the Access add-in directory using the add-in manager. Afterwards it has to be started via the menu entry 'ACLib FilterForm Wizard'. + Das Add-In muss mit dem Add-In-Manager ins Access-Add-In-Verzeichnis installiert werden. Anschließend ist es über den Menü-Eintrag "ACLib FilterForm Wizard" zu starten. + + + DE + Update code modules in the add-in from the SCC repository (draft). + Codemodule in Add-In aus SCC-Repository aktualisieren (draft). + + + DE + Update code modules in the add-in from the SCC repository (master). + Codemodule in Add-In aus SCC-Repository aktualisieren (master). + + + DE + without parameter transfer all records are displayed + ohne Parameterübergabe werden alle Datensätze angezeigt + + + EN + <Create new> + <Create new> + + + EN + ACLib FilterForm Wizard + ACLib FilterForm Wizard + + + EN + ACLib FilterForm Wizard: Incorrect start + ACLib FilterForm Wizard: Incorrect start + + + EN + Add filter controls + Add filter controls + + + EN + All modules are already up to date. +Still re-insert? + All modules are already up to date. +Still re-insert? + + + EN + already installed + already installed + + + EN + ApplyFilter method + ApplyFilter method + + + EN + AutoFilter Checkbox: + AutoFilter Checkbox: + + + EN + Check wizard version + Check wizard version + + + EN + Code has been updated + Code has been updated + + + EN + CommandButton "Apply Filter": + CommandButton "Apply Filter": + + + EN + CommandButton "Remove Filter": + CommandButton "Remove Filter": + + + EN + Control + Control + + + EN + Current version is installed + Current version is installed + + + EN + Data field + Data field + + + EN + Data type + Data type + + + EN + Don't show records + Don't show records + + + EN + Error during version check + Error during version check + + + EN + Fill list with names from data source + Fill list with names from data source + + + EN + Filter Classes + Filter Classes + + + EN + Filter code + Filter code + + + EN + Filter controls: + Filter controls: + + + EN + filter current form + filter current form + + + EN + Filter definition in tag property + Filter definition in tag property + + + EN + Filter form: + Filter form: + + + EN + FilterControlManager methods + FilterControlManager methods + + + EN + FilterStringBuilder methods + FilterStringBuilder methods + + + EN + Insert Form Code + Insert Form Code + + + EN + insert sample code + insert sample code + + + EN + Install classes: + Install classes: + + + EN + New + New + + + EN + New version ({0}) available + New version ({0}) available + + + EN + or with checkbox: + or with checkbox: + + + EN + Other controls + Other controls + + + EN + Please select the data form in the "ApplyFilter method" option + Please select the data form in the "ApplyFilter method" option + + + EN + Please select the data form in the 'ApplyFilter method' option + Please select the data form in the 'ApplyFilter method' option + + + EN + Please set the data form in the 'ApplyFilter method' option first! + Please set the data form in the 'ApplyFilter method' option first! + + + EN + Relational operator + Relational operator + + + EN + Replace all code modules (existing modules are overwritten) + Replace all code modules (existing modules are overwritten) + + + EN + Replace all code modules except 'SqlTools' (SqlTools remains unchanged) + Replace all code modules except 'SqlTools' (SqlTools remains unchanged) + + + EN + Select SQL dialect + Select SQL dialect + + + EN + Show all records + Show all records + + + EN + show 'apply filter' is required + show 'apply filter' is required + + + EN + SQL dialect: + SQL dialect: + + + EN + Subform + Subform + + + EN + The add-in must be installed into the Access add-in directory using the add-in manager. Afterwards it has to be started via the menu entry 'ACLib FilterForm Wizard'. + The add-in must be installed into the Access add-in directory using the add-in manager. Afterwards it has to be started via the menu entry 'ACLib FilterForm Wizard'. + + + EN + Update code modules in the add-in from the SCC repository (draft). + Update code modules in the add-in from the SCC repository (draft). + + + EN + Update code modules in the add-in from the SCC repository (master). + Update code modules in the add-in from the SCC repository (master). + + + EN + without parameter transfer all records are displayed + without parameter transfer all records are displayed + + diff --git a/source/tables/USysRegInfo.xml b/source/tables/USysRegInfo.xml new file mode 100644 index 0000000..40e2460 --- /dev/null +++ b/source/tables/USysRegInfo.xml @@ -0,0 +1,31 @@ + + + + HKEY_CURRENT_ACCESS_PROFILE\Menu Add-Ins\ACLib FilterForm Wizard + 4 + BitmapID + 339 + + + HKEY_CURRENT_ACCESS_PROFILE\Menu Add-Ins\ACLib FilterForm Wizard + 0 + + + HKEY_CURRENT_ACCESS_PROFILE\Menu Add-Ins\ACLib FilterForm Wizard + 1 + Library + |ACCDIR\ACLibFilterFormWizard.accda + + + HKEY_CURRENT_ACCESS_PROFILE\Menu Add-Ins\ACLib FilterForm Wizard + 1 + Expression + =StartApplication() + + + HKEY_CURRENT_ACCESS_PROFILE\Menu Add-Ins\ACLib FilterForm Wizard + 4 + Version + 1 + + diff --git a/source/tables/tabRelationalOperators.xml b/source/tables/tabRelationalOperators.xml new file mode 100644 index 0000000..8d0e234 --- /dev/null +++ b/source/tables/tabRelationalOperators.xml @@ -0,0 +1,38 @@ + + + + <= + SQL_Equal + SQL_LessThan + 2 + + + <> + SQL_LessThan + SQL_GreaterThan + 4 + + + = + SQL_Equal + 1 + + + >= + SQL_Equal + SQL_GreaterThan + 3 + + + Between + SQL_Between + 6 + + + In (…) + SQL_In + 7 + + + Like + SQL_Like + 5 + + diff --git a/source/tables/tabSqlFieldDataTypes.xml b/source/tables/tabSqlFieldDataTypes.xml new file mode 100644 index 0000000..2c302b7 --- /dev/null +++ b/source/tables/tabSqlFieldDataTypes.xml @@ -0,0 +1,19 @@ + + + + Boolean + SQL_Boolean + + + Date + SQL_Date + + + Numeric + SQL_Numeric + + + Text + SQL_Text + + diff --git a/source/tables/tabSqlLangFormat.xml b/source/tables/tabSqlLangFormat.xml new file mode 100644 index 0000000..07353b0 --- /dev/null +++ b/source/tables/tabSqlLangFormat.xml @@ -0,0 +1,27 @@ + + + + Jet/ADODB + \#yyyy-mm-dd hh:nn:ss\# + True + % + + + Jet/DAO + \#yyyy-mm-dd hh:nn:ss\# + True + * + + + MySQL + 'yyyy-mm-dd hh:nn:ss' + 1 + % + + + T-SQL (SQL Server) + 'yyyymmdd hh:nn:ss' + 1 + % + + diff --git a/source/tables/usys_AppFiles.xml b/source/tables/usys_AppFiles.xml new file mode 100644 index 0000000..9b54675 --- /dev/null +++ b/source/tables/usys_AppFiles.xml @@ -0,0 +1,2677 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AppIcon + AAABAAEAICAQAAEABADoAgAAFgAAACgAAAAgAAAAQAAAAAEABAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAgEAAAP9eXgAA6AAAJ5sAAP//AAAAAIAAeVywAAAA +/wD/AP8AAICAAAD//wCAgIAA0L7gAJsAmwD///8AAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAB3AAAAAAAAAAAAAAAAAAB8wHAAAAAAAAAAAAAAAAB3/9wMAAAAAAAAAAAA +AAB3/93M0HAAAAAAAAAAAAB3/9wADN0HAAAAAAAAAAB3/9wADdDN0HAAAAAAAAB3 +/9wADd3dDN0HAAAAAAAgcNwADd3d3dDN0LuwAAAAIHAADd3czd3dDAAAqgAAACBw +Dd3czd3d3dALuwqgAAAgBw3d3d3d3d3dALuwoAAAIQdw3d3d3dzN0NALuwAAACEQ +dw3d0AzN0A0FAADAAAAhEQdw3QiA3QUFANAAAAAAIREQdwCICABQAADdADREACER +EAcIgIgFBVVQAAMwAAAhERCwCAiIAFVVAAAzAzMwIREQuggIiAVVUFAAMDMzACER +ELsICIBQAAAFDwMzMAAhERC6sAgAAAAAAFBQAAAAIREQu6sABQAAAAAFAAAAACER +ELq6oKBQAAAAUFAAAAAgAAC7q6CgBQAABQAFCqAAAN8Au7ugoACQ4FAAALCqAA8N +8LAAAKAAkO4AAAC7CqBg8NAA3wCgAJDu4AAAu7CgZg8ADw3woACZDuAAAAuwoAYA +AADw3wAACZDgAAAAsACAAAAADwDwAACZAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAD//P////B////AP///AB///AAP//AAB//AAAP/AAAAfwAA +AD8AAAAfAAAADwAAAA8AAAAfAAAAHwAAAEMAAAABAAAAAAAAAgAAAAIBAAAQAwAA ++AcAAfx/AAD4JwAAEQMAAgOBAAIHgAACA4AAAgPABgMD4R8Dh/Mfk8//n////w== + + + + FilterControl + VkVSU0lPTiAxLjAgQ0xBU1MNCkJFR0lODQogIE11bHRpVXNlID0gLTEgICdUcnVl +DQpFTkQNCkF0dHJpYnV0ZSBWQl9OYW1lID0gIkZpbHRlckNvbnRyb2wiDQpBdHRy +aWJ1dGUgVkJfR2xvYmFsTmFtZVNwYWNlID0gRmFsc2UNCkF0dHJpYnV0ZSBWQl9D +cmVhdGFibGUgPSBGYWxzZQ0KQXR0cmlidXRlIFZCX1ByZWRlY2xhcmVkSWQgPSBG +YWxzZQ0KQXR0cmlidXRlIFZCX0V4cG9zZWQgPSBGYWxzZQ0KJy0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBLbGFzc2U6IEZpbHRlckNv +bnRyb2wNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0N +CicvKioNCicgXGF1dGhvciAgICAgICBKb3NlZiBQb2V0emwNCicgPHN1bW1hcnk+ +DQonIEZvcm11bGFyLVN0ZXVlcmVsZW1lbnQgbWl0IEZpbHRlcmVpbnN0ZWxsdW5n +ZW4NCicgPC9zdW1tYXJ5Pg0KJyA8cmVtYXJrcz5XaXJkIGluIEZpbHRlckNvbnRy +b2xDb2xsZWN0aW9uIHVuZCBGaWx0ZXJDb250cm9sTWFuYWdlciB2ZXJ3ZW5kZXQ8 +L3JlbWFya3M+DQonIFxpbmdyb3VwIGRhdGENCicqKi8NCictLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCic8Y29kZWxpYj4NCicgIDxmaWxl +PmZvcm0vZmlsdGVyL0ZpbHRlckNvbnRyb2wuY2xzPC9maWxlPg0KJyAgPGxpY2Vu +c2U+X2NvZGVsaWIvbGljZW5zZS5iYXM8L2xpY2Vuc2U+DQonICA8dXNlPmRhdGEv +U3FsVG9vbHMuY2xzPC91c2U+DQonICA8dXNlPmZvcm0vZmlsdGVyL0ZpbHRlckNv +bnRyb2xFdmVudEJyaWRnZS5jbHM8L3VzZT4NCic8L2NvZGVsaWI+DQonLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonDQpPcHRpb24gQ29t +cGFyZSBEYXRhYmFzZQ0KT3B0aW9uIEV4cGxpY2l0DQoNClByaXZhdGUgbV9FdmVu +dEJyaWRnZSBBcyBGaWx0ZXJDb250cm9sRXZlbnRCcmlkZ2UNCkF0dHJpYnV0ZSBt +X0V2ZW50QnJpZGdlLlZCX1ZhckhlbHBJRCA9IC0xDQoNClByaXZhdGUgbV9EYXRh +RmllbGQgQXMgU3RyaW5nDQpQcml2YXRlIG1fRGF0YVR5cGUgQXMgU3FsRmllbGRE +YXRhVHlwZQ0KUHJpdmF0ZSBtX1JlbGF0aW9uYWxPcGVyYXRvciBBcyBTcWxSZWxh +dGlvbmFsT3BlcmF0b3JzDQpQcml2YXRlIG1fSWdub3JlVmFsdWUgQXMgVmFyaWFu +dA0KDQpQcml2YXRlIG1fQ29udHJvbCBBcyBDb250cm9sDQpQcml2YXRlIFdpdGhF +dmVudHMgbV9UZXh0Ym94IEFzIFRleHRCb3gNCkF0dHJpYnV0ZSBtX1RleHRib3gu +VkJfVmFySGVscElEID0gLTENClByaXZhdGUgV2l0aEV2ZW50cyBtX0NvbWJvQm94 +IEFzIENvbWJvQm94DQpBdHRyaWJ1dGUgbV9Db21ib0JveC5WQl9WYXJIZWxwSUQg +PSAtMQ0KUHJpdmF0ZSBXaXRoRXZlbnRzIG1fTGlzdEJveCBBcyBMaXN0Qm94DQpB +dHRyaWJ1dGUgbV9MaXN0Qm94LlZCX1ZhckhlbHBJRCA9IC0xDQpQcml2YXRlIFdp +dGhFdmVudHMgbV9Ub2dnbGVCdXR0b24gQXMgVG9nZ2xlQnV0dG9uDQpBdHRyaWJ1 +dGUgbV9Ub2dnbGVCdXR0b24uVkJfVmFySGVscElEID0gLTENClByaXZhdGUgV2l0 +aEV2ZW50cyBtX0NoZWNrQm94IEFzIENoZWNrQm94DQpBdHRyaWJ1dGUgbV9DaGVj +a0JveC5WQl9WYXJIZWxwSUQgPSAtMQ0KUHJpdmF0ZSBXaXRoRXZlbnRzIG1fT3B0 +aW9uQnV0dG9uIEFzIE9wdGlvbkJ1dHRvbg0KQXR0cmlidXRlIG1fT3B0aW9uQnV0 +dG9uLlZCX1ZhckhlbHBJRCA9IC0xDQpQcml2YXRlIFdpdGhFdmVudHMgbV9PcHRp +b25Hcm91cCBBcyBPcHRpb25Hcm91cA0KQXR0cmlidXRlIG1fT3B0aW9uR3JvdXAu +VkJfVmFySGVscElEID0gLTENCg0KUHJpdmF0ZSBDb25zdCBFdmVudFByb2NlZHVy +ZVByb3BlcnR5VGFnIEFzIFN0cmluZyA9ICJbRXZlbnQgUHJvY2VkdXJlXSINCg0K +UHJpdmF0ZSBtX0ZpbHRlckNvbnRyb2wyIEFzIEZpbHRlckNvbnRyb2wNClByaXZh +dGUgbV9TdWJGaWx0ZXJDb250cm9scyBBcyBDb2xsZWN0aW9uDQoNClB1YmxpYyBE +aXNhYmxlUmVtb3ZlRmlsdGVyVmFsdWUgQXMgQm9vbGVhbg0KDQpQcml2YXRlIFN1 +YiBJbml0Q29udHJvbCgpDQoNCiAgIFJlbW92ZVdpdGhFdmVudHNDb250cm9sUmVm +cw0KDQogICBJZiBUeXBlT2YgbV9Db250cm9sLlBhcmVudCBJcyBPcHRpb25Hcm91 +cCBUaGVuDQogICAgICAnRXJlaWduaXNiZWhhbmRsdW5nIGJlaSBDb250cm9sIG5p +Y2h0IG32Z2xpY2ggPT4gbV9PcHRpb25Hcm91cC5BZnRlclVwZGF0ZSBwcvxmZW4N +CiAgICAgIFNldCBtX09wdGlvbkdyb3VwID0gbV9Db250cm9sLlBhcmVudA0KICAg +ICAgQ2hlY2tBZnRlclVwZGF0ZUV2ZW50SGFuZGxlciBtX09wdGlvbkdyb3VwDQog +ICAgICBFeGl0IFN1Yg0KICAgRW5kIElmDQoNCiAgIFNlbGVjdCBDYXNlIG1fQ29u +dHJvbC5Db250cm9sVHlwZQ0KICAgICAgQ2FzZSBhY1RleHRCb3gNCiAgICAgICAg +IFNldCBtX1RleHRib3ggPSBtX0NvbnRyb2wNCiAgICAgIENhc2UgYWNDb21ib0Jv +eA0KICAgICAgICAgU2V0IG1fQ29tYm9Cb3ggPSBtX0NvbnRyb2wNCiAgICAgIENh +c2UgYWNMaXN0Qm94DQogICAgICAgICBTZXQgbV9MaXN0Qm94ID0gbV9Db250cm9s +DQogICAgICBDYXNlIGFjVG9nZ2xlQnV0dG9uDQogICAgICAgICBTZXQgbV9Ub2dn +bGVCdXR0b24gPSBtX0NvbnRyb2wNCiAgICAgIENhc2UgYWNPcHRpb25CdXR0b24N +CiAgICAgICAgIFNldCBtX09wdGlvbkJ1dHRvbiA9IG1fQ29udHJvbA0KICAgICAg +Q2FzZSBhY0NoZWNrQm94DQogICAgICAgICBTZXQgbV9DaGVja0JveCA9IG1fQ29u +dHJvbA0KICAgICAgQ2FzZSBhY09wdGlvbkdyb3VwDQogICAgICAgICBTZXQgbV9P +cHRpb25Hcm91cCA9IG1fQ29udHJvbA0KICAgICAgQ2FzZSBFbHNlDQogICANCiAg +IEVuZCBTZWxlY3QNCiAgIA0KICAgQ2hlY2tBZnRlclVwZGF0ZUV2ZW50SGFuZGxl +ciBtX0NvbnRyb2wNCg0KRW5kIFN1Yg0KDQpQcml2YXRlIFN1YiBDaGVja0FmdGVy +VXBkYXRlRXZlbnRIYW5kbGVyKEJ5VmFsIENvbnRyb2xUb0NoZWNrIEFzIENvbnRy +b2wpDQoNCiAgIElmIExlbihDb250cm9sVG9DaGVjay5BZnRlclVwZGF0ZSkgPSAw +IFRoZW4NCiAgICAgIENvbnRyb2xUb0NoZWNrLkFmdGVyVXBkYXRlID0gRXZlbnRQ +cm9jZWR1cmVQcm9wZXJ0eVRhZw0KICAgRW5kIElmDQoNCkVuZCBTdWINCg0KUHJp +dmF0ZSBTdWIgUmVtb3ZlV2l0aEV2ZW50c0NvbnRyb2xSZWZzKCkNCiAgIFNldCBt +X1RleHRib3ggPSBOb3RoaW5nDQogICBTZXQgbV9Db21ib0JveCA9IE5vdGhpbmcN +CiAgIFNldCBtX0xpc3RCb3ggPSBOb3RoaW5nDQogICBTZXQgbV9Ub2dnbGVCdXR0 +b24gPSBOb3RoaW5nDQogICBTZXQgbV9DaGVja0JveCA9IE5vdGhpbmcNCiAgIFNl +dCBtX09wdGlvbkJ1dHRvbiA9IE5vdGhpbmcNCiAgIFNldCBtX09wdGlvbkdyb3Vw +ID0gTm90aGluZw0KRW5kIFN1Yg0KDQpQcml2YXRlIFN1YiBDbGFzc19Jbml0aWFs +aXplKCkNCiAgIG1fSWdub3JlVmFsdWUgPSBOdWxsDQpFbmQgU3ViDQoNClByaXZh +dGUgU3ViIENsYXNzX1Rlcm1pbmF0ZSgpDQogICBEaXNwb3NlDQpFbmQgU3ViDQoN +CkZyaWVuZCBTdWIgRGlzcG9zZSgpDQogICBTZXQgbV9FdmVudEJyaWRnZSA9IE5v +dGhpbmcNCiAgIFNldCBtX1N1YkZpbHRlckNvbnRyb2xzID0gTm90aGluZw0KICAg +U2V0IG1fRmlsdGVyQ29udHJvbDIgPSBOb3RoaW5nDQogICBTZXQgbV9Db250cm9s +ID0gTm90aGluZw0KRW5kIFN1Yg0KDQpGcmllbmQgUHJvcGVydHkgR2V0IEV2ZW50 +QnJpZGdlKCkgQXMgRmlsdGVyQ29udHJvbEV2ZW50QnJpZGdlDQogICBTZXQgRXZl +bnRCcmlkZ2UgPSBtX0V2ZW50QnJpZGdlDQpFbmQgUHJvcGVydHkNCg0KRnJpZW5k +IFByb3BlcnR5IFNldCBFdmVudEJyaWRnZShCeVZhbCBOZXdSZWYgQXMgRmlsdGVy +Q29udHJvbEV2ZW50QnJpZGdlKQ0KDQogICBTZXQgbV9FdmVudEJyaWRnZSA9IE5l +d1JlZg0KDQogICBJZiBOb3QgKG1fRmlsdGVyQ29udHJvbDIgSXMgTm90aGluZykg +VGhlbg0KICAgICAgU2V0IG1fRmlsdGVyQ29udHJvbDIuRXZlbnRCcmlkZ2UgPSBt +X0V2ZW50QnJpZGdlDQogICBFbmQgSWYNCg0KICAgSWYgbV9TdWJGaWx0ZXJDb250 +cm9scyBJcyBOb3RoaW5nIFRoZW4gRXhpdCBQcm9wZXJ0eQ0KICAgSWYgbV9TdWJG +aWx0ZXJDb250cm9scy5Db3VudCA9IDAgVGhlbiBFeGl0IFByb3BlcnR5DQogICAN +CiAgIERpbSBmYyBBcyBGaWx0ZXJDb250cm9sDQogICBGb3IgRWFjaCBmYyBJbiBt +X1N1YkZpbHRlckNvbnRyb2xzDQogICAgICBTZXQgZmMuRXZlbnRCcmlkZ2UgPSBt +X0V2ZW50QnJpZGdlDQogICBOZXh0DQoNCkVuZCBQcm9wZXJ0eQ0KDQpQcml2YXRl +IFN1YiBSYWlzZUZpbHRlclZhbHVlQ2hhbmdlZCgpDQogICBJZiBtX0V2ZW50QnJp +ZGdlIElzIE5vdGhpbmcgVGhlbiBFeGl0IFN1Yg0KICAgbV9FdmVudEJyaWRnZS5S +YWlzZUZpbHRlclZhbHVlQ2hhbmdlZCBNZQ0KRW5kIFN1Yg0KDQpQdWJsaWMgUHJv +cGVydHkgR2V0IFNlbGYoKSBBcyBGaWx0ZXJDb250cm9sDQogICBTZXQgU2VsZiA9 +IE1lDQpFbmQgUHJvcGVydHkNCg0KUHVibGljIFByb3BlcnR5IEdldCBDb250cm9s +KCkgQXMgQ29udHJvbA0KICAgU2V0IENvbnRyb2wgPSBtX0NvbnRyb2wNCkVuZCBQ +cm9wZXJ0eQ0KDQpQdWJsaWMgUHJvcGVydHkgU2V0IENvbnRyb2woQnlWYWwgTmV3 +UmVmIEFzIENvbnRyb2wpDQogICBTZXQgbV9Db250cm9sID0gTmV3UmVmDQogICBJ +bml0Q29udHJvbA0KRW5kIFByb3BlcnR5DQoNClB1YmxpYyBQcm9wZXJ0eSBHZXQg +Q29udHJvbDIoKSBBcyBDb250cm9sDQogICBJZiBtX0ZpbHRlckNvbnRyb2wyIElz +IE5vdGhpbmcgVGhlbg0KICAgICAgU2V0IENvbnRyb2wyID0gTm90aGluZw0KICAg +RWxzZQ0KICAgICAgU2V0IENvbnRyb2wyID0gbV9GaWx0ZXJDb250cm9sMi5Db250 +cm9sDQogICBFbmQgSWYNCkVuZCBQcm9wZXJ0eQ0KDQpQdWJsaWMgUHJvcGVydHkg +U2V0IENvbnRyb2wyKEJ5VmFsIE5ld1JlZiBBcyBDb250cm9sKQ0KICAgU2V0IG1f +RmlsdGVyQ29udHJvbDIgPSBOZXcgRmlsdGVyQ29udHJvbA0KICAgV2l0aCBtX0Zp +bHRlckNvbnRyb2wyDQogICAgICBTZXQgLkNvbnRyb2wgPSBOZXdSZWYNCiAgICAg +IFNldCAuRXZlbnRCcmlkZ2UgPSBtX0V2ZW50QnJpZGdlDQogICBFbmQgV2l0aA0K +RW5kIFByb3BlcnR5DQoNClB1YmxpYyBQcm9wZXJ0eSBHZXQgU3ViQ29udHJvbHMo +KSBBcyBDb2xsZWN0aW9uDQogICBJZiBtX1N1YkZpbHRlckNvbnRyb2xzIElzIE5v +dGhpbmcgVGhlbg0KICAgICAgU2V0IFN1YkNvbnRyb2xzID0gTm90aGluZw0KICAg +RWxzZQ0KICAgICAgU2V0IFN1YkNvbnRyb2xzID0gbV9TdWJGaWx0ZXJDb250cm9s +cw0KICAgRW5kIElmDQpFbmQgUHJvcGVydHkNCg0KUHVibGljIFN1YiBTZXRTdWJD +b250cm9scyhCeVZhbCBTdWJDb250cm9sQXJyYXkgQXMgVmFyaWFudCkNCg0KICAg +RGltIGN0bCBBcyBWYXJpYW50DQoNCiAgIFNldCBtX1N1YkZpbHRlckNvbnRyb2xz +ID0gTmV3IENvbGxlY3Rpb24NCiAgIEZvciBFYWNoIGN0bCBJbiBTdWJDb250cm9s +QXJyYXkNCiAgICAgIFdpdGggTmV3IEZpbHRlckNvbnRyb2wNCiAgICAgICAgIFNl +dCAuQ29udHJvbCA9IGN0bA0KICAgICAgICAgU2V0IC5FdmVudEJyaWRnZSA9IG1f +RXZlbnRCcmlkZ2UNCiAgICAgICAgIC5JZ25vcmVWYWx1ZSA9IG1fSWdub3JlVmFs +dWUNCiAgICAgICAgIG1fU3ViRmlsdGVyQ29udHJvbHMuQWRkIC5TZWxmDQogICAg +ICBFbmQgV2l0aA0KICAgTmV4dA0KDQpFbmQgU3ViDQoNClB1YmxpYyBQcm9wZXJ0 +eSBHZXQgRGF0YUZpZWxkKCkgQXMgU3RyaW5nDQogICBEYXRhRmllbGQgPSBtX0Rh +dGFGaWVsZA0KRW5kIFByb3BlcnR5DQoNClB1YmxpYyBQcm9wZXJ0eSBMZXQgRGF0 +YUZpZWxkKEJ5VmFsIE5ld1ZhbHVlIEFzIFN0cmluZykNCiAgIG1fRGF0YUZpZWxk +ID0gTmV3VmFsdWUNCkVuZCBQcm9wZXJ0eQ0KDQpQdWJsaWMgUHJvcGVydHkgR2V0 +IERhdGFUeXBlKCkgQXMgU3FsRmllbGREYXRhVHlwZQ0KICAgRGF0YVR5cGUgPSBt +X0RhdGFUeXBlDQpFbmQgUHJvcGVydHkNCg0KUHVibGljIFByb3BlcnR5IExldCBE +YXRhVHlwZShCeVZhbCBOZXdWYWx1ZSBBcyBTcWxGaWVsZERhdGFUeXBlKQ0KICAg +bV9EYXRhVHlwZSA9IE5ld1ZhbHVlDQpFbmQgUHJvcGVydHkNCg0KUHVibGljIFBy +b3BlcnR5IEdldCBSZWxhdGlvbmFsT3BlcmF0b3IoKSBBcyBTcWxSZWxhdGlvbmFs +T3BlcmF0b3JzDQogICBSZWxhdGlvbmFsT3BlcmF0b3IgPSBtX1JlbGF0aW9uYWxP +cGVyYXRvcg0KRW5kIFByb3BlcnR5DQoNClB1YmxpYyBQcm9wZXJ0eSBMZXQgUmVs +YXRpb25hbE9wZXJhdG9yKEJ5VmFsIE5ld1ZhbHVlIEFzIFNxbFJlbGF0aW9uYWxP +cGVyYXRvcnMpDQogICBtX1JlbGF0aW9uYWxPcGVyYXRvciA9IE5ld1ZhbHVlDQpF +bmQgUHJvcGVydHkNCg0KUHVibGljIFByb3BlcnR5IEdldCBJZ25vcmVWYWx1ZSgp +IEFzIFZhcmlhbnQNCiAgIElnbm9yZVZhbHVlID0gbV9JZ25vcmVWYWx1ZQ0KRW5k +IFByb3BlcnR5DQoNClB1YmxpYyBQcm9wZXJ0eSBMZXQgSWdub3JlVmFsdWUoQnlW +YWwgTmV3VmFsdWUgQXMgVmFyaWFudCkNCiAgIG1fSWdub3JlVmFsdWUgPSBOZXdW +YWx1ZQ0KRW5kIFByb3BlcnR5DQoNClByaXZhdGUgRnVuY3Rpb24gR2V0Q2hlY2tl +ZElnbm9yZVZhbHVlKCkgQXMgVmFyaWFudA0KICAgSWYgSXNBcnJheShtX0lnbm9y +ZVZhbHVlKSBUaGVuDQogICAgICBHZXRDaGVja2VkSWdub3JlVmFsdWUgPSBtX0ln +bm9yZVZhbHVlKExCb3VuZChtX0lnbm9yZVZhbHVlKSkNCiAgIEVsc2UNCiAgICAg +IEdldENoZWNrZWRJZ25vcmVWYWx1ZSA9IG1fSWdub3JlVmFsdWUNCiAgIEVuZCBJ +Zg0KRW5kIEZ1bmN0aW9uDQoNClB1YmxpYyBGdW5jdGlvbiBDcml0ZXJpYVN0cmlu +ZyhCeVZhbCBTcWxUb29sc1JlZiBBcyBTcWxUb29scykgQXMgU3RyaW5nDQogICAN +CiAgIElmIG1fU3ViRmlsdGVyQ29udHJvbHMgSXMgTm90aGluZyBUaGVuDQogICAg +ICBDcml0ZXJpYVN0cmluZyA9IFNxbFRvb2xzUmVmLkJ1aWxkQ3JpdGVyaWEobV9E +YXRhRmllbGQsIG1fRGF0YVR5cGUsIG1fUmVsYXRpb25hbE9wZXJhdG9yLCBHZXRD +b250cm9sVmFsdWUoQ29udHJvbCksIEdldENvbnRyb2xWYWx1ZShDb250cm9sMiks +IElnbm9yZVZhbHVlLCBGYWxzZSkNCiAgIEVsc2UNCiAgICAgIENyaXRlcmlhU3Ry +aW5nID0gU3FsVG9vbHNSZWYuQnVpbGRDcml0ZXJpYShtX0RhdGFGaWVsZCwgbV9E +YXRhVHlwZSwgbV9SZWxhdGlvbmFsT3BlcmF0b3IsIEdldFN1YkNvbnRyb2xzVmFs +dWVzLCAsIElnbm9yZVZhbHVlLCBGYWxzZSkNCiAgIEVuZCBJZg0KDQpFbmQgRnVu +Y3Rpb24NCg0KUHJpdmF0ZSBGdW5jdGlvbiBHZXRTdWJDb250cm9sc1ZhbHVlcygp +IEFzIFZhcmlhbnQoKQ0KICAgDQogICBEaW0gZmMgQXMgRmlsdGVyQ29udHJvbA0K +ICAgRGltIGkgQXMgTG9uZw0KICAgRGltIFZhbHVlcygpIEFzIFZhcmlhbnQNCiAg +IFJlRGltIFZhbHVlcygwIFRvIChtX1N1YkZpbHRlckNvbnRyb2xzLkNvdW50IC0g +MSkpDQoNCiAgIEZvciBFYWNoIGZjIEluIG1fU3ViRmlsdGVyQ29udHJvbHMNCiAg +ICAgIFNlbGVjdCBDYXNlIGZjLkNvbnRyb2wuQ29udHJvbFR5cGUNCiAgICAgICAg +IENhc2UgYWNDaGVja0JveCwgYWNUb2dnbGVCdXR0b24sIGFjT3B0aW9uQnV0dG9u +DQogICAgICAgICAgICBJZiBUeXBlT2YgZmMuQ29udHJvbC5QYXJlbnQgSXMgT3B0 +aW9uR3JvdXAgVGhlbg0KICAgICAgICAgICAgICAgSWYgZmMuQ29udHJvbC5PcHRp +b25WYWx1ZSA9IGZjLkNvbnRyb2wuUGFyZW50LlZhbHVlIFRoZW4NCiAgICAgICAg +ICAgICAgICAgIFZhbHVlcyhpKSA9IGZjLkNvbnRyb2wuVGFnDQogICAgICAgICAg +ICAgICBFbHNlDQogICAgICAgICAgICAgICAgICBWYWx1ZXMoaSkgPSBHZXRDaGVj +a2VkSWdub3JlVmFsdWUNCiAgICAgICAgICAgICAgIEVuZCBJZg0KICAgICAgICAg +ICAgRWxzZQ0KICAgICAgICAgICAgICAgSWYgZmMuQ29udHJvbC5WYWx1ZSA9IFRy +dWUgVGhlbg0KICAgICAgICAgICAgICAgICAgVmFsdWVzKGkpID0gZmMuQ29udHJv +bC5UYWcNCiAgICAgICAgICAgICAgIEVsc2UNCiAgICAgICAgICAgICAgICAgIFZh +bHVlcyhpKSA9IEdldENoZWNrZWRJZ25vcmVWYWx1ZQ0KICAgICAgICAgICAgICAg +RW5kIElmDQogICAgICAgICAgICBFbmQgSWYNCiAgICAgICAgIENhc2UgRWxzZQ0K +ICAgICAgICAgICAgVmFsdWVzKGkpID0gZmMuQ29udHJvbC5WYWx1ZQ0KICAgICAg +RW5kIFNlbGVjdA0KICAgICAgaSA9IGkgKyAxDQogICBOZXh0DQoNCiAgIEdldFN1 +YkNvbnRyb2xzVmFsdWVzID0gVmFsdWVzDQoNCkVuZCBGdW5jdGlvbg0KDQpQcml2 +YXRlIEZ1bmN0aW9uIEdldENvbnRyb2xWYWx1ZShCeVZhbCBDb250cm9sUmVmIEFz +IENvbnRyb2wpIEFzIFZhcmlhbnQNCiAgIA0KICAgSWYgQ29udHJvbFJlZiBJcyBO +b3RoaW5nIFRoZW4NCiAgICAgIEdldENvbnRyb2xWYWx1ZSA9IE51bGwNCiAgICAg +IEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0KICAgDQogICBJZiBUeXBlT2YgQ29u +dHJvbFJlZiBJcyBMaXN0Qm94IFRoZW4NCiAgICAgIEdldENvbnRyb2xWYWx1ZSA9 +IEdldExpc3RCb3hGaWx0ZXJWYWx1ZShDb250cm9sUmVmKQ0KICAgICAgRXhpdCBG +dW5jdGlvbg0KICAgRW5kIElmDQoNCiAgIEdldENvbnRyb2xWYWx1ZSA9IENvbnRy +b2xSZWYuVmFsdWUNCiAgIA0KRW5kIEZ1bmN0aW9uDQoNClByaXZhdGUgRnVuY3Rp +b24gR2V0TGlzdEJveEZpbHRlclZhbHVlKEJ5VmFsIExpc3RCb3hSZWYgQXMgTGlz +dEJveCkgQXMgVmFyaWFudA0KICAgDQogICBJZiBMaXN0Qm94UmVmLk11bHRpU2Vs +ZWN0ID4gMCBUaGVuDQogICAgICBHZXRMaXN0Qm94RmlsdGVyVmFsdWUgPSBHZXRT +ZWxlY3RlZExpc3Rib3hJdGVtQXJyYXkoTGlzdEJveFJlZiwgTGlzdEJveFJlZi5C +b3VuZENvbHVtbiAtIDEpDQogICBFbHNlDQogICAgICBHZXRMaXN0Qm94RmlsdGVy +VmFsdWUgPSBMaXN0Qm94UmVmLlZhbHVlDQogICBFbmQgSWYNCiAgIA0KRW5kIEZ1 +bmN0aW9uDQoNClByaXZhdGUgRnVuY3Rpb24gR2V0U2VsZWN0ZWRMaXN0Ym94SXRl +bUFycmF5KEJ5VmFsIExpc3RCb3hSZWYgQXMgTGlzdEJveCwgQnlWYWwgQ29sdW1u +SW5kZXggQXMgTG9uZykgQXMgVmFyaWFudCgpDQogICANCiAgIERpbSBJdGVtQXJy +YXkoKSBBcyBWYXJpYW50DQogICBEaW0gTWF4QXJySW5kZXggQXMgTG9uZw0KICAg +RGltIFNlbGVjdGVkSXRlbXMgQXMgW19JdGVtc1NlbGVjdGVkXQ0KDQogICBTZXQg +U2VsZWN0ZWRJdGVtcyA9IExpc3RCb3hSZWYuSXRlbXNTZWxlY3RlZA0KICAgTWF4 +QXJySW5kZXggPSBTZWxlY3RlZEl0ZW1zLkNvdW50IC0gMQ0KICAgSWYgTWF4QXJy +SW5kZXggPCAwIFRoZW4NCiAgICAgIEdldFNlbGVjdGVkTGlzdGJveEl0ZW1BcnJh +eSA9IEl0ZW1BcnJheQ0KICAgICAgRXhpdCBGdW5jdGlvbg0KICAgRW5kIElmDQoN +CiAgIFJlRGltIEl0ZW1BcnJheShNYXhBcnJJbmRleCkNCiAgIERpbSBpIEFzIExv +bmcNCg0KICAgRm9yIGkgPSAwIFRvIE1heEFyckluZGV4DQogICAgICBJdGVtQXJy +YXkoaSkgPSBMaXN0Qm94UmVmLkNvbHVtbihDb2x1bW5JbmRleCwgU2VsZWN0ZWRJ +dGVtcy5JdGVtKGkpKQ0KICAgTmV4dA0KDQogICBHZXRTZWxlY3RlZExpc3Rib3hJ +dGVtQXJyYXkgPSBJdGVtQXJyYXkNCg0KRW5kIEZ1bmN0aW9uDQoNClByaXZhdGUg +U3ViIG1fQ2hlY2tCb3hfQWZ0ZXJVcGRhdGUoKQ0KICAgUmFpc2VGaWx0ZXJWYWx1 +ZUNoYW5nZWQNCkVuZCBTdWINCg0KUHJpdmF0ZSBTdWIgbV9Db21ib0JveF9BZnRl +clVwZGF0ZSgpDQogICBSYWlzZUZpbHRlclZhbHVlQ2hhbmdlZA0KRW5kIFN1Yg0K +DQpQcml2YXRlIFN1YiBtX0xpc3RCb3hfQWZ0ZXJVcGRhdGUoKQ0KICAgUmFpc2VG +aWx0ZXJWYWx1ZUNoYW5nZWQNCkVuZCBTdWINCg0KUHJpdmF0ZSBTdWIgbV9PcHRp +b25CdXR0b25fQWZ0ZXJVcGRhdGUoKQ0KICAgUmFpc2VGaWx0ZXJWYWx1ZUNoYW5n +ZWQNCkVuZCBTdWINCg0KUHJpdmF0ZSBTdWIgbV9PcHRpb25Hcm91cF9BZnRlclVw +ZGF0ZSgpDQogICBSYWlzZUZpbHRlclZhbHVlQ2hhbmdlZA0KRW5kIFN1Yg0KDQpQ +cml2YXRlIFN1YiBtX1RleHRib3hfQWZ0ZXJVcGRhdGUoKQ0KICAgUmFpc2VGaWx0 +ZXJWYWx1ZUNoYW5nZWQNCkVuZCBTdWINCg0KUHJpdmF0ZSBTdWIgbV9Ub2dnbGVC +dXR0b25fQWZ0ZXJVcGRhdGUoKQ0KICAgUmFpc2VGaWx0ZXJWYWx1ZUNoYW5nZWQN +CkVuZCBTdWINCg0KUHVibGljIFN1YiBSZW1vdmVGaWx0ZXJWYWx1ZShPcHRpb25h +bCBCeVZhbCBSYWlzZUZpbHRlclZhbHVlQ2hhbmdlZEV2ZW50IEFzIEJvb2xlYW4g +PSBUcnVlKQ0KDQogICBJZiBOb3QgKG1fQ29udHJvbCBJcyBOb3RoaW5nKSBUaGVu +DQoNCiAgICAgIFNlbGVjdCBDYXNlIG1fQ29udHJvbC5Db250cm9sVHlwZQ0KICAg +ICAgICAgQ2FzZSBhY0NoZWNrQm94LCBhY1RvZ2dsZUJ1dHRvbiwgYWNPcHRpb25C +dXR0b24NCiAgICAgICAgICAgIElmIFR5cGVPZiBtX0NvbnRyb2wuUGFyZW50IElz +IE9wdGlvbkdyb3VwIFRoZW4NCiAgICAgICAgICAgICAgIG1fQ29udHJvbC5QYXJl +bnQuVmFsdWUgPSBHZXRDaGVja2VkSWdub3JlVmFsdWUNCiAgICAgICAgICAgIEVs +c2UNCiAgICAgICAgICAgICAgIG1fQ29udHJvbC5WYWx1ZSA9IEZhbHNlDQogICAg +ICAgICAgICBFbmQgSWYNCiAgICAgICAgIENhc2UgYWNDb21ib0JveA0KICAgICAg +ICAgICAgSWYgSXNBcnJheShtX0NvbnRyb2wuVmFsdWUpIFRoZW4NCiAgICAgICAg +ICAgICAgIFJlbW92ZU11bHRpVmFsdWVTZWxlY3Rpb24gbV9Db250cm9sDQogICAg +ICAgICAgICBFbHNlSWYgbV9Db250cm9sLlZhbHVlID0gR2V0Q2hlY2tlZElnbm9y +ZVZhbHVlIFRoZW4NCiAgICAgICAgICAgIEVsc2VJZiBOb3QgKElzTnVsbChtX0Nv +bnRyb2wuVmFsdWUpIEFuZCBJc051bGwoR2V0Q2hlY2tlZElnbm9yZVZhbHVlKSkg +VGhlbg0KICAgICAgICAgICAgICAgbV9Db250cm9sLlZhbHVlID0gR2V0Q2hlY2tl +ZElnbm9yZVZhbHVlDQogICAgICAgICAgICBFbmQgSWYNCiAgICAgICAgIENhc2Ug +YWNMaXN0Qm94DQogICAgICAgICAgICBSZW1vdmVMaXN0Ym94U2VsZWN0aW9uIG1f +Q29udHJvbA0KICAgICAgICAgQ2FzZSBFbHNlDQogICAgICAgICAgICBtX0NvbnRy +b2wuVmFsdWUgPSBHZXRDaGVja2VkSWdub3JlVmFsdWUNCiAgICAgIEVuZCBTZWxl +Y3QNCiAgIEVuZCBJZg0KDQogICBJZiBOb3QgKG1fRmlsdGVyQ29udHJvbDIgSXMg +Tm90aGluZykgVGhlbg0KICAgICAgbV9GaWx0ZXJDb250cm9sMi5SZW1vdmVGaWx0 +ZXJWYWx1ZSBGYWxzZQ0KICAgRW5kIElmDQoNCiAgIElmIE5vdCAobV9TdWJGaWx0 +ZXJDb250cm9scyBJcyBOb3RoaW5nKSBUaGVuDQogICAgICBEaW0gZmMgQXMgRmls +dGVyQ29udHJvbA0KICAgICAgRm9yIEVhY2ggZmMgSW4gbV9TdWJGaWx0ZXJDb250 +cm9scw0KICAgICAgICAgZmMuUmVtb3ZlRmlsdGVyVmFsdWUgRmFsc2UNCiAgICAg +IE5leHQNCiAgIEVuZCBJZg0KDQogICBJZiBSYWlzZUZpbHRlclZhbHVlQ2hhbmdl +ZEV2ZW50IFRoZW4NCiAgICAgIFJhaXNlRmlsdGVyVmFsdWVDaGFuZ2VkDQogICBF +bmQgSWYNCkVuZCBTdWINCg0KUHJpdmF0ZSBTdWIgUmVtb3ZlTGlzdGJveFNlbGVj +dGlvbihCeVZhbCBMaXN0Qm94UmVmIEFzIExpc3RCb3gpDQogICANCiAgIERpbSBJ +dGVtIEFzIFZhcmlhbnQNCg0KICAgV2l0aCBMaXN0Qm94UmVmDQogICAgICBJZiBJ +c0FycmF5KC5WYWx1ZSkgVGhlbg0KICAgICAgICAgUmVtb3ZlTXVsdGlWYWx1ZVNl +bGVjdGlvbiBMaXN0Qm94UmVmDQogICAgICBFbHNlSWYgLk11bHRpU2VsZWN0ID0g +MSBUaGVuDQogICAgICAgICBGb3IgRWFjaCBJdGVtIEluIC5JdGVtc1NlbGVjdGVk +DQogICAgICAgICAgICAuU2VsZWN0ZWQoSXRlbSkgPSBGYWxzZQ0KICAgICAgICAg +TmV4dA0KICAgICAgRWxzZQ0KICAgICAgICAgLlZhbHVlID0gR2V0Q2hlY2tlZEln +bm9yZVZhbHVlDQogICAgICBFbmQgSWYNCiAgIEVuZCBXaXRoDQogICANCkVuZCBT +dWINCg0KUHJpdmF0ZSBTdWIgUmVtb3ZlTXVsdGlWYWx1ZVNlbGVjdGlvbihCeVZh +bCBNdWx0aVZhbHVlQ29udHJvbCBBcyBDb250cm9sKQ0KJyBBdXN3YWhsIGluIE11 +bHRpVmFsdWUtTGlzdGJveC9Db21ib2JveCBsZWVyZW4NCg0KICAgRGltIEZvcm1S +ZWYgQXMgRm9ybQ0KICAgRGltIHJzTVYgQXMgREFPLlJlY29yZHNldDINCg0KICAg +SWYgTm90IElzQXJyYXkoTXVsdGlWYWx1ZUNvbnRyb2wuVmFsdWUpIFRoZW4NCiAg +ICAgIEV4aXQgU3ViDQogICBFbmQgSWYNCiAgIA0KJyAgIE11bHRpVmFsdWVDb250 +cm9sLlZhbHVlID0gQXJyYXkoKSAnIEF1Z3VzdCAyMDE5OiBs5HVmdCBudW4gbmlj +aHQgbWVociA9PiBNZW1vcnkgb3ZlcmZsb3cgPT4gVW13ZWcg/GJlciBSZWNvcmRz +ZXQgZ2VoZW4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +JyAoZnVua3Rpb25pZXJ0ZSBub2NoIGJlaSBPZmZpY2UgMTkwMiBidWlsZCAxMTMy +OC4yMDM2OCwgV2luZG93cyAxMC4wLjEwNTg2IEJ1aWxkIDEwNTg2KQ0KICAgDQog +ICBTZXQgRm9ybVJlZiA9IG1fQ29udHJvbC5QYXJlbnQNCiAgIFNldCByc01WID0g +Rm9ybVJlZi5SZWNvcmRzZXQuRmllbGRzKE11bHRpVmFsdWVDb250cm9sLkNvbnRy +b2xTb3VyY2UpLlZhbHVlDQogICBXaXRoIHJzTVYNCiAgICAgIERvIFdoaWxlIE5v +dCAuRU9GDQogICAgICAgICAuRGVsZXRlDQogICAgICAgICAuUmVxdWVyeQ0KICAg +ICAgTG9vcA0KICAgRW5kIFdpdGgNCg0KICAgRm9ybVJlZi5EaXJ0eSA9IEZhbHNl +DQogICBNdWx0aVZhbHVlQ29udHJvbC5SZXF1ZXJ5DQogICANCkVuZCBTdWINCg== + + 20250609094839 + form/filter/FilterControl.cls + + + FilterControlCollection + VkVSU0lPTiAxLjAgQ0xBU1MNCkJFR0lODQogIE11bHRpVXNlID0gLTEgICdUcnVl +DQpFTkQNCkF0dHJpYnV0ZSBWQl9OYW1lID0gIkZpbHRlckNvbnRyb2xDb2xsZWN0 +aW9uIg0KQXR0cmlidXRlIFZCX0dsb2JhbE5hbWVTcGFjZSA9IEZhbHNlDQpBdHRy +aWJ1dGUgVkJfQ3JlYXRhYmxlID0gRmFsc2UNCkF0dHJpYnV0ZSBWQl9QcmVkZWNs +YXJlZElkID0gRmFsc2UNCkF0dHJpYnV0ZSBWQl9FeHBvc2VkID0gRmFsc2UNCict +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgS2xhc3Nl +OiBGaWx0ZXJDb250cm9sQ29sbGVjdGlvbg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLQ0KJy8qKg0KJyBcYXV0aG9yICAgICAgIEpvc2Vm +IFBvZXR6bA0KJyA8c3VtbWFyeT4NCicgU2FtbWx1bmcgdm9uIEZvcm11bGFyLVN0 +ZXVlcmVsZW1lbnRlbiB6dXIgRmlsdGVyZXJzdGVsbHVuZw0KJyA8L3N1bW1hcnk+ +DQonIDxyZW1hcmtzPldpcmQgaW4gRmlsdGVyQ29udHJvbE1hbmFnZXIgdmVyd2Vu +ZGV0PC9yZW1hcmtzPg0KJyBcaW5ncm91cCBkYXRhDQonKiovDQonLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonPGNvZGVsaWI+DQonICA8 +ZmlsZT5mb3JtL2ZpbHRlci9GaWx0ZXJDb250cm9sQ29sbGVjdGlvbi5jbHM8L2Zp +bGU+DQonICA8bGljZW5zZT5fY29kZWxpYi9saWNlbnNlLmJhczwvbGljZW5zZT4N +CicgIDx1c2U+Zm9ybS9maWx0ZXIvRmlsdGVyQ29udHJvbC5jbHM8L3VzZT4NCicg +IDx1c2U+Zm9ybS9maWx0ZXIvRmlsdGVyQ29udHJvbEV2ZW50QnJpZGdlLmNsczwv +dXNlPg0KJyAgPHVzZT5kYXRhL0ZpbHRlclN0cmluZ0J1aWxkZXIuY2xzPC91c2U+ +DQonICA8dXNlPmRhdGEvU3FsVG9vbHMuY2xzPC91c2U+DQonICA8dGVzdD5fdGVz +dC9mb3JtL2ZpbHRlci9GaWx0ZXJDb250cm9sQ29sbGVjdGlvblRlc3RzLmNsczwv +dGVzdD4NCic8L2NvZGVsaWI+DQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tDQonDQpPcHRpb24gQ29tcGFyZSBEYXRhYmFzZQ0KT3B0aW9u +IEV4cGxpY2l0DQoNClByaXZhdGUgbV9GaWx0ZXJDb250cm9scyBBcyBDb2xsZWN0 +aW9uDQpQcml2YXRlIFdpdGhFdmVudHMgbV9FdmVudEJyaWRnZSBBcyBGaWx0ZXJD +b250cm9sRXZlbnRCcmlkZ2UNCkF0dHJpYnV0ZSBtX0V2ZW50QnJpZGdlLlZCX1Zh +ckhlbHBJRCA9IC0xDQpQcml2YXRlIG1fSXRlbUNvbmNhdE9wZXJhdG9yIEFzIFNx +bExvZ2ljYWxPcGVyYXRvcg0KDQpQcml2YXRlIG1fU3FsUHJlZml4IEFzIFN0cmlu +Zw0KUHJpdmF0ZSBtX1NxbFN1ZmZpeCBBcyBTdHJpbmcNClByaXZhdGUgbV9Db25k +aXRpb25QcmVmaXggQXMgU3RyaW5nDQpQcml2YXRlIG1fSWdub3JlU3FsUHJlU3Vm +Zml4SWZFbXB0eUZpbHRlciBBcyBCb29sZWFuDQoNClByaXZhdGUgQ29uc3QgbV9X +aGVyZVJlcGxhY2VtZW50VGV4dCBBcyBTdHJpbmcgPSAiW1doZXJlU3RhdGVtZW50 +XSINCg0KUHVibGljIEV2ZW50IEZpbHRlclZhbHVlc0NoYW5nZWQoKQ0KUHVibGlj +IEV2ZW50IEZpbHRlclZhbHVlUmVxdWVzdChCeVZhbCBGaWx0ZXJWYWx1ZUNvZGUg +QXMgU3RyaW5nLCBCeVJlZiBGaWx0ZXJWYWx1ZSBBcyBTdHJpbmcpDQoNClByaXZh +dGUgU3ViIENsYXNzX0luaXRpYWxpemUoKQ0KICAgU2V0IG1fRmlsdGVyQ29udHJv +bHMgPSBOZXcgQ29sbGVjdGlvbg0KICAgU2V0IG1fRXZlbnRCcmlkZ2UgPSBOZXcg +RmlsdGVyQ29udHJvbEV2ZW50QnJpZGdlDQogICBtX0l0ZW1Db25jYXRPcGVyYXRv +ciA9IFNxbExvZ2ljYWxPcGVyYXRvci5TUUxfQW5kDQpFbmQgU3ViDQoNCkZyaWVu +ZCBQcm9wZXJ0eSBHZXQgRXZlbnRCcmlkZ2UoKSBBcyBGaWx0ZXJDb250cm9sRXZl +bnRCcmlkZ2UNCiAgIFNldCBFdmVudEJyaWRnZSA9IG1fRXZlbnRCcmlkZ2UNCkVu +ZCBQcm9wZXJ0eQ0KDQpGcmllbmQgUHJvcGVydHkgU2V0IEV2ZW50QnJpZGdlKEJ5 +VmFsIE5ld1JlZiBBcyBGaWx0ZXJDb250cm9sRXZlbnRCcmlkZ2UpDQoNCiAgIFNl +dCBtX0V2ZW50QnJpZGdlID0gTmV3UmVmDQogICANCiAgIERpbSBmYyBBcyBGaWx0 +ZXJDb250cm9sDQogICBGb3IgRWFjaCBmYyBJbiBtX0ZpbHRlckNvbnRyb2xzDQog +ICAgICBTZXQgZmMuRXZlbnRCcmlkZ2UgPSBtX0V2ZW50QnJpZGdlDQogICBOZXh0 +DQoNCkVuZCBQcm9wZXJ0eQ0KDQpQdWJsaWMgUHJvcGVydHkgR2V0IFNlbGYoKSBB +cyBGaWx0ZXJDb250cm9sQ29sbGVjdGlvbg0KICAgU2V0IFNlbGYgPSBNZQ0KRW5k +IFByb3BlcnR5DQoNClB1YmxpYyBGdW5jdGlvbiBBZGQoQnlWYWwgRGF0YUZpZWxk +TmFtZSBBcyBTdHJpbmcsIEJ5VmFsIERhdGFUeXBlIEFzIFNxbEZpZWxkRGF0YVR5 +cGUsIF8NCiAgICAgICAgICAgICAgIEJ5VmFsIFJlbGF0aW9uYWxPcGVyYXRvciBB +cyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzLCBfDQogICAgICAgICAgICAgICBCeVZh +bCBDb250cm9sUmVmIEFzIENvbnRyb2wsIF8NCiAgICAgIE9wdGlvbmFsIEJ5VmFs +IENvbnRyb2wyUmVmIEFzIENvbnRyb2wgPSBOb3RoaW5nLCBfDQogICAgICBPcHRp +b25hbCBCeVZhbCBJZ25vcmVWYWx1ZSBBcyBWYXJpYW50ID0gTnVsbCkgQXMgRmls +dGVyQ29udHJvbA0KICAgDQogICBXaXRoIE5ldyBGaWx0ZXJDb250cm9sDQogICAg +ICBTZXQgLkV2ZW50QnJpZGdlID0gbV9FdmVudEJyaWRnZQ0KICAgICAgU2V0IC5D +b250cm9sID0gQ29udHJvbFJlZg0KICAgICAgLkRhdGFGaWVsZCA9IERhdGFGaWVs +ZE5hbWUNCiAgICAgIC5EYXRhVHlwZSA9IERhdGFUeXBlDQogICAgICAuUmVsYXRp +b25hbE9wZXJhdG9yID0gUmVsYXRpb25hbE9wZXJhdG9yDQogICAgICBJZiBOb3Qg +KENvbnRyb2wyUmVmIElzIE5vdGhpbmcpIFRoZW4NCiAgICAgICAgIFNldCAuQ29u +dHJvbDIgPSBDb250cm9sMlJlZg0KICAgICAgRW5kIElmDQogICAgICAuSWdub3Jl +VmFsdWUgPSBJZ25vcmVWYWx1ZQ0KICAgICAgbV9GaWx0ZXJDb250cm9scy5BZGQg +LlNlbGYNCiAgICAgIFNldCBBZGQgPSAuU2VsZg0KICAgRW5kIFdpdGgNCiAgIA0K +RW5kIEZ1bmN0aW9uDQoNClB1YmxpYyBGdW5jdGlvbiBBZGRHcm91cChPcHRpb25h +bCBCeVZhbCBDb25jYXRPcGVyYXRvciBBcyBTcWxMb2dpY2FsT3BlcmF0b3IgPSBT +cWxMb2dpY2FsT3BlcmF0b3IuU1FMX09yKSBBcyBGaWx0ZXJDb250cm9sQ29sbGVj +dGlvbg0KICAgDQogICBXaXRoIE5ldyBGaWx0ZXJDb250cm9sQ29sbGVjdGlvbg0K +ICAgICAgLkl0ZW1Db25jYXRPcGVyYXRvciA9IENvbmNhdE9wZXJhdG9yDQogICAg +ICBTZXQgLkV2ZW50QnJpZGdlID0gbV9FdmVudEJyaWRnZQ0KICAgICAgbV9GaWx0 +ZXJDb250cm9scy5BZGQgLlNlbGYNCiAgICAgIFNldCBBZGRHcm91cCA9IC5TZWxm +DQogICBFbmQgV2l0aA0KDQpFbmQgRnVuY3Rpb24NCg0KUHVibGljIFByb3BlcnR5 +IEdldCBJdGVtQ29uY2F0T3BlcmF0b3IoKSBBcyBTcWxMb2dpY2FsT3BlcmF0b3IN +CiAgIEl0ZW1Db25jYXRPcGVyYXRvciA9IG1fSXRlbUNvbmNhdE9wZXJhdG9yDQpF +bmQgUHJvcGVydHkNCg0KUHVibGljIFByb3BlcnR5IExldCBJdGVtQ29uY2F0T3Bl +cmF0b3IoQnlWYWwgTmV3VmFsdWUgQXMgU3FsTG9naWNhbE9wZXJhdG9yKQ0KICAg +bV9JdGVtQ29uY2F0T3BlcmF0b3IgPSBOZXdWYWx1ZQ0KRW5kIFByb3BlcnR5DQoN +ClB1YmxpYyBTdWIgQWRkTXVsdGlDb250cm9sQ3JpdGVyaWEoIF8NCiAgICAgICAg +ICAgICAgIEJ5VmFsIERhdGFGaWVsZE5hbWUgQXMgU3RyaW5nLCBCeVZhbCBEYXRh +VHlwZSBBcyBTcWxGaWVsZERhdGFUeXBlLCBfDQogICAgICAgICAgICAgICBCeVZh +bCBSZWxhdGlvbmFsT3BlcmF0b3IgQXMgU3FsUmVsYXRpb25hbE9wZXJhdG9ycywg +Xw0KICAgICAgICAgICAgICAgQnlWYWwgSWdub3JlVmFsdWUgQXMgVmFyaWFudCwg +Xw0KICAgICAgICAgICAgICAgUGFyYW1BcnJheSBDb250cm9scygpIEFzIFZhcmlh +bnQpDQogICANCiAgIFdpdGggTmV3IEZpbHRlckNvbnRyb2wNCiAgICAgIFNldCAu +RXZlbnRCcmlkZ2UgPSBtX0V2ZW50QnJpZGdlDQogICAgICAuRGF0YUZpZWxkID0g +RGF0YUZpZWxkTmFtZQ0KICAgICAgLkRhdGFUeXBlID0gRGF0YVR5cGUNCiAgICAg +IC5SZWxhdGlvbmFsT3BlcmF0b3IgPSBSZWxhdGlvbmFsT3BlcmF0b3INCiAgICAg +IC5JZ25vcmVWYWx1ZSA9IElnbm9yZVZhbHVlDQogICAgICAuU2V0U3ViQ29udHJv +bHMgQ29udHJvbHMNCiAgICAgIG1fRmlsdGVyQ29udHJvbHMuQWRkIC5TZWxmDQog +ICBFbmQgV2l0aA0KICAgDQpFbmQgU3ViDQoNClB1YmxpYyBQcm9wZXJ0eSBHZXQg +SXRlbXMoKSBBcyBDb2xsZWN0aW9uDQogICBTZXQgSXRlbXMgPSBtX0ZpbHRlckNv +bnRyb2xzDQpFbmQgUHJvcGVydHkNCg0KUHVibGljIFN1YiBSZW1vdmVGaWx0ZXJW +YWx1ZXMoT3B0aW9uYWwgQnlWYWwgUmFpc2VGaWx0ZXJWYWx1ZXNDaGFuZ2VkRXZl +bnQgQXMgQm9vbGVhbiA9IFRydWUpDQogICANCiAgIERpbSBmYyBBcyBPYmplY3Qg +JyBGaWx0ZXJDb250cm9sIG9kZXIgRmlsdGVyQ29udHJvbENvbGxlY3Rpb24NCiAg +IEZvciBFYWNoIGZjIEluIEl0ZW1zDQogICAgICBJZiBUeXBlT2YgZmMgSXMgRmls +dGVyQ29udHJvbENvbGxlY3Rpb24gVGhlbg0KICAgICAgICAgZmMuUmVtb3ZlRmls +dGVyVmFsdWVzIEZhbHNlDQogICAgICBFbHNlDQogICAgICAgICBmYy5SZW1vdmVG +aWx0ZXJWYWx1ZSBGYWxzZQ0KICAgICAgRW5kIElmDQogICBOZXh0DQogICANCiAg +IElmIFJhaXNlRmlsdGVyVmFsdWVzQ2hhbmdlZEV2ZW50IFRoZW4NCiAgICAgIFJh +aXNlRXZlbnQgRmlsdGVyVmFsdWVzQ2hhbmdlZA0KICAgRW5kIElmDQogICANCkVu +ZCBTdWINCg0KUHVibGljIFN1YiBSZW1vdmVDb250cm9scyhPcHRpb25hbCBCeVZh +bCBSYWlzZUZpbHRlclZhbHVlc0NoYW5nZWRFdmVudCBBcyBCb29sZWFuID0gVHJ1 +ZSkNCiAgIA0KICAgU2V0IG1fRmlsdGVyQ29udHJvbHMgPSBOb3RoaW5nDQogICBT +ZXQgbV9GaWx0ZXJDb250cm9scyA9IE5ldyBDb2xsZWN0aW9uDQogICANCiAgIElm +IFJhaXNlRmlsdGVyVmFsdWVzQ2hhbmdlZEV2ZW50IFRoZW4NCiAgICAgIFJhaXNl +RXZlbnQgRmlsdGVyVmFsdWVzQ2hhbmdlZA0KICAgRW5kIElmDQogICANCkVuZCBT +dWINCg0KUHJpdmF0ZSBTdWIgbV9FdmVudEJyaWRnZV9GaWx0ZXJWYWx1ZVJlcXVl +c3QoQnlWYWwgRmlsdGVyVmFsdWVDb2RlIEFzIFN0cmluZywgQnlSZWYgRmlsdGVy +VmFsdWUgQXMgU3RyaW5nKQ0KICAgUmFpc2VFdmVudCBGaWx0ZXJWYWx1ZVJlcXVl +c3QoRmlsdGVyVmFsdWVDb2RlLCBGaWx0ZXJWYWx1ZSkNCkVuZCBTdWINCg0KUHJp +dmF0ZSBTdWIgbV9FdmVudEJyaWRnZV9GaWx0ZXJWYWx1ZXNDaGFuZ2VkKEJ5VmFs +IEZpbHRlckNvbnRyb2xSZWYgQXMgRmlsdGVyQ29udHJvbCkNCiAgIFJhaXNlRXZl +bnQgRmlsdGVyVmFsdWVzQ2hhbmdlZA0KRW5kIFN1Yg0KDQpQdWJsaWMgU3ViIENs +ZWFyKCkNCg0KICAgU2V0IG1fRXZlbnRCcmlkZ2UgPSBOb3RoaW5nDQogICBTZXQg +bV9GaWx0ZXJDb250cm9scyA9IE5vdGhpbmcNCiAgIFNldCBtX0ZpbHRlckNvbnRy +b2xzID0gTmV3IENvbGxlY3Rpb24NCiAgIFNldCBtX0V2ZW50QnJpZGdlID0gTmV3 +IEZpbHRlckNvbnRyb2xFdmVudEJyaWRnZQ0KICAgDQpFbmQgU3ViDQoNClB1Ymxp +YyBGdW5jdGlvbiBDcml0ZXJpYVN0cmluZyhCeVZhbCBTcWxUb29sc1JlZiBBcyBT +cWxUb29scykgQXMgU3RyaW5nDQogICANCiAgIERpbSBmYyBBcyBPYmplY3QgJyBz +Y2j2bmVyIHfkcmUgQXMgRmlsdGVyQ29udHJvbCBrb21pbmllcnQgbWl0IEZpbHRl +ckNvbnRyb2xDb2xsZWN0aW9uIGltcGxlbWVudHMgRmlsdGVyQ29udHJvbA0KICAg +ICAgICAgICAgICAgICAgICAnIC4uIGFiZXIgSW1wbGVtZW50cyBpc3QgYXVzIEVy +ZmFocnVuZyBtaXQgVm9yc2ljaHQgenUgZ2VuaWXfZW4sIHdlbm4gQ29kZS9JbnRl +cmZhY2UgaW4gQWNjZXNzL1ZCQSBnZeRuZGVydCB3aXJkLg0KDQogICBXaXRoIE5l +dyBGaWx0ZXJTdHJpbmdCdWlsZGVyDQogICAgICAuQ29uZmlnU3FsU3RhdGVtZW50 +IEluc2VydEV2ZW50VmFsdWVzKG1fU3FsUHJlZml4KSwgSW5zZXJ0RXZlbnRWYWx1 +ZXMobV9TcWxTdWZmaXgpLCBtX0NvbmRpdGlvblByZWZpeCwgbV9JZ25vcmVTcWxQ +cmVTdWZmaXhJZkVtcHR5RmlsdGVyDQogICAgICBGb3IgRWFjaCBmYyBJbiBtX0Zp +bHRlckNvbnRyb2xzDQogICAgICAgICAuQWRkQ3JpdGVyaWEgZmMuQ3JpdGVyaWFT +dHJpbmcoU3FsVG9vbHNSZWYpDQogICAgICBOZXh0DQogICAgICBDcml0ZXJpYVN0 +cmluZyA9IC5Ub1N0cmluZyhtX0l0ZW1Db25jYXRPcGVyYXRvcikNCiAgIEVuZCBX +aXRoDQoNCkVuZCBGdW5jdGlvbg0KDQpQcml2YXRlIEZ1bmN0aW9uIEluc2VydEV2 +ZW50VmFsdWVzKEJ5VmFsIFN0cmluZ1RvQ2hlY2sgQXMgU3RyaW5nKSBBcyBTdHJp +bmcNCg0KICAgRGltIENoZWNrU3RyaW5nQXJyYXkoKSBBcyBTdHJpbmcNCiAgIA0K +ICAgSWYgTGVuKFN0cmluZ1RvQ2hlY2spID0gMCBUaGVuDQogICAgICBFeGl0IEZ1 +bmN0aW9uDQogICBFbmQgSWYNCiAgIA0KICAgQ2hlY2tTdHJpbmdBcnJheSA9IFNw +bGl0KFN0cmluZ1RvQ2hlY2ssICJbRXZlbnRWYWx1ZSgiLCAsIHZiVGV4dENvbXBh +cmUpDQogICANCiAgIERpbSBpIEFzIExvbmcNCiAgIERpbSBBcnJheVNpemUgQXMg +TG9uZw0KICAgDQogICBBcnJheVNpemUgPSBVQm91bmQoQ2hlY2tTdHJpbmdBcnJh +eSkNCiAgIA0KICAgSWYgQXJyYXlTaXplID0gMCBUaGVuDQogICAgICBJbnNlcnRF +dmVudFZhbHVlcyA9IFN0cmluZ1RvQ2hlY2sNCiAgICAgIEV4aXQgRnVuY3Rpb24N +CiAgIEVuZCBJZg0KICAgDQogICBEaW0gRmlsdGVyVmFsdWVDb2RlIEFzIFN0cmlu +Zw0KICAgRGltIEZpbHRlclZhbHVlIEFzIFN0cmluZw0KICAgRGltIFBvcyBBcyBT +dHJpbmcNCiAgIERpbSBUZW1wU3RyaW5nIEFzIFN0cmluZw0KICAgDQogICBGb3Ig +aSA9IDEgVG8gQXJyYXlTaXplDQogICANCiAgICAgIFBvcyA9IEluU3RyKDEsIENo +ZWNrU3RyaW5nQXJyYXkoaSksICIpIikNCiAgICAgIEZpbHRlclZhbHVlQ29kZSA9 +IExlZnQoQ2hlY2tTdHJpbmdBcnJheShpKSwgUG9zIC0gMSkNCiAgICAgIA0KICAg +ICAgUG9zID0gSW5TdHIoUG9zLCBDaGVja1N0cmluZ0FycmF5KGkpLCAiXSIpDQog +ICAgICANCiAgICAgIFRlbXBTdHJpbmcgPSBNaWQoQ2hlY2tTdHJpbmdBcnJheShp +KSwgUG9zICsgMSkNCiAgICAgIA0KICAgICAgRmlsdGVyVmFsdWUgPSAiTnVsbCIN +CiAgICAgIFJhaXNlRXZlbnQgRmlsdGVyVmFsdWVSZXF1ZXN0KEZpbHRlclZhbHVl +Q29kZSwgRmlsdGVyVmFsdWUpDQogICAgICBJZiBGaWx0ZXJWYWx1ZSA9ICJOdWxs +IiBUaGVuDQogICAgICAgICBtX0V2ZW50QnJpZGdlLlJhaXNlRmlsdGVyVmFsdWVS +ZXF1ZXN0IEZpbHRlclZhbHVlQ29kZSwgRmlsdGVyVmFsdWUNCiAgICAgIEVuZCBJ +Zg0KICAgICAgDQogICAgICBDaGVja1N0cmluZ0FycmF5KGkpID0gRmlsdGVyVmFs +dWUgJiBUZW1wU3RyaW5nDQogICAgICANCiAgIE5leHQNCiAgIA0KICAgSW5zZXJ0 +RXZlbnRWYWx1ZXMgPSBKb2luKENoZWNrU3RyaW5nQXJyYXksIHZiTnVsbFN0cmlu +ZykNCg0KRW5kIEZ1bmN0aW9uDQoNClB1YmxpYyBGdW5jdGlvbiBBZGRTdWJTZWxl +Y3RDcml0ZXJpYSggXw0KICAgICAgICAgICAgICAgQnlWYWwgRmllbGROYW1lIEFz +IFN0cmluZywgXw0KICAgICAgICAgICAgICAgQnlWYWwgUmVsYXRpb25hbE9wZXJh +dG9yIEFzIFNxbFJlbGF0aW9uYWxPcGVyYXRvcnMsIF8NCiAgICAgICAgICAgICAg +IEJ5VmFsIFNlbGVjdEZyb21UZXh0IEFzIFN0cmluZywgXw0KICAgICAgICAgICAg +ICAgT3B0aW9uYWwgQnlWYWwgSWdub3JlSWZTdWJTZWxlY3RIYXNOb0NyaXRlcmlh +IEFzIEJvb2xlYW4gPSBGYWxzZSwgXw0KICAgICAgICAgICAgICAgT3B0aW9uYWwg +QnlWYWwgVXNlV2hlcmVSZXBsYWNlbWVudFRleHRJbkZyb21UZXh0IEFzIEJvb2xl +YW4gPSBGYWxzZSwgXw0KICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgU3Vi +U2VsZWN0Q29uY2F0T3BlcmF0b3IgQXMgU3FsTG9naWNhbE9wZXJhdG9yID0gU3Fs +TG9naWNhbE9wZXJhdG9yLlNRTF9BbmQgXw0KICAgICAgKSBBcyBGaWx0ZXJDb250 +cm9sQ29sbGVjdGlvbg0KICAgICAgDQogICBEaW0gU3FsUHJlZml4IEFzIFN0cmlu +Zw0KICAgRGltIFNxbFN1ZmZpeCBBcyBTdHJpbmcNCiAgIERpbSBXaGVyZVJlcGxh +Y2VtZW50UG9zIEFzIExvbmcNCiAgIERpbSBDb25kaXRpb25QcmVmaXggQXMgU3Ry +aW5nDQogICANCiAgIFNxbFByZWZpeCA9IEZpZWxkTmFtZSAmICIgIiAmIFNxbFRv +b2xzLkdldFJlbGF0aW9uYWxPcGVyYXRvclN0cmluZyhSZWxhdGlvbmFsT3BlcmF0 +b3IpICYgIiAoIg0KICAgU3FsU3VmZml4ID0gIikiDQogICBDb25kaXRpb25QcmVm +aXggPSAiIFdoZXJlICINCiAgIA0KICAgSWYgVXNlV2hlcmVSZXBsYWNlbWVudFRl +eHRJbkZyb21UZXh0IFRoZW4NCiAgICAgIFdoZXJlUmVwbGFjZW1lbnRQb3MgPSBJ +blN0cigxLCBTZWxlY3RGcm9tVGV4dCwgbV9XaGVyZVJlcGxhY2VtZW50VGV4dCwg +dmJUZXh0Q29tcGFyZSkNCiAgIEVuZCBJZg0KICAgDQogICBJZiBXaGVyZVJlcGxh +Y2VtZW50UG9zID4gMCBUaGVuDQogICAgICBTcWxQcmVmaXggPSBTcWxQcmVmaXgg +JiBUcmltJChMZWZ0KFNlbGVjdEZyb21UZXh0LCBXaGVyZVJlcGxhY2VtZW50UG9z +IC0gMSkpDQogICAgICBTcWxTdWZmaXggPSAiKSAiICYgVHJpbSQoTWlkJChTZWxl +Y3RGcm9tVGV4dCwgV2hlcmVSZXBsYWNlbWVudFBvcyArIExlbihtX1doZXJlUmVw +bGFjZW1lbnRUZXh0KSArIDEpKSAmIFNxbFN1ZmZpeA0KICAgICAgQ29uZGl0aW9u +UHJlZml4ID0gQ29uZGl0aW9uUHJlZml4ICYgIigiDQogICBFbHNlDQogICAgICBT +cWxQcmVmaXggPSBTcWxQcmVmaXggJiBTZWxlY3RGcm9tVGV4dA0KICAgRW5kIElm +DQogICANCiAgIFdpdGggTmV3IEZpbHRlckNvbnRyb2xDb2xsZWN0aW9uDQogICAg +ICAuSXRlbUNvbmNhdE9wZXJhdG9yID0gU3ViU2VsZWN0Q29uY2F0T3BlcmF0b3IN +CiAgICAgIC5Db25maWdTcWxTdGF0ZW1lbnQgU3FsUHJlZml4Oj1TcWxQcmVmaXgs +IFNxbFN1ZmZpeDo9U3FsU3VmZml4LCBfDQogICAgICAgICAgICAgICAgICAgICAg +ICAgIENvbmRpdGlvblByZWZpeDo9Q29uZGl0aW9uUHJlZml4LCBJZ25vcmVTcWxQ +cmVTdWZmaXhJZkVtcHR5RmlsdGVyOj1JZ25vcmVJZlN1YlNlbGVjdEhhc05vQ3Jp +dGVyaWENCiAgICAgIA0KICAgICAgU2V0IC5FdmVudEJyaWRnZSA9IG1fRXZlbnRC +cmlkZ2UNCiAgICAgIG1fRmlsdGVyQ29udHJvbHMuQWRkIC5TZWxmDQogICAgICBT +ZXQgQWRkU3ViU2VsZWN0Q3JpdGVyaWEgPSAuU2VsZg0KICAgRW5kIFdpdGgNCiAg +IA0KRW5kIEZ1bmN0aW9uDQoNClB1YmxpYyBQcm9wZXJ0eSBHZXQgV2hlcmVSZXBs +YWNlbWVudFRleHQoKSBBcyBTdHJpbmcNCiAgIFdoZXJlUmVwbGFjZW1lbnRUZXh0 +ID0gbV9XaGVyZVJlcGxhY2VtZW50VGV4dA0KRW5kIFByb3BlcnR5DQoNClB1Ymxp +YyBGdW5jdGlvbiBBZGRFeGlzdHNDcml0ZXJpYSggXw0KICAgICAgICAgICAgICAg +ICAgICAgICAgQnlWYWwgU2VsZWN0RnJvbVRleHQgQXMgU3RyaW5nLCBfDQogICAg +ICAgICAgICAgICBPcHRpb25hbCBCeVZhbCBJZ25vcmVJZkV4aXN0c1N0YXRlbWVu +dEhhc05vQ3JpdGVyaWEgQXMgQm9vbGVhbiA9IEZhbHNlLCBfDQogICAgICAgICAg +ICAgICBPcHRpb25hbCBCeVZhbCBTdWJTZWxlY3RDb25jYXRPcGVyYXRvciBBcyBT +cWxMb2dpY2FsT3BlcmF0b3IgPSBTcWxMb2dpY2FsT3BlcmF0b3IuU1FMX0FuZCwg +Xw0KICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgVXNlTm90RXhpc3RzIEFz +IEJvb2xlYW4gPSBGYWxzZSwgXw0KICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlW +YWwgVXNlV2hlcmVSZXBsYWNlbWVudFRleHRJbkZyb21UZXh0IEFzIEJvb2xlYW4g +PSBGYWxzZSBfDQogICAgICApIEFzIEZpbHRlckNvbnRyb2xDb2xsZWN0aW9uDQoN +CiAgIERpbSBTcWxQcmVmaXggQXMgU3RyaW5nDQogICBEaW0gU3FsU3VmZml4IEFz +IFN0cmluZw0KICAgRGltIFdoZXJlUmVwbGFjZW1lbnRQb3MgQXMgTG9uZw0KICAg +RGltIENvbmRpdGlvblByZWZpeCBBcyBTdHJpbmcNCiAgIENvbmRpdGlvblByZWZp +eCA9ICIgV2hlcmUgIg0KICAgDQogICBTcWxQcmVmaXggPSAiRXhpc3RzICgiDQog +ICBTcWxTdWZmaXggPSAiKSINCiAgIElmIFVzZU5vdEV4aXN0cyBUaGVuIFNxbFBy +ZWZpeCA9ICJOb3QgIiAmIFNxbFByZWZpeA0KICAgDQogICBJZiBVc2VXaGVyZVJl +cGxhY2VtZW50VGV4dEluRnJvbVRleHQgVGhlbg0KICAgICAgV2hlcmVSZXBsYWNl +bWVudFBvcyA9IEluU3RyKDEsIFNlbGVjdEZyb21UZXh0LCBtX1doZXJlUmVwbGFj +ZW1lbnRUZXh0LCB2YlRleHRDb21wYXJlKQ0KICAgRW5kIElmDQogICANCiAgIElm +IFdoZXJlUmVwbGFjZW1lbnRQb3MgPiAwIFRoZW4NCiAgICAgIFNxbFByZWZpeCA9 +IFNxbFByZWZpeCAmIFRyaW0kKExlZnQoU2VsZWN0RnJvbVRleHQsIFdoZXJlUmVw +bGFjZW1lbnRQb3MgLSAxKSkNCiAgICAgIFNxbFN1ZmZpeCA9ICIpICIgJiBUcmlt +JChNaWQkKFNlbGVjdEZyb21UZXh0LCBXaGVyZVJlcGxhY2VtZW50UG9zICsgTGVu +KG1fV2hlcmVSZXBsYWNlbWVudFRleHQpICsgMSkpICYgU3FsU3VmZml4DQogICAg +ICBDb25kaXRpb25QcmVmaXggPSBDb25kaXRpb25QcmVmaXggJiAiKCINCiAgIEVs +c2UNCiAgICAgIFNxbFByZWZpeCA9IFNxbFByZWZpeCAmIFNlbGVjdEZyb21UZXh0 +DQogICBFbmQgSWYNCg0KICAgV2l0aCBOZXcgRmlsdGVyQ29udHJvbENvbGxlY3Rp +b24NCiAgICAgIC5JdGVtQ29uY2F0T3BlcmF0b3IgPSBTdWJTZWxlY3RDb25jYXRP +cGVyYXRvcg0KICAgICAgLkNvbmZpZ1NxbFN0YXRlbWVudCBTcWxQcmVmaXg6PVNx +bFByZWZpeCwgXw0KICAgICAgICAgICAgICAgICAgICAgICAgICBTcWxTdWZmaXg6 +PVNxbFN1ZmZpeCwgQ29uZGl0aW9uUHJlZml4Oj1Db25kaXRpb25QcmVmaXgsIEln +bm9yZVNxbFByZVN1ZmZpeElmRW1wdHlGaWx0ZXI6PUlnbm9yZUlmRXhpc3RzU3Rh +dGVtZW50SGFzTm9Dcml0ZXJpYQ0KICAgICAgDQogICAgICBTZXQgLkV2ZW50QnJp +ZGdlID0gbV9FdmVudEJyaWRnZQ0KICAgICAgbV9GaWx0ZXJDb250cm9scy5BZGQg +LlNlbGYNCiAgICAgIFNldCBBZGRFeGlzdHNDcml0ZXJpYSA9IC5TZWxmDQogICBF +bmQgV2l0aA0KDQpFbmQgRnVuY3Rpb24NCg0KRnJpZW5kIFN1YiBDb25maWdTcWxT +dGF0ZW1lbnQoQnlWYWwgU3FsUHJlZml4IEFzIFN0cmluZywgQnlWYWwgU3FsU3Vm +Zml4IEFzIFN0cmluZywgXw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +QnlWYWwgQ29uZGl0aW9uUHJlZml4IEFzIFN0cmluZywgXw0KICAgICAgICAgICAg +ICAgICAgICAgT3B0aW9uYWwgQnlWYWwgSWdub3JlU3FsUHJlU3VmZml4SWZFbXB0 +eUZpbHRlciBBcyBCb29sZWFuID0gRmFsc2UpDQogICANCiAgIG1fU3FsUHJlZml4 +ID0gU3FsUHJlZml4DQogICBtX1NxbFN1ZmZpeCA9IFNxbFN1ZmZpeA0KICAgbV9D +b25kaXRpb25QcmVmaXggPSBDb25kaXRpb25QcmVmaXgNCiAgIG1fSWdub3JlU3Fs +UHJlU3VmZml4SWZFbXB0eUZpbHRlciA9IElnbm9yZVNxbFByZVN1ZmZpeElmRW1w +dHlGaWx0ZXINCg0KRW5kIFN1Yg0K + + 20250609094839 + form/filter/FilterControlCollection.cls + + + FilterControlEventBridge + VkVSU0lPTiAxLjAgQ0xBU1MNCkJFR0lODQogIE11bHRpVXNlID0gLTEgICdUcnVl +DQpFTkQNCkF0dHJpYnV0ZSBWQl9OYW1lID0gIkZpbHRlckNvbnRyb2xFdmVudEJy +aWRnZSINCkF0dHJpYnV0ZSBWQl9HbG9iYWxOYW1lU3BhY2UgPSBGYWxzZQ0KQXR0 +cmlidXRlIFZCX0NyZWF0YWJsZSA9IEZhbHNlDQpBdHRyaWJ1dGUgVkJfUHJlZGVj +bGFyZWRJZCA9IEZhbHNlDQpBdHRyaWJ1dGUgVkJfRXhwb3NlZCA9IEZhbHNlDQon +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonIEtsYXNz +ZTogRmlsdGVyQ29udHJvbEV2ZW50QnJpZGdlDQonLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonLyoqDQonIFxhdXRob3IgICAgICAgSm9z +ZWYgUG9ldHpsDQonIDxzdW1tYXJ5Pg0KJyBIaWxmc2tsYXNzZSB6dXIgV2VpdGVy +Z2FiZSB2b24gRXJlaWduaXNzZW4NCicgPC9zdW1tYXJ5Pg0KJyA8cmVtYXJrcz5X +aXJkIGb8ciBGaWx0ZXJDb250cm9sQ29sbGVjdGlvbiBiZW72dGlndDwvcmVtYXJr +cz4NCicgXGluZ3JvdXAgZGF0YQ0KJyoqLw0KJy0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLQ0KJzxjb2RlbGliPg0KJyAgPGZpbGU+Zm9ybS9m +aWx0ZXIvRmlsdGVyQ29udHJvbEV2ZW50QnJpZGdlLmNsczwvZmlsZT4NCicgIDxs +aWNlbnNlPl9jb2RlbGliL2xpY2Vuc2UuYmFzPC9saWNlbnNlPg0KJyAgPHVzZT5m +b3JtL2ZpbHRlci9GaWx0ZXJDb250cm9sLmNsczwvdXNlPg0KJzwvY29kZWxpYj4N +CictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCk9w +dGlvbiBDb21wYXJlIERhdGFiYXNlDQpPcHRpb24gRXhwbGljaXQNCg0KUHVibGlj +IEV2ZW50IEZpbHRlclZhbHVlc0NoYW5nZWQoQnlWYWwgRmlsdGVyQ29udHJvbFJl +ZiBBcyBGaWx0ZXJDb250cm9sKQ0KUHVibGljIEV2ZW50IEZpbHRlclZhbHVlUmVx +dWVzdChCeVZhbCBGaWx0ZXJWYWx1ZUNvZGUgQXMgU3RyaW5nLCBCeVJlZiBGaWx0 +ZXJWYWx1ZSBBcyBTdHJpbmcpDQoNCkZyaWVuZCBTdWIgUmFpc2VGaWx0ZXJWYWx1 +ZUNoYW5nZWQoQnlWYWwgRmlsdGVyQ29udHJvbFJlZiBBcyBGaWx0ZXJDb250cm9s +KQ0KICAgUmFpc2VFdmVudCBGaWx0ZXJWYWx1ZXNDaGFuZ2VkKEZpbHRlckNvbnRy +b2xSZWYpDQpFbmQgU3ViDQoNCkZyaWVuZCBTdWIgUmFpc2VGaWx0ZXJWYWx1ZVJl +cXVlc3QoQnlWYWwgRmlsdGVyVmFsdWVDb2RlIEFzIFN0cmluZywgQnlSZWYgRmls +dGVyVmFsdWUgQXMgU3RyaW5nKQ0KICAgUmFpc2VFdmVudCBGaWx0ZXJWYWx1ZVJl +cXVlc3QoRmlsdGVyVmFsdWVDb2RlLCBGaWx0ZXJWYWx1ZSkNCkVuZCBTdWINCg== + + 20250609094839 + form/filter/FilterControlEventBridge.cls + + + FilterControlManager + VkVSU0lPTiAxLjAgQ0xBU1MNCkJFR0lODQogIE11bHRpVXNlID0gLTEgICdUcnVl +DQpFTkQNCkF0dHJpYnV0ZSBWQl9OYW1lID0gIkZpbHRlckNvbnRyb2xNYW5hZ2Vy +Ig0KQXR0cmlidXRlIFZCX0dsb2JhbE5hbWVTcGFjZSA9IEZhbHNlDQpBdHRyaWJ1 +dGUgVkJfQ3JlYXRhYmxlID0gRmFsc2UNCkF0dHJpYnV0ZSBWQl9QcmVkZWNsYXJl +ZElkID0gRmFsc2UNCkF0dHJpYnV0ZSBWQl9FeHBvc2VkID0gRmFsc2UNCictLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgS2xhc3NlOiBG +aWx0ZXJDb250cm9sTWFuYWdlcg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLQ0KJy8qKg0KJyBcYXV0aG9yICAgICAgIEpvc2VmIFBvZXR6 +bA0KJyA8c3VtbWFyeT4NCicgRmlsdGVyc3RyaW5nIG1pdCBGb3JtdWxhci1TdGV1 +ZXJlbGVtZW50ZW4gZXJzdGVsbGVuDQonIDwvc3VtbWFyeT4NCicgPHJlbWFya3M+ +PC9yZW1hcmtzPg0KJyBcaW5ncm91cCBkYXRhDQonKiovDQonLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonPGNvZGVsaWI+DQonICA8Zmls +ZT5mb3JtL2ZpbHRlci9GaWx0ZXJDb250cm9sTWFuYWdlci5jbHM8L2ZpbGU+DQon +ICA8bGljZW5zZT5fY29kZWxpYi9saWNlbnNlLmJhczwvbGljZW5zZT4NCicgIDx1 +c2U+Zm9ybS9maWx0ZXIvRmlsdGVyQ29udHJvbENvbGxlY3Rpb24uY2xzPC91c2U+ +DQonICA8dXNlPmRhdGEvRmlsdGVyU3RyaW5nQnVpbGRlci5jbHM8L3VzZT4NCic8 +L2NvZGVsaWI+DQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tDQonDQpPcHRpb24gQ29tcGFyZSBEYXRhYmFzZQ0KT3B0aW9uIEV4cGxpY2l0 +DQoNClByaXZhdGUgbV9TcWxUb29sIEFzIFNxbFRvb2xzDQpQcml2YXRlIFdpdGhF +dmVudHMgbV9GaWx0ZXJDb250cm9scyBBcyBGaWx0ZXJDb250cm9sQ29sbGVjdGlv +bg0KQXR0cmlidXRlIG1fRmlsdGVyQ29udHJvbHMuVkJfVmFySGVscElEID0gLTEN +ClByaXZhdGUgbV9BdXRvRmlsdGVyTW9kZU9uIEFzIEJvb2xlYW4NCg0KUHVibGlj +IEV2ZW50IEZpbHRlclN0cmluZ0NoYW5nZWQoQnlWYWwgTmV3RmlsdGVyU3RyaW5n +IEFzIFN0cmluZykNClB1YmxpYyBFdmVudCBGaWx0ZXJWYWx1ZXNDaGFuZ2VkKCkN +ClB1YmxpYyBFdmVudCBGaWx0ZXJWYWx1ZVJlcXVlc3QoQnlWYWwgRmlsdGVyVmFs +dWVDb2RlIEFzIFN0cmluZywgQnlSZWYgRmlsdGVyVmFsdWUgQXMgU3RyaW5nKQ0K +DQpQcml2YXRlIFN1YiBDbGFzc19Jbml0aWFsaXplKCkNCiAgIFNldCBtX0ZpbHRl +ckNvbnRyb2xzID0gTmV3IEZpbHRlckNvbnRyb2xDb2xsZWN0aW9uDQpFbmQgU3Vi +DQoNClByaXZhdGUgU3ViIENsYXNzX1Rlcm1pbmF0ZSgpDQogICBTZXQgbV9GaWx0 +ZXJDb250cm9scyA9IE5vdGhpbmcNCkVuZCBTdWINCg0KRnJpZW5kIFByb3BlcnR5 +IEdldCBTcWxUb29sKCkgQXMgU3FsVG9vbHMNCiAgIElmIG1fU3FsVG9vbCBJcyBO +b3RoaW5nIFRoZW4NCiAgICAgIFNldCBtX1NxbFRvb2wgPSBTcWxUb29scy5DbG9u +ZQ0KICAgRW5kIElmDQogICBTZXQgU3FsVG9vbCA9IG1fU3FsVG9vbA0KRW5kIFBy +b3BlcnR5DQoNCkZyaWVuZCBQcm9wZXJ0eSBTZXQgU3FsVG9vbChCeVZhbCBOZXdS +ZWYgQXMgU3FsVG9vbHMpDQogICBTZXQgbV9TcWxUb29sID0gTmV3UmVmDQpFbmQg +UHJvcGVydHkNCg0KRnJpZW5kIFN1YiBDb25maWdTcWxGb3JtYXQoQnlWYWwgU3Fs +RGF0ZUZvcm1hdCBBcyBTdHJpbmcsIF8NCiAgICAgICAgICAgICAgICAgICAgICAg +ICAgIEJ5VmFsIFNxbEJvb2xlYW5UcnVlU3RyaW5nIEFzIFN0cmluZywgXw0KICAg +ICAgICAgICAgICAgICAgICAgICAgICAgQnlWYWwgU3FsV2lsZENhcmRTdHJpbmcg +QXMgU3RyaW5nKQ0KICAgDQogICBJZiBtX1NxbFRvb2wgSXMgTm90aGluZyBUaGVu +DQogICAgICBTZXQgbV9TcWxUb29sID0gU3FsVG9vbHMuTmV3SW5zdGFuY2UoU3Fs +RGF0ZUZvcm1hdCwgU3FsQm9vbGVhblRydWVTdHJpbmcsIFNxbFdpbGRDYXJkU3Ry +aW5nKQ0KICAgICAgRXhpdCBTdWINCiAgIEVuZCBJZg0KDQogICBXaXRoIFNxbFRv +b2wNCiAgICAgIC5TcWxEYXRlRm9ybWF0ID0gU3FsRGF0ZUZvcm1hdA0KICAgICAg +LlNxbEJvb2xlYW5UcnVlU3RyaW5nID0gU3FsQm9vbGVhblRydWVTdHJpbmcNCiAg +ICAgIC5TcWxXaWxkQ2FyZFN0cmluZyA9IFNxbFdpbGRDYXJkU3RyaW5nDQogICBF +bmQgV2l0aA0KDQpFbmQgU3ViDQoNClB1YmxpYyBQcm9wZXJ0eSBHZXQgRmlsdGVy +Q29udHJvbHMoKSBBcyBGaWx0ZXJDb250cm9sQ29sbGVjdGlvbg0KICAgU2V0IEZp +bHRlckNvbnRyb2xzID0gbV9GaWx0ZXJDb250cm9scw0KRW5kIFByb3BlcnR5DQoN +ClB1YmxpYyBGdW5jdGlvbiBDcmVhdGVGaWx0ZXJTdHJpbmcoKSBBcyBTdHJpbmcN +CiAgIA0KICAgQ3JlYXRlRmlsdGVyU3RyaW5nID0gRmlsdGVyQ29udHJvbHMuQ3Jp +dGVyaWFTdHJpbmcoU3FsVG9vbCkNCg0KRW5kIEZ1bmN0aW9uDQoNClByaXZhdGUg +U3ViIG1fRmlsdGVyQ29udHJvbHNfRmlsdGVyVmFsdWVSZXF1ZXN0KEJ5VmFsIEZp +bHRlclZhbHVlQ29kZSBBcyBTdHJpbmcsIEJ5UmVmIEZpbHRlclZhbHVlIEFzIFN0 +cmluZykNCiAgIFJhaXNlRXZlbnQgRmlsdGVyVmFsdWVSZXF1ZXN0KEZpbHRlclZh +bHVlQ29kZSwgRmlsdGVyVmFsdWUpDQpFbmQgU3ViDQoNClByaXZhdGUgU3ViIG1f +RmlsdGVyQ29udHJvbHNfRmlsdGVyVmFsdWVzQ2hhbmdlZCgpDQogICBSYWlzZUV2 +ZW50IEZpbHRlclZhbHVlc0NoYW5nZWQNCiAgIFVzZUF1dG9GaWx0ZXJNb2RlDQpF +bmQgU3ViDQoNClB1YmxpYyBQcm9wZXJ0eSBHZXQgQXV0b0ZpbHRlck9uKCkgQXMg +Qm9vbGVhbg0KICAgQXV0b0ZpbHRlck9uID0gbV9BdXRvRmlsdGVyTW9kZU9uDQpF +bmQgUHJvcGVydHkNCg0KUHVibGljIFByb3BlcnR5IExldCBBdXRvRmlsdGVyT24o +QnlWYWwgTmV3VmFsdWUgQXMgQm9vbGVhbikNCiAgIG1fQXV0b0ZpbHRlck1vZGVP +biA9IE5ld1ZhbHVlDQogICBVc2VBdXRvRmlsdGVyTW9kZQ0KRW5kIFByb3BlcnR5 +DQoNClB1YmxpYyBTdWIgVXNlQXV0b0ZpbHRlck1vZGUoKQ0KICAgSWYgbV9BdXRv +RmlsdGVyTW9kZU9uIFRoZW4NCiAgICAgIEFwcGx5RmlsdGVyDQogICBFbmQgSWYN +CkVuZCBTdWINCg0KUHVibGljIFN1YiBVc2VGaWx0ZXIoKQ0KJyBERVBSRUNBVEVE +IC0tPiBOZXc6IEFwcGx5RmlsdGVyDQogICBTdG9wDQogICBBcHBseUZpbHRlcg0K +RW5kIFN1Yg0KDQpQdWJsaWMgU3ViIEFwcGx5RmlsdGVyKCkNCiAgIA0KICAgRGlt +IE5ld0ZpbHRlclN0cmluZyBBcyBTdHJpbmcNCiAgIE5ld0ZpbHRlclN0cmluZyA9 +IENyZWF0ZUZpbHRlclN0cmluZw0KICAgDQogICBSYWlzZUV2ZW50IEZpbHRlclN0 +cmluZ0NoYW5nZWQoTmV3RmlsdGVyU3RyaW5nKQ0KICAgDQpFbmQgU3ViDQoNClB1 +YmxpYyBTdWIgUmVtb3ZlRmlsdGVyKE9wdGlvbmFsIEJ5VmFsIE5ld0ZpbHRlclN0 +cmluZyBBcyBTdHJpbmcgPSB2Yk51bGxTdHJpbmcpDQogICANCiAgIEZpbHRlckNv +bnRyb2xzLlJlbW92ZUZpbHRlclZhbHVlcyBGYWxzZQ0KICAgUmFpc2VFdmVudCBG +aWx0ZXJTdHJpbmdDaGFuZ2VkKE5ld0ZpbHRlclN0cmluZykNCiAgIA0KRW5kIFN1 +Yg0K + + 20250609094839 + form/filter/FilterControlManager.cls + + + FilterControlTagConverter + VkVSU0lPTiAxLjAgQ0xBU1MNCkJFR0lODQogIE11bHRpVXNlID0gLTEgICdUcnVl +DQpFTkQNCkF0dHJpYnV0ZSBWQl9OYW1lID0gIkZpbHRlckNvbnRyb2xUYWdDb252 +ZXJ0ZXIiDQpBdHRyaWJ1dGUgVkJfR2xvYmFsTmFtZVNwYWNlID0gRmFsc2UNCkF0 +dHJpYnV0ZSBWQl9DcmVhdGFibGUgPSBGYWxzZQ0KQXR0cmlidXRlIFZCX1ByZWRl +Y2xhcmVkSWQgPSBGYWxzZQ0KQXR0cmlidXRlIFZCX0V4cG9zZWQgPSBGYWxzZQ0K +Jy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBLbGFz +c2U6IEZpbHRlckNvbnRyb2xUYWdDb252ZXJ0ZXINCictLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicvKioNCicgXGF1dGhvciAgICAgICBK +b3NlZiBQb2V0emwNCicgPHN1bW1hcnk+DQonIEhpbGZza2xhc3NlIHp1bSBCZWb8 +bGxlbiBkZXIgRmlsdGVyQ29udHJvbHMgKGb8ciBkZW4gRmlsdGVyQ29udHJvbE1h +bmFnZXIpIPxiZXIgQ29udHJvbC1UYWctV2VydGUNCicgPC9zdW1tYXJ5Pg0KJyA8 +cmVtYXJrcz48L3JlbWFya3M+DQonIFxpbmdyb3VwIGRhdGENCicqKi8NCictLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCic8Y29kZWxpYj4N +CicgIDxmaWxlPmZvcm0vZmlsdGVyL0ZpbHRlckNvbnRyb2xUYWdDb252ZXJ0ZXIu +Y2xzPC9maWxlPg0KJyAgPGxpY2Vuc2U+X2NvZGVsaWIvbGljZW5zZS5iYXM8L2xp +Y2Vuc2U+DQonICA8dXNlPmZvcm0vZmlsdGVyL0ZpbHRlckNvbnRyb2xDb2xsZWN0 +aW9uLmNsczwvdXNlPg0KJyAgPHVzZT5kYXRhL1NxbFRvb2xzLmNsczwvdXNlPg0K +JzwvY29kZWxpYj4NCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0NCicNCk9wdGlvbiBDb21wYXJlIERhdGFiYXNlDQpPcHRpb24gRXhwbGlj +aXQNCg0KUHJpdmF0ZSBDb25zdCBEZWZhdWx0RmlsdGVyQ29udHJvbE5hbWVQcmVm +aXggQXMgU3RyaW5nID0gImZjdGwiDQpQcml2YXRlIENvbnN0IERlZmF1bHRGaWx0 +ZXJDb250cm9sVGFnVmFsdWVTZXBhcmF0b3IgQXMgU3RyaW5nID0gInwiDQoNClBy +aXZhdGUgQ29uc3QgREVGX0RlZmF1bHROdW1lcmljUmVsYXRpb25hbE9wZXJhdG9y +IEFzIExvbmcgPSBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzLlNRTF9FcXVhbA0KUHJp +dmF0ZSBDb25zdCBERUZfRGVmYXVsdFRleHRSZWxhdGlvbmFsT3BlcmF0b3IgQXMg +TG9uZyA9IFNxbFJlbGF0aW9uYWxPcGVyYXRvcnMuU1FMX0xpa2UgKyBTcWxSZWxh +dGlvbmFsT3BlcmF0b3JzLlNRTF9BZGRfV2lsZENhcmRTdWZmaXgNClByaXZhdGUg +Q29uc3QgREVGX0RlZmF1bHREYXRlUmVsYXRpb25hbE9wZXJhdG9yIEFzIExvbmcg +PSBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzLlNRTF9FcXVhbA0KUHJpdmF0ZSBDb25z +dCBERUZfRGVmYXVsdEJvb2xlYW5SZWxhdGlvbmFsT3BlcmF0b3IgQXMgTG9uZyA9 +IFNxbFJlbGF0aW9uYWxPcGVyYXRvcnMuU1FMX0VxdWFsDQoNClByaXZhdGUgbV9G +aWx0ZXJDb250cm9sTmFtZVByZWZpeCBBcyBTdHJpbmcNClByaXZhdGUgbV9GaWx0 +ZXJDb250cm9sVGFnVmFsdWVTZXBhcmF0b3IgQXMgU3RyaW5nDQoNClByaXZhdGUg +bV9EZWZhdWx0TnVtZXJpY1JlbGF0aW9uYWxPcGVyYXRvciBBcyBTcWxSZWxhdGlv +bmFsT3BlcmF0b3JzDQpQcml2YXRlIG1fRGVmYXVsdFRleHRSZWxhdGlvbmFsT3Bl +cmF0b3IgQXMgU3FsUmVsYXRpb25hbE9wZXJhdG9ycw0KUHJpdmF0ZSBtX0RlZmF1 +bHREYXRlUmVsYXRpb25hbE9wZXJhdG9yIEFzIFNxbFJlbGF0aW9uYWxPcGVyYXRv +cnMNClByaXZhdGUgbV9EZWZhdWx0Qm9vbGVhblJlbGF0aW9uYWxPcGVyYXRvciBB +cyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzDQoNClByaXZhdGUgbV9EYXRhU291cmNl +UmVjb3Jkc2V0IEFzIE9iamVjdCAnIHdlZ2VuIERBTyB1bmQgQURPREINCg0KUHJp +dmF0ZSBUeXBlIEZjdGxEZWYNCiAgIERhdGFGaWVsZE5hbWUgQXMgU3RyaW5nDQog +ICBEYXRhVHlwZSBBcyBTcWxGaWVsZERhdGFUeXBlDQogICBSZWxhdGlvbmFsT3Bl +cmF0b3IgQXMgU3FsUmVsYXRpb25hbE9wZXJhdG9ycw0KICAgSWdub3JlVmFsdWUg +QXMgVmFyaWFudA0KICAgRmlsdGVyQ29udHJvbDJOYW1lIEFzIFN0cmluZw0KRW5k +IFR5cGUNCg0KUHJpdmF0ZSBTdWIgQ2xhc3NfSW5pdGlhbGl6ZSgpDQoNCiAgIG1f +RmlsdGVyQ29udHJvbE5hbWVQcmVmaXggPSBEZWZhdWx0RmlsdGVyQ29udHJvbE5h +bWVQcmVmaXgNCiAgIG1fRmlsdGVyQ29udHJvbFRhZ1ZhbHVlU2VwYXJhdG9yID0g +RGVmYXVsdEZpbHRlckNvbnRyb2xUYWdWYWx1ZVNlcGFyYXRvcg0KICAgDQogICBt +X0RlZmF1bHROdW1lcmljUmVsYXRpb25hbE9wZXJhdG9yID0gREVGX0RlZmF1bHRO +dW1lcmljUmVsYXRpb25hbE9wZXJhdG9yDQogICBtX0RlZmF1bHRUZXh0UmVsYXRp +b25hbE9wZXJhdG9yID0gREVGX0RlZmF1bHRUZXh0UmVsYXRpb25hbE9wZXJhdG9y +DQogICBtX0RlZmF1bHREYXRlUmVsYXRpb25hbE9wZXJhdG9yID0gREVGX0RlZmF1 +bHREYXRlUmVsYXRpb25hbE9wZXJhdG9yDQogICBtX0RlZmF1bHRCb29sZWFuUmVs +YXRpb25hbE9wZXJhdG9yID0gREVGX0RlZmF1bHRCb29sZWFuUmVsYXRpb25hbE9w +ZXJhdG9yDQogICANCkVuZCBTdWINCg0KUHVibGljIFN1YiBBZGRGaWx0ZXJDb250 +cm9scyhCeVZhbCBGY3RsQ29sIEFzIEZpbHRlckNvbnRyb2xDb2xsZWN0aW9uLCBC +eVZhbCBDb250cm9sc1JlZiBBcyBPYmplY3QsIE9wdGlvbmFsIEJ5VmFsIERhdGFT +b3VyY2VSZWNvcmRzZXQgQXMgT2JqZWN0ID0gTm90aGluZykNCiAgIA0KICAgRGlt +IGN0bCBBcyBDb250cm9sDQogICANCiAgIFNldCBtX0RhdGFTb3VyY2VSZWNvcmRz +ZXQgPSBEYXRhU291cmNlUmVjb3Jkc2V0DQogICANCiAgIEZvciBFYWNoIGN0bCBJ +biBDb250cm9sc1JlZg0KICAgICAgSWYgY3RsLk5hbWUgTGlrZSBtX0ZpbHRlckNv +bnRyb2xOYW1lUHJlZml4ICYgIioiIFRoZW4NCiAgICAgICAgIEFkZEZpbHRlckNv +bnRyb2wgRmN0bENvbCwgY3RsDQogICAgICBFbmQgSWYNCiAgIE5leHQNCiAgIA0K +ICAgU2V0IG1fRGF0YVNvdXJjZVJlY29yZHNldCA9IE5vdGhpbmcNCiAgIA0KRW5k +IFN1Yg0KDQpQcml2YXRlIFN1YiBBZGRGaWx0ZXJDb250cm9sKEJ5VmFsIEZjdGxD +b2wgQXMgRmlsdGVyQ29udHJvbENvbGxlY3Rpb24sIEJ5VmFsIEZpbHRlckNvbnRy +b2xSZWYgQXMgQ29udHJvbCkNCiAgIA0KICAgRGltIEZjRGVmIEFzIEZjdGxEZWYN +CiAgIERpbSBGaWx0ZXJDb250cm9sMiBBcyBDb250cm9sDQogICANCiAgIEZjRGVm +ID0gR2V0RmlsdGVyQ29udHJvbERlZmluaXRpb24oRmlsdGVyQ29udHJvbFJlZikN +CiAgIA0KICAgV2l0aCBGY0RlZg0KICAgICAgDQogICAgICBJZiBMZW4oLkZpbHRl +ckNvbnRyb2wyTmFtZSkgPiAwIFRoZW4NCiAgICAgICAgIFNldCBGaWx0ZXJDb250 +cm9sMiA9IEZpbHRlckNvbnRyb2xSZWYuUGFyZW50LkZvcm0uQ29udHJvbHMoLkZp +bHRlckNvbnRyb2wyTmFtZSkNCiAgICAgIEVsc2UNCiAgICAgICAgIFNldCBGaWx0 +ZXJDb250cm9sMiA9IE5vdGhpbmcNCiAgICAgIEVuZCBJZg0KICAgICAgDQogICAg +ICBGY3RsQ29sLkFkZCAuRGF0YUZpZWxkTmFtZSwgLkRhdGFUeXBlLCAuUmVsYXRp +b25hbE9wZXJhdG9yLCBGaWx0ZXJDb250cm9sUmVmLCBGaWx0ZXJDb250cm9sMiwg +Lklnbm9yZVZhbHVlDQogICAgICANCiAgIEVuZCBXaXRoDQogICANCkVuZCBTdWIN +Cg0KUHJpdmF0ZSBGdW5jdGlvbiBHZXRGaWx0ZXJDb250cm9sRGVmaW5pdGlvbihC +eVZhbCBGaWx0ZXJDb250cm9sUmVmIEFzIENvbnRyb2wpIEFzIEZjdGxEZWYNCiAg +IA0KICAgRGltIEZjRGVmIEFzIEZjdGxEZWYNCiAgIA0KICAgRGltIFRhZ1ZhbHVl +cygpIEFzIFN0cmluZw0KICAgDQogICBJZiBMZW4oRmlsdGVyQ29udHJvbFJlZi5U +YWcpID4gMCBUaGVuDQogICAgICBUYWdWYWx1ZXMgPSBTcGxpdChGaWx0ZXJDb250 +cm9sUmVmLlRhZywgbV9GaWx0ZXJDb250cm9sVGFnVmFsdWVTZXBhcmF0b3IpDQog +ICAgICBGaWxsRmlsdGVyQ29udHJvbERlZmluaXRpb25Gcm9tVGFnQXJyYXkgRmNE +ZWYsIFRhZ1ZhbHVlcw0KICAgRW5kIElmDQogICANCiAgIElmIExlbihGY0RlZi5E +YXRhRmllbGROYW1lKSA9IDAgVGhlbg0KICAgICAgRmNEZWYuRGF0YUZpZWxkTmFt +ZSA9IE1pZChGaWx0ZXJDb250cm9sUmVmLk5hbWUsIExlbihtX0ZpbHRlckNvbnRy +b2xOYW1lUHJlZml4KSArIDEpDQogICAgICBJZiBMZW4oRmNEZWYuRGF0YUZpZWxk +TmFtZSkgPSAwIFRoZW4NCiAgICAgICAgIEVyci5SYWlzZSB2Yk9iamVjdEVycm9y +LCAiRmlsdGVyQ29udHJvbFRhZ0NvbnZlcnRlci5HZXRGaWx0ZXJDb250cm9sRGVm +aW5pdGlvbiIsICJEYXRhRmllbGROYW1lIGlzIG5vdCBhdmFpbGFibGUiDQogICAg +ICBFbmQgSWYNCiAgIEVuZCBJZg0KICAgICAgDQogICBJZiBGY0RlZi5EYXRhVHlw +ZSA9IDAgVGhlbg0KICAgICAgSWYgTm90IFRyeUdldERhdGFUeXBlRnJvbURhdGFT +b3VyY2UoRmNEZWYuRGF0YUZpZWxkTmFtZSwgRmNEZWYuRGF0YVR5cGUpIFRoZW4N +CiAgICAgICAgIEVyci5SYWlzZSB2Yk9iamVjdEVycm9yLCAiRmlsdGVyQ29udHJv +bFRhZ0NvbnZlcnRlci5HZXRGaWx0ZXJDb250cm9sRGVmaW5pdGlvbiIsICJEYXRh +VHlwZSBpcyBub3QgYXZhaWxhYmxlIg0KICAgICAgRW5kIElmDQogICBFbmQgSWYN +CiAgIA0KICAgSWYgRmNEZWYuUmVsYXRpb25hbE9wZXJhdG9yID0gMCBUaGVuDQog +ICAgICBGY0RlZi5SZWxhdGlvbmFsT3BlcmF0b3IgPSBHZXREZWZhdWx0UmVsYXRp +b25hbE9wZXJhdG9yKEZjRGVmLkRhdGFUeXBlKQ0KICAgRW5kIElmDQogICANCiAg +IElmIElzRW1wdHkoRmNEZWYuSWdub3JlVmFsdWUpIFRoZW4NCiAgICAgIEZjRGVm +Lklnbm9yZVZhbHVlID0gTnVsbA0KICAgRW5kIElmDQogICANCiAgIEdldEZpbHRl +ckNvbnRyb2xEZWZpbml0aW9uID0gRmNEZWYNCiAgIA0KRW5kIEZ1bmN0aW9uDQoN +ClByaXZhdGUgRnVuY3Rpb24gVHJ5R2V0RGF0YVR5cGVGcm9tRGF0YVNvdXJjZShC +eVZhbCBGaWVsZE5hbWUgQXMgU3RyaW5nLCBCeVJlZiBGaWVsZERhdGFUeXBlIEFz +IFNxbEZpZWxkRGF0YVR5cGUpIEFzIEJvb2xlYW4NCiAgIA0KICAgSWYgbV9EYXRh +U291cmNlUmVjb3Jkc2V0IElzIE5vdGhpbmcgVGhlbg0KICAgICAgVHJ5R2V0RGF0 +YVR5cGVGcm9tRGF0YVNvdXJjZSA9IEZhbHNlDQogICAgICBFeGl0IEZ1bmN0aW9u +DQogICBFbmQgSWYNCiAgIA0KICAgRXJyLlJhaXNlIHZiT2JqZWN0RXJyb3IsICJU +cnlHZXREYXRhVHlwZUZyb21EYXRhU291cmNlIiwgIk5vdCBpbXBsZW1lbnRlZCB5 +ZXQiDQogICANCkVuZCBGdW5jdGlvbg0KDQpQcml2YXRlIEZ1bmN0aW9uIEdldERl +ZmF1bHRSZWxhdGlvbmFsT3BlcmF0b3IoQnlWYWwgRmllbGREYXRhVHlwZSBBcyBT +cWxGaWVsZERhdGFUeXBlKSBBcyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzDQoNCiAg +IFNlbGVjdCBDYXNlIEZpZWxkRGF0YVR5cGUNCiAgICAgIENhc2UgU3FsRmllbGRE +YXRhVHlwZS5TUUxfTnVtZXJpYw0KICAgICAgICAgR2V0RGVmYXVsdFJlbGF0aW9u +YWxPcGVyYXRvciA9IG1fRGVmYXVsdE51bWVyaWNSZWxhdGlvbmFsT3BlcmF0b3IN +CiAgICAgIENhc2UgU3FsRmllbGREYXRhVHlwZS5TUUxfVGV4dA0KICAgICAgICAg +R2V0RGVmYXVsdFJlbGF0aW9uYWxPcGVyYXRvciA9IG1fRGVmYXVsdFRleHRSZWxh +dGlvbmFsT3BlcmF0b3INCiAgICAgIENhc2UgU3FsRmllbGREYXRhVHlwZS5TUUxf +RGF0ZQ0KICAgICAgICAgR2V0RGVmYXVsdFJlbGF0aW9uYWxPcGVyYXRvciA9IG1f +RGVmYXVsdERhdGVSZWxhdGlvbmFsT3BlcmF0b3INCiAgICAgIENhc2UgU3FsRmll +bGREYXRhVHlwZS5TUUxfQm9vbGVhbg0KICAgICAgICAgR2V0RGVmYXVsdFJlbGF0 +aW9uYWxPcGVyYXRvciA9IG1fRGVmYXVsdEJvb2xlYW5SZWxhdGlvbmFsT3BlcmF0 +b3INCiAgICAgIENhc2UgRWxzZQ0KICAgICAgICAgIEVyci5SYWlzZSB2Yk9iamVj +dEVycm9yLCAiRmlsdGVyQ29udHJvbFRhZ0NvbnZlcnRlci5HZXRGaWx0ZXJDb250 +cm9sRGVmaW5pdGlvbiIsICJEYXRhVHlwZSAnIiAmIEZpZWxkRGF0YVR5cGUgJiAi +JyBpcyBub3Qgc3VwcG9ydGVkIg0KICAgRW5kIFNlbGVjdA0KICAgDQpFbmQgRnVu +Y3Rpb24NCg0KUHJpdmF0ZSBTdWIgRmlsbEZpbHRlckNvbnRyb2xEZWZpbml0aW9u +RnJvbVRhZ0FycmF5KEJ5UmVmIEZjRGVmIEFzIEZjdGxEZWYsIEJ5UmVmIFRhZ1Zh +bHVlcygpIEFzIFN0cmluZykNCicgPERhdGFUeXBlPnw8UmVsYXRpb25hbE9wZXJh +dG9yPnw8RmllbGROYW1lPnw8Q29udHJvbDJOYW1lPnw8SWdub3JlVmFsdWU+DQon +DQonIFNhbXBsZXM6DQonICAgIER8YmV0d2VlbnxJbnZvaWNlRGF0ZXx4ZmN0bElu +dm9pY2VEYXRlX01heA0KJyAgICBOfD49DQonICAgIFR8Kmxpa2UqDQonICAgIFQN +CiAgIA0KICAgRGltIE1heEFycmF5SW5kZXggQXMgTG9uZw0KICAgDQogICBNYXhB +cnJheUluZGV4ID0gVUJvdW5kKFRhZ1ZhbHVlcykNCiAgIA0KICAgSWYgTGVuKFRh +Z1ZhbHVlcygwKSkgPiAwIFRoZW4NCiAgICAgIFNldERhdGFUeXBlRnJvbVRhZ1Zh +bHVlIEZjRGVmLkRhdGFUeXBlLCBUYWdWYWx1ZXMoMCkNCiAgIEVuZCBJZg0KICAg +SWYgTWF4QXJyYXlJbmRleCA9IDAgVGhlbiBFeGl0IFN1Yg0KICAgDQogICBJZiBM +ZW4oVGFnVmFsdWVzKDEpKSA+IDAgVGhlbg0KICAgICAgU2V0UmVsYXRpb25hbE9w +ZXJhdG9yRnJvbVRhZ1ZhbHVlIEZjRGVmLlJlbGF0aW9uYWxPcGVyYXRvciwgVGFn +VmFsdWVzKDEpDQogICBFbmQgSWYNCiAgIElmIE1heEFycmF5SW5kZXggPSAxIFRo +ZW4gRXhpdCBTdWINCiAgIA0KICAgSWYgTGVuKFRhZ1ZhbHVlcygyKSkgPiAwIFRo +ZW4NCiAgICAgIEZjRGVmLkRhdGFGaWVsZE5hbWUgPSBUYWdWYWx1ZXMoMikNCiAg +IEVuZCBJZg0KICAgSWYgTWF4QXJyYXlJbmRleCA9IDIgVGhlbiBFeGl0IFN1Yg0K +ICAgDQogICBJZiBMZW4oVGFnVmFsdWVzKDMpKSA+IDAgVGhlbg0KICAgICAgRmNE +ZWYuRmlsdGVyQ29udHJvbDJOYW1lID0gVGFnVmFsdWVzKDMpDQogICBFbmQgSWYN +CiAgIElmIE1heEFycmF5SW5kZXggPSAzIFRoZW4gRXhpdCBTdWINCiAgIA0KICAg +RXJyLlJhaXNlIHZiT2JqZWN0RXJyb3IsICJGaWxsRmlsdGVyQ29udHJvbERlZmlu +aXRpb25Gcm9tVGFnQXJyYXkiLCAiTnVsbFZhbHVlIGlzIG5vdCBpbXBsZW1lbnRl +ZCB5ZXQiDQogICANCkVuZCBTdWINCg0KUHJpdmF0ZSBGdW5jdGlvbiBTZXREYXRh +VHlwZUZyb21UYWdWYWx1ZShCeVJlZiBGY0RlZkRhdGFUeXBlIEFzIFNxbEZpZWxk +RGF0YVR5cGUsIEJ5VmFsIFRhZ1ZhbHVlIEFzIFN0cmluZykgQXMgQm9vbGVhbg0K +ICAgDQogICBTZXREYXRhVHlwZUZyb21UYWdWYWx1ZSA9IFRydWUNCg0KICAgU2Vs +ZWN0IENhc2UgVGFnVmFsdWUNCiAgICAgIENhc2UgIk4iLCAiTnVtZXJpYyINCiAg +ICAgICAgIEZjRGVmRGF0YVR5cGUgPSBTUUxfTnVtZXJpYw0KICAgICAgQ2FzZSAi +VCIsICJUZXh0Ig0KICAgICAgICAgRmNEZWZEYXRhVHlwZSA9IFNRTF9UZXh0DQog +ICAgICBDYXNlICJEIiwgIkRhdGUiDQogICAgICAgICBGY0RlZkRhdGFUeXBlID0g +U1FMX0RhdGUNCiAgICAgIENhc2UgIkIiLCAiQm9vbGVhbiIsICJCb29sIg0KICAg +ICAgICAgRmNEZWZEYXRhVHlwZSA9IFNRTF9Cb29sZWFuDQogICAgICBDYXNlIEVs +c2UNCiAgICAgICAgIFNldERhdGFUeXBlRnJvbVRhZ1ZhbHVlID0gRmFsc2UNCiAg +IEVuZCBTZWxlY3QNCiAgIA0KRW5kIEZ1bmN0aW9uDQoNClByaXZhdGUgRnVuY3Rp +b24gU2V0UmVsYXRpb25hbE9wZXJhdG9yRnJvbVRhZ1ZhbHVlKEJ5UmVmIEZjRGVm +UmVsYXRpb25hbE9wZXJhdG9yIEFzIFNxbFJlbGF0aW9uYWxPcGVyYXRvcnMsIEJ5 +VmFsIFRhZ1ZhbHVlIEFzIFN0cmluZykgQXMgQm9vbGVhbg0KDQogICBEaW0gaSBB +cyBMb25nDQoNCiAgIFNldFJlbGF0aW9uYWxPcGVyYXRvckZyb21UYWdWYWx1ZSA9 +IFRydWUNCiAgIA0KICAgSWYgVGFnVmFsdWUgTGlrZSAiTm90KiIgVGhlbg0KICAg +ICAgRmNEZWZSZWxhdGlvbmFsT3BlcmF0b3IgPSBTUUxfTm90DQogICAgICBUYWdW +YWx1ZSA9IE1pZChUYWdWYWx1ZSwgTGVuKCJOT1QiKSArIDEpDQogICBFbmQgSWYN +CiAgIA0KICAgSWYgVGFnVmFsdWUgTGlrZSAiKmJldHdlZW4qIiBUaGVuDQogICAg +ICBGY0RlZlJlbGF0aW9uYWxPcGVyYXRvciA9IEZjRGVmUmVsYXRpb25hbE9wZXJh +dG9yICsgU1FMX0JldHdlZW4NCiAgICAgIElmIFRhZ1ZhbHVlIExpa2UgIipiZXR3 +ZWVuWypdKiIgVGhlbiAnIFNvbmRlcmZhbGwgZvxyIERhdHVtc3dlcnRlDQogICAg +ICAgICBGY0RlZlJlbGF0aW9uYWxPcGVyYXRvciA9IEZjRGVmUmVsYXRpb25hbE9w +ZXJhdG9yICsgU1FMX0FkZF9XaWxkQ2FyZFN1ZmZpeA0KICAgICAgRW5kIElmDQog +ICAgICBFeGl0IEZ1bmN0aW9uDQogICBFbHNlSWYgVGFnVmFsdWUgTGlrZSAiKmxp +a2UqIiBUaGVuDQogICAgICBGY0RlZlJlbGF0aW9uYWxPcGVyYXRvciA9IEZjRGVm +UmVsYXRpb25hbE9wZXJhdG9yICsgU1FMX0xpa2UNCiAgICAgIElmIFRhZ1ZhbHVl +IExpa2UgIipsaWtlWypdKiIgVGhlbg0KICAgICAgICAgRmNEZWZSZWxhdGlvbmFs +T3BlcmF0b3IgPSBGY0RlZlJlbGF0aW9uYWxPcGVyYXRvciArIFNRTF9BZGRfV2ls +ZENhcmRTdWZmaXgNCiAgICAgIEVuZCBJZg0KICAgICAgSWYgVGFnVmFsdWUgTGlr +ZSAiKlsqXWxpa2UqIiBUaGVuDQogICAgICAgICBGY0RlZlJlbGF0aW9uYWxPcGVy +YXRvciA9IEZjRGVmUmVsYXRpb25hbE9wZXJhdG9yICsgU1FMX0FkZF9XaWxkQ2Fy +ZFByZWZpeA0KICAgICAgRW5kIElmDQogICAgICBFeGl0IEZ1bmN0aW9uDQogICBF +bHNlSWYgVGFnVmFsdWUgTGlrZSAiKkluKiIgVGhlbg0KICAgICAgRmNEZWZSZWxh +dGlvbmFsT3BlcmF0b3IgPSBGY0RlZlJlbGF0aW9uYWxPcGVyYXRvciArIFNRTF9J +bg0KICAgICAgRXhpdCBGdW5jdGlvbg0KICAgRW5kIElmDQogICANCiAgIEZvciBp +ID0gMSBUbyBMZW4oVGFnVmFsdWUpDQogICAgICBTZWxlY3QgQ2FzZSBNaWQoVGFn +VmFsdWUsIGksIDEpDQogICAgICAgICBDYXNlICI9Ig0KICAgICAgICAgICAgRmNE +ZWZSZWxhdGlvbmFsT3BlcmF0b3IgPSBGY0RlZlJlbGF0aW9uYWxPcGVyYXRvciBP +ciBTUUxfRXF1YWwNCiAgICAgICAgIENhc2UgIjwiDQogICAgICAgICAgICBGY0Rl +ZlJlbGF0aW9uYWxPcGVyYXRvciA9IEZjRGVmUmVsYXRpb25hbE9wZXJhdG9yIE9y +IFNRTF9MZXNzVGhhbg0KICAgICAgICAgQ2FzZSAiPiINCiAgICAgICAgICAgIEZj +RGVmUmVsYXRpb25hbE9wZXJhdG9yID0gRmNEZWZSZWxhdGlvbmFsT3BlcmF0b3Ig +T3IgU1FMX0dyZWF0ZXJUaGFuDQogICAgICBFbmQgU2VsZWN0DQogICBOZXh0DQog +ICANCiAgIElmIEZjRGVmUmVsYXRpb25hbE9wZXJhdG9yID0gMCBUaGVuDQogICAg +ICBTZXRSZWxhdGlvbmFsT3BlcmF0b3JGcm9tVGFnVmFsdWUgPSBGYWxzZQ0KICAg +RW5kIElmDQoNCkVuZCBGdW5jdGlvbg0K + + 20250609094839 + form/filter/FilterControlTagConverter.cls + + + FilterStringBuilder + VkVSU0lPTiAxLjAgQ0xBU1MNCkJFR0lODQogIE11bHRpVXNlID0gLTEgICdUcnVl +DQpFTkQNCkF0dHJpYnV0ZSBWQl9OYW1lID0gIkZpbHRlclN0cmluZ0J1aWxkZXIi +DQpBdHRyaWJ1dGUgVkJfR2xvYmFsTmFtZVNwYWNlID0gRmFsc2UNCkF0dHJpYnV0 +ZSBWQl9DcmVhdGFibGUgPSBGYWxzZQ0KQXR0cmlidXRlIFZCX1ByZWRlY2xhcmVk +SWQgPSBGYWxzZQ0KQXR0cmlidXRlIFZCX0V4cG9zZWQgPSBGYWxzZQ0KJy0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBDbGFzczogZGF0 +YS5zcWwuRmlsdGVyU3RyaW5nQnVpbGRlcg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBDcmVhdGUgU1FMIGNyaXRlcmlhIChm +aWx0ZXIpIGV4cHJlc3Npb24NCicNCicgQXV0aG9yOg0KJyAgICAgSm9zZWYgUG9l +dHpsDQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +DQoNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCic8 +Y29kZWxpYj4NCicgIDxmaWxlPmRhdGEvRmlsdGVyU3RyaW5nQnVpbGRlci5jbHM8 +L2ZpbGU+DQonICA8bGljZW5zZT5fY29kZWxpYi9saWNlbnNlLmJhczwvbGljZW5z +ZT4NCicgIDx1c2U+dGV4dC9TdHJpbmdDb2xsZWN0aW9uLmNsczwvdXNlPg0KJyAg +PHVzZT5kYXRhL1NxbFRvb2xzLmNsczwvdXNlPg0KJyAgPHRlc3Q+X3Rlc3QvZGF0 +YS9GaWx0ZXJTdHJpbmdCdWlsZGVyVGVzdHMuY2xzPC90ZXN0Pg0KJzwvY29kZWxp +Yj4NCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicN +Ck9wdGlvbiBDb21wYXJlIFRleHQNCk9wdGlvbiBFeHBsaWNpdA0KDQpQcml2YXRl +IG1fSXRlbXMgQXMgU3RyaW5nQ29sbGVjdGlvbg0KUHJpdmF0ZSBtX1NxbFRvb2wg +QXMgU3FsVG9vbHMNClByaXZhdGUgbV9EZWZhdWx0Q29uY2F0T3BlcmF0b3IgQXMg +U3FsTG9naWNhbE9wZXJhdG9yDQoNClByaXZhdGUgbV9Db25kaXRpb25Hcm91cHMg +QXMgQ29sbGVjdGlvbg0KDQpQcml2YXRlIG1fU3FsUHJlZml4IEFzIFN0cmluZw0K +UHJpdmF0ZSBtX1NxbFN1ZmZpeCBBcyBTdHJpbmcNClByaXZhdGUgbV9Db25kaXRp +b25QcmVmaXggQXMgU3RyaW5nDQpQcml2YXRlIG1fSWdub3JlU3FsUHJlU3VmZml4 +SWZFbXB0eUZpbHRlciBBcyBCb29sZWFuDQoNClByaXZhdGUgQ29uc3QgV2hlcmVS +ZXBsYWNlbWVudFRleHQgQXMgU3RyaW5nID0gIltXaGVyZVN0YXRlbWVudF0iDQoN +ClByaXZhdGUgU3ViIENsYXNzX0luaXRpYWxpemUoKQ0KICAgU2V0IG1fSXRlbXMg +PSBOZXcgU3RyaW5nQ29sbGVjdGlvbg0KICAgbV9EZWZhdWx0Q29uY2F0T3BlcmF0 +b3IgPSBTcWxMb2dpY2FsT3BlcmF0b3IuU1FMX0FuZA0KRW5kIFN1Yg0KDQpQcml2 +YXRlIFN1YiBDbGFzc19UZXJtaW5hdGUoKQ0KICAgU2V0IG1fSXRlbXMgPSBOb3Ro +aW5nDQpFbmQgU3ViDQoNCicjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj +IyMjDQonIEdyb3VwOiBDbGFzcyBzdXBwb3J0DQoNCictLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgUHJvcGVydHk6IFNlbGYNCictLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicgUmVmZXJl +bmNlIHRvIE1lIChjdXJyZW50IGluc3RhbmNlIG9mIEZpbHRlclN0cmluZ0J1aWxk +ZXIgY2xhc3MpDQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tDQpQdWJsaWMgUHJvcGVydHkgR2V0IFNlbGYoKSBBcyBGaWx0ZXJTdHJp +bmdCdWlsZGVyDQogICBTZXQgU2VsZiA9IE1lDQpFbmQgUHJvcGVydHkNCg0KJyMj +IyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCicgR3JvdXA6IENvbmZp +Zw0KDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQon +IFByb3BlcnR5OiBEZWZhdWx0Q29uY2F0T3BlcmF0b3INCictLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicgVGhlIGRlZmF1bHQgY29u +Y2F0IG9wZXJhdG9yIGZvciB0aGUgaW5zdGFuY2UNCicNCictLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NClB1YmxpYyBQcm9wZXJ0eSBHZXQg +RGVmYXVsdENvbmNhdE9wZXJhdG9yKCkgQXMgU3FsTG9naWNhbE9wZXJhdG9yDQog +ICBEZWZhdWx0Q29uY2F0T3BlcmF0b3IgPSBtX0RlZmF1bHRDb25jYXRPcGVyYXRv +cg0KRW5kIFByb3BlcnR5DQoNClB1YmxpYyBQcm9wZXJ0eSBMZXQgRGVmYXVsdENv +bmNhdE9wZXJhdG9yKEJ5VmFsIE5ld1ZhbHVlIEFzIFNxbExvZ2ljYWxPcGVyYXRv +cikNCiAgIG1fRGVmYXVsdENvbmNhdE9wZXJhdG9yID0gTmV3VmFsdWUNCkVuZCBQ +cm9wZXJ0eQ0KDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tDQonIFByb3BlcnR5OiBTcWxUb29sDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tDQonDQonIFNxbFRvb2xzIGluc3RhbmNlIHRvIGJl +IHVzZWQgKGlmIG5vdCBzZXQsIGNsb25lIG9mIGdsb2JhbCBTcWxUb29scyBpbnN0 +YW5jZSBpcyB1c2VkKQ0KJw0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLQ0KRnJpZW5kIFByb3BlcnR5IEdldCBTcWxUb29sKCkgQXMgU3Fs +VG9vbHMNCiAgIElmIG1fU3FsVG9vbCBJcyBOb3RoaW5nIFRoZW4NCiAgICAgIFNl +dCBtX1NxbFRvb2wgPSBTcWxUb29scy5DbG9uZQ0KICAgRW5kIElmDQogICBTZXQg +U3FsVG9vbCA9IG1fU3FsVG9vbA0KRW5kIFByb3BlcnR5DQoNCkZyaWVuZCBQcm9w +ZXJ0eSBTZXQgU3FsVG9vbChCeVZhbCBOZXdSZWYgQXMgU3FsVG9vbHMpDQogICBT +ZXQgbV9TcWxUb29sID0gTmV3UmVmDQpFbmQgUHJvcGVydHkNCg0KJy0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBGdW5jdGlvbjogU2Vs +ZWN0U3FsRGlhbGVjdA0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLQ0KJw0KJyBDb25maWcgc3FsIHRleHQgb3V0cHV0IGZvcm1hdCBmb3Ig +c3BlY2lmaWMgc3FsIGRpYWxlY3QNCicNCicgUGFyYW1ldGVyczoNCicNCicgICAg +IFVzZURpYWxlY3QgLSBzcWwgZGlhbGVjdCAuLiB1c2Ugc2V0dGluZyBvZiBkaWFs +ZWN0IChhcyBiYXNlKQ0KJyAgICAgU3FsRGF0ZUZvcm1hdCAtIG91dHB1dCBzdHJp +bmcgZm9ybWF0IGZvciBkYXRlIHZhbHVlcw0KJyAgICAgU3FsQm9vbGVhblRydWVT +dHJpbmcgLSBvdXRwdXQgc3RyaW5nIGZvcm1hdCBmb3IgYm9vbGVhbiB2YWx1ZXMN +CicgICAgIFNxbFdpbGRDYXJkU3RyaW5nIC0gd2lsZGNhcmQgc3RyaW5nIChlLmcu +ICogLi4gZGFvLCAlIC4uIFQtU1FMKQ0KJw0KJy0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLQ0KRnJpZW5kIFN1YiBTZWxlY3RTcWxEaWFsZWN0 +KEJ5VmFsIFVzZURpYWxlY3QgQXMgU3FsRGlhbGVjdCwgXw0KICAgICAgICAgICAg +ICAgICAgIE9wdGlvbmFsIEJ5VmFsIFNxbERhdGVGb3JtYXQgQXMgU3RyaW5nLCBf +DQogICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgU3FsQm9vbGVhblRy +dWVTdHJpbmcgQXMgU3RyaW5nLCBfDQogICAgICAgICAgICAgICAgICAgT3B0aW9u +YWwgQnlWYWwgU3FsV2lsZENhcmRTdHJpbmcgQXMgU3RyaW5nKQ0KICAgDQogICBT +ZXQgbV9TcWxUb29sID0gU3FsVG9vbHMuRnJvbURpYWxlY3QoVXNlRGlhbGVjdCwg +U3FsRGF0ZUZvcm1hdCwgU3FsQm9vbGVhblRydWVTdHJpbmcsIFNxbFdpbGRDYXJk +U3RyaW5nKQ0KDQpFbmQgU3ViDQoNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0NCicgRnVuY3Rpb246IENvbmZpZ1NxbEZvcm1hdA0KJy0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBDb25m +aWcgc3FsIHRleHQgb3V0cHV0IGZvcm1hdCBmb3Igc3BlY2lmaWMgc3FsIGRpYWxl +Y3QNCicNCicgUGFyYW1ldGVyczoNCicNCicgICAgIFNxbERhdGVGb3JtYXQgLSBv +dXRwdXQgc3RyaW5nIGZvcm1hdCBmb3IgZGF0ZSB2YWx1ZXMNCicgICAgIFNxbEJv +b2xlYW5UcnVlU3RyaW5nIC0gb3V0cHV0IHN0cmluZyBmb3JtYXQgZm9yIGJvb2xl +YW4gdmFsdWVzDQonICAgICBTcWxXaWxkQ2FyZFN0cmluZyAtIHdpbGRjYXJkIHN0 +cmluZyAoZS5nLiAqIC4uIGRhbywgJSAuLiBULVNRTCkNCicNCictLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCkZyaWVuZCBTdWIgQ29uZmln +U3FsRm9ybWF0KEJ5VmFsIFNxbERhdGVGb3JtYXQgQXMgU3RyaW5nLCBfDQogICAg +ICAgICAgICAgICAgICAgICAgICAgICBCeVZhbCBTcWxCb29sZWFuVHJ1ZVN0cmlu +ZyBBcyBTdHJpbmcsIF8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5VmFs +IFNxbFdpbGRDYXJkU3RyaW5nIEFzIFN0cmluZykNCiAgIA0KICAgSWYgbV9TcWxU +b29sIElzIE5vdGhpbmcgVGhlbg0KICAgICAgU2V0IG1fU3FsVG9vbCA9IFNxbFRv +b2xzLk5ld0luc3RhbmNlKFNxbERhdGVGb3JtYXQsIFNxbEJvb2xlYW5UcnVlU3Ry +aW5nLCBTcWxXaWxkQ2FyZFN0cmluZykNCiAgICAgIEV4aXQgU3ViDQogICBFbmQg +SWYNCg0KICAgV2l0aCBtX1NxbFRvb2wNCiAgICAgIC5TcWxEYXRlRm9ybWF0ID0g +U3FsRGF0ZUZvcm1hdA0KICAgICAgLlNxbEJvb2xlYW5UcnVlU3RyaW5nID0gU3Fs +Qm9vbGVhblRydWVTdHJpbmcNCiAgICAgIC5TcWxXaWxkQ2FyZFN0cmluZyA9IFNx +bFdpbGRDYXJkU3RyaW5nDQogICBFbmQgV2l0aA0KDQpFbmQgU3ViDQoNCictLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgRnVuY3Rpb246 +IENvbmZpZ1NxbFN0YXRlbWVudA0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLQ0KJw0KJyBBdXhpbGlhcnkgZnVuY3Rpb24gZm9yIHNldHRp +bmcgU1FMIHRleHRzIGlmIHRoaXMgY2xhc3MgaXMgdXNlZCBpbiBvdGhlciBmaWx0 +ZXIgYnVpbGRlciBjbGFzc2VzLg0KJyAoZS5nLiBpbiBmb3JtLmZpbHRlci5GaWx0 +ZXJDb250cm9sQ29sbGVjdGlvbikNCicNCicgUGFyYW1ldGVyczoNCicNCicgICAg +IFNxbFByZWZpeCAtIElzIHBsYWNlZCBiZWZvcmUgdGhlIEZpbHRlclN0cmluZyBm +b3IgVG9TdHJpbmcgb3V0cHV0IChUb1N0cmluZyA9IG1fU3FsUHJlZml4ICYgRmls +dGVyU3RyaW5nICYgbV9TcWxTdWZmaXgpDQonICAgICBTcWxTdWZmaXggLSBJcyBw +bGFjZWQgYWZ0ZXIgdGhlIEZpbHRlclN0cmluZyBmb3IgVG9TdHJpbmcgb3V0cHV0 +IChUb1N0cmluZyA9IG1fU3FsUHJlZml4ICYgRmlsdGVyU3RyaW5nICYgbV9TcWxT +dWZmaXgpDQonICAgICBDb25kaXRpb25QcmVmaXggLSBJcyBwbGFjZWQgYmVmb3Jl +IHRoZSBmaWx0ZXIgY29uZGl0aW9uIChidXQgb25seSBpZiB0aGUgZmlsdGVyIGNv +bmRpdGlvbiBpcyA+ICIiKS4NCicgICAgIElnbm9yZVNxbFByZVN1ZmZpeElmRW1w +dHlGaWx0ZXIgLSBUcnVlOiBTcWxQcmVmaXggKyBTcWxTdWZmaXggYXJlIG5vdCBz +ZXQgZm9yIGVtcHR5IEZpbHRlclN0cmluZw0KJw0KJy0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KRnJpZW5kIFN1YiBDb25maWdTcWxTdGF0 +ZW1lbnQoQnlWYWwgU3FsUHJlZml4IEFzIFN0cmluZywgQnlWYWwgU3FsU3VmZml4 +IEFzIFN0cmluZywgXw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnlW +YWwgQ29uZGl0aW9uUHJlZml4IEFzIFN0cmluZywgXw0KICAgICAgICAgICAgICAg +ICAgICAgT3B0aW9uYWwgQnlWYWwgSWdub3JlU3FsUHJlU3VmZml4SWZFbXB0eUZp +bHRlciBBcyBCb29sZWFuID0gRmFsc2UpDQogICBtX1NxbFByZWZpeCA9IFNxbFBy +ZWZpeA0KICAgbV9TcWxTdWZmaXggPSBTcWxTdWZmaXgNCiAgIG1fQ29uZGl0aW9u +UHJlZml4ID0gQ29uZGl0aW9uUHJlZml4DQogICBtX0lnbm9yZVNxbFByZVN1ZmZp +eElmRW1wdHlGaWx0ZXIgPSBJZ25vcmVTcWxQcmVTdWZmaXhJZkVtcHR5RmlsdGVy +DQoNCkVuZCBTdWINCg0KJyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj +IyMNCicgR3JvdXA6IEJ1aWxkIENyaXRlcmlhDQoNCictLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgRnVuY3Rpb246IEFkZA0KJy0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBBZGQgZmls +dGVyIGNyaXRlcmlhIGRlZmluaXRpb24NCicgKHVzZXM6IGRhdGEuU3FsVG9vbHMu +QnVpbGRDcml0ZXJpYSkNCicNCicgUGFyYW1ldGVyczoNCicNCicgICAgIEZpZWxk +TmFtZSAgICAgICAgICAgIC0gRmllbGQgbmFtZSBpbiB0aGUgZGF0YSBzb3VyY2Ug +dG8gYmUgZmlsdGVyZWQNCicgICAgIFJlbGF0aW9uYWxPcGVyYXRvciAgIC0gUmVs +YXRpb25hbCBvcGVyYXRvciAoPSwgPD0sIGV0Yy4pDQonICAgICBWYWx1ZSAgICAg +ICAgICAgICAgICAtIEZpbHRlciB2YWx1ZSAoY2FuIGJlIGEgc2luZ2xlIHZhbHVl +IG9yIGFuIGFycmF5IG9mIHZhbHVlcykNCicgICAgIFZhbHVlMiAgICAgICAgICAg +ICAgIC0gT3B0aW9uYWwgMm5kIGZpbHRlciB2YWx1ZSAoZm9yIEJldHdlZW4pDQon +ICAgICBJZ25vcmVWYWx1ZSAgICAgICAgICAtIFRoZSB2YWx1ZSBmb3Igd2hpY2gg +bm8gZmlsdGVyIGNvbmRpdGlvbiBpcyB0byBiZSBjcmVhdGVkLiAoQXJyYXkgdHJh +bnNmZXIgb2YgdmFsdWVzIHBvc3NpYmxlKSwgRGVmYXVsdDogTnVsbA0KJw0KJy0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIFN1 +YiBBZGQoQnlWYWwgRmllbGROYW1lIEFzIFN0cmluZywgQnlWYWwgRmllbGREYXRh +VHlwZSBBcyBTcWxGaWVsZERhdGFUeXBlLCBfDQogICAgICAgICAgICAgICBCeVZh +bCBSZWxhdGlvbmFsT3BlcmF0b3IgQXMgU3FsUmVsYXRpb25hbE9wZXJhdG9ycywg +Xw0KICAgICAgICAgICAgICAgQnlWYWwgVmFsdWUgQXMgVmFyaWFudCwgXw0KICAg +ICAgT3B0aW9uYWwgQnlWYWwgVmFsdWUyIEFzIFZhcmlhbnQgPSBOdWxsLCBfDQog +ICAgICBPcHRpb25hbCBCeVZhbCBJZ25vcmVWYWx1ZSBBcyBWYXJpYW50ID0gTnVs +bCkNCg0KICAgQWRkQ3JpdGVyaWEgU3FsVG9vbC5CdWlsZENyaXRlcmlhKEZpZWxk +TmFtZSwgRmllbGREYXRhVHlwZSwgUmVsYXRpb25hbE9wZXJhdG9yLCBWYWx1ZSwg +VmFsdWUyLCBJZ25vcmVWYWx1ZSkNCg0KRW5kIFN1Yg0KDQonLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonIEZ1bmN0aW9uOiBBZGRDcml0 +ZXJpYQ0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0K +Jw0KJyBBZGQgZmlsdGVyIGNyaXRlcmlhIChTdHJpbmcpDQonDQonIFBhcmFtZXRl +cnM6DQonDQonICAgICBDcml0ZXJpYSAtIENyaXRlcmlhIHN0cmluZyB0byBhcHBl +bmQNCicNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0N +ClB1YmxpYyBTdWIgQWRkQ3JpdGVyaWEoQnlWYWwgQ3JpdGVyaWEgQXMgU3RyaW5n +KQ0KICAgSWYgTGVuKENyaXRlcmlhKSA9IDAgVGhlbiBFeGl0IFN1Yg0KICAgbV9J +dGVtcy5BZGQgQ3JpdGVyaWENCkVuZCBTdWINCg0KJy0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBGdW5jdGlvbjogTmV3Q29uZGl0aW9u +R3JvdXANCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0N +CicNCicgTmV3IGZpbHRlciBjb25kaXRpb24gZ3JvdXAgLSBlLmcuIGZvciBPciBn +cm91cDogKCBhID0gMSBhbmQgKHggPSAyIG9yIHggPj0gMTApICkNCicNCicgUGFy +YW1ldGVyczoNCicNCicgICAgIENvbmNhdE9wZXJhdG9yIC0gW1NRTF9BbmQgKGRl +ZmF1bHQpLCBTUUxfT3IsIFNRTF9Db21tYVNlcGFyYXRvcl0gLi4gdmFsaWQgd2l0 +aGluIHRoZSBuZXcgZ3JvdXANCicNCicgUmV0dXJuczoNCicNCicgICAgIEZpbHRl +clN0cmluZ0J1aWxkZXIgaW5zdGFuY2UgZm9yIG5ldyBncm91cA0KJw0KJy0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIEZ1bmN0 +aW9uIE5ld0NvbmRpdGlvbkdyb3VwKEJ5VmFsIENvbmNhdE9wZXJhdG9yIEFzIFNx +bExvZ2ljYWxPcGVyYXRvcikgQXMgRmlsdGVyU3RyaW5nQnVpbGRlcg0KDQogICBE +aW0gTmV3QnVpbGRlciBBcyBGaWx0ZXJTdHJpbmdCdWlsZGVyDQogICANCiAgIFNl +dCBOZXdCdWlsZGVyID0gTmV3IEZpbHRlclN0cmluZ0J1aWxkZXINCiAgIFNldCBO +ZXdCdWlsZGVyLlNxbFRvb2wgPSBtX1NxbFRvb2wNCiAgIE5ld0J1aWxkZXIuRGVm +YXVsdENvbmNhdE9wZXJhdG9yID0gQ29uY2F0T3BlcmF0b3INCiAgIA0KICAgQ29u +ZGl0aW9uR3JvdXBzLkFkZCBOZXdCdWlsZGVyDQogICANCiAgIFNldCBOZXdDb25k +aXRpb25Hcm91cCA9IE5ld0J1aWxkZXINCiAgIA0KRW5kIEZ1bmN0aW9uDQoNClBy +aXZhdGUgRnVuY3Rpb24gQXBwZW5kRmlsdGVyR3JvdXBzU3RyaW5nKEJ5VmFsIEJh +c2VGaWx0ZXJTdHJpbmcgQXMgU3RyaW5nLCBCeVZhbCBDb25jYXRPcGVyYXRvciBB +cyBTcWxMb2dpY2FsT3BlcmF0b3IsIF8NCiAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgIE9wdGlvbmFsIEJ5VmFsIElnbm9yZUR1cGxpY2F0ZUZpbHRlcnMg +QXMgQm9vbGVhbiA9IEZhbHNlKSBBcyBTdHJpbmcNCiAgIA0KICAgRGltIENvbmRQ +cmVmaXggQXMgU3RyaW5nDQogICBEaW0gQ29uZFN1ZmZpeCBBcyBTdHJpbmcNCiAg +IA0KICAgSWYgbV9Db25kaXRpb25Hcm91cHMgSXMgTm90aGluZyBUaGVuDQogICAg +ICBBcHBlbmRGaWx0ZXJHcm91cHNTdHJpbmcgPSBCYXNlRmlsdGVyU3RyaW5nDQog +ICAgICBFeGl0IEZ1bmN0aW9uDQogICBFbmQgSWYNCiAgIA0KICAgSWYgbV9Db25k +aXRpb25Hcm91cHMuQ291bnQgPSAwIFRoZW4NCiAgICAgIEFwcGVuZEZpbHRlckdy +b3Vwc1N0cmluZyA9IEJhc2VGaWx0ZXJTdHJpbmcNCiAgICAgIEV4aXQgRnVuY3Rp +b24NCiAgIEVuZCBJZg0KICAgDQogICBJZiBDb25jYXRPcGVyYXRvciA8PiBTUUxf +Q29tbWFTZXBhcmF0b3IgVGhlbg0KICAgICAgQ29uZFByZWZpeCA9ICIoIg0KICAg +ICAgQ29uZFN1ZmZpeCA9ICIpIg0KICAgRW5kIElmDQogICANCiAgIERpbSBGU0Ig +QXMgRmlsdGVyU3RyaW5nQnVpbGRlcg0KICAgDQogICBXaXRoIE5ldyBTdHJpbmdD +b2xsZWN0aW9uDQogICANCiAgICAgIC5BZGQgQmFzZUZpbHRlclN0cmluZw0KICAg +ICAgDQogICAgICBGb3IgRWFjaCBGU0IgSW4gbV9Db25kaXRpb25Hcm91cHMNCiAg +ICAgICAgIC5BZGQgRlNCLlRvU3RyaW5nKCkNCiAgICAgIE5leHQNCg0KICAgICAg +QXBwZW5kRmlsdGVyR3JvdXBzU3RyaW5nID0gLlRvU3RyaW5nKEdldENvbmNhdE9w +ZXJhdG9yU3RyaW5nKENvbmNhdE9wZXJhdG9yKSwgQ29uZFByZWZpeCwgQ29uZFN1 +ZmZpeCwgVHJ1ZSwgSWdub3JlRHVwbGljYXRlRmlsdGVycykNCiAgICAgIA0KICAg +RW5kIFdpdGgNCiAgIA0KRW5kIEZ1bmN0aW9uDQoNCictLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgRnVuY3Rpb246IEFkZFN1YlNlbGVj +dENyaXRlcmlhDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tDQonDQonIE5ldyBmaWx0ZXIgY29uZGl0aW9uIGdyb3VwIGZvciBhIHN1YiBz +ZWxlY3QgLSBlLmcuICggYSA9IDEgYW5kIHggSW4gKHNlbGVjdCBuICBmcm9tIHRh +YjEyMykgKQ0KJw0KJyBQYXJhbWV0ZXJzOg0KJw0KJyAgICAgRmllbGROYW1lIC0g +RGF0YSBmaWVsZCBuYW1lIHRvIGNvbXBhcmUNCicgICAgIFJlbGF0aW9uYWxPcGVy +YXRvciAtIFJlbGF0aW9uYWwgb3BlcmF0b3IgZm9yIHN1YiBzZWxlY3Q6IHVzdWFs +bHkgSW4oLi4uKQ0KJyAgICAgU2VsZWN0RnJvbVRleHQgLSBTcWwgdGV4dCBmb3Ig +c3ViIHNlbGVjdCAod2l0aG91dCB3aGVyZSwgZXhjZXB0IFVzZVdoZXJlUmVwbGFj +ZW1lbnRUZXh0SW5Gcm9tVGV4dCBpcyB1c2VkKQ0KJyAgICAgSWdub3JlSWZTdWJT +ZWxlY3RIYXNOb0NyaXRlcmlhIC0gVHJ1ZSA9IElnbm9yZSBzdWJzZWxlY3QgY3Jp +dGVyaW9uIGlmIG5vIGZpbHRlciB2YWx1ZXMgd2VyZSB0cmFuc2ZlcnJlZA0KJyAg +ICAgVXNlV2hlcmVSZXBsYWNlbWVudFRleHRJbkZyb21UZXh0IC0gUmVwbGFjZSBb +V2hlcmVdIHdpdGggV2hlcmUgY29uZGl0aW9uIHN0cmluZyAuLi4gaXMgcmVxdWly +ZWQgZm9yIEdyb3VwIEJ5LVNRTCwgZm9yIGV4YW1wbGUuDQonICAgICBTdWJTZWxl +Y3RDb25jYXRPcGVyYXRvciAtIFtTUUxfQW5kIChkZWZhdWx0KSwgU1FMX09yLCBT +UUxfQ29tbWFTZXBhcmF0b3JdIC4uIHZhbGlkIHdpdGhpbiB0aGUgbmV3IGdyb3Vw +DQonDQonIFJldHVybnM6DQonDQonICAgICBGaWx0ZXJTdHJpbmdCdWlsZGVyIGlu +c3RhbmNlIGZvciBuZXcgc3ViIHNlbGVjdCBncm91cA0KJw0KJy0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIEZ1bmN0aW9uIEFk +ZFN1YlNlbGVjdENyaXRlcmlhKCBfDQogICAgICAgICAgICAgICBCeVZhbCBGaWVs +ZE5hbWUgQXMgU3RyaW5nLCBfDQogICAgICAgICAgICAgICBCeVZhbCBSZWxhdGlv +bmFsT3BlcmF0b3IgQXMgU3FsUmVsYXRpb25hbE9wZXJhdG9ycywgXw0KICAgICAg +ICAgICAgICAgQnlWYWwgU2VsZWN0RnJvbVRleHQgQXMgU3RyaW5nLCBfDQogICAg +ICAgICAgICAgICBPcHRpb25hbCBCeVZhbCBJZ25vcmVJZlN1YlNlbGVjdEhhc05v +Q3JpdGVyaWEgQXMgQm9vbGVhbiA9IEZhbHNlLCBfDQogICAgICAgICAgICAgICBP +cHRpb25hbCBCeVZhbCBVc2VXaGVyZVJlcGxhY2VtZW50VGV4dEluRnJvbVRleHQg +QXMgQm9vbGVhbiA9IEZhbHNlLCBfDQogICAgICAgICAgICAgICBPcHRpb25hbCBC +eVZhbCBTdWJTZWxlY3RDb25jYXRPcGVyYXRvciBBcyBTcWxMb2dpY2FsT3BlcmF0 +b3IgPSBTcWxMb2dpY2FsT3BlcmF0b3IuU1FMX0FuZCBfDQogICAgICApIEFzIEZp +bHRlclN0cmluZ0J1aWxkZXINCg0KICAgRGltIE5ld0J1aWxkZXIgQXMgRmlsdGVy +U3RyaW5nQnVpbGRlcg0KICAgRGltIFNxbFByZWZpeCBBcyBTdHJpbmcNCiAgIERp +bSBTcWxTdWZmaXggQXMgU3RyaW5nDQogICBEaW0gV2hlcmVSZXBsYWNlbWVudFBv +cyBBcyBMb25nDQogICANCiAgIFNxbFByZWZpeCA9IEZpZWxkTmFtZSAmICIgIiAm +IFNxbFRvb2xzLkdldFJlbGF0aW9uYWxPcGVyYXRvclN0cmluZyhSZWxhdGlvbmFs +T3BlcmF0b3IpICYgIiAoIg0KICAgU3FsU3VmZml4ID0gIikiDQogICBJZiBVc2VX +aGVyZVJlcGxhY2VtZW50VGV4dEluRnJvbVRleHQgVGhlbg0KICAgICAgV2hlcmVS +ZXBsYWNlbWVudFBvcyA9IEluU3RyKDEsIFNlbGVjdEZyb21UZXh0LCBXaGVyZVJl +cGxhY2VtZW50VGV4dCwgdmJUZXh0Q29tcGFyZSkNCiAgIEVuZCBJZg0KICAgDQog +ICBJZiBXaGVyZVJlcGxhY2VtZW50UG9zID4gMCBUaGVuDQogICAgICBTcWxQcmVm +aXggPSBTcWxQcmVmaXggJiBUcmltJChMZWZ0KFNlbGVjdEZyb21UZXh0LCBXaGVy +ZVJlcGxhY2VtZW50UG9zIC0gMSkpDQogICAgICBTcWxTdWZmaXggPSAiICIgJiBU +cmltJChNaWQkKFNlbGVjdEZyb21UZXh0LCBXaGVyZVJlcGxhY2VtZW50UG9zICsg +TGVuKFdoZXJlUmVwbGFjZW1lbnRUZXh0KSkpICYgU3FsU3VmZml4DQogICBFbHNl +DQogICAgICBTcWxQcmVmaXggPSBTcWxQcmVmaXggJiBTZWxlY3RGcm9tVGV4dA0K +ICAgRW5kIElmDQogICANCiAgIFNldCBOZXdCdWlsZGVyID0gTmV3IEZpbHRlclN0 +cmluZ0J1aWxkZXINCiAgIE5ld0J1aWxkZXIuRGVmYXVsdENvbmNhdE9wZXJhdG9y +ID0gU3ViU2VsZWN0Q29uY2F0T3BlcmF0b3INCiAgIFNldCBOZXdCdWlsZGVyLlNx +bFRvb2wgPSBtX1NxbFRvb2wNCiAgIA0KICAgTmV3QnVpbGRlci5Db25maWdTcWxT +dGF0ZW1lbnQgU3FsUHJlZml4Oj1TcWxQcmVmaXgsIFNxbFN1ZmZpeDo9U3FsU3Vm +Zml4LCBfDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25kaXRp +b25QcmVmaXg6PSIgV2hlcmUgIiwgSWdub3JlU3FsUHJlU3VmZml4SWZFbXB0eUZp +bHRlcjo9SWdub3JlSWZTdWJTZWxlY3RIYXNOb0NyaXRlcmlhDQogICBDb25kaXRp +b25Hcm91cHMuQWRkIE5ld0J1aWxkZXINCiAgIA0KICAgU2V0IEFkZFN1YlNlbGVj +dENyaXRlcmlhID0gTmV3QnVpbGRlcg0KICAgDQpFbmQgRnVuY3Rpb24NCg0KJy0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBGdW5jdGlv +bjogQWRkRXhpc3RzQ3JpdGVyaWENCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0NCicNCicgTmV3IGZpbHRlciBjb25kaXRpb24gZ3JvdXAg +Zm9yIGEgZXhpdHMgc3ViIHNlbGVjdCAtIGUuZy4gKCBhID0gMSBhbmQgZXhpc3Rz +IChzZWxlY3QgKiBmcm9tIHRhYjEyMyB3aGVyZSB0ID0gYSBhbmQgeSA9IDEyMykg +KQ0KJw0KJyBQYXJhbWV0ZXJzOg0KJw0KJyAgICAgU2VsZWN0RnJvbVRleHQgLSBT +cWwgdGV4dCBmb3Igc3ViIHNlbGVjdCAod2l0aG91dCB3aGVyZSwgZXhjZXB0IFVz +ZVdoZXJlUmVwbGFjZW1lbnRUZXh0SW5Gcm9tVGV4dCBpcyB1c2VkKQ0KJyAgICAg +SWdub3JlSWZFeGlzdHNTdGF0ZW1lbnRIYXNOb0NyaXRlcmlhIC0gVHJ1ZSA9IEln +bm9yZSBzdWJzZWxlY3QgY3JpdGVyaW9uIGlmIG5vIGZpbHRlciB2YWx1ZXMgd2Vy +ZSB0cmFuc2ZlcnJlZA0KJyAgICAgU3ViU2VsZWN0Q29uY2F0T3BlcmF0b3IgLSBb +U1FMX0FuZCAoZGVmYXVsdCksIFNRTF9PciwgU1FMX0NvbW1hU2VwYXJhdG9yXSAu +LiB2YWxpZCB3aXRoaW4gdGhlIG5ldyBncm91cA0KJyAgICAgVXNlTm90RXhpc3Rz +IC0gdXNlIG5vdCBleGlzdHMgKC4uKTogZGVmYXVsdDogZmFsc2UgPSBleGlzdHMg +KC4uLikNCicNCicgUmV0dXJuczoNCicNCicgICAgIEZpbHRlclN0cmluZ0J1aWxk +ZXIgaW5zdGFuY2UgZm9yIG5ldyBleGlzdHMgZ3JvdXANCicNCictLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NClB1YmxpYyBGdW5jdGlvbiBB +ZGRFeGlzdHNDcml0ZXJpYSggXw0KICAgICAgICAgICAgICAgICAgICAgICAgQnlW +YWwgU2VsZWN0RnJvbVRleHQgQXMgU3RyaW5nLCBfDQogICAgICAgICAgICAgICBP +cHRpb25hbCBCeVZhbCBJZ25vcmVJZkV4aXN0c1N0YXRlbWVudEhhc05vQ3JpdGVy +aWEgQXMgQm9vbGVhbiA9IEZhbHNlLCBfDQogICAgICAgICAgICAgICBPcHRpb25h +bCBCeVZhbCBTdWJTZWxlY3RDb25jYXRPcGVyYXRvciBBcyBTcWxMb2dpY2FsT3Bl +cmF0b3IgPSBTcWxMb2dpY2FsT3BlcmF0b3IuU1FMX0FuZCwgXw0KICAgICAgICAg +ICAgICAgT3B0aW9uYWwgQnlWYWwgVXNlTm90RXhpc3RzIEFzIEJvb2xlYW4gPSBG +YWxzZSwgXw0KICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgVXNlV2hlcmVS +ZXBsYWNlbWVudFRleHRJbkZyb21UZXh0IEFzIEJvb2xlYW4gPSBGYWxzZSBfDQog +ICAgICApIEFzIEZpbHRlclN0cmluZ0J1aWxkZXINCg0KICAgRGltIE5ld0J1aWxk +ZXIgQXMgRmlsdGVyU3RyaW5nQnVpbGRlcg0KICAgRGltIEV4aXN0c1NxbFByZWZp +eCBBcyBTdHJpbmcNCiAgIERpbSBXaGVyZVJlcGxhY2VtZW50UG9zIEFzIExvbmcN +CiAgIERpbSBFeGlzdHNTcWxTdWZmaXggQXMgU3RyaW5nDQogICANCiAgIEV4aXN0 +c1NxbFByZWZpeCA9ICJFeGlzdHMgKCINCiAgIElmIFVzZU5vdEV4aXN0cyBUaGVu +IEV4aXN0c1NxbFByZWZpeCA9ICJOb3QgIiAmIEV4aXN0c1NxbFByZWZpeA0KDQog +ICBJZiBVc2VXaGVyZVJlcGxhY2VtZW50VGV4dEluRnJvbVRleHQgVGhlbg0KICAg +ICAgV2hlcmVSZXBsYWNlbWVudFBvcyA9IEluU3RyKDEsIFNlbGVjdEZyb21UZXh0 +LCBXaGVyZVJlcGxhY2VtZW50VGV4dCwgdmJUZXh0Q29tcGFyZSkNCiAgIEVuZCBJ +Zg0KDQogICBJZiBXaGVyZVJlcGxhY2VtZW50UG9zID4gMCBUaGVuDQogICAgICBF +eGlzdHNTcWxTdWZmaXggPSAiICIgJiBUcmltJChNaWQkKFNlbGVjdEZyb21UZXh0 +LCBXaGVyZVJlcGxhY2VtZW50UG9zICsgTGVuKFdoZXJlUmVwbGFjZW1lbnRUZXh0 +KSkpICYgIikiDQogICAgICBTZWxlY3RGcm9tVGV4dCA9IFRyaW0kKExlZnQoU2Vs +ZWN0RnJvbVRleHQsIFdoZXJlUmVwbGFjZW1lbnRQb3MgLSAxKSkNCiAgIEVsc2UN +CiAgICAgIEV4aXN0c1NxbFN1ZmZpeCA9ICIpIg0KICAgRW5kIElmDQogICANCiAg +IFNldCBOZXdCdWlsZGVyID0gTmV3IEZpbHRlclN0cmluZ0J1aWxkZXINCiAgIE5l +d0J1aWxkZXIuRGVmYXVsdENvbmNhdE9wZXJhdG9yID0gU3ViU2VsZWN0Q29uY2F0 +T3BlcmF0b3INCiAgIFNldCBOZXdCdWlsZGVyLlNxbFRvb2wgPSBtX1NxbFRvb2wN +Cg0KICAgTmV3QnVpbGRlci5Db25maWdTcWxTdGF0ZW1lbnQgU3FsUHJlZml4Oj1F +eGlzdHNTcWxQcmVmaXggJiBTZWxlY3RGcm9tVGV4dCwgXw0KICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgU3FsU3VmZml4Oj1FeGlzdHNTcWxTdWZmaXgs +IENvbmRpdGlvblByZWZpeDo9IiBXaGVyZSAiLCBJZ25vcmVTcWxQcmVTdWZmaXhJ +ZkVtcHR5RmlsdGVyOj1JZ25vcmVJZkV4aXN0c1N0YXRlbWVudEhhc05vQ3JpdGVy +aWENCg0KICAgQ29uZGl0aW9uR3JvdXBzLkFkZCBOZXdCdWlsZGVyDQoNCiAgIFNl +dCBBZGRFeGlzdHNDcml0ZXJpYSA9IE5ld0J1aWxkZXINCiAgIA0KRW5kIEZ1bmN0 +aW9uDQoNCicjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQonIEdy +b3VwOiBPdXRwdXQNCg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLQ0KJyBGdW5jdGlvbjogVG9TdHJpbmcNCictLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicgT3V0cHV0IGNyaXRlcmlhIHRv +IFN0cmluZw0KJw0KJyBQYXJhbWV0ZXJzOg0KJw0KJyAgICAgQ29uY2F0T3BlcmF0 +b3IgLSBbU1FMX0FuZCAoZGVmYXVsdCksIFNRTF9PciwgU1FMX0NvbW1hU2VwYXJh +dG9yXQ0KJyAgICAgSWdub3JlRHVwbGljYXRlRmlsdGVycyAtIERvIG5vdCBvdXRw +dXQgZHVwbGljYXRlIGZpbHRlciBjcml0ZXJpYQ0KJw0KJyBSZXR1cm5zOg0KJw0K +JyAgICAgQ3JpdGVyaWEvZmlsdGVyIHN0cmluZw0KJw0KJy0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIEZ1bmN0aW9uIFRvU3Ry +aW5nKE9wdGlvbmFsIEJ5VmFsIENvbmNhdE9wZXJhdG9yIEFzIFNxbExvZ2ljYWxP +cGVyYXRvciA9IFNxbExvZ2ljYWxPcGVyYXRvci5bX1NRTF9EZWZhdWx0XSwgXw0K +ICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsIEJ5VmFsIElnbm9yZUR1 +cGxpY2F0ZUZpbHRlcnMgQXMgQm9vbGVhbiA9IEZhbHNlKSBBcyBTdHJpbmcNCiAg +IA0KICAgRGltIEZpbHRlclN0cmluZyBBcyBTdHJpbmcNCiAgIERpbSBJdGVtUHJl +Zml4IEFzIFN0cmluZw0KICAgRGltIEl0ZW1TdWZmaXggQXMgU3RyaW5nDQoNCiAg +IElmIENvbmNhdE9wZXJhdG9yID0gU3FsTG9naWNhbE9wZXJhdG9yLltfU1FMX0Rl +ZmF1bHRdIFRoZW4NCiAgICAgIENvbmNhdE9wZXJhdG9yID0gRGVmYXVsdENvbmNh +dE9wZXJhdG9yDQogICBFbmQgSWYNCiAgIA0KICAgSWYgQ29uY2F0T3BlcmF0b3Ig +PD4gU1FMX0NvbW1hU2VwYXJhdG9yIFRoZW4NCiAgICAgIEl0ZW1QcmVmaXggPSAi +KCINCiAgICAgIEl0ZW1TdWZmaXggPSAiKSINCiAgIEVuZCBJZg0KICAgDQogICBG +aWx0ZXJTdHJpbmcgPSBtX0l0ZW1zLlRvU3RyaW5nKEdldENvbmNhdE9wZXJhdG9y +U3RyaW5nKENvbmNhdE9wZXJhdG9yKSwgSXRlbVByZWZpeCwgSXRlbVN1ZmZpeCwg +LCBJZ25vcmVEdXBsaWNhdGVGaWx0ZXJzKQ0KICAgRmlsdGVyU3RyaW5nID0gQXBw +ZW5kRmlsdGVyR3JvdXBzU3RyaW5nKEZpbHRlclN0cmluZywgQ29uY2F0T3BlcmF0 +b3IsIElnbm9yZUR1cGxpY2F0ZUZpbHRlcnMpDQogICBJZiBMZW4oRmlsdGVyU3Ry +aW5nKSA+IDAgVGhlbg0KICAgICAgRmlsdGVyU3RyaW5nID0gbV9Db25kaXRpb25Q +cmVmaXggJiBGaWx0ZXJTdHJpbmcNCiAgIEVuZCBJZg0KICAgDQogICBJZiBtX0ln +bm9yZVNxbFByZVN1ZmZpeElmRW1wdHlGaWx0ZXIgVGhlbg0KICAgSWYgTGVuKEZp +bHRlclN0cmluZykgPSAwIFRoZW4NCiAgICAgIFRvU3RyaW5nID0gdmJOdWxsU3Ry +aW5nDQogICAgICBFeGl0IEZ1bmN0aW9uDQogICBFbmQgSWYNCiAgIEVuZCBJZg0K +ICAgDQogICBUb1N0cmluZyA9IG1fU3FsUHJlZml4ICYgRmlsdGVyU3RyaW5nICYg +bV9TcWxTdWZmaXgNCiAgIA0KRW5kIEZ1bmN0aW9uDQoNClByaXZhdGUgRnVuY3Rp +b24gR2V0Q29uY2F0T3BlcmF0b3JTdHJpbmcoQnlWYWwgQ29uY2F0T3BlcmF0b3Ig +QXMgU3FsTG9naWNhbE9wZXJhdG9yKSBBcyBTdHJpbmcNCg0KICAgU2VsZWN0IENh +c2UgQ29uY2F0T3BlcmF0b3INCiAgICAgIENhc2UgU3FsTG9naWNhbE9wZXJhdG9y +LlNRTF9BbmQNCiAgICAgICAgIEdldENvbmNhdE9wZXJhdG9yU3RyaW5nID0gIiBB +bmQgIg0KICAgICAgQ2FzZSBTcWxMb2dpY2FsT3BlcmF0b3IuU1FMX09yDQogICAg +ICAgICBHZXRDb25jYXRPcGVyYXRvclN0cmluZyA9ICIgT3IgIg0KICAgICAgQ2Fz +ZSBTcWxMb2dpY2FsT3BlcmF0b3IuU1FMX0NvbW1hU2VwYXJhdG9yDQogICAgICAg +ICBHZXRDb25jYXRPcGVyYXRvclN0cmluZyA9ICIsICINCiAgICAgIENhc2UgRWxz +ZQ0KICAgICAgICAgDQogICBFbmQgU2VsZWN0DQogDQpFbmQgRnVuY3Rpb24NCg0K +UHJpdmF0ZSBQcm9wZXJ0eSBHZXQgQ29uZGl0aW9uR3JvdXBzKCkgQXMgQ29sbGVj +dGlvbg0KICAgSWYgbV9Db25kaXRpb25Hcm91cHMgSXMgTm90aGluZyBUaGVuDQog +ICAgICBTZXQgbV9Db25kaXRpb25Hcm91cHMgPSBOZXcgQ29sbGVjdGlvbg0KICAg +RW5kIElmDQogICBTZXQgQ29uZGl0aW9uR3JvdXBzID0gbV9Db25kaXRpb25Hcm91 +cHMNCkVuZCBQcm9wZXJ0eQ0KDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tDQonIFByb3BlcnR5OiBXaGVyZVJlcGxhY2VtZW50VGV4dFBs +YWNlaG9sZGVyDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tDQonDQonIFJldHVybnMgdGhlIHBsYWNlaG9sZGVyIHRleHQgdXNlZCBpbiBT +UUwgc3Vic2VsZWN0cyB0byBkeW5hbWljYWxseSBpbnNlcnQgdGhlIFdIRVJFIGNv +bmRpdGlvbi4NCicgVXNlZCBpbiBBZGRTdWJTZWxlY3RDcml0ZXJpYSBhbmQgQWRk +RXhpc3RzQ3JpdGVyaWEgdG8gcmVwbGFjZSAiW1doZXJlU3RhdGVtZW50XSIgaW4g +dGhlIFNRTCB0ZXh0DQonIHdpdGggdGhlIGFjdHVhbCBnZW5lcmF0ZWQgZmlsdGVy +IGNvbmRpdGlvbi4NCicNCicgRXhhbXBsZToNCicgICBTRUxFQ1QgLi4uIEZST00g +Li4uIFtXaGVyZVN0YXRlbWVudF0gLi4uDQonDQonLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpQdWJsaWMgUHJvcGVydHkgR2V0IFdoZXJl +UmVwbGFjZW1lbnRUZXh0UGxhY2Vob2xkZXIoKSBBcyBTdHJpbmcNCiAgICBXaGVy +ZVJlcGxhY2VtZW50VGV4dFBsYWNlaG9sZGVyID0gV2hlcmVSZXBsYWNlbWVudFRl +eHQNCkVuZCBQcm9wZXJ0eQ== + + 20250609094839 + data/FilterStringBuilder.cls + + + SqlTools + VkVSU0lPTiAxLjAgQ0xBU1MNCkJFR0lODQogIE11bHRpVXNlID0gLTEgICdUcnVl +DQpFTkQNCkF0dHJpYnV0ZSBWQl9OYW1lID0gIlNxbFRvb2xzIg0KQXR0cmlidXRl +IFZCX0dsb2JhbE5hbWVTcGFjZSA9IEZhbHNlDQpBdHRyaWJ1dGUgVkJfQ3JlYXRh +YmxlID0gRmFsc2UNCkF0dHJpYnV0ZSBWQl9QcmVkZWNsYXJlZElkID0gVHJ1ZQ0K +QXR0cmlidXRlIFZCX0V4cG9zZWQgPSBGYWxzZQ0KJy0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBDbGFzczogZGF0YS5zcWwuU3FsVG9v +bHMNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicN +CicgRnVuY3Rpb25zIHRvIGJ1aWxkIHNxbCBzdHJpbmdzDQonDQonIEF1dGhvcjoN +CicgICAgIEpvc2VmIFBvZXR6bA0KJw0KJyBSZW1hcmtzOg0KJyAgICAgIkF0dHJp +YnV0ZSBWQl9QcmVkZWNsYXJlZElkID0gVHJ1ZSIgdG8gZW5hYmxlIHVzaW5nIFNx +bFRvb2xzIHdpdGhvdXQgZXhwbGljaXQgaW5zdGFudGlhdGlvbi4NCicNCicgV2Fy +bmluZzoNCicNCid8ICAgIERvbid0IGZvcmdldCB0byBzZXQgcGFyYW1ldGVycyBm +b3IgZGF0ZSBmb3JtYXQsIGJvb2xlYW4gYW5kIHdpbGRjYXJkIGZvciB0aGUgREJN +Uy4NCicNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0N +Cg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJzxj +b2RlbGliPg0KJyAgPGZpbGU+ZGF0YS9TcWxUb29scy5jbHM8L2ZpbGU+DQonICA8 +bGljZW5zZT5fY29kZWxpYi9saWNlbnNlLmJhczwvbGljZW5zZT4NCicgIDxyZXBs +YWNlPmRhdGEvU3FsVG9vbHMuYmFzPC9yZXBsYWNlPg0KJyAgPHRlc3Q+X3Rlc3Qv +ZGF0YS9TcWxUb29sc1Rlc3RzLmNsczwvdGVzdD4NCicgIDx0ZXN0Pl90ZXN0L2Rh +dGEvU3FsVG9vbHNCdWlsZENyaXRlcmlhVGVzdHMuY2xzPC90ZXN0Pg0KJzwvY29k +ZWxpYj4NCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0N +CicNCk9wdGlvbiBDb21wYXJlIFRleHQNCk9wdGlvbiBFeHBsaWNpdA0KDQpQcml2 +YXRlIEVudW0gU3FsVG9vbHNFcnJvck51bWJlcnMNCiAgIEVSUk5SX05PQ09ORklH +ID0gdmJPYmplY3RFcnJvciArIDENCkVuZCBFbnVtDQoNCicgRGVmYXVsdCB2YWx1 +ZXMgZm9yIG1ldGhvZCBwYXJhbWV0ZXJzDQpQcml2YXRlIENvbnN0IFNRTF9ERUZB +VUxUX1RFWFRERUxJTUlURVIgQXMgU3RyaW5nID0gIiciDQpQcml2YXRlIENvbnN0 +IFNRTF9ERUZBVUxUX0RBVEVGT1JNQVQgQXMgU3RyaW5nID0gIiIgICAgICcgIiIg +PT4gU3FsRGF0ZUZvcm1hdCBwcm9wZXJ0eSB3aWxsIHVzZS4NCiAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyBU +byBkaXNhYmxlLCBlbnRlciB2YWx1ZSAoZS5nLiAiXCN5eXl5LW1tXC1kZFwjIiks +DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICcgdGhlbiB0aGlzIHZhbHVlIHdpbGwgYmUgdXNlZCBhcyB0aGUg +ZGVmYXVsdCBlbnRyeS4NClByaXZhdGUgQ29uc3QgU1FMX0RFRkFVTFRfQk9PTFRS +VUVTVFJJTkcgQXMgU3RyaW5nID0gIiIgJyAiIiA9PiBTcWxCb29sZWFuVHJ1ZVN0 +cmluZyBpcyB1c2VkLg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAnIEVudGVyIHZhbHVlIHRvIGRpc2FibGUg +KGUuZy4gIlRydWUgb3IgMSIpDQpQcml2YXRlIENvbnN0IFNRTF9ERUZBVUxUX1dJ +TERDQVJEIEFzIFN0cmluZyA9ICIlIiAgICAgICcgJSA9IGRlZmF1bHQgdmFsdWUs +DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICcgc2V0IHJlcXVpcmVkIHZhcmlhdGlvbnMgdmlhIFNxbFdpbGRD +YXJkU3RyaW5nDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICANClByaXZhdGUgQ29uc3QgU3FsQW5kQ29uY2F0U3RyaW5n +IEFzIFN0cmluZyA9ICIgQW5kICINClByaXZhdGUgQ29uc3QgU3FsT3JDb25jYXRT +dHJpbmcgQXMgU3RyaW5nID0gIiBPciAiDQoNClByaXZhdGUgVHlwZSBTcWxGb3Jt +YXRTZXR0aW5ncw0KICAgU3FsRGF0ZUZvcm1hdCBBcyBTdHJpbmcNCiAgIFNxbEJv +b2xlYW5UcnVlU3RyaW5nIEFzIFN0cmluZw0KICAgU3FsV2lsZENhcmRTdHJpbmcg +QXMgU3RyaW5nDQpFbmQgVHlwZQ0KDQpQcml2YXRlIG1fU3FsRm9ybWF0IEFzIFNx +bEZvcm1hdFNldHRpbmdzDQoNClByaXZhdGUgQ29uc3QgUmVzdWx0VGV4dElmTnVs +bCBBcyBTdHJpbmcgPSAiTnVsbCINCg0KUHVibGljIEVudW0gU3FsUmVsYXRpb25h +bE9wZXJhdG9ycw0KICAgW19JZ25vcmVBbGxdID0gJkg4MDAwMDAwMA0KICAgU1FM +X05vdCA9IDENCiAgIFNRTF9FcXVhbCA9IDINCiAgIFNRTF9MZXNzVGhhbiA9IDQN +CiAgIFNRTF9HcmVhdGVyVGhhbiA9IDgNCiAgIFNRTF9MaWtlID0gMjU2DQogICBT +UUxfQmV0d2VlbiA9IDUxMg0KICAgU1FMX0luID0gMTAyNA0KICAgU1FMX0FkZF9X +aWxkQ2FyZFN1ZmZpeCA9IDIwNDgNCiAgIFNRTF9BZGRfV2lsZENhcmRQcmVmaXgg +PSA0MDk2DQogICBTUUxfU3BsaXRWYWx1ZVRvQXJyYXkgPSA4MTkyDQogICBTUUxf +QWxsb3dTcWxEaXJlY3QgPSAxNjM4NA0KICAgU1FMX1VzZUxpa2VCZWhhdmlvciA9 +IDY1NTM2DQpFbmQgRW51bQ0KDQpQdWJsaWMgRW51bSBTcWxGaWVsZERhdGFUeXBl +DQogICBTUUxfQm9vbGVhbiA9IDENCiAgIFNRTF9OdW1lcmljID0gMg0KICAgU1FM +X1RleHQgPSAzDQogICBTUUxfRGF0ZSA9IDQNCkVuZCBFbnVtDQoNClB1YmxpYyBF +bnVtIFNxbExvZ2ljYWxPcGVyYXRvcg0KICAgW19TUUxfRGVmYXVsdF0gPSAwDQog +ICBTUUxfQW5kID0gMQ0KICAgU1FMX09yID0gMg0KICAgU1FMX0NvbW1hU2VwYXJh +dG9yID0gMw0KRW5kIEVudW0NCg0KUHVibGljIEVudW0gU3FsRGlhbGVjdA0KICAg +U1FMX0N1c3RvbSA9IDANCiAgIFNRTF9EQU8gPSAxDQogICBTUUxfVFNRTCA9IDIN +CkVuZCBFbnVtDQoNCicjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMj +DQonIEdyb3VwOiBDbGFzcyBzdXBwb3J0DQoNCictLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgRnVuY3Rpb246IFNlbGVjdERpYWxlY3QN +CictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicg +Q3JlYXRlIGEgbmV3IGluc3RhbmNlIHdpdGggYmFzaWMgc2V0dGluZ3Mgb2YgdGhl +IHNlbGVjdGVkIGRpYWxlY3QNCicNCicgUGFyYW1ldGVyczoNCicNCicgICAgIFVz +ZURpYWxlY3QgLSB1c2Ugc2V0dGluZyBvZiBkaWFsZWN0IChhcyBiYXNlKQ0KJyAg +ICAgTmV3U3FsRGF0ZUZvcm1hdCAtIHVzZSB0aGlzIGRhdGUgZm9ybWF0IGluc3Rl +YWQgb2YgYmFzZSBkaWFsZWN0DQonICAgICBOZXdTcWxCb29sZWFuVHJ1ZVN0cmlu +ZyAtIHVzZSB0aGlzIHRleHQgZm9yIHRydWUgaW5zdGVhZCBvZiBiYXNlIGRpYWxl +Y3QNCicgICAgIE5ld1NxbFdpbGRDYXJkU3RyaW5nIC0gdXNlIHRoaXMgd2lsZGNh +cmQgc3RyaW5nIGluc3RlYWQgb2YgYmFzZSBkaWFsZWN0DQonDQonIFJldHVybnM6 +DQonDQonICAgICBTcWxUb29scyBpbnN0YW5jZSB3aXRoIGNvbmZpZyBmb3JtIGJh +c2UNCicNCicgU2VlIEFsc286DQonICAgICBOZXdJbnN0YW5jZQ0KJw0KJy0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIEZ1bmN0 +aW9uIEZyb21EaWFsZWN0KEJ5VmFsIFVzZURpYWxlY3QgQXMgU3FsRGlhbGVjdCwg +Xw0KICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgTmV3U3FsRGF0 +ZUZvcm1hdCBBcyBTdHJpbmcgPSBTUUxfREVGQVVMVF9EQVRFRk9STUFULCBfDQog +ICAgICAgICAgICAgICAgICAgICBPcHRpb25hbCBCeVZhbCBOZXdTcWxCb29sZWFu +VHJ1ZVN0cmluZyBBcyBTdHJpbmcgPSBTUUxfREVGQVVMVF9CT09MVFJVRVNUUklO +RywgXw0KICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgTmV3U3Fs +V2lsZENhcmRTdHJpbmcgQXMgU3RyaW5nID0gU1FMX0RFRkFVTFRfV0lMRENBUkQp +IEFzIFNxbFRvb2xzDQoNCiAgIERpbSBOZXdTbHFUb29sc0luc3RhbmNlIEFzIFNx +bFRvb2xzDQogICANCiAgIFNlbGVjdCBDYXNlIFVzZURpYWxlY3QNCiAgICAgIENh +c2UgU3FsRGlhbGVjdC5TUUxfREFPDQogICAgICAgICBTZXQgTmV3U2xxVG9vbHNJ +bnN0YW5jZSA9IE1lLkRBTw0KICAgICAgQ2FzZSBTcWxEaWFsZWN0LlNRTF9UU1FM +DQogICAgICAgICBTZXQgTmV3U2xxVG9vbHNJbnN0YW5jZSA9IE1lLlRTcWwNCiAg +ICAgIENhc2UgRWxzZQ0KICAgICAgICAgU2V0IE5ld1NscVRvb2xzSW5zdGFuY2Ug +PSBNZS5DbG9uZQ0KICAgRW5kIFNlbGVjdA0KDQogICBJZiBMZW4oTmV3U3FsRGF0 +ZUZvcm1hdCkgPiAwIFRoZW4gTmV3U2xxVG9vbHNJbnN0YW5jZS5TcWxEYXRlRm9y +bWF0ID0gTmV3U3FsRGF0ZUZvcm1hdA0KICAgSWYgTGVuKE5ld1NxbEJvb2xlYW5U +cnVlU3RyaW5nKSA+IDAgVGhlbiBOZXdTbHFUb29sc0luc3RhbmNlLlNxbEJvb2xl +YW5UcnVlU3RyaW5nID0gTmV3U3FsQm9vbGVhblRydWVTdHJpbmcNCiAgIElmIExl +bihOZXdTcWxXaWxkQ2FyZFN0cmluZykgPiAwIFRoZW4gTmV3U2xxVG9vbHNJbnN0 +YW5jZS5TcWxXaWxkQ2FyZFN0cmluZyA9IE5ld1NxbFdpbGRDYXJkU3RyaW5nDQoN +CiAgIFNldCBGcm9tRGlhbGVjdCA9IE5ld1NscVRvb2xzSW5zdGFuY2UNCg0KRW5k +IEZ1bmN0aW9uDQoNCg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLQ0KJyBGdW5jdGlvbjogQ2xvbmUNCictLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicgQ3JlYXRlIGEgbmV3IGluc3RhbmNl +IHdpdGggYmFzaWMgc2V0dGluZ3Mgb2YgdGhlIGN1cnJlbnQgaW5zdGFuY2UuDQon +DQonIFBhcmFtZXRlcnM6DQonDQonICAgICBOZXdTcWxEYXRlRm9ybWF0IC0gdXNl +IHRoaXMgZGF0ZSBmb3JtYXQgaW5zdGVhZCBvZiBiYXNlIGluc3RhbmNlDQonICAg +ICBOZXdTcWxCb29sZWFuVHJ1ZVN0cmluZyAtIHVzZSB0aGlzIHRleHQgZm9yIHRy +dWUgaW5zdGVhZCBvZiBiYXNlIGluc3RhbmNlDQonICAgICBOZXdTcWxXaWxkQ2Fy +ZFN0cmluZyAtIHVzZSB0aGlzIHdpbGRjYXJkIHN0cmluZyBpbnN0ZWFkIG9mIGJh +c2UgaW5zdGFuY2UNCicNCicgUmV0dXJuczoNCicNCicgICAgIFNxbFRvb2xzIGlu +c3RhbmNlIHdpdGggY29uZmlnIGZvcm0gYmFzZQ0KJw0KJyBTZWUgQWxzbzoNCicg +ICAgIE5ld0luc3RhbmNlDQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tDQpQdWJsaWMgRnVuY3Rpb24gQ2xvbmUoT3B0aW9uYWwgQnlW +YWwgTmV3U3FsRGF0ZUZvcm1hdCBBcyBTdHJpbmcgPSBTUUxfREVGQVVMVF9EQVRF +Rk9STUFULCBfDQogICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwg +TmV3U3FsQm9vbGVhblRydWVTdHJpbmcgQXMgU3RyaW5nID0gU1FMX0RFRkFVTFRf +Qk9PTFRSVUVTVFJJTkcsIF8NCiAgICAgICAgICAgICAgICAgICAgICBPcHRpb25h +bCBCeVZhbCBOZXdTcWxXaWxkQ2FyZFN0cmluZyBBcyBTdHJpbmcgPSBTUUxfREVG +QVVMVF9XSUxEQ0FSRCkgQXMgU3FsVG9vbHMNCg0KICAgSWYgTGVuKE5ld1NxbERh +dGVGb3JtYXQpID0gMCBUaGVuIE5ld1NxbERhdGVGb3JtYXQgPSBNZS5TcWxEYXRl +Rm9ybWF0DQogICBJZiBMZW4oTmV3U3FsQm9vbGVhblRydWVTdHJpbmcpID0gMCBU +aGVuIE5ld1NxbEJvb2xlYW5UcnVlU3RyaW5nID0gTWUuU3FsQm9vbGVhblRydWVT +dHJpbmcNCiAgIElmIExlbihOZXdTcWxXaWxkQ2FyZFN0cmluZykgPSAwIFRoZW4g +TmV3U3FsV2lsZENhcmRTdHJpbmcgPSBNZS5TcWxXaWxkQ2FyZFN0cmluZw0KDQog +ICBTZXQgQ2xvbmUgPSBOZXdJbnN0YW5jZShOZXdTcWxEYXRlRm9ybWF0LCBOZXdT +cWxCb29sZWFuVHJ1ZVN0cmluZywgTmV3U3FsV2lsZENhcmRTdHJpbmcpDQoNCkVu +ZCBGdW5jdGlvbg0KDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tDQonIEZ1bmN0aW9uOiBOZXdJbnN0YW5jZQ0KJy0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBDcmVhdGUgYSBuZXcgaW5z +dGFuY2UNCicNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0NClB1YmxpYyBGdW5jdGlvbiBOZXdJbnN0YW5jZShCeVZhbCBOZXdTcWxEYXRl +Rm9ybWF0IEFzIFN0cmluZywgXw0KICAgICAgICAgICAgICAgICAgICAgICAgICAg +IEJ5VmFsIE5ld1NxbEJvb2xlYW5UcnVlU3RyaW5nIEFzIFN0cmluZywgXw0KICAg +ICAgICAgICAgICAgICAgICAgICAgICAgIEJ5VmFsIE5ld1NxbFdpbGRDYXJkU3Ry +aW5nIEFzIFN0cmluZykgQXMgU3FsVG9vbHMNCiAgIA0KICAgRGltIE5ld0luc3Qg +QXMgU3FsVG9vbHMNCg0KICAgU2V0IE5ld0luc3QgPSBOZXcgU3FsVG9vbHMNCiAg +IFdpdGggTmV3SW5zdA0KICAgICAgLlNxbERhdGVGb3JtYXQgPSBOZXdTcWxEYXRl +Rm9ybWF0DQogICAgICAuU3FsQm9vbGVhblRydWVTdHJpbmcgPSBOZXdTcWxCb29s +ZWFuVHJ1ZVN0cmluZw0KICAgICAgLlNxbFdpbGRDYXJkU3RyaW5nID0gTmV3U3Fs +V2lsZENhcmRTdHJpbmcNCiAgIEVuZCBXaXRoDQoNCiAgIFNldCBOZXdJbnN0YW5j +ZSA9IE5ld0luc3QNCg0KRW5kIEZ1bmN0aW9uDQoNCictLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgRnVuY3Rpb246IEluaXRTcWxEaWFs +ZWN0DQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQon +DQonIENvbmZpZyBzcWwgdGV4dCBvdXRwdXQgZm9ybWF0IGZvciBzcGVjaWZpYyBz +cWwgZGlhbGVjdA0KJw0KJyBQYXJhbWV0ZXJzOg0KJw0KJyAgICAgU3FsRGF0ZUZv +cm1hdCAtIG91dHB1dCBzdHJpbmcgZm9ybWF0IGZvciBkYXRlIHZhbHVlcw0KJyAg +ICAgU3FsQm9vbGVhblRydWVTdHJpbmcgLSBvdXRwdXQgc3RyaW5nIGZvcm1hdCBm +b3IgYm9vbGVhbiB2YWx1ZXMNCicgICAgIFNxbFdpbGRDYXJkU3RyaW5nIC0gd2ls +ZGNhcmQgc3RyaW5nIChlLmcuICogLi4gZGFvLCAlIC4uIFQtU1FMKQ0KJw0KJy0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KRnJpZW5kIFN1 +YiBJbml0U3FsRGlhbGVjdChCeVZhbCBVc2VEaWFsZWN0IEFzIFNxbERpYWxlY3Qs +IF8NCiAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsIEJ5VmFsIE5ld1NxbERh +dGVGb3JtYXQgQXMgU3RyaW5nID0gU1FMX0RFRkFVTFRfREFURUZPUk1BVCwgXw0K +ICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgTmV3U3FsQm9vbGVh +blRydWVTdHJpbmcgQXMgU3RyaW5nID0gU1FMX0RFRkFVTFRfQk9PTFRSVUVTVFJJ +TkcsIF8NCiAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsIEJ5VmFsIE5ld1Nx +bFdpbGRDYXJkU3RyaW5nIEFzIFN0cmluZyA9IFNRTF9ERUZBVUxUX1dJTERDQVJE +KQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICBEaW0gU3FsRm9ybWF0 +IEFzIFNxbEZvcm1hdFNldHRpbmdzDQogICANCiAgIFNlbGVjdCBDYXNlIFVzZURp +YWxlY3QNCiAgICAgIENhc2UgU3FsRGlhbGVjdC5TUUxfREFPDQogICAgICAgICBT +cWxGb3JtYXQgPSBEYW9TcWxGb3JtYXQNCiAgICAgIENhc2UgU3FsRGlhbGVjdC5T +UUxfVFNRTA0KICAgICAgICAgU3FsRm9ybWF0ID0gVFNxbFNxbEZvcm1hdA0KICAg +ICAgQ2FzZSBFbHNlDQogICAgICAgICAnIHNldCBub3RoaW5nID0+IHVzZSBOZXdT +cWwqIHBhcmFtZXRlcg0KICAgRW5kIFNlbGVjdA0KDQogICBJZiBMZW4oTmV3U3Fs +RGF0ZUZvcm1hdCkgPiAwIFRoZW4gU3FsRm9ybWF0LlNxbERhdGVGb3JtYXQgPSBO +ZXdTcWxEYXRlRm9ybWF0DQogICBJZiBMZW4oTmV3U3FsQm9vbGVhblRydWVTdHJp +bmcpID4gMCBUaGVuIFNxbEZvcm1hdC5TcWxCb29sZWFuVHJ1ZVN0cmluZyA9IE5l +d1NxbEJvb2xlYW5UcnVlU3RyaW5nDQogICBJZiBMZW4oTmV3U3FsV2lsZENhcmRT +dHJpbmcpID4gMCBUaGVuIFNxbEZvcm1hdC5TcWxXaWxkQ2FyZFN0cmluZyA9IE5l +d1NxbFdpbGRDYXJkU3RyaW5nDQoNCiAgIEluaXRTcWxGb3JtYXQgU3FsRm9ybWF0 +LlNxbERhdGVGb3JtYXQsIFNxbEZvcm1hdC5TcWxCb29sZWFuVHJ1ZVN0cmluZywg +U3FsRm9ybWF0LlNxbFdpbGRDYXJkU3RyaW5nDQogICAgICAgICAgICAgICAgICAg +ICAgICAgICANCg0KRW5kIFN1Yg0KDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tDQonIEZ1bmN0aW9uOiBJbml0U3FsRm9ybWF0DQonLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonDQonIENvbmZp +ZyBzcWwgdGV4dCBvdXRwdXQgZm9ybWF0IGZvciBzcGVjaWZpYyBzcWwgZGlhbGVj +dA0KJw0KJyBQYXJhbWV0ZXJzOg0KJw0KJyAgICAgU3FsRGF0ZUZvcm1hdCAtIG91 +dHB1dCBzdHJpbmcgZm9ybWF0IGZvciBkYXRlIHZhbHVlcw0KJyAgICAgU3FsQm9v +bGVhblRydWVTdHJpbmcgLSBvdXRwdXQgc3RyaW5nIGZvcm1hdCBmb3IgYm9vbGVh +biB2YWx1ZXMNCicgICAgIFNxbFdpbGRDYXJkU3RyaW5nIC0gd2lsZGNhcmQgc3Ry +aW5nIChlLmcuICogLi4gZGFvLCAlIC4uIFQtU1FMKQ0KJw0KJy0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KRnJpZW5kIFN1YiBJbml0U3Fs +Rm9ybWF0KEJ5VmFsIFNxbERhdGVGb3JtYXQgQXMgU3RyaW5nLCBfDQogICAgICAg +ICAgICAgICAgICAgICAgICAgICBCeVZhbCBTcWxCb29sZWFuVHJ1ZVN0cmluZyBB +cyBTdHJpbmcsIF8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5VmFsIFNx +bFdpbGRDYXJkU3RyaW5nIEFzIFN0cmluZykNCiAgICAgICAgICAgICAgICAgICAg +ICAgICAgIA0KICAgTWUuU3FsRGF0ZUZvcm1hdCA9IFNxbERhdGVGb3JtYXQNCiAg +IE1lLlNxbEJvb2xlYW5UcnVlU3RyaW5nID0gU3FsQm9vbGVhblRydWVTdHJpbmcN +CiAgIE1lLlNxbFdpbGRDYXJkU3RyaW5nID0gU3FsV2lsZENhcmRTdHJpbmcNCg0K +RW5kIFN1Yg0KDQonIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0K +JyBHcm91cDogU1FMIGRpYWxlY3QgcHJlZmVyZW5jZXMNCg0KJy0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBQcm9wZXJ0eTogREFPDQon +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonDQonIFNx +bFRvb2xzIGluc3RhbmNlIGNvbmZpZ3VyZWQgZm9yIERBTy1TUUwgKEpldC9BQ0Up +DQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpQ +dWJsaWMgUHJvcGVydHkgR2V0IERBTygpIEFzIFNxbFRvb2xzDQogICBXaXRoIERh +b1NxbEZvcm1hdA0KICAgICAgU2V0IERBTyA9IE1lLk5ld0luc3RhbmNlKC5TcWxE +YXRlRm9ybWF0LCAuU3FsQm9vbGVhblRydWVTdHJpbmcsIC5TcWxXaWxkQ2FyZFN0 +cmluZykNCiAgIEVuZCBXaXRoDQpFbmQgUHJvcGVydHkNCg0KUHJpdmF0ZSBQcm9w +ZXJ0eSBHZXQgRGFvU3FsRm9ybWF0KCkgQXMgU3FsRm9ybWF0U2V0dGluZ3MNCg0K +ICAgRGltIFNxbEZvcm1hdCBBcyBTcWxGb3JtYXRTZXR0aW5ncw0KICAgDQogICBT +cWxGb3JtYXQuU3FsRGF0ZUZvcm1hdCA9ICJcI3l5eXktbW0tZGQgaGg6bm46c3Nc +IyINCiAgIFNxbEZvcm1hdC5TcWxCb29sZWFuVHJ1ZVN0cmluZyA9ICJUcnVlIg0K +ICAgU3FsRm9ybWF0LlNxbFdpbGRDYXJkU3RyaW5nID0gIioiDQogICANCiAgIERh +b1NxbEZvcm1hdCA9IFNxbEZvcm1hdA0KDQpFbmQgUHJvcGVydHkNCg0KJy0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBQcm9wZXJ0eTog +VFNxbA0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0K +Jw0KJyBTcWxUb29scyBpbnN0YW5jZSBjb25maWd1cmVkIGZvciBULVNRTA0KJw0K +Jy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGlj +IFByb3BlcnR5IEdldCBUU3FsKCkgQXMgU3FsVG9vbHMNCiAgIFdpdGggVFNxbFNx +bEZvcm1hdA0KICAgICAgU2V0IFRTcWwgPSBNZS5OZXdJbnN0YW5jZSguU3FsRGF0 +ZUZvcm1hdCwgLlNxbEJvb2xlYW5UcnVlU3RyaW5nLCAuU3FsV2lsZENhcmRTdHJp +bmcpDQogICBFbmQgV2l0aA0KRW5kIFByb3BlcnR5DQoNClByaXZhdGUgUHJvcGVy +dHkgR2V0IFRTcWxTcWxGb3JtYXQoKSBBcyBTcWxGb3JtYXRTZXR0aW5ncw0KDQog +ICBEaW0gU3FsRm9ybWF0IEFzIFNxbEZvcm1hdFNldHRpbmdzDQogICANCiAgIFNx +bEZvcm1hdC5TcWxEYXRlRm9ybWF0ID0gIid5eXl5bW1kZCBoaDpubjpzcyciDQog +ICBTcWxGb3JtYXQuU3FsQm9vbGVhblRydWVTdHJpbmcgPSAiMSINCiAgIFNxbEZv +cm1hdC5TcWxXaWxkQ2FyZFN0cmluZyA9ICIlIg0KICAgDQogICBUU3FsU3FsRm9y +bWF0ID0gU3FsRm9ybWF0DQoNCkVuZCBQcm9wZXJ0eQ0KDQonIENvbmZpZ3VyYXRp +b24gZm9yIFNRTCBkaWFsZWN0DQoNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0NCicgUHJvcGVydHk6IFNxbFdpbGRDYXJkU3RyaW5nDQon +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonDQonIFdp +bGRjYXJkIGNoYXJhY3RlciBmb3IgbGlrZQ0KJw0KJy0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIFByb3BlcnR5IEdldCBTcWxX +aWxkQ2FyZFN0cmluZygpIEFzIFN0cmluZw0KICAgSWYgTGVuKG1fU3FsRm9ybWF0 +LlNxbFdpbGRDYXJkU3RyaW5nKSA+IDAgVGhlbg0KICAgICAgU3FsV2lsZENhcmRT +dHJpbmcgPSBtX1NxbEZvcm1hdC5TcWxXaWxkQ2FyZFN0cmluZw0KICAgRWxzZQ0K +ICAgICAgU3FsV2lsZENhcmRTdHJpbmcgPSBTUUxfREVGQVVMVF9XSUxEQ0FSRA0K +ICAgRW5kIElmDQpFbmQgUHJvcGVydHkNCg0KUHVibGljIFByb3BlcnR5IExldCBT +cWxXaWxkQ2FyZFN0cmluZyhCeVZhbCBOZXdWYWx1ZSBBcyBTdHJpbmcpDQogICBt +X1NxbEZvcm1hdC5TcWxXaWxkQ2FyZFN0cmluZyA9IE5ld1ZhbHVlDQpFbmQgUHJv +cGVydHkNCg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LQ0KJyBQcm9wZXJ0eTogU3FsRGF0ZUZvcm1hdA0KJy0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBGb3JtYXQgZm9yIGRhdGUgdmFs +dWVzDQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +DQpQdWJsaWMgUHJvcGVydHkgR2V0IFNxbERhdGVGb3JtYXQoKSBBcyBTdHJpbmcN +CiAgIElmIExlbihtX1NxbEZvcm1hdC5TcWxEYXRlRm9ybWF0KSA+IDAgVGhlbg0K +ICAgICAgU3FsRGF0ZUZvcm1hdCA9IG1fU3FsRm9ybWF0LlNxbERhdGVGb3JtYXQN +CiAgIEVsc2UNCiAgICAgIFNxbERhdGVGb3JtYXQgPSBTUUxfREVGQVVMVF9EQVRF +Rk9STUFUDQogICBFbmQgSWYNCkVuZCBQcm9wZXJ0eQ0KDQpQdWJsaWMgUHJvcGVy +dHkgTGV0IFNxbERhdGVGb3JtYXQoQnlWYWwgTmV3VmFsdWUgQXMgU3RyaW5nKQ0K +ICAgbV9TcWxGb3JtYXQuU3FsRGF0ZUZvcm1hdCA9IE5ld1ZhbHVlDQpFbmQgUHJv +cGVydHkNCg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LQ0KJyBQcm9wZXJ0eTogU3FsQm9vbGVhblRydWVTdHJpbmcNCictLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicgQm9vbGVhbiBzdHJp +bmcgaW4gU1FMIHN0YXRlbWVudA0KJw0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIFByb3BlcnR5IEdldCBTcWxCb29sZWFu +VHJ1ZVN0cmluZygpIEFzIFN0cmluZw0KICAgSWYgTGVuKG1fU3FsRm9ybWF0LlNx +bEJvb2xlYW5UcnVlU3RyaW5nKSA+IDAgVGhlbg0KICAgICAgU3FsQm9vbGVhblRy +dWVTdHJpbmcgPSBtX1NxbEZvcm1hdC5TcWxCb29sZWFuVHJ1ZVN0cmluZw0KICAg +RWxzZQ0KICAgICAgU3FsQm9vbGVhblRydWVTdHJpbmcgPSBTUUxfREVGQVVMVF9C +T09MVFJVRVNUUklORw0KICAgRW5kIElmDQpFbmQgUHJvcGVydHkNCg0KUHVibGlj +IFByb3BlcnR5IExldCBTcWxCb29sZWFuVHJ1ZVN0cmluZyhCeVZhbCBOZXdWYWx1 +ZSBBcyBTdHJpbmcpDQogICBtX1NxbEZvcm1hdC5TcWxCb29sZWFuVHJ1ZVN0cmlu +ZyA9IE5ld1ZhbHVlDQpFbmQgUHJvcGVydHkNCg0KJyMjIyMjIyMjIyMjIyMjIyMj +IyMjIyMjIyMjIyMjIyMjIyMNCicgR3JvdXA6IEJ1aWxkQ3JpdGVyaWENCg0KJy0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBGdW5jdGlv +bjogQnVpbGRDcml0ZXJpYQ0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLQ0KJw0KJyBDcmVhdGUgU1FMIGNyaXRlcmlhIHN0cmluZw0KJw0K +JyBQYXJhbWV0ZXJzOg0KJyAgICAgRmllbGROYW1lICAgICAgICAgICAgLSBGaWVs +ZCBuYW1lIGluIHRoZSBkYXRhIHNvdXJjZSB0byBiZSBmaWx0ZXJlZA0KJyAgICAg +UmVsYXRpb25hbE9wZXJhdG9yICAgLSBSZWxhdGlvbmFsIG9wZXJhdG9yICg9LCA8 +PSwgZXRjLikNCicgICAgIEZpbHRlclZhbHVlICAgICAgICAgIC0gRmlsdGVyIHZh +bHVlIChjYW4gYmUgYSBzaW5nbGUgdmFsdWUgb3IgYW4gYXJyYXkgb2YgdmFsdWVz +KQ0KJyAgICAgRmlsdGVyVmFsdWUyICAgICAgICAgLSBPcHRpb25hbCAybmQgZmls +dGVyIHZhbHVlIChmb3IgQmV0d2VlbikNCicgICAgIElnbm9yZVZhbHVlICAgICAg +ICAgIC0gVGhlIHZhbHVlIGZvciB3aGljaCBubyBmaWx0ZXIgY29uZGl0aW9uIGlz +IHRvIGJlIGNyZWF0ZWQuIChBcnJheSB0cmFuc2ZlciBvZiB2YWx1ZXMgcG9zc2li +bGUpDQonDQonIFJldHVybnM6DQonICAgICBTUUwgY3JpdGVyaWEgc3RyaW5nDQon +DQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpQdWJs +aWMgRnVuY3Rpb24gQnVpbGRDcml0ZXJpYShCeVZhbCBGaWVsZE5hbWUgQXMgU3Ry +aW5nLCBCeVZhbCBGaWVsZERhdGFUeXBlIEFzIFNxbEZpZWxkRGF0YVR5cGUsIF8N +CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5VmFsIFJlbGF0aW9uYWxP +cGVyYXRvciBBcyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzLCBfDQogICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICBCeVZhbCBGaWx0ZXJWYWx1ZSBBcyBWYXJpYW50 +LCBfDQogICAgICAgICAgICAgICAgICAgICBPcHRpb25hbCBCeVZhbCBGaWx0ZXJW +YWx1ZTIgQXMgVmFyaWFudCA9IE51bGwsIF8NCiAgICAgICAgICAgICAgICAgICAg +IE9wdGlvbmFsIEJ5VmFsIElnbm9yZVZhbHVlIEFzIFZhcmlhbnQsIF8NCiAgICAg +ICAgICAgICAgICAgICAgIE9wdGlvbmFsIEJ5VmFsIERpc2FibGVJZ25vcmVOdWxs +VmFsdWUgQXMgQm9vbGVhbiA9IEZhbHNlKSBBcyBTdHJpbmcNCg0KICAgRGltIEZp +bHRlclZhbHVlU3RyaW5nIEFzIFN0cmluZw0KICAgRGltIE9wZXJhdG9yU3RyaW5n +IEFzIFN0cmluZw0KICAgRGltIENyaXRlcmlhIEFzIFN0cmluZw0KICAgDQogICBJ +ZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBbX0lnbm9yZUFsbF0pID0gW19JZ25v +cmVBbGxdIFRoZW4NCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0KICAg +DQogICBJZiBJc01pc3NpbmcoSWdub3JlVmFsdWUpIFRoZW4NCiAgICAgIElmIE5v +dCBEaXNhYmxlSWdub3JlTnVsbFZhbHVlIFRoZW4NCiAgICAgICAgIERpc2FibGVJ +Z25vcmVOdWxsVmFsdWUgPSBUcnVlDQogICAgICBFbmQgSWYNCiAgICAgIElnbm9y +ZVZhbHVlID0gTnVsbA0KICAgRW5kIElmDQogICANCiAgICcgU3BlY2lhbCBjYXNl +cyAocGFydCAxKToNCiAgIElmIE5vdCBJc0FycmF5KEZpbHRlclZhbHVlKSBUaGVu +DQogICANCiAgICAgIElmIEZpbHRlclZhbHVlID0gIntOVUxMfSIgT3IgRmlsdGVy +VmFsdWUgPSAie0xFRVJ9IiBPciBGaWx0ZXJWYWx1ZSA9ICJ7RU1QVFl9IiBUaGVu +DQogICAgICAgICBGaWx0ZXJWYWx1ZSA9IE51bGwNCiAgICAgICAgIERpc2FibGVJ +Z25vcmVOdWxsVmFsdWUgPSBUcnVlDQogICAgICBFbmQgSWYNCiAgICAgIA0KICAg +ICAgSWYgRmlsdGVyVmFsdWUyID0gIntOVUxMfSIgT3IgRmlsdGVyVmFsdWUyID0g +IntMRUVSfSIgT3IgRmlsdGVyVmFsdWUyID0gIntFTVBUWX0iIFRoZW4NCiAgICAg +ICAgIEZpbHRlclZhbHVlMiA9IE51bGwNCiAgICAgICAgIERpc2FibGVJZ25vcmVO +dWxsVmFsdWUgPSBUcnVlDQogICAgICBFbmQgSWYNCiAgICAgIA0KICAgICAgSWYg +KFJlbGF0aW9uYWxPcGVyYXRvciBBbmQgU1FMX0FsbG93U3FsRGlyZWN0KSA9IFNR +TF9BbGxvd1NxbERpcmVjdCBUaGVuDQogICAgICAgICBJZiBGaWx0ZXJWYWx1ZSBM +aWtlICJ7KkAqfSIgVGhlbiAnIElkZWUgdm9uIFVscmljaDogQW53ZW5kZXIgc2No +cmVpYnQgU1FMLUF1c2RydWNrDQogICAgICAgICAgICBDcml0ZXJpYSA9IFJlcGxh +Y2UoTWlkKEZpbHRlclZhbHVlLCAyLCBMZW4oRmlsdGVyVmFsdWUpIC0gMiksICJA +IiwgRmllbGROYW1lKQ0KICAgICAgICAgICAgSWYgKFJlbGF0aW9uYWxPcGVyYXRv +ciBBbmQgU1FMX05vdCkgPSBTUUxfTm90IFRoZW4NCiAgICAgICAgICAgICAgIENy +aXRlcmlhID0gIk5vdCAiICYgQ3JpdGVyaWENCiAgICAgICAgICAgIEVuZCBJZg0K +ICAgICAgICAgICAgQnVpbGRDcml0ZXJpYSA9IENyaXRlcmlhDQogICAgICAgICAg +ICBFeGl0IEZ1bmN0aW9uDQogICAgICAgICBFbmQgSWYNCiAgICAgIEVuZCBJZg0K +ICAgICAgDQogICBFbmQgSWYNCiAgIA0KICAgSWYgTnVsbEZpbHRlck9yRW1wdHlG +aWx0ZXIoRmllbGROYW1lLCBGaWVsZERhdGFUeXBlLCBSZWxhdGlvbmFsT3BlcmF0 +b3IsIE56KEZpbHRlclZhbHVlLCBGaWx0ZXJWYWx1ZTIpLCBJZ25vcmVWYWx1ZSwg +Q3JpdGVyaWEsIERpc2FibGVJZ25vcmVOdWxsVmFsdWUpIFRoZW4NCiAgICAgIEJ1 +aWxkQ3JpdGVyaWEgPSBDcml0ZXJpYQ0KICAgICAgRXhpdCBGdW5jdGlvbg0KICAg +RW5kIElmDQogICANCiAgIElmIFRyeUJ1aWxkU3BsaXRUb0FycmF5Q3JpdGVyaWEo +RmllbGROYW1lLCBGaWVsZERhdGFUeXBlLCBSZWxhdGlvbmFsT3BlcmF0b3IsIEZp +bHRlclZhbHVlLCBJZ25vcmVWYWx1ZSwgQ3JpdGVyaWEpIFRoZW4NCiAgICAgIEJ1 +aWxkQ3JpdGVyaWEgPSBDcml0ZXJpYQ0KICAgICAgRXhpdCBGdW5jdGlvbg0KICAg +RW5kIElmDQogICANCiAgICdTcGVjaWFsIGNhc2VzIChwYXJ0IDIpOg0KICAgSWYg +Tm90IElzQXJyYXkoRmlsdGVyVmFsdWUpIFRoZW4NCiAgICAgDQogICAgICBJZiBG +aWVsZERhdGFUeXBlID0gU1FMX051bWVyaWMgT3IgRmllbGREYXRhVHlwZSA9IFNR +TF9EYXRlIFRoZW4NCiAgICAgIA0KICAgICAgICAgSWYgRmlsdGVyVmFsdWUgPSAi +KiIgQW5kIFJlbGF0aW9uYWxPcGVyYXRvciA9IFNRTF9FcXVhbCBUaGVuDQogICAg +ICAgICAgICBCdWlsZENyaXRlcmlhID0gQnVpbGRDcml0ZXJpYShGaWVsZE5hbWUs +IEZpZWxkRGF0YVR5cGUsIFNRTF9Ob3QsIE51bGwsIE51bGwsIDAsIFRydWUpDQog +ICAgICAgICAgICBFeGl0IEZ1bmN0aW9uDQogICAgICAgICBFbmQgSWYNCiAgICAg +ICAgIA0KICAgICAgICAgSWYgSXNOdWxsKEZpbHRlclZhbHVlMikgVGhlbg0KICAg +ICAgICAgICAgSWYgVHJ5QnVpbGROdW1lcmljU3BlY2lhbENhc2VzQ3JpdGVyaWEo +RmllbGROYW1lLCBGaWVsZERhdGFUeXBlLCBSZWxhdGlvbmFsT3BlcmF0b3IsIEZp +bHRlclZhbHVlLCBJZ25vcmVWYWx1ZSwgRGlzYWJsZUlnbm9yZU51bGxWYWx1ZSwg +Q3JpdGVyaWEpIFRoZW4NCiAgICAgICAgICAgICAgIEJ1aWxkQ3JpdGVyaWEgPSBD +cml0ZXJpYQ0KICAgICAgICAgICAgICAgRXhpdCBGdW5jdGlvbg0KICAgICAgICAg +ICAgRW5kIElmDQogICAgICAgICBFbmQgSWYNCiAgICAgICAgIA0KICAgICAgICAg +Q29uZmlnTnVtZXJpY1NwZWNpYWxzIFJlbGF0aW9uYWxPcGVyYXRvciwgRmlsdGVy +VmFsdWUsIEZpbHRlclZhbHVlMg0KICAgICAgICAgDQogICAgICBFbmQgSWYNCiAg +ICAgIA0KICAgRW5kIElmDQoNCiAgIElmIFRyeUJ1aWxkSW5Dcml0ZXJpYShGaWVs +ZE5hbWUsIEZpZWxkRGF0YVR5cGUsIFJlbGF0aW9uYWxPcGVyYXRvciwgRmlsdGVy +VmFsdWUsIElnbm9yZVZhbHVlLCBDcml0ZXJpYSkgVGhlbg0KICAgICAgQnVpbGRD +cml0ZXJpYSA9IENyaXRlcmlhDQogICAgICBFeGl0IEZ1bmN0aW9uDQogICBFbmQg +SWYNCg0KICAgSWYgVHJ5QnVpbGRBcnJheUNyaXRlcmlhKEZpZWxkTmFtZSwgRmll +bGREYXRhVHlwZSwgUmVsYXRpb25hbE9wZXJhdG9yLCBGaWx0ZXJWYWx1ZSwgSWdu +b3JlVmFsdWUsIENyaXRlcmlhKSBUaGVuDQogICAgICBCdWlsZENyaXRlcmlhID0g +Q3JpdGVyaWENCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0KDQogICBJ +ZiBUcnlCdWlsZEJldHdlZW5Dcml0ZXJpYShGaWVsZE5hbWUsIEZpZWxkRGF0YVR5 +cGUsIFJlbGF0aW9uYWxPcGVyYXRvciwgRmlsdGVyVmFsdWUsIEZpbHRlclZhbHVl +MiwgSWdub3JlVmFsdWUsIENyaXRlcmlhKSBUaGVuDQogICAgICBCdWlsZENyaXRl +cmlhID0gQ3JpdGVyaWENCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0K +DQogICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfTGlrZSkgPSBTUUxf +TGlrZSBPciAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfVXNlTGlrZUJlaGF2 +aW9yKSA9IFNRTF9Vc2VMaWtlQmVoYXZpb3IgVGhlbg0KICAgICAgSWYgU3FsV2ls +ZENhcmRTdHJpbmcgPD4gIioiIFRoZW4NCiAgICAgICAgIElmIEluU3RyKDEsIEZp +bHRlclZhbHVlLCAiKiIpID4gMCBUaGVuDQogICAgICAgICAgICBGaWx0ZXJWYWx1 +ZSA9IFJlcGxhY2UoRmlsdGVyVmFsdWUsICJbKl0iLCAiQEBAfHx8U1RBUnx8fEBA +QCIpDQogICAgICAgICAgICBGaWx0ZXJWYWx1ZSA9IFJlcGxhY2UoRmlsdGVyVmFs +dWUsICIqIiwgU3FsV2lsZENhcmRTdHJpbmcpDQogICAgICAgICAgICBGaWx0ZXJW +YWx1ZSA9IFJlcGxhY2UoRmlsdGVyVmFsdWUsICJAQEB8fHxTVEFSfHx8QEBAIiwg +IioiKQ0KICAgICAgICAgRW5kIElmDQogICAgICBFbmQgSWYNCiAgIEVuZCBJZg0K +DQogICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfQWRkX1dpbGRDYXJk +U3VmZml4KSA9IFNRTF9BZGRfV2lsZENhcmRTdWZmaXggVGhlbg0KICAgICAgSWYg +VHJ5QnVpbGRXaWxkQ2FyZFN1ZmZpeE9yUHJlQnVpbGRQYXJhbXMoRmllbGROYW1l +LCBGaWVsZERhdGFUeXBlLCBSZWxhdGlvbmFsT3BlcmF0b3IsIEZpbHRlclZhbHVl +LCBGaWx0ZXJWYWx1ZTIsIElnbm9yZVZhbHVlLCBDcml0ZXJpYSkgVGhlbg0KICAg +ICAgICAgQnVpbGRDcml0ZXJpYSA9IENyaXRlcmlhDQogICAgICAgICBFeGl0IEZ1 +bmN0aW9uDQogICAgICBFbmQgSWYNCiAgIEVuZCBJZg0KDQogICBJZiAoUmVsYXRp +b25hbE9wZXJhdG9yIEFuZCBTUUxfQWRkX1dpbGRDYXJkUHJlZml4KSA9IFNRTF9B +ZGRfV2lsZENhcmRQcmVmaXggVGhlbg0KICAgICAgSWYgKFJlbGF0aW9uYWxPcGVy +YXRvciBBbmQgU1FMX0xpa2UpID0gU1FMX0xpa2UgT3IgKFJlbGF0aW9uYWxPcGVy +YXRvciBBbmQgU1FMX1VzZUxpa2VCZWhhdmlvcikgPSBTUUxfVXNlTGlrZUJlaGF2 +aW9yIFRoZW4NCiAgICAgICAgIEZpbHRlclZhbHVlID0gU3FsV2lsZENhcmRTdHJp +bmcgJiBGaWx0ZXJWYWx1ZQ0KICAgICAgRW5kIElmDQogICBFbmQgSWYNCg0KICAg +RmlsdGVyVmFsdWVTdHJpbmcgPSBDb252ZXJ0VG9TcWxUZXh0KEZpbHRlclZhbHVl +LCBGaWVsZERhdGFUeXBlKQ0KDQogICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFu +ZCBTUUxfTGlrZSkgPSBTUUxfTGlrZSBUaGVuDQogICAgICBPcGVyYXRvclN0cmlu +ZyA9ICIgTGlrZSAiDQogICAgICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBT +UUxfTm90KSA9IFNRTF9Ob3QgVGhlbg0KICAgICAgICAgT3BlcmF0b3JTdHJpbmcg +PSAiIE5vdCIgJiBPcGVyYXRvclN0cmluZw0KICAgICAgRW5kIElmDQogICAgICBC +dWlsZENyaXRlcmlhID0gRmllbGROYW1lICYgT3BlcmF0b3JTdHJpbmcgJiBGaWx0 +ZXJWYWx1ZVN0cmluZw0KICAgICAgRXhpdCBGdW5jdGlvbg0KICAgRW5kIElmDQog +ICANCiAgIE9wZXJhdG9yU3RyaW5nID0gR2V0UmVsYXRpb25hbE9wZXJhdG9yU3Ry +aW5nKFJlbGF0aW9uYWxPcGVyYXRvcikNCg0KICAgQ3JpdGVyaWEgPSBGaWVsZE5h +bWUgJiAiICIgJiBPcGVyYXRvclN0cmluZyAmICIgIiAmIEZpbHRlclZhbHVlU3Ry +aW5nDQoNCiAgIElmIChSZWxhdGlvbmFsT3BlcmF0b3IgQW5kIFNRTF9Ob3QpID0g +U1FMX05vdCBUaGVuDQogICAgICAnPzogd2lsbCB0aGlzIGxpbmUgYmUgcmVhY2hl +ZD8NCiAgICAgIENyaXRlcmlhID0gIk5vdCAiICYgQ3JpdGVyaWENCiAgIEVuZCBJ +Zg0KDQogICBCdWlsZENyaXRlcmlhID0gQ3JpdGVyaWENCg0KRW5kIEZ1bmN0aW9u +DQoNCicjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQonIEdyb3Vw +OiBDb252ZXJ0IHRvIFNRTA0KDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tDQonIEZ1bmN0aW9uOiBDb252ZXJ0VG9TcWxUZXh0DQonLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonDQonIENvbnZl +cnQgdmFsdWVzIHRvIHN0cmluZyBmb3IgU1FMIHN0YXRlbWVudCBhc3NlbWJsZWQg +YnkgVkJBLg0KJw0KJyBQYXJhbWV0ZXJzOg0KJyAgICAgVmFsdWUgICAgICAgICAg +LSBWYWx1ZSB0byBjb252ZXJ0DQonICAgICBGaWVsZERhdGFUeXBlICAtIERhdGEg +dHlwZSBvZiB0aGUgdmFsdWUgdG8gYmUgY29udmVydGVkDQonDQonIFJldHVybnM6 +DQonICAgICBTdHJpbmcgICAtIFNRTCBjb25mb3JtIHN0cmluZw0KJw0KJy0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIEZ1bmN0 +aW9uIENvbnZlcnRUb1NxbFRleHQoQnlWYWwgVmFsdWUgQXMgVmFyaWFudCwgXw0K +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnlWYWwgRmllbGREYXRh +VHlwZSBBcyBTcWxGaWVsZERhdGFUeXBlKSBBcyBTdHJpbmcNCiAgICAgICAgICAg +ICAgICAgICAgIA0KICAgU2VsZWN0IENhc2UgRmllbGREYXRhVHlwZQ0KICAgICAg +Q2FzZSBTcWxGaWVsZERhdGFUeXBlLlNRTF9UZXh0DQogICAgICAgICBDb252ZXJ0 +VG9TcWxUZXh0ID0gVGV4dFRvU3FsVGV4dChWYWx1ZSkNCiAgICAgIENhc2UgU3Fs +RmllbGREYXRhVHlwZS5TUUxfTnVtZXJpYw0KICAgICAgICAgQ29udmVydFRvU3Fs +VGV4dCA9IE51bWJlclRvU3FsVGV4dChWYWx1ZSkNCiAgICAgIENhc2UgU3FsRmll +bGREYXRhVHlwZS5TUUxfRGF0ZQ0KICAgICAgICAgQ29udmVydFRvU3FsVGV4dCA9 +IERhdGVUb1NxbFRleHQoVmFsdWUpDQogICAgICBDYXNlIFNxbEZpZWxkRGF0YVR5 +cGUuU1FMX0Jvb2xlYW4NCiAgICAgICAgIENvbnZlcnRUb1NxbFRleHQgPSBCb29s +ZWFuVG9TcWxUZXh0KFZhbHVlKQ0KICAgICAgQ2FzZSBFbHNlDQogICAgICAgICBF +cnIuUmFpc2UgdmJPYmplY3RFcnJvciwgIlNxbFRvb2xzLkNvbnZlcnRUb1NxbFRl +eHQiLCAiRmllbGREYXRhVHlwZSAnIiAmIEZpZWxkRGF0YVR5cGUgJiAiJyBub3Qg +c3VwcG9ydGVkIg0KICAgRW5kIFNlbGVjdA0KICAgDQpFbmQgRnVuY3Rpb24NCg0K +Jy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBGdW5j +dGlvbjogVGV4dFRvU3FsVGV4dA0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLQ0KJw0KJyBQcmVwYXJlIHRleHQgZm9yIFNRTCBzdGF0ZW1l +bnQNCicNCicgUGFyYW1ldGVyczoNCicgICAgIFZhbHVlICAgICAgICAgICAgICAg +ICAgIC0gVmFsdWUgdG8gY29udmVydA0KJyAgICAgRGVsaW1pdGVyICAgICAgICAg +ICAgICAgLSBEZWxpbWl0ZXIgZm9yIHRleHQgdmFsdWVzLiAoSW4gbW9zdCBEQk1T +ICcgaXMgdXNlZCBhcyBhIGRlbGltaXRlcikuDQonICAgICBXaXRob3V0TGVmdFJp +Z2h0RGVsaW0gICAtIE9ubHkgZG91YmxlIHRoZSBib3VuZGFyeSBkcmF3aW5nIHdp +dGhpbiB0aGUgdmFsdWVzLCBidXQgZG8gbm90IHNldCB0aGUgYm91bmRhcnkuDQon +DQonIFJldHVybnM6DQonICAgICBTdHJpbmcNCicNCicgRXhhbXBsZToNCicgICAg +ICAgIHN0clNRTCA9ICJzZWxlY3QgLi4uIGZyb20gdGFiZWxsZSB3aGVyZSBGZWxk +ID0gIiAmIFRleHRUb1NxbFRleHQoImFiJ2NkIikNCicgICAgID0+IHN0clNRTCA9 +ICJzZWxlY3QgLi4uIGZyb20gdGFiZWxsZSB3aGVyZSBGZWxkID0gJ2FiJydjZCci +DQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpQ +dWJsaWMgRnVuY3Rpb24gVGV4dFRvU3FsVGV4dChCeVZhbCBWYWx1ZSBBcyBWYXJp +YW50LCBfDQogICAgICAgICAgICAgICAgICAgICBPcHRpb25hbCBCeVZhbCBEZWxp +bWl0ZXIgQXMgU3RyaW5nID0gU1FMX0RFRkFVTFRfVEVYVERFTElNSVRFUiwgXw0K +ICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgV2l0aG91dExlZnRS +aWdodERlbGltIEFzIEJvb2xlYW4gPSBGYWxzZSkgQXMgU3RyaW5nDQogICANCiAg +IERpbSBSZXN1bHQgQXMgU3RyaW5nDQogICANCiAgIElmIElzTnVsbChWYWx1ZSkg +VGhlbg0KICAgICAgVGV4dFRvU3FsVGV4dCA9IFJlc3VsdFRleHRJZk51bGwNCiAg +ICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0KICAgDQogICBSZXN1bHQgPSBS +ZXBsYWNlJChWYWx1ZSwgRGVsaW1pdGVyLCBEZWxpbWl0ZXIgJiBEZWxpbWl0ZXIp +DQogICBJZiBOb3QgV2l0aG91dExlZnRSaWdodERlbGltIFRoZW4NCiAgICAgIFJl +c3VsdCA9IERlbGltaXRlciAmIFJlc3VsdCAmIERlbGltaXRlcg0KICAgRW5kIElm +DQogICANCiAgIFRleHRUb1NxbFRleHQgPSBSZXN1bHQNCg0KRW5kIEZ1bmN0aW9u +DQoNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicg +RnVuY3Rpb246IERhdGVUb1NxbFRleHQNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0NCicNCicgQ29udmVydCBkYXRlIHZhbHVlIHRvIHN0 +cmluZyBmb3IgU1FMIHN0YXRlbWVudCBhc3NlbWJsZWQgYnkgVkJBLg0KJw0KJyBQ +YXJhbWV0ZXJzOg0KJyAgICAgVmFsdWUgICAgICAgICAgLSBWYWx1ZSB0byBjb252 +ZXJ0DQonICAgICBGb3JtYXRTdHJpbmcgICAtIERhdGUgZm9ybWF0IChkZXBlbmRz +IG9uIERCTVMhKQ0KJw0KJyBSZXR1cm5zOg0KJyAgICAgU3RyaW5nDQonDQonLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpQdWJsaWMgRnVu +Y3Rpb24gRGF0ZVRvU3FsVGV4dChCeVZhbCBWYWx1ZSBBcyBWYXJpYW50LCBfDQog +ICAgICAgICAgICAgICAgICAgICBPcHRpb25hbCBCeVZhbCBGb3JtYXRTdHJpbmcg +QXMgU3RyaW5nID0gU1FMX0RFRkFVTFRfREFURUZPUk1BVCkgQXMgU3RyaW5nDQoN +CiAgIElmIElzTnVsbChWYWx1ZSkgVGhlbg0KICAgICAgRGF0ZVRvU3FsVGV4dCA9 +IFJlc3VsdFRleHRJZk51bGwNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJ +Zg0KICAgDQogICBJZiBOb3QgSXNEYXRlKFZhbHVlKSBUaGVuDQogICAgICBFcnIu +UmFpc2UgdmJPYmplY3RFcnJvciwgIlNxbFRvb2xzLkRhdGVUb1NxbFRleHQiLCAi +RGVyIFdlcnQgJyIgJiBWYWx1ZSAmICInIHZvbSBQYXJhbWV0ZXIgVmFsdWUgaXN0 +IGtlaW4gRGF0dW1zd2VydCEiDQogICBFbmQgSWYNCg0KICAgSWYgTGVuKEZvcm1h +dFN0cmluZykgPSAwIFRoZW4NCiAgICAgIEZvcm1hdFN0cmluZyA9IFNxbERhdGVG +b3JtYXQNCiAgICAgIElmIExlbihGb3JtYXRTdHJpbmcpID0gMCBUaGVuDQogICAg +ICAgICBFcnIuUmFpc2UgU3FsVG9vbHNFcnJvck51bWJlcnMuRVJSTlJfTk9DT05G +SUcsICJEYXRlVG9TcWxUZXh0IiwgImRhdGUgZm9ybWF0IGlzIG5vdCBkZWZpbmVk +Ig0KICAgICAgRW5kIElmDQogICBFbmQgSWYNCiAgIA0KICAgRGF0ZVRvU3FsVGV4 +dCA9IFZCQS5Gb3JtYXQkKFZhbHVlLCBGb3JtYXRTdHJpbmcpDQoNCkVuZCBGdW5j +dGlvbg0KDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +DQonIEZ1bmN0aW9uOiBOdW1iZXJUb1NxbFRleHQNCictLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicgQ29udmVydCBudW1lcmljIHZh +bHVlIHRvIHN0cmluZyBmb3IgU1FMIHN0YXRlbWVudCBhc3NlbWJsZWQgYnkgVkJB +Lg0KJw0KJyBQYXJhbWV0ZXJzOg0KJyAgICAgVmFsdWUgICAgICAgICAgLSBWYWx1 +ZSB0byBjb252ZXJ0DQonICAgICBGb3JtYXRTdHJpbmcgICAtIERhdGUgZm9ybWF0 +IChkZXBlbmRzIG9uIERCTVMhKQ0KJw0KJyBSZXR1cm5zOg0KJyAgICAgU3RyaW5n +DQonDQonIFJlbWFya3M6DQonICAgICBTdHIgZnVuY3Rpb24gZW5zdXJlcyAiLiIu +DQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpQ +dWJsaWMgRnVuY3Rpb24gTnVtYmVyVG9TcWxUZXh0KEJ5VmFsIFZhbHVlIEFzIFZh +cmlhbnQpIEFzIFN0cmluZw0KDQogICBEaW0gUmVzdWx0IEFzIFN0cmluZw0KDQog +ICBJZiBJc051bGwoVmFsdWUpIFRoZW4NCiAgICAgIE51bWJlclRvU3FsVGV4dCA9 +IFJlc3VsdFRleHRJZk51bGwNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJ +Zg0KICAgDQogICBWYWx1ZSA9IENvbnZlcnRUb051bWVyaWMoVmFsdWUpDQogICAN +CiAgIFJlc3VsdCA9IFRyaW0kKFN0ciQoVmFsdWUpKQ0KICAgSWYgTGVmdChSZXN1 +bHQsIDEpID0gIi4iIFRoZW4NCiAgICAgIFJlc3VsdCA9ICIwIiAmIFJlc3VsdA0K +ICAgRW5kIElmDQogICANCiAgIE51bWJlclRvU3FsVGV4dCA9IFJlc3VsdA0KICAg +DQpFbmQgRnVuY3Rpb24NCg0KRnJpZW5kIEZ1bmN0aW9uIENvbnZlcnRUb051bWVy +aWMoQnlWYWwgVmFsdWUgQXMgVmFyaWFudCkgQXMgVmFyaWFudA0KICAgDQogICBD +b25zdCBDaGVja051bWJlciBBcyBEb3VibGUgPSAxLjIzDQogICANCiAgIERpbSBD +aGVja1RleHQgQXMgU3RyaW5nDQogICBEaW0gRGVjaW1hbFNlcGFyYXRvclRvUmVw +bGFjZSBBcyBTdHJpbmcNCiAgIERpbSBOZXdEZWNpbWFsU2VwYXJhdG9yIEFzIFN0 +cmluZw0KICAgDQogICBJZiBJc051bGwoVmFsdWUpIFRoZW4NCiAgICAgIENvbnZl +cnRUb051bWVyaWMgPSBOdWxsDQogICAgICBFeGl0IEZ1bmN0aW9uDQogICBFbHNl +SWYgQ1N0cihWYWx1ZSkgPSB2Yk51bGxTdHJpbmcgVGhlbg0KICAgICAgQ29udmVy +dFRvTnVtZXJpYyA9IE51bGwNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJ +Zg0KICAgDQogICBDaGVja1RleHQgPSBDU3RyKENoZWNrTnVtYmVyKQ0KICAgSWYg +SW5TdHIoMSwgQ2hlY2tUZXh0LCAiLCIpID4gMCBUaGVuDQogICAgICBEZWNpbWFs +U2VwYXJhdG9yVG9SZXBsYWNlID0gIi4iDQogICAgICBOZXdEZWNpbWFsU2VwYXJh +dG9yID0gIiwiDQogICBFbHNlDQogICAgICBEZWNpbWFsU2VwYXJhdG9yVG9SZXBs +YWNlID0gIiwiDQogICAgICBOZXdEZWNpbWFsU2VwYXJhdG9yID0gIi4iDQogICBF +bmQgSWYNCiAgIA0KICAgSWYgSW5TdHIoMSwgVmFsdWUsIERlY2ltYWxTZXBhcmF0 +b3JUb1JlcGxhY2UpID4gMCBUaGVuDQogICAgICAgVmFsdWUgPSBSZXBsYWNlKFZh +bHVlLCBEZWNpbWFsU2VwYXJhdG9yVG9SZXBsYWNlLCBOZXdEZWNpbWFsU2VwYXJh +dG9yKQ0KICAgICAgIERvIFdoaWxlIFZhbHVlIExpa2UgIioiICYgTmV3RGVjaW1h +bFNlcGFyYXRvciAmICIqIiAmIE5ld0RlY2ltYWxTZXBhcmF0b3IgJiAiKiINCiAg +ICAgICAgICBWYWx1ZSA9IFJlcGxhY2UoVmFsdWUsIE5ld0RlY2ltYWxTZXBhcmF0 +b3IsIHZiTnVsbFN0cmluZywgMSwgMSkNCiAgICAgICBMb29wDQogICAgRW5kIElm +DQogICANCiAgIENvbnZlcnRUb051bWVyaWMgPSBDRGJsKFZhbHVlKQ0KICAgDQpF +bmQgRnVuY3Rpb24NCg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLQ0KJyBGdW5jdGlvbjogQm9vbGVhblRvU3FsVGV4dA0KJy0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBQcmVwYXJlIEJv +b2xlYW4gZm9yIFNRTCB0ZXh0DQonDQonIFBhcmFtZXRlcnM6DQonICAgICBWYWx1 +ZSAgICAgICAgICAtIFZhbHVlIHRvIGNvbnZlcnQNCicgICAgIFRydWVTdHJpbmcg +ICAtICAgU3RyaW5nIGZvciB0cnVlIHZhbHVlIChvcHRpb25hbCkNCicNCicgUmV0 +dXJuczoNCicgICAgIFN0cmluZw0KJw0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIEZ1bmN0aW9uIEJvb2xlYW5Ub1NxbFRl +eHQoQnlWYWwgVmFsdWUgQXMgVmFyaWFudCwgXw0KICAgICAgICAgICAgICAgICAg +ICAgICAgT3B0aW9uYWwgQnlWYWwgVHJ1ZVN0cmluZyBBcyBTdHJpbmcgPSBTUUxf +REVGQVVMVF9CT09MVFJVRVNUUklORykgQXMgU3RyaW5nDQoNCiAgIElmIElzTnVs +bChWYWx1ZSkgVGhlbg0KICAgICAgQm9vbGVhblRvU3FsVGV4dCA9IFJlc3VsdFRl +eHRJZk51bGwNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0KDQogICBJ +ZiBDQm9vbChWYWx1ZSkgPSBUcnVlIFRoZW4gJyBDQm9vbChWYWx1ZSkgdG8gcmFp +c2UgZXJyb3IgMTMgKHR5cGUgbWlzbWF0Y2gpIGlmIFZhbHVlIGlzIG5vdCBhIGJv +b2xlYW4NCiAgICAgIElmIExlbihUcnVlU3RyaW5nKSA9IDAgVGhlbg0KICAgICAg +ICAgVHJ1ZVN0cmluZyA9IFNxbEJvb2xlYW5UcnVlU3RyaW5nDQogICAgICAgICBJ +ZiBMZW4oVHJ1ZVN0cmluZykgPSAwIFRoZW4NCiAgICAgICAgICAgIEVyci5SYWlz +ZSBTcWxUb29sc0Vycm9yTnVtYmVycy5FUlJOUl9OT0NPTkZJRywgIkJvb2xlYW5U +b1NxbFRleHQiLCAiYm9vbGVhbiBzdHJpbmcgZm9yIHRydWUgaXMgbm90IGRlZmlu +ZWQiDQogICAgICAgICBFbmQgSWYNCiAgICAgIEVuZCBJZg0KICAgICAgQm9vbGVh +blRvU3FsVGV4dCA9IFRydWVTdHJpbmcNCiAgIEVsc2UNCiAgICAgIEJvb2xlYW5U +b1NxbFRleHQgPSAiMCINCiAgIEVuZCBJZg0KICAgDQpFbmQgRnVuY3Rpb24NCg0K +UHJpdmF0ZSBGdW5jdGlvbiBDb25maWdOdW1lcmljU3BlY2lhbHMoIF8NCiAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgIEJ5UmVmIFJlbGF0aW9uYWxPcGVyYXRv +ciBBcyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzLCBfDQogICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICBCeVJlZiBGaWx0ZXJWYWx1ZSBBcyBWYXJpYW50LCBfDQog +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCeVJlZiBGaWx0ZXJWYWx1ZTIg +QXMgVmFyaWFudCkNCg0KICAgSWYgTGVmdChGaWx0ZXJWYWx1ZSwgMSkgPSAiPCIg +VGhlbg0KICAgICAgSWYgKChSZWxhdGlvbmFsT3BlcmF0b3IgQW5kIFNRTF9FcXVh +bCkgPSBTUUxfRXF1YWwpIFRoZW4NCiAgICAgICAgIFJlbGF0aW9uYWxPcGVyYXRv +ciA9IFJlbGF0aW9uYWxPcGVyYXRvciAtIFNRTF9FcXVhbA0KICAgICAgRW5kIElm +DQogICAgICBSZWxhdGlvbmFsT3BlcmF0b3IgPSBSZWxhdGlvbmFsT3BlcmF0b3Ig +T3IgU1FMX0xlc3NUaGFuDQogICAgICBGaWx0ZXJWYWx1ZSA9IE1pZChGaWx0ZXJW +YWx1ZSwgMikNCiAgIEVuZCBJZg0KICAgDQogICBJZiBMZWZ0KEZpbHRlclZhbHVl +LCAxKSA9ICI+IiBUaGVuDQogICAgICBJZiAoKFJlbGF0aW9uYWxPcGVyYXRvciBB +bmQgU1FMX0VxdWFsKSA9IFNRTF9FcXVhbCkgVGhlbg0KICAgICAgICAgUmVsYXRp +b25hbE9wZXJhdG9yID0gUmVsYXRpb25hbE9wZXJhdG9yIC0gU1FMX0VxdWFsDQog +ICAgICBFbmQgSWYNCiAgICAgIFJlbGF0aW9uYWxPcGVyYXRvciA9IFJlbGF0aW9u +YWxPcGVyYXRvciBPciBTUUxfR3JlYXRlclRoYW4NCiAgICAgIEZpbHRlclZhbHVl +ID0gTWlkKEZpbHRlclZhbHVlLCAyKQ0KICAgRW5kIElmDQoNCiAgIElmIExlZnQo +RmlsdGVyVmFsdWUsIDEpID0gIj0iIFRoZW4NCiAgICAgIFJlbGF0aW9uYWxPcGVy +YXRvciA9IFJlbGF0aW9uYWxPcGVyYXRvciBPciBTUUxfRXF1YWwNCiAgICAgIEZp +bHRlclZhbHVlID0gTWlkKEZpbHRlclZhbHVlLCAyKQ0KICAgRW5kIElmDQogICAN +CiAgIElmIFJpZ2h0KEZpbHRlclZhbHVlLCAxKSA9ICIqIiBUaGVuDQogICAgICBS +ZWxhdGlvbmFsT3BlcmF0b3IgPSBSZWxhdGlvbmFsT3BlcmF0b3IgT3IgU1FMX0Fk +ZF9XaWxkQ2FyZFN1ZmZpeA0KICAgRWxzZUlmIFJpZ2h0KEZpbHRlclZhbHVlMiwg +MSkgPSAiKiIgVGhlbg0KICAgICAgUmVsYXRpb25hbE9wZXJhdG9yID0gUmVsYXRp +b25hbE9wZXJhdG9yIE9yIFNRTF9BZGRfV2lsZENhcmRTdWZmaXgNCiAgIEVuZCBJ +Zg0KDQpFbmQgRnVuY3Rpb24NCg0KUHJpdmF0ZSBGdW5jdGlvbiBHZXROZXh0RGln +aXROdW1iZXIoQnlWYWwgTnVtVmFsdWUgQXMgVmFyaWFudCwgT3B0aW9uYWwgQWRk +VG9BYnNvbHV0ZVZhbHVlIEFzIEJvb2xlYW4gPSBGYWxzZSkgQXMgRG91YmxlDQog +ICANCiAgIERpbSBUZXN0U3RyaW5nIEFzIFN0cmluZw0KICAgRGltIERlY1NpZ25Q +b3MgQXMgTG9uZw0KICAgRGltIERpZ2l0cyBBcyBMb25nDQogICBEaW0gSXNOZWdh +dGl2IEFzIEJvb2xlYW4NCg0KICAgQ29uc3QgQWRkaXRpb25hbERlY0RpZ2l0IEFz +IFN0cmluZyA9ICIxIg0KICAgQ29uc3QgQWRkaXRpb25hbERlY0RpZ2l0S29yciBB +cyBEb3VibGUgPSAwLjENCiAgIA0KICAgVGVzdFN0cmluZyA9IFRyaW0oQ1N0cihD +b252ZXJ0VG9OdW1lcmljKFJlcGxhY2UoQ1N0cihOdW1WYWx1ZSksICIqIiwgQWRk +aXRpb25hbERlY0RpZ2l0KSkpKQ0KICAgDQogICBJZiBMZWZ0KFRlc3RTdHJpbmcs +IDEpID0gIi0iIEFuZCAoTm90IEFkZFRvQWJzb2x1dGVWYWx1ZSkgVGhlbg0KICAg +ICAgR2V0TmV4dERpZ2l0TnVtYmVyID0gQ0RibChSZXBsYWNlKENTdHIoTnVtVmFs +dWUpLCAiKiIsIHZiTnVsbFN0cmluZykpDQogICAgICBFeGl0IEZ1bmN0aW9uDQog +ICBFbmQgSWYNCiAgIA0KICAgSWYgTGVmdChUZXN0U3RyaW5nLCAxKSA9ICItIiBU +aGVuDQogICAgICBJc05lZ2F0aXYgPSBUcnVlDQogICBFbmQgSWYNCiAgIA0KICAg +RGVjU2lnblBvcyA9IEluU3RyUmV2KFRlc3RTdHJpbmcsIERlY2ltYWxNYXJrZXIp +DQogICBJZiBEZWNTaWduUG9zID0gMCBUaGVuICcgbmV4dCBpbnRlZ2VyDQogICAg +ICBJZiBBZGRUb0Fic29sdXRlVmFsdWUgQW5kIElzTmVnYXRpdiBUaGVuDQogICAg +ICAgICBHZXROZXh0RGlnaXROdW1iZXIgPSBDRGJsKFJlcGxhY2UoQ1N0cihOdW1W +YWx1ZSksICIqIiwgdmJOdWxsU3RyaW5nKSkgLSAxDQogICAgICBFbHNlDQogICAg +ICAgICBHZXROZXh0RGlnaXROdW1iZXIgPSBDRGJsKFJlcGxhY2UoQ1N0cihOdW1W +YWx1ZSksICIqIiwgdmJOdWxsU3RyaW5nKSkgKyAxDQogICAgICBFbmQgSWYNCiAg +ICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0KICAgDQogICBEaWdpdHMgPSBM +ZW4oVGVzdFN0cmluZykgLSBEZWNTaWduUG9zIC0gMQ0KICAgDQogICBJZiBMZWZ0 +KFRlc3RTdHJpbmcsIDEpID0gIi0iIFRoZW4NCiAgICAgIElzTmVnYXRpdiA9IFRy +dWUNCiAgIEVuZCBJZg0KICAgDQogICBJZiBBZGRUb0Fic29sdXRlVmFsdWUgQW5k +IElzTmVnYXRpdiBUaGVuDQogICAgICBHZXROZXh0RGlnaXROdW1iZXIgPSBDRGJs +KFRlc3RTdHJpbmcpICsgQWRkaXRpb25hbERlY0RpZ2l0S29yciAvIDEwIF4gRGln +aXRzIC0gQWRkaXRpb25hbERlY0RpZ2l0S29yciAvIDEwIF4gKERpZ2l0cyAtIDEp +DQogICBFbHNlDQogICAgICBHZXROZXh0RGlnaXROdW1iZXIgPSBDRGJsKFRlc3RT +dHJpbmcpICsgKDEgLSBBZGRpdGlvbmFsRGVjRGlnaXRLb3JyKSAvIDEwIF4gRGln +aXRzDQogICBFbmQgSWYNCiAgIA0KRW5kIEZ1bmN0aW9uDQoNClByaXZhdGUgUHJv +cGVydHkgR2V0IERlY2ltYWxNYXJrZXIoKSBBcyBTdHJpbmcNCg0KICAgU3RhdGlj +IERlY0NoYXIgQXMgU3RyaW5nDQogICBEaW0gQ2hlY2tTdHJpbmcgQXMgU3RyaW5n +DQogICANCiAgIElmIExlbihEZWNDaGFyKSA9IDAgVGhlbg0KICAgICAgQ2hlY2tT +dHJpbmcgPSBUcmltKENTdHIoMS4yKSkNCiAgICAgIERlY0NoYXIgPSBNaWQoQ2hl +Y2tTdHJpbmcsIDIsIDEpDQogICBFbmQgSWYNCiAgIA0KICAgRGVjaW1hbE1hcmtl +ciA9IERlY0NoYXINCg0KRW5kIFByb3BlcnR5DQoNClByaXZhdGUgRnVuY3Rpb24g +Q2hhclRyaW0oQnlWYWwgVmFsdWVUb1RyaW0gQXMgU3RyaW5nLCBCeVZhbCBUcmlt +Q2hhciBBcyBTdHJpbmcpIEFzIFN0cmluZw0KDQogICBEaW0gVHJpbVN0cmluZyBB +cyBTdHJpbmcNCiAgIA0KICAgVHJpbVN0cmluZyA9ICIgIiAmIFRyaW1DaGFyDQog +ICBEbyBXaGlsZSBJblN0cigxLCBWYWx1ZVRvVHJpbSwgVHJpbVN0cmluZykNCiAg +ICAgIFZhbHVlVG9UcmltID0gUmVwbGFjZShWYWx1ZVRvVHJpbSwgVHJpbVN0cmlu +ZywgVHJpbUNoYXIpDQogICBMb29wDQogICANCiAgIFRyaW1TdHJpbmcgPSBUcmlt +Q2hhciAmICIgIg0KICAgRG8gV2hpbGUgSW5TdHIoMSwgVmFsdWVUb1RyaW0sIFRy +aW1TdHJpbmcpDQogICAgICBWYWx1ZVRvVHJpbSA9IFJlcGxhY2UoVmFsdWVUb1Ry +aW0sIFRyaW1TdHJpbmcsIFRyaW1DaGFyKQ0KICAgTG9vcA0KICAgDQogICBDaGFy +VHJpbSA9IFZhbHVlVG9UcmltDQoNCkVuZCBGdW5jdGlvbg0KDQpGcmllbmQgRnVu +Y3Rpb24gR2V0UmVsYXRpb25hbE9wZXJhdG9yU3RyaW5nKEJ5UmVmIFJlbGF0aW9u +YWxPcGVyYXRvciBBcyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzKSBBcyBTdHJpbmcN +Cg0KICAgRGltIE9wZXJhdG9yU3RyaW5nIEFzIFN0cmluZw0KICAgRGltIG9wIEFz +IFNxbFJlbGF0aW9uYWxPcGVyYXRvcnMNCiAgIA0KICAgSWYgKFJlbGF0aW9uYWxP +cGVyYXRvciBBbmQgU1FMX0luKSA9IFNRTF9JbiBUaGVuDQogICAgICBPcGVyYXRv +clN0cmluZyA9IE9wZXJhdG9yU3RyaW5nICYgIkluIg0KICAgICAgSWYgKFJlbGF0 +aW9uYWxPcGVyYXRvciBBbmQgU1FMX05vdCkgPSBTUUxfTm90IFRoZW4NCiAgICAg +ICAgIE9wZXJhdG9yU3RyaW5nID0gIk5vdCAiICYgT3BlcmF0b3JTdHJpbmcNCiAg +ICAgIEVuZCBJZg0KICAgICAgR2V0UmVsYXRpb25hbE9wZXJhdG9yU3RyaW5nID0g +T3BlcmF0b3JTdHJpbmcNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0K +ICAgDQogICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfTm90KSA9IFNR +TF9Ob3QgVGhlbg0KICAgICAgDQogICAgICBvcCA9IFJlbGF0aW9uYWxPcGVyYXRv +ciBYb3IgU1FMX05vdA0KICAgICAgDQogICAgICBJZiBvcCA9IFNxbFJlbGF0aW9u +YWxPcGVyYXRvcnMuU1FMX0VxdWFsIFRoZW4gJyA9PiAiPSIgenUgIjw+IiAuLiBu +dWxsIGJlcvxja3NpY2h0aWdlbj8NCiAgICAgICAgIFJlbGF0aW9uYWxPcGVyYXRv +ciA9IFNRTF9MZXNzVGhhbiArIFNRTF9HcmVhdGVyVGhhbg0KICAgICAgRWxzZUlm +IG9wID0gU1FMX0dyZWF0ZXJUaGFuICsgU1FMX0xlc3NUaGFuIFRoZW4gJyA9PiAi +PD4iIHp1ICI9IiAuLiBudWxsIGJlcvxja3NpY2h0aWdlbj8NCiAgICAgICAgIFJl +bGF0aW9uYWxPcGVyYXRvciA9IFNRTF9FcXVhbA0KICAgICAgRWxzZQ0KICAgICAg +ICAgUmVsYXRpb25hbE9wZXJhdG9yID0gUmVsYXRpb25hbE9wZXJhdG9yIFhvciBT +UUxfTm90DQogICAgICAgICBJZiAob3AgQW5kIFNRTF9FcXVhbCkgPSBTUUxfRXF1 +YWwgVGhlbg0KICAgICAgICAgICAgUmVsYXRpb25hbE9wZXJhdG9yID0gUmVsYXRp +b25hbE9wZXJhdG9yIFhvciBTUUxfRXF1YWwNCiAgICAgICAgIEVsc2UNCiAgICAg +ICAgICAgIFJlbGF0aW9uYWxPcGVyYXRvciA9IFJlbGF0aW9uYWxPcGVyYXRvciBP +ciBTUUxfRXF1YWwNCiAgICAgICAgIEVuZCBJZg0KICAgICAgICAgSWYgKG9wIEFu +ZCBTUUxfTGVzc1RoYW4pID0gU1FMX0xlc3NUaGFuIFRoZW4NCiAgICAgICAgICAg +IFJlbGF0aW9uYWxPcGVyYXRvciA9IFJlbGF0aW9uYWxPcGVyYXRvciBYb3IgU1FM +X0xlc3NUaGFuDQogICAgICAgICAgICBSZWxhdGlvbmFsT3BlcmF0b3IgPSBSZWxh +dGlvbmFsT3BlcmF0b3IgT3IgU1FMX0dyZWF0ZXJUaGFuDQogICAgICAgICBFbmQg +SWYNCiAgICAgICAgIElmIChvcCBBbmQgU1FMX0dyZWF0ZXJUaGFuKSA9IFNRTF9H +cmVhdGVyVGhhbiBUaGVuDQogICAgICAgICAgICBSZWxhdGlvbmFsT3BlcmF0b3Ig +PSBSZWxhdGlvbmFsT3BlcmF0b3IgWG9yIFNRTF9HcmVhdGVyVGhhbg0KICAgICAg +ICAgICAgUmVsYXRpb25hbE9wZXJhdG9yID0gUmVsYXRpb25hbE9wZXJhdG9yIE9y +IFNRTF9MZXNzVGhhbg0KICAgICAgICAgRW5kIElmDQogICAgICBFbmQgSWYNCiAg +IEVuZCBJZg0KDQogICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfTGVz +c1RoYW4pID0gU1FMX0xlc3NUaGFuIFRoZW4NCiAgICAgIE9wZXJhdG9yU3RyaW5n +ID0gT3BlcmF0b3JTdHJpbmcgJiAiPCINCiAgIEVuZCBJZg0KICAgDQogICBJZiAo +UmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfR3JlYXRlclRoYW4pID0gU1FMX0dy +ZWF0ZXJUaGFuIFRoZW4NCiAgICAgIE9wZXJhdG9yU3RyaW5nID0gT3BlcmF0b3JT +dHJpbmcgJiAiPiINCiAgIEVuZCBJZg0KDQogICBJZiAoUmVsYXRpb25hbE9wZXJh +dG9yIEFuZCBTUUxfRXF1YWwpID0gU1FMX0VxdWFsIFRoZW4NCiAgICAgIE9wZXJh +dG9yU3RyaW5nID0gT3BlcmF0b3JTdHJpbmcgJiAiPSINCiAgIEVuZCBJZg0KDQog +ICBHZXRSZWxhdGlvbmFsT3BlcmF0b3JTdHJpbmcgPSBPcGVyYXRvclN0cmluZw0K +DQpFbmQgRnVuY3Rpb24NCg0KUHJpdmF0ZSBGdW5jdGlvbiBUcnlCdWlsZFdpbGRD +YXJkU3VmZml4T3JQcmVCdWlsZFBhcmFtcyhCeVZhbCBGaWVsZE5hbWUgQXMgU3Ry +aW5nLCBCeVZhbCBGaWVsZERhdGFUeXBlIEFzIFNxbEZpZWxkRGF0YVR5cGUsIF8N +CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5UmVmIFJl +bGF0aW9uYWxPcGVyYXRvciBBcyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzLCBfDQog +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCeVJlZiBGaWx0 +ZXJWYWx1ZSBBcyBWYXJpYW50LCBfDQogICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICBCeVJlZiBGaWx0ZXJWYWx1ZTIgQXMgVmFyaWFudCwgXw0K +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnlSZWYgSWdu +b3JlVmFsdWUgQXMgVmFyaWFudCwgXw0KICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgQnlSZWYgQ3JpdGVyaWEgQXMgU3RyaW5nKSBBcyBCb29s +ZWFuDQoNCiAgIERpbSBDcml0ZXJpYTEgQXMgU3RyaW5nDQogICBEaW0gQ3JpdGVy +aWEyIEFzIFN0cmluZw0KDQogICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBT +UUxfTGlrZSkgPSBTUUxfTGlrZSBPciAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBT +UUxfVXNlTGlrZUJlaGF2aW9yKSA9IFNRTF9Vc2VMaWtlQmVoYXZpb3IgVGhlbg0K +ICAgICAgRmlsdGVyVmFsdWUgPSBGaWx0ZXJWYWx1ZSAmIFNxbFdpbGRDYXJkU3Ry +aW5nDQogICBFbHNlSWYgRmllbGREYXRhVHlwZSA9IFNRTF9EYXRlIFRoZW4NCiAg +ICAgIElmIChSZWxhdGlvbmFsT3BlcmF0b3IgQW5kIFNRTF9MZXNzVGhhbikgPSAw +IFRoZW4gJyBubyA8IHRoZXJlZm9yZTogID4sID49IG9yIG9ubHkgPQ0KICAgICAg +ICAgSWYgKFJlbGF0aW9uYWxPcGVyYXRvciBBbmQgU1FMX0dyZWF0ZXJUaGFuKSA9 +IFNRTF9HcmVhdGVyVGhhbiBUaGVuDQogICAgICAgICAgICAnIGNoYW5nZSBub3Ro +aW5nIC4uLiA+PSBEYXRhVmFsdWUgIC8gU1FMX0FkZF9XaWxkQ2FyZFN1ZmZpeCBp +cyBub3QgbG9naWNhbA0KICAgICAgICAgRWxzZSAnIENvbnNpZGVyIHRoZSB3aG9s +ZSBkYXkgLi4uIEZpZWxkTmFtZSA+PSBEYXRlVmFsdWUgYW5kIEZpZWxkTmFtZSA8 +IERhdGVBZGQoImQiLCAxLCBGaWx0ZXJWYWx1ZSkpDQogICAgICAgICAgICBDcml0 +ZXJpYSA9IEJ1aWxkQ3JpdGVyaWEoRmllbGROYW1lLCBGaWVsZERhdGFUeXBlLCBT +UUxfR3JlYXRlclRoYW4gKyBTUUxfRXF1YWwsIEZpbHRlclZhbHVlLCAsICwgRmFs +c2UpICYgXw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNxbEFuZENvbmNh +dFN0cmluZyAmIF8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBCdWlsZENy +aXRlcmlhKEZpZWxkTmFtZSwgRmllbGREYXRhVHlwZSwgU1FMX0xlc3NUaGFuLCBE +YXRlQWRkKCJkIiwgMSwgQ0RhdGUoQ0xuZyhDRGF0ZShGaWx0ZXJWYWx1ZSkpKSks +ICwgLCBGYWxzZSkNCiAgICAgICAgICAgIFRyeUJ1aWxkV2lsZENhcmRTdWZmaXhP +clByZUJ1aWxkUGFyYW1zID0gVHJ1ZQ0KICAgICAgICAgICAgRXhpdCBGdW5jdGlv +bg0KICAgICAgICAgRW5kIElmDQogICAgICBFbHNlDQogICAgICAgICBJZiAoUmVs +YXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfRXF1YWwpID0gU1FMX0VxdWFsIFRoZW4N +CiAgICAgICAgICAgIFJlbGF0aW9uYWxPcGVyYXRvciA9IFJlbGF0aW9uYWxPcGVy +YXRvciAtIFNRTF9FcXVhbA0KICAgICAgICAgRW5kIElmDQogICAgICAgICBGaWx0 +ZXJWYWx1ZSA9IERhdGVBZGQoImQiLCAxLCBDRGF0ZShDTG5nKENEYXRlKEZpbHRl +clZhbHVlKSkpKQ0KICAgICAgRW5kIElmDQogICBFbHNlSWYgRmllbGREYXRhVHlw +ZSA9IFNRTF9OdW1lcmljIFRoZW4NCiAgICAgIElmIChSZWxhdGlvbmFsT3BlcmF0 +b3IgQW5kIFNRTF9MZXNzVGhhbikgPSAwIFRoZW4gJyBubyA8IGRhaGVyOiAgPiwg +Pj0gb3Igb25seSA9DQogICAgICAgICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFu +ZCBTUUxfR3JlYXRlclRoYW4pID0gU1FMX0dyZWF0ZXJUaGFuIFRoZW4NCiAgICAg +ICAgICAgIElmIEZpbHRlclZhbHVlIExpa2UgIipbLC5dKlsqXSIgVGhlbg0KICAg +ICAgICAgICAgICAgRmlsdGVyVmFsdWUgPSBSZXBsYWNlKEZpbHRlclZhbHVlLCAi +KiIsIDApDQogICAgICAgICAgICBFbHNlSWYgRmlsdGVyVmFsdWUgTGlrZSAiKlsq +XSIgVGhlbg0KICAgICAgICAgICAgICAgRmlsdGVyVmFsdWUgPSBSZXBsYWNlKEZp +bHRlclZhbHVlLCAiKiIsIHZiTnVsbFN0cmluZykNCiAgICAgICAgICAgIEVuZCBJ +Zg0KICAgICAgICAgICAgJyBjaGFuZ2Ugbm90aGluZyA9PiA+PSBOdW1iZXIgIC8g +U1FMX0FkZF9XaWxkQ2FyZFN1ZmZpeCBpcyBub3QgbG9naWNhbA0KICAgICAgICAg +RWxzZSAnIENvbnNpZGVyIGZvbGxvd2luZyBkZWNpbWFsIHZhbHVlcyAuLi4gRmll +bGROYW1lID49IE51bWJlciBhbmQgRmllbGROYW1lIDwgKE51bWJlciArIHgpDQog +ICAgICAgICAgICBJZiBGaWx0ZXJWYWx1ZSBMaWtlICItKlsqXSIgVGhlbg0KICAg +ICAgICAgICAgICAgSWYgRmlsdGVyVmFsdWUgTGlrZSAiKlssLl0qWypdIiBUaGVu +DQogICAgICAgICAgICAgICAgICBGaWx0ZXJWYWx1ZTIgPSBSZXBsYWNlKEZpbHRl +clZhbHVlLCAiKiIsIDApDQogICAgICAgICAgICAgICBFbHNlDQogICAgICAgICAg +ICAgICAgICBGaWx0ZXJWYWx1ZTIgPSBSZXBsYWNlKEZpbHRlclZhbHVlLCAiKiIs +IHZiTnVsbFN0cmluZykNCiAgICAgICAgICAgICAgIEVuZCBJZg0KICAgICAgICAg +ICAgICAgQ3JpdGVyaWExID0gQnVpbGRDcml0ZXJpYShGaWVsZE5hbWUsIEZpZWxk +RGF0YVR5cGUsIFNRTF9HcmVhdGVyVGhhbiwgR2V0TmV4dERpZ2l0TnVtYmVyKEZp +bHRlclZhbHVlLCBUcnVlKSwgLCBOdWxsLCBGYWxzZSkNCiAgICAgICAgICAgICAg +IENyaXRlcmlhMiA9IEJ1aWxkQ3JpdGVyaWEoRmllbGROYW1lLCBGaWVsZERhdGFU +eXBlLCBTUUxfTGVzc1RoYW4gKyBTUUxfRXF1YWwsIEZpbHRlclZhbHVlMiwgLCBO +dWxsLCBGYWxzZSkNCiAgICAgICAgICAgIEVsc2UNCiAgICAgICAgICAgICAgIENy +aXRlcmlhMSA9IEJ1aWxkQ3JpdGVyaWEoRmllbGROYW1lLCBGaWVsZERhdGFUeXBl +LCBTUUxfR3JlYXRlclRoYW4gKyBTUUxfRXF1YWwsIEZpbHRlclZhbHVlLCAsIE51 +bGwsIEZhbHNlKQ0KICAgICAgICAgICAgICAgQ3JpdGVyaWEyID0gQnVpbGRDcml0 +ZXJpYShGaWVsZE5hbWUsIEZpZWxkRGF0YVR5cGUsIFNRTF9MZXNzVGhhbiwgR2V0 +TmV4dERpZ2l0TnVtYmVyKEZpbHRlclZhbHVlKSwgLCBOdWxsLCBGYWxzZSkNCiAg +ICAgICAgICAgIEVuZCBJZg0KICAgICAgICAgICAgQ3JpdGVyaWEgPSBDcml0ZXJp +YTEgJiBTcWxBbmRDb25jYXRTdHJpbmcgJiBDcml0ZXJpYTINCiAgICAgICAgICAg +IFRyeUJ1aWxkV2lsZENhcmRTdWZmaXhPclByZUJ1aWxkUGFyYW1zID0gVHJ1ZQ0K +ICAgICAgICAgICAgRXhpdCBGdW5jdGlvbg0KICAgICAgICAgRW5kIElmDQogICAg +ICBFbHNlDQogICAgICAgICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxf +RXF1YWwpID0gU1FMX0VxdWFsIFRoZW4NCiAgICAgICAgICAgIFJlbGF0aW9uYWxP +cGVyYXRvciA9IFJlbGF0aW9uYWxPcGVyYXRvciAtIFNRTF9FcXVhbA0KICAgICAg +ICAgRW5kIElmDQogICAgICAgICBGaWx0ZXJWYWx1ZSA9IEdldE5leHREaWdpdE51 +bWJlcihGaWx0ZXJWYWx1ZSkNCiAgICAgIEVuZCBJZg0KICAgRW5kIElmDQoNCkVu +ZCBGdW5jdGlvbg0KDQpQcml2YXRlIEZ1bmN0aW9uIFRyeUJ1aWxkTnVtZXJpY1Nw +ZWNpYWxDYXNlc0NyaXRlcmlhKEJ5UmVmIEZpZWxkTmFtZSBBcyBTdHJpbmcsIEJ5 +VmFsIEZpZWxkRGF0YVR5cGUgQXMgU3FsRmllbGREYXRhVHlwZSwgXw0KICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnlSZWYgUmVsYXRpb25h +bE9wZXJhdG9yIEFzIFNxbFJlbGF0aW9uYWxPcGVyYXRvcnMsIF8NCiAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5UmVmIEZpbHRlclZhbHVl +IEFzIFZhcmlhbnQsIF8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgIEJ5UmVmIElnbm9yZVZhbHVlIEFzIFZhcmlhbnQsIF8NCiAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5UmVmIERpc2FibGVJZ25v +cmVOdWxsVmFsdWUgQXMgQm9vbGVhbiwgXw0KICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgQnlSZWYgQ3JpdGVyaWEgQXMgU3RyaW5nKSBBcyBC +b29sZWFuDQoNCiAgIERpbSBDcml0ZXJpYUJ1aWxkIEFzIEJvb2xlYW4NCiAgIERp +bSBUZW1wQXJyKCkgQXMgU3RyaW5nDQogICANCiAgIENvbnN0IEZpbHRlclZhbHVl +MiBBcyBWYXJpYW50ID0gTnVsbA0KDQogICBJZiBWYXJUeXBlKEZpbHRlclZhbHVl +KSA9IHZiU3RyaW5nIFRoZW4NCiAgICAgIEZpbHRlclZhbHVlID0gVHJpbShGaWx0 +ZXJWYWx1ZSkNCiAgIEVuZCBJZg0KICAgDQogICBJZiBGaWx0ZXJWYWx1ZSBMaWtl +ICJbMC05XSouLipbMC05XSoiIE9yIEZpbHRlclZhbHVlIExpa2UgIlsrLV1bMC05 +XSouLipbMC05XSoiIFRoZW4NCiAgICAgIFRlbXBBcnIgPSBTcGxpdChGaWx0ZXJW +YWx1ZSwgIi4uIikNCiAgICAgIENyaXRlcmlhID0gQnVpbGRDcml0ZXJpYShGaWVs +ZE5hbWUsIEZpZWxkRGF0YVR5cGUsIFNRTF9CZXR3ZWVuLCBUcmltKFRlbXBBcnIo +MCkpLCBUcmltKFRlbXBBcnIoMSkpLCBJZ25vcmVWYWx1ZSwgRGlzYWJsZUlnbm9y +ZU51bGxWYWx1ZSkNCiAgICAgIENyaXRlcmlhQnVpbGQgPSBUcnVlDQogICBFbHNl +SWYgRmlsdGVyVmFsdWUgTGlrZSAiWzAtOV0qLSpbMC05XSoiIE9yIEZpbHRlclZh +bHVlIExpa2UgIlsrLV1bMC05XSotKlswLTldKiIgVGhlbiAgICAnIGNvbnZlcnQg +dG8gYS4uYg0KICAgICAgSWYgTGVmdChGaWx0ZXJWYWx1ZSwgMSkgPSAiLSIgVGhl +bg0KICAgICAgICAgRmlsdGVyVmFsdWUgPSAie019IiAmIE1pZChGaWx0ZXJWYWx1 +ZSwgMikNCiAgICAgIEVuZCBJZg0KICAgICAgRmlsdGVyVmFsdWUgPSBSZXBsYWNl +KEZpbHRlclZhbHVlLCAiICAiLCAiICIpDQogICAgICBGaWx0ZXJWYWx1ZSA9IFJl +cGxhY2UoRmlsdGVyVmFsdWUsICItIC0iLCAiLS0iKQ0KICAgICAgRmlsdGVyVmFs +dWUgPSBSZXBsYWNlKEZpbHRlclZhbHVlLCAiLS0iLCAiLXtNfSIpDQogICAgICBG +aWx0ZXJWYWx1ZSA9IFJlcGxhY2UoRmlsdGVyVmFsdWUsICItIiwgIi4uIikNCiAg +ICAgIEZpbHRlclZhbHVlID0gUmVwbGFjZShGaWx0ZXJWYWx1ZSwgIntNfSIsICIt +IikNCiAgICAgIA0KICAgICAgVGVtcEFyciA9IFNwbGl0KEZpbHRlclZhbHVlLCAi +Li4iKQ0KICAgICAgQ3JpdGVyaWEgPSBCdWlsZENyaXRlcmlhKEZpZWxkTmFtZSwg +RmllbGREYXRhVHlwZSwgU1FMX0JldHdlZW4sIFRyaW0oVGVtcEFycigwKSksIFRy +aW0oVGVtcEFycigxKSksIElnbm9yZVZhbHVlLCBEaXNhYmxlSWdub3JlTnVsbFZh +bHVlKQ0KICAgICAgQ3JpdGVyaWFCdWlsZCA9IFRydWUNCiAgIEVsc2VJZiBGaWx0 +ZXJWYWx1ZSBMaWtlICIqWzAtOV0iICYgRGVjaW1hbE1hcmtlciAmICIqWypdIiBU +aGVuDQogICAgICBJZiAoUmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfQWRkX1dp +bGRDYXJkU3VmZml4KSA9IDAgVGhlbg0KICAgICAgICAgQ3JpdGVyaWEgPSBCdWls +ZENyaXRlcmlhKEZpZWxkTmFtZSwgRmllbGREYXRhVHlwZSwgUmVsYXRpb25hbE9w +ZXJhdG9yICsgU1FMX0FkZF9XaWxkQ2FyZFN1ZmZpeCwgRmlsdGVyVmFsdWUsIEZp +bHRlclZhbHVlMiwgSWdub3JlVmFsdWUsIERpc2FibGVJZ25vcmVOdWxsVmFsdWUp +DQogICAgICAgICBDcml0ZXJpYUJ1aWxkID0gVHJ1ZQ0KICAgICAgRW5kIElmDQog +ICBFbmQgSWYNCiAgIA0KICAgVHJ5QnVpbGROdW1lcmljU3BlY2lhbENhc2VzQ3Jp +dGVyaWEgPSBDcml0ZXJpYUJ1aWxkDQoNCkVuZCBGdW5jdGlvbg0KDQoNClByaXZh +dGUgRnVuY3Rpb24gVHJ5QnVpbGRTcGxpdFRvQXJyYXlDcml0ZXJpYShCeVJlZiBG +aWVsZE5hbWUgQXMgU3RyaW5nLCBCeVZhbCBGaWVsZERhdGFUeXBlIEFzIFNxbEZp +ZWxkRGF0YVR5cGUsIF8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgIEJ5UmVmIFJlbGF0aW9uYWxPcGVyYXRvciBBcyBTcWxSZWxhdGlvbmFs +T3BlcmF0b3JzLCBfDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICBCeVJlZiBGaWx0ZXJWYWx1ZSBBcyBWYXJpYW50LCBfDQogICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCeVJlZiBJZ25vcmVWYWx1ZSBB +cyBWYXJpYW50LCBfDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICBCeVJlZiBDcml0ZXJpYSBBcyBTdHJpbmcpIEFzIEJvb2xlYW4NCiAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgIA0KICAgRGltIFZhbHVlU3BsaXR0ZWQg +QXMgQm9vbGVhbg0KICAgRGltIENyaXRlcmlhQ29uY2F0U3RyaW5nIEFzIFN0cmlu +Zw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICBJZiAoUmVsYXRpb25h +bE9wZXJhdG9yIEFuZCBTUUxfU3BsaXRWYWx1ZVRvQXJyYXkpID0gU1FMX1NwbGl0 +VmFsdWVUb0FycmF5IFRoZW4NCiAgICAgIA0KICAgICAgUmVsYXRpb25hbE9wZXJh +dG9yID0gUmVsYXRpb25hbE9wZXJhdG9yIFhvciBTUUxfU3BsaXRWYWx1ZVRvQXJy +YXkNCiAgICAgIA0KICAgICAgSWYgSW5TdHIoMSwgRmlsdGVyVmFsdWUsIFNxbE9y +Q29uY2F0U3RyaW5nLCB2YlRleHRDb21wYXJlKSA+IDAgVGhlbg0KICAgICAgICAg +RmlsdGVyVmFsdWUgPSBSZXBsYWNlKEZpbHRlclZhbHVlLCBTcWxPckNvbmNhdFN0 +cmluZywgIjsiKQ0KICAgICAgRW5kIElmDQogICAgICANCiAgICAgIElmIEluU3Ry +KDEsIEZpbHRlclZhbHVlLCBTcWxBbmRDb25jYXRTdHJpbmcsIHZiVGV4dENvbXBh +cmUpID4gMCBUaGVuDQogICAgICAgICBGaWx0ZXJWYWx1ZSA9IFJlcGxhY2UoRmls +dGVyVmFsdWUsIFNxbEFuZENvbmNhdFN0cmluZywgIisiKQ0KICAgICAgRW5kIElm +DQogICAgICANCiAgICAgIElmIEluU3RyKDEsIEZpbHRlclZhbHVlLCAiOyIpID4g +MCBUaGVuDQogICAgICAgICBJZiBJblN0cigxLCBGaWx0ZXJWYWx1ZSwgIisiKSA+ +IDAgVGhlbg0KICAgICAgICAgICAgUmVsYXRpb25hbE9wZXJhdG9yID0gUmVsYXRp +b25hbE9wZXJhdG9yIE9yIFNRTF9TcGxpdFZhbHVlVG9BcnJheQ0KICAgICAgICAg +RW5kIElmDQogICAgICAgICBDcml0ZXJpYUNvbmNhdFN0cmluZyA9IFNxbE9yQ29u +Y2F0U3RyaW5nDQogICAgICAgICBGaWx0ZXJWYWx1ZSA9IFNwbGl0KENoYXJUcmlt +KEZpbHRlclZhbHVlLCAiOyIpLCAiOyIpDQogICAgICAgICBWYWx1ZVNwbGl0dGVk +ID0gVHJ1ZQ0KICAgICAgRWxzZUlmIEluU3RyKDEsIEZpbHRlclZhbHVlLCAiKyIp +ID4gMCBUaGVuDQogICAgICAgICBDcml0ZXJpYUNvbmNhdFN0cmluZyA9IFNxbEFu +ZENvbmNhdFN0cmluZw0KICAgICAgICAgRmlsdGVyVmFsdWUgPSBTcGxpdChDaGFy +VHJpbShGaWx0ZXJWYWx1ZSwgIisiKSwgIisiKQ0KICAgICAgICAgVmFsdWVTcGxp +dHRlZCA9IFRydWUNCiAgICAgIEVuZCBJZg0KICAgRW5kIElmDQogICANCiAgIElm +IFZhbHVlU3BsaXR0ZWQgVGhlbg0KICAgDQogICAgICBJZiBDcml0ZXJpYUNvbmNh +dFN0cmluZyA9IFNxbE9yQ29uY2F0U3RyaW5nIFRoZW4NCiAgICAgIElmIFRyeUJ1 +aWxkSW5Dcml0ZXJpYShGaWVsZE5hbWUsIEZpZWxkRGF0YVR5cGUsIFJlbGF0aW9u +YWxPcGVyYXRvciwgRmlsdGVyVmFsdWUsIElnbm9yZVZhbHVlLCBDcml0ZXJpYSkg +VGhlbg0KICAgICAgICAgRXhpdCBGdW5jdGlvbg0KICAgICAgRW5kIElmDQogICAg +ICBFbmQgSWYNCiAgIA0KICAgICAgVHJ5QnVpbGRTcGxpdFRvQXJyYXlDcml0ZXJp +YSA9IFRyeUJ1aWxkQXJyYXlDcml0ZXJpYShGaWVsZE5hbWUsIEZpZWxkRGF0YVR5 +cGUsIFJlbGF0aW9uYWxPcGVyYXRvciwgRmlsdGVyVmFsdWUsIElnbm9yZVZhbHVl +LCBDcml0ZXJpYSwgQ3JpdGVyaWFDb25jYXRTdHJpbmcpDQogICANCiAgIEVuZCBJ +Zg0KICAgDQpFbmQgRnVuY3Rpb24NCg0KDQpQcml2YXRlIEZ1bmN0aW9uIFRyeUJ1 +aWxkQXJyYXlDcml0ZXJpYShCeVJlZiBGaWVsZE5hbWUgQXMgU3RyaW5nLCBCeVZh +bCBGaWVsZERhdGFUeXBlIEFzIFNxbEZpZWxkRGF0YVR5cGUsIF8NCiAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5UmVmIFJlbGF0aW9uYWxP +cGVyYXRvciBBcyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzLCBfDQogICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCeVJlZiBGaWx0ZXJWYWx1ZSBB +cyBWYXJpYW50LCBfDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICBCeVJlZiBJZ25vcmVWYWx1ZSBBcyBWYXJpYW50LCBfDQogICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCeVJlZiBDcml0ZXJpYSBBcyBT +dHJpbmcsIF8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFs +IEJ5VmFsIENyaXRlcmlhQ29uY2F0U3RyaW5nIEFzIFN0cmluZyA9IFNxbE9yQ29u +Y2F0U3RyaW5nKSBBcyBCb29sZWFuDQogICBEaW0gaXRtIEFzIFZhcmlhbnQNCiAg +IERpbSBJdG1Dcml0ZXJpYSBBcyBTdHJpbmcNCiAgIA0KICAgRGltIGFyckZpbHRl +clZhbHVlKCkgQXMgVmFyaWFudA0KICAgDQogICBJZiBOb3QgSXNBcnJheShGaWx0 +ZXJWYWx1ZSkgVGhlbg0KICAgICAgRXhpdCBGdW5jdGlvbg0KICAgRW5kIElmDQoN +CiAgICdDb25uZWN0IGNyaXRlcmlhIHZpYSBPcg0KICAgRm9yIEVhY2ggaXRtIElu +IEZpbHRlclZhbHVlDQogICAgICBJdG1Dcml0ZXJpYSA9IEJ1aWxkQ3JpdGVyaWEo +RmllbGROYW1lLCBGaWVsZERhdGFUeXBlLCBSZWxhdGlvbmFsT3BlcmF0b3IsIGl0 +bSwgLCBJZ25vcmVWYWx1ZSwgRmFsc2UpDQogICAgICBJZiBMZW4oSXRtQ3JpdGVy +aWEpID4gMCBUaGVuDQogICAgICAgICBDcml0ZXJpYSA9IENyaXRlcmlhICYgQ3Jp +dGVyaWFDb25jYXRTdHJpbmcgJiBJdG1Dcml0ZXJpYQ0KICAgICAgRW5kIElmDQog +ICBOZXh0DQogICBJZiBMZW4oQ3JpdGVyaWEpID4gMCBUaGVuDQogICAgICBDcml0 +ZXJpYSA9IE1pZChDcml0ZXJpYSwgTGVuKENyaXRlcmlhQ29uY2F0U3RyaW5nKSAr +IDEpICcgMS4gT3Igd2Vnc2NobmVpZGVuDQogICBFbmQgSWYNCg0KICAgVHJ5QnVp +bGRBcnJheUNyaXRlcmlhID0gVHJ1ZQ0KDQpFbmQgRnVuY3Rpb24NCg0KUHJpdmF0 +ZSBGdW5jdGlvbiBUcnlCdWlsZEluQ3JpdGVyaWEoQnlSZWYgRmllbGROYW1lIEFz +IFN0cmluZywgQnlWYWwgRmllbGREYXRhVHlwZSBBcyBTcWxGaWVsZERhdGFUeXBl +LCBfDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCeVJlZiBS +ZWxhdGlvbmFsT3BlcmF0b3IgQXMgU3FsUmVsYXRpb25hbE9wZXJhdG9ycywgXw0K +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnlSZWYgRmlsdGVy +VmFsdWUgQXMgVmFyaWFudCwgXw0KICAgICAgICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgQnlSZWYgSWdub3JlVmFsdWUgQXMgVmFyaWFudCwgXw0KICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnlSZWYgQ3JpdGVyaWEgQXMg +U3RyaW5nKSBBcyBCb29sZWFuDQoNCiAgIERpbSBPcGVyYXRvclN0cmluZyBBcyBT +dHJpbmcNCiAgIERpbSBGaWx0ZXJWYWx1ZVN0cmluZyBBcyBTdHJpbmcNCg0KICAg +SWYgKFJlbGF0aW9uYWxPcGVyYXRvciBBbmQgU1FMX0luKSA9IDAgVGhlbg0KICAg +ICAgRXhpdCBGdW5jdGlvbg0KICAgRW5kIElmDQoNCiAgIElmIElzQXJyYXkoRmls +dGVyVmFsdWUpIFRoZW4NCiAgICAgIEZpbHRlclZhbHVlU3RyaW5nID0gR2V0VmFs +dWVBcnJheVN0cmluZyhGaWx0ZXJWYWx1ZSwgRmllbGREYXRhVHlwZSwgIiwiLCBJ +Z25vcmVWYWx1ZSkNCiAgIEVsc2VJZiBWYXJUeXBlKEZpbHRlclZhbHVlKSA9IHZi +U3RyaW5nIFRoZW4NCiAgICAgIElmIEZpZWxkRGF0YVR5cGUgPSBTUUxfVGV4dCBU +aGVuDQogICAgICAgICBJZiBMZWZ0KEZpbHRlclZhbHVlLCAxKSA9ICInIiBUaGVu +ICcgSXMgYWxyZWFkeSBhcyBTUUwgdGV4dCBpbiB0aGUgRmlsdGVyU3RyaW5nDQog +ICAgICAgICAgICBGaWx0ZXJWYWx1ZVN0cmluZyA9IEZpbHRlclZhbHVlDQogICAg +ICAgICBFbHNlDQogICAgICAgICAgICBGaWx0ZXJWYWx1ZVN0cmluZyA9IENvbnZl +cnRUb1NxbFRleHQoRmlsdGVyVmFsdWUsIEZpZWxkRGF0YVR5cGUpDQogICAgICAg +ICBFbmQgSWYNCiAgICAgIEVsc2UNCiAgICAgICAgIEZpbHRlclZhbHVlU3RyaW5n +ID0gRmlsdGVyVmFsdWUgJyBWYWx1ZSBpcyBhbHJlYWR5IGluIHRoZSBsaXN0aW5n +IGFzIGEgc3RyaW5nDQogICAgICBFbmQgSWYNCiAgIEVsc2UNCiAgICAgIEZpbHRl +clZhbHVlU3RyaW5nID0gQ29udmVydFRvU3FsVGV4dChGaWx0ZXJWYWx1ZSwgRmll +bGREYXRhVHlwZSkNCiAgIEVuZCBJZg0KDQogICBPcGVyYXRvclN0cmluZyA9ICIg +SW4gIg0KICAgSWYgKFJlbGF0aW9uYWxPcGVyYXRvciBBbmQgU1FMX05vdCkgPSBT +UUxfTm90IFRoZW4NCiAgICAgIE9wZXJhdG9yU3RyaW5nID0gIiBOb3QiICYgT3Bl +cmF0b3JTdHJpbmcNCiAgIEVuZCBJZg0KDQogICBJZiBMZW4oRmlsdGVyVmFsdWVT +dHJpbmcpID4gMCBUaGVuDQogICANCiAgICAgIElmIFJlbW92ZU51bGxGcm9tSW5W +YWx1ZVN0cmluZyhGaWx0ZXJWYWx1ZVN0cmluZykgVGhlbg0KICAgICAgICAgQ3Jp +dGVyaWEgPSBGaWVsZE5hbWUgJiAiIElzIE51bGwiDQogICAgICAgICBJZiBMZW4o +RmlsdGVyVmFsdWVTdHJpbmcpID4gMCBUaGVuDQogICAgICAgICAgICBDcml0ZXJp +YSA9IENyaXRlcmlhICYgIiBPciAiICYgRmllbGROYW1lICYgT3BlcmF0b3JTdHJp +bmcgJiAiKCIgJiBGaWx0ZXJWYWx1ZVN0cmluZyAmICIpIg0KICAgICAgICAgRW5k +IElmDQogICAgICBFbHNlDQogICAgICAgICBDcml0ZXJpYSA9IEZpZWxkTmFtZSAm +IE9wZXJhdG9yU3RyaW5nICYgIigiICYgRmlsdGVyVmFsdWVTdHJpbmcgJiAiKSIN +CiAgICAgIEVuZCBJZg0KICAgIA0KICAgRW5kIElmDQoNCiAgIFRyeUJ1aWxkSW5D +cml0ZXJpYSA9IFRydWUNCg0KRW5kIEZ1bmN0aW9uDQoNClByaXZhdGUgRnVuY3Rp +b24gVHJ5QnVpbGRCZXR3ZWVuQ3JpdGVyaWEoQnlSZWYgRmllbGROYW1lIEFzIFN0 +cmluZywgQnlWYWwgRmllbGREYXRhVHlwZSBBcyBTcWxGaWVsZERhdGFUeXBlLCBf +DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5UmVm +IFJlbGF0aW9uYWxPcGVyYXRvciBBcyBTcWxSZWxhdGlvbmFsT3BlcmF0b3JzLCBf +DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5UmVm +IEZpbHRlclZhbHVlIEFzIFZhcmlhbnQsIF8NCiAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgQnlSZWYgRmlsdGVyVmFsdWUyIEFzIFZhcmlh +bnQsIF8NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg +QnlSZWYgSWdub3JlVmFsdWUgQXMgVmFyaWFudCwgXw0KICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICBCeVJlZiBDcml0ZXJpYSBBcyBTdHJp +bmcpIEFzIEJvb2xlYW4NCiAgIA0KICAgRGltIENyaXRlcmlhMSBBcyBTdHJpbmcN +CiAgIERpbSBDcml0ZXJpYTIgQXMgU3RyaW5nDQogICANCiAgIElmIChSZWxhdGlv +bmFsT3BlcmF0b3IgQW5kIFNRTF9CZXR3ZWVuKSA9IEZhbHNlIFRoZW4NCiAgICAg +IFRyeUJ1aWxkQmV0d2VlbkNyaXRlcmlhID0gRmFsc2UNCiAgICAgIEV4aXQgRnVu +Y3Rpb24NCiAgIEVuZCBJZg0KICAgDQogICBJZiAoUmVsYXRpb25hbE9wZXJhdG9y +IEFuZCBTUUxfTm90KSA9IFNRTF9Ob3QgVGhlbiAnUmV2ZXJzZSBjb25kaXRpb24N +CiAgICAgIENyaXRlcmlhMSA9IEJ1aWxkQ3JpdGVyaWEoRmllbGROYW1lLCBGaWVs +ZERhdGFUeXBlLCBTUUxfTGVzc1RoYW4sIEZpbHRlclZhbHVlLCAsIElnbm9yZVZh +bHVlLCBGYWxzZSkNCiAgICAgIENyaXRlcmlhMiA9IEJ1aWxkQ3JpdGVyaWEoRmll +bGROYW1lLCBGaWVsZERhdGFUeXBlLCBTUUxfR3JlYXRlclRoYW4sIEZpbHRlclZh +bHVlMiwgLCBJZ25vcmVWYWx1ZSwgRmFsc2UpDQogICAgICBDcml0ZXJpYSA9IENy +aXRlcmlhMSAmIFNxbEFuZENvbmNhdFN0cmluZyAmIENyaXRlcmlhMg0KICAgICAg +VHJ5QnVpbGRCZXR3ZWVuQ3JpdGVyaWEgPSBUcnVlDQogICAgICBFeGl0IEZ1bmN0 +aW9uDQogICBFbmQgSWYNCiAgIA0KICAgSWYgRmllbGREYXRhVHlwZSA9IFNRTF9O +dW1lcmljIFRoZW4NCiAgICAgIElmIEZpbHRlclZhbHVlMiBMaWtlICI8PSoiIFRo +ZW4gJ2N1dCBhd2F5DQogICAgICAgICBGaWx0ZXJWYWx1ZTIgPSBNaWQoRmlsdGVy +VmFsdWUyLCAzKQ0KICAgICAgRWxzZUlmIEZpbHRlclZhbHVlMiBMaWtlICI8KiIg +VGhlbg0KICAgICAgICAgRmlsdGVyVmFsdWUyID0gTWlkKEZpbHRlclZhbHVlMiwg +MikNCiAgICAgICAgIENyaXRlcmlhMSA9IEJ1aWxkQ3JpdGVyaWEoRmllbGROYW1l +LCBGaWVsZERhdGFUeXBlLCBTUUxfR3JlYXRlclRoYW4gKyBTUUxfRXF1YWwsIEZp +bHRlclZhbHVlLCAsIE51bGwsIEZhbHNlKQ0KICAgICAgICAgQ3JpdGVyaWEyID0g +QnVpbGRDcml0ZXJpYShGaWVsZE5hbWUsIEZpZWxkRGF0YVR5cGUsIFNRTF9MZXNz +VGhhbiwgRmlsdGVyVmFsdWUyLCAsIE51bGwsIEZhbHNlKQ0KICAgICAgICAgQ3Jp +dGVyaWEgPSBDcml0ZXJpYTEgJiBTcWxBbmRDb25jYXRTdHJpbmcgJiBDcml0ZXJp +YTINCiAgICAgICAgIFRyeUJ1aWxkQmV0d2VlbkNyaXRlcmlhID0gVHJ1ZQ0KICAg +ICAgICAgRXhpdCBGdW5jdGlvbg0KICAgICAgRW5kIElmDQogICBFbmQgSWYNCg0K +ICAgSWYgSXNOdWxsKEZpbHRlclZhbHVlMikgT3IgSXNNaXNzaW5nKEZpbHRlclZh +bHVlMikgT3IgVmFsdWVzQXJlRXF1YWwoRmllbGREYXRhVHlwZSwgRmlsdGVyVmFs +dWUyLCBJZ25vcmVWYWx1ZSkgVGhlbg0KICAgICAgUmVsYXRpb25hbE9wZXJhdG9y +ID0gU1FMX0dyZWF0ZXJUaGFuICsgU1FMX0VxdWFsDQogICBFbHNlSWYgSXNOdWxs +KEZpbHRlclZhbHVlKSBPciBWYWx1ZXNBcmVFcXVhbChGaWVsZERhdGFUeXBlLCBG +aWx0ZXJWYWx1ZSwgSWdub3JlVmFsdWUpIFRoZW4NCiAgICAgIFJlbGF0aW9uYWxP +cGVyYXRvciA9IFNRTF9MZXNzVGhhbiArIFNRTF9FcXVhbA0KICAgICAgRmlsdGVy +VmFsdWUgPSBGaWx0ZXJWYWx1ZTINCiAgICAgIEZpbHRlclZhbHVlMiA9IEdldENo +ZWNrZWRJZ25vcmVWYWx1ZShJZ25vcmVWYWx1ZSkNCiAgIEVsc2VJZiAoRmllbGRE +YXRhVHlwZSBBbmQgU1FMX0RhdGUpID0gU1FMX0RhdGUgQW5kIChSZWxhdGlvbmFs +T3BlcmF0b3IgQW5kIFNRTF9BZGRfV2lsZENhcmRTdWZmaXgpIFRoZW4NCiAgICAg +IENyaXRlcmlhMSA9IEJ1aWxkQ3JpdGVyaWEoRmllbGROYW1lLCBGaWVsZERhdGFU +eXBlLCBTUUxfR3JlYXRlclRoYW4gKyBTUUxfRXF1YWwsIEZpbHRlclZhbHVlLCAs +IE51bGwsIEZhbHNlKQ0KICAgICAgQ3JpdGVyaWEyID0gQnVpbGRDcml0ZXJpYShG +aWVsZE5hbWUsIEZpZWxkRGF0YVR5cGUsIFNRTF9MZXNzVGhhbiArIFNRTF9FcXVh +bCArIFNRTF9BZGRfV2lsZENhcmRTdWZmaXgsIEZpbHRlclZhbHVlMiwgLCBOdWxs +LCBGYWxzZSkNCiAgICAgIENyaXRlcmlhID0gQ3JpdGVyaWExICYgU3FsQW5kQ29u +Y2F0U3RyaW5nICYgQ3JpdGVyaWEyDQogICAgICBUcnlCdWlsZEJldHdlZW5Dcml0 +ZXJpYSA9IFRydWUNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVsc2VJZiAoRmll +bGREYXRhVHlwZSBBbmQgU1FMX051bWVyaWMpID0gU1FMX051bWVyaWMgQW5kIChS +ZWxhdGlvbmFsT3BlcmF0b3IgQW5kIFNRTF9BZGRfV2lsZENhcmRTdWZmaXgpIFRo +ZW4NCiAgICAgIENyaXRlcmlhMSA9IEJ1aWxkQ3JpdGVyaWEoRmllbGROYW1lLCBG +aWVsZERhdGFUeXBlLCBTUUxfR3JlYXRlclRoYW4gKyBTUUxfRXF1YWwsIEZpbHRl +clZhbHVlLCAsIE51bGwsIEZhbHNlKQ0KICAgICAgQ3JpdGVyaWEyID0gQnVpbGRD +cml0ZXJpYShGaWVsZE5hbWUsIEZpZWxkRGF0YVR5cGUsIFNRTF9MZXNzVGhhbiAr +IFNRTF9FcXVhbCArIFNRTF9BZGRfV2lsZENhcmRTdWZmaXgsIEZpbHRlclZhbHVl +MiwgLCBOdWxsLCBGYWxzZSkNCiAgICAgIENyaXRlcmlhID0gQ3JpdGVyaWExICYg +U3FsQW5kQ29uY2F0U3RyaW5nICYgQ3JpdGVyaWEyDQogICAgICBUcnlCdWlsZEJl +dHdlZW5Dcml0ZXJpYSA9IFRydWUNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVs +c2UNCiAgICAgIENyaXRlcmlhID0gRmllbGROYW1lICYgIiBCZXR3ZWVuICIgJiBD +b252ZXJ0VG9TcWxUZXh0KEZpbHRlclZhbHVlLCBGaWVsZERhdGFUeXBlKSAmIFNx +bEFuZENvbmNhdFN0cmluZyAmIENvbnZlcnRUb1NxbFRleHQoRmlsdGVyVmFsdWUy +LCBGaWVsZERhdGFUeXBlKQ0KICAgICAgVHJ5QnVpbGRCZXR3ZWVuQ3JpdGVyaWEg +PSBUcnVlDQogICAgICBFeGl0IEZ1bmN0aW9uDQogICBFbmQgSWYNCg0KRW5kIEZ1 +bmN0aW9uDQoNClByaXZhdGUgRnVuY3Rpb24gR2V0Q2hlY2tlZElnbm9yZVZhbHVl +KEJ5VmFsIElnbm9yZVZhbHVlIEFzIFZhcmlhbnQpIEFzIFZhcmlhbnQNCiAgIElm +IElzQXJyYXkoSWdub3JlVmFsdWUpIFRoZW4NCiAgICAgIEdldENoZWNrZWRJZ25v +cmVWYWx1ZSA9IElnbm9yZVZhbHVlKExCb3VuZChJZ25vcmVWYWx1ZSkpDQogICBF +bHNlDQogICAgICBHZXRDaGVja2VkSWdub3JlVmFsdWUgPSBJZ25vcmVWYWx1ZQ0K +ICAgRW5kIElmDQpFbmQgRnVuY3Rpb24NCg0KUHJpdmF0ZSBGdW5jdGlvbiBOdWxs +RmlsdGVyT3JFbXB0eUZpbHRlcihCeVZhbCBGaWVsZE5hbWUgQXMgU3RyaW5nLCBC +eVZhbCBGaWVsZERhdGFUeXBlIEFzIFNxbEZpZWxkRGF0YVR5cGUsIF8NCiAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnlWYWwgUmVsYXRp +b25hbE9wZXJhdG9yIEFzIFNxbFJlbGF0aW9uYWxPcGVyYXRvcnMsIF8NCiAgICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnlWYWwgVmFsdWUg +QXMgVmFyaWFudCwgQnlWYWwgSWdub3JlVmFsdWUgQXMgVmFyaWFudCwgXw0KICAg +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCeVJlZiBOdWxs +RmlsdGVyU3RyaW5nIEFzIFN0cmluZywgXw0KICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICBPcHRpb25hbCBCeVZhbCBEaXNhYmxlSWdub3JlTnVsbFZhbHVl +IEFzIEJvb2xlYW4gPSBGYWxzZSkgQXMgQm9vbGVhbg0KICAgDQogICBJZiBJc09i +amVjdChJZ25vcmVWYWx1ZSkgVGhlbg0KICAgSWYgSWdub3JlVmFsdWUgSXMgTm90 +aGluZyBUaGVuDQogICAgICBJZiBJc051bGwoVmFsdWUpIFRoZW4NCiAgICAgICAg +IElmIChSZWxhdGlvbmFsT3BlcmF0b3IgQW5kIFNRTF9Ob3QpID0gU1FMX05vdCBU +aGVuDQogICAgICAgICAgICBOdWxsRmlsdGVyU3RyaW5nID0gRmllbGROYW1lICYg +IiBJcyBOb3QgTnVsbCINCiAgICAgICAgIEVsc2UNCiAgICAgICAgICAgIE51bGxG +aWx0ZXJTdHJpbmcgPSBGaWVsZE5hbWUgJiAiIElzIE51bGwiDQogICAgICAgICBF +bmQgSWYNCiAgICAgICAgIE51bGxGaWx0ZXJPckVtcHR5RmlsdGVyID0gVHJ1ZQ0K +ICAgICAgRWxzZQ0KICAgICAgICAgTnVsbEZpbHRlck9yRW1wdHlGaWx0ZXIgPSBG +YWxzZQ0KICAgICAgRW5kIElmDQogICAgICBFeGl0IEZ1bmN0aW9uDQogICBFbmQg +SWYNCiAgIEVuZCBJZg0KICAgDQogICBJZiBJc051bGwoVmFsdWUpIFRoZW4NCiAg +ICAgIElmIERpc2FibGVJZ25vcmVOdWxsVmFsdWUgVGhlbg0KICAgICAgICAgTnVs +bEZpbHRlclN0cmluZyA9IEZpZWxkTmFtZSAmICIgSXMgTnVsbCINCiAgICAgIEVs +c2VJZiBOb3QgVmFsdWVzQXJlRXF1YWwoRmllbGREYXRhVHlwZSwgVmFsdWUsIEln +bm9yZVZhbHVlKSBUaGVuDQogICAgICAgICBOdWxsRmlsdGVyU3RyaW5nID0gRmll +bGROYW1lICYgIiBJcyBOdWxsIg0KICAgICAgRW5kIElmDQogICAgICBOdWxsRmls +dGVyT3JFbXB0eUZpbHRlciA9IFRydWUNCiAgIEVsc2VJZiBJc0FycmF5KFZhbHVl +KSBUaGVuDQogICAgICBEaW0gQ2hlY2tBcnJheSgpIEFzIFZhcmlhbnQNCk9uIEVy +cm9yIFJlc3VtZSBOZXh0DQogICAgICBDaGVja0FycmF5ID0gVmFsdWUNCiAgICAg +IElmIEVyci5OdW1iZXIgPSAwIFRoZW4NCiAgICAgIElmICgwIC8gMSkgKyAoTm90 +IE5vdCBDaGVja0FycmF5KSA9IDAgVGhlbg0KICAgICAgICAgTnVsbEZpbHRlck9y +RW1wdHlGaWx0ZXIgPSBUcnVlDQogICAgICAgICBFeGl0IEZ1bmN0aW9uDQogICAg +ICBFbmQgSWYNCiAgICAgIEVsc2UNCiAgICAgICAgIEVyci5DbGVhcg0KICAgICAg +ICAgRGltIEFycmF5U2l6ZSBBcyBMb25nDQogICAgICAgICBBcnJheVNpemUgPSBV +Qm91bmQoVmFsdWUpDQogICAgICAgICBJZiBFcnIuTnVtYmVyIDw+IDAgVGhlbg0K +ICAgICAgICAgICAgRXJyLkNsZWFyDQogICAgICAgICAgICBOdWxsRmlsdGVyT3JF +bXB0eUZpbHRlciA9IFRydWUNCiAgICAgICAgICAgIEV4aXQgRnVuY3Rpb24NCiAg +ICAgICAgIEVuZCBJZg0KICAgICAgRW5kIElmDQogICBFbHNlDQogICAgICBOdWxs +RmlsdGVyT3JFbXB0eUZpbHRlciA9IFZhbHVlc0FyZUVxdWFsKEZpZWxkRGF0YVR5 +cGUsIFZhbHVlLCBJZ25vcmVWYWx1ZSkNCiAgIEVuZCBJZg0KICAgDQogICBJZiAo +UmVsYXRpb25hbE9wZXJhdG9yIEFuZCBTUUxfTm90KSA9IFNRTF9Ob3QgVGhlbg0K +ICAgICAgICAgTnVsbEZpbHRlclN0cmluZyA9IFJlcGxhY2UoTnVsbEZpbHRlclN0 +cmluZywgIklzIE51bGwiLCAiSXMgTm90IE51bGwiKQ0KICAgRW5kIElmDQoNCkVu +ZCBGdW5jdGlvbg0KDQpQcml2YXRlIEZ1bmN0aW9uIFZhbHVlc0FyZUVxdWFsKEJ5 +VmFsIEZpZWxkRGF0YVR5cGUgQXMgU3FsRmllbGREYXRhVHlwZSwgQnlWYWwgVmFs +dWUgQXMgVmFyaWFudCwgQnlWYWwgVmFsdWUyIEFzIFZhcmlhbnQpIEFzIEJvb2xl +YW4NCiAgIA0KICAgSWYgSXNBcnJheShWYWx1ZTIpIFRoZW4NCiAgICAgIFZhbHVl +c0FyZUVxdWFsID0gQXJyYXlDb250YWlucyhGaWVsZERhdGFUeXBlLCBWYWx1ZTIs +IFZhbHVlKQ0KICAgRWxzZUlmIElzTnVsbChWYWx1ZSkgVGhlbg0KICAgICAgVmFs +dWVzQXJlRXF1YWwgPSBJc051bGwoVmFsdWUyKQ0KICAgRWxzZUlmIElzTnVsbChW +YWx1ZTIpIFRoZW4NCiAgICAgIFZhbHVlc0FyZUVxdWFsID0gRmFsc2UNCiAgIEVs +c2UNCiAgICAgIFNlbGVjdCBDYXNlIEZpZWxkRGF0YVR5cGUNCiAgICAgICAgIENh +c2UgU3FsRmllbGREYXRhVHlwZS5TUUxfVGV4dA0KICAgICAgICAgICAgVmFsdWVz +QXJlRXF1YWwgPSAoVkJBLlN0ckNvbXAoVmFsdWUsIFZhbHVlMiwgdmJUZXh0Q29t +cGFyZSkgPSAwKQ0KICAgICAgICAgQ2FzZSBTcWxGaWVsZERhdGFUeXBlLlNRTF9O +dW1lcmljDQogICAgICAgICAgICBWYWx1ZXNBcmVFcXVhbCA9IChDRGJsKFZhbHVl +KSA9IENEYmwoVmFsdWUyKSkNCiAgICAgICAgIENhc2UgU3FsRmllbGREYXRhVHlw +ZS5TUUxfRGF0ZQ0KICAgICAgICAgICAgVmFsdWVzQXJlRXF1YWwgPSAoQ0RhdGUo +VmFsdWUpID0gQ0RhdGUoVmFsdWUyKSkNCiAgICAgICAgIENhc2UgU3FsRmllbGRE +YXRhVHlwZS5TUUxfQm9vbGVhbg0KICAgICAgICAgICAgVmFsdWVzQXJlRXF1YWwg +PSAoQ0Jvb2woVmFsdWUpID0gQ0Jvb2woVmFsdWUyKSkNCiAgICAgICAgIENhc2Ug +RWxzZQ0KICAgICAgICAgICAgVmFsdWVzQXJlRXF1YWwgPSAoVmFsdWUgPSBWYWx1 +ZTIpDQogICAgICBFbmQgU2VsZWN0DQogICBFbmQgSWYNCg0KRW5kIEZ1bmN0aW9u +DQoNClByaXZhdGUgRnVuY3Rpb24gQXJyYXlDb250YWlucyhCeVZhbCBGaWVsZERh +dGFUeXBlIEFzIFNxbEZpZWxkRGF0YVR5cGUsIEJ5VmFsIEFycmF5VG9DaGVjayBB +cyBWYXJpYW50LCBCeVZhbCBTZWFyY2hWYWx1ZSBBcyBWYXJpYW50KSBBcyBCb29s +ZWFuDQogICANCiAgIERpbSBpIEFzIExvbmcNCg0KICAgSWYgSXNOdWxsKFNlYXJj +aFZhbHVlKSBUaGVuDQogICAgICBBcnJheUNvbnRhaW5zID0gQXJyYXlDb250YWlu +c051bGwoQXJyYXlUb0NoZWNrKQ0KICAgICAgRXhpdCBGdW5jdGlvbg0KICAgRW5k +IElmDQoNCiAgIEZvciBpID0gTEJvdW5kKEFycmF5VG9DaGVjaykgVG8gVUJvdW5k +KEFycmF5VG9DaGVjaykNCiAgICAgIElmIFZhbHVlc0FyZUVxdWFsKEZpZWxkRGF0 +YVR5cGUsIEFycmF5VG9DaGVjayhpKSwgU2VhcmNoVmFsdWUpIFRoZW4NCiAgICAg +ICAgIEFycmF5Q29udGFpbnMgPSBUcnVlDQogICAgICAgICBFeGl0IEZ1bmN0aW9u +DQogICAgICBFbmQgSWYNCiAgIE5leHQNCg0KICAgQXJyYXlDb250YWlucyA9IEZh +bHNlDQoNCkVuZCBGdW5jdGlvbg0KDQpQcml2YXRlIEZ1bmN0aW9uIEFycmF5Q29u +dGFpbnNOdWxsKEJ5VmFsIEFycmF5VG9DaGVjayBBcyBWYXJpYW50KSBBcyBCb29s +ZWFuDQogICANCiAgIERpbSBpIEFzIExvbmcNCg0KICAgRm9yIGkgPSBMQm91bmQo +QXJyYXlUb0NoZWNrKSBUbyBVQm91bmQoQXJyYXlUb0NoZWNrKQ0KICAgICAgSWYg +SXNOdWxsKEFycmF5VG9DaGVjayhpKSkgVGhlbg0KICAgICAgICAgQXJyYXlDb250 +YWluc051bGwgPSBUcnVlDQogICAgICAgICBFeGl0IEZ1bmN0aW9uDQogICAgICBF +bmQgSWYNCiAgIE5leHQNCg0KICAgQXJyYXlDb250YWluc051bGwgPSBGYWxzZQ0K +DQpFbmQgRnVuY3Rpb24NCg0KUHJpdmF0ZSBGdW5jdGlvbiBHZXRWYWx1ZUFycmF5 +U3RyaW5nKEJ5VmFsIFZhbHVlIEFzIFZhcmlhbnQsIEJ5VmFsIEZpZWxkRGF0YVR5 +cGUgQXMgU3FsRmllbGREYXRhVHlwZSwgXw0KICAgICAgICAgICAgICAgICAgICAg +ICAgICAgICAgICAgICAgIEJ5VmFsIERlbGltaXRlciBBcyBTdHJpbmcsIEJ5VmFs +IElnbm9yZVZhbHVlIEFzIFZhcmlhbnQpIEFzIFN0cmluZw0KICAgDQogICBEaW0g +aSBBcyBMb25nDQogICBEaW0gcyBBcyBTdHJpbmcNCg0KICAgRm9yIGkgPSBMQm91 +bmQoVmFsdWUpIFRvIFVCb3VuZChWYWx1ZSkNCiAgICAgIElmIElzQXJyYXkoSWdu +b3JlVmFsdWUpIFRoZW4NCiAgICAgICAgIElmIEFycmF5Q29udGFpbnMoRmllbGRE +YXRhVHlwZSwgSWdub3JlVmFsdWUsIFZhbHVlKGkpKSBUaGVuDQogICAgICAgICBF +bHNlDQogICAgICAgICAgICBzID0gcyAmIERlbGltaXRlciAmIENvbnZlcnRUb1Nx +bFRleHQoVmFsdWUoaSksIEZpZWxkRGF0YVR5cGUpDQogICAgICAgICBFbmQgSWYN +CiAgICAgIEVsc2UNCiAgICAgICAgIElmIFZhbHVlKGkpID0gSWdub3JlVmFsdWUg +VGhlbg0KICAgICAgICAgRWxzZUlmIElzTnVsbChWYWx1ZShpKSkgQW5kIElzTnVs +bChJZ25vcmVWYWx1ZSkgVGhlbg0KICAgICAgICAgRWxzZQ0KICAgICAgICAgICAg +cyA9IHMgJiBEZWxpbWl0ZXIgJiBDb252ZXJ0VG9TcWxUZXh0KFZhbHVlKGkpLCBG +aWVsZERhdGFUeXBlKQ0KICAgICAgICAgRW5kIElmDQogICAgICBFbmQgSWYNCiAg +IE5leHQNCiAgIElmIExlbihzKSA+IDAgQW5kIExlbihEZWxpbWl0ZXIpID4gMCBU +aGVuDQogICAgICBzID0gTWlkKHMsIExlbihEZWxpbWl0ZXIpICsgMSkNCiAgIEVu +ZCBJZg0KICAgR2V0VmFsdWVBcnJheVN0cmluZyA9IHMNCg0KRW5kIEZ1bmN0aW9u +DQoNClByaXZhdGUgRnVuY3Rpb24gUmVtb3ZlTnVsbEZyb21JblZhbHVlU3RyaW5n +KEJ5UmVmIFZhbHVlU3RyaW5nIEFzIFN0cmluZykgQXMgQm9vbGVhbg0KDQogICBD +b25zdCBOdWxsQ2hlY2tTdHJpbmcgQXMgU3RyaW5nID0gIixOdWxsLCINCiAgIERp +bSBUZXN0U3RyaW5nIEFzIFN0cmluZw0KICAgDQogICBUZXN0U3RyaW5nID0gIiwi +ICYgVmFsdWVTdHJpbmcgJiAiLCINCg0KICAgSWYgTm90IChJblN0cigxLCBUZXN0 +U3RyaW5nLCBOdWxsQ2hlY2tTdHJpbmcpID4gMCkgVGhlbg0KICAgICAgUmVtb3Zl +TnVsbEZyb21JblZhbHVlU3RyaW5nID0gRmFsc2UNCiAgICAgIEV4aXQgRnVuY3Rp +b24NCiAgIEVuZCBJZg0KICAgDQogICBUZXN0U3RyaW5nID0gUmVwbGFjZShUZXN0 +U3RyaW5nLCBOdWxsQ2hlY2tTdHJpbmcsICIsIikNCiAgIA0KICAgSWYgTGVuKFRl +c3RTdHJpbmcpID4gMSBUaGVuDQogICAgICBWYWx1ZVN0cmluZyA9IE1pZChUZXN0 +U3RyaW5nLCAyLCBMZW4oVGVzdFN0cmluZykgLSAyKQ0KICAgRWxzZQ0KICAgICAg +VmFsdWVTdHJpbmcgPSB2Yk51bGxTdHJpbmcNCiAgIEVuZCBJZg0KICAgDQogICBS +ZW1vdmVOdWxsRnJvbUluVmFsdWVTdHJpbmcgPSBUcnVlDQoNCkVuZCBGdW5jdGlv +bg0K + + 20250609094839 + data/SqlTools.cls + + + StringCollection + VkVSU0lPTiAxLjAgQ0xBU1MNCkJFR0lODQogIE11bHRpVXNlID0gLTEgICdUcnVl +DQpFTkQNCkF0dHJpYnV0ZSBWQl9OYW1lID0gIlN0cmluZ0NvbGxlY3Rpb24iDQpB +dHRyaWJ1dGUgVkJfR2xvYmFsTmFtZVNwYWNlID0gRmFsc2UNCkF0dHJpYnV0ZSBW +Ql9DcmVhdGFibGUgPSBGYWxzZQ0KQXR0cmlidXRlIFZCX1ByZWRlY2xhcmVkSWQg +PSBGYWxzZQ0KQXR0cmlidXRlIFZCX0V4cG9zZWQgPSBGYWxzZQ0KJy0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJyBDbGFzczogdGV4dC5T +dHJpbmdDb2xsZWN0aW9uDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tDQonDQonIENvbGxlY3Rpb24gZm9yIHN0cmluZ3MNCicNCicgQXV0 +aG9yOg0KJyAgICAgSm9zZWYgUG9ldHpsDQonDQonLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0NCic8Y29kZWxpYj4NCicgIDxmaWxlPnRleHQvU3Ry +aW5nQ29sbGVjdGlvbi5jbHM8L2ZpbGU+DQonICA8bGljZW5zZT5fY29kZWxpYi9s +aWNlbnNlLmJhczwvbGljZW5zZT4NCicgIDx0ZXN0Pl90ZXN0L3RleHQvU3RyaW5n +Q29sbGVjdGlvblRlc3RzLmNsczwvdGVzdD4NCic8L2NvZGVsaWI+DQonLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonDQpPcHRpb24gQ29t +cGFyZSBUZXh0DQpPcHRpb24gRXhwbGljaXQNCg0KUHJpdmF0ZSBtX0l0ZW1zIEFz +IENvbGxlY3Rpb24NCg0KUHJpdmF0ZSBTdWIgQ2xhc3NfSW5pdGlhbGl6ZSgpDQog +ICBTZXQgbV9JdGVtcyA9IE5ldyBDb2xsZWN0aW9uDQpFbmQgU3ViDQoNClByaXZh +dGUgU3ViIENsYXNzX1Rlcm1pbmF0ZSgpDQogICBTZXQgbV9JdGVtcyA9IE5vdGhp +bmcNCkVuZCBTdWINCg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLQ0KJyBQcm9wZXJ0eTogU2VsZg0KJy0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBSZWZlcmVuY2UgdG8gc2VsZiAoTWUp +DQonDQonIFJlbWFya3M6DQonICAgICBVc2VmdWwgZm9yIHdpdGgtYmxvY2sNCicN +CicgUmV0dXJuczoNCicgICAgIERhdGFiYXNlLlN0cmluZ0NvbGxlY3Rpb24NCicN +CictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NClB1Ymxp +YyBQcm9wZXJ0eSBHZXQgU2VsZigpIEFzIFN0cmluZ0NvbGxlY3Rpb24NCiAgIFNl +dCBTZWxmID0gTWUNCkVuZCBQcm9wZXJ0eQ0KDQonLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonIFByb3BlcnR5OiBJdGVtcw0KJy0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBDb2xsZWN0 +aW9uIHdpdGggaXRlbXMNCicNCicgUmV0dXJuczoNCicgICAgIFZCQS5Db2xsZWN0 +aW9uDQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +DQpQdWJsaWMgUHJvcGVydHkgR2V0IEl0ZW1zKCkgQXMgQ29sbGVjdGlvbg0KICAg +U2V0IEl0ZW1zID0gbV9JdGVtcw0KRW5kIFByb3BlcnR5DQoNCictLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgUHJvcGVydHk6IEl0ZW0N +CictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicg +SXRlbSBvZiBDb2xsZWN0aW9uDQonDQonIFBhcmFtZXRlcnM6DQonICAgICBJbmRl +eCAtIChWYXJpYW50KQ0KJw0KJyBSZXR1cm5zOg0KJyAgICAgSXRlbSBzdHJpbmcg +LSAoU3RyaW5nKQ0KJw0KJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLQ0KUHVibGljIFByb3BlcnR5IEdldCBJdGVtKEJ5VmFsIEluZGV4IEFz +IFZhcmlhbnQpIEFzIFN0cmluZw0KICAgSXRlbSA9IG1fSXRlbXMuSXRlbShJbmRl +eCkNCkVuZCBQcm9wZXJ0eQ0KDQpQdWJsaWMgUHJvcGVydHkgTGV0IEl0ZW0oQnlW +YWwgSW5kZXggQXMgVmFyaWFudCwgQnlWYWwgTmV3VmFsdWUgQXMgU3RyaW5nKQ0K +QXR0cmlidXRlIEl0ZW0uVkJfVXNlck1lbUlkID0gMA0KICAgbV9JdGVtcy5BZGQg +TmV3VmFsdWUsICwgLCBJbmRleA0KICAgbV9JdGVtcy5SZW1vdmUgSW5kZXgNCkVu +ZCBQcm9wZXJ0eQ0KDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tDQonIFN1YjogQWRkDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tDQonDQonIEFkZCBzdHJpbmcgdG8gY29sbGVjdGlvbg0KJw0K +JyBQYXJhbWV0ZXJzOg0KJyAgICAgSXRlbSB0byBhZGQgLSAoU3RyaW5nKQ0KJw0K +Jy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGlj +IFN1YiBBZGQoQnlWYWwgSXRlbSBBcyBTdHJpbmcpDQogICBtX0l0ZW1zLkFkZCBJ +dGVtDQpFbmQgU3ViDQoNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0NCicgU3ViOiBBZGRGcm9tQXJyYXkNCictLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicNCicgQWRkIGl0ZW1zIGZvcm0gYW4g +YXJyYXkgdG8gY29sbGVjdGlvbg0KJw0KJyBQYXJhbWV0ZXJzOg0KJyAgICAgQXJy +YXlUb0FkZCAtIChWYXJpYW50KQ0KJyAgICAgSXRlbVN0cmluZ0Zvcm1hdCAtIChT +dHJpbmcpIEZvcm1hdCBlYWNoIGl0ZW0gb2YgQXJyYXkgd2l0aCBJdGVtU3RyaW5n +Rm9ybWF0IGJlZm9yZSBhZGQgdG8gY29sbGVjdGlvbg0KJw0KJy0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KUHVibGljIFN1YiBBZGRGcm9t +QXJyYXkoQnlSZWYgQXJyYXlUb0FkZCBBcyBWYXJpYW50LCBPcHRpb25hbCBCeVZh +bCBJdGVtU3RyaW5nRm9ybWF0IEFzIFN0cmluZyA9IHZiTnVsbFN0cmluZykNCg0K +ICAgRGltIGkgQXMgTG9uZw0KDQogICBGb3IgaSA9IExCb3VuZChBcnJheVRvQWRk +KSBUbyBVQm91bmQoQXJyYXlUb0FkZCkNCiAgICAgIG1fSXRlbXMuQWRkIEZvcm1h +dChBcnJheVRvQWRkKGkpLCBJdGVtU3RyaW5nRm9ybWF0KQ0KICAgTmV4dA0KDQpF +bmQgU3ViDQoNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0NCicgU3ViOiBBZGRGcm9tQ29sbGVjdGlvbg0KJy0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLQ0KJw0KJyBBZGQgaXRlbXMgZm9ybSBhIGNv +bGxlY3Rpb24gdG8gc3RyaW5nIGNvbGxlY3Rpb24NCicNCicgUGFyYW1ldGVyczoN +CicgICAgIENvbGxlY3Rpb25Ub0FwcGVuZCAtIChPYmplY3QpIC4uIHNvIHRoYXQg +YWxsIGNvbGxlY3Rpb25zIHdpdGggRW51bWFyYWJsZSBhbmQgSXRlbShpbmRleCkg +aW50ZXJmYWNlIGNhbiBiZSBydW4gdGhyb3VnaA0KJyAgICAgSXRlbVN0cmluZ0Zv +cm1hdCAgIC0gKFN0cmluZykgRm9ybWF0IGVhY2ggaXRlbSBvZiBjb2xsZWN0aW9u +IHdpdGggSXRlbVN0cmluZ0Zvcm1hdCBiZWZvcmUgYWRkIHRvIGNvbGxlY3Rpb24N +CicNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NClB1 +YmxpYyBTdWIgQWRkRnJvbUNvbGxlY3Rpb24oQnlWYWwgQ29sbGVjdGlvblRvQXBw +ZW5kIEFzIE9iamVjdCwgT3B0aW9uYWwgQnlWYWwgSXRlbVN0cmluZ0Zvcm1hdCBB +cyBTdHJpbmcgPSB2Yk51bGxTdHJpbmcpDQoNCiAgIERpbSBpdG0gQXMgVmFyaWFu +dA0KDQogICBGb3IgRWFjaCBpdG0gSW4gQ29sbGVjdGlvblRvQXBwZW5kDQogICAg +ICBtX0l0ZW1zLkFkZCBGb3JtYXQoaXRtLCBJdGVtU3RyaW5nRm9ybWF0KQ0KICAg +TmV4dA0KDQpFbmQgU3ViDQoNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0NCicgRnVuY3Rpb246IFRvU3RyaW5nDQonLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQonDQonIFJldHVybiBDb2xsZWN0 +aW9uIGl0ZW1zIGFzIGpvaW5lZCBTdHJpbmcNCicNCicgUGFyYW1ldGVyczoNCicg +ICAgIERlbGltaXRlciAgICAgICAgICAgICAtIChTdHJpbmcpIEV4YW1wbGU6ICIs +ICIgPT4gIkl0ZW0xLCBJdGVtMiwgSXRlbTMiDQonICAgICBJdGVtUHJlZml4ICAg +ICAgICAgICAgLSAoU3RyaW5nKSBQcmVmaXggZm9yIGVhY2ggaXRlbQ0KJyAgICAg +SXRlbVN1ZmZpeCAgICAgICAgICAgIC0gKFN0cmluZykgU3VmZml4IGZvciBlYWNo +IGl0ZW0NCicgICAgIElnbm9yZUVtcHR5VmFsdWUgICAgICAtIChCb29sZWFuKSBk +b24ndCBvdXRwdXQgYW4gZW1wdHkgaXRlbQ0KJyAgICAgSWdub3JlRHVwbGljYXRl +VmFsdWVzIC0gKEJvb2xlYW4pIFRydWUgPSBkb24ndCBvdXRwdXQgZHVwbGljYXRl +IGl0ZW1zDQonDQonIFJldHVybnM6DQonICAgICBTdHJpbmcNCicNCictLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NClB1YmxpYyBGdW5jdGlv +biBUb1N0cmluZyhPcHRpb25hbCBCeVZhbCBEZWxpbWl0ZXIgQXMgU3RyaW5nID0g +IiwgIiwgXw0KICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsIEJ5VmFs +IEl0ZW1QcmVmaXggQXMgU3RyaW5nID0gdmJOdWxsU3RyaW5nLCBfDQogICAgICAg +ICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgSXRlbVN1ZmZpeCBBcyBT +dHJpbmcgPSB2Yk51bGxTdHJpbmcsIF8NCiAgICAgICAgICAgICAgICAgICAgICAg +ICBPcHRpb25hbCBCeVZhbCBJZ25vcmVFbXB0eVZhbHVlIEFzIEJvb2xlYW4gPSBG +YWxzZSwgXw0KICAgICAgICAgICAgICAgICAgICAgICAgIE9wdGlvbmFsIEJ5VmFs +IElnbm9yZUR1cGxpY2F0ZVZhbHVlcyBBcyBCb29sZWFuID0gRmFsc2UpIEFzIFN0 +cmluZw0KICAgDQogICBEaW0gcyBBcyBTdHJpbmcNCg0KICAgcyA9IFZCQS5Kb2lu +KFRvU3RyaW5nQXJyYXkoSWdub3JlRW1wdHlWYWx1ZSwgSWdub3JlRHVwbGljYXRl +VmFsdWVzKSwgSXRlbVN1ZmZpeCAmIERlbGltaXRlciAmIEl0ZW1QcmVmaXgpDQog +ICBJZiBMZW4ocykgPiAwIFRoZW4gcyA9IEl0ZW1QcmVmaXggJiBzICYgSXRlbVN1 +ZmZpeA0KDQogICBUb1N0cmluZyA9IHMNCg0KRW5kIEZ1bmN0aW9uDQoNCictLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCicgRnVuY3Rpb246 +IFRvU3RyaW5nQXJyYXkNCictLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0NCicNCicgUmV0dXJuIENvbGxlY3Rpb24gaXRlbXMgYXMgU3RyaW5n +IGFycmF5DQonDQonIFBhcmFtZXRlcnM6DQonICAgICBJZ25vcmVFbXB0eVZhbHVl +ICAgICAgLSAoQm9vbGVhbikgZG9uJ3Qgb3V0cHV0IGFuIGVtcHR5IGl0ZW0NCicg +ICAgIElnbm9yZUR1cGxpY2F0ZVZhbHVlcyAtIChCb29sZWFuKSBUcnVlID0gZG9u +J3Qgb3V0cHV0IGR1cGxpY2F0ZSBpdGVtcw0KJw0KJyBSZXR1cm5zOg0KJyAgICAg +U3RyaW5nIGFycmF5DQonDQonLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t +LS0tLS0tLS0tDQpQdWJsaWMgRnVuY3Rpb24gVG9TdHJpbmdBcnJheShPcHRpb25h +bCBCeVZhbCBJZ25vcmVFbXB0eVZhbHVlIEFzIEJvb2xlYW4gPSBGYWxzZSwgXw0K +ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3B0aW9uYWwgQnlWYWwgSWdu +b3JlRHVwbGljYXRlVmFsdWVzIEFzIEJvb2xlYW4gPSBGYWxzZSkgQXMgU3RyaW5n +KCkNCg0KICAgRGltIEl0ZW1BcnJheSgpIEFzIFN0cmluZw0KICAgRGltIE1heEFy +cmF5SW5kZXggQXMgTG9uZw0KICAgRGltIGkgQXMgTG9uZw0KDQogICBNYXhBcnJh +eUluZGV4ID0gbV9JdGVtcy5Db3VudCAtIDENCg0KICAgSWYgTWF4QXJyYXlJbmRl +eCA8IDAgVGhlbg0KICAgICAgVG9TdHJpbmdBcnJheSA9IEl0ZW1BcnJheQ0KICAg +ICAgRXhpdCBGdW5jdGlvbg0KICAgRW5kIElmDQogICANCiAgIElmIElnbm9yZUVt +cHR5VmFsdWUgVGhlbg0KICAgICAgSWYgSWdub3JlRHVwbGljYXRlVmFsdWVzIFRo +ZW4NCiAgICAgICAgIFRvU3RyaW5nQXJyYXkgPSBSZW1vdmVEdXBsaWNhdGVWYWx1 +ZXMoR2V0QXJyYXlXaXRob3V0RW1wdHlWYWx1ZXMoKSkNCiAgICAgIEVsc2UNCiAg +ICAgICAgIFRvU3RyaW5nQXJyYXkgPSBHZXRBcnJheVdpdGhvdXRFbXB0eVZhbHVl +cygpDQogICAgICBFbmQgSWYNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJ +Zg0KDQogICBSZURpbSBJdGVtQXJyYXkoMCBUbyBNYXhBcnJheUluZGV4KQ0KICAg +Rm9yIGkgPSAwIFRvIE1heEFycmF5SW5kZXgNCiAgICAgIEl0ZW1BcnJheShpKSA9 +IG1fSXRlbXMuSXRlbShpICsgMSkNCiAgIE5leHQNCg0KICAgSWYgSWdub3JlRHVw +bGljYXRlVmFsdWVzIFRoZW4NCiAgICAgIFRvU3RyaW5nQXJyYXkgPSBSZW1vdmVE +dXBsaWNhdGVWYWx1ZXMoSXRlbUFycmF5KQ0KICAgRWxzZQ0KICAgICAgVG9TdHJp +bmdBcnJheSA9IEl0ZW1BcnJheQ0KICAgRW5kIElmDQogICANCkVuZCBGdW5jdGlv +bg0KDQpQcml2YXRlIEZ1bmN0aW9uIEdldEFycmF5V2l0aG91dEVtcHR5VmFsdWVz +KCkgQXMgU3RyaW5nKCkNCg0KICAgRGltIEl0ZW1BcnJheSgpIEFzIFN0cmluZw0K +ICAgRGltIE1heEFycmF5SW5kZXggQXMgTG9uZw0KICAgRGltIEl0ZW1JbmRleCBB +cyBMb25nDQogICBEaW0gaXRtIEFzIFZhcmlhbnQNCg0KICAgTWF4QXJyYXlJbmRl +eCA9IG1fSXRlbXMuQ291bnQgLSAxDQoNCiAgIElmIE1heEFycmF5SW5kZXggPCAw +IFRoZW4NCiAgICAgIEdldEFycmF5V2l0aG91dEVtcHR5VmFsdWVzID0gSXRlbUFy +cmF5DQogICAgICBFeGl0IEZ1bmN0aW9uDQogICBFbmQgSWYNCg0KICAgUmVEaW0g +SXRlbUFycmF5KDAgVG8gTWF4QXJyYXlJbmRleCkNCiAgIEl0ZW1JbmRleCA9IC0x +DQogICBGb3IgRWFjaCBpdG0gSW4gbV9JdGVtcw0KICAgICAgSWYgTGVuKGl0bSkg +PiAwIFRoZW4NCiAgICAgICAgIEl0ZW1JbmRleCA9IEl0ZW1JbmRleCArIDENCiAg +ICAgICAgIEl0ZW1BcnJheShJdGVtSW5kZXgpID0gaXRtDQogICAgICBFbmQgSWYN +CiAgIE5leHQNCiAgIA0KICAgSWYgSXRlbUluZGV4ID0gLTEgVGhlbg0KICAgICAg +RXJhc2UgSXRlbUFycmF5DQogICAgICBHZXRBcnJheVdpdGhvdXRFbXB0eVZhbHVl +cyA9IEl0ZW1BcnJheQ0KICAgICAgRXhpdCBGdW5jdGlvbg0KICAgRW5kIElmDQog +ICANCiAgIElmIEl0ZW1JbmRleCA8IChtX0l0ZW1zLkNvdW50IC0gMSkgVGhlbg0K +ICAgICAgUmVEaW0gUHJlc2VydmUgSXRlbUFycmF5KDAgVG8gSXRlbUluZGV4KQ0K +ICAgRW5kIElmDQogICANCiAgIEdldEFycmF5V2l0aG91dEVtcHR5VmFsdWVzID0g +SXRlbUFycmF5DQoNCkVuZCBGdW5jdGlvbg0KDQpQcml2YXRlIEZ1bmN0aW9uIFJl +bW92ZUR1cGxpY2F0ZVZhbHVlcyhCeVJlZiBBcnJheVRvQ2hlY2soKSBBcyBTdHJp +bmcpIEFzIFN0cmluZygpDQoNCiAgIERpbSBJdGVtQXJyYXkoKSBBcyBTdHJpbmcN +CiAgIERpbSBNYXhBcnJheUluZGV4IEFzIExvbmcNCiAgIERpbSBJdGVtSW5kZXgg +QXMgTG9uZw0KICAgRGltIEFycmF5SXRlbSBBcyBWYXJpYW50DQoNCiAgIE1heEFy +cmF5SW5kZXggPSBVQm91bmQoQXJyYXlUb0NoZWNrKQ0KDQogICBJZiBNYXhBcnJh +eUluZGV4ID0gMCBUaGVuDQogICAgICBSZW1vdmVEdXBsaWNhdGVWYWx1ZXMgPSBB +cnJheVRvQ2hlY2sNCiAgICAgIEV4aXQgRnVuY3Rpb24NCiAgIEVuZCBJZg0KICAg +DQogICBSZURpbSBJdGVtQXJyYXkoTWF4QXJyYXlJbmRleCkNCiAgIA0KICAgSXRl +bUluZGV4ID0gLTENCiAgIEZvciBFYWNoIEFycmF5SXRlbSBJbiBBcnJheVRvQ2hl +Y2sNCiAgICAgIElmIE5vdCBWYWx1ZUV4aXN0c0luQXJyYXkoSXRlbUFycmF5LCBB +cnJheUl0ZW0sIEl0ZW1JbmRleCkgVGhlbg0KICAgICAgICAgSXRlbUluZGV4ID0g +SXRlbUluZGV4ICsgMQ0KICAgICAgICAgSXRlbUFycmF5KEl0ZW1JbmRleCkgPSBB +cnJheUl0ZW0NCiAgICAgIEVuZCBJZg0KICAgTmV4dA0KICAgDQogICBJZiBJdGVt +SW5kZXggPCAobV9JdGVtcy5Db3VudCAtIDEpIFRoZW4NCiAgICAgIFJlRGltIFBy +ZXNlcnZlIEl0ZW1BcnJheSgwIFRvIEl0ZW1JbmRleCkNCiAgIEVuZCBJZg0KICAg +DQogICBSZW1vdmVEdXBsaWNhdGVWYWx1ZXMgPSBJdGVtQXJyYXkNCiAgIA0KRW5k +IEZ1bmN0aW9uDQoNClByaXZhdGUgRnVuY3Rpb24gVmFsdWVFeGlzdHNJbkFycmF5 +KEJ5UmVmIEFycmF5VG9DaGVjaygpIEFzIFN0cmluZywgQnlWYWwgVmFsdWVUb0No +ZWNrIEFzIFN0cmluZywgQnlWYWwgQ2hlY2tVbnRpbEFycmF5SW5kZXggQXMgTG9u +ZykgQXMgQm9vbGVhbg0KICAgDQogICBEaW0gaSBBcyBMb25nDQogICANCiAgIElm +IENoZWNrVW50aWxBcnJheUluZGV4IDwgMCBUaGVuDQogICAgICBFeGl0IEZ1bmN0 +aW9uDQogICBFbmQgSWYNCiAgIA0KICAgRm9yIGkgPSBMQm91bmQoQXJyYXlUb0No +ZWNrKSBUbyBDaGVja1VudGlsQXJyYXlJbmRleA0KICAgICAgSWYgU3RyQ29tcChB +cnJheVRvQ2hlY2soaSksIFZhbHVlVG9DaGVjaywgdmJCaW5hcnlDb21wYXJlKSA9 +IDAgVGhlbg0KICAgICAgICAgVmFsdWVFeGlzdHNJbkFycmF5ID0gVHJ1ZQ0KICAg +ICAgICAgRXhpdCBGdW5jdGlvbg0KICAgICAgRW5kIElmDQogICBOZXh0DQogICAN +CkVuZCBGdW5jdGlvbg0K + + 20250609094839 + text/StringCollection.cls + + + diff --git a/source/tbldefs/L10n_Dict.sql b/source/tbldefs/L10n_Dict.sql new file mode 100644 index 0000000..e9b8f9a --- /dev/null +++ b/source/tbldefs/L10n_Dict.sql @@ -0,0 +1,6 @@ +CREATE TABLE [L10n_Dict] ( + [LangCode] VARCHAR (2), + [KeyText] VARCHAR (255), + [LngText] VARCHAR (255), + CONSTRAINT [PK_L10n_Dict] PRIMARY KEY ([LangCode], [KeyText]) +) diff --git a/source/tbldefs/L10n_Dict.xml b/source/tbldefs/L10n_Dict.xml new file mode 100644 index 0000000..429fb56 --- /dev/null +++ b/source/tbldefs/L10n_Dict.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tbldefs/USysRegInfo.sql b/source/tbldefs/USysRegInfo.sql new file mode 100644 index 0000000..35e1b05 --- /dev/null +++ b/source/tbldefs/USysRegInfo.sql @@ -0,0 +1,6 @@ +CREATE TABLE [USysRegInfo] ( + [Subkey] VARCHAR (255), + [Type] LONG, + [ValName] VARCHAR (255), + [Value] VARCHAR (255) +) diff --git a/source/tbldefs/USysRegInfo.xml b/source/tbldefs/USysRegInfo.xml new file mode 100644 index 0000000..703a2c7 --- /dev/null +++ b/source/tbldefs/USysRegInfo.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tbldefs/tabFilterControls.sql b/source/tbldefs/tabFilterControls.sql new file mode 100644 index 0000000..109aab4 --- /dev/null +++ b/source/tbldefs/tabFilterControls.sql @@ -0,0 +1,12 @@ +CREATE TABLE [tabFilterControls] ( + [DataField] VARCHAR (255), + [DataType] VARCHAR (255), + [RelationalOperator] VARCHAR (255), + [Control] VARCHAR (255), + [Control2] VARCHAR (255), + [WildCardSuffix] BIT, + [WildCardPrefix] BIT, + [RelationalOperatorNot] BIT, + [CreateControl] BIT, + [ControlType] LONG +) diff --git a/source/tbldefs/tabFilterControls.xml b/source/tbldefs/tabFilterControls.xml new file mode 100644 index 0000000..cd6bd6c --- /dev/null +++ b/source/tbldefs/tabFilterControls.xml @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tbldefs/tabRelationalOperators.sql b/source/tbldefs/tabRelationalOperators.sql new file mode 100644 index 0000000..17d01e2 --- /dev/null +++ b/source/tbldefs/tabRelationalOperators.sql @@ -0,0 +1,5 @@ +CREATE TABLE [tabRelationalOperators] ( + [RelationalOperator] VARCHAR (20) CONSTRAINT [PrimaryKey] PRIMARY KEY UNIQUE NOT NULL, + [RelationalOperatorCode] VARCHAR (255), + [OrderPos] BYTE +) diff --git a/source/tbldefs/tabRelationalOperators.xml b/source/tbldefs/tabRelationalOperators.xml new file mode 100644 index 0000000..2f185a5 --- /dev/null +++ b/source/tbldefs/tabRelationalOperators.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tbldefs/tabSqlFieldDataTypes.sql b/source/tbldefs/tabSqlFieldDataTypes.sql new file mode 100644 index 0000000..fbff215 --- /dev/null +++ b/source/tbldefs/tabSqlFieldDataTypes.sql @@ -0,0 +1,4 @@ +CREATE TABLE [tabSqlFieldDataTypes] ( + [SqlFieldDataType] VARCHAR (20) CONSTRAINT [PrimaryKey] PRIMARY KEY UNIQUE NOT NULL, + [SqlFieldDataTypeCode] VARCHAR (255) +) diff --git a/source/tbldefs/tabSqlFieldDataTypes.xml b/source/tbldefs/tabSqlFieldDataTypes.xml new file mode 100644 index 0000000..c9de816 --- /dev/null +++ b/source/tbldefs/tabSqlFieldDataTypes.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tbldefs/tabSqlLangFormat.sql b/source/tbldefs/tabSqlLangFormat.sql new file mode 100644 index 0000000..4dc3127 --- /dev/null +++ b/source/tbldefs/tabSqlLangFormat.sql @@ -0,0 +1,6 @@ +CREATE TABLE [tabSqlLangFormat] ( + [SqlLang] VARCHAR (20) CONSTRAINT [PrimaryKey] PRIMARY KEY UNIQUE NOT NULL, + [SqlDateFormat] VARCHAR (255), + [SqlBooleanTrueString] VARCHAR (255), + [SqlWildCardString] VARCHAR (255) +) diff --git a/source/tbldefs/tabSqlLangFormat.xml b/source/tbldefs/tabSqlLangFormat.xml new file mode 100644 index 0000000..3eb9dfa --- /dev/null +++ b/source/tbldefs/tabSqlLangFormat.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/tbldefs/usys_AppFiles.sql b/source/tbldefs/usys_AppFiles.sql new file mode 100644 index 0000000..48091bb --- /dev/null +++ b/source/tbldefs/usys_AppFiles.sql @@ -0,0 +1,7 @@ +CREATE TABLE [usys_AppFiles] ( + [id] VARCHAR (255) CONSTRAINT [PrimaryKey] PRIMARY KEY UNIQUE NOT NULL, + [version] VARCHAR (10), + [file] LONGBINARY, + [SccRev] VARCHAR (50), + [url] VARCHAR (255) +) diff --git a/source/tbldefs/usys_AppFiles.xml b/source/tbldefs/usys_AppFiles.xml new file mode 100644 index 0000000..1a47b1a --- /dev/null +++ b/source/tbldefs/usys_AppFiles.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/themes/Office.thmx b/source/themes/Office.thmx new file mode 100644 index 0000000..5773f1c Binary files /dev/null and b/source/themes/Office.thmx differ diff --git a/source/vbe-project.json b/source/vbe-project.json new file mode 100644 index 0000000..486cb26 --- /dev/null +++ b/source/vbe-project.json @@ -0,0 +1,17 @@ +{ + "Info": { + "Class": "clsDbVbeProject", + "Description": "VBE Project" + }, + "Items": { + "Name": "ACLibFilterFormWizard", + "Description": "Assistent für die Erstellung von Filterformularen", + "FileName": "ACLibFilterFormWizard.accdb", + "HelpFile": "", + "HelpContextId": 0, + "ConditionalCompilationArguments": "USELOCALIZATION = 1 : L10nMsgBoxReplacement = 1", + "Mode": 0, + "Protection": 0, + "Type": 100 + } +} diff --git a/source/vbe-references.json b/source/vbe-references.json new file mode 100644 index 0000000..3acd933 --- /dev/null +++ b/source/vbe-references.json @@ -0,0 +1,16 @@ +{ + "Info": { + "Class": "clsDbVbeReference", + "Description": "VBE References" + }, + "Items": { + "DAO": { + "GUID": "{4AC9E1DA-5BAD-4AC7-86E3-24F4CDCECA28}", + "Version": "12.0" + }, + "VBIDE": { + "GUID": "{0002E157-0000-0000-C000-000000000046}", + "Version": "5.3" + } + } +} diff --git a/source/vcs-options.json b/source/vcs-options.json new file mode 100644 index 0000000..46325c9 --- /dev/null +++ b/source/vcs-options.json @@ -0,0 +1,81 @@ +{ + "Info": { + "AddinVersion": "4.1.2-jp.2", + "AccessVersion": "16.0 64-bit" + }, + "Options": { + "ExportFolder": "\\source", + "ShowDebug": false, + "UseFastSave": true, + "UseMergeBuild": false, + "UseGitIntegration": false, + "SavePrintVars": true, + "ExportPrintSettings": { + "Orientation": true, + "PaperSize": true, + "Duplex": false, + "PrintQuality": false, + "DisplayFrequency": false, + "Collate": false, + "Resolution": false, + "DisplayFlags": false, + "Color": false, + "Copies": false, + "ICMMethod": false, + "DefaultSource": false, + "Scale": false, + "ICMIntent": false, + "FormName": false, + "PaperLength": false, + "DitherType": false, + "MediaType": false, + "PaperWidth": false, + "TTOption": false + }, + "SaveQuerySQL": true, + "FormatSQL": true, + "ForceImportOriginalQuerySQL": false, + "SaveTableSQL": true, + "SplitLayoutFromVBA": true, + "StripPublishOption": true, + "SanitizeColors": 1, + "SanitizeLevel": 2, + "ExtractThemeFiles": false, + "TablesToExportData": { + "L10n_Dict": { + "Format": "XML Format" + }, + "tabRelationalOperators": { + "Format": "XML Format" + }, + "tabSqlFieldDataTypes": { + "Format": "XML Format" + }, + "tabSqlLangFormat": { + "Format": "XML Format" + }, + "usys_AppFiles": { + "Format": "XML Format" + }, + "USysRegInfo": { + "Format": "XML Format" + }, + "USysRibbons": { + "Format": "Tab Delimited" + } + }, + "SchemaExports": { + }, + "RunBeforeExport": "VcsRunBeforeExport", + "RunAfterExport": "", + "RunBeforeBuild": "", + "RunAfterBuild": "", + "RunBeforeMerge": "", + "RunAfterMerge": "", + "ShowVCSLegacy": true, + "HashAlgorithm": "SHA256", + "UseShortHash": true, + "BreakOnError": false, + "PreserveRubberDuckID": false + } +}